Esempio n. 1
0
void Highlight::searchwords_find_fast(GtkTextBuffer * textbuffer, GtkTextIter * beginbound, GtkTextIter * endbound, const ustring & searchword, bool casesensitive, vector < GtkTextIter > &wordstart, vector < GtkTextIter > &wordend)
// Searches for words to highlight. For simple highligthing. 
// Is much faster than the slow routine, see there fore more information.
{
  // Variable.
  GtkTextIter begin;
  GtkTextIter end;
  // Extract the line.
  ustring line = gtk_text_buffer_get_slice(textbuffer, beginbound, endbound, false);
  // Deal with case sensitivity.
  ustring case_considerate_search_word(searchword);
  if (!casesensitive)
    case_considerate_search_word = case_considerate_search_word.casefold();
  // Go through the line looking for matches.
  for (unsigned int i = 0; i < line.length(); i++) {
    if (interrupt_thread)
      continue;
    ustring compareline(line.substr(i, searchword.length()));
    // Deal with case sensitivity.
    if (!casesensitive)
      compareline = compareline.casefold();
    // Now compare.
    if (case_considerate_search_word == compareline) {
      // Get the iterators in the textbuffer that belong to this possible match.
      begin = *beginbound;
      gtk_text_iter_forward_chars(&begin, i);
      end = begin;
      gtk_text_iter_forward_chars(&end, searchword.length());
      // Add the boundaries of the word to highlight.
      wordstart.push_back(begin);
      wordend.push_back(end);
    }
  }
}
static void
ide_source_snippet_get_nth_chunk_range (IdeSourceSnippet *self,
                                        gint              n,
                                        GtkTextIter      *begin,
                                        GtkTextIter      *end)
{
  gint run;
  gint i;

  g_return_if_fail (IDE_IS_SOURCE_SNIPPET (self));
  g_return_if_fail (n >= 0);
  g_return_if_fail (begin);
  g_return_if_fail (end);

  gtk_text_buffer_get_iter_at_mark (self->buffer, begin, self->mark_begin);

  for (i = 0; i < n; i++)
    {
      run = g_array_index (self->runs, gint, i);
      gtk_text_iter_forward_chars (begin, run);
    }

  gtk_text_iter_assign (end, begin);
  run = g_array_index (self->runs, gint, n);
  gtk_text_iter_forward_chars (end, run);
}
Esempio n. 3
0
/* vers=0: right == NOOPS*/
static void doc_shift_selection( Tdocument *doc, gboolean vers ) {
	GtkTextIter itstart, itend;
	if ( gtk_text_buffer_get_selection_bounds( doc->buffer, &itstart, &itend ) ) {
		GtkTextMark * end;

		doc_unbind_signals( doc );
		doc_unre_new_group( doc );
		/* we have a selection, now we loop trough the characters, and for every newline
		we add or remove a tab, we set the end with a mark */
		end = gtk_text_buffer_create_mark( doc->buffer, NULL, &itend, TRUE );
		/* set to: the fist char of the fist line */
		if ( gtk_text_iter_get_line_offset( &itstart ) > 0 ) {
			gtk_text_iter_set_line_index( &itstart, 0 );
		}
		/* remove one line from current selection for each step*/
		while ( gtk_text_iter_compare( &itstart, &itend ) < 0 ) {
			GtkTextMark * cur;
			cur = gtk_text_buffer_create_mark( doc->buffer, NULL, &itstart, TRUE );
			if ( vers ) {
				itend = itstart;
				gtk_text_iter_forward_chars( &itend, 1 );
				gchar *buf = gtk_text_buffer_get_text( doc->buffer, &itstart, &itend, FALSE );
				if ( !strstr( buf, "\n" ) ) {
					gint offsetstart, offsetend;
					offsetstart = gtk_text_iter_get_offset( &itstart );
					offsetend = gtk_text_iter_get_offset( &itend );
					gtk_text_buffer_delete( doc->buffer, &itstart, &itend );
					doc_unre_add( doc, buf, offsetstart, offsetend, UndoDelete );
				}
				g_free( buf );
			}
			gtk_text_buffer_get_iter_at_mark( doc->buffer, &itstart, cur );
			gtk_text_buffer_get_iter_at_mark( doc->buffer, &itend, end );
			gtk_text_buffer_delete_mark( doc->buffer, cur );
			/* forward one more line */
			gtk_text_iter_forward_line( &itstart );
		}
		gtk_text_buffer_delete_mark( doc->buffer, end );
		doc_bind_signals( doc );
		doc_set_modified( doc, 1 );
	} else {
		/* there is no selection, work on the current line */
		GtkTextIter iter;
		gtk_text_buffer_get_iter_at_mark( doc->buffer, &iter, gtk_text_buffer_get_insert( doc->buffer ) );
		if ( vers ) {
			GtkTextIter itend;
			gtk_text_iter_set_line_offset( &iter, 0 );
			itend = iter;
			gtk_text_iter_forward_chars( &itend, 1 );
			gtk_text_buffer_delete( doc->buffer, &iter, &itend );
		}
	}
}
Esempio n. 4
0
/* returns the number of bytes
that are already present in the text.

this is used to avoid for example inserting "return;" in a location where ';' is already the
character directly beyond the insert position.
*/
static gint
get_existing_end_len(BluefishTextView * btv, const gchar *string, gint prefix_bytelen)
{
	gchar *tmp;
	GtkTextIter it1, it2;
	gint i,len;
	gint string_len = g_utf8_strlen(string, -1);

	gtk_text_buffer_get_iter_at_mark(btv->buffer, &it1, gtk_text_buffer_get_insert(btv->buffer));
	it2 = it1;
	DBG_AUTOCOMP("get_existing_end_len, forward %d chars\n",string_len - prefix_bytelen);
	gtk_text_iter_forward_chars(&it2,string_len - prefix_bytelen);
	DBG_AUTOCOMP("get the text %d:%d\n",gtk_text_iter_get_offset(&it1),gtk_text_iter_get_offset(&it2));
	tmp = gtk_text_buffer_get_text(btv->buffer, &it1, &it2, TRUE);
	/*g_print("got tmp='%s'\n",tmp);*/
	len = strlen(tmp);
	i = len-1;
	do {
		DBG_AUTOCOMP("get_existing_end_len, compare %d characters of %s and %s\n",i,string+prefix_bytelen+len-i,tmp);
		if (strncmp(string+prefix_bytelen+len-i, tmp, i)==0) {
			DBG_AUTOCOMP("get_existing_end_len, found %d existing characters\n",i);
			g_free(tmp);
			return i;
		}
		i--;
	} while(i>0);
	g_free(tmp);
	DBG_AUTOCOMP("get_existing_end_len, found no existing characters\n");
	return 0;
}
Esempio n. 5
0
static gboolean locate_color(Tdocument *doc, const GtkTextIter *iter) {
	Tin_html_tag iht;
	gboolean retval=FALSE;
	GtkTextIter leftiter=*iter, rightiter, maxiter = *iter;
	DEBUG_MSG("locate_color, started\n");
	rec_color.found = FALSE;
	gtk_text_iter_backward_chars(&maxiter, 8);
	/* first we look to the left for a #, and we look back at max. 8 chars (7 would be good enough) */
	iht.findchar = '#';
	iht.prevchar = '\n';
	iht.ignore_if_prevchar = '\0';
	if (gtk_text_iter_backward_find_char(&leftiter,
					(GtkTextCharPredicate)iter_char_search_lcb,&iht,&maxiter)) 
					{
		gchar *text;
		rightiter = leftiter;
		gtk_text_iter_forward_chars(&rightiter, 7);
		text = gtk_text_buffer_get_text(doc->buffer,&leftiter,&rightiter,FALSE);
		DEBUG_MSG("locate_color,is '%s' a color?\n",text);
		if (text) {
			retval = string_is_color(text);
			if (retval) {
				rec_color.so = gtk_text_iter_get_offset(&leftiter);
				rec_color.eo = gtk_text_iter_get_offset(&rightiter);
				rec_color.found = TRUE;
				rec_color.doc = doc;
				DEBUG_MSG("found color from so=%d to eo=%d\n",rec_color.so, rec_color.eo);
			}
			g_free(text);
		}
	}
	return retval;
}
Esempio n. 6
0
static gchar *
get_content_type_from_content (GeditDocument *doc)
{
	gchar *content_type;
	gchar *data;
	GtkTextBuffer *buffer;
	GtkTextIter start;
	GtkTextIter end;

	buffer = GTK_TEXT_BUFFER (doc);

	gtk_text_buffer_get_start_iter (buffer, &start);
	end = start;
	gtk_text_iter_forward_chars (&end, 255);

	data = gtk_text_buffer_get_text (buffer, &start, &end, TRUE);

	content_type = g_content_type_guess (NULL,
	                                     (const guchar *)data,
	                                     strlen (data),
	                                     NULL);

	g_free (data);

	return content_type;
}
Esempio n. 7
0
//==========================================================================
  char GUI_edi_RdChr (MemObj *mo, int offset) {
//==========================================================================
/// \code
/// read char near cursor;
/// offset  0 = char right of cursor
/// offset -1 = char left of cursor
/// returns  '\0' for out-of-file-positions.
/// returns  -1 for a multibyte-character
/// \endcode

  GtkTextMark *mk1;
  GtkTextIter it1;
  gboolean    b1;
  long        uc;
  // char        c1;


  // printf("GUI_edi_RdChr |%c| %d\n",c1,cpos);

  // set GUI_ed1_view GUI_ed1_buff
  if(mo) {   // for internal call: mo=NULL
    if(GUI_ed1_decode(mo)) return -1;
  }


  // get mark at CurPos
  mk1 = gtk_text_buffer_get_mark (GUI_ed1_buff, "insert");

  // iter at CurPos
  gtk_text_buffer_get_iter_at_mark (GUI_ed1_buff, &it1, mk1);

  // move iter back
  if(offset < 0) {
    b1 = gtk_text_iter_backward_chars (&it1, -offset);
    // false if left of 1. char; returns Null !.
    if(b1 == FALSE) return '\0';
  }

  // move iter forw
  if(offset > 0) {
    b1 = gtk_text_iter_forward_chars (&it1, offset);
    // false if left of 1. char; returns Null !.
    if(b1 == FALSE) return '\0';
  }


  // get unicode-char at curpos
  uc = gtk_text_iter_get_char (&it1);

  if((uc > 127)||(uc < 0)) return -1;

  // printf("ex GUI_edi_RdChr |%ld|\n",uc);

  return uc;

}
Esempio n. 8
0
void Highlight::searchwords_in_area(GtkTextBuffer * textbuffer, vector < GtkTextIter > &start, vector < GtkTextIter > &end, bool area_id, bool area_intro, bool area_heading, bool area_chapter, bool area_study, bool area_notes, bool area_xref, bool area_verse)
/*
Finds out whether the text within the "start" and "end" iterators is inside
one of the given areas. If not, it removes the iterator from the containers.
*/
{
  // Categorization data
  CategorizeLine categorize("");
  // Go through the iterators, starting at the end (to make erasing it easier).
  for (int it = start.size() - 1; it >= 0; it--) {
    // Get line number of the iterator.
    gint linenumber = gtk_text_iter_get_line(&start[it]);
    // Get the usfm this line starts with.
    ustring usfm;
    {
      GtkTextIter line1;
      gtk_text_buffer_get_iter_at_line(textbuffer, &line1, linenumber);
      GtkTextIter line2 = line1;
      gtk_text_iter_forward_chars(&line2, 10);
      ustring line = gtk_text_iter_get_text(&line1, &line2);
      usfm = usfm_extract_marker(line);
    }
    // See if this usfm is in one of the areas given.
    bool in_area = false;
    if (area_id)
      if (categorize.is_id_marker(usfm))
        in_area = true;
    if (area_intro)
      if (categorize.is_intro_marker(usfm))
        in_area = true;
    if (area_heading)
      if (categorize.is_head_marker(usfm))
        in_area = true;
    if (area_chapter)
      if (categorize.is_chap_marker(usfm))
        in_area = true;
    if (area_study)
      if (categorize.is_study_marker(usfm))
        in_area = true;
    // The variables "area_notes" and "area_xref" are not relevant.
    if (area_verse)
      if (categorize.is_verse_marker(usfm))
        in_area = true;
    // If not in one of the areas, remove this iterator from the container.
    if (!in_area) {
      vector < GtkTextIter >::iterator startiter = start.begin();
      vector < GtkTextIter >::iterator enditer = end.begin();
      for (int i = 0; i < it; i++) {
        startiter++;
        enditer++;
      }
      start.erase(startiter);
      end.erase(enditer);
    }
  }
}
Esempio n. 9
0
File: color.c Progetto: Moeryn/bmc
/**
 * \fn void color(BrailleMusicEditor *editor)
 * \brief This function color the differents types of braille music notations
 * in the textview.
 * \param editor The GUI structure.
 * 
 * This function will color the diffrents types of braille music notations present in text. 
 */
void color(BrailleMusicEditor *editor)
{
    GtkTextIter start, end;
    GtkTextIter start_match, end_match, start_match2, start_match3;

    GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(editor->textview)); 
    
    gtk_text_buffer_get_start_iter(buffer, &start);
    gtk_text_buffer_get_end_iter(buffer, &end);
    
    gtk_text_buffer_get_start_iter(buffer, &start_match);
    gtk_text_buffer_get_start_iter(buffer, &end_match);
    
    set_tags(buffer);
    init_braille_table();
    
    do {
	gtk_text_iter_forward_chars(&end_match, 1);
	gchar *c = gtk_text_iter_get_slice(&start_match, &end_match);
	
	start_match2 = start_match;
	gtk_text_iter_backward_chars(&start_match2, 1);
	gchar *c2 = gtk_text_iter_get_slice(&start_match2, &end_match);
	
	start_match3 = start_match2;
	gtk_text_iter_backward_chars(&start_match3, 1);
	gchar *c3 = gtk_text_iter_get_slice(&start_match3, &end_match);

	gchar *type;
	if((type = g_hash_table_lookup(braille_table, c3)) != NULL) {
	    gtk_text_buffer_remove_all_tags(buffer, &start_match3, &end_match);
	    gtk_text_buffer_apply_tag_by_name(buffer, type, &start_match3, &end_match);
	}
	else if((type = g_hash_table_lookup(braille_table, c2)) != NULL) {
	    gtk_text_buffer_remove_all_tags(buffer, &start_match2, &end_match);
	    gtk_text_buffer_apply_tag_by_name(buffer, type, &start_match2, &end_match);
	}
	else if((type = g_hash_table_lookup(braille_table, c)) != NULL) {
	    gtk_text_buffer_apply_tag_by_name(buffer, type, &start_match, &end_match);
	}
	
    } while(gtk_text_iter_forward_chars(&start_match, 1));
}
Esempio n. 10
0
static gboolean word_starts_with(const GtkTextIter *word_start, const char *prefix) {
	gboolean res;
	gchar *schema = NULL;
	GtkTextIter end = *word_start;
	gtk_text_iter_forward_chars(&end, strlen(prefix));
	schema = gtk_text_iter_get_slice(word_start, &end);
	res = ( g_strcmp0(schema, prefix) == 0 );
	g_free(schema);
	return res;
}
Esempio n. 11
0
gchar *
ide_source_snippet_get_nth_text (IdeSourceSnippet *self,
                                 gint              n)
{
  GtkTextIter iter;
  GtkTextIter end;
  gchar *ret;
  gint i;

  g_return_val_if_fail (IDE_IS_SOURCE_SNIPPET (self), NULL);
  g_return_val_if_fail (n >= 0, NULL);

  gtk_text_buffer_get_iter_at_mark (self->buffer, &iter, self->mark_begin);

  for (i = 0; i < n; i++)
    gtk_text_iter_forward_chars (&iter, g_array_index (self->runs, gint, i));

  gtk_text_iter_assign (&end, &iter);
  gtk_text_iter_forward_chars (&end, g_array_index (self->runs, gint, n));

  ret = gtk_text_buffer_get_text (self->buffer, &iter, &end, TRUE);

  return ret;
}
Esempio n. 12
0
/* While not as cool as c-mode, this will do as a quick attempt at highlighting */
static void
fontify (GtkTextBuffer *source_buffer)
{
  GtkTextIter start_iter, next_iter, tmp_iter;
  gint state;
  gchar *text;
  gchar *start_ptr, *end_ptr;
  gchar *tag;

  gtk_text_buffer_get_bounds (source_buffer, &start_iter, &tmp_iter);
  gtk_text_buffer_apply_tag_by_name (source_buffer, "source", &start_iter, &tmp_iter);

  state = STATE_NORMAL;

  gtk_text_buffer_get_iter_at_offset (source_buffer, &start_iter, 0);

  next_iter = start_iter;
  while (gtk_text_iter_forward_line (&next_iter))
    {
      gboolean start = TRUE;
      start_ptr = text = gtk_text_iter_get_text (&start_iter, &next_iter);

      do
        {
          parse_chars (start_ptr, &end_ptr, &state, &tag, start);

          start = FALSE;
          if (end_ptr)
            {
              tmp_iter = start_iter;
              gtk_text_iter_forward_chars (&tmp_iter, end_ptr - start_ptr);
            }
          else
            {
              tmp_iter = next_iter;
            }
          if (tag)
            gtk_text_buffer_apply_tag_by_name (source_buffer, tag, &start_iter, &tmp_iter);

          start_iter = tmp_iter;
          start_ptr = end_ptr;
        }
      while (end_ptr);

      g_free (text);
      start_iter = next_iter;
    }
}
bool CheckCapitalization::is_reference(GtkTextIter iter)
/*
Looks whether the text at iter looks like a reference.
A reference, e.g. Mt.5.5 or Mt.5:5 or John 10:5 follows a certain pattern,
while going through it. Some references are given without the bookname, e.g.
"10.5". Handle these too.
Patterns:
- digit, dot/colon, digit.
*/
{
  GtkTextIter iter0 = iter;
  gtk_text_iter_backward_chars(&iter0, 4);
  gtk_text_iter_forward_chars(&iter, 4);
  ustring reference = gtk_text_iter_get_text(&iter0, &iter);
  return text_contains_reference(reference);
}
Esempio n. 14
0
File: gitg-utils.c Progetto: hb/gitg
gchar *
gitg_utils_guess_content_type(GtkTextBuffer *buffer)
{
    GtkTextIter start;
    GtkTextIter end;

    gtk_text_buffer_get_start_iter(buffer, &start);
    end = start;

    gtk_text_iter_forward_chars(&end, 256);
    gchar *data = gtk_text_buffer_get_text(buffer, &start, &end, FALSE);

    gchar *content_type = g_content_type_guess(NULL, (guchar *)data, strlen(data), NULL);
    g_free(data);

    return content_type;
}
Esempio n. 15
0
void indent_multi_line_unindent(GtkTextBuffer *buffer)
{
	GtkTextIter start_iter, end_iter, iter;
	gint start_line, end_line, i, len;
	gboolean pos;
	gchar *ind;
	
	gtk_text_buffer_get_selection_bounds(buffer, &start_iter, &end_iter);
	start_line = gtk_text_iter_get_line(&start_iter);
	end_line = gtk_text_iter_get_line(&end_iter);
	gtk_text_buffer_get_iter_at_mark(buffer, &iter, gtk_text_buffer_get_insert(buffer));
	pos = gtk_text_iter_equal(&iter, &start_iter);
	i = start_line;
	do {
		ind = compute_indentation(buffer, NULL, i);
		if (ind && strlen(ind)) {
			len = compute_indent_offset_length(ind);
			gtk_text_buffer_get_iter_at_line(buffer, &start_iter, i);
			gtk_text_buffer_place_cursor(buffer, &start_iter);
			end_iter = start_iter;
			gtk_text_iter_forward_chars(&end_iter, len);
			gtk_text_buffer_move_mark_by_name(buffer, "insert", &end_iter);
			g_signal_emit_by_name(G_OBJECT(buffer), "begin-user-action");
			gtk_text_buffer_delete(buffer, &start_iter, &end_iter);
			g_signal_emit_by_name(G_OBJECT(buffer), "end-user-action");
			undo_set_sequency(TRUE);
			g_free(ind);
		}
		i++;
	} while (i < end_line);
	undo_set_sequency(FALSE);
	
	gtk_text_buffer_get_iter_at_line(buffer, &start_iter, start_line);
	gtk_text_buffer_get_iter_at_line(buffer, &end_iter, end_line);
	if (pos) {
		gtk_text_buffer_place_cursor(buffer, &end_iter);
		gtk_text_buffer_move_mark_by_name(buffer, "insert", &start_iter);
	} else {
		gtk_text_buffer_place_cursor(buffer, &start_iter);
		gtk_text_buffer_move_mark_by_name(buffer, "insert", &end_iter);
	}
}
Esempio n. 16
0
/**
 * bmark_text_for_offset:
 *
 * will use offset if itoffset is NULL
 * will use itoffset if not NULL
 */
static gchar *bmark_text_for_offset(Tdocument *doc, GtkTextIter *itoffset, gint offset) {
	GtkTextIter it, eit, sit;
	if (itoffset) {
		it = *itoffset;
	} else {
		gtk_text_buffer_get_iter_at_offset(doc->buffer,&it,offset);
	}
	sit = eit = it;
	gtk_text_iter_forward_to_line_end(&eit);
	gtk_text_iter_forward_chars(&sit, BMARK_SHOW_NUM_TEXT_CHARS);
	if (!gtk_text_iter_in_range(&sit, &it, &eit))
		sit = eit;
#ifdef DEBUG
	{
		gchar *tmp = gtk_text_iter_get_text(&it, &sit);
		DEBUG_MSG("bmark_text_for_offset, text=%s\n",tmp);
		g_free(tmp);
	}
#endif
	return gtk_text_iter_get_text(&it, &sit);
}
Esempio n. 17
0
/* Helper function: extract some characters of context around the match, with
 the match itself highlighted in bold. String must be freed. */
static gchar *
extract_context(GtkTextBuffer *buffer, GtkTextIter *match_start, GtkTextIter *match_end)
{
	GtkTextIter context_start = *match_start, context_end = *match_end;

	/* Create a larger range to extract the context */
	gtk_text_iter_backward_chars(&context_start, 8);
	gtk_text_iter_forward_chars(&context_end, 32);

	/* Get the surrounding text as context */
	gchar *before = gtk_text_buffer_get_text(buffer, &context_start, match_start, TRUE);
	gchar *term = gtk_text_buffer_get_text(buffer, match_start, match_end, TRUE);
	gchar *after = gtk_text_buffer_get_text(buffer, match_end, &context_end, TRUE);
	gchar *context = g_strconcat(before, "<b>", term, "</b>", after, NULL);
	g_strdelimit(context, "\n\r\t", ' ');
	g_free(before);
	g_free(term);
	g_free(after);

	return context;
}
Esempio n. 18
0
bool Gobby::FindDialog::find_wrap(const GtkTextIter* from,
                                  SearchDirection direction,
                                  GtkTextIter* match_start,
                                  GtkTextIter* match_end)
{
	SessionView* view = m_folder->get_current_document();
	TextSessionView* text_view = dynamic_cast<TextSessionView*>(view);
	g_assert(text_view != NULL);

	GtkTextIter start_pos = *from;

	bool result = find_range(&start_pos, NULL, direction,
	                         match_start, match_end);
	if(result == true) return true;

	if(!m_check_wrap_around->get_active()) return false;

	// Wrap around
	GtkTextIter restart_pos;
	GtkTextBuffer* buffer = GTK_TEXT_BUFFER(text_view->get_text_buffer());

	if(direction == SEARCH_FORWARD)
		gtk_text_buffer_get_start_iter(buffer, &restart_pos);
	else
		gtk_text_buffer_get_end_iter(buffer, &restart_pos);
		
	// Limit to search to: Normally the position where we started.
	GtkTextIter* relimit = &start_pos;
	if(direction == SEARCH_BACKWARD)
	{
		// ???
		gtk_text_iter_forward_chars(&start_pos,
		                            get_find_text().length());
		if(gtk_text_iter_is_end(&start_pos))
			relimit = NULL;
	}

	return find_range(&restart_pos, relimit, direction,
	                  match_start, match_end);
}
static gboolean
mark_in_current_var(GtkSnippetsInPlaceParser *self, GtkTextMark *mark,gint move_offset)
{
	GtkTextBuffer * buffer = gtk_text_view_get_buffer(self->priv->view);
	GtkTextIter location;
	GtkTextIter start_iter,end_iter;
	GtkTextMark *start_mark, *end_mark;
	gtk_text_buffer_get_iter_at_mark(buffer,&location,mark);
	gtk_text_iter_forward_chars(&location,move_offset);
	GtkSnippetsGtvVar *var = GTKSNIPPETS_GTV_VAR(self->priv->active_var_pos->data);
	start_mark = gtksnippets_gtv_var_get_start_mark(var);
	end_mark = gtksnippets_gtv_var_get_end_mark(var);
	gint current_offset = gtk_text_iter_get_offset(&location);
	gtk_text_buffer_get_iter_at_mark(buffer,&start_iter,start_mark);
	gtk_text_buffer_get_iter_at_mark(buffer,&end_iter,end_mark);
	gint start_offset = gtk_text_iter_get_offset(&start_iter);
	gint end_offset = gtk_text_iter_get_offset(&end_iter);
	/*Test if the cursor is out of the current placeholder*/
	if (current_offset<start_offset || current_offset > end_offset)
		return FALSE;
	return TRUE;
}
Esempio n. 20
0
gboolean save_file (char *fname) {
  FILE *f;
  int ok = TRUE;
    
  if (!fname) {
    GtkWidget *dialog =
      gtk_file_chooser_dialog_new("Save File As...", NULL,
                                  GTK_FILE_CHOOSER_ACTION_SAVE,
                                  GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, NULL);
    int resp = gtk_dialog_run(GTK_DIALOG(dialog));

    if (resp == GTK_RESPONSE_ACCEPT) {
      fname =
        g_strdup(gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)));
      gtk_widget_destroy(dialog);
    }
    else {
      gtk_widget_destroy(dialog);
      return FALSE;
    }
  }
  if (!(f = fopen(fname, "w"))) {
    // Error opening file
    g_printerr("%s: %s\n", fname, g_strerror(errno));
    ok = FALSE;
  }
  else {
    GtkTextIter start, end, p;

    // Get the starting and ending position
    gtk_text_buffer_get_bounds(GTK_TEXT_BUFFER(editor_buf), &start, &end);
    p = start;
    while (!gtk_text_iter_equal(&start, &end)) {
      gchar *buf, *fbuf;
      gsize br, bw;
      GError *err = NULL;

      gtk_text_iter_forward_chars(&p, CHAR_BUF);
      buf = gtk_text_iter_get_slice(&start, &p);
      fbuf = g_locale_from_utf8(buf, -1, &br, &bw, &err);
      g_free(buf);

      if (!fbuf) {
        g_printerr("Failed UTF-8 to locale conversion: %s\n",
                   err->message);
        g_clear_error(&err);
        ok = FALSE;
        break;
      }
      fwrite(fbuf, bw, 1, f);
      g_free(fbuf);
      if (ferror(f)) {
        g_printerr("%s: %s\n", fname, g_strerror(errno));
        ok = FALSE;
        break;
      }
      start = p;
    }
    if (fclose(f) == EOF) {
      g_printerr("%s: %s\n", fname, g_strerror(errno));
      ok = FALSE;
    }
  }
    
  if (ok) {
    gtk_text_buffer_set_modified(editor_buf, FALSE);
    if (fname != filename) {
      gchar *wt = g_strdup_printf("TextView (%s)", fname);

      g_free(filename);
      filename = fname;
      gtk_window_set_title(GTK_WINDOW(editor_window), wt);
      g_free(wt);
    }
  }
  return ok;
}
Esempio n. 21
0
static gsize
read_line (XeditDocumentInputStream *stream,
	   gchar                    *outbuf,
	   gsize                     space_left)
{
	GtkTextIter start, next, end;
	gchar *buf;
	gint bytes; /* int since it's what iter_get_offset returns */
	gsize bytes_to_write, newline_size, read;
	const gchar *newline;
	gboolean is_last;

	gtk_text_buffer_get_iter_at_mark (stream->priv->buffer,
					  &start,
					  stream->priv->pos);

	if (gtk_text_iter_is_end (&start))
		return 0;

	end = next = start;
	newline = get_new_line (stream);

	/* Check needed for empty lines */
	if (!gtk_text_iter_ends_line (&end))
		gtk_text_iter_forward_to_line_end (&end);

	gtk_text_iter_forward_line (&next);

	buf = gtk_text_iter_get_slice (&start, &end);

	/* the bytes of a line includes also the newline, so with the
	   offsets we remove the newline and we add the new newline size */
	bytes = gtk_text_iter_get_bytes_in_line (&start) - stream->priv->bytes_partial;

	/* bytes_in_line includes the newlines, so we remove that assuming that
	   they are single byte characters */
	bytes = bytes - (gtk_text_iter_get_offset (&next) - gtk_text_iter_get_offset (&end));
	is_last = gtk_text_iter_is_end (&end);

	/* bytes_to_write contains the amount of bytes we would like to write.
	   This means its the amount of bytes in the line (without the newline
	   in the buffer) + the amount of bytes for the newline we want to
	   write (newline_size) */
	bytes_to_write = bytes;

	/* do not add the new newline_size for the last line */
	newline_size = get_new_line_size (stream);
	if (!is_last)
		bytes_to_write += newline_size;

	if (bytes_to_write > space_left)
	{
		gchar *ptr;
		gint char_offset;
		gint written;
		gsize to_write;

		/* Here the line does not fit in the buffer, we thus write
		   the amount of bytes we can still fit, storing the position
		   for the next read with the mark. Do not try to write the
		   new newline in this case, it will be handled in the next
		   iteration */
		to_write = MIN (space_left, bytes);
		ptr = buf;
		written = 0;
		char_offset = 0;

		while (written < to_write)
		{
			gint w;

			ptr = g_utf8_next_char (ptr);
			w = (ptr - buf);
			if (w > to_write)
			{
				break;
			}
			else
			{
				written = w;
				++char_offset;
			}
		}

		memcpy (outbuf, buf, written);

		/* Note: offset is one past what we wrote */
		gtk_text_iter_forward_chars (&start, char_offset);
		stream->priv->bytes_partial += written;
		read = written;
	}
	else
	{
		/* First just copy the bytes without the newline */
		memcpy (outbuf, buf, bytes);

		/* Then add the newline, but not for the last line */
		if (!is_last)
		{
			memcpy (outbuf + bytes, newline, newline_size);
		}

		start = next;
		stream->priv->bytes_partial = 0;
		read = bytes_to_write;
	}

	gtk_text_buffer_move_mark (stream->priv->buffer,
				   stream->priv->pos,
				   &start);

	g_free (buf);
	return read;
}
Esempio n. 22
0
void snippet_info_initial_expand (GuSnippetInfo* info, GuEditor* ec) {
    GuSnippetExpandInfo* value = NULL;
    GtkTextIter start, end;
    GHashTable* map = NULL;
    GList* current = NULL;
    gchar* text = NULL;
    gint key = 0;

    map = g_hash_table_new (NULL, NULL);
    current = g_list_first (info->einfo);

    while (current) {
        GuSnippetExpandInfo* einfo = GU_SNIPPET_EXPAND_INFO (current->data);
        if (!g_hash_table_lookup_extended (map, ((gpointer)einfo->group_number),
                    (gpointer)&key, (gpointer)&value)) {
            g_hash_table_insert (map, (gpointer)einfo->group_number, einfo);
            info->einfo_unique = g_list_append (info->einfo_unique, einfo);
        }
        current = g_list_next (current);
    }
    info->einfo_unique = g_list_sort (info->einfo_unique, snippet_info_num_cmp);

    current = g_list_first (info->einfo);
    info->offset = 0;

    while (current) {
        GuSnippetExpandInfo* einfo = GU_SNIPPET_EXPAND_INFO (current->data);
        g_hash_table_lookup_extended (map, (gpointer)einfo->group_number,
                (gpointer)&key, (gpointer)&value);
        gtk_text_buffer_get_iter_at_mark (ec_buffer, &start, einfo->left_mark);
        gtk_text_buffer_get_iter_at_mark (ec_buffer, &end, einfo->right_mark);

        /* Expand macros */
        text = GU_SNIPPET_EXPAND_INFO(current->data)->text;
        if (STR_EQU (text, "SELECTED_TEXT")) {
            GtkTextIter ms, me;
            gtk_text_buffer_delete (ec_buffer, &start, &end);
            gtk_text_buffer_insert (ec_buffer, &start, info->sel_text, -1);
            gtk_text_buffer_get_iter_at_mark (ec_buffer, &ms, &info->sel_start);
            me = ms;
            gtk_text_iter_forward_chars (&me, strlen (info->sel_text));
            gtk_text_buffer_delete (ec_buffer, &ms, &me);
        } else if (STR_EQU (text, "FILENAME")) {
            gtk_text_buffer_delete (ec_buffer, &start, &end);
            gtk_text_buffer_insert (ec_buffer, &start,
                    ec->filename? ec->filename: "", -1);
        } else if (STR_EQU (text, "BASENAME")) {
            gchar* basename = g_path_get_basename(ec->filename?ec->filename:"");
            gtk_text_buffer_delete (ec_buffer, &start, &end);
            gtk_text_buffer_insert (ec_buffer, &start, basename, -1);
            g_free (basename);
        } else {
            /* Expand text of same group with with text of group leader */
            gtk_text_buffer_delete (ec_buffer, &start, &end);
            gtk_text_buffer_insert (ec_buffer, &start, value->text, -1);
        }

        current = g_list_next (current);
    }
    g_hash_table_destroy (map);
}
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;
}
Esempio n. 24
0
File: editor.c Progetto: ueno/c-smie
static gboolean
editor_application_window_key_press_event (GtkWidget *widget,
					   GdkEventKey *event)
{
  EditorApplicationWindow *window = EDITOR_APPLICATION_WINDOW (widget);
  if (event->keyval == GDK_KEY_KP_Tab || event->keyval == GDK_KEY_Tab)
    {
      GtkTextMark *mark;
      smie_gtk_source_buffer_context_t context;
      gint indent, current_indent;
      GtkTextIter iter, start_iter, end_iter;

      memset (&context, 0, sizeof (smie_gtk_source_buffer_context_t));
      context.buffer = window->buffer;
      mark = gtk_text_buffer_get_insert (GTK_TEXT_BUFFER (window->buffer));
      gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (window->buffer),
					&iter,
					mark);
      gtk_text_iter_assign (&context.iter, &iter);
      indent = smie_indenter_calculate (window->indenter, &context);
      if (indent < 0)
	{
	  g_printf ("indent: undetermined\n");
	  return TRUE;
	}
      else
	g_printf ("indent: %d\n", indent);

      /* Point START_ITER to the beginning of the line.  */
      gtk_text_iter_assign (&start_iter, &iter);
      while (!gtk_text_iter_is_start (&start_iter)
	     && !gtk_text_iter_starts_line (&start_iter)
	     && gtk_text_iter_backward_char (&start_iter))
	;

      /* Point END_ITER to the end of the indent and count the offset.  */
      gtk_text_iter_assign (&end_iter, &start_iter);
      current_indent = 0;
      while (!gtk_text_iter_is_end (&end_iter)
	     && !gtk_text_iter_ends_line (&end_iter)
	     && g_unichar_isspace (gtk_text_iter_get_char (&end_iter))
	     && gtk_text_iter_forward_char (&end_iter))
	current_indent++;

      /* Replace the current indent if it doesn't match the computed one.  */
      if (indent < current_indent)
	{
	  gtk_text_iter_forward_chars (&start_iter, indent);
	  gtk_text_buffer_delete (GTK_TEXT_BUFFER (window->buffer),
				  &start_iter, &end_iter);
	}
      else if (indent > current_indent)
	{
	  gchar *text = g_new0 (gchar, indent - current_indent);
	  memset (text, ' ', indent * sizeof (gchar));
	  gtk_text_buffer_insert (GTK_TEXT_BUFFER (window->buffer),
				  &start_iter,
				  text,
				  indent - current_indent);
	  g_free (text);
	}
      return TRUE;
    }
  return GTK_WIDGET_CLASS (editor_application_window_parent_class)->key_press_event (widget, event);
}
Esempio n. 25
0
static void update_view(PussVConsole* self) {
	VConsole* vcon = self->vcon;
	SMALL_RECT* range;
	DWORD i, j, h, w, sz;
	DWORD cx, cy;
	gchar text[(MAX_SCR_LEN+1)*6 + MAX_SCR_ROW];
	gchar* pd = text;
	CHAR_INFO* ps;
	GtkTextIter it, end;
	GtkTextView* txt_view = GTK_TEXT_VIEW(self->view);
	GtkTextBuffer* txt_buf = gtk_text_view_get_buffer(txt_view);

	if( !self->vcon || !self->need_update )
		return;
	self->need_update = FALSE;

	range = &(vcon->screen_info->srWindow);
	h = range->Bottom - range->Top + 1;
	w = range->Right - range->Left + 1;
	cy = vcon->screen_info->dwCursorPosition.Y - range->Top;
	cx = vcon->screen_info->dwCursorPosition.X - range->Left;

	// scroll bar update
	self->adjust->lower = 1;
	self->adjust->upper = vcon->screen_info->dwSize.Y;
	self->adjust->step_increment = 1;
	self->adjust->page_size = h;
	self->adjust->page_increment = h;
	self->adjust->value = range->Top;

	// screen buffer update
	ps = vcon->screen_buffer;
	for( i=0; i<h; ++i ) {
		for( j=0; j<w; ++j ) {
			if( ps->Char.UnicodeChar && g_unichar_validate(ps->Char.UnicodeChar) ) {
				sz = g_unichar_to_utf8(ps->Char.UnicodeChar, pd);
				pd += sz;
				if( ps->Char.UnicodeChar > 0xff ) {
					++j;
					if( cy==i )
						--cx;
				}
			} else {
				//g_print("unknown =  %d\n", ps->Char.UnicodeChar);
			}
			++ps;
		}

		// remove end space
		while(*(pd-1)=='\t' || *(pd-1)==' ' ) --pd;
		*pd = '\n';
		++pd;
	}
	*pd = '\0';
	sz = (DWORD)(pd - text);

	gtk_text_buffer_set_text(txt_buf, text, sz);

	// cursor update
	h = gtk_text_buffer_get_line_count(txt_buf);
	if( cy >= h ) {
		gtk_text_view_set_cursor_visible(txt_view, FALSE);

	} else {
		gtk_text_buffer_get_iter_at_line(txt_buf, &it, cy);
		end = it;
		if( gtk_text_iter_forward_chars(&end, cx) ) {
			it = end;
		} else {
			if( gtk_text_iter_forward_to_line_end(&end) ) {
				it = end;
			} else {
				gtk_text_buffer_get_iter_at_line(txt_buf, &it, cy);
			}
		}
		gtk_text_buffer_place_cursor(txt_buf, &it);
		gtk_text_view_set_cursor_visible(txt_view, TRUE);
	}

	gtk_adjustment_changed(self->adjust);
}
Esempio n. 26
0
/* original version taken from bluefish's (doc_indent_selection) */
gint func_indent( GtkWidget *widget, GdkEventKey *kevent, Tbfwin *bfwin, gint opt) {
	Tdocument *doc = bfwin->current_document;
	if (!doc) return 0;

	gint unindent = opt & FUNC_VALUE_0;

	GtkTextIter itstart, itend;
	if ( gtk_text_buffer_get_selection_bounds( doc->buffer, &itstart, &itend ) ) {
		GtkTextMark * end;
		doc_unbind_signals( doc );
		doc_unre_new_group( doc );
		/* we have a selection, now we loop trough the characters, and for every newline
		we add or remove a tab, we set the end with a mark */
		end = gtk_text_buffer_create_mark( doc->buffer, NULL, &itend, TRUE );
		if ( gtk_text_iter_get_line_offset( &itstart ) > 0 ) {
			gtk_text_iter_set_line_index( &itstart, 0 );
		}
		while ( gtk_text_iter_compare( &itstart, &itend ) < 0 ) {
			GtkTextMark * cur;
			cur = gtk_text_buffer_create_mark( doc->buffer, NULL, &itstart, TRUE );
			if ( unindent ) {
				/* when unindenting we try to set itend to the end of the indenting step
				which might be a tab or 'tabsize' spaces, then we delete that part */
				gboolean cont = TRUE;
				gchar *buf = NULL;
				gunichar cchar = gtk_text_iter_get_char( &itstart );
				if ( cchar == 9 ) { /* 9 is ascii for tab */
					itend = itstart;
					cont = gtk_text_iter_forward_char( &itend );
					buf = g_strdup( "\t" );
				} else if ( cchar == 32 ) { /* 32 is ascii for space */
					gint i = 0;
					itend = itstart;
					gtk_text_iter_forward_chars( &itend, main_v->props.editor_tab_width );
					buf = gtk_text_buffer_get_text( doc->buffer, &itstart, &itend, FALSE );
					DEBUG_MSG( "func_indent: tab_width=%d, strlen(buf)=%d, buf='%s'\n", main_v->props.editor_tab_width, strlen( buf ), buf );
					while ( cont && buf[ i ] != '\0' ) {
						cont = ( buf[ i ] == ' ' );
						DEBUG_MSG( "func_indent: buf[%d]='%c'\n", i, buf[ i ] );
						i++;
					}
					if ( !cont ) {
						g_free ( buf );
					}
				} else {
					cont = FALSE;
				}
				if ( cont ) {
					gint offsetstart, offsetend;
					offsetstart = gtk_text_iter_get_offset( &itstart );
					offsetend = gtk_text_iter_get_offset( &itend );
					gtk_text_buffer_delete( doc->buffer, &itstart, &itend );
					doc_unre_add( doc, buf, offsetstart, offsetend, UndoDelete );
					g_free ( buf );
				}
			} else { /* indent */
				gint offsetstart = gtk_text_iter_get_offset( &itstart );
				gchar *indentstring;
				gint indentlen;
				if ( main_v->props.view_bars & MODE_INDENT_WITH_SPACES ) {
					indentstring = bf_str_repeat( " ", main_v->props.editor_tab_width );
					indentlen = main_v->props.editor_tab_width;
				} else {
					indentstring = g_strdup( "\t" );
					indentlen = 1;
				}
				gtk_text_buffer_insert( doc->buffer, &itstart, indentstring, indentlen );
				doc_unre_add( doc, indentstring, offsetstart, offsetstart + indentlen, UndoInsert );
				g_free( indentstring );
			}
			gtk_text_buffer_get_iter_at_mark( doc->buffer, &itstart, cur );
			gtk_text_buffer_get_iter_at_mark( doc->buffer, &itend, end );
			gtk_text_buffer_delete_mark( doc->buffer, cur );
			gtk_text_iter_forward_line( &itstart );
			DEBUG_MSG( "func_indent: itstart at %d, itend at %d\n", gtk_text_iter_get_offset( &itstart ), gtk_text_iter_get_offset( &itend ) );
		}
		gtk_text_buffer_delete_mark( doc->buffer, end );
		doc_bind_signals( doc );
		doc_set_modified( doc, 1 );
	} else {
		/* there is no selection, work on the current line */
		GtkTextIter iter;
		gtk_text_buffer_get_iter_at_mark( doc->buffer, &iter, gtk_text_buffer_get_insert( doc->buffer ) );
		gtk_text_iter_set_line_offset( &iter, 0 );
		if ( unindent ) {
			gint deletelen = 0;
			gchar *tmpstr, *tmp2str;
			GtkTextIter itend = iter;
			gtk_text_iter_forward_chars( &itend, main_v->props.editor_tab_width );
			tmpstr = gtk_text_buffer_get_text( doc->buffer, &iter, &itend, FALSE );
			tmp2str = bf_str_repeat( " ", main_v->props.editor_tab_width );
			if ( tmpstr[ 0 ] == '\t' ) {
				deletelen = 1;
			} else if ( tmpstr && strncmp( tmpstr, tmp2str, main_v->props.editor_tab_width ) == 0 ) {
				deletelen = main_v->props.editor_tab_width;
			}
			g_free( tmpstr );
			g_free( tmp2str );
			if ( deletelen ) {
				itend = iter;
				gtk_text_iter_forward_chars( &itend, deletelen );
				gtk_text_buffer_delete( doc->buffer, &iter, &itend );
			}
		} else { /* indent */
			gchar *indentstring;
			gint indentlen;
			if ( main_v->props.view_bars & MODE_INDENT_WITH_SPACES ) {
				indentstring = bf_str_repeat( " ", main_v->props.editor_tab_width );
				indentlen = main_v->props.editor_tab_width;
			} else {
				indentstring = g_strdup( "\t" );
				indentlen = 1;
			}
			gtk_text_buffer_insert( doc->buffer, &iter, indentstring, indentlen );
			g_free( indentstring );
		}
	}
	return 1;
}
Esempio n. 27
0
static void
gimp_text_tool_move_cursor (GimpTextTool    *text_tool,
                            GtkMovementStep  step,
                            gint             count,
                            gboolean         extend_selection)
{
  GtkTextBuffer *buffer = GTK_TEXT_BUFFER (text_tool->buffer);
  GtkTextIter    cursor;
  GtkTextIter    selection;
  GtkTextIter   *sel_start;
  gboolean       cancel_selection = FALSE;
  gint           x_pos  = -1;

  GIMP_LOG (TEXT_EDITING, "%s count = %d, select = %s",
            g_enum_get_value (g_type_class_ref (GTK_TYPE_MOVEMENT_STEP),
                              step)->value_name,
            count,
            extend_selection ? "TRUE" : "FALSE");

  gtk_text_buffer_get_iter_at_mark (buffer, &cursor,
                                    gtk_text_buffer_get_insert (buffer));
  gtk_text_buffer_get_iter_at_mark (buffer, &selection,
                                    gtk_text_buffer_get_selection_bound (buffer));

  if (extend_selection)
    {
      sel_start = &selection;
    }
  else
    {
      /*  when there is a selection, moving the cursor without
       *  extending it should move the cursor to the end of the
       *  selection that is in moving direction
       */
      if (count > 0)
        gtk_text_iter_order (&selection, &cursor);
      else
        gtk_text_iter_order (&cursor, &selection);

      sel_start = &cursor;

      /* if we actually have a selection, just move *to* the beginning/end
       * of the selection and not *from* there on LOGICAL_POSITIONS
       * and VISUAL_POSITIONS movement
       */
      if (! gtk_text_iter_equal (&cursor, &selection))
        cancel_selection = TRUE;
    }

  switch (step)
    {
    case GTK_MOVEMENT_LOGICAL_POSITIONS:
      if (! cancel_selection)
        gtk_text_iter_forward_visible_cursor_positions (&cursor, count);
      break;

    case GTK_MOVEMENT_VISUAL_POSITIONS:
      if (! cancel_selection)
        {
          PangoLayout *layout;
          const gchar *text;

          if (! gimp_text_tool_ensure_layout (text_tool))
            break;

          layout = gimp_text_layout_get_pango_layout (text_tool->layout);
          text = pango_layout_get_text (layout);

          while (count != 0)
            {
              const gunichar word_joiner = 8288; /*g_utf8_get_char(WORD_JOINER);*/
              gint index;
              gint trailing = 0;
              gint new_index;

              index = gimp_text_buffer_get_iter_index (text_tool->buffer,
                                                       &cursor, TRUE);

              if (count > 0)
                {
                  if (g_utf8_get_char (text + index) == word_joiner)
                    pango_layout_move_cursor_visually (layout, TRUE,
                                                       index, 0, 1,
                                                       &new_index, &trailing);
                  else
                    new_index = index;

                  pango_layout_move_cursor_visually (layout, TRUE,
                                                     new_index, trailing, 1,
                                                     &new_index, &trailing);
                  count--;
                }
              else
                {
                  pango_layout_move_cursor_visually (layout, TRUE,
                                                     index, 0, -1,
                                                     &new_index, &trailing);

                  if (new_index != -1 && new_index != G_MAXINT &&
                      g_utf8_get_char (text + new_index) == word_joiner)
                    {
                      pango_layout_move_cursor_visually (layout, TRUE,
                                                         new_index, trailing, -1,
                                                         &new_index, &trailing);
                    }

                  count++;
                }

              if (new_index != G_MAXINT && new_index != -1)
                index = new_index;
              else
                break;

              gimp_text_buffer_get_iter_at_index (text_tool->buffer,
                                                  &cursor, index, TRUE);
              gtk_text_iter_forward_chars (&cursor, trailing);
            }
        }
      break;

    case GTK_MOVEMENT_WORDS:
      if (count < 0)
        {
          gtk_text_iter_backward_visible_word_starts (&cursor, -count);
        }
      else if (count > 0)
        {
	  if (! gtk_text_iter_forward_visible_word_ends (&cursor, count))
	    gtk_text_iter_forward_to_line_end (&cursor);
        }
      break;

    case GTK_MOVEMENT_DISPLAY_LINES:
      {
        GtkTextIter      start;
        GtkTextIter      end;
        gint             cursor_index;
        PangoLayout     *layout;
        PangoLayoutLine *layout_line;
        PangoLayoutIter *layout_iter;
        PangoRectangle   logical;
        gint             line;
        gint             trailing;
        gint             i;

        gtk_text_buffer_get_bounds (buffer, &start, &end);

        cursor_index = gimp_text_buffer_get_iter_index (text_tool->buffer,
                                                        &cursor, TRUE);

        if (! gimp_text_tool_ensure_layout (text_tool))
          break;

        layout = gimp_text_layout_get_pango_layout (text_tool->layout);

        pango_layout_index_to_line_x (layout, cursor_index, FALSE,
                                      &line, &x_pos);

        layout_iter = pango_layout_get_iter (layout);
        for (i = 0; i < line; i++)
          pango_layout_iter_next_line (layout_iter);

        pango_layout_iter_get_line_extents (layout_iter, NULL, &logical);

        x_pos += logical.x;

        pango_layout_iter_free (layout_iter);

        /*  try to go to the remembered x_pos if it exists *and* we are at
         *  the beginning or at the end of the current line
         */
        if (text_tool->x_pos != -1 && (x_pos <= logical.x ||
                                       x_pos >= logical.x + logical.width))
          x_pos = text_tool->x_pos;

        line += count;

        if (line < 0)
          {
            cursor = start;
            break;
          }
        else if (line >= pango_layout_get_line_count (layout))
          {
            cursor = end;
            break;
          }

        layout_iter = pango_layout_get_iter (layout);
        for (i = 0; i < line; i++)
          pango_layout_iter_next_line (layout_iter);

        layout_line = pango_layout_iter_get_line_readonly (layout_iter);
        pango_layout_iter_get_line_extents (layout_iter, NULL, &logical);

        pango_layout_iter_free (layout_iter);

        pango_layout_line_x_to_index (layout_line, x_pos - logical.x,
                                      &cursor_index, &trailing);

        gimp_text_buffer_get_iter_at_index (text_tool->buffer, &cursor,
                                            cursor_index, TRUE);

        while (trailing--)
          gtk_text_iter_forward_char (&cursor);
      }
      break;

    case GTK_MOVEMENT_PAGES: /* well... */
    case GTK_MOVEMENT_BUFFER_ENDS:
      if (count < 0)
        {
          gtk_text_buffer_get_start_iter (buffer, &cursor);
        }
      else if (count > 0)
        {
          gtk_text_buffer_get_end_iter (buffer, &cursor);
        }
      break;

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

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

    default:
      return;
    }

  text_tool->x_pos = x_pos;

  gimp_draw_tool_pause (GIMP_DRAW_TOOL (text_tool));

  gimp_text_tool_reset_im_context (text_tool);

  gtk_text_buffer_select_range (buffer, &cursor, sel_start);

  gimp_draw_tool_resume (GIMP_DRAW_TOOL (text_tool));
}
Esempio n. 28
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);
      }
    }
  }
}
Esempio n. 29
0
static void
add_chat_msg(GtTwitchChatView* self,
             const gchar* sender,
             const gchar* colour,
             const gchar* msg,
             GList* emotes,
             gint user_modes)
{
    GtTwitchChatViewPrivate* priv = gt_twitch_chat_view_get_instance_private(self);
    GtkTextTag* sender_colour_tag = NULL;
    gint offset = 0;

    gtk_text_buffer_get_end_iter(priv->chat_buffer, &priv->bottom_iter);

    if (!colour || strlen(colour) < 1) //TODO: Set random colour instead of just black
        colour = get_default_chat_colour(sender);

    sender_colour_tag = gtk_text_tag_table_lookup(priv->tag_table, colour);

    if (!sender_colour_tag)
    {
        sender_colour_tag = gtk_text_tag_new(colour);
        g_object_set(sender_colour_tag,
                     "foreground", colour,
                     "weight", PANGO_WEIGHT_BOLD,
                     NULL);
        gtk_text_tag_table_add(priv->tag_table, sender_colour_tag);
    }

    offset = strlen(sender) + 2;

    //TODO: Cleanup?
#define INSERT_USER_MOD_PIXBUF(mode, name)                              \
    if (user_modes & mode)                                              \
    {                                                                   \
        gtk_text_buffer_insert_pixbuf(priv->chat_buffer, &priv->bottom_iter, priv->chat_badges->name); \
        gtk_text_buffer_insert(priv->chat_buffer, &priv->bottom_iter, " ", -1); \
        gtk_text_iter_forward_chars(&priv->bottom_iter, 2);             \
        offset += 2;                                                    \
    }                                                                   \

    INSERT_USER_MOD_PIXBUF(USER_MODE_SUBSCRIBER, subscriber);
    INSERT_USER_MOD_PIXBUF(USER_MODE_TURBO, turbo);
    INSERT_USER_MOD_PIXBUF(USER_MODE_GLOBAL_MOD, global_mod);
    INSERT_USER_MOD_PIXBUF(USER_MODE_BROADCASTER, broadcaster);
    INSERT_USER_MOD_PIXBUF(USER_MODE_STAFF, staff);
    INSERT_USER_MOD_PIXBUF(USER_MODE_ADMIN, admin);
    INSERT_USER_MOD_PIXBUF(USER_MODE_MOD, mod);

#undef INSERT_USER_MOD_PIXBUF

    gtk_text_buffer_insert_with_tags(priv->chat_buffer, &priv->bottom_iter, sender, -1, sender_colour_tag, NULL);
    gtk_text_iter_forward_word_end(&priv->bottom_iter);
    gtk_text_buffer_insert(priv->chat_buffer, &priv->bottom_iter, ": ", -1);
    gtk_text_iter_forward_chars(&priv->bottom_iter, 2);
    insert_message_with_emotes(priv->chat_buffer, &priv->bottom_iter, emotes, msg, offset);
    gtk_text_iter_forward_to_line_end(&priv->bottom_iter);
    gtk_text_buffer_insert(priv->chat_buffer, &priv->bottom_iter, "\n", -1);
    gtk_text_buffer_move_mark(priv->chat_buffer, priv->bottom_mark, &priv->bottom_iter);
    gtk_text_view_scroll_mark_onscreen(GTK_TEXT_VIEW(priv->chat_view), priv->bottom_mark);
}
Esempio n. 30
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;
}