[gnome-builder/wip/chergert/layout: 13/118] more work on ripping up the editor
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder/wip/chergert/layout: 13/118] more work on ripping up the editor
- Date: Wed, 5 Jul 2017 11:49:08 +0000 (UTC)
commit 8fc005b6e03a515dcf489a91724d46d40df70cb8
Author: Christian Hergert <chergert redhat com>
Date: Tue Jun 27 16:02:14 2017 -0700
more work on ripping up the editor
TODO.txt | 32 ++
data/gtk/menus.ui | 82 +--
data/themes/Adwaita-shared.css | 91 +---
data/themes/shared.css | 7 +-
data/themes/shared/shared-layout.css | 80 +++
libide/editor/ide-editor-perspective.c | 274 ++++++++--
libide/editor/ide-editor-perspective.h | 13 +-
libide/editor/ide-editor-search-bar.c | 590 ++++++++++++++++++++
libide/editor/ide-editor-search-bar.h | 40 ++
libide/editor/ide-editor-search-bar.ui | 276 +++++++++
libide/editor/ide-editor-view-settings.c | 10 +-
libide/editor/ide-editor-view.c | 127 ++++-
libide/editor/ide-editor-view.h | 4 +-
libide/editor/ide-editor-view.ui | 14 +
libide/layout/ide-layout-grid-actions.c | 71 ---
libide/layout/ide-layout-grid.c | 129 +++++-
libide/layout/ide-layout-grid.h | 5 +
libide/layout/ide-layout-stack-header.c | 1 +
libide/layout/ide-layout-stack-header.h | 2 +-
libide/layout/ide-layout-stack.c | 23 +
libide/layout/ide-layout-stack.h | 3 +
libide/layout/ide-layout-view.c | 2 +
libide/layout/ide-layout.c | 167 +------
libide/layout/ide-layout.h | 16 +-
libide/libide.gresource.xml | 2 +
libide/meson.build | 5 +-
plugins/beautifier/gb-beautifier-workbench-addin.c | 4 +-
plugins/color-picker/gb-color-picker-prefs.c | 2 +-
.../gb-color-picker-workbench-addin-private.h | 2 +-
.../color-picker/gb-color-picker-workbench-addin.c | 20 +-
plugins/comment-code/gbp-comment-code-view-addin.c | 4 +-
plugins/project-tree/gb-project-tree-actions.c | 2 +-
.../project-tree/gb-project-tree-editor-addin.c | 2 +-
.../gbp-quick-highlight-view-addin.c | 8 +-
plugins/retab/gbp-retab-view-addin.c | 4 +-
plugins/symbol-tree/symbol-tree-panel.c | 2 +-
plugins/symbol-tree/symbol-tree.c | 8 +-
37 files changed, 1649 insertions(+), 475 deletions(-)
---
diff --git a/TODO.txt b/TODO.txt
new file mode 100644
index 0000000..ada637d
--- /dev/null
+++ b/TODO.txt
@@ -0,0 +1,32 @@
+
+ - Search entry context menu (use a GMenu and merging this time)
+ Might also require DzlWidgetActionGroup.
+
+ - Enter, Up, and Down accelerators for search/replace entries.
+
+ - perspective focus_location
+
+ - other perspective interface methods
+
+ - can we make perspectives the plugin interface?
+
+ - Check if buffer is already in visible stack before adding new view
+
+ - view-added/removed/etc on IdeLayoutGrid
+
+ - Remove get_right_edge() etc, switch with "classification" for panels
+
+ - Ability to disable plugin by default
+
+ - Plugins to fix for API
+ - devhelp
+ - command bar / vim
+ - project-tree
+ - terminal
+ - symbol-tree
+
+ - Remove accelerators from perspective, use shortcut engine
+
+ - Move panel position settings to org.gnome.builder.editor maybe
+
+
diff --git a/data/gtk/menus.ui b/data/gtk/menus.ui
index 189b3ec..2283aed 100644
--- a/data/gtk/menus.ui
+++ b/data/gtk/menus.ui
@@ -61,27 +61,6 @@
<attribute name="verb-icon">builder-view-right-pane-symbolic</attribute>
</item>
</section>
-<!--
- <section>
- <attribute name="id">juntion-section</attribute>
- <attribute name="display-hint">horizontal-buttons</attribute>
- <item>
- <attribute name="label" translatable="yes">_Reload</attribute>
- <attribute name="action">win.revert</attribute>
- <attribute name="verb-icon">view-refresh-symbolic</attribute>
- </item>
- <item>
- <attribute name="label" translatable="yes">_Print…</attribute>
- <attribute name="action">win.print</attribute>
- <attribute name="verb-icon">printer-symbolic</attribute>
- </item>
- <item>
- <attribute name="label" translatable="yes">_Fullscreen</attribute>
- <attribute name="action">win.fullscreen</attribute>
- <attribute name="verb-icon">view-fullscreen-symbolic</attribute>
- </item>
- </section>
--->
<section id="gear-menu-new-section">
<item>
<attribute name="label" translatable="yes">_New File</attribute>
@@ -262,61 +241,50 @@
</item>
</section>
</menu>
- <menu id="ide-layout-stack-menu">
- <section id="ide-layout-stack-menu-splits-section">
- <attribute name="display-hint">horizontal-buttons</attribute>
- <attribute name="label" translatable="yes">Split</attribute>
+ <menu id="ide-layout-stack-frame-menu">
+ <section id="ide-layout-stack-frame-section">
+ <attribute name="label" translatable="yes">Frame</attribute>
<item>
- <attribute name="label" translatable="yes">Split Left</attribute>
- <attribute name="action">view-stack.split-left</attribute>
- <attribute name="verb-icon">builder-split-tab-left-symbolic</attribute>
+ <attribute name="label" translatable="yes">Move Left</attribute>
+ <attribute name="action">layoutstack.move-left</attribute>
</item>
<item>
- <attribute name="label" translatable="yes">Split Right</attribute>
- <attribute name="action">view-stack.split-right</attribute>
- <attribute name="verb-icon">builder-split-tab-right-symbolic</attribute>
+ <attribute name="label" translatable="yes">Move Right</attribute>
+ <attribute name="action">layoutstack.move-right</attribute>
</item>
<item>
- <attribute name="label" translatable="yes">Split Down</attribute>
- <attribute name="action">view-stack.split-down</attribute>
- <attribute name="verb-icon">builder-split-tab-symbolic</attribute>
+ <attribute name="action">layoutstack.split-view</attribute>
+ <attribute name="label" translatable="yes">Split</attribute>
</item>
- </section>
- <section id="ide-layout-stack-menu-move-section">
- <attribute name="display-hint">horizontal-buttons</attribute>
- <attribute name="label" translatable="yes">Move</attribute>
<item>
- <attribute name="label" translatable="yes">Move Left</attribute>
- <attribute name="action">view-stack.move-left</attribute>
- <attribute name="verb-icon">builder-move-left-symbolic</attribute>
+ <attribute name="action">layoutgrid.close-stack</attribute>
+ <attribute name="label" translatable="yes">Close</attribute>
</item>
+ </section>
+ </menu>
+ <menu id="ide-editor-view-document-menu">
+ <section id="editor-document-section">
+ <attribute name="label" translatable="yes">Document</attribute>
<item>
- <attribute name="label" translatable="yes">Move Right</attribute>
- <attribute name="action">view-stack.move-right</attribute>
- <attribute name="verb-icon">builder-move-right-symbolic</attribute>
+ <attribute name="label" translatable="yes">Open in New Frame</attribute>
+ <attribute name="action">layoutstack.open-in-new-frame</attribute>
</item>
- </section>
- <section id="ide-layout-stack-menu-preview-section"/>
- <section id="ide-layout-stack-menu-save-section">
<item>
- <attribute name="label" translatable="yes">_Save</attribute>
- <attribute name="action">view.save</attribute>
+ <attribute name="label" translatable="yes">Open Preview</attribute>
</item>
<item>
- <attribute name="label" translatable="yes">_Save As</attribute>
- <attribute name="action">view.save-as</attribute>
+ <attribute name="label" translatable="yes">Print…</attribute>
</item>
</section>
- <section id="ide-layout-stack-menu-print-section">
+ <section id="editor-document-preferences-section">
<item>
- <attribute name="label" translatable="yes">_Print</attribute>
- <attribute name="action">view.print</attribute>
+ <attribute name="label" translatable="yes">Document Preferences</attribute>
</item>
</section>
- <section id="ide-layout-stack-menu-close-section">
+ <section id="editor-document-close-section">
<item>
- <attribute name="label" translatable="yes">_Close</attribute>
- <attribute name="action">view-stack.close</attribute>
+ <attribute name="action">layoutstack.close-view</attribute>
+ <attribute name="label" translatable="yes">Close</attribute>
</item>
</section>
</menu>
diff --git a/data/themes/Adwaita-shared.css b/data/themes/Adwaita-shared.css
index d90bdd8..408611b 100644
--- a/data/themes/Adwaita-shared.css
+++ b/data/themes/Adwaita-shared.css
@@ -1,95 +1,8 @@
@import url("resource:///org/gnome/builder/themes/shared.css");
-
-/*
- * Layout tab and tab bar tweaks
- *
- * The following makes the layout stack header look similar to a tab bar.
- */
-layouttabbar > box > button {
- opacity: 0.5;
-}
-layouttabbar > box > button:hover {
- opacity: 0.75;
-}
-layouttabbar > box > button:active {
- opacity: 1;
-}
-layouttabbar button {
- border: none;
- box-shadow: none;
- background: transparent;
-}
-layouttab label {
- padding: 5px;
-}
-layouttab {
- background-color: @theme_bg_color;
-
- border-bottom: 3px;
- border-bottom-style: solid;
-
- border-right: 1px solid alpha(@borders, 0.75);
- border-left: 1px solid alpha(@borders, 0.75);
-
- border-bottom-left-radius: 3px;
- border-bottom-right-radius: 3px;
-}
-layouttab:backdrop {
- border-right-color: alpha(@borders, 0.75);
- border-left-color: alpha(@borders, 0.75);
- box-shadow: none;
-}
-layouttabbar:backdrop {
- box-shadow: none;
-}
-layouttab separator.vertical {
- margin-top: 7px;
- margin-bottom: 7px;
- opacity: 0.75;
+idelayoutstackheader > button:last-child {
+ margin-right: 3px;
}
-layouttab separator.vertical:backdrop {
- opacity: 0.3;
-}
-layouttab button:disabled,
-layouttab button {
- background: none;
- border: none;
- box-shadow: none;
- padding-left: 4px;
- padding-right: 4px;
-}
-
-
-/*
- * Close button styling for layouttab.
- */
-layouttab > box > button:last-child image {
- color: @theme_fg_color;
- opacity: 0.3;
- margin: 2px;
- border: 1px solid transparent;
- border-radius: 3px;
-}
-layouttab > box > button:last-child:hover image {
- opacity: .75;
- transition-duration: 250ms;
- border: 1px solid @borders;
-}
-layouttab > box > button:last-child:active image {
- opacity: .8;
- background-image: linear-gradient(shade(@theme_bg_color, 0.9), @theme_bg_color);
-}
-layouttab > box > button:last-child:backdrop image {
- opacity: .1;
-}
-
-
-layout {
- border: 1px solid alpha(@borders, 0.75);
- -PnlDockBin-handle-size: 1;
-}
-
entry.search-missing {
background-color: #cc0000;
diff --git a/data/themes/shared.css b/data/themes/shared.css
index 746f586..d084ec0 100644
--- a/data/themes/shared.css
+++ b/data/themes/shared.css
@@ -1,3 +1,5 @@
+@import url("resource:///org/gnome/builder/themes/shared/shared-layout.css");
+
/* work around some gtk padding issue */
filechooser actionbar button.combo {
padding: 0;
@@ -9,7 +11,7 @@ filechooser actionbar button.combo {
}
/* styling for editor search */
-frame.gb-search-frame {
+ideeditorsearchbar {
background-image: linear-gradient(shade(@theme_bg_color,1.05), @theme_bg_color);
padding: 6px;
border-style: solid;
@@ -20,9 +22,6 @@ frame.gb-search-frame {
border-bottom-left-radius: 5px;
border-bottom-right-radius: 5px;
}
-frame.gb-search-frame border {
- border: none;
-}
/* styling for the search and spellchecker list close button */
frame.gb-search-frame > box > grid:first-child > button.close:disabled,
diff --git a/data/themes/shared/shared-layout.css b/data/themes/shared/shared-layout.css
new file mode 100644
index 0000000..7eeb6f5
--- /dev/null
+++ b/data/themes/shared/shared-layout.css
@@ -0,0 +1,80 @@
+idelayoutstackheader {
+ min-height: 26px;
+}
+
+idelayoutstackheader button {
+ border: none;
+ border-radius: 0;
+ background: transparent;
+ box-shadow: none;
+ padding: 0;
+ margin: 0;
+}
+
+idelayoutstackheader button:not(:disabled) image {
+ opacity: 0.55;
+}
+
+idelayoutstackheader button:checked image,
+idelayoutstackheader button:not(:disabled):hover image {
+ opacity: 1;
+}
+
+idelayoutstackheader button:checked,
+idelayoutstackheader button:hover {
+ background: shade(@theme_bg_color, 0.9);
+}
+
+idelayoutstackheader button:active {
+ background: shade(@theme_bg_color, 0.85);
+}
+
+idelayoutstackheader > button {
+ padding-left: 12px;
+ padding-right: 12px;
+}
+
+idelayoutstackheader * button:first-child > image,
+idelayoutstackheader * button:last-child:dir(rtl) > image {
+ padding-left: 12px;
+ padding-right: 10px;
+}
+
+idelayoutstackheader * button:first-child:dir(rtl) > image,
+idelayoutstackheader * button:last-child > image {
+ padding-right: 12px;
+ padding-left: 9px;
+}
+
+idelayoutgrid.handle {
+ border: 1px solid @borders;
+}
+
+popover.symbols-button {
+ padding: 12px;
+}
+
+popover.symbols-button treeview {
+ background: transparent;
+ color: @theme_text_color;
+}
+
+popover.title-popover scrolledwindow {
+ min-width: 300px;
+}
+
+popover.title-popover list {
+ background: transparent;
+}
+
+popover.title-popover list row {
+ padding: 6px;
+}
+
+popover.title-popover list row button {
+ margin: 0;
+ padding: 0;
+ box-shadow: none;
+ border: none;
+ background: transparent;
+}
diff --git a/libide/editor/ide-editor-perspective.c b/libide/editor/ide-editor-perspective.c
index 42c44d6..4aa65b0 100644
--- a/libide/editor/ide-editor-perspective.c
+++ b/libide/editor/ide-editor-perspective.c
@@ -18,59 +18,30 @@
#define G_LOG_DOMAIN "ide-editor-perspective"
-#include "ide-editor-perspective.h"
+#include <glib/gi18n.h>
+
+#include "editor/ide-editor-perspective.h"
+#include "editor/ide-editor-view.h"
+#include "workbench/ide-perspective.h"
struct _IdeEditorPerspective
{
IdeLayout parent_instance;
+ /* Template widgets */
IdeLayoutGrid *grid;
};
-enum {
- PROP_0,
- N_PROPS
-};
-
-G_DEFINE_TYPE (IdeEditorPerspective, ide_editor_perspective, IDE_TYPE_LAYOUT)
-
-static GParamSpec *properties [N_PROPS];
-
-static void
-ide_editor_perspective_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- switch (prop_id)
- {
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- }
-}
+static void perspective_iface_init (IdePerspectiveInterface *iface);
-static void
-ide_editor_perspective_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- switch (prop_id)
- {
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- }
-}
+G_DEFINE_TYPE_WITH_CODE (IdeEditorPerspective, ide_editor_perspective, IDE_TYPE_LAYOUT,
+ G_IMPLEMENT_INTERFACE (IDE_TYPE_PERSPECTIVE, perspective_iface_init))
static void
ide_editor_perspective_class_init (IdeEditorPerspectiveClass *klass)
{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
- object_class->get_property = ide_editor_perspective_get_property;
- object_class->set_property = ide_editor_perspective_set_property;
-
gtk_widget_class_set_template_from_resource (widget_class,
"/org/gnome/builder/ui/ide-editor-perspective.ui");
gtk_widget_class_bind_template_child (widget_class, IdeEditorPerspective, grid);
}
@@ -78,6 +49,7 @@ ide_editor_perspective_class_init (IdeEditorPerspectiveClass *klass)
static void
ide_editor_perspective_init (IdeEditorPerspective *self)
{
+ gtk_widget_init_template (GTK_WIDGET (self));
}
/**
@@ -98,3 +70,229 @@ ide_editor_perspective_get_grid (IdeEditorPerspective *self)
return self->grid;
}
+
+void
+ide_editor_perspective_focus_location (IdeEditorPerspective *self,
+ IdeSourceLocation *location)
+{
+ g_return_if_fail (IDE_IS_EDITOR_PERSPECTIVE (self));
+ g_return_if_fail (location != NULL);
+
+ /* TODO: */
+}
+
+void
+ide_editor_perspective_focus_buffer_in_current_stack (IdeEditorPerspective *self,
+ IdeBuffer *buffer)
+{
+ IdeLayoutStack *stack;
+ IdeEditorView *view;
+
+ g_return_if_fail (IDE_IS_EDITOR_PERSPECTIVE (self));
+ g_return_if_fail (IDE_IS_BUFFER (buffer));
+
+ stack = ide_layout_grid_get_current_stack (self->grid);
+
+ /* TODO: Check if buffer is in stack */
+
+ view = g_object_new (IDE_TYPE_EDITOR_VIEW,
+ "buffer", buffer,
+ "visible", TRUE,
+ NULL);
+
+ gtk_container_add (GTK_CONTAINER (stack), GTK_WIDGET (view));
+}
+
+/**
+ * ide_editor_perspective_get_active_view:
+ * @self: a #IdeEditorPerspective
+ *
+ * Gets the active view for the perspective, or %NULL if there is not one.
+ *
+ * Returns: (nullable) (transfer none): An #IdeLayoutView or %NULL.
+ *
+ * Since: 3.26
+ */
+IdeLayoutView *
+ide_editor_perspective_get_active_view (IdeEditorPerspective *self)
+{
+ IdeLayoutStack *stack;
+
+ g_return_val_if_fail (IDE_IS_EDITOR_PERSPECTIVE (self), NULL);
+
+ stack = ide_layout_grid_get_current_stack (self->grid);
+
+ return ide_layout_stack_get_visible_child (stack);
+}
+
+/**
+ * ide_editor_perspective_get_right_edge:
+ *
+ * Returns: (transfer none): A #GtkWidget
+ */
+GtkWidget *
+ide_editor_perspective_get_right_edge (IdeEditorPerspective *self)
+{
+ g_return_val_if_fail (IDE_IS_EDITOR_PERSPECTIVE (self), NULL);
+ return dzl_dock_bin_get_right_edge (DZL_DOCK_BIN (self));
+}
+
+/**
+ * ide_editor_perspective_get_bottom_edge:
+ *
+ * Returns: (transfer none): A #GtkWidget
+ */
+GtkWidget *
+ide_editor_perspective_get_bottom_edge (IdeEditorPerspective *self)
+{
+ g_return_val_if_fail (IDE_IS_EDITOR_PERSPECTIVE (self), NULL);
+ return dzl_dock_bin_get_bottom_edge (DZL_DOCK_BIN (self));
+}
+
+static void
+set_reveal_child_without_transition (DzlDockRevealer *revealer,
+ gboolean reveal)
+{
+ DzlDockRevealerTransitionType type;
+
+ g_assert (DZL_IS_DOCK_REVEALER (revealer));
+
+ type = dzl_dock_revealer_get_transition_type (revealer);
+ dzl_dock_revealer_set_transition_type (revealer, DZL_DOCK_REVEALER_TRANSITION_TYPE_NONE);
+ dzl_dock_revealer_set_reveal_child (revealer, reveal);
+ dzl_dock_revealer_set_transition_type (revealer, type);
+}
+
+static void
+ide_editor_perspective_restore_panel_state (IdeEditorPerspective *self)
+{
+ g_autoptr(GSettings) settings = NULL;
+ GtkWidget *pane;
+ gboolean reveal;
+ guint position;
+
+ g_assert (IDE_IS_EDITOR_PERSPECTIVE (self));
+
+ /* TODO: This belongs in editor settings probably */
+
+ settings = g_settings_new ("org.gnome.builder.workbench");
+
+ pane = dzl_dock_bin_get_left_edge (DZL_DOCK_BIN (self));
+ reveal = g_settings_get_boolean (settings, "left-visible");
+ position = g_settings_get_int (settings, "left-position");
+ dzl_dock_revealer_set_position (DZL_DOCK_REVEALER (pane), position);
+ set_reveal_child_without_transition (DZL_DOCK_REVEALER (pane), reveal);
+
+ pane = dzl_dock_bin_get_right_edge (DZL_DOCK_BIN (self));
+ reveal = g_settings_get_boolean (settings, "right-visible");
+ position = g_settings_get_int (settings, "right-position");
+ dzl_dock_revealer_set_position (DZL_DOCK_REVEALER (pane), position);
+ set_reveal_child_without_transition (DZL_DOCK_REVEALER (pane), reveal);
+
+ pane = dzl_dock_bin_get_bottom_edge (DZL_DOCK_BIN (self));
+ reveal = g_settings_get_boolean (settings, "bottom-visible");
+ position = g_settings_get_int (settings, "bottom-position");
+ dzl_dock_revealer_set_position (DZL_DOCK_REVEALER (pane), position);
+ set_reveal_child_without_transition (DZL_DOCK_REVEALER (pane), reveal);
+}
+
+static void
+ide_editor_perspective_save_panel_state (IdeEditorPerspective *self)
+{
+ g_autoptr(GSettings) settings = NULL;
+ GtkWidget *pane;
+ gboolean reveal;
+ guint position;
+
+ g_assert (IDE_IS_EDITOR_PERSPECTIVE (self));
+
+ /* TODO: possibly belongs in editor settings */
+ settings = g_settings_new ("org.gnome.builder.workbench");
+
+ pane = dzl_dock_bin_get_left_edge (DZL_DOCK_BIN (self));
+ position = dzl_dock_revealer_get_position (DZL_DOCK_REVEALER (pane));
+ reveal = dzl_dock_revealer_get_reveal_child (DZL_DOCK_REVEALER (pane));
+ g_settings_set_boolean (settings, "left-visible", reveal);
+ g_settings_set_int (settings, "left-position", position);
+
+ pane = dzl_dock_bin_get_right_edge (DZL_DOCK_BIN (self));
+ position = dzl_dock_revealer_get_position (DZL_DOCK_REVEALER (pane));
+ reveal = dzl_dock_revealer_get_reveal_child (DZL_DOCK_REVEALER (pane));
+ g_settings_set_boolean (settings, "right-visible", reveal);
+ g_settings_set_int (settings, "right-position", position);
+
+ pane = dzl_dock_bin_get_bottom_edge (DZL_DOCK_BIN (self));
+ position = dzl_dock_revealer_get_position (DZL_DOCK_REVEALER (pane));
+ reveal = dzl_dock_revealer_get_reveal_child (DZL_DOCK_REVEALER (pane));
+ g_settings_set_boolean (settings, "bottom-visible", reveal);
+ g_settings_set_int (settings, "bottom-position", position);
+}
+
+static void
+ide_editor_perspective_views_foreach (IdePerspective *perspective,
+ GtkCallback callback,
+ gpointer user_data)
+{
+ IdeEditorPerspective *self = (IdeEditorPerspective *)perspective;
+
+ g_assert (IDE_IS_EDITOR_PERSPECTIVE (self));
+ g_assert (callback != NULL);
+
+ ide_layout_grid_foreach_view (self->grid, callback, user_data);
+}
+
+static gchar *
+ide_editor_perspective_get_id (IdePerspective *perspective)
+{
+ return g_strdup ("editor");
+}
+
+static gchar *
+ide_editor_perspective_get_icon_name (IdePerspective *perspective)
+{
+ return g_strdup ("builder-editor-symbolic");
+}
+
+static gchar *
+ide_editor_perspective_get_accelerator (IdePerspective *perspective)
+{
+ return g_strdup ("<Alt>1");
+}
+
+static gchar *
+ide_editor_perspective_get_title (IdePerspective *perspective)
+{
+ return g_strdup (_("Editor"));
+}
+
+static void
+ide_editor_perspective_restore_state (IdePerspective *perspective)
+{
+ IdeEditorPerspective *self = (IdeEditorPerspective *)perspective;
+ g_assert (IDE_IS_EDITOR_PERSPECTIVE (self));
+ ide_editor_perspective_restore_panel_state (self);
+}
+
+static gboolean
+ide_editor_perspective_agree_to_shutdown (IdePerspective *perspective)
+{
+ IdeEditorPerspective *self = (IdeEditorPerspective *)perspective;
+
+ g_assert (IDE_IS_EDITOR_PERSPECTIVE (self));
+
+ ide_editor_perspective_save_panel_state (self);
+
+ return TRUE;
+}
+
+static void
+perspective_iface_init (IdePerspectiveInterface *iface)
+{
+ iface->agree_to_shutdown = ide_editor_perspective_agree_to_shutdown;
+ iface->get_accelerator = ide_editor_perspective_get_accelerator;
+ iface->get_icon_name = ide_editor_perspective_get_icon_name;
+ iface->get_id = ide_editor_perspective_get_id;
+ iface->get_title = ide_editor_perspective_get_title;
+ iface->restore_state = ide_editor_perspective_restore_state;
+ iface->views_foreach = ide_editor_perspective_views_foreach;
+}
diff --git a/libide/editor/ide-editor-perspective.h b/libide/editor/ide-editor-perspective.h
index 7e2dcb5..47b102e 100644
--- a/libide/editor/ide-editor-perspective.h
+++ b/libide/editor/ide-editor-perspective.h
@@ -18,6 +18,7 @@
#pragma once
+#include "diagnostics/ide-source-location.h"
#include "layout/ide-layout.h"
#include "layout/ide-layout-grid.h"
@@ -27,6 +28,16 @@ G_BEGIN_DECLS
G_DECLARE_FINAL_TYPE (IdeEditorPerspective, ide_editor_perspective, IDE, EDITOR_PERSPECTIVE, IdeLayout)
-IdeLayoutGrid *ide_editor_perspective_get_grid (IdeEditorPerspective *self);
+IdeLayoutGrid *ide_editor_perspective_get_grid (IdeEditorPerspective *self);
+void ide_editor_perspective_focus_location (IdeEditorPerspective *self,
+ IdeSourceLocation *location);
+void ide_editor_perspective_focus_buffer_in_current_stack (IdeEditorPerspective *self,
+ IdeBuffer *buffer);
+IdeLayoutView *ide_editor_perspective_get_active_view (IdeEditorPerspective *self);
+
+/* We want this to use "classifications" rather than "edges" */
+GtkWidget *ide_editor_perspective_get_right_edge (IdeEditorPerspective *self);
+GtkWidget *ide_editor_perspective_get_bottom_edge (IdeEditorPerspective *self);
+
G_END_DECLS
diff --git a/libide/editor/ide-editor-search-bar.c b/libide/editor/ide-editor-search-bar.c
new file mode 100644
index 0000000..8b844b7
--- /dev/null
+++ b/libide/editor/ide-editor-search-bar.c
@@ -0,0 +1,590 @@
+/* ide-editor-search-bar.c
+ *
+ * Copyright (C) 2017 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 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 "ide-editor-search-bar"
+
+#include <glib/gi18n.h>
+#include <libgd/gd-tagged-entry.h>
+
+#include "ide-macros.h"
+
+#include "editor/ide-editor-search-bar.h"
+
+struct _IdeEditorSearchBar
+{
+ DzlBin parent_instance;
+
+ /* Owned references */
+ GtkSourceSearchSettings *search_settings;
+ GtkSourceSearchContext *search_context;
+ DzlSignalGroup *search_context_signals;
+ GdTaggedEntryTag *search_entry_tag;
+
+ /* Weak pointers */
+ IdeBuffer *buffer;
+ IdeSourceView *view;
+
+ /* Template widgets */
+ GtkCheckButton *case_sensitive;
+ GtkButton *close_button;
+ GtkButton *replace_all_button;
+ GtkButton *replace_button;
+ GtkSearchEntry *replace_entry;
+ GdTaggedEntry *search_entry;
+ GtkGrid *search_options;
+ GtkCheckButton *use_regex;
+ GtkCheckButton *whole_word;
+};
+
+enum {
+ PROP_0,
+ PROP_BUFFER,
+ PROP_VIEW,
+ N_PROPS
+};
+
+G_DEFINE_TYPE (IdeEditorSearchBar, ide_editor_search_bar, DZL_TYPE_BIN)
+
+static GParamSpec *properties [N_PROPS];
+
+static gboolean
+maybe_escape_regex (GBinding *binding,
+ const GValue *from_value,
+ GValue *to_value,
+ gpointer user_data)
+{
+ IdeEditorSearchBar *self = user_data;
+
+ g_assert (IDE_IS_EDITOR_SEARCH_BAR (self));
+ g_assert (from_value != NULL);
+ g_assert (to_value != NULL);
+
+ if (g_value_get_string (from_value) == NULL)
+ g_value_set_static_string (to_value, "");
+ else
+ {
+ const gchar *entry_text = g_value_get_string (from_value);
+ g_autofree gchar *unescaped = NULL;
+
+ if (!gtk_source_search_settings_get_regex_enabled (self->search_settings))
+ entry_text = unescaped = gtk_source_utils_unescape_search_text (entry_text);
+
+ g_value_set_string (to_value, entry_text);
+ }
+
+ return TRUE;
+}
+
+static gboolean
+pacify_null_text (GBinding *binding,
+ const GValue *from_value,
+ GValue *to_value,
+ gpointer user_data)
+{
+ g_assert (from_value != NULL);
+ g_assert (to_value != NULL);
+
+ if (g_value_get_string (from_value) == NULL)
+ g_value_set_static_string (to_value, "");
+ else
+ g_value_copy (from_value, to_value);
+
+ return TRUE;
+}
+
+static void
+update_replace_actions_sensitivity (IdeEditorSearchBar *self)
+{
+ g_autoptr(GError) regex_error = NULL;
+ g_autoptr(GError) replace_regex_error = NULL;
+ GtkTextBuffer *buffer;
+ GtkTextIter begin;
+ GtkTextIter end;
+ const gchar *search_text;
+ const gchar *replace_text;
+ gint pos;
+ gint count;
+ gboolean enable_replace;
+ gboolean enable_replace_all;
+ gboolean replace_regex_valid;
+
+ g_assert (IDE_IS_EDITOR_SEARCH_BAR (self));
+
+ if (self->search_context == NULL ||
+ self->view == NULL ||
+ self->buffer == NULL ||
+ self->search_settings == NULL)
+ return;
+
+ buffer = GTK_TEXT_BUFFER (self->buffer);
+
+ gtk_text_buffer_get_selection_bounds (buffer, &begin, &end);
+ replace_text = gtk_entry_get_text (GTK_ENTRY (self->replace_entry));
+
+ /* Gather enough info to determine if Replace or Replace All would make sense */
+ search_text = gtk_entry_get_text (GTK_ENTRY (self->search_entry));
+ pos = gtk_source_search_context_get_occurrence_position (self->search_context, &begin, &end);
+ count = gtk_source_search_context_get_occurrences_count (self->search_context);
+ regex_error = gtk_source_search_context_get_regex_error (self->search_context);
+ replace_regex_valid = gtk_source_search_settings_get_regex_enabled (self->search_settings) ?
+ g_regex_check_replacement (replace_text, NULL, &replace_regex_error) :
+ TRUE;
+
+ enable_replace = (!ide_str_empty0 (search_text) &&
+ regex_error == NULL &&
+ replace_regex_valid &&
+ pos > 0);
+
+ enable_replace_all = (!ide_str_empty0 (search_text) &&
+ regex_error == NULL &&
+ replace_regex_valid &&
+ count > 0);
+
+ dzl_gtk_widget_action_set (GTK_WIDGET (self), "search-entry", "replace",
+ "enabled", enable_replace,
+ NULL);
+ dzl_gtk_widget_action_set (GTK_WIDGET (self), "search-entry", "replace-all",
+ "enabled", enable_replace_all,
+ NULL);
+}
+
+static void
+on_notify_search_text (IdeEditorSearchBar *self,
+ GParamSpec *pspec,
+ GtkSourceSearchSettings *search_settings)
+{
+ g_assert (IDE_IS_EDITOR_SEARCH_BAR (self));
+ g_assert (GTK_SOURCE_IS_SEARCH_SETTINGS (search_settings));
+
+ update_replace_actions_sensitivity (self);
+}
+
+static void
+set_position_label (IdeEditorSearchBar *self,
+ const gchar *text)
+{
+ g_assert (IDE_IS_EDITOR_SEARCH_BAR (self));
+
+ if (ide_str_empty0 (text))
+ {
+ if (self->search_entry_tag != NULL)
+ {
+ gd_tagged_entry_remove_tag (self->search_entry, self->search_entry_tag);
+ g_clear_object (&self->search_entry_tag);
+ }
+
+ return;
+ }
+
+ if (self->search_entry_tag == NULL)
+ {
+ self->search_entry_tag = gd_tagged_entry_tag_new ("");
+ gd_tagged_entry_add_tag (self->search_entry, self->search_entry_tag);
+ gd_tagged_entry_tag_set_style (self->search_entry_tag,
+ "gb-search-entry-occurrences-tag");
+ }
+
+ gd_tagged_entry_tag_set_label (self->search_entry_tag, text);
+}
+
+static void
+update_search_position_label (IdeEditorSearchBar *self)
+{
+ g_autofree gchar *text = NULL;
+ GtkStyleContext *context;
+ GtkTextBuffer *buffer;
+ GtkTextIter begin;
+ GtkTextIter end;
+ const gchar *search_text;
+ gint count;
+ gint pos;
+
+ g_return_if_fail (IDE_IS_EDITOR_SEARCH_BAR (self));
+
+ if (self->buffer == NULL || self->search_context == NULL)
+ return;
+
+ buffer = GTK_TEXT_BUFFER (self->buffer);
+
+ gtk_text_buffer_get_selection_bounds (buffer, &begin, &end);
+ pos = gtk_source_search_context_get_occurrence_position (self->search_context, &begin, &end);
+ count = gtk_source_search_context_get_occurrences_count (self->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.
+ */
+ set_position_label (self, NULL);
+ return;
+ }
+
+ context = gtk_widget_get_style_context (GTK_WIDGET (self->search_entry));
+ search_text = gtk_entry_get_text (GTK_ENTRY (self->search_entry));
+
+ /* We use our own error class because we don't want to colide with styling
+ * from GTK+ themes.
+ */
+ if ((count == 0) && !ide_str_empty0 (search_text))
+ gtk_style_context_add_class (context, "search-missing");
+ else
+ gtk_style_context_remove_class (context, "search-missing");
+
+ /* translators: first %u is the Nth position of second %u N occurrences */
+ text = g_strdup_printf (_("%u of %u"), pos, count);
+ set_position_label (self, text);
+}
+
+static void
+on_notify_occurrences_count (IdeEditorSearchBar *self,
+ GParamSpec *pspec,
+ GtkSourceSearchContext *search_context)
+{
+ g_assert (IDE_IS_EDITOR_SEARCH_BAR (self));
+ g_assert (GTK_SOURCE_IS_SEARCH_CONTEXT (search_context));
+
+ update_search_position_label (self);
+ update_replace_actions_sensitivity (self);
+}
+
+static void
+on_notify_regex_error (IdeEditorSearchBar *self,
+ GParamSpec *pspec,
+ GtkSourceSearchContext *search_context)
+{
+ g_autoptr(GError) error = NULL;
+ PangoAttrList *attrs = NULL;
+ const gchar *tooltip_text = NULL;
+
+ g_assert (IDE_IS_EDITOR_SEARCH_BAR (self));
+ g_assert (GTK_SOURCE_IS_SEARCH_CONTEXT (search_context));
+
+ /*
+ * If the regular expression is invalid, add a white squiggly underline;
+ * otherwise remove it. We will also set the tooltip-text to the error
+ * that occurred while parsing the regex.
+ */
+
+ error = gtk_source_search_context_get_regex_error (search_context);
+
+ if (error != NULL)
+ {
+ attrs = pango_attr_list_new ();
+ pango_attr_list_insert (attrs, pango_attr_underline_new (PANGO_UNDERLINE_ERROR));
+ pango_attr_list_insert (attrs, pango_attr_underline_color_new (65535, 65535, 65535));
+ tooltip_text = error->message;
+ }
+
+ gtk_entry_set_attributes (GTK_ENTRY (self->search_entry), attrs);
+ gtk_widget_set_tooltip_text (GTK_WIDGET (self->search_entry), tooltip_text);
+
+ update_replace_actions_sensitivity (self);
+
+ pango_attr_list_unref (attrs);
+}
+
+static void
+check_replace_text (IdeEditorSearchBar *self)
+{
+ g_autoptr(GError) error = NULL;
+ PangoAttrList *attrs = NULL;
+ const gchar *tooltip_text = NULL;
+
+ g_assert (IDE_IS_EDITOR_SEARCH_BAR (self));
+ g_assert (self->search_settings != NULL);
+
+ if (self->search_context == NULL)
+ return;
+
+ /*
+ * If the replace expression is invalid, add a white squiggly underline;
+ * otherwise remove it. Also set the error message to the tooltip text
+ * so that the user can get some info on the error.
+ */
+ if (gtk_source_search_settings_get_regex_enabled (self->search_settings))
+ {
+ const gchar *replace_text;
+
+ replace_text = gtk_entry_get_text (GTK_ENTRY (self->replace_entry));
+
+ if (!g_regex_check_replacement (replace_text, NULL, &error))
+ {
+ attrs = pango_attr_list_new ();
+ pango_attr_list_insert (attrs, pango_attr_underline_new (PANGO_UNDERLINE_ERROR));
+ pango_attr_list_insert (attrs, pango_attr_underline_color_new (65535, 65535, 65535));
+ tooltip_text = error->message;
+ }
+ }
+
+ gtk_entry_set_attributes (GTK_ENTRY (self->replace_entry), attrs);
+ gtk_widget_set_tooltip_text (GTK_WIDGET (self->replace_entry), tooltip_text);
+
+ pango_attr_list_unref (attrs);
+}
+
+static void
+on_notify_regex_enabled (IdeEditorSearchBar *self,
+ GParamSpec *pspec,
+ GtkSourceSearchSettings *search_settings)
+{
+ g_assert (IDE_IS_EDITOR_SEARCH_BAR (self));
+ g_assert (GTK_SOURCE_IS_SEARCH_SETTINGS (search_settings));
+
+ check_replace_text (self);
+}
+
+static void
+ide_editor_search_bar_finalize (GObject *object)
+{
+ IdeEditorSearchBar *self = (IdeEditorSearchBar *)object;
+
+ ide_clear_weak_pointer (&self->buffer);
+ ide_clear_weak_pointer (&self->view);
+
+ g_clear_object (&self->search_context);
+ g_clear_object (&self->search_settings);
+ g_clear_object (&self->search_context_signals);
+ g_clear_object (&self->search_entry_tag);
+
+ G_OBJECT_CLASS (ide_editor_search_bar_parent_class)->finalize (object);
+}
+
+static void
+ide_editor_search_bar_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ IdeEditorSearchBar *self = IDE_EDITOR_SEARCH_BAR (object);
+
+ switch (prop_id)
+ {
+ case PROP_BUFFER:
+ g_value_set_object (value, ide_editor_search_bar_get_buffer (self));
+ break;
+
+ case PROP_VIEW:
+ g_value_set_object (value, ide_editor_search_bar_get_view (self));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+ide_editor_search_bar_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ IdeEditorSearchBar *self = IDE_EDITOR_SEARCH_BAR (object);
+
+ switch (prop_id)
+ {
+ case PROP_BUFFER:
+ ide_editor_search_bar_set_buffer (self, g_value_get_object (value));
+ break;
+
+ case PROP_VIEW:
+ ide_editor_search_bar_set_view (self, g_value_get_object (value));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+ide_editor_search_bar_class_init (IdeEditorSearchBarClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+ object_class->finalize = ide_editor_search_bar_finalize;
+ object_class->get_property = ide_editor_search_bar_get_property;
+ object_class->set_property = ide_editor_search_bar_set_property;
+
+ gtk_widget_class_set_template_from_resource (widget_class,
+ "/org/gnome/builder/ui/ide-editor-search-bar.ui");
+ gtk_widget_class_bind_template_child (widget_class, IdeEditorSearchBar, case_sensitive);
+ gtk_widget_class_bind_template_child (widget_class, IdeEditorSearchBar, close_button);
+ gtk_widget_class_bind_template_child (widget_class, IdeEditorSearchBar, replace_all_button);
+ gtk_widget_class_bind_template_child (widget_class, IdeEditorSearchBar, replace_button);
+ gtk_widget_class_bind_template_child (widget_class, IdeEditorSearchBar, replace_entry);
+ gtk_widget_class_bind_template_child (widget_class, IdeEditorSearchBar, search_entry);
+ gtk_widget_class_bind_template_child (widget_class, IdeEditorSearchBar, search_options);
+ gtk_widget_class_bind_template_child (widget_class, IdeEditorSearchBar, use_regex);
+ gtk_widget_class_bind_template_child (widget_class, IdeEditorSearchBar, whole_word);
+
+ gtk_widget_class_set_css_name (widget_class, "ideeditorsearchbar");
+
+ g_type_ensure (GD_TYPE_TAGGED_ENTRY);
+}
+
+static void
+ide_editor_search_bar_init (IdeEditorSearchBar *self)
+{
+ g_autoptr(GSimpleActionGroup) group = NULL;
+ static const gchar *proxy_names[] = {
+ "case-sensitive",
+ "at-word-boundaries",
+ "regex-enabled",
+ "wrap-around",
+ };
+
+ gtk_widget_init_template (GTK_WIDGET (self));
+
+ self->search_settings = gtk_source_search_settings_new ();
+
+ g_object_bind_property_full (self->search_entry, "text",
+ self->search_settings, "search-text",
+ G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL,
+ maybe_escape_regex, pacify_null_text,
+ self, NULL);
+
+ self->search_context_signals = dzl_signal_group_new (GTK_SOURCE_TYPE_SEARCH_CONTEXT);
+
+ dzl_signal_group_connect_swapped (self->search_context_signals,
+ "notify::occurrences-count",
+ G_CALLBACK (on_notify_occurrences_count),
+ self);
+
+ dzl_signal_group_connect_swapped (self->search_context_signals,
+ "notify::regex-error",
+ G_CALLBACK (on_notify_regex_error),
+ self);
+
+ g_signal_connect_object (self->search_settings,
+ "notify::search-text",
+ G_CALLBACK (on_notify_search_text),
+ self,
+ G_CONNECT_SWAPPED);
+
+ g_signal_connect_object (self->search_settings,
+ "notify::regex-enabled",
+ G_CALLBACK (on_notify_regex_enabled),
+ self,
+ G_CONNECT_SWAPPED);
+
+ group = g_simple_action_group_new ();
+
+ for (guint i = 0; i < G_N_ELEMENTS (proxy_names); i++)
+ {
+ g_autoptr(GPropertyAction) action = NULL;
+ const gchar *name = proxy_names[i];
+
+ action = g_property_action_new (name, self->search_settings, name);
+ g_action_map_add_action (G_ACTION_MAP (group), G_ACTION (action));
+ }
+
+ gtk_widget_insert_action_group (GTK_WIDGET (self), "search-entry", G_ACTION_GROUP (group));
+}
+
+GtkWidget *
+ide_editor_search_bar_new (void)
+{
+ return g_object_new (IDE_TYPE_EDITOR_SEARCH_BAR, NULL);
+}
+
+/**
+ * ide_editor_search_bar_get_buffer:
+ * @self: a #IdeEditorSearchBar
+ *
+ * Gets the buffer used by the search bar.
+ *
+ * Returns: (nullable) (transfer none): An #IdeBuffer or %NULL
+ *
+ * Since: 3.26
+ */
+IdeBuffer *
+ide_editor_search_bar_get_buffer (IdeEditorSearchBar *self)
+{
+ g_return_val_if_fail (IDE_IS_EDITOR_SEARCH_BAR (self), NULL);
+
+ return self->buffer;
+}
+
+/**
+ * ide_editor_search_bar_set_buffer:
+ * @self: a #IdeEditorSearchBar
+ *
+ * Sets the buffer used by the search bar.
+ *
+ * Since: 3.26
+ */
+void
+ide_editor_search_bar_set_buffer (IdeEditorSearchBar *self,
+ IdeBuffer *buffer)
+{
+ g_return_if_fail (IDE_IS_EDITOR_SEARCH_BAR (self));
+ g_return_if_fail (!buffer || IDE_IS_BUFFER (buffer));
+
+ if (ide_set_weak_pointer (&self->buffer, buffer))
+ {
+ g_clear_object (&self->search_context);
+ dzl_signal_group_set_target (self->search_context_signals, NULL);
+
+ if (buffer != NULL)
+ {
+ self->search_context = gtk_source_search_context_new (GTK_SOURCE_BUFFER (buffer),
+ self->search_settings);
+ dzl_signal_group_set_target (self->search_context_signals, self->search_context);
+ }
+
+ g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_BUFFER]);
+ }
+}
+
+/**
+ * ide_editor_search_bar_get_view:
+ * @self: a #IdeEditorSearchBar
+ *
+ * Gets the view used by the search bar.
+ *
+ * Returns: (nullable) (transfer none): An #IdeBuffer or %NULL
+ *
+ * Since: 3.26
+ */
+IdeSourceView *
+ide_editor_search_bar_get_view (IdeEditorSearchBar *self)
+{
+ g_return_val_if_fail (IDE_IS_EDITOR_SEARCH_BAR (self), NULL);
+
+ return self->view;
+}
+
+/**
+ * ide_editor_search_bar_set_view:
+ * @self: a #IdeEditorSearchBar
+ *
+ * Sets the view used by the search bar.
+ *
+ * Since: 3.26
+ */
+void
+ide_editor_search_bar_set_view (IdeEditorSearchBar *self,
+ IdeSourceView *view)
+{
+ g_return_if_fail (IDE_IS_EDITOR_SEARCH_BAR (self));
+ g_return_if_fail (!view || IDE_IS_SOURCE_VIEW (view));
+
+ if (ide_set_weak_pointer (&self->view, view))
+ g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_VIEW]);
+}
diff --git a/libide/editor/ide-editor-search-bar.h b/libide/editor/ide-editor-search-bar.h
new file mode 100644
index 0000000..6dd67ad
--- /dev/null
+++ b/libide/editor/ide-editor-search-bar.h
@@ -0,0 +1,40 @@
+/* ide-editor-search-bar.h
+ *
+ * Copyright (C) 2017 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 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/>.
+ */
+
+#pragma once
+
+#include <dazzle.h>
+
+#include "buffers/ide-buffer.h"
+#include "sourceview/ide-source-view.h"
+
+G_BEGIN_DECLS
+
+#define IDE_TYPE_EDITOR_SEARCH_BAR (ide_editor_search_bar_get_type())
+
+G_DECLARE_FINAL_TYPE (IdeEditorSearchBar, ide_editor_search_bar, IDE, EDITOR_SEARCH_BAR, DzlBin)
+
+GtkWidget *ide_editor_search_bar_new (void);
+IdeBuffer *ide_editor_search_bar_get_buffer (IdeEditorSearchBar *self);
+void ide_editor_search_bar_set_buffer (IdeEditorSearchBar *self,
+ IdeBuffer *buffer);
+IdeSourceView *ide_editor_search_bar_get_view (IdeEditorSearchBar *self);
+void ide_editor_search_bar_set_view (IdeEditorSearchBar *self,
+ IdeSourceView *view);
+
+G_END_DECLS
diff --git a/libide/editor/ide-editor-search-bar.ui b/libide/editor/ide-editor-search-bar.ui
new file mode 100644
index 0000000..7d6e39b
--- /dev/null
+++ b/libide/editor/ide-editor-search-bar.ui
@@ -0,0 +1,276 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <template class="IdeEditorSearchBar" parent="DzlBin">
+ <child>
+ <object class="GtkBox">
+ <property name="visible">true</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">7</property>
+ <child>
+ <object class="GtkGrid">
+ <property name="visible">true</property>
+ <property name="can_focus">false</property>
+ <property name="row_spacing">8</property>
+ <property name="column_spacing">8</property>
+ <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-chars">20</property>
+ <property name="max-width-chars">30</property>
+ <property name="primary_icon_name">edit-find-symbolic</property>
+ <property name="primary_icon_activatable">false</property>
+ <property name="primary_icon_sensitive">false</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSearchEntry" id="replace_entry">
+ <property name="visible">false</property>
+ <property name="can_focus">true</property>
+ <property name="width-chars">20</property>
+ <property name="max-width-chars">30</property>
+ <property name="primary_icon_name">edit-find-replace-symbolic</property>
+ <property name="primary_icon_activatable">false</property>
+ <property name="primary_icon_sensitive">false</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="homogeneous">true</property>
+ <property name="visible">true</property>
+ <property name="can_focus">false</property>
+ <property name="valign">center</property>
+ <style>
+ <class name="linked"/>
+ </style>
+ <child>
+ <object class="GtkButton">
+ <property name="action-name">frame.previous-search-result</property>
+ <property name="visible">true</property>
+ <property name="can_focus">false</property>
+ <property name="receives_default">true</property>
+ <child>
+ <object class="GtkImage">
+ <property name="visible">true</property>
+ <property name="can_focus">false</property>
+ <property name="icon_name">go-up-symbolic</property>
+ <property name="icon_size">1</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">false</property>
+ <property name="fill">true</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton">
+ <property name="action-name">frame.next-search-result</property>
+ <property name="visible">true</property>
+ <property name="can_focus">false</property>
+ <property name="receives_default">true</property>
+ <child>
+ <object class="GtkImage">
+ <property name="visible">true</property>
+ <property name="can_focus">false</property>
+ <property name="icon_name">go-down-symbolic</property>
+ <property name="icon_size">1</property>
+ </object>
+ </child>
+ </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">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="replace_button">
+ <property name="label" translatable="yes">Replace</property>
+ <property name="action-name">search-entry.replace</property>
+ <property name="visible">false</property>
+ <property name="can_focus">true</property>
+ <property name="receives_default">true</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="replace_all_button">
+ <property name="label" translatable="yes">Replace All</property>
+ <property name="action-name">search-entry.replace-all</property>
+ <property name="visible">false</property>
+ <property name="can_focus">true</property>
+ <property name="receives_default">true</property>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="homogeneous">true</property>
+ <property name="visible">true</property>
+ <property name="can_focus">false</property>
+ <property name="valign">center</property>
+ <property name="spacing">8</property>
+ <child>
+ <object class="GtkToggleButton">
+ <property name="action-name">search-entry.toggle-search-replace</property>
+ <property name="action-target">true</property>
+ <property name="tooltip-text" translatable="yes">Switch between Search and
Search-and-Replace</property>
+ <property name="visible">true</property>
+ <property name="can_focus">true</property>
+ <property name="receives_default">true</property>
+ <property name="image_position">right</property>
+ <child>
+ <object class="GtkImage">
+ <property name="visible">true</property>
+ <property name="can_focus">false</property>
+ <property name="icon_name">edit-find-replace-symbolic</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">false</property>
+ <property name="fill">true</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkToggleButton">
+ <property name="action-name">search-entry.toggle-search-options</property>
+ <property name="action-target">true</property>
+ <property name="tooltip-text" translatable="yes">Show or hide search options such as
case sensitivity</property>
+ <property name="visible">true</property>
+ <property name="can_focus">true</property>
+ <property name="receives_default">true</property>
+ <child>
+ <object class="GtkImage">
+ <property name="visible">true</property>
+ <property name="can_focus">false</property>
+ <property name="icon_name">emblem-system-symbolic</property>
+ </object>
+ </child>
+ </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">2</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="close_button">
+ <property name="visible">true</property>
+ <property name="action-name">search-entry.exit-search</property>
+ <property name="halign">center</property>
+ <property name="valign">center</property>
+ <property name="focus_on_click">false</property>
+ <style>
+ <class name="close"/>
+ </style>
+ <child>
+ <object class="GtkImage">
+ <property name="visible">true</property>
+ <property name="icon_name">window-close-symbolic</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">4</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">false</property>
+ <property name="fill">true</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkGrid" id="search_options">
+ <property name="visible">false</property>
+ <property name="can_focus">false</property>
+ <property name="column_spacing">8</property>
+ <child>
+ <object class="GtkCheckButton" id="use_regex">
+ <property name="action-name">search-entry.regex-enabled</property>
+ <property name="label" translatable="yes">Regular expressions</property>
+ <property name="visible">true</property>
+ <property name="can_focus">false</property>
+ <property name="receives_default">false</property>
+ <property name="xalign">0</property>
+ <property name="draw_indicator">true</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="case_sensitive">
+ <property name="action-name">search-entry.case-sensitive</property>
+ <property name="label" translatable="yes">Case sensitive</property>
+ <property name="visible">true</property>
+ <property name="can_focus">false</property>
+ <property name="receives_default">false</property>
+ <property name="xalign">0</property>
+ <property name="draw_indicator">true</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="whole_word">
+ <property name="action-name">search-entry.at-word-boundaries</property>
+ <property name="label" translatable="yes">Match whole word only</property>
+ <property name="visible">true</property>
+ <property name="can_focus">false</property>
+ <property name="receives_default">false</property>
+ <property name="xalign">0</property>
+ <property name="draw_indicator">true</property>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">false</property>
+ <property name="fill">true</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </template>
+</interface>
diff --git a/libide/editor/ide-editor-view-settings.c b/libide/editor/ide-editor-view-settings.c
index 9eb39f3..7c32684 100644
--- a/libide/editor/ide-editor-view-settings.c
+++ b/libide/editor/ide-editor-view-settings.c
@@ -21,6 +21,7 @@
#include "ide-editor-private.h"
static GSettings *editor_settings;
+static GSettings *insight_settings;
static gboolean
get_smart_home_end (GValue *value,
@@ -58,7 +59,7 @@ _ide_editor_view_init_settings (IdeEditorView *self)
if (editor_settings == NULL)
editor_settings = g_settings_new ("org.gnome.builder.editor");
- source_view = ide_editor_view_get_source_view (self);
+ source_view = ide_editor_view_get_view (self);
buffer = ide_editor_view_get_buffer (self);
g_settings_bind (editor_settings, "highlight-current-line",
@@ -114,4 +115,11 @@ _ide_editor_view_init_settings (IdeEditorView *self)
g_settings_bind (editor_settings, "auto-hide-map",
self, "auto-hide-map",
G_SETTINGS_BIND_GET);
+
+ if (insight_settings == NULL)
+ insight_settings = g_settings_new ("org.gnome.builder.code-insight");
+
+ g_settings_bind (insight_settings, "word-completion",
+ source_view, "enable-word-completion",
+ G_SETTINGS_BIND_GET);
}
diff --git a/libide/editor/ide-editor-view.c b/libide/editor/ide-editor-view.c
index 831d7bf..2fccfd4 100644
--- a/libide/editor/ide-editor-view.c
+++ b/libide/editor/ide-editor-view.c
@@ -22,35 +22,107 @@
#include <libpeas/peas.h>
#include "ide-editor-private.h"
+#include "ide-editor-search-bar.h"
#include "ide-editor-view.h"
#include "ide-editor-view-addin.h"
struct _IdeEditorView
{
- IdeLayoutView parent_instance;
+ IdeLayoutView parent_instance;
- PeasExtensionSet *addins;
+ PeasExtensionSet *addins;
- IdeBuffer *buffer;
- DzlBindingGroup *buffer_bindings;
- DzlSignalGroup *buffer_signals;
+ IdeBuffer *buffer;
+ DzlBindingGroup *buffer_bindings;
+ DzlSignalGroup *buffer_signals;
- GtkOverlay *overlay;
- IdeSourceView *source_view;
- GtkScrolledWindow *scroller;
+ GtkOverlay *overlay;
+ IdeSourceView *source_view;
+ GtkScrolledWindow *scroller;
+ IdeEditorSearchBar *search_bar;
+ GtkRevealer *search_revealer;
};
enum {
PROP_0,
PROP_BUFFER,
+ PROP_VIEW,
N_PROPS
};
+enum {
+ DND_TARGET_URI_LIST = 100,
+};
+
G_DEFINE_TYPE (IdeEditorView, ide_editor_view, IDE_TYPE_LAYOUT_VIEW)
static GParamSpec *properties [N_PROPS];
static void
+ide_editor_view_drag_data_received (IdeEditorView *self,
+ GdkDragContext *context,
+ gint x,
+ gint y,
+ GtkSelectionData *selection_data,
+ guint info,
+ guint timestamp,
+ IdeSourceView *source_view)
+{
+ g_auto(GStrv) uri_list = NULL;
+
+ g_assert (IDE_IS_EDITOR_VIEW (self));
+ g_assert (IDE_IS_SOURCE_VIEW (source_view));
+
+ switch (info)
+ {
+ case DND_TARGET_URI_LIST:
+ uri_list = dzl_dnd_get_uri_list (selection_data);
+
+ if (uri_list != NULL)
+ {
+ GVariantBuilder *builder;
+ GVariant *variant;
+ guint i;
+
+ 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);
+
+ /*
+ * request that we get focus first so the workbench will deliver the
+ * document to us in the case it is not already open
+ */
+ gtk_widget_grab_focus (GTK_WIDGET (self));
+ dzl_gtk_widget_action (GTK_WIDGET (self), "workbench", "open-uri-list", variant);
+ }
+
+ gtk_drag_finish (context, TRUE, FALSE, timestamp);
+ break;
+
+ default:
+ break;
+ }
+}
+
+static gboolean
+ide_editor_view_focus_in_event (IdeEditorView *self,
+ GdkEventFocus *focus,
+ IdeSourceView *source_view)
+{
+ g_assert (IDE_IS_EDITOR_VIEW (self));
+ g_assert (IDE_IS_SOURCE_VIEW (source_view));
+
+ gtk_revealer_set_reveal_child (self->search_revealer, FALSE);
+
+ if (self->buffer != NULL)
+ ide_buffer_check_for_volume_change (self->buffer);
+
+ return GDK_EVENT_PROPAGATE;
+}
+
+static void
ide_editor_view_buffer_modified_changed (IdeEditorView *self,
GtkSourceBuffer *buffer)
{
@@ -213,6 +285,16 @@ ide_editor_view_constructed (GObject *object)
_ide_editor_view_init_actions (self);
_ide_editor_view_init_shortcuts (self);
_ide_editor_view_init_settings (self);
+
+ g_signal_connect_swapped (self->source_view,
+ "drag-data-received",
+ G_CALLBACK (ide_editor_view_drag_data_received),
+ self);
+
+ g_signal_connect_swapped (self->source_view,
+ "focus-in-event",
+ G_CALLBACK (ide_editor_view_focus_in_event),
+ self);
}
static void
@@ -255,6 +337,10 @@ ide_editor_view_get_property (GObject *object,
g_value_set_object (value, ide_editor_view_get_buffer (self));
break;
+ case PROP_VIEW:
+ g_value_set_object (value, ide_editor_view_get_view (self));
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
@@ -302,17 +388,31 @@ ide_editor_view_class_init (IdeEditorViewClass *klass)
IDE_TYPE_BUFFER,
(G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
+ properties [PROP_VIEW] =
+ g_param_spec_object ("view",
+ "View",
+ "The view for editing the buffer",
+ IDE_TYPE_SOURCE_VIEW,
+ (G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+
g_object_class_install_properties (object_class, N_PROPS, properties);
gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/builder/ui/ide-editor-view.ui");
gtk_widget_class_bind_template_child (widget_class, IdeEditorView, overlay);
gtk_widget_class_bind_template_child (widget_class, IdeEditorView, scroller);
+ gtk_widget_class_bind_template_child (widget_class, IdeEditorView, search_bar);
+ gtk_widget_class_bind_template_child (widget_class, IdeEditorView, search_revealer);
gtk_widget_class_bind_template_child (widget_class, IdeEditorView, source_view);
+
+ g_type_ensure (IDE_TYPE_SOURCE_VIEW);
+ g_type_ensure (IDE_TYPE_EDITOR_SEARCH_BAR);
}
static void
ide_editor_view_init (IdeEditorView *self)
{
+ GtkTargetList *target_list;
+
gtk_widget_init_template (GTK_WIDGET (self));
ide_layout_view_set_can_split (IDE_LAYOUT_VIEW (self), TRUE);
@@ -343,6 +443,13 @@ ide_editor_view_init (IdeEditorView *self)
*/
self->buffer_bindings = dzl_binding_group_new ();
dzl_binding_group_bind (self->buffer_bindings, "title", self, "title", 0);
+
+ /*
+ * Setup Drag and Drop support.
+ */
+ target_list = gtk_drag_dest_get_target_list (GTK_WIDGET (self->source_view));
+ if (target_list != NULL)
+ gtk_target_list_add_uri_targets (target_list, DND_TARGET_URI_LIST);
}
/**
@@ -364,7 +471,7 @@ ide_editor_view_get_buffer (IdeEditorView *self)
}
/**
- * ide_editor_view_get_source_view:
+ * ide_editor_view_get_view:
* @self: a #IdeEditorView
*
* Gets the #IdeSourceView that is part of the #IdeEditorView.
@@ -374,7 +481,7 @@ ide_editor_view_get_buffer (IdeEditorView *self)
* Since: 3.26
*/
IdeSourceView *
-ide_editor_view_get_source_view (IdeEditorView *self)
+ide_editor_view_get_view (IdeEditorView *self)
{
g_return_val_if_fail (IDE_IS_EDITOR_VIEW (self), NULL);
diff --git a/libide/editor/ide-editor-view.h b/libide/editor/ide-editor-view.h
index 2e0a979..d7243fe 100644
--- a/libide/editor/ide-editor-view.h
+++ b/libide/editor/ide-editor-view.h
@@ -30,7 +30,7 @@ G_BEGIN_DECLS
G_DECLARE_FINAL_TYPE (IdeEditorView, ide_editor_view, IDE, EDITOR_VIEW, IdeLayoutView)
-IdeBuffer *ide_editor_view_get_buffer (IdeEditorView *self);
-IdeSourceView *ide_editor_view_get_source_view (IdeEditorView *self);
+IdeBuffer *ide_editor_view_get_buffer (IdeEditorView *self);
+IdeSourceView *ide_editor_view_get_view (IdeEditorView *self);
G_END_DECLS
diff --git a/libide/editor/ide-editor-view.ui b/libide/editor/ide-editor-view.ui
index 58a717f..f774973 100644
--- a/libide/editor/ide-editor-view.ui
+++ b/libide/editor/ide-editor-view.ui
@@ -4,6 +4,20 @@
<child>
<object class="GtkOverlay" id="overlay">
<property name="visible">true</property>
+ <child type="overlay">
+ <object class="GtkRevealer" id="search_revealer">
+ <property name="halign">end</property>
+ <property name="margin-right">24</property>
+ <property name="reveal-child">false</property>
+ <property name="valign">start</property>
+ <property name="visible">true</property>
+ <child>
+ <object class="IdeEditorSearchBar" id="search_bar">
+ <property name="visible">true</property>
+ </object>
+ </child>
+ </object>
+ </child>
<child>
<object class="GtkScrolledWindow" id="scroller">
<property name="visible">true</property>
diff --git a/libide/layout/ide-layout-grid.c b/libide/layout/ide-layout-grid.c
index c574738..751f0b7 100644
--- a/libide/layout/ide-layout-grid.c
+++ b/libide/layout/ide-layout-grid.c
@@ -23,14 +23,23 @@
typedef struct
{
+ /* Owned references */
DzlSignalGroup *toplevel_signals;
GQueue focus_column;
+
+ /*
+ * This unowned reference is simply used to compare to a new focus
+ * view to see if we have changed our current view. It is not to
+ * be used directly, only for pointer comparison.
+ */
+ IdeLayoutView *_last_focused_view;
} IdeLayoutGridPrivate;
enum {
PROP_0,
PROP_CURRENT_COLUMN,
PROP_CURRENT_STACK,
+ PROP_CURRENT_VIEW,
N_PROPS
};
@@ -110,12 +119,16 @@ ide_layout_grid_after_set_focus (IdeLayoutGrid *self,
GtkWidget *widget,
GtkWidget *toplevel)
{
+ IdeLayoutGridPrivate *priv = ide_layout_grid_get_instance_private (self);
+
g_assert (IDE_IS_LAYOUT_GRID (self));
g_assert (!widget || GTK_IS_WIDGET (widget));
g_assert (GTK_IS_WINDOW (toplevel));
if (widget != NULL)
{
+ GtkWidget *view;
+
if (gtk_widget_is_ancestor (widget, GTK_WIDGET (self)))
{
GtkWidget *column = gtk_widget_get_ancestor (widget, IDE_TYPE_LAYOUT_GRID_COLUMN);
@@ -123,6 +136,17 @@ ide_layout_grid_after_set_focus (IdeLayoutGrid *self,
if (column != NULL)
ide_layout_grid_set_current_column (self, IDE_LAYOUT_GRID_COLUMN (column));
}
+
+ /*
+ * self->_last_focused_view is an unowned reference, we only
+ * use it for pointer comparison, nothing more.
+ */
+ view = gtk_widget_get_ancestor (widget, IDE_TYPE_LAYOUT_VIEW);
+ if (view != (GtkWidget *)priv->_last_focused_view)
+ {
+ priv->_last_focused_view = (IdeLayoutView *)view;
+ g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_CURRENT_VIEW]);
+ }
}
}
@@ -339,16 +363,31 @@ ide_layout_grid_class_init (IdeLayoutGridClass *klass)
properties [PROP_CURRENT_STACK] =
g_param_spec_object ("current-stack",
"Current Stack",
- "The most recent focused IdeLayoutStack",
+ "The most recently focused IdeLayoutStack",
IDE_TYPE_LAYOUT_STACK,
- (G_PARAM_READABLE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS));
+ (G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+
+ properties [PROP_CURRENT_VIEW] =
+ g_param_spec_object ("current-view",
+ "Current View",
+ "The most recently focused IdeLayoutView",
+ IDE_TYPE_LAYOUT_VIEW,
+ (G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
g_object_class_install_properties (object_class, N_PROPS, properties);
gtk_widget_class_set_css_name (widget_class, "idelayoutgrid");
+ /**
+ * IdeLayoutGrid::create-stack:
+ * @self: an #IdeLayoutGrid
+ *
+ * Creates a new stack to be added to the grid.
+ *
+ * Returns: (transfer full): A newly created #IdeLayoutStack
+ */
signals [CREATE_STACK] =
- g_signal_new ("create-stack",
+ g_signal_new (g_intern_static_string ("create-stack"),
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (IdeLayoutGridClass, create_stack),
@@ -571,3 +610,87 @@ ide_layout_grid_set_current_column (IdeLayoutGrid *self,
g_warning ("%s does not contain %s",
G_OBJECT_TYPE_NAME (self), G_OBJECT_TYPE_NAME (column));
}
+
+/**
+ * ide_layout_grid_get_current_view:
+ * @self: a #IdeLayoutGrid
+ *
+ * Gets the most recent view used by the user as determined by tracking
+ * the window focus.
+ *
+ * Returns: (transfer none): An #IdeLayoutView or %NULL
+ *
+ * Since: 3.26
+ */
+IdeLayoutView *
+ide_layout_grid_get_current_view (IdeLayoutGrid *self)
+{
+ IdeLayoutStack *stack;
+
+ g_return_val_if_fail (IDE_IS_LAYOUT_GRID (self), NULL);
+
+ stack = ide_layout_grid_get_current_stack (self);
+
+ if (stack != NULL)
+ ide_layout_stack_get_visible_child (stack);
+
+ return NULL;
+}
+
+static void
+collect_views (GtkWidget *widget,
+ GPtrArray *ar)
+{
+ if (IDE_IS_LAYOUT_VIEW (widget))
+ g_ptr_array_add (ar, widget);
+}
+
+/**
+ * ide_layout_grid_foreach_view:
+ * @self: a #IdeLayoutGrid
+ * @callback: (scope call) (closure user_data): A callback for each view
+ * @user_data: user data for @callback
+ *
+ * This function will call @callback for every view found in @self.
+ *
+ * Since: 3.26
+ */
+void
+ide_layout_grid_foreach_view (IdeLayoutGrid *self,
+ GtkCallback callback,
+ gpointer user_data)
+{
+ g_autoptr(GPtrArray) views = NULL;
+ guint n_columns;
+
+ g_return_if_fail (IDE_IS_LAYOUT_GRID (self));
+ g_return_if_fail (callback != NULL);
+
+ views = g_ptr_array_new ();
+
+ n_columns = dzl_multi_paned_get_n_children (DZL_MULTI_PANED (self));
+
+ for (guint i = 0; i < n_columns; i++)
+ {
+ GtkWidget *column = dzl_multi_paned_get_nth_child (DZL_MULTI_PANED (self), i);
+ guint n_stacks;
+
+ g_assert (IDE_IS_LAYOUT_GRID_COLUMN (column));
+
+ n_stacks = dzl_multi_paned_get_n_children (DZL_MULTI_PANED (column));
+
+ for (guint j = 0; j < n_stacks; j++)
+ {
+ GtkWidget *stack = dzl_multi_paned_get_nth_child (DZL_MULTI_PANED (column), j);
+
+ g_assert (IDE_IS_LAYOUT_STACK (stack));
+
+ ide_layout_stack_foreach_view (IDE_LAYOUT_STACK (stack),
+ (GtkCallback) collect_views,
+ views);
+ }
+ }
+
+ for (guint i = 0; i < views->len; i++)
+ callback (g_ptr_array_index (views, i), user_data);
+}
diff --git a/libide/layout/ide-layout-grid.h b/libide/layout/ide-layout-grid.h
index 36eb512..53ba67e 100644
--- a/libide/layout/ide-layout-grid.h
+++ b/libide/layout/ide-layout-grid.h
@@ -22,6 +22,7 @@
#include "ide-layout-grid-column.h"
#include "ide-layout-stack.h"
+#include "ide-layout-view.h"
G_BEGIN_DECLS
@@ -50,5 +51,9 @@ IdeLayoutGridColumn *ide_layout_grid_get_current_column (IdeLayoutGrid *se
void ide_layout_grid_set_current_column (IdeLayoutGrid *self,
IdeLayoutGridColumn *column);
IdeLayoutStack *ide_layout_grid_get_current_stack (IdeLayoutGrid *self);
+IdeLayoutView *ide_layout_grid_get_current_view (IdeLayoutGrid *self);
+void ide_layout_grid_foreach_view (IdeLayoutGrid *self,
+ GtkCallback callback,
+ gpointer user_data);
G_END_DECLS
diff --git a/libide/layout/ide-layout-stack-header.c b/libide/layout/ide-layout-stack-header.c
index 82178cc..cc9dd56 100644
--- a/libide/layout/ide-layout-stack-header.c
+++ b/libide/layout/ide-layout-stack-header.c
@@ -415,6 +415,7 @@ ide_layout_stack_header_new (void)
* ide_layout_stack_header_add_custom_title:
* @self: a #IdeLayoutStackHeader
* @widget: A #GtkWidget
+ * @priority: the sort priority
*
* This will add @widget to the title area with @priority determining the
* sort order of the child.
diff --git a/libide/layout/ide-layout-stack-header.h b/libide/layout/ide-layout-stack-header.h
index 15ea9f0..5952836 100644
--- a/libide/layout/ide-layout-stack-header.h
+++ b/libide/layout/ide-layout-stack-header.h
@@ -30,7 +30,7 @@ GtkWidget *ide_layout_stack_header_new (void);
void ide_layout_stack_header_set_title (IdeLayoutStackHeader *self,
const gchar *title);
void ide_layout_stack_header_add_custom_title (IdeLayoutStackHeader *self,
- GtkWidget *custom_title,
+ GtkWidget *widget,
gint priority);
G_END_DECLS
diff --git a/libide/layout/ide-layout-stack.c b/libide/layout/ide-layout-stack.c
index ffb9e75..f5f30ac 100644
--- a/libide/layout/ide-layout-stack.c
+++ b/libide/layout/ide-layout-stack.c
@@ -821,3 +821,26 @@ _ide_layout_stack_transfer (IdeLayoutStack *self,
gtk_container_add (GTK_CONTAINER (dest_priv->stack), GTK_WIDGET (view));
g_object_unref (view);
}
+
+/**
+ * ide_layout_stack_foreach_view:
+ * @self: a #IdeLayoutStack
+ * @callback: (scope call) (closure user_data): A callback for each view
+ * @user_data: user data for @callback
+ *
+ * This function will call @callback for every view found in @self.
+ *
+ * Since: 3.26
+ */
+void
+ide_layout_stack_foreach_view (IdeLayoutStack *self,
+ GtkCallback callback,
+ gpointer user_data)
+{
+ IdeLayoutStackPrivate *priv = ide_layout_stack_get_instance_private (self);
+
+ g_return_if_fail (IDE_IS_LAYOUT_STACK (self));
+ g_return_if_fail (callback != NULL);
+
+ gtk_container_foreach (GTK_CONTAINER (priv->stack), callback, user_data);
+}
diff --git a/libide/layout/ide-layout-stack.h b/libide/layout/ide-layout-stack.h
index c487d09..68715f2 100644
--- a/libide/layout/ide-layout-stack.h
+++ b/libide/layout/ide-layout-stack.h
@@ -63,5 +63,8 @@ void ide_layout_stack_agree_to_close_async (IdeLayoutStack *sel
gboolean ide_layout_stack_agree_to_close_finish (IdeLayoutStack *self,
GAsyncResult *result,
GError **error);
+void ide_layout_stack_foreach_view (IdeLayoutStack *self,
+ GtkCallback callback,
+ gpointer user_data);
G_END_DECLS
diff --git a/libide/layout/ide-layout-view.c b/libide/layout/ide-layout-view.c
index ade87b0..3bcae94 100644
--- a/libide/layout/ide-layout-view.c
+++ b/libide/layout/ide-layout-view.c
@@ -249,6 +249,8 @@ ide_layout_view_class_init (IdeLayoutViewClass *klass)
*
* This signal will only be emitted when #IdeLayoutView:can-split is
* set to %TRUE. The default is %FALSE.
+ *
+ * Returns: (transfer full): A newly created #IdeLayoutView
*/
signals [CREATE_SPLIT_VIEW] =
g_signal_new (g_intern_static_string ("create-split-view"),
diff --git a/libide/layout/ide-layout.c b/libide/layout/ide-layout.c
index 44a047c..4a44458 100644
--- a/libide/layout/ide-layout.c
+++ b/libide/layout/ide-layout.c
@@ -16,121 +16,13 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "ide-layout.h"
-#include "ide-layout-pane.h"
-#include "ide-layout-view.h"
+#define G_LOG_DOMAIN "ide-layout"
-typedef struct
-{
- GtkWidget *active_view;
-
- gulong focus_handler;
-} IdeLayoutPrivate;
-
-G_DEFINE_TYPE_WITH_PRIVATE (IdeLayout, ide_layout, DZL_TYPE_DOCK_BIN)
-
-enum {
- PROP_0,
- PROP_ACTIVE_VIEW,
- LAST_PROP
-};
-
-static GParamSpec *properties [LAST_PROP];
-
-static void
-ide_layout_active_view_weak_cb (IdeLayout *self,
- GtkWidget *where_view_was)
-{
- IdeLayoutPrivate *priv = ide_layout_get_instance_private (self);
-
- g_assert (IDE_IS_LAYOUT (self));
-
- if (where_view_was == priv->active_view)
- {
- priv->active_view = NULL;
- g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_ACTIVE_VIEW]);
- }
-}
-
-static void
-ide_layout_set_active_view (IdeLayout *self,
- GtkWidget *active_view)
-{
- IdeLayoutPrivate *priv = ide_layout_get_instance_private (self);
-
- g_assert (IDE_IS_LAYOUT (self));
- g_assert (!active_view || GTK_IS_WIDGET (active_view));
-
- if (active_view != priv->active_view)
- {
- if (priv->active_view != NULL)
- {
- g_object_weak_unref (G_OBJECT (priv->active_view),
- (GWeakNotify)ide_layout_active_view_weak_cb,
- self);
- priv->active_view = NULL;
- }
-
- if (active_view != NULL)
- {
- priv->active_view = active_view;
- g_object_weak_ref (G_OBJECT (priv->active_view),
- (GWeakNotify)ide_layout_active_view_weak_cb,
- self);
- }
-
- g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_ACTIVE_VIEW]);
- }
-}
-
-static void
-ide_layout_toplevel_set_focus (IdeLayout *self,
- GtkWidget *widget,
- GtkWidget *toplevel)
-{
- g_assert (IDE_IS_LAYOUT (self));
-
- if (widget != NULL && !IDE_IS_LAYOUT_VIEW (widget))
- widget = gtk_widget_get_ancestor (widget, IDE_TYPE_LAYOUT_VIEW);
-
- if (widget != NULL)
- ide_layout_set_active_view (self, widget);
-}
+#include "layout/ide-layout.h"
+#include "layout/ide-layout-pane.h"
+#include "layout/ide-layout-view.h"
-static void
-ide_layout_hierarchy_changed (GtkWidget *widget,
- GtkWidget *old_toplevel)
-{
- IdeLayout *self = (IdeLayout *)widget;
- IdeLayoutPrivate *priv = ide_layout_get_instance_private (self);
- GtkWidget *toplevel;
-
- g_assert (IDE_IS_LAYOUT (self));
- g_assert (!old_toplevel || GTK_IS_WIDGET (old_toplevel));
-
- if ((old_toplevel != NULL) && (priv->focus_handler != 0))
- {
- g_signal_handler_disconnect (old_toplevel, priv->focus_handler);
- priv->focus_handler = 0;
-
- if (priv->active_view)
- {
- g_object_weak_unref (G_OBJECT (priv->active_view),
- (GWeakNotify)ide_layout_active_view_weak_cb,
- self);
- priv->active_view = NULL;
- }
- }
-
- toplevel = gtk_widget_get_toplevel (widget);
-
- if (GTK_IS_WINDOW (toplevel))
- priv->focus_handler =
- g_signal_connect_swapped (toplevel,
- "set-focus",
- G_CALLBACK (ide_layout_toplevel_set_focus),
- self);
-}
+G_DEFINE_TYPE (IdeLayout, ide_layout, DZL_TYPE_DOCK_BIN)
static GtkWidget *
ide_layout_create_edge (DzlDockBin *dock)
@@ -144,63 +36,14 @@ ide_layout_create_edge (DzlDockBin *dock)
}
static void
-ide_layout_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- IdeLayout *self = IDE_LAYOUT (object);
-
- switch (prop_id)
- {
- case PROP_ACTIVE_VIEW:
- g_value_set_object (value, ide_layout_get_active_view (self));
- break;
-
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
- }
-}
-
-static void
ide_layout_class_init (IdeLayoutClass *klass)
{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
- GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
DzlDockBinClass *dock_bin_class = DZL_DOCK_BIN_CLASS (klass);
- object_class->get_property = ide_layout_get_property;
-
- widget_class->hierarchy_changed = ide_layout_hierarchy_changed;
-
dock_bin_class->create_edge = ide_layout_create_edge;
-
- properties [PROP_ACTIVE_VIEW] =
- g_param_spec_object ("active-view",
- "Active View",
- "Active View",
- GTK_TYPE_WIDGET,
- (G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
-
- g_object_class_install_properties (object_class, LAST_PROP, properties);
}
static void
ide_layout_init (IdeLayout *self)
{
}
-
-/**
- * ide_layout_get_active_view:
- *
- * Returns: (transfer none) (nullable): An #IdeLayoutView or %NULL.
- */
-GtkWidget *
-ide_layout_get_active_view (IdeLayout *self)
-{
- IdeLayoutPrivate *priv = ide_layout_get_instance_private (self);
-
- g_return_val_if_fail (IDE_IS_LAYOUT (self), NULL);
-
- return priv->active_view;
-}
diff --git a/libide/layout/ide-layout.h b/libide/layout/ide-layout.h
index 50534ee..0b2154e 100644
--- a/libide/layout/ide-layout.h
+++ b/libide/layout/ide-layout.h
@@ -16,8 +16,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef IDE_LAYOUT_H
-#define IDE_LAYOUT_H
+#pragma once
#include <dazzle.h>
@@ -30,10 +29,15 @@ G_DECLARE_DERIVABLE_TYPE (IdeLayout, ide_layout, IDE, LAYOUT, DzlDockBin)
struct _IdeLayoutClass
{
DzlDockBinClass parent_class;
-};
-GtkWidget *ide_layout_get_active_view (IdeLayout *self);
+ gpointer _reserved1;
+ gpointer _reserved2;
+ gpointer _reserved3;
+ gpointer _reserved4;
+ gpointer _reserved5;
+ gpointer _reserved6;
+ gpointer _reserved7;
+ gpointer _reserved8;
+};
G_END_DECLS
-
-#endif /* IDE_LAYOUT_H */
diff --git a/libide/libide.gresource.xml b/libide/libide.gresource.xml
index 305a6db..ac4239e 100644
--- a/libide/libide.gresource.xml
+++ b/libide/libide.gresource.xml
@@ -32,6 +32,7 @@
<file compressed="true" alias="Arc-shared.css">../data/themes/Arc-shared.css</file>
<file compressed="true" alias="shared.css">../data/themes/shared.css</file>
+ <file compressed="true" alias="shared/shared-layout.css">../data/themes/shared/shared-layout.css</file>
</gresource>
<gresource prefix="/org/gnome/builder/modelines">
@@ -54,6 +55,7 @@
<file compressed="true" preprocess="xml-stripblanks"
alias="ide-layout-stack-header.ui">layout/ide-layout-stack-header.ui</file>
<file compressed="true" preprocess="xml-stripblanks"
alias="ide-layout-stack.ui">layout/ide-layout-stack.ui</file>
<file compressed="true" preprocess="xml-stripblanks"
alias="ide-editor-perspective.ui">editor/ide-editor-perspective.ui</file>
+ <file compressed="true" preprocess="xml-stripblanks"
alias="ide-editor-search-bar.ui">editor/ide-editor-search-bar.ui</file>
<file compressed="true" preprocess="xml-stripblanks"
alias="ide-editor-spell-widget.ui">spellcheck/ide-editor-spell-widget.ui</file>
<file compressed="true" preprocess="xml-stripblanks"
alias="ide-editor-view.ui">editor/ide-editor-view.ui</file>
<file compressed="true" preprocess="xml-stripblanks"
alias="ide-greeter-perspective.ui">greeter/ide-greeter-perspective.ui</file>
diff --git a/libide/meson.build b/libide/meson.build
index 8370103..fb14de0 100644
--- a/libide/meson.build
+++ b/libide/meson.build
@@ -459,10 +459,12 @@ libide_sources = libide_generated_headers + libide_public_sources + [
'editor/ide-editor-plugin.c',
'editor/ide-editor-print-operation.c',
'editor/ide-editor-print-operation.h',
+ 'editor/ide-editor-private.h',
+ 'editor/ide-editor-search-bar.c',
+ 'editor/ide-editor-search-bar.h',
'editor/ide-editor-view-actions.c',
'editor/ide-editor-view-settings.c',
'editor/ide-editor-view-shortcuts.c',
- 'editor/ide-editor-private.h',
'editor/ide-editor-workbench-addin.c',
'editor/ide-editor-workbench-addin.h',
'gconstructor.h',
@@ -480,7 +482,6 @@ libide_sources = libide_generated_headers + libide_public_sources + [
'keybindings/ide-keybindings.h',
'keybindings/ide-shortcuts-window.c',
'keybindings/ide-shortcuts-window.h',
- 'layout/ide-layout-grid-actions.c',
'layout/ide-layout-grid-column-actions.c',
'layout/ide-layout-private.h',
'layout/ide-layout-stack-actions.c',
diff --git a/plugins/beautifier/gb-beautifier-workbench-addin.c
b/plugins/beautifier/gb-beautifier-workbench-addin.c
index e8caf55..ebe90e9 100644
--- a/plugins/beautifier/gb-beautifier-workbench-addin.c
+++ b/plugins/beautifier/gb-beautifier-workbench-addin.c
@@ -71,7 +71,7 @@ view_activate_beautify_action_cb (GSimpleAction *action,
if (view == NULL || !IDE_IS_EDITOR_VIEW (view))
return;
- source_view = ide_editor_view_get_active_source_view (view);
+ source_view = ide_editor_view_get_view (view);
if (!GTK_SOURCE_IS_VIEW (source_view))
{
g_warning ("Beautifier Plugin: the view is not a GtkSourceView");
@@ -244,7 +244,7 @@ setup_view_cb (GtkWidget *widget,
g_object_set_data (G_OBJECT (view), "gb-beautifier-workbench-addin", self);
- source_view = ide_editor_view_get_active_source_view (view);
+ source_view = ide_editor_view_get_view (view);
g_signal_connect_object (source_view,
"populate-popup",
G_CALLBACK (view_populate_popup),
diff --git a/plugins/color-picker/gb-color-picker-prefs.c b/plugins/color-picker/gb-color-picker-prefs.c
index 2e68e53..8deb8a0 100644
--- a/plugins/color-picker/gb-color-picker-prefs.c
+++ b/plugins/color-picker/gb-color-picker-prefs.c
@@ -370,7 +370,7 @@ generate_palette_button_clicked_cb (GbColorPickerPrefs *self,
g_assert (GTK_IS_BUTTON (button));
view = IDE_EDITOR_VIEW (self->addin->active_view);
- buffer = GTK_TEXT_BUFFER (ide_editor_view_get_document (view));
+ buffer = GTK_TEXT_BUFFER (ide_editor_view_get_buffer (view));
palette = gstyle_palette_new_from_buffer (buffer, NULL, NULL, NULL, NULL);
if (palette != NULL)
diff --git a/plugins/color-picker/gb-color-picker-workbench-addin-private.h
b/plugins/color-picker/gb-color-picker-workbench-addin-private.h
index 96e1387..b35f302 100644
--- a/plugins/color-picker/gb-color-picker-workbench-addin-private.h
+++ b/plugins/color-picker/gb-color-picker-workbench-addin-private.h
@@ -30,7 +30,7 @@ struct _GbColorPickerWorkbenchAddin
GHashTable *views;
IdeWorkbench *workbench;
IdeEditorPerspective *editor;
- GtkWidget *active_view;
+ IdeLayoutView *active_view;
GtkWidget *dock;
GtkWidget *color_panel;
GbColorPickerPrefs *prefs;
diff --git a/plugins/color-picker/gb-color-picker-workbench-addin.c
b/plugins/color-picker/gb-color-picker-workbench-addin.c
index 3c70926..6bafdff 100644
--- a/plugins/color-picker/gb-color-picker-workbench-addin.c
+++ b/plugins/color-picker/gb-color-picker-workbench-addin.c
@@ -141,7 +141,7 @@ get_view_monitor (GbColorPickerWorkbenchAddin *self,
g_assert (GB_IS_COLOR_PICKER_WORKBENCH_ADDIN (self));
g_assert (IDE_IS_EDITOR_VIEW (view));
- buffer = ide_editor_view_get_document (view);
+ buffer = ide_editor_view_get_buffer (view);
if (buffer == NULL)
return NULL;
@@ -237,7 +237,7 @@ monitor_color_found_cb (GbColorPickerWorkbenchAddin *self,
if (self->active_view == NULL)
return;
- active_buffer = ide_editor_view_get_document (IDE_EDITOR_VIEW (self->active_view));
+ active_buffer = ide_editor_view_get_buffer (IDE_EDITOR_VIEW (self->active_view));
if (active_buffer != NULL && self->dock != NULL)
{
gstyle_color_fill_rgba (color, &rgba);
@@ -337,7 +337,7 @@ activate_color_picker_action_cb (GbColorPickerWorkbenchAddin *self,
else
init_dock (self);
- buffer = ide_editor_view_get_document (view);
+ buffer = ide_editor_view_get_buffer (view);
monitor = g_object_get_data (G_OBJECT (buffer), "monitor");
if (monitor == NULL)
{
@@ -460,30 +460,30 @@ gb_color_picker_workbench_addin_load (IdeWorkbenchAddin *addin,
IdeWorkbench *workbench)
{
GbColorPickerWorkbenchAddin *self = (GbColorPickerWorkbenchAddin *)addin;
- IdeLayout *layout;
+ IdeLayoutGrid *grid;
g_assert (GB_IS_COLOR_PICKER_WORKBENCH_ADDIN (addin));
g_assert (IDE_IS_WORKBENCH (workbench));
ide_set_weak_pointer (&self->workbench, workbench);
self->editor = IDE_EDITOR_PERSPECTIVE (ide_workbench_get_perspective_by_name (workbench, "editor"));
- layout = ide_editor_perspective_get_layout (self->editor);
+ grid = ide_editor_perspective_get_grid (self->editor);
ide_perspective_views_foreach (IDE_PERSPECTIVE (self->editor), (GtkCallback)setup_view_cb, self);
- self->active_view = ide_editor_perspective_get_active_view (self->editor);
+ self->active_view = ide_layout_grid_get_current_view (grid);
- g_signal_connect_object (self->editor,
+ g_signal_connect_object (grid,
"view-added",
G_CALLBACK (view_added_cb),
self,
G_CONNECT_SWAPPED);
- g_signal_connect_object (self->editor,
+ g_signal_connect_object (grid,
"view-removed",
G_CALLBACK (view_removed_cb),
self,
G_CONNECT_SWAPPED);
- g_signal_connect_object (layout,
- "notify::active-view",
+ g_signal_connect_object (grid,
+ "notify::current-view",
G_CALLBACK (active_view_changed_cb),
self,
G_CONNECT_SWAPPED);
diff --git a/plugins/comment-code/gbp-comment-code-view-addin.c
b/plugins/comment-code/gbp-comment-code-view-addin.c
index 18b6a27..3b8103f 100644
--- a/plugins/comment-code/gbp-comment-code-view-addin.c
+++ b/plugins/comment-code/gbp-comment-code-view-addin.c
@@ -280,8 +280,8 @@ gbp_comment_code_view_addin_comment_action (GSimpleAction *action,
g_assert (G_IS_SIMPLE_ACTION (action));
- buffer = GTK_TEXT_BUFFER (ide_editor_view_get_document (editor_view));
- source_view = ide_editor_view_get_active_source_view (editor_view);
+ buffer = GTK_TEXT_BUFFER (ide_editor_view_get_buffer (editor_view));
+ source_view = ide_editor_view_get_view (editor_view);
if (source_view == NULL || !GTK_SOURCE_IS_VIEW (source_view))
return;
diff --git a/plugins/project-tree/gb-project-tree-actions.c b/plugins/project-tree/gb-project-tree-actions.c
index 6039e5e..ca2b2ed 100644
--- a/plugins/project-tree/gb-project-tree-actions.c
+++ b/plugins/project-tree/gb-project-tree-actions.c
@@ -726,7 +726,7 @@ gb_project_tree_actions_close_views_cb (GtkWidget *widget,
{
IdeBuffer *buffer;
- buffer = ide_editor_view_get_document (IDE_EDITOR_VIEW (view));
+ buffer = ide_editor_view_get_buffer (IDE_EDITOR_VIEW (view));
if (buffer == removal->document)
removal->views = g_list_prepend (removal->views, g_object_ref (view));
diff --git a/plugins/project-tree/gb-project-tree-editor-addin.c
b/plugins/project-tree/gb-project-tree-editor-addin.c
index ce6960b..38f9539 100644
--- a/plugins/project-tree/gb-project-tree-editor-addin.c
+++ b/plugins/project-tree/gb-project-tree-editor-addin.c
@@ -63,7 +63,7 @@ gb_project_tree_editor_addin_reveal (GSimpleAction *action,
tree = g_object_get_data (G_OBJECT (workbench), "GB_PROJECT_TREE");
g_assert (GB_IS_PROJECT_TREE (tree));
- buffer = ide_editor_view_get_document (self->view);
+ buffer = ide_editor_view_get_buffer (self->view);
g_assert (IDE_IS_BUFFER (buffer));
ifile = ide_buffer_get_file (buffer);
diff --git a/plugins/quick-highlight/gbp-quick-highlight-view-addin.c
b/plugins/quick-highlight/gbp-quick-highlight-view-addin.c
index 70e3821..c57453e 100644
--- a/plugins/quick-highlight/gbp-quick-highlight-view-addin.c
+++ b/plugins/quick-highlight/gbp-quick-highlight-view-addin.c
@@ -103,7 +103,7 @@ gbp_quick_highlight_view_addin_match (GbpQuickHighlightViewAddin *self)
g_assert (GBP_IS_QUICK_HIGHLIGHT_VIEW_ADDIN (self));
- buffer = GTK_TEXT_BUFFER (ide_editor_view_get_document (self->editor_view));
+ buffer = GTK_TEXT_BUFFER (ide_editor_view_get_buffer (self->editor_view));
if (gtk_text_buffer_get_selection_bounds (buffer, &begin, &end))
{
@@ -200,7 +200,7 @@ gbp_quick_highlight_view_addin_enabled_changed (GbpQuickHighlightViewAddin *self
g_assert (GBP_IS_QUICK_HIGHLIGHT_VIEW_ADDIN (self));
g_assert (G_IS_SETTINGS (settings));
- buffer = ide_editor_view_get_document (self->editor_view);
+ buffer = ide_editor_view_get_buffer (self->editor_view);
enabled = g_settings_get_boolean (settings, "enabled");
if (!self->enabled && enabled)
@@ -235,7 +235,7 @@ gbp_quick_highlight_view_addin_load (IdeEditorViewAddin *addin,
self->editor_view = view;
- buffer = GTK_SOURCE_BUFFER (ide_editor_view_get_document (view));
+ buffer = GTK_SOURCE_BUFFER (ide_editor_view_get_buffer (view));
self->insert_mark = gtk_text_buffer_get_insert (GTK_TEXT_BUFFER (buffer));
@@ -300,7 +300,7 @@ gbp_quick_highlight_view_addin_unload (IdeEditorViewAddin *addin,
g_assert (GBP_IS_QUICK_HIGHLIGHT_VIEW_ADDIN (self));
- buffer = GTK_SOURCE_BUFFER (ide_editor_view_get_document (view));
+ buffer = GTK_SOURCE_BUFFER (ide_editor_view_get_buffer (view));
ide_clear_source (&self->queued_update);
diff --git a/plugins/retab/gbp-retab-view-addin.c b/plugins/retab/gbp-retab-view-addin.c
index 3d0e88a..8304a39 100644
--- a/plugins/retab/gbp-retab-view-addin.c
+++ b/plugins/retab/gbp-retab-view-addin.c
@@ -135,8 +135,8 @@ gbp_retab_view_addin_action (GSimpleAction *action,
g_assert (G_IS_SIMPLE_ACTION (action));
- buffer = GTK_TEXT_BUFFER (ide_editor_view_get_document (editor_view));
- source_view = ide_editor_view_get_active_source_view (editor_view);
+ buffer = GTK_TEXT_BUFFER (ide_editor_view_get_buffer (editor_view));
+ source_view = ide_editor_view_get_view (editor_view);
if (source_view == NULL || !GTK_SOURCE_IS_VIEW (source_view))
return;
diff --git a/plugins/symbol-tree/symbol-tree-panel.c b/plugins/symbol-tree/symbol-tree-panel.c
index 8480383..dfc8c90 100644
--- a/plugins/symbol-tree/symbol-tree-panel.c
+++ b/plugins/symbol-tree/symbol-tree-panel.c
@@ -152,7 +152,7 @@ refresh_tree (SymbolTreePanel *self)
if ((active_view = ide_editor_perspective_get_active_view (IDE_EDITOR_PERSPECTIVE (perspective))) &&
IDE_IS_EDITOR_VIEW (active_view))
{
- document = ide_editor_view_get_document (IDE_EDITOR_VIEW (active_view));
+ document = ide_editor_view_get_buffer (IDE_EDITOR_VIEW (active_view));
if (IDE_IS_BUFFER (document))
change_count = ide_buffer_get_change_count (IDE_BUFFER (document));
}
diff --git a/plugins/symbol-tree/symbol-tree.c b/plugins/symbol-tree/symbol-tree.c
index 287691c..768f530 100644
--- a/plugins/symbol-tree/symbol-tree.c
+++ b/plugins/symbol-tree/symbol-tree.c
@@ -53,7 +53,7 @@ notify_active_view_cb (SymbolTree *self,
GParamFlags *pspec,
IdeLayout *layout)
{
- GtkWidget *active_view;
+ IdeLayotuView *active_view = NULL;
IdeBuffer *buffer;
IDE_ENTRY;
@@ -72,10 +72,12 @@ notify_active_view_cb (SymbolTree *self,
ide_clear_weak_pointer (&self->buffer);
}
- active_view = ide_layout_get_active_view (layout);
+ if (IDE_IS_EDITOR_PERSPECTIVE (layout))
+ active_view = ide_editor_perspective_get_active_view (IDE_EDITOR_PERPSECTIVE (layout));
+
if (IDE_IS_EDITOR_VIEW (active_view))
{
- buffer = ide_editor_view_get_document (IDE_EDITOR_VIEW (active_view));
+ buffer = ide_editor_view_get_buffer (IDE_EDITOR_VIEW (active_view));
if (ide_buffer_get_symbol_resolver (buffer) == NULL)
{
ide_set_weak_pointer (&self->buffer, buffer);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]