예제 #1
0
GObject *
ide_workbench_get_selection_owner (IdeWorkbench *self)
{
  g_assert (IDE_IS_WORKBENCH (self));

  return self->selection_owner;
}
예제 #2
0
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);
}
예제 #3
0
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));
    }
}
예제 #4
0
/**
 * 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;
}
예제 #5
0
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));
}
예제 #6
0
/**
 * 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;
}
예제 #7
0
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);
}
예제 #8
0
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);
    }
}
예제 #9
0
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;
}
예제 #10
0
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;
}
예제 #11
0
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);

    }
}
예제 #12
0
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);
}
예제 #13
0
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;
}
예제 #14
0
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));
    }
}
예제 #15
0
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);
}
예제 #16
0
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);
}
예제 #17
0
/**
 * 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);
}
예제 #18
0
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;
}
예제 #19
0
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);
}
예제 #20
0
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);
}
예제 #21
0
/**
 * 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);
}
예제 #22
0
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;
}
예제 #23
0
/**
 * 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));
}
예제 #24
0
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));
}
예제 #25
0
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;
}
예제 #26
0
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);
}
예제 #27
0
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);
}
예제 #28
0
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;
}
예제 #29
0
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));
}
예제 #30
0
/**
 * 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);
}