643 lines
22 KiB
C
643 lines
22 KiB
C
/* ide-editor-page-actions.c
|
|
*
|
|
* Copyright 2017-2019 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/>.
|
|
*
|
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
|
*/
|
|
|
|
#define G_LOG_DOMAIN "ide-editor-page-actions"
|
|
|
|
#include "config.h"
|
|
|
|
#include <glib/gi18n.h>
|
|
#include <libide-code.h>
|
|
#include <libide-gui.h>
|
|
|
|
#include "ide-editor-surface.h"
|
|
#include "ide-editor-private.h"
|
|
#include "ide-editor-print-operation.h"
|
|
#include "ide-editor-settings-dialog.h"
|
|
|
|
typedef struct
|
|
{
|
|
IdeEditorPage *self;
|
|
guint line;
|
|
guint line_offset;
|
|
} ReloadState;
|
|
|
|
static void
|
|
reload_state_free (ReloadState *state)
|
|
{
|
|
g_clear_object (&state->self);
|
|
g_slice_free (ReloadState, state);
|
|
}
|
|
|
|
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ReloadState, reload_state_free)
|
|
|
|
static void
|
|
ide_editor_page_actions_reload_cb (GObject *object,
|
|
GAsyncResult *result,
|
|
gpointer user_data)
|
|
{
|
|
IdeBufferManager *bufmgr = (IdeBufferManager *)object;
|
|
g_autoptr(ReloadState) state = user_data;
|
|
g_autoptr(IdeBuffer) buffer = NULL;
|
|
g_autoptr(GError) error = NULL;
|
|
|
|
g_assert (IDE_IS_BUFFER_MANAGER (bufmgr));
|
|
g_assert (G_IS_ASYNC_RESULT (result));
|
|
g_assert (state != NULL);
|
|
g_assert (IDE_IS_EDITOR_PAGE (state->self));
|
|
|
|
if (state->self->progress_bar != NULL)
|
|
dzl_gtk_widget_hide_with_fade (GTK_WIDGET (state->self->progress_bar));
|
|
|
|
if (!(buffer = ide_buffer_manager_load_file_finish (bufmgr, result, &error)))
|
|
{
|
|
g_warning ("%s", error->message);
|
|
ide_page_report_error (IDE_PAGE (state->self),
|
|
/* translators: %s is the error message */
|
|
_("Failed to load file: %s"), error->message);
|
|
ide_page_set_failed (IDE_PAGE (state->self), TRUE);
|
|
}
|
|
else
|
|
{
|
|
IdeSourceView *view;
|
|
GtkTextIter iter;
|
|
|
|
view = ide_editor_page_get_view (state->self);
|
|
gtk_text_buffer_get_iter_at_line_offset (GTK_TEXT_BUFFER (buffer),
|
|
&iter,
|
|
state->line,
|
|
state->line_offset);
|
|
gtk_text_buffer_select_range (GTK_TEXT_BUFFER (buffer), &iter, &iter);
|
|
ide_source_view_scroll_to_iter (view,
|
|
&iter,
|
|
.25,
|
|
IDE_SOURCE_SCROLL_BOTH,
|
|
1.0,
|
|
0.5,
|
|
FALSE);
|
|
|
|
}
|
|
|
|
gtk_revealer_set_reveal_child (state->self->modified_revealer, FALSE);
|
|
}
|
|
|
|
static void
|
|
ide_editor_page_actions_reload (GSimpleAction *action,
|
|
GVariant *param,
|
|
gpointer user_data)
|
|
{
|
|
IdeEditorPage *self = user_data;
|
|
g_autoptr(IdeNotification) notif = NULL;
|
|
g_autoptr(IdeContext) context = NULL;
|
|
IdeBufferManager *bufmgr;
|
|
ReloadState *state;
|
|
GtkTextIter iter;
|
|
IdeBuffer *buffer;
|
|
GFile *file;
|
|
|
|
g_assert (IDE_IS_EDITOR_PAGE (self));
|
|
|
|
buffer = ide_editor_page_get_buffer (self);
|
|
context = ide_buffer_ref_context (buffer);
|
|
bufmgr = ide_buffer_manager_from_context (context);
|
|
file = ide_buffer_get_file (buffer);
|
|
|
|
gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (self->progress_bar), 0.0);
|
|
gtk_widget_show (GTK_WIDGET (self->progress_bar));
|
|
|
|
notif = ide_notification_new ();
|
|
|
|
ide_buffer_get_selection_bounds (buffer, &iter, NULL);
|
|
|
|
state = g_slice_new0 (ReloadState);
|
|
state->self = g_object_ref (self);
|
|
state->line = gtk_text_iter_get_line (&iter);
|
|
state->line_offset = gtk_text_iter_get_line_offset (&iter);
|
|
|
|
ide_buffer_manager_load_file_async (bufmgr,
|
|
file,
|
|
IDE_BUFFER_OPEN_FLAGS_FORCE_RELOAD,
|
|
notif,
|
|
NULL,
|
|
ide_editor_page_actions_reload_cb,
|
|
g_steal_pointer (&state));
|
|
|
|
g_object_bind_property (notif, "progress",
|
|
self->progress_bar, "fraction",
|
|
G_BINDING_SYNC_CREATE);
|
|
}
|
|
|
|
static void
|
|
handle_print_result (IdeEditorPage *self,
|
|
GtkPrintOperation *operation,
|
|
GtkPrintOperationResult result)
|
|
{
|
|
g_assert (IDE_IS_EDITOR_PAGE (self));
|
|
g_assert (GTK_IS_PRINT_OPERATION (operation));
|
|
|
|
if (result == GTK_PRINT_OPERATION_RESULT_ERROR)
|
|
{
|
|
g_autoptr(GError) error = NULL;
|
|
|
|
gtk_print_operation_get_error (operation, &error);
|
|
|
|
g_warning ("%s", error->message);
|
|
ide_page_report_error (IDE_PAGE (self),
|
|
/* translators: %s is the error message */
|
|
_("Print failed: %s"), error->message);
|
|
}
|
|
}
|
|
|
|
static void
|
|
print_done (GtkPrintOperation *operation,
|
|
GtkPrintOperationResult result,
|
|
gpointer user_data)
|
|
{
|
|
IdeEditorPage *self = user_data;
|
|
|
|
g_assert (GTK_IS_PRINT_OPERATION (operation));
|
|
g_assert (IDE_IS_EDITOR_PAGE (self));
|
|
|
|
handle_print_result (self, operation, result);
|
|
|
|
g_object_unref (operation);
|
|
g_object_unref (self);
|
|
}
|
|
|
|
static void
|
|
ide_editor_page_actions_print (GSimpleAction *action,
|
|
GVariant *param,
|
|
gpointer user_data)
|
|
{
|
|
g_autoptr(IdeEditorPrintOperation) operation = NULL;
|
|
IdeEditorPage *self = user_data;
|
|
IdeSourceView *source_view;
|
|
GtkWidget *toplevel;
|
|
GtkPrintOperationResult result;
|
|
|
|
g_assert (IDE_IS_EDITOR_PAGE (self));
|
|
|
|
toplevel = gtk_widget_get_ancestor (GTK_WIDGET (self), GTK_TYPE_WINDOW);
|
|
|
|
source_view = ide_editor_page_get_view (self);
|
|
operation = ide_editor_print_operation_new (source_view);
|
|
|
|
/* keep a ref until "done" is emitted */
|
|
g_object_ref (operation);
|
|
g_signal_connect_after (g_object_ref (operation),
|
|
"done",
|
|
G_CALLBACK (print_done),
|
|
g_object_ref (self));
|
|
|
|
result = gtk_print_operation_run (GTK_PRINT_OPERATION (operation),
|
|
GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG,
|
|
GTK_WINDOW (toplevel),
|
|
NULL);
|
|
|
|
handle_print_result (self, GTK_PRINT_OPERATION (operation), result);
|
|
}
|
|
|
|
static void
|
|
ide_editor_page_actions_save_cb (GObject *object,
|
|
GAsyncResult *result,
|
|
gpointer user_data)
|
|
{
|
|
IdeBuffer *buffer = (IdeBuffer *)object;
|
|
g_autoptr(IdeEditorPage) self = user_data;
|
|
g_autoptr(GError) error = NULL;
|
|
|
|
g_assert (IDE_IS_BUFFER (buffer));
|
|
g_assert (G_IS_ASYNC_RESULT (result));
|
|
g_assert (IDE_IS_EDITOR_PAGE (self));
|
|
|
|
if (!ide_buffer_save_file_finish (buffer, result, &error))
|
|
{
|
|
g_warning ("%s", error->message);
|
|
ide_page_report_error (IDE_PAGE (self),
|
|
/* translators: %s is the error message */
|
|
_("Failed to save file: %s"), error->message);
|
|
ide_page_set_failed (IDE_PAGE (self), TRUE);
|
|
}
|
|
|
|
if (self->progress_bar != NULL)
|
|
dzl_gtk_widget_hide_with_fade (GTK_WIDGET (self->progress_bar));
|
|
}
|
|
|
|
static void
|
|
ide_editor_page_actions_save (GSimpleAction *action,
|
|
GVariant *variant,
|
|
gpointer user_data)
|
|
{
|
|
IdeEditorPage *self = user_data;
|
|
g_autoptr(IdeNotification) notif = NULL;
|
|
g_autoptr(IdeContext) context = NULL;
|
|
g_autoptr(GFile) local_file = NULL;
|
|
g_autoptr(GFile) workdir = NULL;
|
|
IdeBuffer *buffer;
|
|
GFile *file;
|
|
|
|
g_assert (G_IS_SIMPLE_ACTION (action));
|
|
g_assert (IDE_IS_EDITOR_PAGE (self));
|
|
|
|
buffer = ide_editor_page_get_buffer (self);
|
|
g_return_if_fail (IDE_IS_BUFFER (buffer));
|
|
|
|
context = ide_buffer_ref_context (buffer);
|
|
g_return_if_fail (IDE_IS_CONTEXT (context));
|
|
|
|
file = ide_buffer_get_file (buffer);
|
|
g_return_if_fail (G_IS_FILE (file));
|
|
|
|
workdir = ide_context_ref_workdir (context);
|
|
g_assert (G_IS_FILE (workdir));
|
|
|
|
if (ide_buffer_get_is_temporary (buffer))
|
|
{
|
|
GtkFileChooserNative *dialog;
|
|
GtkWidget *toplevel;
|
|
gint ret;
|
|
|
|
toplevel = gtk_widget_get_ancestor (GTK_WIDGET (self), GTK_TYPE_WINDOW);
|
|
|
|
dialog = gtk_file_chooser_native_new (_("Save File"),
|
|
GTK_WINDOW (toplevel),
|
|
GTK_FILE_CHOOSER_ACTION_SAVE,
|
|
_("Save"), _("Cancel"));
|
|
|
|
g_object_set (dialog,
|
|
"do-overwrite-confirmation", TRUE,
|
|
"local-only", FALSE,
|
|
"modal", TRUE,
|
|
"select-multiple", FALSE,
|
|
"show-hidden", FALSE,
|
|
NULL);
|
|
|
|
gtk_file_chooser_set_current_folder_file (GTK_FILE_CHOOSER (dialog), workdir, NULL);
|
|
|
|
ret = gtk_native_dialog_run (GTK_NATIVE_DIALOG (dialog));
|
|
|
|
if (ret == GTK_RESPONSE_ACCEPT)
|
|
file = local_file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (dialog));
|
|
|
|
gtk_native_dialog_destroy (GTK_NATIVE_DIALOG (dialog));
|
|
|
|
if (local_file == NULL)
|
|
return;
|
|
}
|
|
|
|
ide_buffer_save_file_async (buffer,
|
|
file,
|
|
NULL,
|
|
¬if,
|
|
ide_editor_page_actions_save_cb,
|
|
g_object_ref (self));
|
|
|
|
g_object_bind_property (notif, "progress", self->progress_bar, "fraction",
|
|
G_BINDING_SYNC_CREATE);
|
|
|
|
gtk_widget_show (GTK_WIDGET (self->progress_bar));
|
|
}
|
|
|
|
|
|
static void
|
|
ide_editor_page_actions_save_as_cb (GObject *object,
|
|
GAsyncResult *result,
|
|
gpointer user_data)
|
|
{
|
|
IdeBuffer *buffer = (IdeBuffer *)object;
|
|
g_autoptr(IdeEditorPage) self = user_data;
|
|
g_autoptr(GError) error = NULL;
|
|
|
|
g_assert (IDE_IS_BUFFER (buffer));
|
|
g_assert (G_IS_ASYNC_RESULT (result));
|
|
g_assert (IDE_IS_EDITOR_PAGE (self));
|
|
|
|
if (!ide_buffer_save_file_finish (buffer, result, &error))
|
|
{
|
|
/* In this case, the editor page hasn't failed since this is for an
|
|
* alternate file (which maybe we just don't have access to on the
|
|
* network or something).
|
|
*
|
|
* But we do still need to notify the user of the error.
|
|
*/
|
|
g_warning ("%s", error->message);
|
|
ide_page_report_error (IDE_PAGE (self),
|
|
/* translators: %s is the underlying error message */
|
|
_("Failed to save file: %s"),
|
|
error->message);
|
|
}
|
|
|
|
dzl_gtk_widget_hide_with_fade (GTK_WIDGET (self->progress_bar));
|
|
}
|
|
|
|
static void
|
|
ide_editor_page_actions_save_as (GSimpleAction *action,
|
|
GVariant *param,
|
|
gpointer user_data)
|
|
{
|
|
IdeEditorPage *self = user_data;
|
|
GtkFileChooserNative *dialog;
|
|
IdeBuffer *buffer;
|
|
GtkWidget *toplevel;
|
|
GFile *file;
|
|
gint ret;
|
|
|
|
g_assert (IDE_IS_EDITOR_PAGE (self));
|
|
|
|
buffer = ide_editor_page_get_buffer (self);
|
|
file = ide_buffer_get_file (buffer);
|
|
|
|
/* Just redirect to the save flow if we have a temporary
|
|
* file currently. That way we can avoid splitting the
|
|
* flow to handle both cases here.
|
|
*/
|
|
if (ide_buffer_get_is_temporary (buffer))
|
|
{
|
|
ide_editor_page_actions_save (action, NULL, user_data);
|
|
return;
|
|
}
|
|
|
|
toplevel = gtk_widget_get_ancestor (GTK_WIDGET (self), GTK_TYPE_WINDOW);
|
|
dialog = gtk_file_chooser_native_new (_("Save a Copy"),
|
|
GTK_WINDOW (toplevel),
|
|
GTK_FILE_CHOOSER_ACTION_SAVE,
|
|
_("Save"),
|
|
_("Cancel"));
|
|
|
|
gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (dialog), TRUE);
|
|
gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (dialog), FALSE);
|
|
gtk_file_chooser_set_show_hidden (GTK_FILE_CHOOSER (dialog), FALSE);
|
|
|
|
if (file != NULL)
|
|
gtk_file_chooser_set_file (GTK_FILE_CHOOSER (dialog), file, NULL);
|
|
|
|
ret = gtk_native_dialog_run (GTK_NATIVE_DIALOG (dialog));
|
|
|
|
if (ret == GTK_RESPONSE_ACCEPT)
|
|
{
|
|
g_autoptr(GFile) save_as = NULL;
|
|
g_autoptr(IdeNotification) notif = NULL;
|
|
|
|
save_as = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (dialog));
|
|
|
|
ide_buffer_save_file_async (buffer,
|
|
save_as,
|
|
NULL,
|
|
¬if,
|
|
ide_editor_page_actions_save_as_cb,
|
|
g_object_ref (self));
|
|
|
|
g_object_bind_property (notif, "progress", self->progress_bar, "fraction",
|
|
G_BINDING_SYNC_CREATE);
|
|
|
|
gtk_widget_show (GTK_WIDGET (self->progress_bar));
|
|
}
|
|
|
|
gtk_native_dialog_destroy (GTK_NATIVE_DIALOG (dialog));
|
|
}
|
|
|
|
static void
|
|
ide_editor_page_actions_find (GSimpleAction *action,
|
|
GVariant *variant,
|
|
gpointer user_data)
|
|
{
|
|
IdeEditorPage *self = user_data;
|
|
GtkTextIter begin;
|
|
GtkTextIter end;
|
|
|
|
g_assert (G_IS_SIMPLE_ACTION (action));
|
|
g_assert (IDE_IS_EDITOR_PAGE (self));
|
|
|
|
if (gtk_text_buffer_get_selection_bounds (GTK_TEXT_BUFFER (self->buffer), &begin, &end))
|
|
{
|
|
g_autofree gchar *word = gtk_text_iter_get_slice (&begin, &end);
|
|
ide_editor_search_set_search_text (self->search, word);
|
|
}
|
|
|
|
ide_editor_search_bar_set_replace_mode (self->search_bar, FALSE);
|
|
gtk_revealer_set_reveal_child (self->search_revealer, TRUE);
|
|
gtk_widget_grab_focus (GTK_WIDGET (self->search_bar));
|
|
}
|
|
|
|
static void
|
|
ide_editor_page_actions_find_replace (GSimpleAction *action,
|
|
GVariant *variant,
|
|
gpointer user_data)
|
|
{
|
|
IdeEditorPage *self = user_data;
|
|
GtkTextIter begin;
|
|
GtkTextIter end;
|
|
|
|
g_assert (G_IS_SIMPLE_ACTION (action));
|
|
g_assert (IDE_IS_EDITOR_PAGE (self));
|
|
|
|
if (gtk_text_buffer_get_selection_bounds (GTK_TEXT_BUFFER (self->buffer), &begin, &end))
|
|
{
|
|
g_autofree gchar *word = gtk_text_iter_get_slice (&begin, &end);
|
|
ide_editor_search_set_search_text (self->search, word);
|
|
}
|
|
|
|
ide_editor_search_bar_set_replace_mode (self->search_bar, TRUE);
|
|
gtk_revealer_set_reveal_child (self->search_revealer, TRUE);
|
|
gtk_widget_grab_focus (GTK_WIDGET (self->search_bar));
|
|
}
|
|
|
|
static void
|
|
ide_editor_page_actions_hide_search (GSimpleAction *action,
|
|
GVariant *variant,
|
|
gpointer user_data)
|
|
{
|
|
IdeEditorPage *self = user_data;
|
|
|
|
g_assert (G_IS_SIMPLE_ACTION (action));
|
|
g_assert (IDE_IS_EDITOR_PAGE (self));
|
|
|
|
gtk_revealer_set_reveal_child (self->search_revealer, FALSE);
|
|
gtk_widget_grab_focus (GTK_WIDGET (self->source_view));
|
|
}
|
|
|
|
static void
|
|
ide_editor_page_actions_notify_file_settings (IdeEditorPage *self,
|
|
GParamSpec *pspec,
|
|
IdeSourceView *source_view)
|
|
{
|
|
IdeFileSettings *file_settings;
|
|
GActionGroup *group;
|
|
|
|
g_assert (IDE_IS_EDITOR_PAGE (self));
|
|
g_assert (IDE_IS_SOURCE_VIEW (source_view));
|
|
|
|
group = gtk_widget_get_action_group (GTK_WIDGET (self), "file-settings");
|
|
g_assert (DZL_IS_PROPERTIES_GROUP (group));
|
|
|
|
file_settings = ide_source_view_get_file_settings (source_view);
|
|
g_assert (!file_settings || IDE_IS_FILE_SETTINGS (file_settings));
|
|
|
|
g_object_set (group, "object", file_settings, NULL);
|
|
}
|
|
|
|
static void
|
|
ide_editor_page_actions_move_next_error (GSimpleAction *action,
|
|
GVariant *variant,
|
|
gpointer user_data)
|
|
{
|
|
ide_editor_page_move_next_error (user_data);
|
|
}
|
|
|
|
static void
|
|
ide_editor_page_actions_move_previous_error (GSimpleAction *action,
|
|
GVariant *variant,
|
|
gpointer user_data)
|
|
{
|
|
ide_editor_page_move_previous_error (user_data);
|
|
}
|
|
|
|
static void
|
|
ide_editor_page_actions_activate_next_search_result (GSimpleAction *action,
|
|
GVariant *variant,
|
|
gpointer user_data)
|
|
{
|
|
IdeEditorPage *self = user_data;
|
|
GtkTextIter begin;
|
|
GtkTextIter end;
|
|
|
|
g_assert (IDE_IS_EDITOR_PAGE (self));
|
|
|
|
ide_editor_page_move_next_search_result (self);
|
|
|
|
gtk_text_buffer_get_selection_bounds (GTK_TEXT_BUFFER (self->buffer), &begin, &end);
|
|
gtk_widget_grab_focus (GTK_WIDGET (self->source_view));
|
|
gtk_text_buffer_select_range (GTK_TEXT_BUFFER (self->buffer), &begin, &end);
|
|
ide_source_view_scroll_to_insert (self->source_view);
|
|
}
|
|
|
|
static void
|
|
ide_editor_page_actions_move_next_search_result (GSimpleAction *action,
|
|
GVariant *variant,
|
|
gpointer user_data)
|
|
{
|
|
ide_editor_page_move_next_search_result (user_data);
|
|
}
|
|
|
|
static void
|
|
ide_editor_page_actions_move_previous_search_result (GSimpleAction *action,
|
|
GVariant *variant,
|
|
gpointer user_data)
|
|
{
|
|
ide_editor_page_move_previous_search_result (user_data);
|
|
}
|
|
|
|
static void
|
|
ide_editor_page_actions_properties (GSimpleAction *action,
|
|
GVariant *variant,
|
|
gpointer user_data)
|
|
{
|
|
IdeEditorPage *self = user_data;
|
|
IdeEditorSettingsDialog *dialog;
|
|
|
|
g_assert (IDE_IS_EDITOR_PAGE (self));
|
|
|
|
dialog = ide_editor_settings_dialog_new (self);
|
|
g_signal_connect (dialog, "response", G_CALLBACK (gtk_widget_destroy), NULL);
|
|
ide_gtk_window_present (GTK_WINDOW (dialog));
|
|
}
|
|
|
|
static void
|
|
ide_editor_page_actions_toggle_map (GSimpleAction *action,
|
|
GVariant *variant,
|
|
gpointer user_data)
|
|
{
|
|
IdeEditorPage *self = user_data;
|
|
|
|
g_assert (G_IS_SIMPLE_ACTION (action));
|
|
g_assert (IDE_IS_EDITOR_PAGE (self));
|
|
|
|
ide_editor_page_set_show_map (self, !ide_editor_page_get_show_map (self));
|
|
}
|
|
|
|
static const GActionEntry editor_view_entries[] = {
|
|
{ "activate-next-search-result", ide_editor_page_actions_activate_next_search_result },
|
|
{ "find", ide_editor_page_actions_find },
|
|
{ "find-replace", ide_editor_page_actions_find_replace },
|
|
{ "hide-search", ide_editor_page_actions_hide_search },
|
|
{ "move-next-error", ide_editor_page_actions_move_next_error },
|
|
{ "move-next-search-result", ide_editor_page_actions_move_next_search_result },
|
|
{ "move-previous-error", ide_editor_page_actions_move_previous_error },
|
|
{ "move-previous-search-result", ide_editor_page_actions_move_previous_search_result },
|
|
{ "properties", ide_editor_page_actions_properties },
|
|
{ "print", ide_editor_page_actions_print },
|
|
{ "reload", ide_editor_page_actions_reload },
|
|
{ "save", ide_editor_page_actions_save },
|
|
{ "save-as", ide_editor_page_actions_save_as },
|
|
{ "toggle-map", ide_editor_page_actions_toggle_map },
|
|
};
|
|
|
|
void
|
|
_ide_editor_page_init_actions (IdeEditorPage *self)
|
|
{
|
|
g_autoptr(GSimpleActionGroup) group = NULL;
|
|
g_autoptr(DzlPropertiesGroup) sv_props = NULL;
|
|
g_autoptr(DzlPropertiesGroup) file_props = NULL;
|
|
IdeSourceView *source_view;
|
|
|
|
g_return_if_fail (IDE_IS_EDITOR_PAGE (self));
|
|
|
|
source_view = ide_editor_page_get_view (self);
|
|
|
|
/* Setup our user-facing actions */
|
|
group = g_simple_action_group_new ();
|
|
g_action_map_add_action_entries (G_ACTION_MAP (group),
|
|
editor_view_entries,
|
|
G_N_ELEMENTS (editor_view_entries),
|
|
self);
|
|
gtk_widget_insert_action_group (GTK_WIDGET (self), "editor-page", G_ACTION_GROUP (group));
|
|
|
|
/* We want to access some settings properties as stateful GAction so they
|
|
* manipulated using regular Gtk widgets from the properties panel.
|
|
*/
|
|
sv_props = dzl_properties_group_new (G_OBJECT (source_view));
|
|
dzl_properties_group_add_all_properties (sv_props);
|
|
dzl_properties_group_add_property_full (sv_props,
|
|
"use-spaces",
|
|
"insert-spaces-instead-of-tabs",
|
|
DZL_PROPERTIES_FLAGS_STATEFUL_BOOLEANS);
|
|
gtk_widget_insert_action_group (GTK_WIDGET (self), "source-view", G_ACTION_GROUP (sv_props));
|
|
|
|
/*
|
|
* We want to bind our file-settings, used to tweak values in the
|
|
* source-view, to a GActionGroup that can be manipulated by the properties
|
|
* editor. Make sure we get notified of changes and sink the current state.
|
|
*/
|
|
file_props = dzl_properties_group_new_for_type (IDE_TYPE_FILE_SETTINGS);
|
|
dzl_properties_group_add_all_properties (file_props);
|
|
g_signal_connect_swapped (source_view,
|
|
"notify::file-settings",
|
|
G_CALLBACK (ide_editor_page_actions_notify_file_settings),
|
|
self);
|
|
gtk_widget_insert_action_group (GTK_WIDGET (self), "file-settings", G_ACTION_GROUP (file_props));
|
|
ide_editor_page_actions_notify_file_settings (self, NULL, source_view);
|
|
}
|
|
|
|
void
|
|
_ide_editor_page_update_actions (IdeEditorPage *self)
|
|
{
|
|
g_return_if_fail (IDE_IS_EDITOR_PAGE (self));
|
|
|
|
}
|