static gchar *
ide_xml_indenter_format (IdeIndenter *indenter,
                         GtkTextView *view,
                         GtkTextIter *begin,
                         GtkTextIter *end,
                         gint        *cursor_offset,
                         GdkEventKey *trigger)
{
  IdeXmlIndenter *xml = (IdeXmlIndenter *)indenter;
  guint tab_width = 2;
  gint indent_width = -1;

  g_return_val_if_fail (IDE_IS_XML_INDENTER (xml), NULL);

  *cursor_offset = 0;

  if (GTK_SOURCE_IS_VIEW (view))
    {
      tab_width = gtk_source_view_get_tab_width (GTK_SOURCE_VIEW (view));
      indent_width = gtk_source_view_get_indent_width (GTK_SOURCE_VIEW (view));
      if (indent_width != -1)
        tab_width = indent_width;
    }

  xml->tab_width = tab_width;
  xml->use_tabs = !gtk_source_view_get_insert_spaces_instead_of_tabs (GTK_SOURCE_VIEW (view));

  if (indent_width <= 0)
    xml->indent_width = tab_width;
  else
    xml->indent_width = indent_width;

  /* do nothing if we are in a cdata section */
  if (text_iter_in_cdata (begin))
    return NULL;

  switch (trigger->keyval)
    {
    case GDK_KEY_Return:
    case GDK_KEY_KP_Enter:
      if ((trigger->state & GDK_SHIFT_MASK) == 0)
        return ide_xml_indenter_indent (xml, begin, end, cursor_offset);
      return NULL;

    case GDK_KEY_slash:
      return ide_xml_indenter_maybe_unindent (xml, begin, end);

    case GDK_KEY_greater:
      return ide_xml_indenter_maybe_add_closing (xml, begin, end, cursor_offset);

    default:
      g_return_val_if_reached (NULL);
    }

  return NULL;
}
static void
gbp_retab_editor_page_addin_action (GSimpleAction *action,
                             GVariant      *variant,
                             gpointer       user_data)
{
  GbpRetabEditorPageAddin *self = user_data;
  IdeSourceView *source_view;
  GtkTextBuffer *buffer;
  IdeCompletion *completion;
  guint tab_width;
  gint start_line;
  gint end_line;
  gint indent;
  GtkTextIter begin;
  GtkTextIter end;
  gboolean editable;
  gboolean to_spaces;

  g_assert (GBP_IS_RETAB_EDITOR_PAGE_ADDIN (self));
  g_assert (G_IS_SIMPLE_ACTION (action));

  buffer = GTK_TEXT_BUFFER (ide_editor_page_get_buffer (self->editor_view));
  source_view = ide_editor_page_get_view (self->editor_view);

  g_assert (IDE_IS_SOURCE_VIEW (source_view));

  editable = gtk_text_view_get_editable (GTK_TEXT_VIEW (source_view));
  completion = ide_source_view_get_completion (IDE_SOURCE_VIEW (source_view));
  tab_width = gtk_source_view_get_tab_width(GTK_SOURCE_VIEW (source_view));
  to_spaces = gtk_source_view_get_insert_spaces_instead_of_tabs(GTK_SOURCE_VIEW (source_view));

  if (!editable)
    return;

  gtk_text_buffer_get_selection_bounds (buffer, &begin, &end);
  gtk_text_iter_order (&begin, &end);

  if (!gtk_text_iter_equal (&begin, &end) && gtk_text_iter_starts_line (&end))
    gtk_text_iter_backward_char (&end);

  start_line = gtk_text_iter_get_line (&begin);
  end_line = gtk_text_iter_get_line (&end);

  ide_completion_block_interactive (completion);
  gtk_text_buffer_begin_user_action (buffer);

  for (gint line = start_line; line <= end_line; ++line)
    {
      indent = get_buffer_range_indent (buffer, line, to_spaces);
      if (indent > 0)
        gbp_retab_editor_page_addin_retab (buffer, line, tab_width, indent, to_spaces);
    }

  gtk_text_buffer_end_user_action (buffer);
  ide_completion_unblock_interactive (completion);
}
Exemple #3
0
static gboolean
check_previous (GtkSourceView   *view,
                ModelineOptions *previous,
                ModelineSet      set)
{
	GtkSourceBuffer *buffer = GTK_SOURCE_BUFFER (gtk_text_view_get_buffer (GTK_TEXT_VIEW (view)));
	   
	/* Do not restore default when this is the first time */
	if (!previous)
		return FALSE;

	/* Do not restore default when previous was not set */
	if (!(previous->set & set))
		return FALSE;

	/* Only restore default when setting has not changed */
	switch (set)
	{
		case MODELINE_SET_INSERT_SPACES:
			return gtk_source_view_get_insert_spaces_instead_of_tabs (view) ==
			       previous->insert_spaces;
		break;
		case MODELINE_SET_TAB_WIDTH:
			return gtk_source_view_get_tab_width (view) == previous->tab_width;
		break;
		case MODELINE_SET_INDENT_WIDTH:
			return gtk_source_view_get_indent_width (view) == previous->indent_width;
		break;
		case MODELINE_SET_WRAP_MODE:
			return gtk_text_view_get_wrap_mode (GTK_TEXT_VIEW (view)) ==
			       previous->wrap_mode;
		break;
		case MODELINE_SET_RIGHT_MARGIN_POSITION:
			return gtk_source_view_get_right_margin_position (view) ==
			       previous->right_margin_position;
		break;
		case MODELINE_SET_SHOW_RIGHT_MARGIN:
			return gtk_source_view_get_show_right_margin (view) ==
			       previous->display_right_margin;
		break;
		case MODELINE_SET_LANGUAGE:
		{
			GtkSourceLanguage *language = gtk_source_buffer_get_language (buffer);
			
			return (language == NULL && previous->language_id == NULL) ||
			       (language != NULL && g_strcmp0 (gtk_source_language_get_id (language),
			                                       previous->language_id) == 0);
		}
		break;
		default:
			return FALSE;
		break;
	}
}
/**
 * gb_view_source_init:
 * @: (in): A #GbViewSource.
 *
 * Initializes the newly created #GbViewSource instance.
 */
static void
gb_view_source_init (GbViewSource *source)
{
    GbViewSourcePrivate *priv;
    GtkWidget *overlay;

    ENTRY;

    source->priv = priv =
                       G_TYPE_INSTANCE_GET_PRIVATE(source,
                               GB_TYPE_VIEW_SOURCE,
                               GbViewSourcePrivate);

    g_object_set(source,
                 "icon-name", GTK_STOCK_FILE,
                 "name", _("Unsaved Document"),
                 NULL);

    priv->buffer = gtk_source_buffer_new(NULL);
    g_signal_connect_swapped(priv->buffer,
                             "notify::cursor-position",
                             G_CALLBACK(gb_view_source_notify_cursor),
                             source);
    g_signal_connect_swapped(priv->buffer, "modified-changed",
                             G_CALLBACK(gb_view_source_buffer_modified_changed),
                             source);

    overlay = g_object_new(GTK_TYPE_OVERLAY,
                           "visible", TRUE,
                           NULL);
    g_signal_connect(overlay, "get-child-position",
                     G_CALLBACK(gb_view_source_position_progress),
                     NULL);
    gtk_container_add_with_properties(GTK_CONTAINER(source), overlay,
                                      "left-attach", 0,
                                      "width", 1,
                                      "top-attach", 0,
                                      "height", 1,
                                      NULL);

    priv->vpaned = g_object_new(GTK_TYPE_VPANED,
                                "visible", TRUE,
                                NULL);
    gtk_container_add(GTK_CONTAINER(overlay), priv->vpaned);

    priv->progress = g_object_new(GB_TYPE_PROGRESS_BAR,
                                  "visible", FALSE,
                                  NULL);
    gtk_overlay_add_overlay(GTK_OVERLAY(overlay), priv->progress);

    priv->scroller1 = g_object_new(gb_get_scrolled_window_gtype(),
                                   "expand", TRUE,
                                   "visible", TRUE,
                                   NULL);
    gtk_container_add_with_properties(GTK_CONTAINER(priv->vpaned), priv->scroller1,
                                      "shrink", FALSE,
                                      "resize", TRUE,
                                      NULL);

    priv->source1 = gb_view_source_create_source_view(source);
    gtk_container_add(GTK_CONTAINER(priv->scroller1), priv->source1);

    {
        GtkSourceLanguageManager *langs = gtk_source_language_manager_get_default();
        const gchar * const * ids = gtk_source_language_manager_get_language_ids(langs);
        GtkSourceLanguage *lang;
        const gchar *section;
        GHashTable *section_menu;
        GPtrArray *sorted;
        GtkWidget *controls = gb_view_get_controls(GB_VIEW(source));
        GtkWidget *menu;
        GtkWidget *mitem;
        GtkWidget *submenu;
        guint i;

        section_menu = g_hash_table_new(g_str_hash, g_str_equal);
        menu = gtk_menu_new();

        sorted = g_ptr_array_new();
        for (i = 0; ids[i]; i++) {
            lang = gtk_source_language_manager_get_language(langs, ids[i]);
            g_ptr_array_add(sorted, lang);
        }
        g_ptr_array_sort(sorted, lang_sort_func);
        for (i = 0; i < sorted->len; i++) {
            lang = g_ptr_array_index(sorted, i);
            section = gtk_source_language_get_section(lang);
            if (!(submenu = g_hash_table_lookup(section_menu, section))) {
                submenu = gtk_menu_new();
                mitem = g_object_new(GTK_TYPE_MENU_ITEM,
                                     "label", section,
                                     "submenu", submenu,
                                     "visible", TRUE,
                                     NULL);
                gtk_container_add(GTK_CONTAINER(menu), mitem);
                g_hash_table_insert(section_menu, (gchar*)section, submenu);
            }
            mitem = g_object_new(GTK_TYPE_MENU_ITEM,
                                 "label", gtk_source_language_get_name(lang),
                                 "visible", TRUE,
                                 NULL);
            g_signal_connect_swapped(mitem, "activate",
                                     G_CALLBACK(gb_view_source_lang_activate),
                                     source);
            g_object_set_data(G_OBJECT(mitem), "language-id",
                              (gchar *)gtk_source_language_get_id(lang));
            gtk_container_add(GTK_CONTAINER(submenu), mitem);
        }
        g_ptr_array_free(sorted, TRUE);

        priv->lang_combo = g_object_new(GB_TYPE_MENU_BUTTON,
                                        "hexpand", FALSE,
                                        "label", "",
                                        "menu", menu,
                                        "tooltip-text", _("Set source language."),
                                        "visible", TRUE,
                                        NULL);
        gb_widget_shrink_font(
            gb_menu_button_get_label_widget(
                GB_MENU_BUTTON(priv->lang_combo)));

        gtk_style_context_add_class(gtk_widget_get_style_context(priv->lang_combo),
                                    GB_STYLE_CLASS_TOP_BAR);
        gtk_container_add_with_properties(GTK_CONTAINER(controls), priv->lang_combo,
                                          "expand", FALSE,
                                          NULL);

        g_hash_table_unref(section_menu);
    }

    {
        GtkWidget *controls = gb_view_get_controls(GB_VIEW(source));
        GtkWidget *b;
        GtkWidget *item;
        GtkWidget *menu;
        GtkWidget *group = NULL;
        gboolean active;
        gchar *str;
        int tabs[] = { 2, 3, 4, 5, 8, 0 };
        int i;

        b = g_object_new(GB_TYPE_MENU_BUTTON,
                         "hexpand", FALSE,
                         "label", "4",
                         "tooltip-text", _("Set tab-character width."),
                         "visible", TRUE,
                         "width-request", 45,
                         NULL);

        menu = gtk_menu_new();
        for (i = 0; tabs[i]; i++) {
            str = g_strdup_printf("%d", tabs[i]);
            item = g_object_new(GTK_TYPE_RADIO_MENU_ITEM,
                                "group", group,
                                "label", str,
                                "visible", TRUE,
                                NULL);
            if (!group) {
                group = item;
            }
            active = (tabs[i] == gtk_source_view_get_tab_width(
                          GTK_SOURCE_VIEW(priv->source1)));
            g_object_set(item, "active", active, NULL);
            if (active) {
                g_object_set(b, "label", str, NULL);
            }
            g_signal_connect(item, "activate",
                             G_CALLBACK(gb_view_source_tab_size_activate),
                             source);
            gtk_container_add(GTK_CONTAINER(menu), item);
            g_free(str);
        }
        g_object_set(b, "menu", menu, NULL);

        item = g_object_new(GTK_TYPE_SEPARATOR_MENU_ITEM,
                            "visible", TRUE,
                            NULL);
        gtk_container_add(GTK_CONTAINER(menu), item);

        item = g_object_new(GTK_TYPE_CHECK_MENU_ITEM,
                            "active", TRUE,
                            "label", _("Use Spaces"),
                            "visible", TRUE,
                            NULL);
        g_signal_connect(item, "toggled",
                         G_CALLBACK(gb_view_source_spaces_toggled),
                         source);
        gtk_container_add(GTK_CONTAINER(menu), item);

        gb_widget_shrink_font(gb_menu_button_get_label_widget(GB_MENU_BUTTON(b)));
        gtk_style_context_add_class(gtk_widget_get_style_context(b),
                                    GB_STYLE_CLASS_TOP_BAR);
        gtk_container_add_with_properties(GTK_CONTAINER(controls), b,
                                          "expand", FALSE,
                                          NULL);
        priv->size_combo = b;
    }

    {
        GtkWidget *controls = gb_view_get_controls(GB_VIEW(source));
        GtkWidget *img;
        GtkWidget *b;

        img = g_object_new(GTK_TYPE_IMAGE,
                           "icon-name", "gb-split",
                           "icon-size", GTK_ICON_SIZE_MENU,
                           "visible", TRUE,
                           NULL);
        b = g_object_new(GTK_TYPE_TOGGLE_BUTTON,
                         "child", img,
                         "tooltip-text", _("Split the editor into two views."),
                         "visible", TRUE,
                         NULL);
        gtk_style_context_add_class(gtk_widget_get_style_context(b),
                                    GB_STYLE_CLASS_TOP_BAR);
        gtk_container_add_with_properties(GTK_CONTAINER(controls), b,
                                          "expand", FALSE,
                                          NULL);
        g_signal_connect(b, "toggled",
                         G_CALLBACK(split_toggled),
                         source);
    }

    {
        GtkWidget *hbox;
        GtkWidget *vp;
        GtkWidget *c;

        hbox = g_object_new(GTK_TYPE_HBOX,
                            "height-request", 30,
                            "visible", TRUE,
                            NULL);
        gtk_container_add_with_properties(GTK_CONTAINER(source), hbox,
                                          "height", 1,
                                          "left-attach", 0,
                                          "top-attach", 1,
                                          "width", 1,
                                          NULL);

        gtk_container_add(GTK_CONTAINER(hbox),
                          (c = g_object_new(GTK_TYPE_COMBO_BOX,
                                            "visible", TRUE,
                                            NULL)));
        gtk_style_context_add_class(gtk_widget_get_style_context(c),
                                    GB_STYLE_CLASS_BOTTOM_BAR);

        vp = g_object_new(GTK_TYPE_VIEWPORT,
                          "visible", TRUE,
                          NULL);
        gtk_style_context_add_class(gtk_widget_get_style_context(vp),
                                    GB_STYLE_CLASS_BOTTOM_BAR);
        gtk_container_add_with_properties(GTK_CONTAINER(hbox), vp,
                                          "expand", FALSE,
                                          "fill", TRUE,
                                          NULL);

        priv->pos_label = g_object_new(GTK_TYPE_LABEL,
                                       "label", _("Line 1, Column 1"),
                                       "visible", TRUE,
                                       "xalign", 1.0f,
                                       "xpad", 6,
                                       NULL);
        gb_widget_shrink_font(priv->pos_label);
        gtk_container_add(GTK_CONTAINER(vp), priv->pos_label);
    }

    priv->theme_handler =
        g_signal_connect_swapped(gtk_settings_get_default(),
                                 "notify::gtk-application-prefer-dark-theme",
                                 G_CALLBACK(gb_view_source_update_style),
                                 source);

    EXIT;
}