static void
gb_editor_view_actions_reload_buffer (GSimpleAction *action,
                                      GVariant      *param,
                                      gpointer       user_data)
{
  GbEditorView *self = user_data;
  IdeContext *context;
  IdeBufferManager *buffer_manager;
  IdeFile *file;
  g_autoptr(IdeProgress) progress = NULL;

  g_assert (GB_IS_EDITOR_VIEW (self));

  context = ide_buffer_get_context (IDE_BUFFER (self->document));
  file = ide_buffer_get_file (IDE_BUFFER (self->document));

  buffer_manager = ide_context_get_buffer_manager (context);

  gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (self->progress_bar), 0.0);
  gtk_widget_show (GTK_WIDGET (self->progress_bar));

  ide_buffer_manager_load_file_async (buffer_manager,
                                      file,
                                      TRUE,
                                      &progress,
                                      NULL,
                                      gb_editor_view_actions_reload_buffer_cb,
                                      g_object_ref (self));

  g_object_bind_property (progress, "fraction", self->progress_bar, "fraction",
                          G_BINDING_SYNC_CREATE);
}
Example #2
0
static void
gb_editor_view__buffer_changed_on_volume (GbEditorView *self,
                                          GParamSpec   *pspec,
                                          IdeBuffer    *buffer)
{
  g_assert (GB_IS_EDITOR_VIEW (self));
  g_assert (IDE_IS_BUFFER (buffer));

  if (ide_buffer_get_changed_on_volume (buffer))
    gtk_revealer_set_reveal_child (self->modified_revealer, TRUE);
  else if (gtk_revealer_get_reveal_child (self->modified_revealer))
    {
      GtkTextIter iter;

      gtk_text_buffer_get_start_iter (GTK_TEXT_BUFFER (buffer), &iter);
      gtk_text_buffer_select_range (GTK_TEXT_BUFFER (buffer), &iter, &iter);

      /*
       * FIXME:
       *
       * Without this delay, I see a condition with split view where the
       * non-focused split will just render blank. Well that isn't totally
       * correct, it renders empty gutters and proper line grid background. But
       * no textual content. And the adjustment is way out of sync. Even
       * changing the adjustment manually doesn't help. So whatever, I'll
       * insert a short delay and we'll pick up after the textview has
       * stablized.
       */
      g_timeout_add (10, no_really_scroll_to_the_top, g_object_ref (self));

      gtk_revealer_set_reveal_child (self->modified_revealer, FALSE);
    }
}
Example #3
0
static void
gb_editor_view_set_split_view (GbView   *view,
                               gboolean  split_view)
{
  GbEditorView *self = (GbEditorView *)view;

  g_assert (GB_IS_EDITOR_VIEW (self));

  if (split_view && (self->frame2 != NULL))
    return;

  if (!split_view && (self->frame2 == NULL))
    return;

  if (split_view)
    {
      self->frame2 = g_object_new (GB_TYPE_EDITOR_FRAME,
                                   "document", self->document,
                                   "visible", TRUE,
                                   NULL);
      gtk_container_add_with_properties (GTK_CONTAINER (self->paned), GTK_WIDGET (self->frame2),
                                         "shrink", FALSE,
                                         "resize", TRUE,
                                         NULL);
      gtk_widget_grab_focus (GTK_WIDGET (self->frame2));
    }
  else
    {
      GtkWidget *copy = GTK_WIDGET (self->frame2);

      self->frame2 = NULL;
      gtk_container_remove (GTK_CONTAINER (self->paned), copy);
      gtk_widget_grab_focus (GTK_WIDGET (self->frame1));
    }
}
static void
gb_editor_view_actions_reload_buffer_cb (GObject      *object,
                                         GAsyncResult *result,
                                         gpointer      user_data)
{
  IdeBufferManager *buffer_manager = (IdeBufferManager *)object;
  g_autoptr(GbEditorView) self = user_data;
  g_autoptr(GError) error = NULL;
  g_autoptr(IdeBuffer) buffer = NULL;

  g_assert (IDE_IS_BUFFER_MANAGER (buffer_manager));
  g_assert (GB_IS_EDITOR_VIEW (self));

  gtk_revealer_set_reveal_child (self->modified_revealer, FALSE);

  if (!(buffer = ide_buffer_manager_load_file_finish (buffer_manager, result, &error)))
    {
      g_warning ("%s", error->message);
    }
  else
    {
      g_signal_emit_by_name (self->frame1->source_view, "movement",
                             IDE_SOURCE_VIEW_MOVEMENT_FIRST_LINE, FALSE, TRUE,
                             FALSE);
      if (self->frame2 != NULL)
        g_signal_emit_by_name (self->frame2->source_view, "movement",
                               IDE_SOURCE_VIEW_MOVEMENT_FIRST_LINE, FALSE, TRUE,
                               FALSE);
    }

  gb_widget_fade_hide (GTK_WIDGET (self->progress_bar));
}
static void
gb_editor_view_actions_print (GSimpleAction *action,
                              GVariant      *param,
                              gpointer       user_data)
{
  GbEditorView *self = user_data;
  GtkWidget *toplevel;
  g_autoptr(GbEditorPrintOperation) operation;
  GtkPrintOperationResult result;

  g_assert (GB_IS_EDITOR_VIEW (self));

  toplevel = gtk_widget_get_toplevel (GTK_WIDGET (self));

  operation = gb_editor_print_operation_new (self->frame1->source_view);

  /* keep a ref until "done" is emitted */
  g_object_ref (operation);

  g_signal_connect_after (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);
}
Example #6
0
static void
gb_editor_view_hide_reload_bar (GbEditorView *self,
                                GtkWidget    *button)
{
  g_assert (GB_IS_EDITOR_VIEW (self));

  gtk_revealer_set_reveal_child (self->modified_revealer, FALSE);
}
static void
gb_editor_view_actions_preview (GSimpleAction *action,
                                GVariant      *param,
                                gpointer       user_data)
{
  GbEditorView *self = user_data;
  GtkSourceLanguage *language;
  const gchar *lang_id = NULL;
  g_autoptr(GbDocument) document = NULL;

  g_assert (GB_IS_EDITOR_VIEW (self));

  language = gtk_source_buffer_get_language (GTK_SOURCE_BUFFER (self->document));
  if (!language)
    return;

  lang_id = gtk_source_language_get_id (language);
  if (!lang_id)
    return;

#if 0
  if (g_str_equal (lang_id, "html"))
    {
      document = g_object_new (GB_TYPE_HTML_DOCUMENT,
                               "buffer", self->document,
                               NULL);
    }
  else if (g_str_equal (lang_id, "markdown"))
    {
      document = g_object_new (GB_TYPE_HTML_DOCUMENT,
                               "buffer", self->document,
                               NULL);
      gb_html_document_set_transform_func (GB_HTML_DOCUMENT (document),
                                           gb_html_markdown_transform);
    }
#endif

  if (document)
    {
      GtkWidget *parent = gtk_widget_get_parent (GTK_WIDGET (self));

      while (parent && !GB_IS_VIEW_GRID (parent))
        parent = gtk_widget_get_parent (parent);

      if (parent == NULL)
        {
          while (parent && !GB_IS_VIEW_STACK (parent))
            parent = gtk_widget_get_parent (parent);
          g_assert (GB_IS_VIEW_STACK (parent));
          gb_view_stack_focus_document (GB_VIEW_STACK (parent), document);
          return;
        }

      g_assert (GB_IS_VIEW_GRID (parent));
      gb_view_grid_focus_document (GB_VIEW_GRID (parent), document);
    }
}
Example #8
0
static void
gb_editor_view__buffer_modified_changed (GbEditorView  *self,
                                         GParamSpec    *pspec,
                                         GtkTextBuffer *buffer)
{
  g_assert (GB_IS_EDITOR_VIEW (self));

  g_object_notify (G_OBJECT (self), "modified");
}
Example #9
0
static GbDocument *
gb_editor_view_get_document (GbView *view)
{
  GbEditorView *self = (GbEditorView *)view;

  g_assert (GB_IS_EDITOR_VIEW (self));

  return GB_DOCUMENT (self->document);
}
Example #10
0
static gboolean
gb_editor_view_get_modified (GbView *view)
{
  GbEditorView *self = (GbEditorView *)view;

  g_assert (GB_IS_EDITOR_VIEW (self));

  return gtk_text_buffer_get_modified (GTK_TEXT_BUFFER (self->document));
}
Example #11
0
static void
gb_editor_view__buffer_notify_title (GbEditorView *self,
                                     GParamSpec   *pspec,
                                     IdeBuffer    *buffer)
{
  g_assert (GB_IS_EDITOR_VIEW (self));
  g_assert (GB_IS_EDITOR_DOCUMENT (buffer));

  g_object_notify (G_OBJECT (self), "title");
}
Example #12
0
static void
gb_editor_view_grab_focus (GtkWidget *widget)
{
  GbEditorView *self = (GbEditorView *)widget;

  g_assert (GB_IS_EDITOR_VIEW (self));

  /* todo: track last focus frame */

  gtk_widget_grab_focus (GTK_WIDGET (self->frame1->source_view));
}
static gboolean
set_split_view (gpointer data)
{
  g_autoptr(GbEditorView) self = data;

  g_assert (GB_IS_EDITOR_VIEW (self));

  gb_view_set_split_view (GB_VIEW (self), (self->frame2 == NULL));

  return G_SOURCE_REMOVE;
}
static void
gb_editor_view_actions_goto_line (GSimpleAction *action,
                                  GVariant      *param,
                                  gpointer      user_data)
{
  GbEditorView *self = user_data;

  g_assert (GB_IS_EDITOR_VIEW (self));

  gtk_widget_activate (GTK_WIDGET (self->goto_line_button));
}
static void
gb_editor_view_actions_toggle_split (GSimpleAction *action,
                                     GVariant      *param,
                                     gpointer       user_data)
{
  GbEditorView *self = user_data;

  g_assert (GB_IS_EDITOR_VIEW (self));

  g_timeout_add (0, set_split_view, g_object_ref (self));
}
static void
gb_editor_view_actions_find_other_file (GSimpleAction *action,
                                        GVariant      *param,
                                        gpointer       user_data)
{
  GbEditorView *self = user_data;
  IdeFile *file;

  g_assert (GB_IS_EDITOR_VIEW (self));

  file = ide_buffer_get_file (IDE_BUFFER (self->document));
  ide_file_find_other_async (file, NULL, find_other_file_cb, g_object_ref (self));
}
Example #17
0
static void
gb_editor_view__extension_removed (PeasExtensionSet  *set,
                                   PeasPluginInfo    *info,
                                   GbEditorViewAddin *addin,
                                   GbEditorView      *self)
{
  g_assert (PEAS_IS_EXTENSION_SET (set));
  g_assert (info != NULL);
  g_assert (GB_IS_EDITOR_VIEW_ADDIN (addin));
  g_assert (GB_IS_EDITOR_VIEW (self));

  gb_editor_view_addin_unload (addin, self);
}
static void
save_temp_response (GtkWidget *widget,
                    gint       response,
                    gpointer   user_data)
{
  g_autoptr(GbEditorView) self = user_data;
  g_autoptr(GFile) target = NULL;
  g_autoptr(IdeProgress) progress = NULL;
  GtkFileChooser *chooser = (GtkFileChooser *)widget;

  g_assert (GTK_IS_FILE_CHOOSER (chooser));
  g_assert (GB_IS_EDITOR_VIEW (self));

  switch (response)
    {
    case GTK_RESPONSE_OK:
      target = gtk_file_chooser_get_file (chooser);
      break;

    case GTK_RESPONSE_CANCEL:
    default:
      break;
    }

  if (target != NULL)
    {
      IdeBufferManager *buffer_manager;
      IdeContext *context;
      IdeProject *project;
      IdeBuffer *buffer = IDE_BUFFER (self->document);
      g_autoptr(IdeFile) file = NULL;

      context = ide_buffer_get_context (buffer);
      project = ide_context_get_project (context);
      buffer_manager = ide_context_get_buffer_manager (context);
      file = ide_project_get_project_file (project, target);

      ide_buffer_set_file (buffer, file);

      ide_buffer_manager_save_file_async (buffer_manager,
                                          buffer,
                                          file,
                                          &progress,
                                          NULL,
                                          gb_editor_view_actions__save_temp_cb,
                                          g_object_ref (self));
    }

  gtk_widget_destroy (widget);
}
Example #19
0
static void
gb_editor_view_set_document (GbEditorView     *self,
                             GbEditorDocument *document)
{
  g_return_if_fail (GB_IS_EDITOR_VIEW (self));
  g_return_if_fail (GB_IS_EDITOR_DOCUMENT (document));

  if (g_set_object (&self->document, document))
    {
      if (self->frame1)
        gb_editor_frame_set_document (self->frame1, document);

      if (self->frame2)
        gb_editor_frame_set_document (self->frame2, document);

      g_settings_bind (self->settings, "style-scheme-name",
                       document, "style-scheme-name",
                       G_SETTINGS_BIND_GET);
      g_settings_bind (self->settings, "highlight-matching-brackets",
                       document, "highlight-matching-brackets",
                       G_SETTINGS_BIND_GET);

      g_object_bind_property_full (document, "language", self->tweak_button,
                                   "label", G_BINDING_SYNC_CREATE,
                                   language_to_string, NULL, NULL, NULL);

      g_signal_connect_object (document,
                               "modified-changed",
                               G_CALLBACK (gb_editor_view__buffer_modified_changed),
                               self,
                               G_CONNECT_SWAPPED);

      g_signal_connect_object (document,
                               "notify::title",
                               G_CALLBACK (gb_editor_view__buffer_notify_title),
                               self,
                               G_CONNECT_SWAPPED);

      g_signal_connect_object (document,
                               "notify::changed-on-volume",
                               G_CALLBACK (gb_editor_view__buffer_changed_on_volume),
                               self,
                               G_CONNECT_SWAPPED);

      g_object_notify_by_pspec (G_OBJECT (self), gParamSpecs [PROP_DOCUMENT]);

      gb_editor_view_actions_update (self);
    }
}
Example #20
0
static GbView *
gb_editor_view_create_split (GbView *view)
{
  GbEditorView *self = (GbEditorView *)view;
  GbView *ret;

  g_assert (GB_IS_EDITOR_VIEW (self));

  ret = g_object_new (GB_TYPE_EDITOR_VIEW,
                      "document", self->document,
                      "visible", TRUE,
                      NULL);

  return ret;
}
static void
gb_editor_view_actions_save_as (GSimpleAction *action,
                                GVariant      *param,
                                gpointer       user_data)
{
  GbEditorView *self = user_data;
  IdeBuffer *buffer;
  GtkWidget *suggested;
  GtkWidget *toplevel;
  GtkWidget *dialog;
  IdeFile *file;
  GFile *gfile;

  g_assert (GB_IS_EDITOR_VIEW (self));

  toplevel = gtk_widget_get_toplevel (GTK_WIDGET (self));
  dialog = g_object_new (GTK_TYPE_FILE_CHOOSER_DIALOG,
                         "action", GTK_FILE_CHOOSER_ACTION_SAVE,
                         "do-overwrite-confirmation", TRUE,
                         "local-only", FALSE,
                         "modal", TRUE,
                         "select-multiple", FALSE,
                         "show-hidden", FALSE,
                         "transient-for", toplevel,
                         "title", _("Save Document As"),
                         NULL);

  buffer = IDE_BUFFER (self->document);
  file = ide_buffer_get_file (buffer);
  gfile = ide_file_get_file (file);

  if (gfile != NULL)
    gtk_file_chooser_set_file (GTK_FILE_CHOOSER (dialog), gfile, NULL);

  gtk_dialog_add_buttons (GTK_DIALOG (dialog),
                          _("Cancel"), GTK_RESPONSE_CANCEL,
                          _("Save"), GTK_RESPONSE_OK,
                          NULL);
  gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);

  suggested = gtk_dialog_get_widget_for_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
  gtk_style_context_add_class (gtk_widget_get_style_context (suggested),
                               GTK_STYLE_CLASS_SUGGESTED_ACTION);

  g_signal_connect (dialog, "response", G_CALLBACK (save_as_response), g_object_ref (self));

  gtk_window_present (GTK_WINDOW (dialog));
}
static void
gb_editor_view_actions_reveal (GSimpleAction *action,
                               GVariant      *param,
                               gpointer       user_data)
{
  GbEditorView *self = user_data;
  GbWorkbench *workbench;
  IdeFile *file;
  GFile *gfile;

  g_assert (G_IS_SIMPLE_ACTION (action));
  g_assert (GB_IS_EDITOR_VIEW (self));

  file = ide_buffer_get_file (IDE_BUFFER (self->document));
  gfile = ide_file_get_file (file);
  workbench = gb_widget_get_workbench (GTK_WIDGET (self));
  gb_workbench_reveal_file (workbench, gfile);
}
static void
gb_editor_view_actions_close (GSimpleAction *action,
                              GVariant      *param,
                              gpointer       user_data)
{
  GbEditorView *self = user_data;

  g_assert (GB_IS_EDITOR_VIEW (self));

  /* just close our current frame if we have split view */
  if (self->frame2 != NULL)
    {
      /* todo: swap frame1/frame2 if frame2 was last focused. */
      g_timeout_add (0, set_split_view, g_object_ref (self));
    }
  else
    {
      gb_widget_activate_action (GTK_WIDGET (self), "view-stack", "close", NULL);
    }
}
Example #24
0
static void
gb_editor_view_navigate_to (GbView            *view,
                            IdeSourceLocation *location)
{
  GbEditorView *self = (GbEditorView *)view;
  GbEditorFrame *frame;
  GtkTextMark *insert;
  GtkTextBuffer *buffer;
  GtkTextIter iter;
  guint line;
  guint line_offset;

  IDE_ENTRY;

  g_assert (GB_IS_EDITOR_VIEW (self));
  g_assert (location != NULL);

  frame = gb_editor_view_get_last_focused (self);
  buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (frame->source_view));

  line = ide_source_location_get_line (location);
  line_offset = ide_source_location_get_line_offset (location);

  gtk_text_buffer_get_iter_at_line (buffer, &iter, line);
  for (; line_offset; line_offset--)
    if (gtk_text_iter_ends_line (&iter) || !gtk_text_iter_forward_char (&iter))
      break;

  gtk_text_buffer_select_range (buffer, &iter, &iter);

  insert = gtk_text_buffer_get_insert (buffer);
  gtk_text_view_scroll_to_mark (GTK_TEXT_VIEW (frame->source_view), insert, 0.0, TRUE, 1.0, 0.5);

  g_signal_emit_by_name (frame->source_view, "save-insert-mark");

  IDE_EXIT;
}
void
gb_editor_view_actions_update (GbEditorView *self)
{
  GtkSourceLanguage *language;
  const gchar *lang_id = NULL;
  GActionGroup *group;
  GAction *action;
  gboolean enabled;

  g_assert (GB_IS_EDITOR_VIEW (self));

  group = gtk_widget_get_action_group (GTK_WIDGET (self), "view");
  if (!G_IS_SIMPLE_ACTION_GROUP (group))
    return;

  /* update preview sensitivity */
  language = gtk_source_buffer_get_language (GTK_SOURCE_BUFFER (self->document));
  if (language)
    lang_id = gtk_source_language_get_id (language);
  enabled = ((g_strcmp0 (lang_id, "html") == 0) ||
             (g_strcmp0 (lang_id, "markdown") == 0));
  action = g_action_map_lookup_action (G_ACTION_MAP (group), "preview");
  g_simple_action_set_enabled (G_SIMPLE_ACTION (action), enabled);
}
static void
gb_editor_view_actions_language (GSimpleAction *action,
                                 GVariant      *variant,
                                 gpointer       user_data)
{
  GbEditorView *self = user_data;
  GtkSourceLanguageManager *manager;
  GtkSourceLanguage *language;
  GtkSourceBuffer *buffer;
  const gchar *name;

  g_assert (GB_IS_EDITOR_VIEW (self));

  manager = gtk_source_language_manager_get_default ();
  name = g_variant_get_string (variant, NULL);
  buffer = GTK_SOURCE_BUFFER (self->document);

  if (name != NULL)
    {
      language = gtk_source_language_manager_get_language (manager, name);
      gtk_source_buffer_set_language (buffer, language);
      gb_editor_view_actions_update (self);
    }
}
static void
gb_editor_view_actions_save (GSimpleAction *action,
                             GVariant      *param,
                             gpointer       user_data)
{
  GbEditorView *self = user_data;
  IdeContext *context;
  IdeBufferManager *buffer_manager;
  IdeFile *file;
  IdeProgress *progress = NULL;
  IdeVcs *vcs;
  GFile *workdir;

  g_assert (GB_IS_EDITOR_VIEW (self));

  file = ide_buffer_get_file (IDE_BUFFER (self->document));
  context = ide_buffer_get_context (IDE_BUFFER (self->document));
  buffer_manager = ide_context_get_buffer_manager (context);
  vcs = ide_context_get_vcs (context);
  workdir = ide_vcs_get_working_directory (vcs);

  if (ide_file_get_is_temporary (file))
    {
      GtkDialog *dialog;
      GtkWidget *toplevel;
      GtkWidget *suggested;

      toplevel = gtk_widget_get_toplevel (GTK_WIDGET (self));
      dialog = g_object_new (GTK_TYPE_FILE_CHOOSER_DIALOG,
                             "action", GTK_FILE_CHOOSER_ACTION_SAVE,
                             "do-overwrite-confirmation", TRUE,
                             "local-only", FALSE,
                             "modal", TRUE,
                             "select-multiple", FALSE,
                             "show-hidden", FALSE,
                             "transient-for", toplevel,
                             "title", _("Save Document"),
                             NULL);

      gtk_file_chooser_set_current_folder_file (GTK_FILE_CHOOSER (dialog), workdir, NULL);

      gtk_dialog_add_buttons (GTK_DIALOG (dialog),
                              _("Cancel"), GTK_RESPONSE_CANCEL,
                              _("Save"), GTK_RESPONSE_OK,
                              NULL);
      gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);

      suggested = gtk_dialog_get_widget_for_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
      gtk_style_context_add_class (gtk_widget_get_style_context (suggested),
                                   GTK_STYLE_CLASS_SUGGESTED_ACTION);

      g_signal_connect (dialog, "response", G_CALLBACK (save_temp_response), g_object_ref (self));

      gtk_window_present (GTK_WINDOW (dialog));

      return;
    }

  ide_buffer_manager_save_file_async (buffer_manager,
                                      IDE_BUFFER (self->document),
                                      file,
                                      &progress,
                                      NULL,
                                      save_file_cb,
                                      g_object_ref (self));
  g_object_bind_property (progress, "fraction", self->progress_bar, "fraction",
                          G_BINDING_SYNC_CREATE);
  gtk_widget_show (GTK_WIDGET (self->progress_bar));
  g_clear_object (&progress);
}