Beispiel #1
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);
	}
}
Beispiel #2
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;
	}
}
Beispiel #3
0
static gboolean
goto_next_word (GeditDocument *doc)
{
	CheckRange *range;
	GtkTextIter current_iter;
	GtkTextIter old_current_iter;
	GtkTextIter end_iter;

	gedit_debug (DEBUG_PLUGINS);

	g_return_val_if_fail (doc != NULL, FALSE);

	range = get_check_range (doc);
	g_return_val_if_fail (range != NULL, FALSE);

	gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (doc), 
					  &current_iter,
					  range->current_mark);
	gtk_text_buffer_get_end_iter (GTK_TEXT_BUFFER (doc), &end_iter);

	old_current_iter = current_iter;

	gtk_text_iter_forward_word_ends (&current_iter, 2);
	gtk_text_iter_backward_word_start (&current_iter);

	if (gedit_spell_utils_skip_no_spell_check (&current_iter, &end_iter) &&
	    (gtk_text_iter_compare (&old_current_iter, &current_iter) < 0) &&
	    (gtk_text_iter_compare (&current_iter, &end_iter) < 0))
	{
		update_current (doc, gtk_text_iter_get_offset (&current_iter));
		return TRUE;
	}

	return FALSE;
}
Beispiel #4
0
/**
  Kolorowanie słów.
  Słowa nie znajdujące się w słowniku - potencjalnie błędne - zostają
  oznaczone na czerwono.
  */
static void show_errors() {
  GtkTextIter start, end, text_end;
  int i, range;
  char *word;
  gunichar *wword;

  gtk_text_buffer_create_tag(editor_buf, "red_fg", 
                             "foreground", "red", 
                             "weight", PANGO_WEIGHT_BOLD, NULL);
  gtk_text_buffer_get_end_iter(editor_buf, &text_end);
  gtk_text_buffer_get_start_iter(editor_buf, &end);
  range = gtk_text_buffer_get_char_count(editor_buf);
  while (!gtk_text_iter_is_end(&end)) {
    gtk_text_iter_forward_word_end(&end); 
    start = end;
    gtk_text_iter_backward_word_start(&start); 

    word = gtk_text_iter_get_text(&start, &end);
    wword = g_utf8_to_ucs4_fast(word, -1, NULL);
    if (make_lowercase(wword)) {
      if (!dictionary_find(dict, wword))
      gtk_text_buffer_apply_tag_by_name(editor_buf, "red_fg", 
                                      &start, &end);
    }
    g_free(word);
    g_free(wword);
  }

}
Beispiel #5
0
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);
}
Beispiel #6
0
static gboolean
gtkspell_text_iter_backward_word_start(GtkTextIter *i) {
	GtkTextIter iter;

	if (!gtk_text_iter_backward_word_start(i))
		return FALSE;

	iter = *i;
	if (gtk_text_iter_backward_char(&iter)) {
		if (gtk_text_iter_get_char(&iter) == '\'') {
			if (gtk_text_iter_backward_char(&iter)) {
				if (g_unichar_isalpha(gtk_text_iter_get_char(&iter))) {
					return (gtk_text_iter_backward_word_start(i));
				}
			}
		}
	}

	return TRUE;
}
Beispiel #7
0
// Koloruje słowa nie ze słownika na czerwono
static void ColorMistakes (GtkMenuItem *item, gpointer data) {
  GtkTextIter start, end, buffEnd;

  gtk_text_buffer_get_start_iter(editor_buf, &end);

  //Teraz sztuczką przesuwamy końcowy iterator na koniec ostatniego słowa
  gtk_text_buffer_get_end_iter(editor_buf, &buffEnd);
  gtk_text_iter_backward_word_start(&buffEnd);
  gtk_text_iter_forward_word_end(&buffEnd);

  gtk_text_buffer_create_tag(editor_buf, "red_fg", 
                             "foreground", "red", 
                             "weight", PANGO_WEIGHT_BOLD, NULL);

  // Aktualizacja słownika
  if(update_actual_dict() < 0)
    return;
  start = end;

  while (!gtk_text_iter_equal(&end, &buffEnd)) {
    // Inkrementacja zmiennych
		gtk_text_iter_forward_word_end(&end); 
		start = end;
		gtk_text_iter_backward_word_start(&start);

    // Usuwamy etykietkę ze słowa jeśli jest
    gtk_text_buffer_remove_tag_by_name(editor_buf, "red_fg", 
                                      &start, &end);

    // Separujemy słowo
    char* word = gtk_text_iter_get_text(&start, &end);
    gunichar* wword = g_utf8_to_ucs4_fast(word, -1, NULL);

    // Jeśli znaleziono w słowniku to kolorujemy
    if(!dictionary_find(dict, (const wchar_t*)wword))
      gtk_text_buffer_apply_tag_by_name(editor_buf, "red_fg", 
                                        &start, &end);
    g_free(word);

  }
}
Beispiel #8
0
gboolean snippets_key_press_cb (GuSnippets* sc, GuEditor* ec, GdkEventKey* ev) {
    GtkTextIter current, start;

    if (ev->keyval == GDK_KEY_Tab) {
        gchar* key = NULL;
        editor_get_current_iter (ec, &current);
        if (gtk_text_iter_ends_word (&current)) {
            start = current;
            gtk_text_iter_backward_word_start (&start);
            key = gtk_text_iter_get_text (&start, &current);

            if (snippets_get_value (sc, key)) {
                gtk_text_buffer_delete (ec_buffer, &start, &current);
                snippets_activate (sc, ec, key);
                g_free (key);
                return TRUE;
            }
            g_free (key);
        }
    }
    
    if (sc->info) {
        if (ev->keyval == GDK_KEY_Tab) {
            if (!snippet_info_goto_next_placeholder (sc->info, ec))
                snippets_deactivate (sc, ec);
            return TRUE;
        } else if (ev->keyval == GDK_KEY_ISO_Left_Tab
                   && ev->state & GDK_SHIFT_MASK) {
            if (!snippet_info_goto_prev_placeholder (sc->info, ec))
                snippets_deactivate (sc, ec);
            return TRUE;
        }
        /* Deactivate snippet if the current insert range is not within the
         * snippet */
        editor_get_current_iter (ec, &current);
        gint offset = gtk_text_iter_get_offset (&current);
        GList* last = g_list_last (sc->info->einfo);
        if (last) {
            gtk_text_buffer_get_iter_at_mark (ec_buffer, &current,
                    GU_SNIPPET_EXPAND_INFO (last->data)->left_mark);
            gint bound_end = gtk_text_iter_get_offset (&current);
            if (offset < sc->info->start_offset || offset > bound_end)
                snippets_deactivate (sc, ec);
        }
    }

    return FALSE;
}
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);
}
Beispiel #10
0
gboolean
ide_editor_spell_utils_text_iter_backward_word_start (GtkTextIter *iter)
{
  g_return_val_if_fail (iter != NULL, FALSE);

  while (gtk_text_iter_backward_word_start (iter))
    {
      GtkTextIter prev_char = *iter;

      if (!gtk_text_iter_backward_char (&prev_char) ||
          !is__text_iter_apostrophe_or_dash (&prev_char) ||
          !gtk_text_iter_ends_word (&prev_char))
        return TRUE;

      *iter = prev_char;
    }

  return FALSE;
}
Beispiel #11
0
void insert_open_brace(GtkWidget **tip_win, GtkWidget *text_view, GtkTextIter *arg1)
{
	GdkWindow *win;
	GtkTextIter start;
	GdkRectangle buf_loc;
	gint x, y;
	gint win_x, win_y;
	gchar *text;
	gchar *tip_text;

	start = *arg1;
	if (!gtk_text_iter_backward_word_start (&start))
		return;
	text = gtk_text_iter_get_text (&start, arg1);
	g_strstrip (text);

	tip_text = get_tip(text);  
	if (tip_text == NULL)
		return;

	gtk_text_view_get_iter_location (GTK_TEXT_VIEW (text_view), arg1, &buf_loc);
	g_printf ("Buffer: %d, %d\n", buf_loc.x, buf_loc.y);
	gtk_text_view_buffer_to_window_coords (GTK_TEXT_VIEW (text_view),
	GTK_TEXT_WINDOW_WIDGET,
	buf_loc.x, buf_loc.y,
	&win_x, &win_y);
	g_printf ("Window: %d, %d\n", win_x, win_y);
	win = gtk_text_view_get_window (GTK_TEXT_VIEW (text_view), 
	GTK_TEXT_WINDOW_WIDGET);
	gdk_window_get_origin (win, &x, &y);

	if (*tip_win != NULL)
		gtk_widget_destroy (GTK_WIDGET (*tip_win));  

	*tip_win = tip_window_new (tip_text);
	g_free(tip_text);
	gtk_window_move (GTK_WINDOW (*tip_win), win_x + x, 
	win_y + y + buf_loc.height);
	gtk_widget_show_all (*tip_win);
}
Beispiel #12
0
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;
}
Beispiel #13
0
ParseWords::ParseWords(const ustring & text)
// Parses a line of text in its separate words.
// Note: This is comparable to object Parse, but does a better job.
{
  // Load text into buffer.
  ustring text2(text);
  text2.append(" ");
  GtkTextBuffer *textbuffer;
  textbuffer = gtk_text_buffer_new(NULL);
  gtk_text_buffer_set_text(textbuffer, text2.c_str(), -1);
  // Iterators.  
  GtkTextIter startiter, enditer;
  // Parse into separate words.
  gtk_text_buffer_get_start_iter(textbuffer, &enditer);
  while (gtk_text_iter_forward_word_end(&enditer)) {
    startiter = enditer;
    gtk_text_iter_backward_word_start(&startiter);
    ustring word = gtk_text_iter_get_text(&startiter, &enditer);
    words.push_back(word);
  }
  // Free memory
  g_object_unref(textbuffer);
}
Beispiel #14
0
gboolean
xed_spell_utils_skip_no_spell_check (GtkTextIter *start,
                                       GtkTextIter *end)
{
	GtkSourceBuffer *buffer = GTK_SOURCE_BUFFER (gtk_text_iter_get_buffer (start));

	while (gtk_source_buffer_iter_has_context_class (buffer, start, "no-spell-check"))
	{
		GtkTextIter last = *start;

		if (!gtk_source_buffer_iter_forward_to_context_class_toggle (buffer, start, "no-spell-check"))
		{
			return FALSE;
		}

		if (gtk_text_iter_compare (start, &last) <= 0)
		{
			return FALSE;
		}

		gtk_text_iter_forward_word_end (start);
		gtk_text_iter_backward_word_start (start);

		if (gtk_text_iter_compare (start, &last) <= 0)
		{
			return FALSE;
		}

		if (gtk_text_iter_compare (start, end) >= 0)
		{
			return FALSE;
		}
	}

	return TRUE;
}
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;
	}
}
Beispiel #16
0
bool search_in_bibledit_word_boundaries_match(const ustring & text, const ustring & searchword, bool matchbeginning, bool matchending, bool globbing)
// Does the word boundary matching.
{
  /*
     Deal with matching the start of a word and/or of the end.

     There are four cases here.
     1. Match word start only.
     2. Match word end only.
     3. Both match start end end of a word, which implies "whole word".
     4. No matching at all.

     Boundary resolution is handled by pango_break(). Textual boundaries such 
     as word boundaries and line boundaries are determined for each item.
     In most cases a general algorithm suffices for this process, but in some
     cases a language module will override the generic algorithm with a more
     specific one.
     It seems to be easier programming to use GtkTextIter and GtkTextBuffer,
     rather than pango_break() directly.
   */

  // Whether the word matches.
  bool match = false;

  // Textbuffer for determining word boundaries.
  GtkTextBuffer *textbuffer = gtk_text_buffer_new(NULL);
  gtk_text_buffer_set_text(textbuffer, text.c_str(), -1);

  // Iterators needed.
  GtkTextIter startiter;
  GtkTextIter enditer;

  // Store segments of text to compare against.
  vector < ustring > segments;

  // Deal with case one: Match word start only.  
  if (matchbeginning && !matchending) {
    // Create a patternword for the glob-style pattern matching.
    ustring patternword = searchword + "*";
    // Collect all strings starting with a word.
    gtk_text_buffer_get_start_iter(textbuffer, &startiter);
    gtk_text_buffer_get_end_iter(textbuffer, &enditer);
    while (gtk_text_iter_forward_word_end(&startiter)) {
      gtk_text_iter_backward_word_start(&startiter);
      segments.push_back(gtk_text_iter_get_text(&startiter, &enditer));
      gtk_text_iter_forward_word_end(&startiter);
    }
    // See whether the word is in it.
    for (unsigned int i2 = 0; i2 < segments.size(); i2++) {
      if (globbing) {
        // Glob-style pattern matching.
        if (g_pattern_match_simple(patternword.c_str(), segments[i2].c_str())) {
          match = true;
          break;
        }
      } else {
        // Straight compare.
        if (segments[i2].find(searchword) == 0) {
          match = true;
          break;
        }
      }
    }
  }
  // Deal with case two: Match word end only.  
  if (!matchbeginning && matchending) {
    // Create a patternword for the glob-style pattern matching.
    ustring patternword = "*" + searchword;
    // Collect all strings ending with a word.
    gtk_text_buffer_get_start_iter(textbuffer, &startiter);
    gtk_text_buffer_get_start_iter(textbuffer, &enditer);
    while (gtk_text_iter_forward_word_end(&enditer)) {
      segments.push_back(gtk_text_iter_get_text(&startiter, &enditer));
    }
    // See whether the word is in it.
    for (unsigned int i2 = 0; i2 < segments.size(); i2++) {
      if (globbing) {
        // Glob-style pattern matching.
        if (g_pattern_match_simple(patternword.c_str(), segments[i2].c_str())) {
          match = true;
          break;
        }
      } else {
        // Straight compare.
        size_t matchposition;
        matchposition = segments[i2].length() - searchword.length();
        // Negative match positions cause a false match. Solve that here.
        matchposition = CLAMP(matchposition, 0, 99999999);
        if (segments[i2].find(searchword) == matchposition) {
          match = true;
          break;
        }
      }
    }
  }
  // Deal with case three: Match both word start and end.  
  // Interpreted as "match whole word".
  if (matchbeginning && matchending) {
    // Create a patternword for the glob-style pattern matching.
    ustring patternword = searchword;
    // Collect all whole words.
    gtk_text_buffer_get_start_iter(textbuffer, &enditer);
    while (gtk_text_iter_forward_word_end(&enditer)) {
      startiter = enditer;
      gtk_text_iter_backward_word_start(&startiter);
      segments.push_back(gtk_text_iter_get_text(&startiter, &enditer));
    }
    // See whether the word is in it.
    for (unsigned int i2 = 0; i2 < segments.size(); i2++) {
      if (globbing) {
        // Glob-style pattern matching.
        if (g_pattern_match_simple(patternword.c_str(), segments[i2].c_str())) {
          match = true;
          break;
        }
      } else {
        // Straight compare.
        if (segments[i2] == searchword) {
          match = true;
          break;
        }
      }
    }
  }
  // Case four: Nothing to test, so set found to true.
  if (!matchbeginning && !matchending)
    match = true;

  // Free memory.
  g_object_unref(textbuffer);

  // Return whether match.
  return match;
}
Beispiel #17
0
/**
 * Handles the keypress events from webview and inputbox.
 */
VbResult ex_keypress(int key)
{
    GtkTextIter start, end;
    GtkTextBuffer *buffer = vb.gui.buffer;
    GtkTextMark *mark;

    /* delegate call to the submode */
    if (RESULT_COMPLETE == hints_keypress(key)) {
        return RESULT_COMPLETE;
    }

    switch (key) {
        case KEY_TAB:
            complete(1);
            break;

        case KEY_SHIFT_TAB:
            complete(-1);
            break;

        case CTRL('['):
        case CTRL('C'):
            mode_enter('n');
            vb_set_input_text("");
            break;

        case KEY_CR:
            input_activate();
            break;

        case KEY_UP:
            history(true);
            break;

        case KEY_DOWN:
            history(false);
            break;

        /* basic command line editing */
        case CTRL('H'):
            /* delete the last char before the cursor */
            mark = gtk_text_buffer_get_insert(buffer);
            gtk_text_buffer_get_iter_at_mark(buffer, &start, mark);
            gtk_text_buffer_backspace(buffer, &start, true, true);
            break;

        case CTRL('W'):
            /* delete word backward from cursor */
            mark = gtk_text_buffer_get_insert(buffer);
            gtk_text_buffer_get_iter_at_mark(buffer, &end, mark);

            /* copy the iter to build start and end point for deletion */
            start = end;

            /* move the iterator to the beginning of previous word */
            if (gtk_text_iter_backward_word_start(&start)) {
                gtk_text_buffer_delete(buffer, &start, &end);
            }
            break;

        case CTRL('B'):
            /* move the cursor direct behind the prompt */
            gtk_text_buffer_get_iter_at_offset(buffer, &start, strlen(vb.state.prompt));
            gtk_text_buffer_place_cursor(buffer, &start);
            break;

        case CTRL('E'):
            /* move the cursor to the end of line */
            gtk_text_buffer_get_end_iter(buffer, &start);
            gtk_text_buffer_place_cursor(buffer, &start);
            break;

        case CTRL('U'):
            /* remove everythings between cursor and prompt */
            mark = gtk_text_buffer_get_insert(buffer);
            gtk_text_buffer_get_iter_at_mark(buffer, &end, mark);
            gtk_text_buffer_get_iter_at_offset(buffer, &start, strlen(vb.state.prompt));
            gtk_text_buffer_delete(buffer, &start, &end);
            break;

        default:
            /* if is printable ascii char, than write it at the cursor
             * position into input box */
            if (key >= 0x20 && key <= 0x7e) {
                gtk_text_buffer_insert_at_cursor(buffer, (char[2]){key, 0}, 1);
            } else {
Beispiel #18
0
static void
set_check_range (GeditDocument *doc,
		 GtkTextIter   *start,
		 GtkTextIter   *end)
{
	CheckRange *range;
	GtkTextIter iter;

	gedit_debug (DEBUG_PLUGINS);

	range = get_check_range (doc);

	if (range == NULL)
	{
		gedit_debug_message (DEBUG_PLUGINS, "There was not a previous check range");

		gtk_text_buffer_get_end_iter (GTK_TEXT_BUFFER (doc), &iter);

		range = g_new0 (CheckRange, 1);

		range->start_mark = gtk_text_buffer_create_mark (GTK_TEXT_BUFFER (doc),
				"check_range_start_mark", &iter, TRUE);

		range->end_mark = gtk_text_buffer_create_mark (GTK_TEXT_BUFFER (doc),
				"check_range_end_mark", &iter, FALSE);

		range->current_mark = gtk_text_buffer_create_mark (GTK_TEXT_BUFFER (doc),
				"check_range_current_mark", &iter, TRUE);

		g_object_set_qdata_full (G_OBJECT (doc), 
				 check_range_id, 
				 range, 
				 (GDestroyNotify)g_free);
	}

	if (gedit_spell_utils_skip_no_spell_check (start, end))
	 {
		if (!gtk_text_iter_inside_word (end))
		{
			/* if we're neither inside a word,
			 * we must be in some spaces.
			 * skip backward to the end of the previous word. */
			if (!gtk_text_iter_is_end (end))
			{
				gtk_text_iter_backward_word_start (end);
				gtk_text_iter_forward_word_end (end);
			}
		}
		else
		{
			if (!gtk_text_iter_ends_word (end))
				gtk_text_iter_forward_word_end (end);
		}
	}
	else
	{
		/* no spell checking in the specified range */
		start = end;
	}

	gtk_text_buffer_move_mark (GTK_TEXT_BUFFER (doc),
				   range->start_mark,
				   start);
	gtk_text_buffer_move_mark (GTK_TEXT_BUFFER (doc),
				   range->end_mark,
				   end);

	range->mw_start = -1;
	range->mw_end = -1;

	update_current (doc, gtk_text_iter_get_offset (start));
}
Beispiel #19
0
Datei: ex.c Projekt: yzhou61/vimb
/**
 * Handles the keypress events from webview and inputbox.
 */
VbResult ex_keypress(int key)
{
    GtkTextIter start, end;
    gboolean check_empty  = false;
    GtkTextBuffer *buffer = vb.gui.buffer;
    GtkTextMark *mark;
    VbResult res;
    const char *text;

    /* delegate call to hint mode if this is active */
    if (vb.mode->flags & FLAG_HINTING
        && RESULT_COMPLETE == hints_keypress(key)) {

        return RESULT_COMPLETE;
    }

    /* process the register */
    if (info.phase == PHASE_REG) {
        info.reg   = (char)key;
        info.phase = PHASE_REG;

        /* insert the register text at cursor position */
        text = vb_register_get((char)key);
        if (text) {
            gtk_text_buffer_insert_at_cursor(buffer, text, strlen(text));
        }

        res = RESULT_COMPLETE;
    } else {
        res = RESULT_COMPLETE;
        switch (key) {
            case KEY_TAB:
                complete(1);
                break;

            case KEY_SHIFT_TAB:
                complete(-1);
                break;

            case CTRL('['):
            case CTRL('C'):
                vb_enter('n');
                vb_set_input_text("");
                break;

            case KEY_CR:
                input_activate();
                break;

            case KEY_UP:
                history(true);
                break;

            case KEY_DOWN:
                history(false);
                break;

            /* basic command line editing */
            case CTRL('H'):
                /* delete the last char before the cursor */
                mark = gtk_text_buffer_get_insert(buffer);
                gtk_text_buffer_get_iter_at_mark(buffer, &start, mark);
                gtk_text_buffer_backspace(buffer, &start, true, true);
                check_empty = true;
                break;

            case CTRL('W'):
                /* delete word backward from cursor */
                mark = gtk_text_buffer_get_insert(buffer);
                gtk_text_buffer_get_iter_at_mark(buffer, &end, mark);

                /* copy the iter to build start and end point for deletion */
                start = end;

                /* move the iterator to the beginning of previous word */
                if (gtk_text_iter_backward_word_start(&start)) {
                    gtk_text_buffer_delete(buffer, &start, &end);
                }
                check_empty = true;
                break;

            case CTRL('B'):
                /* move the cursor direct behind the prompt */
                gtk_text_buffer_get_iter_at_offset(buffer, &start, strlen(vb.state.prompt));
                gtk_text_buffer_place_cursor(buffer, &start);
                break;

            case CTRL('E'):
                /* move the cursor to the end of line */
                gtk_text_buffer_get_end_iter(buffer, &start);
                gtk_text_buffer_place_cursor(buffer, &start);
                break;

            case CTRL('U'):
                /* remove everything between cursor and prompt */
                mark = gtk_text_buffer_get_insert(buffer);
                gtk_text_buffer_get_iter_at_mark(buffer, &end, mark);
                gtk_text_buffer_get_iter_at_offset(buffer, &start, strlen(vb.state.prompt));
                gtk_text_buffer_delete(buffer, &start, &end);
                break;

            case CTRL('R'):
                info.phase      = PHASE_REG;
                vb.mode->flags |= FLAG_NOMAP;
                res             = RESULT_MORE;
                break;

            default:
                /* if is printable ascii char, than write it at the cursor
                 * position into input box */
                if (key >= 0x20 && key <= 0x7e) {
                    gtk_text_buffer_insert_at_cursor(buffer, (char[2]){key, 0}, 1);
                } else {
Beispiel #20
0
static void WhatCheck (GtkMenuItem *item, gpointer data) {
  GtkWidget *dialog;
  GtkTextIter start, end;
  char *word;
  gunichar *wword;
  
  // Znajdujemy pozycję kursora
  gtk_text_buffer_get_iter_at_mark(editor_buf, &start,
                                   gtk_text_buffer_get_insert(editor_buf));

  // Jeśli nie wewnątrz słowa, kończymy
  if (!gtk_text_iter_inside_word(&start)) {
    dialog = gtk_message_dialog_new(NULL, 0, GTK_MESSAGE_ERROR,
                                    GTK_BUTTONS_OK,
                                    "Kursor musi być w środku słowa");
    gtk_dialog_run(GTK_DIALOG(dialog));
    gtk_widget_destroy(dialog);
    return;
  }

  // Znajdujemy początek i koniec słowa, a potem samo słowo 
  end = start;
  gtk_text_iter_backward_word_start(&start);
  gtk_text_iter_forward_word_end(&end); 
  word = gtk_text_iter_get_text(&start, &end);

  // Zamieniamy na wide char (no prawie)
  wword = g_utf8_to_ucs4_fast(word, -1, NULL);

  if(update_actual_dict() < 0)
    return;
  // Sprawdzamy
  if (dictionary_find(dict, (wchar_t *)wword)) {
    dialog = gtk_message_dialog_new(NULL, 0, GTK_MESSAGE_INFO, GTK_BUTTONS_OK,
                                    "Wszystko w porządku,\nśpij spokojnie");
    gtk_dialog_run(GTK_DIALOG(dialog));
    gtk_widget_destroy(dialog);
  }
  else {
    // Czas korekty
    GtkWidget *vbox, *label, *combo;
    struct word_list hints;
    int i;
    wchar_t **words;

    dictionary_hints(dict, (wchar_t *)wword, &hints);
    words = word_list_get(&hints);
    dialog = gtk_dialog_new_with_buttons("Korekta", NULL, 0, 
                                         GTK_STOCK_OK,
                                         GTK_RESPONSE_ACCEPT,
                                         GTK_STOCK_CANCEL,
                                         GTK_RESPONSE_REJECT,
                                         NULL);
    // W treści dialogu dwa elementy
    vbox = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
    // Tekst
    label = gtk_label_new("Coś nie tak, mam kilka propozycji");
    gtk_widget_show(label);
    gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 1);

    // Spuszczane menu
    combo = gtk_combo_box_text_new();
    for (i = 0; i < word_list_size(&hints); i++) {
      // Combo box lubi mieć Gtk
      char *uword = g_ucs4_to_utf8((gunichar *)words[i], -1, NULL, NULL, NULL);

      // Dodajemy kolejny element
      gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), uword);
      g_free(uword);
    }
    //gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo),"<inne...>");
    gtk_combo_box_set_active(GTK_COMBO_BOX(combo), 0);
    gtk_box_pack_start(GTK_BOX(vbox), combo, FALSE, FALSE, 1);
    gtk_widget_show(combo);

    char *korekta, *question;
    GtkWidget *ask_dialog, *ask_vbox, *ask_label;
    switch (gtk_dialog_run(GTK_DIALOG(dialog))) {
      case GTK_RESPONSE_ACCEPT:
        korekta =
          gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(combo));

        // Usuwamy stare
        gtk_text_buffer_delete(editor_buf, &start, &end);
        // Wstawiamy nowe
        gtk_text_buffer_insert(editor_buf, &start, korekta, -1);
        g_free(korekta);
        break;

      case GTK_RESPONSE_REJECT:
        question = "Czy chcesz dodać to słowo do słownika?";
        ask_dialog = gtk_dialog_new_with_buttons(question, NULL, 0, 
                                                 GTK_STOCK_OK,
                                                 GTK_RESPONSE_ACCEPT,
                                                 GTK_STOCK_CANCEL,
                                                 GTK_RESPONSE_REJECT,
                                                 NULL);
        ask_vbox = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
        // Tekst
        ask_label = gtk_label_new("Coś nie tak, mam kilka propozycji");
        gtk_widget_show(ask_label);
        gtk_box_pack_start(GTK_BOX(ask_vbox), ask_label, FALSE, FALSE, 1);

        // Jeśli chiciał dodać nowe słowo do słownika to dodamy i zapiszemy
        if (gtk_dialog_run(GTK_DIALOG(ask_dialog)) == GTK_RESPONSE_ACCEPT) {
          dictionary_insert(dict, (wchar_t *)wword);
          dictionary_save_lang(dict, dict_location);
        }
        
        gtk_widget_destroy(ask_dialog);
        break;
      }
  
    gtk_widget_destroy(dialog);
  }
  
}
void CheckCapitalization::check_capitalization(vector < int >&chapters, vector < ustring > &verses, ustring & text, vector < size_t > &pointers, bool end_check)
/*
Check capitalization in text.
If "end_check" is true, it also check for final sentence closing.
*/
{
  /*
     Note that this at first used gtk_text_iter_starts_sentence (&iter) and
     gtk_text_iter_ends_sentence (&iter), but these functions are not good enough,
     because do not work in several cases, like e.g. in the following line, it does
     not indicate the end of the sentence:
     As soon as the leaders of the tribes of Israel took their places, the 
     Israelites said, “How could such a horrible thing happen?"
     Therefore we use other means to check sentences.
   */

  // No check if there's no text.
  if (trim(text).empty())
    return;
  // Some variables needed.
  bool expect_capital_now = false;
  bool expect_capital_caused_by_reference = false;
  gunichar previous_char = 0;
  int localchapter = 0;
  ustring localverse = "0";
  GtkTextBuffer *textbuffer;
  textbuffer = gtk_text_buffer_new(NULL);
  gtk_text_buffer_set_text(textbuffer, text.c_str(), -1);
  GtkTextIter iter;
  gtk_text_buffer_get_start_iter(textbuffer, &iter);
  bool going = true;
  while (going) {
    // Get the unicode character.
    gunichar unichar = gtk_text_iter_get_char(&iter);
    // See whether to expect a capital now.
    if (punctuation_followed_by_capitals_set.find(unichar) != punctuation_followed_by_capitals_set.end()) {
      // Ok, expect capital.
      expect_capital_now = true;
      expect_capital_caused_by_reference = false;
      // Was this expectation caused by a reference?
      if (is_reference(iter))
        expect_capital_caused_by_reference = true;
    }
    // If we expect a capital, and we find one, no longer look for one.
    if (expect_capital_now) {
      if (g_unichar_isupper(unichar)) {
        expect_capital_now = false;
      }
    }
    // If we expect a capital, and we get lower case, that might be trouble.
    if (expect_capital_now) {
      if (g_unichar_islower(unichar)) {
        // There is no trouble if it follows a character after which to ignore lower case.
        if (ignore_lower_case_following_set.find(previous_char) != ignore_lower_case_following_set.end()) {
          expect_capital_now = false;
        }
        // If the lowercase character follows an abbreviation, there is no trouble either.
        GtkTextIter iter2 = iter;
        gtk_text_iter_backward_word_start(&iter2);
        GtkTextIter iter3 = iter2;
        gtk_text_iter_forward_word_end(&iter3);
        gtk_text_iter_forward_char(&iter3);
        ustring abbreviation = gtk_text_iter_get_text(&iter2, &iter3);
        if (abbreviations.find(abbreviation) != abbreviations.end()) {
          expect_capital_now = false;
        }
        // If it follows a reference, there is no trouble.
        if (expect_capital_caused_by_reference)
          expect_capital_now = false;
        // Ok, give message.
        if (expect_capital_now) {
          // Determine chapter and verse.
          get_chapter_and_verse(chapters, verses, pointers, iter, localchapter, localverse);
          message(book, localchapter, localverse, _("Capital expected: ") + get_context(iter));
        }
        // Only give one message about missing capitals in this context.
        expect_capital_now = false;
      }
    }
    // Store this characters as the previous characters for the next round.
    if (g_unichar_isgraph(unichar))
      previous_char = unichar;
    // Next round.
    going = gtk_text_iter_forward_char(&iter);
  }
  // The sentence should be ended with proper punctuation.
  if (end_check) {
    if (expect_capital_now)
      if (g_unichar_isdigit(previous_char))
        expect_capital_now = false;
    if (!expect_capital_now) {
      message(book, chapter, verse, _("Unended sentence: ") + get_context(iter));
    }
  }
  // Free memory
  g_object_unref(textbuffer);
}
void CheckCapitalization::check_suspicious_capitalization(ustring & text)
/*
Checks on suspicious capitalization, like "bOat" or "BOat".
There are exceptions to this check.
*/
{
  // Load text into buffer.
  ustring text2(text);
  text2.append(" ");
  GtkTextBuffer *textbuffer;
  textbuffer = gtk_text_buffer_new(NULL);
  gtk_text_buffer_set_text(textbuffer, text2.c_str(), -1);
  // Iterators.  
  GtkTextIter startiter, enditer;
  // Check all separate words.
  gtk_text_buffer_get_start_iter(textbuffer, &enditer);
  while (gtk_text_iter_forward_word_end(&enditer)) {
    startiter = enditer;
    gtk_text_iter_backward_word_start(&startiter);
    vector < bool > capspattern;
    unsigned int capscount = 0;
    GtkTextIter iter = startiter;
    while (gtk_text_iter_in_range(&iter, &startiter, &enditer)) {
      bool upper = g_unichar_isupper(gtk_text_iter_get_char(&iter));
      capspattern.push_back(upper);
      if (upper)
        capscount++;
      gtk_text_iter_forward_char(&iter);
    }
    // No further checking if words are too short.
    if (capspattern.size() < 2)
      continue;
    // No further checking if only small letters.
    if (capscount == 0)
      continue;
    // No further checking if all capitals.
    if (capscount == capspattern.size())
      continue;
    // No further checking if first letter capitalized only.
    if ((capspattern[0]) && (capscount == 1))
      continue;
    // Ok, there could be a problem of mixed capitalization.
    // Get the prefix before the first capital, and the suffix after it.
    ustring word = gtk_text_iter_get_text(&startiter, &enditer);
    ustring uncapitalized_prefix;
    ustring capitalized_suffix;
    for (unsigned int i = 1; i < capspattern.size(); i++) {
      if (capspattern[i]) {
        uncapitalized_prefix = word.substr(0, i);
        capitalized_suffix = word.substr(i, word.length() - i);
        break;
      }
    }
    // See whether the suffix is properly capitalized.
    unsigned int suffix_capital_count = 0;
    for (unsigned int i = 0; i < capitalized_suffix.length(); i++) {
      if (g_unichar_isupper(g_utf8_get_char(capitalized_suffix.substr(i, 1).c_str())))
        suffix_capital_count++;
    }
    bool suffix_properly_capitalized = false;
    if (suffix_capital_count == 1)
      suffix_properly_capitalized = true;
    if (suffix_capital_count == capitalized_suffix.length())
      suffix_properly_capitalized = true;
    // Give message and continue if capitalization error in suffix, but only
    // if this so-called wrongly capitalized suffix has not been approved af.
    if (!suffix_properly_capitalized) {
      if (capitalized_suffixes.find(capitalized_suffix) == capitalized_suffixes.end()) {
        mixed_capitalization_message(word);
        continue;
      }
    }
    // No further checking if this uncapitalized prefix is in the list,
    // or any is allowed.
    if (uncapitalized_prefixes.find(uncapitalized_prefix) != uncapitalized_prefixes.end())
      continue;
    if (allow_any_uncapitalized_prefixes)
      continue;
    // Ok, not in the list. Try again with lower case initial.
    ustring initial = uncapitalized_prefix.substr(0, 1);
    initial = initial.casefold();
    uncapitalized_prefix.replace(0, 1, initial);
    if (uncapitalized_prefixes.find(uncapitalized_prefix) != uncapitalized_prefixes.end())
      continue;
    // No further checking if the suffix is in the list of approved suffixes.
    if (capitalized_suffixes.find(capitalized_suffix) != capitalized_suffixes.end())
      continue;
    // Ok, not found, but it could be this suffix is in all capitals. Handle that.
    initial = capitalized_suffix.substr(0, 1);
    capitalized_suffix.erase(0, 1);
    capitalized_suffix = capitalized_suffix.casefold();
    capitalized_suffix.insert(0, initial);
    if (capitalized_suffixes.find(capitalized_suffix) != capitalized_suffixes.end())
      continue;
    // Ok, it appears we've got an error here -> give message.
    mixed_capitalization_message(word);
  }
  // Free memory
  g_object_unref(textbuffer);
}
Beispiel #23
0
/**
  Sprawdzenie słowa, na którym aktualnie znajduje się kursor. Ewentualne dodanie do słownika.
  @param[in] item element menu.
  @param[in] data wskaźnik na wartość.
  */
static void WhatCheck (GtkMenuItem *item, gpointer data) {
  GtkWidget *dialog;
  GtkTextIter start, end;
  char *word;
  gunichar *wword;

  //load_dictionary_from_menu(&dict);
  
  // Znajdujemy pozycję kursora
  gtk_text_buffer_get_iter_at_mark(editor_buf, &start,
                                   gtk_text_buffer_get_insert(editor_buf));

  // Jeśli nie wewnątrz słowa, kończymy
  if (!gtk_text_iter_inside_word(&start)) {
    dialog = gtk_message_dialog_new(NULL, 0, GTK_MESSAGE_ERROR,
                                    GTK_BUTTONS_OK,
                                    "Kursor musi być w środku słowa");
    gtk_dialog_run(GTK_DIALOG(dialog));
    gtk_widget_destroy(dialog);
    return;
  }

  // Znajdujemy początek i koniec słowa, a potem samo słowo 
  end = start;
  gtk_text_iter_backward_word_start(&start);
  gtk_text_iter_forward_word_end(&end); 
  word = gtk_text_iter_get_text(&start, &end);

  // Zamieniamy na wide char (no prawie)
  wword = g_utf8_to_ucs4_fast(word, -1, NULL);
  
  if (!make_lowercase(wword)) {
    dialog = gtk_message_dialog_new(NULL, 0, GTK_MESSAGE_INFO, GTK_BUTTONS_OK,
                                    "Podane słowo nie jest słowem słownikowym.");
    gtk_dialog_run(GTK_DIALOG(dialog));
    gtk_widget_destroy(dialog);
  }
  else {
    // Sprawdzamy
    if (dictionary_find(dict, (wchar_t *)wword)) {
      dialog = gtk_message_dialog_new(NULL, 0, GTK_MESSAGE_INFO, GTK_BUTTONS_OK,
                                      "Wszystko w porządku,\nśpij spokojnie");
      gtk_dialog_run(GTK_DIALOG(dialog));
      gtk_widget_destroy(dialog);
    }
    else {
      // Czas korekty
      GtkWidget *vbox, *label, *combo;
      struct word_list hints;
      int i;
      wchar_t **words;

      dictionary_hints(dict, (wchar_t *)wword, &hints);
      words = (wchar_t **) word_list_get(&hints);
      dialog = gtk_dialog_new_with_buttons("Korekta", NULL, 0, 
                                           GTK_STOCK_OK,
                                           GTK_RESPONSE_ACCEPT,
                                           GTK_STOCK_ADD,
                                           GTK_RESPONSE_APPLY,
                                           GTK_STOCK_CANCEL,
                                           GTK_RESPONSE_REJECT,
                                           NULL);
      // W treści dialogu dwa elementy
      vbox = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
      // Tekst
      label = gtk_label_new("Słowo nie znajduje się w słowniku. Wybierz \njedną z propozycji lub dodaj słowa do słownika.");
      gtk_widget_show(label);
      gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 1);

      // Spuszczane menu
      combo = gtk_combo_box_text_new();
      for (i = 0; i < word_list_size(&hints); i++) {
        // Combo box lubi mieć Gtk
        char *uword = g_ucs4_to_utf8((gunichar *)words[i], -1, NULL, NULL, NULL);

        // Dodajemy kolejny element
        gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), uword);
        g_free(uword);
      }
      gtk_combo_box_set_active(GTK_COMBO_BOX(combo), 0);
      gtk_box_pack_start(GTK_BOX(vbox), combo, FALSE, FALSE, 1);
      gtk_widget_show(combo);

      gint click = gtk_dialog_run(GTK_DIALOG(dialog));

      if (click == GTK_RESPONSE_ACCEPT) {
        char *korekta =
          gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(combo));

        // Usuwamy stare
        gtk_text_buffer_delete(editor_buf, &start, &end);
        // Wstawiamy nowe
        gtk_text_buffer_insert(editor_buf, &start, korekta, -1);
        g_free(korekta);
      }
      // Proponujemy dodanie słowa do słownika
      else if (click == GTK_RESPONSE_APPLY)
        dictionary_insert(dict, wword);
      gtk_widget_destroy(dialog);
    }
  }
  g_free(word);
  g_free(wword);
}
Beispiel #24
0
void
load_file (const gchar *demoname,
           const gchar *filename)
{
  GtkTextBuffer *info_buffer, *source_buffer;
  GtkTextIter start, end;
  char *resource_filename;
  GError *err = NULL;
  int state = 0;
  gboolean in_para = 0;
  gchar **lines;
  GBytes *bytes;
  gint i;

  if (!g_strcmp0 (current_file, filename))
    return;

  remove_data_tabs ();

  add_data_tab (demoname);

  g_free (current_file);
  current_file = g_strdup (filename);

  info_buffer = gtk_text_buffer_new (NULL);
  gtk_text_buffer_create_tag (info_buffer, "title",
                              "font", "Sans 18",
                              "pixels-below-lines", 10,
                              NULL);

  source_buffer = gtk_text_buffer_new (NULL);
  gtk_text_buffer_create_tag (source_buffer, "source",
                              "font", "monospace",
                              NULL);
  gtk_text_buffer_create_tag (source_buffer, "comment",
                              "foreground", "DodgerBlue",
                              NULL);
  gtk_text_buffer_create_tag (source_buffer, "type",
                              "foreground", "ForestGreen",
                              NULL);
  gtk_text_buffer_create_tag (source_buffer, "string",
                              "foreground", "RosyBrown",
                              "weight", PANGO_WEIGHT_BOLD,
                              NULL);
  gtk_text_buffer_create_tag (source_buffer, "control",
                              "foreground", "purple",
                              NULL);
  gtk_text_buffer_create_tag (source_buffer, "preprocessor",
                              "style", PANGO_STYLE_OBLIQUE,
                              "foreground", "burlywood4",
                              NULL);
  gtk_text_buffer_create_tag (source_buffer, "function",
                              "weight", PANGO_WEIGHT_BOLD,
                              "foreground", "DarkGoldenrod4",
                              NULL);

  resource_filename = g_strconcat ("/sources/", filename, NULL);
  bytes = g_resources_lookup_data (resource_filename, 0, &err);
  g_free (resource_filename);

  if (bytes == NULL)
    {
      g_warning ("Cannot open source for %s: %s\n", filename, err->message);
      g_error_free (err);
      return;
    }

  lines = g_strsplit (g_bytes_get_data (bytes, NULL), "\n", -1);
  g_bytes_unref (bytes);

  gtk_text_buffer_get_iter_at_offset (info_buffer, &start, 0);
  for (i = 0; lines[i] != NULL; i++)
    {
      gchar *p;
      gchar *q;
      gchar *r;

      /* Make sure \r is stripped at the end for the poor windows people */
      lines[i] = g_strchomp (lines[i]);

      p = lines[i];
      switch (state)
        {
        case 0:
          /* Reading title */
          while (*p == '/' || *p == '*' || g_ascii_isspace (*p))
            p++;
          r = p;
          while (*r != '\0')
            {
              while (*r != '/' && *r != ':' && *r != '\0')
                r++;
              if (*r == '/')
                {
                  r++;
                  p = r;
                }
              if (r[0] == ':' && r[1] == ':')
                *r = '\0';
            }
          q = p + strlen (p);
          while (q > p && g_ascii_isspace (*(q - 1)))
            q--;


          if (q > p)
            {
              int len_chars = g_utf8_pointer_to_offset (p, q);

              end = start;

              g_assert (strlen (p) >= q - p);
              gtk_text_buffer_insert (info_buffer, &end, p, q - p);
              start = end;

              gtk_text_iter_backward_chars (&start, len_chars);
              gtk_text_buffer_apply_tag_by_name (info_buffer, "title", &start, &end);

              start = end;

              while (*p && *p != '\n') p++;

              state++;
            }
          break;

        case 1:
          /* Reading body of info section */
          while (g_ascii_isspace (*p))
            p++;
          if (*p == '*' && *(p + 1) == '/')
            {
              gtk_text_buffer_get_iter_at_offset (source_buffer, &start, 0);
              state++;
            }
          else
            {
              int len;

              while (*p == '*' || g_ascii_isspace (*p))
                p++;

              len = strlen (p);
              while (g_ascii_isspace (*(p + len - 1)))
                len--;

              if (len > 0)
                {
                  if (in_para)
                    gtk_text_buffer_insert (info_buffer, &start, " ", 1);

                  g_assert (strlen (p) >= len);
                  gtk_text_buffer_insert (info_buffer, &start, p, len);
                  in_para = 1;
                }
              else
                {
                  gtk_text_buffer_insert (info_buffer, &start, "\n", 1);
                  in_para = 0;
                }
            }
          break;

        case 2:
          /* Skipping blank lines */
          while (g_ascii_isspace (*p))
            p++;
          if (*p)
            {
              p = lines[i];
              state++;
              /* Fall through */
            }
          else
            break;

        case 3:
          /* Reading program body */
          gtk_text_buffer_insert (source_buffer, &start, p, -1);
          if (lines[i+1] != NULL)
            gtk_text_buffer_insert (source_buffer, &start, "\n", 1);
          break;
        }
    }

  g_strfreev (lines);

  fontify (source_buffer);

  gtk_text_buffer_create_tag (source_buffer, "top-margin",
                              "pixels-above-lines", 20,
                              NULL);
  gtk_text_buffer_get_start_iter (source_buffer, &start);
  end = start;
  gtk_text_iter_forward_word_end (&end);
  gtk_text_buffer_apply_tag_by_name (source_buffer, "top-margin", &start, &end);

  gtk_text_buffer_create_tag (source_buffer, "bottom-margin",
                              "pixels-below-lines", 20,
                              NULL);
  gtk_text_buffer_get_end_iter (source_buffer, &end);
  start = end;
  gtk_text_iter_backward_word_start (&start);
  gtk_text_buffer_apply_tag_by_name (source_buffer, "bottom-margin", &start, &end);

  gtk_text_view_set_buffer (GTK_TEXT_VIEW (source_view), source_buffer);
  g_object_unref (source_buffer);

  gtk_text_buffer_create_tag (info_buffer, "top-margin",
                              "pixels-above-lines", 20,
                              NULL);
  gtk_text_buffer_get_start_iter (info_buffer, &start);
  end = start;
  gtk_text_iter_forward_word_end (&end);
  gtk_text_buffer_apply_tag_by_name (info_buffer, "top-margin", &start, &end);

  gtk_text_buffer_create_tag (info_buffer, "bottom-margin",
                              "pixels-below-lines", 20,
                              NULL);
  gtk_text_buffer_get_end_iter (info_buffer, &end);
  start = end;
  gtk_text_iter_backward_word_start (&start);
  gtk_text_buffer_apply_tag_by_name (info_buffer, "bottom-margin", &start, &end);

  gtk_text_view_set_buffer (GTK_TEXT_VIEW (info_view), info_buffer);
  g_object_unref (info_buffer);
}
Beispiel #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;
        }