示例#1
0
文件: gtkspell.c 项目: jmissig/gabber
static void
print_iter(char *name, GtkTextIter *iter) {
	g_print("%1s[%d%c%c%c] ", name, gtk_text_iter_get_offset(iter),
		gtk_text_iter_starts_word(iter) ? 's' : ' ',
		gtk_text_iter_inside_word(iter) ? 'i' : ' ',
		gtk_text_iter_ends_word(iter) ? 'e' : ' ');
}
示例#2
0
bool Gobby::FindDialog::find_range(const GtkTextIter* from,
                                   const GtkTextIter* to,
                                   SearchDirection direction,
                                   GtkTextIter* match_start,
                                   GtkTextIter* match_end)
{
	GtkTextIter start_pos = *from;
	while(find_range_once(&start_pos, to, direction,
	                      match_start, match_end))
	{
		if(m_check_whole_word->get_active() )
		{
			if(!gtk_text_iter_starts_word(match_start) ||
			   !gtk_text_iter_ends_word(match_end))
			{
				if(direction == SEARCH_FORWARD)
					start_pos = *match_end;
				else
					start_pos = *match_start;

				continue;
			}
		}

		return true;
	}

	return false;
}
示例#3
0
gboolean
_gtk_source_iter_ends_extra_natural_word (const GtkTextIter *iter,
					  gboolean           visible)
{
	GtkTextIter prev;
	gboolean ends_word;

	prev = *iter;
	if (!backward_cursor_position (&prev, visible))
	{
		return FALSE;
	}

	ends_word = gtk_text_iter_ends_word (iter);

	if (gtk_text_iter_is_end (iter))
	{
		return ends_word || gtk_text_iter_get_char (&prev) == '_';
	}

	if (ends_word)
	{
		return gtk_text_iter_get_char (iter) != '_';
	}

	return (gtk_text_iter_get_char (&prev) == '_' &&
		gtk_text_iter_get_char (iter) != '_' &&
		!gtk_text_iter_starts_word (iter));
}
static void
do_title_case (GtkTextBuffer *buffer,
               GtkTextIter   *start,
               GtkTextIter   *end)
{
	GString *s = g_string_new (NULL);

	while (!gtk_text_iter_is_end (start) &&
	       !gtk_text_iter_equal (start, end))
	{
		gunichar c, nc;

		c = gtk_text_iter_get_char (start);
		if (gtk_text_iter_starts_word (start))
			nc = g_unichar_totitle (c);
		else
			nc = g_unichar_tolower (c);
		g_string_append_unichar (s, nc);

		gtk_text_iter_forward_char (start);
	}

	gtk_text_buffer_delete_selection (buffer, TRUE, TRUE);
	gtk_text_buffer_insert_at_cursor (buffer, s->str, s->len);

	g_string_free (s, TRUE);
}
示例#5
0
static void
update_words (ExampleAppWindow *win)
{
  ExampleAppWindowPrivate *priv;
  GHashTable *strings;
  GHashTableIter iter;
  GtkWidget *tab, *view, *row;
  GtkTextBuffer *buffer;
  GtkTextIter start, end;
  GList *children, *l;
  gchar *word, *key;

  priv = example_app_window_get_instance_private (win);

  tab = gtk_stack_get_visible_child (GTK_STACK (priv->stack));

  if (tab == NULL)
    return;

  view = gtk_bin_get_child (GTK_BIN (tab));
  buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));

  strings = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);

  gtk_text_buffer_get_start_iter (buffer, &start);
  while (!gtk_text_iter_is_end (&start))
    {
      while (!gtk_text_iter_starts_word (&start))
        {
          if (!gtk_text_iter_forward_char (&start))
            goto done;
        }
      end = start;
      if (!gtk_text_iter_forward_word_end (&end))
        goto done;
      word = gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
      g_hash_table_add (strings, g_utf8_strdown (word, -1));
      g_free (word);
      start = end;
    }

done:
  children = gtk_container_get_children (GTK_CONTAINER (priv->words));
  for (l = children; l; l = l->next)
    gtk_container_remove (GTK_CONTAINER (priv->words), GTK_WIDGET (l->data));
  g_list_free (children);

  g_hash_table_iter_init (&iter, strings);
  while (g_hash_table_iter_next (&iter, (gpointer *)&key, NULL))
    {
      row = gtk_button_new_with_label (key);
      g_signal_connect (row, "clicked",
                        G_CALLBACK (find_word), win);
      gtk_widget_show (row);
      gtk_container_add (GTK_CONTAINER (priv->words), row);
    }

  g_hash_table_unref (strings);
}
示例#6
0
文件: gtkspell.c 项目: jmissig/gabber
static void
get_cur_word_extents(GtkTextBuffer *buffer,
                     GtkTextIter *start, GtkTextIter *end) {
	gtk_text_buffer_get_iter_at_mark(buffer, start, 
			gtk_text_buffer_get_insert(buffer));
	if (!gtk_text_iter_starts_word(start)) 
		gtk_text_iter_backward_word_start(start);
	*end = *start;
	if (gtk_text_iter_inside_word(end))
		gtk_text_iter_forward_word_end(end);
}
示例#7
0
static void
update_current (GeditDocument *doc,
		gint           current)
{
	CheckRange *range;
	GtkTextIter iter;
	GtkTextIter end_iter;

	gedit_debug (DEBUG_PLUGINS);

	g_return_if_fail (doc != NULL);
	g_return_if_fail (current >= 0);

	range = get_check_range (doc);
	g_return_if_fail (range != NULL);

	gtk_text_buffer_get_iter_at_offset (GTK_TEXT_BUFFER (doc), 
					    &iter, current);

	if (!gtk_text_iter_inside_word (&iter))
	{	
		/* if we're not inside a word,
		 * we must be in some spaces.
		 * skip forward to the beginning of the next word. */
		if (!gtk_text_iter_is_end (&iter))
		{
			gtk_text_iter_forward_word_end (&iter);
			gtk_text_iter_backward_word_start (&iter);	
		}
	}
	else
	{
		if (!gtk_text_iter_starts_word (&iter))
			gtk_text_iter_backward_word_start (&iter);	
	}

	gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (doc),
					  &end_iter,
					  range->end_mark);

	if (gtk_text_iter_compare (&end_iter, &iter) < 0)
	{	
		gtk_text_buffer_move_mark (GTK_TEXT_BUFFER (doc),
					   range->current_mark,
					   &end_iter);
	}
	else
	{
		gtk_text_buffer_move_mark (GTK_TEXT_BUFFER (doc),
					   range->current_mark,
					   &iter);
	}
}
示例#8
0
文件: gtkspell.c 项目: jmissig/gabber
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;
	}
}
示例#9
0
文件: chat.c 项目: mjpak0109/linphone
static void insert_link_tags(GtkTextBuffer *buffer, const GtkTextIter *begin, const GtkTextIter *end) {
	GtkTextIter iter = *begin;
	while(gtk_text_iter_compare(&iter, end) < 0) {
		if(gtk_text_iter_starts_word(&iter) && (
				word_starts_with(&iter, "http://") ||
				word_starts_with(&iter, "https://") ||
				word_starts_with(&iter, "ftp://") ||
				word_starts_with(&iter, "ftps://"))) {
			GtkTextIter uri_begin = iter;
			if(gtk_text_iter_forward_find_char(&iter, is_space, NULL, end)) {
				gtk_text_buffer_apply_tag_by_name(buffer, "link", &uri_begin, &iter);
			}
		}
		gtk_text_iter_forward_char(&iter);
	}
}
static void
get_word_extents_from_mark (GtkTextBuffer *buffer,
			    GtkTextIter   *start,
			    GtkTextIter   *end,
			    GtkTextMark   *mark)
{
	gtk_text_buffer_get_iter_at_mark(buffer, start, mark);

	if (!gtk_text_iter_starts_word (start))
		gtk_text_iter_backward_word_start (start);

	*end = *start;

	if (gtk_text_iter_inside_word (end))
		gtk_text_iter_forward_word_end (end);
}
示例#11
0
void
gimp_text_tool_editor_button_press (GimpTextTool        *text_tool,
                                    gdouble              x,
                                    gdouble              y,
                                    GimpButtonPressType  press_type)
{
  GtkTextBuffer *buffer = GTK_TEXT_BUFFER (text_tool->buffer);
  GtkTextIter    cursor;
  GtkTextIter    selection;

  gimp_text_tool_xy_to_iter (text_tool, x, y, &cursor);

  selection = cursor;

  text_tool->select_start_iter = cursor;
  text_tool->select_words      = FALSE;
  text_tool->select_lines      = FALSE;

  switch (press_type)
    {
    case GIMP_BUTTON_PRESS_NORMAL:
      gtk_text_buffer_place_cursor (buffer, &cursor);
      break;

    case GIMP_BUTTON_PRESS_DOUBLE:
      text_tool->select_words = TRUE;

      if (! gtk_text_iter_starts_word (&cursor))
        gtk_text_iter_backward_visible_word_starts (&cursor, 1);

      if (! gtk_text_iter_ends_word (&selection) &&
          ! gtk_text_iter_forward_visible_word_ends (&selection, 1))
        gtk_text_iter_forward_to_line_end (&selection);

      gtk_text_buffer_select_range (buffer, &cursor, &selection);
      break;

    case GIMP_BUTTON_PRESS_TRIPLE:
      text_tool->select_lines = TRUE;

      gtk_text_iter_set_line_offset (&cursor, 0);
      gtk_text_iter_forward_to_line_end (&selection);

      gtk_text_buffer_select_range (buffer, &cursor, &selection);
      break;
    }
}
示例#12
0
/* Extends the definition of a natural-language word used by Pango. The
 * underscore is added to the possible characters of a natural-language word.
 */
void
_gtk_source_iter_forward_extra_natural_word_end (GtkTextIter *iter)
{
	GtkTextIter next_word_end = *iter;
	GtkTextIter next_underscore_end = *iter;
	GtkTextIter *limit = NULL;
	gboolean found;

	if (gtk_text_iter_forward_visible_word_end (&next_word_end))
	{
		limit = &next_word_end;
	}

	found = gtk_text_iter_forward_search (iter,
					      "_",
					      GTK_TEXT_SEARCH_VISIBLE_ONLY | GTK_TEXT_SEARCH_TEXT_ONLY,
					      NULL,
					      &next_underscore_end,
					      limit);

	if (found)
	{
		*iter = next_underscore_end;
	}
	else
	{
		*iter = next_word_end;
	}

	while (TRUE)
	{
		if (gtk_text_iter_get_char (iter) == '_')
		{
			gtk_text_iter_forward_visible_cursor_position (iter);
		}
		else if (gtk_text_iter_starts_word (iter))
		{
			gtk_text_iter_forward_visible_word_end (iter);
		}
		else
		{
			break;
		}
	}
}
示例#13
0
gboolean
ide_editor_spell_utils_text_iter_inside_word (const GtkTextIter *iter)
{
  g_return_val_if_fail (iter != NULL, FALSE);

  if (gtk_text_iter_inside_word (iter))
    return TRUE;

  if (gtk_text_iter_ends_word (iter) &&
      is__text_iter_apostrophe_or_dash (iter))
    {
      GtkTextIter next_char = *iter;
      gtk_text_iter_forward_char (&next_char);
      return gtk_text_iter_starts_word (&next_char);
    }

  return FALSE;
}
示例#14
0
gboolean
ide_editor_spell_utils_text_iter_starts_word (const GtkTextIter *iter)
{
  GtkTextIter prev_char;

  g_return_val_if_fail (iter != NULL, FALSE);

  if (!gtk_text_iter_starts_word (iter))
    return FALSE;

  prev_char = *iter;
  if (!gtk_text_iter_backward_char (&prev_char))
    return TRUE;

  if (is__text_iter_apostrophe_or_dash (&prev_char) &&
      gtk_text_iter_ends_word (&prev_char))
    return FALSE;

  return TRUE;
}
示例#15
0
gboolean
mousepad_util_iter_starts_word (const GtkTextIter *iter)
{
  GtkTextIter prev;

  /* normal gtk word start */
  if (!gtk_text_iter_starts_word (iter))
    return FALSE;

  /* init iter for previous char */
  prev = *iter;

  /* return true when we could not step backwards (start of buffer) */
  if (!gtk_text_iter_backward_char (&prev))
    return TRUE;

  /* check if the previous char also belongs to the word */
  if (mousepad_util_iter_word_characters (&prev))
    return FALSE;

  return TRUE;
}
示例#16
0
gboolean
ide_editor_spell_utils_text_iter_forward_word_end (GtkTextIter *iter)
{
  g_return_val_if_fail (iter != NULL, FALSE);

  while (gtk_text_iter_forward_word_end (iter))
    {
      GtkTextIter next_char;

      if (!is__text_iter_apostrophe_or_dash (iter))
        return TRUE;

      next_char = *iter;
      gtk_text_iter_forward_char (&next_char);
      if (!gtk_text_iter_starts_word (&next_char))
        return TRUE;

      *iter = next_char;
    }

  return FALSE;
}
示例#17
0
gboolean
gbp_spell_utils_text_iter_ends_word (const GtkTextIter *iter)
{
  GtkTextIter next_char;

  g_return_val_if_fail (iter != NULL, FALSE);

  if (!gtk_text_iter_ends_word (iter))
    return FALSE;

  if (gtk_text_iter_is_end (iter))
    return TRUE;

  next_char = *iter;
  gtk_text_iter_forward_char (&next_char);

  if (is__text_iter_apostrophe_or_dash (iter) &&
      gtk_text_iter_starts_word (&next_char))
    return FALSE;

  return TRUE;
}
示例#18
0
文件: console.c 项目: aylusltd/gretl
static gint console_complete_word (GtkTextBuffer *buf,
				   GtkTextIter *iter)
{
    GtkTextIter start, end;
    const char *targ = NULL;
    gchar *src;

    start = end = *iter;

    if (!gtk_text_iter_starts_word(&start)) {
	gtk_text_iter_backward_word_start(&start);
    }

    if (!gtk_text_iter_ends_word(&end)) {
	gtk_text_iter_forward_word_end(&end);
    }

    src = gtk_text_buffer_get_text(buf, &start, &end, FALSE);

    if (src != NULL && *src != '\0') {
	if (gtk_text_iter_get_line_offset(&start) == 2) {
	    /* first word on line */
	    targ = gretl_command_complete(src);
	} else {
	    targ = console_varname_complete(src);
	}
	if (targ != NULL) {
	    gtk_text_buffer_delete(buf, &start, &end);
	    gtk_text_buffer_insert(buf, &start, targ, -1);
	} else {
	    console_beep();
	}
    } 

    g_free(src);

    return TRUE;
}
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;
		}
	}
}
示例#20
0
/**
@brief Search backward from @a iter to try to find next match of @a str in textbuffer

This is like gtk_text_iter_backward_search(), but supports case-insensitive
and whole-word searching.
See comments for e2_iter_forward_search().

@param  iter a GtkTextIter where the search begins
@param  str search string, may include 1 or more \n
@param  flags bitmask of flags affecting the search
@param  match_start return location for start of match, or NULL
@param  match_end return location for end of match, or NULL
@param  limit lower bound of match end, or NULL for start of buffer

@return TRUE if a match was found
*/
gboolean e2_iter_backward_search (
		const GtkTextIter   *iter,
		const gchar         *str,
		E2TextSearchFlags    flags,
		GtkTextIter         *match_start,
		GtkTextIter         *match_end,
		const GtkTextIter   *limit)
{
	gboolean visible_only, slice, retval;
	GtkTextIter search, match;

	g_return_val_if_fail (iter != NULL, FALSE);
	g_return_val_if_fail (str != NULL, FALSE);

	if (!(flags & E2_SEARCH_CASE_INSENSITIVE))
	{
		search = *iter;
rescan:
		retval = gtk_text_iter_backward_search (&search, str, flags,
						      match_start, match_end, limit);
		if (retval && (flags & E2_SEARCH_WHOLE_WORD)
					&& (!gtk_text_iter_starts_word (match_start)
//see comment above re end-checking when highlighting || !gtk_text_iter_ends_word (match_end)
		))
		{
			search = *match_start;
			if (gtk_text_iter_backward_char (&search))
				goto rescan;
			retval = FALSE;
		}
		return retval;
	}

	if (limit != NULL && gtk_text_iter_compare (iter, limit) < 0)
		return FALSE;

	if (*str == '\0') //matching nothing
	{
		//if we can move one char, return that location for the match
		match = *iter;
		if (gtk_text_iter_backward_char (&match))
		{
			if (limit == NULL || gtk_text_iter_compare (&match, limit) >= 0)
			{
				if (match_start != NULL)
					*match_start = match;
				if (match_end != NULL)
					*match_end = match;
				return TRUE;
			}
		}
		return FALSE;
	}

	//split search string into lines
	gchar **lines = e2_utils_str_breakup (str, "\n", -1);
	if (lines == NULL)
		return FALSE;	//FIXME warn user about error

	visible_only = (flags & E2_SEARCH_VISIBLE_ONLY) != 0;
	slice = (flags & E2_SEARCH_TEXT_ONLY) == 0;
	retval = FALSE;
	search = *iter;

	while (TRUE)
	{
		/* This loop has an inefficient worst-case, where
		   gtk_text_iter_get_text() is called repeatedly on each single line */
		GtkTextIter end;
rescan2:
		if (limit != NULL && gtk_text_iter_compare (&search, limit) < 0)
			break;

		if (_e2_textiter_backward_lines_match (&search, (const gchar**)lines,
					  visible_only, slice, &match, &end))
		{
			if (limit == NULL || gtk_text_iter_compare (&end, limit) >= 0)
			{
				if ((flags & E2_SEARCH_WHOLE_WORD) &&
				(!gtk_text_iter_starts_word (&match)
//see comment above re end-checking when highlighting || !gtk_text_iter_ends_word (&end)
					))
				{
					search = match;
					if (gtk_text_iter_backward_char (&search))
						goto rescan2;
				}
				else
				{
					retval = TRUE;
					if (match_start)
						*match_start = match;
					if (match_end)
						*match_end = end;
				}
			}
			break;
		}

		if (gtk_text_iter_get_line_offset (&search) == 0)	//at start of line
		{
			if (!gtk_text_iter_backward_line (&search))	//can't move to start of previous line
				break;
		}
		else
			gtk_text_iter_set_line_offset (&search, 0);	//go to start of current line and check again
	}

	g_strfreev (lines);

	return retval;
}
示例#21
0
bool searchwords_find_fast (const ustring& text, 
                            const vector <ustring>& searchwords,
							const vector <bool>& wholewords,
							const vector <bool>& casesensitives, 
                            vector <size_t>& startpositions,
							vector <size_t>& lengths)
// Finds occurrences of searchwords in the text.
// text: Text to be looked through.
// searchwords: Search words to look for.
// wholewords / casesensitives: Attributes of the searchwords.
// startpositions: If non-NULL, will be filled with the positions that each searchword starts at.
// lengths: If non-NULL, will be filled with the lengths of the searchwords found.
// Returns whether one or more searchwords were found in the text.
{
  // Clear output containers.
  startpositions.clear();
  lengths.clear();

  // A textbuffer makes searching text easier in this case.
  GtkTextBuffer * textbuffer = gtk_text_buffer_new (NULL);
  gtk_text_buffer_set_text (textbuffer, text.c_str(), -1);
  GtkTextIter startiter;
  gtk_text_buffer_get_start_iter(textbuffer, &startiter);

  bool found = false;

  // Go through all words to look for.
  for (unsigned int i2 = 0; i2 < searchwords.size(); i2++) {

    // Define this search word and its parameters.
    ustring searchword = searchwords[i2];
    bool wholeword = wholewords[i2];
    bool casesensitive = casesensitives[i2];

    // Handle case sensitivity.
    ustring mytext;
    ustring mysearchword;
    if (casesensitive) {
      mytext = text;
      mysearchword = searchword;
    } else {
      mytext = text.casefold();
      mysearchword = searchword.casefold();
    }
    // Find all occurrences of the word.
    size_t position = mytext.find(mysearchword);
    while (position != string::npos) {
      bool temporally_approved = true;
      GtkTextIter approvedstart = startiter;
      GtkTextIter approvedend;
      gtk_text_iter_forward_chars(&approvedstart, position);
      approvedend = approvedstart;
      gtk_text_iter_forward_chars(&approvedend, searchword.length());
      if (wholeword) {
        if (!gtk_text_iter_starts_word(&approvedstart))
          temporally_approved = false;
        if (!gtk_text_iter_ends_word(&approvedend))
          temporally_approved = false;
      }
      if (temporally_approved) {
        found = true;
        startpositions.push_back (position);
        lengths.push_back (searchword.length());
      }
      position = mytext.find(mysearchword, ++position);
    }
  }
 
  // Free textbuffer used.
  g_object_unref (textbuffer);  

  if (found) {
    // Sort the output.
    quick_sort (startpositions, lengths, 0, (unsigned int)startpositions.size());
    // Overlapping items need to be combined to avoid crashes.
    xml_combine_overlaps (startpositions, lengths);
  }

  // Return true if anything was found.  
  return found;
}
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;
	}
}
示例#23
0
static void
gimp_text_tool_delete_from_cursor (GimpTextTool  *text_tool,
                                   GtkDeleteType  type,
                                   gint           count)
{
  GtkTextBuffer *buffer = GTK_TEXT_BUFFER (text_tool->buffer);
  GtkTextIter    cursor;
  GtkTextIter    end;

  GIMP_LOG (TEXT_EDITING, "%s count = %d",
            g_enum_get_value (g_type_class_ref (GTK_TYPE_DELETE_TYPE),
                              type)->value_name,
            count);

  gimp_text_tool_reset_im_context (text_tool);

  gtk_text_buffer_get_iter_at_mark (buffer, &cursor,
                                    gtk_text_buffer_get_insert (buffer));
  end = cursor;

  switch (type)
    {
    case GTK_DELETE_CHARS:
      if (gtk_text_buffer_get_has_selection (buffer))
        {
          gtk_text_buffer_delete_selection (buffer, TRUE, TRUE);
          return;
        }
      else
        {
          gtk_text_iter_forward_cursor_positions (&end, count);
        }
      break;

    case GTK_DELETE_WORD_ENDS:
      if (count < 0)
        {
          if (! gtk_text_iter_starts_word (&cursor))
            gtk_text_iter_backward_visible_word_starts (&cursor, 1);
        }
      else if (count > 0)
        {
          if (! gtk_text_iter_ends_word (&end) &&
              ! gtk_text_iter_forward_visible_word_ends (&end, 1))
            gtk_text_iter_forward_to_line_end (&end);
        }
      break;

    case GTK_DELETE_WORDS:
      if (! gtk_text_iter_starts_word (&cursor))
        gtk_text_iter_backward_visible_word_starts (&cursor, 1);

      if (! gtk_text_iter_ends_word (&end) &&
          ! gtk_text_iter_forward_visible_word_ends (&end, 1))
        gtk_text_iter_forward_to_line_end (&end);
      break;

    case GTK_DELETE_DISPLAY_LINES:
      break;

    case GTK_DELETE_DISPLAY_LINE_ENDS:
      break;

    case GTK_DELETE_PARAGRAPH_ENDS:
      if (count < 0)
        {
          gtk_text_iter_set_line_offset (&cursor, 0);
        }
      else if (count > 0)
        {
          if (! gtk_text_iter_ends_line (&end))
            gtk_text_iter_forward_to_line_end (&end);
          else
            gtk_text_iter_forward_cursor_positions (&end, 1);
        }
      break;

    case GTK_DELETE_PARAGRAPHS:
      break;

    case GTK_DELETE_WHITESPACE:
      find_whitepace_region (&cursor, &cursor, &end);
      break;
    }

  if (! gtk_text_iter_equal (&cursor, &end))
    {
      gtk_text_buffer_delete_interactive (buffer, &cursor, &end, TRUE);
    }
}
示例#24
0
void
gimp_text_tool_editor_motion (GimpTextTool *text_tool,
                              gdouble       x,
                              gdouble       y)
{
  GtkTextBuffer *buffer = GTK_TEXT_BUFFER (text_tool->buffer);
  GtkTextIter    old_cursor;
  GtkTextIter    old_selection;
  GtkTextIter    cursor;
  GtkTextIter    selection;

  gtk_text_buffer_get_iter_at_mark (buffer, &old_cursor,
                                    gtk_text_buffer_get_insert (buffer));
  gtk_text_buffer_get_iter_at_mark (buffer, &old_selection,
                                    gtk_text_buffer_get_selection_bound (buffer));

  gimp_text_tool_xy_to_iter (text_tool, x, y, &cursor);
  selection = text_tool->select_start_iter;

  if (text_tool->select_words ||
      text_tool->select_lines)
    {
      GtkTextIter start;
      GtkTextIter end;

      if (gtk_text_iter_compare (&cursor, &selection) < 0)
        {
          start = cursor;
          end   = selection;
        }
      else
        {
          start = selection;
          end   = cursor;
        }

      if (text_tool->select_words)
        {
          if (! gtk_text_iter_starts_word (&start))
            gtk_text_iter_backward_visible_word_starts (&start, 1);

          if (! gtk_text_iter_ends_word (&end) &&
              ! gtk_text_iter_forward_visible_word_ends (&end, 1))
            gtk_text_iter_forward_to_line_end (&end);
        }
      else if (text_tool->select_lines)
        {
          gtk_text_iter_set_line_offset (&start, 0);
          gtk_text_iter_forward_to_line_end (&end);
        }

      if (gtk_text_iter_compare (&cursor, &selection) < 0)
        {
          cursor    = start;
          selection = end;
        }
      else
        {
          selection = start;
          cursor    = end;
        }
    }

  if (! gtk_text_iter_equal (&cursor,    &old_cursor) ||
      ! gtk_text_iter_equal (&selection, &old_selection))
    {
      gimp_draw_tool_pause (GIMP_DRAW_TOOL (text_tool));

      gtk_text_buffer_select_range (buffer, &cursor, &selection);

      gimp_draw_tool_resume (GIMP_DRAW_TOOL (text_tool));
    }
}
示例#25
0
/**
 * gail_text_util_get_text:
 * @textutil: A #GailTextUtil
 * @layout: A gpointer which is a PangoLayout, a GtkTreeView of NULL
 * @function: An enumeration specifying whether to return the text before, at, or
 *   after the offset.
 * @boundary_type: The boundary type.
 * @offset: The offset of the text in the GailTextUtil 
 * @start_offset: Address of location in which the start offset is returned
 * @end_offset: Address of location in which the end offset is returned
 *
 * This function gets the requested substring from the text in the GtkTextUtil.
 * The layout is used only for getting the text on a line. The value is NULL 
 * for a GtkTextView which is not wrapped, is a GtkTextView for a GtkTextView 
 * which is wrapped and is a PangoLayout otherwise.
 *
 * Returns: the substring requested
 **/
gchar*
gail_text_util_get_text (GailTextUtil    *textutil,
                         gpointer        layout,
                         GailOffsetType  function,
                         AtkTextBoundary boundary_type,
                         gint            offset,
                         gint            *start_offset,
                         gint            *end_offset)
{
  GtkTextIter start, end;
  gint line_number;
  GtkTextBuffer *buffer;

  g_return_val_if_fail (GAIL_IS_TEXT_UTIL (textutil), NULL);

  buffer = textutil->buffer;
  if (buffer == NULL)
    {
      *start_offset = 0;
      *end_offset = 0;
      return NULL;
    }

  if (!gtk_text_buffer_get_char_count (buffer))
    {
      *start_offset = 0;
      *end_offset = 0;
      return g_strdup ("");
    }
  gtk_text_buffer_get_iter_at_offset (buffer, &start, offset);

    
  end = start;

  switch (function)
    {
    case GAIL_BEFORE_OFFSET:
      switch (boundary_type)
        {
        case ATK_TEXT_BOUNDARY_CHAR:
          gtk_text_iter_backward_char(&start);
          break;
        case ATK_TEXT_BOUNDARY_WORD_START:
          if (!gtk_text_iter_starts_word (&start))
            gtk_text_iter_backward_word_start (&start);
          end = start;
          gtk_text_iter_backward_word_start(&start);
          break;
        case ATK_TEXT_BOUNDARY_WORD_END:
          if (gtk_text_iter_inside_word (&start) &&
              !gtk_text_iter_starts_word (&start))
            gtk_text_iter_backward_word_start (&start);
          while (!gtk_text_iter_ends_word (&start))
            {
              if (!gtk_text_iter_backward_char (&start))
                break;
            }
          end = start;
          gtk_text_iter_backward_word_start(&start);
          while (!gtk_text_iter_ends_word (&start))
            {
              if (!gtk_text_iter_backward_char (&start))
                break;
            }
          break;
        case ATK_TEXT_BOUNDARY_SENTENCE_START:
          if (!gtk_text_iter_starts_sentence (&start))
            gtk_text_iter_backward_sentence_start (&start);
          end = start;
          gtk_text_iter_backward_sentence_start (&start);
          break;
        case ATK_TEXT_BOUNDARY_SENTENCE_END:
          if (gtk_text_iter_inside_sentence (&start) &&
              !gtk_text_iter_starts_sentence (&start))
            gtk_text_iter_backward_sentence_start (&start);
          while (!gtk_text_iter_ends_sentence (&start))
            {
              if (!gtk_text_iter_backward_char (&start))
                break;
            }
          end = start;
          gtk_text_iter_backward_sentence_start (&start);
          while (!gtk_text_iter_ends_sentence (&start))
            {
              if (!gtk_text_iter_backward_char (&start))
                break;
            }
          break;
        case ATK_TEXT_BOUNDARY_LINE_START:
          if (layout == NULL)
            {
              line_number = gtk_text_iter_get_line (&start);
              if (line_number == 0)
                {
                  gtk_text_buffer_get_iter_at_offset (buffer,
                    &start, 0);
                }
              else
                {
                  gtk_text_iter_backward_line (&start);
                  gtk_text_iter_forward_line (&start);
                }
              end = start;
              gtk_text_iter_backward_line (&start);
            }
          else if GTK_IS_TEXT_VIEW (layout)
            {
              GtkTextView *view = GTK_TEXT_VIEW (layout);

              gtk_text_view_backward_display_line_start (view, &start);
              end = start;
              gtk_text_view_backward_display_line (view, &start);
            }
          else if (PANGO_IS_LAYOUT (layout))
            get_pango_text_offsets (PANGO_LAYOUT (layout),
                                    buffer,
                                    function,
                                    boundary_type,
                                    offset,
                                    start_offset,
                                    end_offset,
                                    &start,
                                    &end);
          break;
        case ATK_TEXT_BOUNDARY_LINE_END:
          if (layout == NULL)
            {
              line_number = gtk_text_iter_get_line (&start);
              if (line_number == 0)
                {
                  gtk_text_buffer_get_iter_at_offset (buffer,
                    &start, 0);
                  end = start;
                }
              else
                {
                  gtk_text_iter_backward_line (&start);
                  end = start;
                  while (!gtk_text_iter_ends_line (&start))
                    {
                      if (!gtk_text_iter_backward_char (&start))
                        break;
                    }
                  gtk_text_iter_forward_to_line_end (&end);
                }
            }
          else if GTK_IS_TEXT_VIEW (layout)
            {
              GtkTextView *view = GTK_TEXT_VIEW (layout);

              gtk_text_view_backward_display_line_start (view, &start);
              if (!gtk_text_iter_is_start (&start))
                {
                  gtk_text_view_backward_display_line (view, &start);
                  end = start;
                  if (!gtk_text_iter_is_start (&start))
                    {
                      gtk_text_view_backward_display_line (view, &start);
                      gtk_text_view_forward_display_line_end (view, &start);
                    }
                  gtk_text_view_forward_display_line_end (view, &end);
                } 
              else
                {
                  end = start;
                }
            }
          else if (PANGO_IS_LAYOUT (layout))
            get_pango_text_offsets (PANGO_LAYOUT (layout),
                                    buffer,
                                    function,
                                    boundary_type,
                                    offset,
                                    start_offset,
                                    end_offset,
                                    &start,
                                    &end);
          break;
        }
示例#26
0
void Highlight::searchwords_find_slow(GtkTextBuffer * textbuffer, GtkTextIter * beginbound, GtkTextIter * endbound, const ustring & searchword, bool casesensitive, bool globbing, bool matchbegin, bool matchend, vector < GtkTextIter > &wordstart, vector < GtkTextIter > &wordend)
/*
Searches for words to highlight.
Problem when case insensitive searching:
  Character ffi was changed to ffi after casefolding, and as that one is 2
  characters longer than the original ffi, we ran in problems of searching
  past the line, which gave an exception in Gtk.
The solution was to determine the length of the word from the ones that are 
to highlight, not from the casefolded searchword, but the original one.
*/
{
  // Variable.
  GtkTextIter begin;
  GtkTextIter end;
  // Extract the line.
  ustring line = gtk_text_buffer_get_slice(textbuffer, beginbound, endbound, false);
  // Find all places in this line that have the search word.
  /*
     To do that properly for glob-style pattern matching, for begin/end word
     matching and case (in)sensitivity, we need to open the box of tricks.
     We produce all possible combinations for characters and lengths, e.g.
     We have this text:
     he is
     We then make the following strings from it, and see whether they match:
     "h"
     "he"
     "he "
     "he i"
     "he is"
     "e"
     "e "
     "e i"
     "e is"
     " "
     " i"
     " is"
     "i"
     "is"
     "s"
     Any string matching will then be highlighted.
   */
  // Deal with case sensitivity.
  ustring case_considerate_search_word(searchword);
  if (!casesensitive)
    case_considerate_search_word = case_considerate_search_word.casefold();
  for (unsigned int i = 0; i < line.length(); i++) {
    if (interrupt_thread)
      continue;
    ustring line2(line.substr(0, i + 1));
    for (unsigned int offposition = 0; offposition < line2.length(); offposition++) {
      // Get the line as described above.
      // We use optimization here to get the speed acceptable when we have 
      // long lines. But when globbing is done, because of the characters of 
      // glob-style matching, we don't know how long the searchword might be,
      // we do not use that optimization.
      unsigned int linelength = line2.length() - offposition;
      if (!globbing)
        if (linelength > searchword.length())
          continue;
      ustring compareline(line2.substr(offposition, linelength));
      // Deal with case sensitivity.
      if (!casesensitive)
        compareline = compareline.casefold();
      // Now compare.
      bool match = false;
      if (globbing) {
        if (g_pattern_match_simple(case_considerate_search_word.c_str(), compareline.c_str()))
          match = true;
      } else {
        if (case_considerate_search_word == compareline)
          match = true;
      }
      // Get the iterators in the textbuffer that belong to this possible match.
      if (match) {
        begin = *beginbound;
        gtk_text_iter_forward_chars(&begin, offposition);
        end = begin;
        gtk_text_iter_forward_chars(&end, searchword.length());
      }
      // Deal with begin-word matching.
      if (match) {
        if (matchbegin) {
          if (!gtk_text_iter_starts_word(&begin))
            match = false;
        }
      }
      // Deal with end-word matching.
      if (match) {
        if (matchend) {
          if (!gtk_text_iter_ends_word(&end))
            match = false;
        }
      }
      // Add the boundaries of the word to highlight.
      if (match) {
        wordstart.push_back(begin);
        wordend.push_back(end);
      }
    }
  }
}
bool WindowCheckKeyterms::find_renderings (const ustring& text, const vector <ustring>& renderings, const vector <bool>& wholewords, const vector <bool>& casesensitives, vector <size_t> * startpositions, vector <size_t> * lengths)
// Finds renderings in the text.
// text: Text to be looked into.
// renderings: Renderings to look for.
// wholewords / casesensitives: Attributes of the renderings.
// startpositions: If non-NULL, will be filled with the positions that each rendering starts at.
// lengths: If non-NULL, will be filled with the lengths of the renderings found.
// Returns whether one or more renderings were found in the verse.
{
  if (startpositions)
    startpositions->clear();
  if (lengths)
    lengths->clear();

  GtkTextBuffer * textbuffer = gtk_text_buffer_new (NULL);
  gtk_text_buffer_set_text (textbuffer, text.c_str(), -1);
  GtkTextIter startiter;
  gtk_text_buffer_get_start_iter(textbuffer, &startiter);

  bool found = false;

  for (unsigned int i2 = 0; i2 < renderings.size(); i2++) {

    ustring rendering = renderings[i2];
    bool wholeword = wholewords[i2];
    bool casesensitive = casesensitives[i2];

    ustring mytext;
    ustring myrendering;
    if (casesensitive) {
      mytext = text;
      myrendering = rendering;
    } else {
      mytext = text.casefold();
      myrendering = rendering.casefold();
    }
    size_t position = mytext.find(myrendering);
    while (position != string::npos) {
      bool temporally_approved = true;
      GtkTextIter approvedstart = startiter;
      GtkTextIter approvedend;
      gtk_text_iter_forward_chars(&approvedstart, position);
      approvedend = approvedstart;
      gtk_text_iter_forward_chars(&approvedend, rendering.length());
      if (wholeword) {
        if (!gtk_text_iter_starts_word(&approvedstart))
          temporally_approved = false;
        if (!gtk_text_iter_ends_word(&approvedend))
          temporally_approved = false;
      }
      if (temporally_approved) {
        found = true;
        if (startpositions)
          startpositions->push_back (position);
        if (lengths)
          lengths->push_back (rendering.length());
      }
      position = mytext.find(myrendering, ++position);
    }
  }

  g_object_unref (textbuffer);  
  
  return found;
}
示例#28
0
文件: myre.c 项目: vobiscum/myre
void
my_text_buffer_highlight(GtkTextBuffer *buffer, char *word, short mode) {
    /*mode: 0:title/occurance 1:title 2:keyword, 3:invisible 4:highlight 5:normal others:normal*/
    gboolean found = TRUE, titled = FALSE;
    GtkTextTag *tag = occurance;

    gtk_text_buffer_get_iter_at_offset(text2, &start, 0);
    current = start;
    end = start;

#ifdef MinGW
    int zhTitle = 0;
    int isTitle = 0;
#endif

    while(found) {
        found = gtk_text_iter_forward_search(
                    &end,
                    word,
                    GTK_TEXT_SEARCH_VISIBLE_ONLY,
                    &current,
                    &end,
                    NULL);


        if(found) {

#ifdef MinGW
            /*check zh char*/
            char *sample = gtk_text_iter_get_slice (&current, &end);
            int sampleLen = strlen(sample);
            if( testZh(sample, sampleLen))
                zhTitle = 1;
#endif
            /*title or body*/
            if(1== mode || (0 == mode && !titled && 0 == gtk_text_iter_get_line(&current)))
            {
#ifdef MinGW
                isTitle = 1;
#endif
                tag = title;
                titled = TRUE;
            }
            else if( 0 == mode )
            {
                tag = occurance;
            }
            else if( 2 == mode) {
#ifdef MinGW
                /*keyword, pretend title to use better font*/
                isTitle = 1;
#endif
                tag = keyword;
            }
            else if( 3 == mode) {
                tag = invisible;
#ifdef MinGW
                zhTitle = 0;
                isTitle = 0;
#endif
            }
            else if( 4 == mode) {
                tag = highlight;
            }
            else if( 5 == mode) {
                tag = normal; /* will do remove-tag after extending to full word */
            }
            else {
                tag = normal;
#ifdef MinGW
                zhTitle = 0;
                isTitle = 0;
#endif
            }

            /*extend word*/
            if( 2 != mode && 3 != mode && !gtk_text_iter_starts_word(&current)) {
                gtk_text_iter_backward_visible_word_start(&current);
            }

            if(2 != mode && 3 != mode && !gtk_text_iter_ends_word(&end)) {
                gtk_text_iter_forward_visible_word_end(&end);
            }
            if (5 == mode)
            {
                gtk_text_buffer_remove_tag (buffer, highlight, &current, &end);
            }
#ifdef MinGW
            /*Clear default_font to allow better font only when no zh chars present*/
            if( !zhTitle && isTitle )
                gtk_text_buffer_remove_tag (buffer, default_font, &current, &end);
#endif
            gtk_text_buffer_apply_tag(buffer, tag, &current, &end);
        }
    }

    current = start;
    end = start;

}