static void
ide_highlight_engine__unbind_buffer_cb (IdeHighlightEngine  *self,
                                        EggSignalGroup      *group)
{
    GtkTextBuffer *text_buffer;
    GtkTextTagTable *tag_table;
    GtkTextIter begin;
    GtkTextIter end;
    GSList *iter;

    IDE_ENTRY;

    g_assert (IDE_IS_HIGHLIGHT_ENGINE (self));
    g_assert (EGG_IS_SIGNAL_GROUP (group));

    text_buffer = GTK_TEXT_BUFFER (self->buffer);

    if (self->work_timeout)
    {
        g_source_remove (self->work_timeout);
        self->work_timeout = 0;
    }

    g_object_set_qdata (G_OBJECT (text_buffer), gEngineQuark, NULL);

    tag_table = gtk_text_buffer_get_tag_table (text_buffer);

    gtk_text_buffer_delete_mark (text_buffer, self->invalid_begin);
    gtk_text_buffer_delete_mark (text_buffer, self->invalid_end);

    self->invalid_begin = NULL;
    self->invalid_end = NULL;

    gtk_text_buffer_get_bounds (text_buffer, &begin, &end);

    for (iter = self->private_tags; iter; iter = iter->next)
    {
        gtk_text_buffer_remove_tag (text_buffer, iter->data, &begin, &end);
        gtk_text_tag_table_remove (tag_table, iter->data);
    }
    g_clear_pointer (&self->private_tags, g_slist_free);

    for (iter = self->public_tags; iter; iter = iter->next)
    {
        gtk_text_buffer_remove_tag (text_buffer, iter->data, &begin, &end);
        gtk_text_tag_table_remove (tag_table, iter->data);
    }
    g_clear_pointer (&self->public_tags, g_slist_free);

    ide_clear_weak_pointer (&self->buffer);

    IDE_EXIT;
}
static void
ide_highlight_engine_reload (IdeHighlightEngine *self)
{
    GtkTextBuffer *buffer;
    GtkTextIter begin;
    GtkTextIter end;
    GSList *iter;

    IDE_ENTRY;

    g_assert (IDE_IS_HIGHLIGHT_ENGINE (self));

    if (self->work_timeout != 0)
    {
        g_source_remove (self->work_timeout);
        self->work_timeout = 0;
    }

    if (self->buffer == NULL)
        IDE_EXIT;

    buffer = GTK_TEXT_BUFFER (self->buffer);

    gtk_text_buffer_get_bounds (buffer, &begin, &end);

    /*
     * Invalidate the whole buffer.
     */
    gtk_text_buffer_move_mark (buffer, self->invalid_begin, &begin);
    gtk_text_buffer_move_mark (buffer, self->invalid_end, &end);

    /*
     * Remove our highlight tags from the buffer.
     */
    for (iter = self->private_tags; iter; iter = iter->next)
        gtk_text_buffer_remove_tag (buffer, iter->data, &begin, &end);
    g_clear_pointer (&self->private_tags, g_slist_free);

    for (iter = self->public_tags; iter; iter = iter->next)
        gtk_text_buffer_remove_tag (buffer, iter->data, &begin, &end);
    g_clear_pointer (&self->public_tags, g_slist_free);

    if (self->highlighter == NULL)
        IDE_EXIT;

    ide_highlight_engine_queue_work (self);

    IDE_EXIT;
}
Пример #3
0
static void
gtkspell_free(GtkSpell *spell) {
	GtkTextBuffer *buffer;
	GtkTextTagTable *table;
	GtkTextIter start, end;

	buffer = gtk_text_view_get_buffer(spell->view);
	table = gtk_text_buffer_get_tag_table(buffer);

	gtk_text_buffer_get_bounds(buffer, &start, &end);
	gtk_text_buffer_remove_tag(buffer, spell->tag_highlight, &start, &end);
	gtk_text_tag_table_remove(table, spell->tag_highlight);

	gtk_text_buffer_delete_mark(buffer, spell->mark_insert);

	delete_aspell_speller(spell->speller);

	g_signal_handlers_disconnect_matched(spell->view,
			G_SIGNAL_MATCH_DATA,
			0, 0, NULL, NULL,
			spell);
	g_signal_handlers_disconnect_matched(buffer,
			G_SIGNAL_MATCH_DATA,
			0, 0, NULL, NULL,
			spell);
	g_free(spell);
}
Пример #4
0
static void
gbp_spell_navigator_select_misspelled_word (GbpSpellNavigator *self)
{
  GtkTextTag *tag;
  GtkTextIter begin;
  GtkTextIter end;

  g_assert (GBP_IS_SPELL_NAVIGATOR (self));

  if (self->view == NULL)
    return;

  if (self->buffer != NULL && NULL != (tag = get_misspelled_tag (self)))
    {
      gtk_text_buffer_get_iter_at_mark (self->buffer, &begin, self->start_boundary);
      gtk_text_buffer_get_iter_at_mark (self->buffer, &end, self->end_boundary);
      gtk_text_buffer_remove_tag (self->buffer, tag, &begin, &end);

      gtk_text_buffer_get_iter_at_mark (self->buffer, &begin, self->word_start);
      gtk_text_buffer_get_iter_at_mark (self->buffer, &end, self->word_end);
      gtk_text_buffer_apply_tag (self->buffer, tag, &begin, &end);

      gtk_widget_queue_draw (GTK_WIDGET (self->view));

      ide_source_view_scroll_to_mark (IDE_SOURCE_VIEW (self->view), self->word_start,
                                      0.25, TRUE, 1.0, 0.0, TRUE);
    }
}
Пример #5
0
void
gimp_text_buffer_set_color (GimpTextBuffer    *buffer,
                            const GtkTextIter *start,
                            const GtkTextIter *end,
                            const GimpRGB     *color)
{
  GList *list;

  g_return_if_fail (GIMP_IS_TEXT_BUFFER (buffer));
  g_return_if_fail (start != NULL);
  g_return_if_fail (end != NULL);

  if (gtk_text_iter_equal (start, end))
    return;

  gtk_text_buffer_begin_user_action (GTK_TEXT_BUFFER (buffer));

  for (list = buffer->color_tags; list; list = g_list_next (list))
    {
      gtk_text_buffer_remove_tag (GTK_TEXT_BUFFER (buffer), list->data,
                                  start, end);
    }

  if (color)
    {
      GtkTextTag *tag = gimp_text_buffer_get_color_tag (buffer, color);

      gtk_text_buffer_apply_tag (GTK_TEXT_BUFFER (buffer), tag,
                                 start, end);
    }

  gtk_text_buffer_end_user_action (GTK_TEXT_BUFFER (buffer));
}
Пример #6
0
void SourceEditor::expandLine(int line)
{
    if (!foldingEnabled())
        return;

    if (!m_foldsData[line].hasFold)
        return;

    if (!m_foldsData[line].collapsed)
        return;

    if (!static_cast<SourceFile &>(file()).structureUpdated())
        return;

    const SourceFile::StructureNode *node =
        static_cast<SourceFile &>(file()).structureNodeAt(line);
    assert(node && node->beginLine() == line);

    GtkTextBuffer *buffer = gtk_text_view_get_buffer(
        GTK_TEXT_VIEW(gtkSourceView()));
    GtkTextIter begin, end;
    gtk_text_buffer_get_iter_at_line(buffer, &begin, line + 1);
    gtk_text_buffer_get_iter_at_line(buffer, &end, node->endLine());
    gtk_text_buffer_remove_tag(buffer, tagInvisible, &begin, &end);
    m_foldsData[line].collapsed = false;

    // Check the states of the folds under this structure and apply the
    // invisible tag if collapsed.
    applyInvisibleTag(node);
}
Пример #7
0
static void
gimp_text_style_editor_tag_toggled (GtkToggleButton     *toggle,
                                    GimpTextStyleEditor *editor)
{
  GtkTextBuffer *buffer = GTK_TEXT_BUFFER (editor->buffer);
  GtkTextTag    *tag    = g_object_get_data (G_OBJECT (toggle), "tag");
  GList         *insert_tags;
  GList         *remove_tags;

  if (gtk_text_buffer_get_has_selection (buffer))
    {
      GtkTextIter start, end;

      gtk_text_buffer_get_selection_bounds (buffer, &start, &end);

      gtk_text_buffer_begin_user_action (buffer);

      if (gtk_toggle_button_get_active (toggle))
        {
          gtk_text_buffer_apply_tag (buffer, tag, &start, &end);
        }
      else
        {
          gtk_text_buffer_remove_tag (buffer, tag, &start, &end);
        }

      gtk_text_buffer_end_user_action (buffer);
    }

  insert_tags = gimp_text_style_editor_list_tags (editor, &remove_tags);
  gimp_text_buffer_set_insert_tags (editor->buffer, insert_tags, remove_tags);
}
Пример #8
0
void
utl_gui_text_buffer_toggle_tags (GtkTextBuffer *buffer, const gchar *tag_name) {

GtkTextTagTable *tag_table;
GtkTextTag *tag;
GtkTextIter start, end, titer;
gboolean itagged;
	
	tag_table = gtk_text_buffer_get_tag_table (buffer);
	tag = gtk_text_tag_table_lookup (tag_table, tag_name);
	
	g_return_if_fail (tag != NULL);

	gtk_text_buffer_get_selection_bounds (buffer, &start, &end);
	
	itagged = TRUE;

	for (titer = start; !gtk_text_iter_equal (&titer, &end); gtk_text_iter_forward_char (&titer)) {
		if ((itagged = gtk_text_iter_has_tag (&titer, tag)) == FALSE) {
			break;
		}
	}
	
	if (itagged) {
		gtk_text_buffer_remove_tag (buffer, tag, &start, &end);
	} else {
		gtk_text_buffer_apply_tag (buffer, tag, &start, &end);
	}
}
Пример #9
0
void
gui_editor_clear_all_highlights (GUIEditor * self)
{
  GtkTextIter buffer_start, buffer_end;

  gtk_text_buffer_get_bounds (GTK_TEXT_BUFFER(self->buffer), &buffer_start, &buffer_end);
  gtk_text_buffer_remove_tag (GTK_TEXT_BUFFER(self->buffer), self->hltag, &buffer_start, &buffer_end);
}
Пример #10
0
void Highlight::remove_previous_highlights(GtkTextBuffer * textbuffer)
// Removes previous highlights.
// Ensure that removing the tags does not influence the modified status of the textbuffer.
{
  GtkTextIter startiter;
  GtkTextIter enditer;
  gtk_text_buffer_get_start_iter(textbuffer, &startiter);
  gtk_text_buffer_get_end_iter(textbuffer, &enditer);
  bool modified_status = gtk_text_buffer_get_modified(textbuffer);
  gtk_text_buffer_remove_tag(textbuffer, mytag, &startiter, &enditer);
  if (!modified_status)
    gtk_text_buffer_set_modified(textbuffer, false);
}
Пример #11
0
static void
check_range(GtkSpell *spell, GtkTextBuffer *buffer,
            GtkTextIter start, GtkTextIter end) {
	/* we need to "split" on word boundaries.
	 * luckily, pango knows what "words" are 
	 * so we don't have to figure it out. */

	GtkTextIter wstart, wend;
	if (debug) {
		g_print("check_range: "); print_iter("s", &start); print_iter("e", &end); g_print(" -> ");
	}

	if (gtk_text_iter_inside_word(&end))
		gtk_text_iter_forward_word_end(&end);
	if (!gtk_text_iter_starts_word(&start)) {
		if (gtk_text_iter_inside_word(&start) || 
				gtk_text_iter_ends_word(&start)) {
			gtk_text_iter_backward_word_start(&start);
		} else {
			/* if we're neither at the beginning nor inside a word,
			 * me must be in some spaces.
			 * skip forward to the beginning of the next word. */
			//gtk_text_buffer_remove_tag(buffer, tag_highlight, &start, &end);
			if (gtk_text_iter_forward_word_end(&start))
				gtk_text_iter_backward_word_start(&start);
		}
	}
	gtk_text_buffer_remove_tag(buffer, spell->tag_highlight, &start, &end);

	if (debug) {print_iter("s", &start); print_iter("e", &end); g_print("\n");}

	wstart = start;
	while (gtk_text_iter_compare(&wstart, &end) < 0) {
		/* move wend to the end of the current word. */
		wend = wstart;
		gtk_text_iter_forward_word_end(&wend);

		check_word(spell, buffer, &wstart, &wend);

		/* now move wend to the beginning of the next word, */
		gtk_text_iter_forward_word_end(&wend);
		gtk_text_iter_backward_word_start(&wend);
		/* make sure we've actually advanced
		 * (we don't advance in some corner cases), */
		if (gtk_text_iter_equal(&wstart, &wend))
			break; /* we're done in these cases.. */
		/* and then pick this as the new next word beginning. */
		wstart = wend;
	}
}
Пример #12
0
void SourceEditor::onFileStructureUpdated()
{
    if (onFileStructureNodeUpdated(
        static_cast<SourceFile &>(file()).structureRoot()))
    {
        // Update the invisible tag.
        GtkTextBuffer *buffer = gtk_text_view_get_buffer(
            GTK_TEXT_VIEW(gtkSourceView()));
        GtkTextIter begin, end;
        gtk_text_buffer_get_start_iter(buffer, &begin);
        gtk_text_buffer_get_end_iter(buffer, &end);
        gtk_text_buffer_remove_tag(buffer, tagInvisible, &begin, &end);
        applyInvisibleTag(static_cast<SourceFile &>(file()).structureRoot());
        gtk_source_gutter_renderer_queue_draw(m_foldsRenderer);
    }
}
Пример #13
0
void
gui_editor_set_highlight (GUIEditor * self, guint line_no, gboolean set)
{
  g_assert (self);
  GtkTextIter line_start, line_end;

  /* get line bounds */
  gtk_text_buffer_get_iter_at_line (GTK_TEXT_BUFFER (self->buffer), &line_start, (line_no -1));
  line_end = line_start;
  gtk_text_iter_forward_to_line_end (&line_end);

  if (set)
	gtk_text_buffer_apply_tag (GTK_TEXT_BUFFER(self->buffer), self->hltag, &line_start, &line_end);
  else
	gtk_text_buffer_remove_tag (GTK_TEXT_BUFFER(self->buffer), self->hltag, &line_start, &line_end);
}
Пример #14
0
void SourceEditor::unhighlightAllTokens(int beginLine, int beginColumn,
                                        int endLine, int endColumn)
{
    GtkTextBuffer *buffer = gtk_text_view_get_buffer(
        GTK_TEXT_VIEW(gtkSourceView()));
    GtkTextIter begin, end;
    gtk_text_buffer_get_iter_at_line_index(buffer, &begin,
                                           beginLine, beginColumn);
    if (endLine == -1 && endColumn == -1)
        gtk_text_buffer_get_end_iter(buffer, &end);
    else
        gtk_text_buffer_get_iter_at_line_index(buffer, &end,
                                               endLine, endColumn);
    for (int i = 0; i < N_TOKEN_KINDS; ++i)
        gtk_text_buffer_remove_tag(buffer, tokenTags[i],
                                   &begin, &end);
}
Пример #15
0
static void
add_to_dictionary(GtkWidget *menuitem, GtkSpell *spell) {
	char *word;
	GtkTextIter start, end;
	GtkTextBuffer *buffer;
	
	buffer = gtk_text_view_get_buffer(spell->view);

	get_cur_word_extents(buffer, &start, &end);
	word = gtk_text_buffer_get_text(buffer, &start, &end, FALSE);
	
	aspell_speller_add_to_session(spell->speller, word, strlen(word));

	gtk_text_buffer_remove_tag(buffer, spell->tag_highlight, &start, &end);

	g_free(word);
}
Пример #16
0
void darken_code(int line, GtkTextTag *tag)
{
  GtkTextIter start, end;

  if (line == -1)
  {
    gtk_text_buffer_get_start_iter(code_textbuffer, &start);
    gtk_text_buffer_get_end_iter(code_textbuffer, &end);
  }
  else
  {
    gtk_text_buffer_get_iter_at_line(code_textbuffer, &start, line);
    end = start;
    gtk_text_iter_forward_to_line_end(&end);
  }

  gtk_text_buffer_remove_tag(code_textbuffer, tag, &start, &end);
}
Пример #17
0
static void
remove_tag_if_present (GtkTextBuffer *buffer,
                       GtkTextIter *where)
{
	GtkTextTagTable *tag_table;
	GtkTextTag *tag;
	GtkTextIter start, end;

	g_return_if_fail (buffer != NULL);
	g_return_if_fail (where != NULL);

	tag_table = gtk_text_buffer_get_tag_table (buffer);
	tag = gtk_text_tag_table_lookup (tag_table, E_BUFFER_TAGGER_LINK_TAG);
	g_return_if_fail (tag != NULL);

	if (get_tag_bounds (where, tag, &start, &end))
		gtk_text_buffer_remove_tag (buffer, tag, &start, &end);
}
static void
ide_highlight_engine_clear (IdeHighlightEngine *self)
{
    GtkTextIter begin;
    GtkTextIter end;

    g_assert (IDE_IS_HIGHLIGHT_ENGINE (self));

    if (self->buffer != NULL)
    {
        GtkTextBuffer *buffer = GTK_TEXT_BUFFER (self->buffer);
        GSList *iter;

        gtk_text_buffer_get_bounds (GTK_TEXT_BUFFER (self->buffer), &begin, &end);

        for (iter = self->public_tags; iter; iter = iter->next)
            gtk_text_buffer_remove_tag (buffer, iter->data, &begin, &end);
    }
}
Пример #19
0
static void
gbp_spell_buffer_addin_apply (GbpSpellBufferAddin *self)
{
  GspellTextBuffer *spell_buffer;

  IDE_ENTRY;

  g_assert (GBP_IS_SPELL_BUFFER_ADDIN (self));

  /* We might be disposed */
  if (self->buffer == NULL)
    return;

  spell_buffer = gspell_text_buffer_get_from_gtk_text_buffer (GTK_TEXT_BUFFER (self->buffer));

  if (!gbp_spell_buffer_addin_get_enabled (self))
    {
      GtkTextIter begin;
      GtkTextIter end;

      gspell_text_buffer_set_spell_checker (spell_buffer, NULL);
      g_clear_object (&self->spellchecker);

      gtk_text_buffer_get_bounds (GTK_TEXT_BUFFER (self->buffer), &begin, &end);
      gtk_text_buffer_remove_tag (GTK_TEXT_BUFFER (self->buffer),
                                  self->misspelled_tag, &begin, &end);

      return;
    }

  if (self->spellchecker == NULL)
    {

      /* Setup the spell checker for the buffer. We retrain the spellchecker
       * instance so that we can add words/modify the dictionary at runtime.
       */
      self->spellchecker = gspell_checker_new (NULL);
      gspell_text_buffer_set_spell_checker (spell_buffer, self->spellchecker);
    }

  IDE_EXIT;
}
Пример #20
0
void
gimp_text_buffer_pre_serialize (GimpTextBuffer *buffer,
                                GtkTextBuffer  *content)
{
  GtkTextIter iter;

  g_return_if_fail (GIMP_IS_TEXT_BUFFER (buffer));
  g_return_if_fail (GTK_IS_TEXT_BUFFER (content));

  gtk_text_buffer_get_start_iter (content, &iter);

  do
    {
      GSList *tags = gtk_text_iter_get_tags (&iter);
      GSList *list;

      for (list = tags; list; list = g_slist_next (list))
        {
          GtkTextTag *tag = list->data;

          if (g_list_find (buffer->kerning_tags, tag))
            {
              GtkTextIter end;

              gtk_text_buffer_insert_with_tags (content, &iter,
                                                WORD_JOINER, -1,
                                                tag, NULL);

              end = iter;
              gtk_text_iter_forward_char (&end);

              gtk_text_buffer_remove_tag (content, tag, &iter, &end);
              break;
            }
        }

      g_slist_free (tags);
    }
  while (gtk_text_iter_forward_char (&iter));
}
Пример #21
0
void SourceEditor::disableFolding()
{
    if (foldingEnabled())
    {
        m_foldsData.clear();

        GtkSourceView *view = gtkSourceView();
        GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(view));

        // Expand all folds.
        GtkTextIter begin, end;
        gtk_text_buffer_get_start_iter(buffer, &begin);
        gtk_text_buffer_get_end_iter(buffer, &end);
        gtk_text_buffer_remove_tag(buffer, tagInvisible, &begin, &end);

        GtkSourceGutter *gutter =
            gtk_source_view_get_gutter(view,
                                       GTK_TEXT_WINDOW_LEFT);
        gtk_source_gutter_remove(gutter, m_foldsRenderer);
        m_foldsRenderer = NULL;
    }
}
Пример #22
0
static void
remove_tag_to_word (GeditAutomaticSpellChecker *spell, const gchar *word)
{
	GtkTextIter iter;
	GtkTextIter match_start, match_end;

	gboolean found;

	gtk_text_buffer_get_iter_at_offset (GTK_TEXT_BUFFER (spell->doc), &iter, 0);

	found = TRUE;

	while (found)
	{
		found = gtk_text_iter_forward_search (&iter,
				word,
				GTK_TEXT_SEARCH_VISIBLE_ONLY | GTK_TEXT_SEARCH_TEXT_ONLY,
				&match_start,
				&match_end,
				NULL);

		if (found)
		{
			if (gtk_text_iter_starts_word (&match_start) &&
			    gtk_text_iter_ends_word (&match_end))
			{
				gtk_text_buffer_remove_tag (GTK_TEXT_BUFFER (spell->doc),
						spell->tag_highlight,
						&match_start,
						&match_end);
			}

			iter = match_end;
		}
	}
}
Пример #23
0
bool SourceEditor::setup()
{
    if (!TextEditor::setup(s_sharedTagTable))
        return false;

    const PropertyTree &prefs =
        Application::instance().preferences().child(TEXT_EDITOR);
    if (prefs.get<bool>(FOLD_STRUCTURED_TEXT))
    {
        // Need to remove the invisible tag that may be copied from the source
        // buffer.
        GtkTextBuffer *buffer = gtk_text_view_get_buffer(
            GTK_TEXT_VIEW(gtkSourceView()));
        GtkTextIter begin, end;
        gtk_text_buffer_get_start_iter(buffer, &begin);
        gtk_text_buffer_get_end_iter(buffer, &end);
        gtk_text_buffer_remove_tag(buffer, tagInvisible, &begin, &end);

        enableFolding();
        if (static_cast<SourceFile &>(file()).structureUpdated())
            onFileStructureUpdated();
    }
    return true;
}
Пример #24
0
void
gimp_text_buffer_insert (GimpTextBuffer *buffer,
                         const gchar    *text)
{
  GtkTextIter  iter, start;
  gint         start_offset;
  gboolean     insert_tags_set;
  GList       *insert_tags;
  GList       *remove_tags;
  GSList      *tags_off = NULL;

  g_return_if_fail (GIMP_IS_TEXT_BUFFER (buffer));

  gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (buffer), &iter,
                                    gtk_text_buffer_get_insert (GTK_TEXT_BUFFER (buffer)));

  start_offset = gtk_text_iter_get_offset (&iter);

  insert_tags_set = buffer->insert_tags_set;
  insert_tags     = buffer->insert_tags;
  remove_tags     = buffer->remove_tags;

  buffer->insert_tags_set = FALSE;
  buffer->insert_tags     = NULL;
  buffer->remove_tags     = NULL;

  tags_off = gtk_text_iter_get_toggled_tags (&iter, FALSE);

  gtk_text_buffer_begin_user_action (GTK_TEXT_BUFFER (buffer));

  gtk_text_buffer_insert (GTK_TEXT_BUFFER (buffer), &iter, text, -1);

  gtk_text_buffer_get_iter_at_offset (GTK_TEXT_BUFFER (buffer), &start,
                                      start_offset);

  if (insert_tags_set)
    {
      GList *list;

      for (list = remove_tags; list; list = g_list_next (list))
        {
          GtkTextTag *tag = list->data;

          gtk_text_buffer_remove_tag (GTK_TEXT_BUFFER (buffer), tag,
                                      &start, &iter);
        }

      for (list = insert_tags; list; list = g_list_next (list))
        {
          GtkTextTag *tag = list->data;

          gtk_text_buffer_apply_tag (GTK_TEXT_BUFFER (buffer), tag,
                                     &start, &iter);
        }
    }

  if (tags_off)
    {
      GSList *slist;

      for (slist = tags_off; slist; slist = g_slist_next (slist))
        {
          GtkTextTag *tag = slist->data;

          if (! g_list_find (remove_tags, tag) &&
              ! g_list_find (buffer->kerning_tags, tag))
            {
              gtk_text_buffer_apply_tag (GTK_TEXT_BUFFER (buffer), tag,
                                         &start, &iter);
            }
        }

      g_slist_free (tags_off);
    }

  g_list_free (remove_tags);
  g_list_free (insert_tags);

  gtk_text_buffer_end_user_action (GTK_TEXT_BUFFER (buffer));
}
Пример #25
0
static void
check_range (GeditAutomaticSpellChecker *spell,
	     GtkTextIter                 start,
	     GtkTextIter                 end,
	     gboolean                    force_all)
{
	/* we need to "split" on word boundaries.
	 * luckily, Pango knows what "words" are
	 * so we don't have to figure it out. */

	GtkTextIter wstart;
	GtkTextIter wend;
	GtkTextIter cursor;
	GtkTextIter precursor;
  	gboolean    highlight;

	/*
	g_print ("Check range: [%d - %d]\n", gtk_text_iter_get_offset (&start),
						gtk_text_iter_get_offset (&end));
	*/

	if (gtk_text_iter_inside_word (&end))
		gtk_text_iter_forward_word_end (&end);

	if (!gtk_text_iter_starts_word (&start))
	{
		if (gtk_text_iter_inside_word (&start) ||
		    gtk_text_iter_ends_word (&start))
		{
			gtk_text_iter_backward_word_start (&start);
		}
		else
		{
			/* if we're neither at the beginning nor inside a word,
			 * me must be in some spaces.
			 * skip forward to the beginning of the next word. */

			if (gtk_text_iter_forward_word_end (&start))
				gtk_text_iter_backward_word_start (&start);
		}
	}

	gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (spell->doc),
					  &cursor,
					  gtk_text_buffer_get_insert (GTK_TEXT_BUFFER (spell->doc)));

	precursor = cursor;
	gtk_text_iter_backward_char (&precursor);

  	highlight = gtk_text_iter_has_tag (&cursor, spell->tag_highlight) ||
  	            gtk_text_iter_has_tag (&precursor, spell->tag_highlight);

	gtk_text_buffer_remove_tag (GTK_TEXT_BUFFER (spell->doc),
				    spell->tag_highlight,
				    &start,
				    &end);

	/* Fix a corner case when replacement occurs at beginning of buffer:
	 * An iter at offset 0 seems to always be inside a word,
  	 * even if it's not.  Possibly a pango bug.
	 */
  	if (gtk_text_iter_get_offset (&start) == 0)
	{
		gtk_text_iter_forward_word_end(&start);
		gtk_text_iter_backward_word_start(&start);
	}

	wstart = start;

	while (gedit_spell_utils_skip_no_spell_check (&wstart, &end) &&
	       gtk_text_iter_compare (&wstart, &end) < 0)
	{
		gboolean inword;

		/* move wend to the end of the current word. */
		wend = wstart;

		gtk_text_iter_forward_word_end (&wend);

		inword = (gtk_text_iter_compare (&wstart, &cursor) < 0) &&
			 (gtk_text_iter_compare (&cursor, &wend) <= 0);

		if (inword && !force_all)
		{
			/* this word is being actively edited,
			 * only check if it's already highligted,
			 * otherwise defer this check until later. */
			if (highlight)
				check_word (spell, &wstart, &wend);
			else
				spell->deferred_check = TRUE;
		}
		else
		{
			check_word (spell, &wstart, &wend);
			spell->deferred_check = FALSE;
		}

		/* now move wend to the beginning of the next word, */
		gtk_text_iter_forward_word_end (&wend);
		gtk_text_iter_backward_word_start (&wend);

		/* make sure we've actually advanced
		 * (we don't advance in some corner cases), */
		if (gtk_text_iter_equal (&wstart, &wend))
			break; /* we're done in these cases.. */

		/* and then pick this as the new next word beginning. */
		wstart = wend;
	}
}
Пример #26
0
static void
gedit_automatic_spell_checker_free_internal (GeditAutomaticSpellChecker *spell)
{
	GtkTextTagTable *table;
	GtkTextIter start, end;
	GSList *list;

	g_return_if_fail (spell != NULL);

	table = gtk_text_buffer_get_tag_table (GTK_TEXT_BUFFER (spell->doc));

	if (table != NULL && spell->tag_highlight != NULL)
	{
		gtk_text_buffer_get_bounds (GTK_TEXT_BUFFER (spell->doc),
					    &start,
					    &end);
		gtk_text_buffer_remove_tag (GTK_TEXT_BUFFER (spell->doc),
					    spell->tag_highlight,
					    &start,
					    &end);

		g_signal_handlers_disconnect_matched (G_OBJECT (table),
					G_SIGNAL_MATCH_DATA,
					0, 0, NULL, NULL,
					spell);

		gtk_text_tag_table_remove (table, spell->tag_highlight);
	}

	g_signal_handlers_disconnect_matched (G_OBJECT (spell->doc),
			G_SIGNAL_MATCH_DATA,
			0, 0, NULL, NULL,
			spell);

	g_signal_handlers_disconnect_matched (G_OBJECT (spell->spell_checker),
			G_SIGNAL_MATCH_DATA,
			0, 0, NULL, NULL,
			spell);

	g_object_unref (spell->spell_checker);

	list = spell->views;
	while (list != NULL)
	{
		GeditView *view = GEDIT_VIEW (list->data);

		g_signal_handlers_disconnect_matched (G_OBJECT (view),
				G_SIGNAL_MATCH_DATA,
				0, 0, NULL, NULL,
				spell);

		g_signal_handlers_disconnect_matched (G_OBJECT (view),
			G_SIGNAL_MATCH_DATA,
			0, 0, NULL, NULL,
			spell);

		list = g_slist_next (list);
	}

	g_slist_free (spell->views);

	g_free (spell);
}
Пример #27
0
void
gimp_text_buffer_change_kerning (GimpTextBuffer    *buffer,
                                 const GtkTextIter *start,
                                 const GtkTextIter *end,
                                 gint               count)
{
  GtkTextIter  iter;
  GtkTextIter  span_start;
  GtkTextIter  span_end;
  GtkTextTag  *span_tag;
  gint         span_kerning;

  g_return_if_fail (GIMP_IS_TEXT_BUFFER (buffer));
  g_return_if_fail (start != NULL);
  g_return_if_fail (end != NULL);

  if (gtk_text_iter_equal (start, end))
    return;

  iter       = *start;
  span_start = *start;
  span_tag   = gimp_text_buffer_get_iter_kerning (buffer, &iter,
                                                  &span_kerning);

  gtk_text_buffer_begin_user_action (GTK_TEXT_BUFFER (buffer));

  do
    {
      GtkTextTag *iter_tag;
      gint        iter_kerning;

      gtk_text_iter_forward_char (&iter);

      iter_tag = gimp_text_buffer_get_iter_kerning (buffer, &iter,
                                                    &iter_kerning);

      span_end = iter;

      if (iter_kerning != span_kerning ||
          gtk_text_iter_compare (&iter, end) >= 0)
        {
          if (span_kerning != 0)
            {
              gtk_text_buffer_remove_tag (GTK_TEXT_BUFFER (buffer), span_tag,
                                          &span_start, &span_end);
            }

          if (span_kerning + count != 0)
            {
              span_tag = gimp_text_buffer_get_kerning_tag (buffer,
                                                           span_kerning + count);

              gtk_text_buffer_apply_tag (GTK_TEXT_BUFFER (buffer), span_tag,
                                         &span_start, &span_end);
            }

          span_start   = iter;
          span_kerning = iter_kerning;
          span_tag     = iter_tag;
        }

      /* We might have moved too far */
      if (gtk_text_iter_compare (&iter, end) > 0)
        iter = *end;
    }
  while (! gtk_text_iter_equal (&iter, end));

  gtk_text_buffer_end_user_action (GTK_TEXT_BUFFER (buffer));
}
Пример #28
0
gint
mousepad_util_highlight (GtkTextBuffer       *buffer,
                         GtkTextTag          *tag,
                         const gchar         *string,
                         MousepadSearchFlags  flags)
{
  GtkTextIter start, iter, end;
  GtkTextIter match_start, match_end;
  GtkTextIter cache_start, cache_end;
  gboolean    found, cached = FALSE;
  gint        counter = 0;

  g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), -1);
  g_return_val_if_fail (GTK_IS_TEXT_TAG (tag), -1);
  g_return_val_if_fail (string == NULL || g_utf8_validate (string, -1, NULL), -1);
  g_return_val_if_fail ((flags & MOUSEPAD_SEARCH_FLAGS_DIR_BACKWARD) == 0, -1);

  /* get the buffer bounds */
  gtk_text_buffer_get_bounds (buffer, &start, &end);

  /* remove all the highlight tags */
  gtk_text_buffer_remove_tag (buffer, tag, &start, &end);

  /* quit if there is nothing to highlight */
  if (string == NULL || *string == '\0' || flags & MOUSEPAD_SEARCH_FLAGS_ACTION_CLEANUP)
    return 0;

  /* get the search iters */
  mousepad_util_search_get_iters (buffer, flags, &start, &end, &iter);

  /* initialize cache iters */
  cache_start = cache_end = iter;

  /* highlight all the occurences of the strings */
  do
    {
      /* search for the next occurence of the string */
      found = mousepad_util_search_iter (&iter, string, flags, &match_start, &match_end, &end);

      if (G_LIKELY (found))
        {
          /* try to extend the cache */
          if (gtk_text_iter_equal (&cache_end, &match_start))
            {
              /* enable caching */
              cached = TRUE;
            }
          else
            {
              if (cached)
                {
                  /* highlight the cached occurences */
                  gtk_text_buffer_apply_tag (buffer, tag, &cache_start, &cache_end);

                  /* cache is flushed */
                  cached = FALSE;
                }

              /* highlight the matched occurence */
              gtk_text_buffer_apply_tag (buffer, tag, &match_start, &match_end);

              /* set the new cache start iter */
              cache_start = match_start;
            }

          /* set the end iters */
          iter = cache_end = match_end;

          /* increase the counter */
          counter++;
        }
      else if (G_UNLIKELY (cached))
        {
          /* flush the cached iters */
          gtk_text_buffer_apply_tag (buffer, tag, &cache_start, &cache_end);
        }
    }
  while (G_LIKELY (found));

  return counter;
}
Пример #29
0
static void
gb_source_view_update_search (GbSourceView *view)
{
   GbSourceViewPrivate *priv;
   GRegexCompileFlags flags = 0;
   GtkTextBuffer *buffer;
   GtkTextIter begin;
   GtkTextIter end;
   GMatchInfo *match_info = NULL;
   GtkTextTag *search_tag;
   gboolean has_matches = FALSE;
   GRegex *regex = NULL;
   gchar *text;
   gchar *escaped;

   g_assert(GB_IS_SOURCE_VIEW(view));

   priv = view->priv;

   buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(view));
   gtk_text_buffer_get_bounds(buffer, &begin, &end);

   search_tag = gb_source_view_ref_search_tag(view);
   gtk_text_buffer_remove_tag(buffer, search_tag, &begin, &end);

   if (g_str_empty0(priv->search_text) && !priv->search_regex) {
      goto cleanup;
   }

   if (priv->search_text) {
      if (!priv->search_case_sensitive) {
         flags = G_REGEX_CASELESS;
      }
      escaped = g_regex_escape_string(priv->search_text, -1);
      regex = g_regex_new(escaped, flags, 0, NULL);
      g_free(escaped);
   } else if (priv->search_regex) {
      regex = g_regex_ref(priv->search_regex);
   }

   if (regex) {
      text = gtk_text_buffer_get_text(buffer, &begin, &end, TRUE);
      if (g_regex_match(regex, text, 0, &match_info)) {
         guint count;
         guint i;
         gint begin_pos;
         gint end_pos;

         do {
            count = g_match_info_get_match_count(match_info);
            for (i = 0; i < count; i++) {
               if (g_match_info_fetch_pos(match_info, i, &begin_pos, &end_pos)) {
                  gtk_text_buffer_get_iter_at_offset(buffer, &begin, begin_pos);
                  gtk_text_buffer_get_iter_at_offset(buffer, &end, end_pos);
                  gtk_text_buffer_apply_tag(buffer, search_tag, &begin, &end);
                  has_matches = TRUE;
               }
            }
         } while (g_match_info_next(match_info, NULL));
      }
      g_match_info_free(match_info);
      g_regex_unref(regex);
      g_free(text);
   }

cleanup:
   if (priv->has_matches != has_matches) {
      priv->has_matches = has_matches;
      g_object_notify_by_pspec(G_OBJECT(view), gParamSpecs[PROP_HAS_MATCHES]);
   }

   gtk_widget_queue_draw(GTK_WIDGET(view));
   g_object_unref(search_tag);
}
Пример #30
0
/**
 * gtk_text_buffer_deserialize:
 * @register_buffer: the #GtkTextBuffer @format is registered with
 * @content_buffer: the #GtkTextBuffer to deserialize into
 * @format: the rich text format to use for deserializing
 * @iter: insertion point for the deserialized text
 * @data: (array length=length): data to deserialize
 * @length: length of @data
 * @error: return location for a #GError
 *
 * This function deserializes rich text in format @format and inserts
 * it at @iter.
 *
 * @format<!-- -->s to be used must be registered using
 * gtk_text_buffer_register_deserialize_format() or
 * gtk_text_buffer_register_deserialize_tagset() beforehand.
 *
 * Return value: %TRUE on success, %FALSE otherwise.
 *
 * Since: 2.10
 **/
gboolean
gtk_text_buffer_deserialize (GtkTextBuffer  *register_buffer,
                             GtkTextBuffer  *content_buffer,
                             GdkAtom         format,
                             GtkTextIter    *iter,
                             const guint8   *data,
                             gsize           length,
                             GError        **error)
{
  GList    *formats;
  GList    *list;

  g_return_val_if_fail (GTK_IS_TEXT_BUFFER (register_buffer), FALSE);
  g_return_val_if_fail (GTK_IS_TEXT_BUFFER (content_buffer), FALSE);
  g_return_val_if_fail (format != GDK_NONE, FALSE);
  g_return_val_if_fail (iter != NULL, FALSE);
  g_return_val_if_fail (data != NULL, FALSE);
  g_return_val_if_fail (length > 0, FALSE);
  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);

  formats = g_object_get_qdata (G_OBJECT (register_buffer),
                                deserialize_quark ());

  for (list = formats; list; list = g_list_next (list))
    {
      GtkRichTextFormat *fmt = list->data;

      if (fmt->atom == format)
        {
          GtkTextBufferDeserializeFunc function = fmt->function;
          gboolean                     success;
          GSList                      *split_tags;
          GSList                      *list;
          GtkTextMark                 *left_end        = NULL;
          GtkTextMark                 *right_start     = NULL;
          GSList                      *left_start_list = NULL;
          GSList                      *right_end_list  = NULL;

          /*  We don't want the tags that are effective at the insertion
           *  point to affect the pasted text, therefore we remove and
           *  remember them, so they can be re-applied left and right of
           *  the inserted text after pasting
           */
          split_tags = gtk_text_iter_get_tags (iter);

          list = split_tags;
          while (list)
            {
              GtkTextTag *tag = list->data;

              list = g_slist_next (list);

              /*  If a tag begins at the insertion point, ignore it
               *  because it doesn't affect the pasted text
               */
              if (gtk_text_iter_begins_tag (iter, tag))
                split_tags = g_slist_remove (split_tags, tag);
            }

          if (split_tags)
            {
              /*  Need to remember text marks, because text iters
               *  don't survive pasting
               */
              left_end = gtk_text_buffer_create_mark (content_buffer,
                                                      NULL, iter, TRUE);
              right_start = gtk_text_buffer_create_mark (content_buffer,
                                                         NULL, iter, FALSE);

              for (list = split_tags; list; list = g_slist_next (list))
                {
                  GtkTextTag  *tag             = list->data;
                  GtkTextIter *backward_toggle = gtk_text_iter_copy (iter);
                  GtkTextIter *forward_toggle  = gtk_text_iter_copy (iter);
                  GtkTextMark *left_start      = NULL;
                  GtkTextMark *right_end       = NULL;

                  gtk_text_iter_backward_to_tag_toggle (backward_toggle, tag);
                  left_start = gtk_text_buffer_create_mark (content_buffer,
                                                            NULL,
                                                            backward_toggle,
                                                            FALSE);

                  gtk_text_iter_forward_to_tag_toggle (forward_toggle, tag);
                  right_end = gtk_text_buffer_create_mark (content_buffer,
                                                           NULL,
                                                           forward_toggle,
                                                           TRUE);

                  left_start_list = g_slist_prepend (left_start_list, left_start);
                  right_end_list = g_slist_prepend (right_end_list, right_end);

                  gtk_text_buffer_remove_tag (content_buffer, tag,
                                              backward_toggle,
                                              forward_toggle);

                  gtk_text_iter_free (forward_toggle);
                  gtk_text_iter_free (backward_toggle);
                }

              left_start_list = g_slist_reverse (left_start_list);
              right_end_list = g_slist_reverse (right_end_list);
            }

          success = function (register_buffer, content_buffer,
                              iter, data, length,
                              fmt->can_create_tags,
                              fmt->user_data,
                              error);

          if (!success && error != NULL && *error == NULL)
            g_set_error (error, 0, 0,
                         _("Unknown error when trying to deserialize %s"),
                         gdk_atom_name (format));

          if (split_tags)
            {
              GSList      *left_list;
              GSList      *right_list;
              GtkTextIter  left_e;
              GtkTextIter  right_s;

              /*  Turn the remembered marks back into iters so they
               *  can by used to re-apply the remembered tags
               */
              gtk_text_buffer_get_iter_at_mark (content_buffer,
                                                &left_e, left_end);
              gtk_text_buffer_get_iter_at_mark (content_buffer,
                                                &right_s, right_start);

              for (list = split_tags,
                     left_list = left_start_list,
                     right_list = right_end_list;
                   list && left_list && right_list;
                   list = g_slist_next (list),
                     left_list = g_slist_next (left_list),
                     right_list = g_slist_next (right_list))
                {
                  GtkTextTag  *tag        = list->data;
                  GtkTextMark *left_start = left_list->data;
                  GtkTextMark *right_end  = right_list->data;
                  GtkTextIter  left_s;
                  GtkTextIter  right_e;

                  gtk_text_buffer_get_iter_at_mark (content_buffer,
                                                    &left_s, left_start);
                  gtk_text_buffer_get_iter_at_mark (content_buffer,
                                                    &right_e, right_end);

                  gtk_text_buffer_apply_tag (content_buffer, tag,
                                             &left_s, &left_e);
                  gtk_text_buffer_apply_tag (content_buffer, tag,
                                             &right_s, &right_e);

                  gtk_text_buffer_delete_mark (content_buffer, left_start);
                  gtk_text_buffer_delete_mark (content_buffer, right_end);
                }

              gtk_text_buffer_delete_mark (content_buffer, left_end);
              gtk_text_buffer_delete_mark (content_buffer, right_start);

              g_slist_free (split_tags);
              g_slist_free (left_start_list);
              g_slist_free (right_end_list);
            }

          return success;
        }
    }

  g_set_error (error, 0, 0,
               _("No deserialize function found for format %s"),
               gdk_atom_name (format));

  return FALSE;
}