/** * ide_editor_perspective_get_utilities: * * Returns: (transfer none): An #IdeEditorUtilities */ GtkWidget * ide_editor_perspective_get_utilities (IdeEditorPerspective *self) { g_return_val_if_fail (IDE_IS_EDITOR_PERSPECTIVE (self), NULL); return dzl_dock_bin_get_bottom_edge (DZL_DOCK_BIN (self)); }
/** * ide_editor_perspective_get_transient_sidebar: * @self: a #IdeEditorPerspective * * Gets the transient sidebar for the editor perspective. * * The transient sidebar is a sidebar on the right side of the perspective. It * is displayed only when necessary. It animates in and out of view based on * focus tracking and other heuristics. * * Returns: (transfer none): An #IdeLayoutTransientSidebar * * Since: 3.26 */ IdeLayoutTransientSidebar * ide_editor_perspective_get_transient_sidebar (IdeEditorPerspective *self) { g_return_val_if_fail (IDE_IS_EDITOR_PERSPECTIVE (self), NULL); return IDE_LAYOUT_TRANSIENT_SIDEBAR (dzl_dock_bin_get_right_edge (DZL_DOCK_BIN (self))); }
/** * ide_editor_perspective_get_grid: * @self: a #IdeEditorPerspective * * Gets the grid for the perspective. This is the area containing * grid columns, stacks, and views. * * Returns: (transfer none): An #IdeLayoutGrid. * * Since: 3.26 */ IdeLayoutGrid * ide_editor_perspective_get_grid (IdeEditorPerspective *self) { g_return_val_if_fail (IDE_IS_EDITOR_PERSPECTIVE (self), NULL); return self->grid; }
static void ide_editor_perspective_focus_location_cb (GObject *object, GAsyncResult *result, gpointer user_data) { IdeBufferManager *bufmgr = (IdeBufferManager *)object; FocusLocation *state = user_data; GError *error = NULL; IDE_ENTRY; g_assert (IDE_IS_BUFFER_MANAGER (bufmgr)); g_assert (state != NULL); g_assert (IDE_IS_EDITOR_PERSPECTIVE (state->self)); g_assert (state->location != NULL); if (!ide_buffer_manager_load_file_finish (bufmgr, result, &error)) { /* TODO: display warning breifly to the user in the frame? */ g_warning ("%s", error->message); g_clear_error (&error); IDE_GOTO (cleanup); } /* try again now that we have loaded */ ide_editor_perspective_focus_location_full (state->self, state->location, FALSE); cleanup: g_clear_object (&state->self); g_clear_pointer (&state->location, ide_source_location_unref); g_slice_free (FocusLocation, state); IDE_EXIT; }
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 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_set_fullscreen (IdePerspective *perspective, gboolean fullscreen) { IdeEditorPerspective *self = (IdeEditorPerspective *)perspective; g_assert (IDE_IS_EDITOR_PERSPECTIVE (self)); if (fullscreen) { gboolean left_visible; gboolean bottom_visible; g_object_get (self, "left-visible", &left_visible, "bottom-visible", &bottom_visible, NULL); self->prefocus_had_left = left_visible; self->prefocus_had_bottom = bottom_visible; g_object_set (self, "left-visible", FALSE, "bottom-visible", FALSE, NULL); } else { g_object_set (self, "left-visible", self->prefocus_had_left, "bottom-visible", self->prefocus_had_bottom, NULL); } }
/** * ide_editor_perspective_get_overlay: * @self: a #IdeEditorPerspective * * Gets the overlay widget which can be used to layer things above all * items in the layout grid. * * Returns: (transfer none) (type Gtk.Overlay): a #GtkWidget */ GtkWidget * ide_editor_perspective_get_overlay (IdeEditorPerspective *self) { g_return_val_if_fail (IDE_IS_EDITOR_PERSPECTIVE (self), NULL); return GTK_WIDGET (self->overlay); }
static gboolean ide_editor_perspective_focus_if_found (IdeEditorPerspective *self, IdeBuffer *buffer, gboolean any_stack) { IdeLayoutStack *stack; struct { IdeBuffer *buffer; IdeLayoutView *view; } lookup = { buffer }; g_return_val_if_fail (IDE_IS_EDITOR_PERSPECTIVE (self), FALSE); g_return_val_if_fail (IDE_IS_BUFFER (buffer), FALSE); stack = ide_layout_grid_get_current_stack (self->grid); if (any_stack) ide_layout_grid_foreach_view (self->grid, locate_view_for_buffer, &lookup); else ide_layout_stack_foreach_view (stack, locate_view_for_buffer, &lookup); if (lookup.view != NULL) { stack = IDE_LAYOUT_STACK (gtk_widget_get_ancestor (GTK_WIDGET (lookup.view), IDE_TYPE_LAYOUT_STACK)); ide_layout_stack_set_visible_child (stack, lookup.view); gtk_widget_grab_focus (GTK_WIDGET (lookup.view)); return TRUE; } return FALSE; }
/** * ide_editor_perspective_get_sidebar: * @self: a #IdeEditorPerspective * * Gets the #IdeEditorSidebar for the editor perspective. * * Returns: (transfer none): an #IdeEditorSidebar * * Since: 3.26 */ IdeEditorSidebar * ide_editor_perspective_get_sidebar (IdeEditorPerspective *self) { g_return_val_if_fail (IDE_IS_EDITOR_PERSPECTIVE (self), NULL); return IDE_EDITOR_SIDEBAR (dzl_dock_bin_get_left_edge (DZL_DOCK_BIN (self))); }
static void ide_editor_perspective_grab_focus (GtkWidget *widget) { IdeEditorPerspective *self = (IdeEditorPerspective *)widget; g_assert (IDE_IS_EDITOR_PERSPECTIVE (self)); gtk_widget_grab_focus (GTK_WIDGET (self->grid)); }
/** * ide_editor_addin_unload: * @self: an #IdeEditorAddin * @perspective: an #IdeEditorPerspective * * This method is called to unload the addin. * * The addin is responsible for undoing anything it setup in load * and cancel any in-flight or pending tasks immediately. * * Since: 3.26 */ void ide_editor_addin_unload (IdeEditorAddin *self, IdeEditorPerspective *perspective) { g_return_if_fail (IDE_IS_EDITOR_ADDIN (self)); g_return_if_fail (IDE_IS_EDITOR_PERSPECTIVE (perspective)); if (IDE_EDITOR_ADDIN_GET_IFACE (self)->unload) IDE_EDITOR_ADDIN_GET_IFACE (self)->unload (self, perspective); }
static void ide_editor_perspective_destroy (GtkWidget *widget) { IdeEditorPerspective *self = (IdeEditorPerspective *)widget; g_assert (IDE_IS_EDITOR_PERSPECTIVE (self)); g_clear_object (&self->addins); GTK_WIDGET_CLASS (ide_editor_perspective_parent_class)->destroy (widget); }
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; }
/** * 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); }
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 void ide_editor_perspective_actions_open_file (GSimpleAction *action, GVariant *variant, gpointer user_data) { IdeEditorPerspective *self = user_data; GtkFileChooserNative *chooser; IdeWorkbench *workbench; gint ret; g_assert (G_IS_SIMPLE_ACTION (action)); g_assert (IDE_IS_EDITOR_PERSPECTIVE (self)); workbench = ide_widget_get_workbench (GTK_WIDGET (self)); if (workbench == NULL) { g_warning ("Failed to locate workbench"); return; } chooser = gtk_file_chooser_native_new (_("Open File"), GTK_WINDOW (workbench), GTK_FILE_CHOOSER_ACTION_OPEN, _("Open"), _("Cancel")); gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (chooser), FALSE); gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (chooser), TRUE); ret = gtk_native_dialog_run (GTK_NATIVE_DIALOG (chooser)); if (ret == GTK_RESPONSE_ACCEPT) { g_autoptr(GPtrArray) ar = NULL; GSList *files; ar = g_ptr_array_new_with_free_func (g_object_unref); files = gtk_file_chooser_get_files (GTK_FILE_CHOOSER (chooser)); for (const GSList *iter = files; iter; iter = iter->next) g_ptr_array_add (ar, iter->data); g_slist_free (files); if (ar->len > 0) ide_workbench_open_files_async (workbench, (GFile **)ar->pdata, ar->len, "editor", IDE_WORKBENCH_OPEN_FLAGS_NONE, NULL, NULL, NULL); } gtk_native_dialog_destroy (GTK_NATIVE_DIALOG (chooser)); }
static IdeLayoutView * ide_editor_perspective_create_view (IdeEditorPerspective *self, const gchar *uri, IdeLayoutGrid *grid) { g_autoptr(GFile) file = NULL; g_autoptr(IdeFile) ifile = NULL; IdeBufferManager *bufmgr; IdeContext *context; IdeBuffer *buffer; g_assert (IDE_IS_EDITOR_PERSPECTIVE (self)); g_assert (uri != NULL); g_assert (IDE_IS_LAYOUT_GRID (grid)); g_debug ("Creating view for %s", uri); context = ide_widget_get_context (GTK_WIDGET (self)); file = g_file_new_for_uri (uri); ifile = ide_file_new (context, file); bufmgr = ide_context_get_buffer_manager (context); buffer = ide_buffer_manager_find_buffer (bufmgr, file); /* * If we failed to locate an already loaded buffer, we need to start * loading the buffer. But that could take some time. Either way, after * we start the loading process, we can access the buffer and we'll * display it while it loads. */ if (buffer == NULL) { /* TODO: We probably need a generic "Open" API that allows * us to handle any sort of API and redirect it to a * given view provider. */ ide_buffer_manager_load_file_async (bufmgr, ifile, FALSE, IDE_WORKBENCH_OPEN_FLAGS_NO_VIEW, NULL, NULL, ide_editor_perspective_load_file_cb, g_object_ref (self)); buffer = ide_buffer_manager_find_buffer (bufmgr, file); } return g_object_new (IDE_TYPE_EDITOR_VIEW, "buffer", buffer, "visible", TRUE, NULL); }
void ide_editor_perspective_focus_location (IdeEditorPerspective *self, IdeSourceLocation *location) { IDE_ENTRY; g_return_if_fail (IDE_IS_EDITOR_PERSPECTIVE (self)); g_return_if_fail (location != NULL); ide_editor_perspective_focus_location_full (self, location, TRUE); IDE_EXIT; }
static void ide_editor_perspective_add (GtkContainer *container, GtkWidget *widget) { IdeEditorPerspective *self = (IdeEditorPerspective *)container; g_assert (IDE_IS_EDITOR_PERSPECTIVE (self)); g_assert (GTK_IS_WIDGET (widget)); if (IDE_IS_LAYOUT_VIEW (widget)) gtk_container_add (GTK_CONTAINER (self->grid), widget); else GTK_CONTAINER_CLASS (ide_editor_perspective_parent_class)->add (container, widget); }
void _ide_editor_perspective_show_properties (IdeEditorPerspective *self, IdeEditorView *view) { IdeLayoutTransientSidebar *sidebar; g_return_if_fail (IDE_IS_EDITOR_PERSPECTIVE (self)); g_return_if_fail (!view || IDE_IS_EDITOR_VIEW (view)); sidebar = ide_editor_perspective_get_transient_sidebar (self); ide_editor_properties_set_view (self->properties, view); ide_layout_transient_sidebar_set_view (sidebar, (IdeLayoutView *)view); ide_layout_transient_sidebar_set_panel (sidebar, GTK_WIDGET (self->properties)); g_object_set (self, "right-visible", view != NULL, NULL); }
/** * ide_editor_addin_find_by_module_name: * @editor: an #IdeEditorPerspective * @module_name: the module name of the addin * * This function allows locating an #IdeEditorAddin that is attached * to the #IdeEditorPerspective by the addin module name. The module name * should match the value specified in the ".plugin" module definition. * * Returns: (transfer none) (nullable): An #IdeEditorAddin or %NULL */ IdeEditorAddin * ide_editor_addin_find_by_module_name (IdeEditorPerspective *editor, const gchar *module_name) { PeasExtension *ret = NULL; PeasPluginInfo *plugin_info; g_return_val_if_fail (IDE_IS_EDITOR_PERSPECTIVE (editor), NULL); g_return_val_if_fail (module_name != NULL, NULL); plugin_info = peas_engine_get_plugin_info (peas_engine_get_default (), module_name); if (plugin_info != NULL) ret = peas_extension_set_get_extension (editor->addins, plugin_info); else g_warning ("No such module found \"%s\"", module_name); return ret ? IDE_EDITOR_ADDIN (ret) : NULL; }
static void ide_editor_perspective_addin_removed (PeasExtensionSet *set, PeasPluginInfo *plugin_info, PeasExtension *exten, gpointer user_data) { IdeEditorPerspective *self = user_data; IdeEditorAddin *addin = (IdeEditorAddin *)exten; IdeLayoutView *view; g_assert (IDE_IS_EDITOR_PERSPECTIVE (self)); g_assert (IDE_IS_EDITOR_ADDIN (addin)); g_assert (PEAS_IS_EXTENSION_SET (set)); g_assert (plugin_info != NULL); view = ide_layout_grid_get_current_view (self->grid); if (view != NULL) ide_editor_addin_view_set (addin, NULL); ide_editor_addin_unload (addin, self); }
static void ide_editor_perspective_actions_new_file (GSimpleAction *action, GVariant *variant, gpointer user_data) { IdeEditorPerspective *self = user_data; IdeWorkbench *workbench; IdeContext *context; IdeBufferManager *bufmgr; IdeBuffer *buffer; g_assert (G_IS_SIMPLE_ACTION (action)); g_assert (IDE_IS_EDITOR_PERSPECTIVE (self)); workbench = ide_widget_get_workbench (GTK_WIDGET (self)); context = ide_workbench_get_context (workbench); bufmgr = ide_context_get_buffer_manager (context); buffer = ide_buffer_manager_create_temporary_buffer (bufmgr); g_clear_object (&buffer); }
void ide_editor_perspective_focus_buffer (IdeEditorPerspective *self, IdeBuffer *buffer) { IdeEditorView *view; IDE_ENTRY; g_return_if_fail (IDE_IS_EDITOR_PERSPECTIVE (self)); g_return_if_fail (IDE_IS_BUFFER (buffer)); if (ide_editor_perspective_focus_if_found (self, buffer, TRUE)) IDE_EXIT; view = g_object_new (IDE_TYPE_EDITOR_VIEW, "buffer", buffer, "visible", TRUE, NULL); gtk_container_add (GTK_CONTAINER (self->grid), GTK_WIDGET (view)); IDE_EXIT; }
static void ide_editor_perspective_hierarchy_changed (GtkWidget *widget, GtkWidget *old_toplevel) { IdeEditorPerspective *self = (IdeEditorPerspective *)widget; g_assert (IDE_IS_EDITOR_PERSPECTIVE (self)); g_assert (!old_toplevel || GTK_IS_WIDGET (old_toplevel)); if (self->addins == NULL) { GtkWidget *toplevel; /* * If we just got a new toplevel and it is a workbench, * and we have not yet created our addins, do so now. */ toplevel = gtk_widget_get_ancestor (widget, IDE_TYPE_WORKBENCH); if (toplevel != NULL) { self->addins = peas_extension_set_new (peas_engine_get_default (), IDE_TYPE_EDITOR_ADDIN, NULL); g_signal_connect (self->addins, "extension-added", G_CALLBACK (ide_editor_perspective_addin_added), self); g_signal_connect (self->addins, "extension-removed", G_CALLBACK (ide_editor_perspective_addin_removed), self); peas_extension_set_foreach (self->addins, ide_editor_perspective_addin_added, self); } } }
static void ide_editor_perspective_notify_current_view (IdeEditorPerspective *self, GParamSpec *pspec, IdeLayoutGrid *grid) { IdeLayoutView *view; g_assert (IDE_IS_EDITOR_PERSPECTIVE (self)); g_assert (pspec != NULL); g_assert (IDE_IS_LAYOUT_GRID (grid)); view = ide_layout_grid_get_current_view (grid); if (IDE_IS_EDITOR_VIEW (view)) ide_editor_properties_set_view (self->properties, IDE_EDITOR_VIEW (view)); else ide_editor_properties_set_view (self->properties, NULL); peas_extension_set_foreach (self->addins, ide_editor_perspective_addins_view_set, view); }
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)); if (ide_editor_perspective_focus_if_found (self, buffer, FALSE)) return; stack = ide_layout_grid_get_current_stack (self->grid); view = g_object_new (IDE_TYPE_EDITOR_VIEW, "buffer", buffer, "visible", TRUE, NULL); gtk_container_add (GTK_CONTAINER (stack), GTK_WIDGET (view)); }
static void ide_editor_perspective_focus_location_full (IdeEditorPerspective *self, IdeSourceLocation *location, gboolean open_if_not_found) { struct { IdeFile *file; IdeEditorView *view; } lookup = { 0 }; GtkWidget *stack; guint line; guint line_offset; IDE_ENTRY; g_assert (IDE_IS_EDITOR_PERSPECTIVE (self)); g_assert (location != NULL); lookup.file = ide_source_location_get_file (location); lookup.view = NULL; if (lookup.file == NULL) { g_warning ("IdeSourceLocation does not contain a file"); IDE_EXIT; } #ifdef IDE_ENABLE_TRACE { const gchar *path = ide_file_get_path (lookup.file); IDE_TRACE_MSG ("Locating %s, open_if_not_found=%d", path, open_if_not_found); } #endif ide_perspective_views_foreach (IDE_PERSPECTIVE (self), ide_editor_perspective_find_source_location, &lookup); if (!open_if_not_found && lookup.view == NULL) IDE_EXIT; if (lookup.view == NULL) { FocusLocation *state; IdeBufferManager *bufmgr; IdeWorkbench *workbench; IdeContext *context; workbench = ide_widget_get_workbench (GTK_WIDGET (self)); context = ide_workbench_get_context (workbench); bufmgr = ide_context_get_buffer_manager (context); state = g_slice_new0 (FocusLocation); state->self = g_object_ref (self); state->location = ide_source_location_ref (location); ide_buffer_manager_load_file_async (bufmgr, lookup.file, FALSE, IDE_WORKBENCH_OPEN_FLAGS_NONE, NULL, NULL, ide_editor_perspective_focus_location_cb, state); IDE_EXIT; } line = ide_source_location_get_line (location); line_offset = ide_source_location_get_line_offset (location); stack = gtk_widget_get_ancestor (GTK_WIDGET (lookup.view), IDE_TYPE_LAYOUT_STACK); ide_layout_stack_set_visible_child (IDE_LAYOUT_STACK (stack), IDE_LAYOUT_VIEW (lookup.view)); ide_editor_view_scroll_to_line_offset (lookup.view, line, line_offset); IDE_EXIT; }
void ide_workbench_set_visible_perspective (IdeWorkbench *self, IdePerspective *perspective) { g_autofree gchar *id = NULL; GActionGroup *actions = NULL; const gchar *current_id; GtkWidget *titlebar; guint restore_duration = 0; g_return_if_fail (IDE_IS_WORKBENCH (self)); g_return_if_fail (IDE_IS_PERSPECTIVE (perspective)); /* * If we can detect that this is the first transition to the editor, * and that our window is not yet displayed, we can avoid the transition * duration altogether. This is handy when first opening a window with * a project loaded, as used by self->disable_greeter. */ if (self->disable_greeter && IDE_IS_EDITOR_PERSPECTIVE (perspective) && !self->did_initial_editor_transition) { self->did_initial_editor_transition = TRUE; restore_duration = gtk_stack_get_transition_duration (self->perspectives_stack); gtk_stack_set_transition_duration (self->perspectives_stack, 0); } current_id = gtk_stack_get_visible_child_name (self->perspectives_stack); id = ide_perspective_get_id (perspective); if (!ide_str_equal0 (current_id, id)) gtk_stack_set_visible_child_name (self->perspectives_stack, id); titlebar = gtk_stack_get_child_by_name (self->header_stack, id); if (titlebar != NULL) gtk_stack_set_visible_child (self->header_stack, titlebar); else gtk_stack_set_visible_child (self->header_stack, GTK_WIDGET (self->header_bar)); actions = ide_perspective_get_actions (perspective); gtk_widget_insert_action_group (GTK_WIDGET (self), "perspective", actions); /* * If we are transitioning to the editor the first time, we can * remove the early perspectives (greeter, etc). */ if (IDE_IS_EDITOR_PERSPECTIVE (perspective)) remove_early_perspectives (self); gtk_widget_set_visible (GTK_WIDGET (self->perspective_menu_button), !ide_perspective_is_early (perspective)); if (self->addins != NULL) peas_extension_set_foreach (self->addins, ide_workbench_notify_perspective_set, perspective); g_clear_object (&actions); if (restore_duration != 0) gtk_stack_set_transition_duration (self->perspectives_stack, restore_duration); /* Notify the application to possibly update actions such * as the preferences state. */ ide_application_actions_update (IDE_APPLICATION_DEFAULT); }