GObject * ide_workbench_get_selection_owner (IdeWorkbench *self) { g_assert (IDE_IS_WORKBENCH (self)); return self->selection_owner; }
void ide_application_actions_update (IdeApplication *self) { GList *windows; GAction *action; gboolean enabled; g_assert (IDE_IS_APPLICATION (self)); /* * We only enable the preferences action if we have a workbench open * that is past the greeter. */ action = g_action_map_lookup_action (G_ACTION_MAP (self), "preferences"); enabled = FALSE; for (windows = gtk_application_get_windows (GTK_APPLICATION (self)); windows != NULL; windows = windows->next) { GtkWindow *window = windows->data; if (IDE_IS_WORKBENCH (window) && !ide_str_equal0 ("greeter", ide_workbench_get_visible_perspective_name (IDE_WORKBENCH (window)))) { enabled = TRUE; break; } } g_simple_action_set_enabled (G_SIMPLE_ACTION (action), enabled); }
void ide_workbench_set_visible_perspective (IdeWorkbench *self, IdePerspective *perspective) { GActionGroup *actions; GtkStack *stack; gchar *id; g_return_if_fail (IDE_IS_WORKBENCH (self)); g_return_if_fail (IDE_IS_PERSPECTIVE (perspective)); stack = GTK_STACK (gtk_widget_get_ancestor (GTK_WIDGET (perspective), GTK_TYPE_STACK)); id = ide_perspective_get_id (perspective); if (!ide_str_equal0 (gtk_stack_get_visible_child_name (stack), id)) { gtk_stack_set_visible_child_name (stack, id); gtk_stack_set_visible_child_name (self->titlebar_stack, id); } g_free (id); actions = ide_perspective_get_actions (perspective); gtk_widget_insert_action_group (GTK_WIDGET (self), "perspective", actions); if ((stack == self->perspectives_stack) && !ide_str_equal0 (gtk_stack_get_visible_child_name (self->top_stack), "perspectives")) { gtk_stack_set_visible_child_name (self->top_stack, "perspectives"); g_timeout_add (1000 + gtk_stack_get_transition_duration (self->top_stack), remove_early_perspectives, g_object_ref (self)); } }
/** * ide_workbench_get_context: * @self: An #IdeWorkbench. * * Gets the context associated with the workbench, or %NULL. * * Returns: (transfer none) (nullable): An #IdeContext or %NULL. */ IdeContext * ide_workbench_get_context (IdeWorkbench *self) { g_return_val_if_fail (IDE_IS_WORKBENCH (self), NULL); return self->context; }
void ide_workbench_remove_perspective (IdeWorkbench *self, IdePerspective *perspective) { guint n_items; guint i; g_assert (IDE_IS_WORKBENCH (self)); g_assert (IDE_IS_PERSPECTIVE (perspective)); g_assert (gtk_widget_get_parent (GTK_WIDGET (perspective)) == GTK_WIDGET (self->perspectives_stack)); n_items = g_list_model_get_n_items (G_LIST_MODEL (self->perspectives)); for (i = 0; i < n_items; i++) { g_autoptr(IdePerspective) item = NULL; item = g_list_model_get_item (G_LIST_MODEL (self->perspectives), i); if (item == perspective) { g_list_store_remove (self->perspectives, i); break; } } gtk_container_remove (GTK_CONTAINER (self->perspectives_stack), GTK_WIDGET (perspective)); }
/** * ide_workbench_get_headerbar: * * Helper that is equivalent to calling gtk_window_get_titlebar() and casting * to an #IdeWorkbenchHeaderBar. This is convenience for plugins. * * Returns: (transfer none): An #IdeWorkbenchHeaderBar. */ IdeWorkbenchHeaderBar * ide_workbench_get_headerbar (IdeWorkbench *self) { g_return_val_if_fail (IDE_IS_WORKBENCH (self), NULL); return self->header_bar; }
static void gb_vim_command_split_cb (GObject *object, GAsyncResult *result, gpointer user_data) { IdeWorkbench *workbench = (IdeWorkbench *)object; SplitCallbackData *split_callback_data = user_data; GtkWidget *active_widget; const gchar *file_path; GVariant *variant; g_autoptr(GError) error = NULL; g_assert (IDE_IS_WORKBENCH (workbench)); g_assert (split_callback_data != NULL); if (ide_workbench_open_finish (workbench, result, &error)) { active_widget = split_callback_data->active_widget; file_path = split_callback_data->file_path; variant = g_variant_new_string (file_path); dzl_gtk_widget_action (GTK_WIDGET (active_widget), "frame", "split-page", variant); } g_clear_object (&split_callback_data->active_widget); g_clear_pointer (&split_callback_data->file_path, g_free); g_slice_free (SplitCallbackData, split_callback_data); }
static void ide_workbench_notify_visible_child (IdeWorkbench *self, GParamSpec *pspec, GtkStack *stack) { IdePerspective *perspective; g_assert (IDE_IS_WORKBENCH (self)); g_assert (GTK_IS_STACK (stack)); perspective = IDE_PERSPECTIVE (gtk_stack_get_visible_child (stack)); if (perspective != NULL) { GActionGroup *actions; gchar *id; id = ide_perspective_get_id (perspective); gtk_stack_set_visible_child_name (self->titlebar_stack, id); actions = ide_perspective_get_actions (perspective); gtk_widget_insert_action_group (GTK_WIDGET (self), "perspective", actions); g_clear_object (&actions); g_free (id); } }
static gboolean ide_workbench_agree_to_shutdown (IdeWorkbench *self) { GList *children; const GList *iter; gboolean ret = TRUE; g_assert (IDE_IS_WORKBENCH (self)); children = gtk_container_get_children (GTK_CONTAINER (self->perspectives_stack)); for (iter = children; iter; iter = iter->next) { IdePerspective *perspective = iter->data; if (!ide_perspective_agree_to_shutdown (perspective)) { ret = FALSE; break; } } g_list_free (children); return ret; }
static gboolean maybe_open_with_existing_workspace (IdeApplication *self, GFile *file, const gchar *hint, GCancellable *cancellable) { GList *windows; GList *iter; g_assert (IDE_IS_APPLICATION (self)); g_assert (G_IS_FILE (file)); windows = gtk_application_get_windows (GTK_APPLICATION (self)); for (iter = windows; iter != NULL; iter = iter->next) { GtkWindow *window = iter->data; if (IDE_IS_WORKBENCH (window) && workbench_manages_file (IDE_WORKBENCH (window), file)) { ide_workbench_open_files_async (IDE_WORKBENCH (window), &file, 1, hint, 0, cancellable, NULL, NULL); return TRUE; } } return FALSE; }
void ide_workbench_add_perspective (IdeWorkbench *self, IdePerspective *perspective) { g_autofree gchar *accel= NULL; g_autofree gchar *icon_name = NULL; g_autofree gchar *id = NULL; g_autofree gchar *title = NULL; GtkWidget *titlebar; g_assert (IDE_IS_WORKBENCH (self)); g_assert (IDE_IS_PERSPECTIVE (perspective)); id = ide_perspective_get_id (perspective); title = ide_perspective_get_title (perspective); icon_name = ide_perspective_get_icon_name (perspective); titlebar = ide_perspective_get_titlebar (perspective); gtk_container_add_with_properties (GTK_CONTAINER (self->perspectives_stack), GTK_WIDGET (perspective), "icon-name", icon_name, "name", id, "needs-attention", FALSE, "title", title, NULL); if (titlebar != NULL) gtk_container_add_with_properties (GTK_CONTAINER (self->header_stack), titlebar, "name", id, NULL); if (!IDE_IS_GREETER_PERSPECTIVE (perspective)) { guint position = 0; gtk_container_child_get (GTK_CONTAINER (self->perspectives_stack), GTK_WIDGET (perspective), "position", &position, NULL); g_list_store_append (self->perspectives, perspective); g_list_store_sort (self->perspectives, ide_workbench_compare_perspective, NULL); } accel = ide_perspective_get_accelerator (perspective); if (accel != NULL) { const gchar *accel_map[] = { accel, NULL }; g_autofree gchar *action_name = NULL; action_name = g_strdup_printf ("win.perspective('%s')", id); gtk_application_set_accels_for_action (GTK_APPLICATION (IDE_APPLICATION_DEFAULT), action_name, accel_map); } }
static void gb_terminal_respawn (GbTerminalView *self, VteTerminal *terminal) { g_autoptr(GPtrArray) args = NULL; g_autofree gchar *workpath = NULL; GtkWidget *toplevel; GError *error = NULL; IdeContext *context; IdeVcs *vcs; GFile *workdir; GPid child_pid; gint64 now; g_assert (GB_IS_TERMINAL_VIEW (self)); vte_terminal_reset (terminal, TRUE, TRUE); toplevel = gtk_widget_get_toplevel (GTK_WIDGET (self)); if (!IDE_IS_WORKBENCH (toplevel)) return; /* Prevent flapping */ now = g_get_monotonic_time (); if ((now - self->last_respawn) < (G_USEC_PER_SEC / 10)) return; self->last_respawn = now; context = ide_workbench_get_context (IDE_WORKBENCH (toplevel)); vcs = ide_context_get_vcs (context); workdir = ide_vcs_get_working_directory (vcs); workpath = g_file_get_path (workdir); args = g_ptr_array_new_with_free_func (g_free); g_ptr_array_add (args, vte_get_user_shell ()); g_ptr_array_add (args, NULL); vte_terminal_spawn_sync (terminal, VTE_PTY_DEFAULT | VTE_PTY_NO_LASTLOG | VTE_PTY_NO_UTMP | VTE_PTY_NO_WTMP, workpath, (gchar **)args->pdata, NULL, G_SPAWN_DEFAULT, NULL, NULL, &child_pid, NULL, &error); if (error != NULL) { g_warning ("%s", error->message); g_clear_error (&error); return; } vte_terminal_watch_child (terminal, child_pid); }
void ide_workbench_set_selection_owner (IdeWorkbench *self, GObject *object) { g_assert (IDE_IS_WORKBENCH (self)); g_assert (G_IS_OBJECT (object) || object == NULL); self->selection_owner = object; }
void ide_workbench_set_context (IdeWorkbench *self, IdeContext *context) { g_autoptr(GSettings) settings = NULL; IdeProject *project; guint duration; g_return_if_fail (IDE_IS_WORKBENCH (self)); g_return_if_fail (IDE_IS_CONTEXT (context)); g_return_if_fail (self->context == NULL); settings = g_settings_new ("org.gnome.builder"); g_set_object (&self->context, context); project = ide_context_get_project (context); g_object_bind_property_full (project, "name", self, "title", G_BINDING_SYNC_CREATE, transform_title, NULL, NULL, NULL); self->addins = peas_extension_set_new (peas_engine_get_default (), IDE_TYPE_WORKBENCH_ADDIN, NULL); g_signal_connect (self->addins, "extension-added", G_CALLBACK (ide_workbench_addin_added), self); g_signal_connect (self->addins, "extension-removed", G_CALLBACK (ide_workbench_addin_removed), self); peas_extension_set_foreach (self->addins, ide_workbench_addin_added, self); /* * Creating all the addins above is a bit intenstive, so give ourselves * just a bit of time to stablize allocations and sizing before * transitioning to the editor. */ g_timeout_add (STABLIZE_DELAY_MSEC, stablize_cb, g_object_ref (self)); /* * When restoring, previous buffers may get loaded. This causes new * widgets to be created and added to the workspace. Doing so during * the stack transition results in non-smooth transitions. So instead, * we will delay until the transition has completed. */ if (g_settings_get_boolean (settings, "restore-previous-files")) { duration = gtk_stack_get_transition_duration (self->top_stack); g_timeout_add (STABLIZE_DELAY_MSEC + duration, restore_in_timeout, g_object_ref (context)); } }
void ide_workbench_focus (IdeWorkbench *self, GtkWidget *widget) { g_return_if_fail (IDE_IS_WORKBENCH (self)); g_return_if_fail (GTK_IS_WIDGET (widget)); ide_workbench_show_parents (widget); gtk_widget_grab_focus (widget); }
void ide_application_addin_workbench_removed (IdeApplicationAddin *self, IdeWorkbench *workbench) { g_return_if_fail (IDE_IS_APPLICATION_ADDIN (self)); g_return_if_fail (IDE_IS_WORKBENCH (workbench)); if (IDE_APPLICATION_ADDIN_GET_IFACE (self)->workbench_removed) IDE_APPLICATION_ADDIN_GET_IFACE (self)->workbench_removed (self, workbench); }
/** * ide_workbench_get_visible_perspective: * @self: An #IdeWorkbench. * * Gets the current perspective. * * Returns: (transfer none): An #IdePerspective. */ IdePerspective * ide_workbench_get_visible_perspective (IdeWorkbench *self) { GtkWidget *ret; g_return_val_if_fail (IDE_IS_WORKBENCH (self), NULL); ret = gtk_stack_get_visible_child (self->perspectives_stack); return IDE_PERSPECTIVE (ret); }
static gboolean stablize_cb (gpointer data) { g_autoptr(IdeWorkbench) self = data; g_assert (IDE_IS_WORKBENCH (self)); ide_workbench_set_visible_perspective_name (self, "editor"); return G_SOURCE_REMOVE; }
void ide_workbench_set_visible_perspective_name (IdeWorkbench *self, const gchar *name) { IdePerspective *perspective; g_return_if_fail (IDE_IS_WORKBENCH (self)); g_return_if_fail (name != NULL); perspective = ide_workbench_get_perspective_by_name (self, name); if (perspective != NULL) ide_workbench_set_visible_perspective (self, perspective); }
static void ide_editor_view_hierarchy_changed (GtkWidget *widget, GtkWidget *previous_toplevel) { IdeEditorView *self = (IdeEditorView *)widget; GtkWidget *toplevel; g_assert (IDE_IS_EDITOR_VIEW (self)); /* * NOTE: If we ever support tearing out the editor, we should probably use * ide_widget_get_workbench() to discover a "synthetic" toplevel. */ toplevel = gtk_widget_get_toplevel (widget); if (IDE_IS_WORKBENCH (previous_toplevel) && self->extensions != NULL) ide_editor_view_unload_addins (self); if (IDE_IS_WORKBENCH (toplevel)) ide_editor_view_load_addins (self); }
/** * ide_workbench_get_perspective_by_name: * * Gets the perspective by its registered name as defined in * ide_perspective_get_id(). * * Returns: (nullable) (transfer none): An #IdePerspective or %NULL. */ IdePerspective * ide_workbench_get_perspective_by_name (IdeWorkbench *self, const gchar *name) { GtkWidget *ret; g_return_val_if_fail (IDE_IS_WORKBENCH (self), NULL); g_return_val_if_fail (name != NULL, NULL); ret = gtk_stack_get_child_by_name (self->perspectives_stack, name); return IDE_PERSPECTIVE (ret); }
static void ide_workbench_actions_open_with_dialog (GSimpleAction *action, GVariant *param, gpointer user_data) { IdeWorkbench *self = user_data; GtkWidget *button; GtkWidget *dialog; gint ret; IDE_ENTRY; g_assert (IDE_IS_WORKBENCH (self)); dialog = gtk_file_chooser_dialog_new (_("Open File"), GTK_WINDOW (self), GTK_FILE_CHOOSER_ACTION_OPEN, _("Cancel"), GTK_RESPONSE_CANCEL, _("Open"), GTK_RESPONSE_OK, NULL); gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (dialog), FALSE); button = gtk_dialog_get_widget_for_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK); gtk_style_context_add_class (gtk_widget_get_style_context (button), GTK_STYLE_CLASS_SUGGESTED_ACTION); /* * TODO: Allow workbench addins to specify file filters? * Do we want to move this to a custom interface and use that * for file loading as well? */ ret = gtk_dialog_run (GTK_DIALOG (dialog)); if (ret == GTK_RESPONSE_OK) { g_autoptr(GFile) file = NULL; IDE_PROBE; file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (dialog)); ide_workbench_open_files_async (self, &file, 1, NULL, NULL, ide_workbench_actions_open_with_dialog_cb, NULL); } gtk_widget_destroy (dialog); IDE_EXIT; }
/** * ide_workbench_get_visible_perspective: * @self: An #IdeWorkbench. * * Gets the current perspective. * * Returns: (transfer none): An #IdePerspective. */ IdePerspective * ide_workbench_get_visible_perspective (IdeWorkbench *self) { GtkWidget *visible_child; g_return_val_if_fail (IDE_IS_WORKBENCH (self), NULL); visible_child = gtk_stack_get_visible_child (self->top_stack); if (IDE_IS_PERSPECTIVE (visible_child)) return IDE_PERSPECTIVE (visible_child); return IDE_PERSPECTIVE (gtk_stack_get_visible_child (self->perspectives_stack)); }
static void ide_workbench_unload_cb (GObject *object, GAsyncResult *result, gpointer user_data) { g_autoptr(IdeWorkbench) self = user_data; IdeContext *context = (IdeContext *)object; g_return_if_fail (IDE_IS_WORKBENCH (self)); ide_context_unload_finish (context, result, NULL); gtk_widget_destroy (GTK_WIDGET (self)); }
static void remove_early_perspectives (IdeWorkbench *self) { g_assert (IDE_IS_WORKBENCH (self)); if (self->early_perspectives_removed) return; gtk_container_foreach (GTK_CONTAINER (self->perspectives_stack), do_remove_early_perspectives, NULL); self->early_perspectives_removed = TRUE; }
static void ide_workbench_actions_opacity (GSimpleAction *action, GVariant *variant, gpointer user_data) { IdeWorkbench *workbench = user_data; gdouble opacity; g_assert (IDE_IS_WORKBENCH (workbench)); g_assert (g_variant_is_of_type (variant, G_VARIANT_TYPE_INT32)); opacity = CLAMP (g_variant_get_int32 (variant), 10, 100) / 100.0; gtk_widget_set_opacity (GTK_WIDGET (workbench), opacity); }
static void ide_workbench_addin_removed (PeasExtensionSet *set, PeasPluginInfo *plugin_info, PeasExtension *extension, gpointer user_data) { IdeWorkbench *self = user_data; g_assert (PEAS_IS_EXTENSION_SET (set)); g_assert (plugin_info != NULL); g_assert (IDE_IS_WORKBENCH_ADDIN (extension)); g_assert (IDE_IS_WORKBENCH (self)); ide_workbench_addin_unload (IDE_WORKBENCH_ADDIN (extension), self); }
static gboolean remove_early_perspectives (gpointer data) { g_autoptr(IdeWorkbench) self = data; GtkWidget *widget; g_assert (IDE_IS_WORKBENCH (self)); widget = gtk_stack_get_child_by_name (self->top_stack, "greeter"); gtk_widget_destroy (widget); widget = gtk_stack_get_child_by_name (self->top_stack, "genesis"); gtk_widget_destroy (widget); return G_SOURCE_REMOVE; }
static void ide_application_actions_about (GSimpleAction *action, GVariant *param, gpointer user_data) { IdeApplication *self = user_data; GtkDialog *dialog; GtkWindow *parent = NULL; GList *iter; GList *windows; g_assert (IDE_IS_APPLICATION (self)); windows = gtk_application_get_windows (GTK_APPLICATION (self)); for (iter = windows; iter; iter = iter->next) { if (IDE_IS_WORKBENCH (iter->data)) { parent = iter->data; break; } } dialog = g_object_new (GTK_TYPE_ABOUT_DIALOG, "artists", ide_application_credits_artists, "authors", ide_application_credits_authors, "comments", _("An IDE for GNOME"), "copyright", "Copyright © 2014—2016 Christian Hergert, et al.", "documenters", ide_application_credits_documenters, "license-type", GTK_LICENSE_GPL_3_0, "logo-icon-name", "org.gnome.Builder", "modal", TRUE, "program-name", _("GNOME Builder"), "transient-for", parent, "translator-credits", _("translator-credits"), "version", PACKAGE_VERSION, "website", "https://wiki.gnome.org/Apps/Builder", "website-label", _("Learn more about GNOME Builder"), NULL); gtk_about_dialog_add_credit_section (GTK_ABOUT_DIALOG (dialog), _("Funded By"), ide_application_credits_funders); g_signal_connect (dialog, "response", G_CALLBACK (gtk_widget_destroy), NULL); gtk_window_present (GTK_WINDOW (dialog)); }
/** * ide_workbench_views_foreach: * @self: An #IdeWorkbench. * @callback: (scope call): The callback to execute * @user_data: user data for @callback. * * Executes @callback for every #IdeLayoutView across all perspectives. */ void ide_workbench_views_foreach (IdeWorkbench *self, GtkCallback callback, gpointer user_data) { struct { GtkCallback callback; gpointer user_data; } closure = { callback, user_data }; g_return_if_fail (IDE_IS_WORKBENCH (self)); g_return_if_fail (callback != NULL); gtk_container_foreach (GTK_CONTAINER (self->perspectives_stack), ide_workbench_views_foreach_cb, &closure); }