static PeasPluginInfo * ide_application_locate_tool (IdeApplication *self, const gchar *tool_name) { PeasEngine *engine; const GList *list; g_assert (IDE_IS_APPLICATION (self)); g_assert (tool_name != NULL); engine = peas_engine_get_default (); list = peas_engine_get_plugin_list (engine); for (; list != NULL; list = list->next) { PeasPluginInfo *plugin_info = list->data; const gchar *name; name = peas_plugin_info_get_external_data (plugin_info, "Tool-Name"); if (g_strcmp0 (name, tool_name) == 0) return plugin_info; } return NULL; }
void ide_application_add_test (IdeApplication *self, const gchar *test_name, IdeApplicationTest test_func, IdeApplicationTestCompletion test_completion) { AsyncTest *test; IDE_ENTRY; g_return_if_fail (IDE_IS_APPLICATION (self)); g_return_if_fail (test_name != NULL); g_return_if_fail (test_func != NULL); if (test_completion == NULL) test_completion = ide_application_task_completion; test = g_slice_new0 (AsyncTest); test->name = g_strdup (test_name); test->test_func = test_func; test->test_completion = test_completion; self->test_funcs = g_list_append (self->test_funcs, test); IDE_EXIT; }
static void ide_application_actions_help (GSimpleAction *action, GVariant *param, gpointer user_data) { IdeApplication *self = user_data; GtkWindow *focused_window= NULL; GdkScreen *screen = NULL; GError *err = NULL; g_assert (IDE_IS_APPLICATION (self)); focused_window = gtk_application_get_active_window (GTK_APPLICATION (self)); screen = gtk_window_get_screen (focused_window); gtk_show_uri (screen, "help:gnome-builder", gtk_get_current_event_time (), &err); if (err) { g_message ("Unable to open help: %s\n", err->message); g_error_free (err); } }
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_application_load_addins (IdeApplication *self) { g_return_if_fail (IDE_IS_APPLICATION (self)); self->addins = peas_extension_set_new (peas_engine_get_default (), IDE_TYPE_APPLICATION_ADDIN, NULL); g_signal_connect_object (self->addins, "extension-added", G_CALLBACK (ide_application_addin_added), self, 0); g_signal_connect_object (self->addins, "extension-removed", G_CALLBACK (ide_application_addin_removed), self, 0); peas_extension_set_foreach (self->addins, ide_application_addin_added, self); }
static void ide_application_unload_plugin_resources (IdeApplication *self, PeasPluginInfo *plugin_info, PeasEngine *engine) { g_autofree gchar *path = NULL; const gchar *data_dir; const gchar *module_name; g_assert (IDE_IS_APPLICATION (self)); g_assert (plugin_info != NULL); g_assert (PEAS_IS_ENGINE (engine)); module_name = peas_plugin_info_get_module_name (plugin_info); data_dir = peas_plugin_info_get_data_dir (plugin_info); /* Remove embedded gresources */ path = g_strdup_printf ("resource:///org/gnome/builder/plugins/%s/", module_name); dzl_application_remove_resources (DZL_APPLICATION (self), path); /* Remove on disk resources */ if (!g_str_has_prefix (data_dir, "resource://")) dzl_application_remove_resources (DZL_APPLICATION (self), data_dir); ide_application_plugins_unload_plugin_gresources (self, plugin_info, engine); }
static void present_greeter_with_surface (GSimpleAction *action, GVariant *param, gpointer user_data) { GbpGreeterApplicationAddin *self = user_data; g_autoptr(IdeWorkbench) workbench = NULL; IdeGreeterWorkspace *workspace; const gchar *name; g_assert (!action || G_IS_SIMPLE_ACTION (action)); g_assert (!param || g_variant_is_of_type (param, G_VARIANT_TYPE_STRING)); g_assert (GBP_IS_GREETER_APPLICATION_ADDIN (self)); g_assert (IDE_IS_APPLICATION (self->application)); workbench = ide_workbench_new (); ide_application_add_workbench (self->application, workbench); workspace = ide_greeter_workspace_new (self->application); ide_workbench_add_workspace (workbench, IDE_WORKSPACE (workspace)); if (param != NULL && (name = g_variant_get_string (param, NULL)) && !ide_str_empty0 (name)) ide_workspace_set_visible_surface_name (IDE_WORKSPACE (workspace), name); ide_workbench_focus_workspace (workbench, IDE_WORKSPACE (workspace)); }
static void ide_application_plugins_enabled_changed (IdeApplication *self, const gchar *key, GSettings *settings) { PeasPluginInfo *plugin_info; PeasEngine *engine; gboolean enabled; g_assert (IDE_IS_APPLICATION (self)); g_assert (dzl_str_equal0 (key, "enabled")); g_assert (G_IS_SETTINGS (settings)); enabled = g_settings_get_boolean (settings, key); engine = peas_engine_get_default (); plugin_info = g_object_get_data (G_OBJECT (settings), "PEAS_PLUGIN_INFO"); g_assert (plugin_info != NULL); if (enabled && ide_application_can_load_plugin (self, plugin_info) && !peas_plugin_info_is_loaded (plugin_info)) peas_engine_load_plugin (engine, plugin_info); else if (!enabled && peas_plugin_info_is_loaded (plugin_info)) peas_engine_unload_plugin (engine, plugin_info); }
static PeasPluginInfo * ide_application_locate_worker (IdeApplication *self, const gchar *worker_name) { PeasEngine *engine; const GList *list; g_assert (IDE_IS_APPLICATION (self)); g_assert (worker_name != NULL); engine = peas_engine_get_default (); list = peas_engine_get_plugin_list (engine); for (; list != NULL; list = list->next) { PeasPluginInfo *plugin_info = list->data; const gchar *name; name = peas_plugin_info_get_module_name (plugin_info); if (g_strcmp0 (name, worker_name) == 0) return plugin_info; } return NULL; }
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); }
static void gbp_greeter_application_addin_handle_command_line (IdeApplicationAddin *addin, IdeApplication *application, GApplicationCommandLine *cmdline) { GbpGreeterApplicationAddin *self = (GbpGreeterApplicationAddin *)addin; g_auto(GStrv) argv = NULL; GVariantDict *dict; const gchar *clone_uri = NULL; gint argc; g_assert (GBP_IS_GREETER_APPLICATION_ADDIN (self)); g_assert (IDE_IS_APPLICATION (application)); g_assert (G_IS_APPLICATION_COMMAND_LINE (cmdline)); dict = g_application_command_line_get_options_dict (cmdline); argv = ide_application_get_argv (IDE_APPLICATION (application), cmdline); argc = g_strv_length (argv); /* * If we are processing the arguments for the startup of the primary * instance, then we want to show the greeter if no arguments are * provided. (That means argc == 1, the programe executable). * * Also, if they provided --greeter or -g we'll show a new greeter. */ if ((!g_application_command_line_get_is_remote (cmdline) && argc == 1) || g_variant_dict_contains (dict, "greeter")) { present_greeter_with_surface (NULL, NULL, addin); return; } /* * If the --clone=URI option was provided, switch the greeter to the * clone surface and begin cloning. */ if (dict != NULL && g_variant_dict_lookup (dict, "clone", "&s", &clone_uri)) { IdeGreeterWorkspace *workspace; IdeWorkbench *workbench; IdeSurface *surface; workbench = ide_workbench_new (); ide_application_add_workbench (self->application, workbench); workspace = ide_greeter_workspace_new (self->application); ide_workbench_add_workspace (workbench, IDE_WORKSPACE (workspace)); surface = ide_workspace_get_surface_by_name (IDE_WORKSPACE (workspace), "clone"); ide_workspace_set_visible_surface (IDE_WORKSPACE (workspace), surface); if (IDE_IS_CLONE_SURFACE (surface)) ide_clone_surface_set_uri (IDE_CLONE_SURFACE (surface), clone_uri); ide_workbench_focus_workspace (workbench, IDE_WORKSPACE (workspace)); } }
gboolean ide_application_open_finish (IdeApplication *self, GAsyncResult *result, GError **error) { g_return_val_if_fail (IDE_IS_APPLICATION (self), FALSE); return g_task_propagate_boolean (G_TASK (result), error); }
/** * ide_application_addin_unload: * @self: An #IdeApplicationAddin. * @application: An #IdeApplication. * * This inteface method is called when the application is shutting down or the * plugin has been unloaded. * * Use this function to cleanup after anything setup in * ide_application_addin_load(). * * Since: 3.32 */ void ide_application_addin_unload (IdeApplicationAddin *self, IdeApplication *application) { g_return_if_fail (IDE_IS_APPLICATION_ADDIN (self)); g_return_if_fail (IDE_IS_APPLICATION (application)); IDE_APPLICATION_ADDIN_GET_IFACE (self)->unload (self, application); }
static gboolean ide_application_can_load_plugin (IdeApplication *self, PeasPluginInfo *plugin_info) { const gchar *module_name; g_assert (IDE_IS_APPLICATION (self)); g_assert (plugin_info != NULL); module_name = peas_plugin_info_get_module_name (plugin_info); for (guint i = 0; i < G_N_ELEMENTS (blacklisted_plugins); i++) { if (g_strcmp0 (module_name, blacklisted_plugins[i]) == 0) return FALSE; } if (self->mode == IDE_APPLICATION_MODE_WORKER) { if (self->worker != plugin_info) return FALSE; } if (self->mode == IDE_APPLICATION_MODE_TOOL) { /* * Plugins might provide critical features needed * to load a project (build system, vcs, etc). */ return TRUE; } /* * TODO: Do ABI check on external data. * * Right now, we don't have any way to check that the plugin is implementing * the same version of the API/ABI that the application exports. There are a * couple ways we could go about doing this. * * One approach might be to generate UUIDs for each plugin structure, * and update it every time the structure changes. However, plenty of changes * can be safe for existing modules. So perhaps we need something that has * a revision since last break. Then plugins would specify which version * and revision of an interface they require. * * Imagine the scenario that FooIface added the method frobnicate(). Previous * extensions for FooIface are perfectly happy to keep on working, but a new * addin that requires FooIface may require frobnicate()'s existance. So while * the ABI hasn't broken, some plugins will require a newer revision. * * This is not entirely different from libtool's interface age. Presumably, * Gedit's IAge is similar here, but we would need it per-structure. */ return TRUE; }
/** * ide_application_addin_add_option_entries: * @self: a #IdeApplicationAddin * @application: an #IdeApplication * * This function is called to allow the application a chance to add various * command-line options to the #GOptionContext. See * g_application_add_main_option_entries() for more information on how to * add arguments. * * See ide_application_addin_handle_command_line() for how to handle arguments * once command line argument processing begins. * * Make sure you set `X-At-Startup=true` in your `.plugin` file so that the * plugin is loaded early during startup or this virtual function will not * be called. * * Since: 3.32 */ void ide_application_addin_add_option_entries (IdeApplicationAddin *self, IdeApplication *application) { g_return_if_fail (IDE_IS_APPLICATION_ADDIN (self)); g_return_if_fail (IDE_IS_APPLICATION (application)); if (IDE_APPLICATION_ADDIN_GET_IFACE (self)->add_option_entries) IDE_APPLICATION_ADDIN_GET_IFACE (self)->add_option_entries (self, application); }
/** * ide_application_addin_activate: * @self: a #IdeApplicationAddin * @application: an #ideApplication * * This function is activated when the GApplication::activate signal is * emitted. * * Since: 3.32 */ void ide_application_addin_activate (IdeApplicationAddin *self, IdeApplication *application) { g_return_if_fail (IDE_IS_APPLICATION_ADDIN (self)); g_return_if_fail (IDE_IS_APPLICATION (application)); if (IDE_APPLICATION_ADDIN_GET_IFACE (self)->activate) IDE_APPLICATION_ADDIN_GET_IFACE (self)->activate (self, application); }
static void ide_application_actions_open_project (GSimpleAction *action, GVariant *variant, gpointer user_data) { IdeApplication *self = user_data; g_assert (IDE_IS_APPLICATION (self)); ide_application_show_projects_window (self); }
static void ide_application_actions_new_project (GSimpleAction *action, GVariant *variant, gpointer user_data) { IdeApplication *self = user_data; g_assert (IDE_IS_APPLICATION (self)); ide_application_actions_load_workbench_view (self, "GbpCreateProjectGenesisAddin", NULL); }
/** * ide_application_addin_handle_command_line: * @self: a #IdeApplicationAddin * @application: an #IdeApplication * @cmdline: a #GApplicationCommandLine * * This function is called to allow the addin to procses command line arguments * that were parsed based on options added in * ide_application_addin_add_option_entries(). * * See g_application_command_line_get_option_dict() for more information. * * Since: 3.32 */ void ide_application_addin_handle_command_line (IdeApplicationAddin *self, IdeApplication *application, GApplicationCommandLine *cmdline) { g_return_if_fail (IDE_IS_APPLICATION_ADDIN (self)); g_return_if_fail (IDE_IS_APPLICATION (application)); g_return_if_fail (G_IS_APPLICATION_COMMAND_LINE (cmdline)); if (IDE_APPLICATION_ADDIN_GET_IFACE (self)->handle_command_line) IDE_APPLICATION_ADDIN_GET_IFACE (self)->handle_command_line (self, application, cmdline); }
static void new_window (GSimpleAction *action, GVariant *param, gpointer user_data) { GbpGreeterApplicationAddin *self = user_data; g_assert (!action || G_IS_SIMPLE_ACTION (action)); g_assert (GBP_IS_GREETER_APPLICATION_ADDIN (self)); g_assert (IDE_IS_APPLICATION (self->application)); present_greeter_with_surface (NULL, NULL, self); }
/** * ide_application_addin_open: * @self: a #IdeApplicationAddin * @application: an #ideApplication * @files: (array length=n_files) (element-type GFile): an array of #GFiles * @n_files: the length of @files * @hint: a hint provided by the calling instance * * This function is activated when the #GApplication::open signal is emitted. * * Since: 3.32 */ void ide_application_addin_open (IdeApplicationAddin *self, IdeApplication *application, GFile **files, gint n_files, const gchar *hint) { g_return_if_fail (IDE_IS_APPLICATION_ADDIN (self)); g_return_if_fail (IDE_IS_APPLICATION (application)); if (IDE_APPLICATION_ADDIN_GET_IFACE (self)->open) IDE_APPLICATION_ADDIN_GET_IFACE (self)->open (self, application, files, n_files, hint); }
static void gbp_greeter_application_addin_activate (IdeApplicationAddin *addin, IdeApplication *app) { GtkWindow *window; g_assert (IDE_IS_MAIN_THREAD ()); g_assert (GBP_IS_GREETER_APPLICATION_ADDIN (addin)); g_assert (IDE_IS_APPLICATION (app)); if (!(window = gtk_application_get_active_window (GTK_APPLICATION (app)))) present_greeter_with_surface (NULL, NULL, addin); }
static void ide_application_actions_load_flatpak (GSimpleAction *action, GVariant *args, gpointer user_data) { IdeApplication *self = user_data; const gchar *manifest = NULL; g_assert (IDE_IS_APPLICATION (self)); manifest = g_variant_get_string (args, NULL); ide_application_actions_load_workbench_view (self, "GbpFlatpakGenesisAddin", manifest); }
static void gbp_greeter_application_addin_unload (IdeApplicationAddin *addin, IdeApplication *application) { GbpGreeterApplicationAddin *self = (GbpGreeterApplicationAddin *)addin; g_assert (GBP_IS_GREETER_APPLICATION_ADDIN (self)); g_assert (IDE_IS_APPLICATION (application)); for (guint i = 0; i < G_N_ELEMENTS (actions); i++) g_action_map_remove_action (G_ACTION_MAP (application), actions[i].name); self->application = NULL; }
static void ide_application_actions_quit (GSimpleAction *action, GVariant *param, gpointer user_data) { IdeApplication *self = user_data; IDE_ENTRY; g_assert (IDE_IS_APPLICATION (self)); g_application_quit (G_APPLICATION (self)); IDE_EXIT; }
void ide_application_load_plugins (IdeApplication *self) { PeasEngine *engine; const GList *list; g_return_if_fail (IDE_IS_APPLICATION (self)); engine = peas_engine_get_default (); list = peas_engine_get_plugin_list (engine); for (; list; list = list->next) { PeasPluginInfo *plugin_info = list->data; GSettings *settings; const gchar *module_name; module_name = peas_plugin_info_get_module_name (plugin_info); settings = _ide_application_plugin_get_settings (self, module_name); g_object_set_data (G_OBJECT (settings), "PEAS_PLUGIN_INFO", plugin_info); g_signal_connect_object (settings, "changed::enabled", G_CALLBACK (ide_application_plugins_enabled_changed), self, G_CONNECT_SWAPPED); if (!g_settings_get_boolean (settings, "enabled")) continue; /* * If we are running the unit tests, we don't want to load plugins here, * but defer until the test is loading to perform the loading. However, * we do want all of the other machinery above to be setup. */ if (self->mode == IDE_APPLICATION_MODE_TESTS) continue; if (ide_application_can_load_plugin (self, plugin_info)) { g_debug ("Loading plugin \"%s\"", peas_plugin_info_get_module_name (plugin_info)); peas_engine_load_plugin (engine, plugin_info); } } }
void ide_application_run_tests (IdeApplication *self) { IDE_ENTRY; g_assert (IDE_IS_APPLICATION (self)); if (self->test_funcs != NULL) { g_test_log_set_fatal_handler (fatal_log_handler, NULL); g_application_hold (G_APPLICATION (self)); ide_application_run_next_test (self); } IDE_EXIT; }
static void gbp_greeter_application_addin_load (IdeApplicationAddin *addin, IdeApplication *application) { GbpGreeterApplicationAddin *self = (GbpGreeterApplicationAddin *)addin; g_assert (GBP_IS_GREETER_APPLICATION_ADDIN (self)); g_assert (IDE_IS_APPLICATION (application)); self->application = application; g_action_map_add_action_entries (G_ACTION_MAP (application), actions, G_N_ELEMENTS (actions), self); }
static gchar * ide_application_get_command_help (IdeApplication *self, gboolean long_form) { PeasEngine *engine; const GList *list; GString *str; gint count = 0; g_assert (IDE_IS_APPLICATION (self)); engine = peas_engine_get_default (); list = peas_engine_get_plugin_list (engine); str = g_string_new (NULL); if (long_form) g_string_append_printf (str, "%s\n", _("Commands:")); for (; list != NULL; list = list->next) { PeasPluginInfo *plugin_info = list->data; const gchar *name; const gchar *desc; name = peas_plugin_info_get_external_data (plugin_info, "Tool-Name"); desc = peas_plugin_info_get_external_data (plugin_info, "Tool-Description"); if (name != NULL) { if (long_form) g_string_append_printf (str, " %-25s %s\n", name, desc); else g_string_append_printf (str, "%s\n", name); count++; } } if (count == 0) { g_string_free (str, TRUE); return NULL; } return g_strstrip (g_string_free (str, FALSE)); }
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)); }