static gboolean
get_invalidation_area (GtkTextIter *begin,
                       GtkTextIter *end)
{
    GtkTextIter begin_tmp;
    GtkTextIter end_tmp;

    g_assert (begin != NULL);
    g_assert (end != NULL);

    /*
     * Move to the beginning of line.We dont use gtk_text_iter_backward_line
     * because if begin is at the beginning of the line we dont want to
     * move to the previous line
     */
    gtk_text_iter_set_line_offset (begin, 0);

    /* Move to the beginning of the next line. */
    gtk_text_iter_forward_line (end);

    /* Save the original locations. We will need them down the line. */
    begin_tmp = *begin;
    end_tmp = *end;

    /*
     * Fordward begin iter character by character until:
     * - We reach a non space character
     * - We reach end iter
     */
    while (g_unichar_isspace (gtk_text_iter_get_char (begin)) &&
            gtk_text_iter_compare (begin, &end_tmp) < 0)
        gtk_text_iter_forward_char (begin);


    /*
     * If after moving forward the begin iter, we reached the end iter,
     * there is no need to play with the end iter.
     */
    if (gtk_text_iter_compare (begin, end) < 0)
    {
        /*
         * Backward end iter character by character until:
         * - We reach a non space character
         * - We reach begin iter
         */
        while (g_unichar_isspace (gtk_text_iter_get_char (end)) &&
                gtk_text_iter_compare (end, &begin_tmp) > 0)
            gtk_text_iter_backward_char (end);

        /*
         * If we found the character we are looking for then move one
         * character forward in order to include it as the last
         * character of the begin - end range.
         */
        if (gtk_text_iter_compare (end, &end_tmp) < 0)
            gtk_text_iter_forward_char (end);
    }

    return gtk_text_iter_compare (begin, end) < 0;
}
void
apotheke_highlight_buffer_diff (GtkTextBuffer *buffer, GtkTextIter *start)
{
	GtkTextIter *end;
	GtkTextIter *word_end;
	gchar *c;

	if (!gtk_text_iter_starts_line (start))
		gtk_text_iter_set_line_offset (start, 0);


	while (!gtk_text_iter_is_end (start)) {
		end = gtk_text_iter_copy (start);
		if (!gtk_text_iter_forward_to_line_end (end))
			break;

		word_end = gtk_text_iter_copy (start);
		gtk_text_iter_forward_char (word_end);
		
		c = gtk_text_iter_get_text (start, word_end);
		if (g_ascii_strcasecmp ("+", c) == 0) {
			gtk_text_buffer_apply_tag_by_name (buffer,
							   "diff-added",
							   start, end);
		} 
		else if (g_ascii_strcasecmp ("-", c) == 0) {
			gtk_text_buffer_apply_tag_by_name (buffer,
							   "diff-removed",
							   start, end);
		}

		gtk_text_iter_forward_line (start);
	}
}
示例#3
0
static std::vector<LineInfo> getLinesInfo(GtkTextView* textView, int height)
    {
    std::vector<LineInfo> linesInfo;

    int y1 = 0;
    int y2 = height;
    gtk_text_view_window_to_buffer_coords(textView, GTK_TEXT_WINDOW_LEFT,
            0, y1, NULL, &y1);
    gtk_text_view_window_to_buffer_coords(textView, GTK_TEXT_WINDOW_LEFT,
            0, y2, NULL, &y2);

    GtkTextIter iter;
    gtk_text_view_get_line_at_y(textView, &iter, y1, NULL);
    while(!gtk_text_iter_is_end(&iter))
        {
        int y, height;
        gtk_text_view_get_line_yrange(textView, &iter, &y, &height);
        int line = gtk_text_iter_get_line(&iter);
        linesInfo.push_back(LineInfo(line+1, y));
        if((y + height) >= y2)
            {
            break;
            }
        gtk_text_iter_forward_line(&iter);
        }
    if(linesInfo.size() == 0)
        {
        linesInfo.push_back(LineInfo(1, 1));
        }
    return linesInfo;
    }
示例#4
0
文件: menu_edit.c 项目: kawatea/cedit
//カーソルのある行を削除する
void kill_line(void)
{
    int delete_flag = 0;
    GtkTextIter start, end;
    GtkClipboard *clipboard = gtk_widget_get_clipboard(view, GDK_SELECTION_CLIPBOARD);
    
    buf[0] = '\0';
    if (kill_flag == 1) {
        char *text = gtk_clipboard_wait_for_text(clipboard);
        strcat(buf, text);
        free(text);
    }
    
    gtk_text_buffer_get_iter_at_mark(GTK_TEXT_BUFFER(buffer), &start, gtk_text_buffer_get_insert(GTK_TEXT_BUFFER(buffer)));
    end = start;
    gtk_text_iter_forward_line(&end);
    if (!gtk_text_iter_starts_line(&start) && !gtk_text_iter_ends_line(&start) && !gtk_text_iter_is_end(&end) && kill_flag == 0) gtk_text_iter_backward_char(&end);
    
    char *text = gtk_text_buffer_get_text(GTK_TEXT_BUFFER(buffer), &start, &end, TRUE);
    strcat(buf, text);
    free(text);
    
    if (buf[0] != '\0') delete_flag = 1;
    
    gtk_clipboard_set_text(clipboard, buf, -1);
    gtk_text_buffer_delete(GTK_TEXT_BUFFER(buffer), &start, &end);
    
    kill_flag = delete_flag;
}
示例#5
0
void	Amt::LoggerImpl::insertLine(const char* _ctime, const char* _mess, unsigned _type, bool newString ){
	if (_type >= riku::logger::NUM_ERR_MESS_TYPE )
	    return;
	if (!_in_textbuffer || !_in_textview)    
	    return;
	GtkTextIter iter;
	/*Добавим новое сообщение*/
	gtk_text_buffer_get_end_iter (_in_textbuffer, &iter );
	gtk_text_buffer_insert_with_tags ( _in_textbuffer, &iter, _ctime, -1, _in_tagArr[_type], NULL  );
	gtk_text_buffer_insert ( _in_textbuffer, &iter, "  ", -1 );
	gtk_text_buffer_insert_with_tags(_in_textbuffer, &iter, _mess, -1, _in_tagArr[_type], NULL );
	if (newString)
	    gtk_text_buffer_insert(_in_textbuffer, &iter, "\n", -1);

	/*Передвинем маркер скроллинга, и прокрутим список*/
	GtkTextMark *mark = gtk_text_buffer_get_mark (_in_textbuffer, "scroll");
	gtk_text_buffer_move_mark (_in_textbuffer, mark, &iter);
	gtk_text_view_scroll_mark_onscreen (GTK_TEXT_VIEW(_in_textview), mark);
	/*Удалим записи, если их стало больше чем maxLines*/
	if (_in_maxLines < gtk_text_buffer_get_line_count(_in_textbuffer) ){
	    GtkTextIter startI, endI;
	    gtk_text_buffer_get_iter_at_line(_in_textbuffer, &endI, 9);
	    gtk_text_buffer_get_iter_at_line(_in_textbuffer, &startI, 9);	    
	    gtk_text_iter_forward_line(&endI );
	    gtk_text_buffer_delete(_in_textbuffer, &startI, &endI);
	}
	
}
示例#6
0
static void
update_lines (ExampleAppWindow *win)
{
  ExampleAppWindowPrivate *priv;
  GtkWidget *tab, *view;
  GtkTextBuffer *buffer;
  GtkTextIter iter;
  int count;
  gchar *lines;

  priv = example_app_window_get_instance_private (win);

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

  if (tab == NULL)
    return;

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

  count = 0;

  gtk_text_buffer_get_start_iter (buffer, &iter);
  while (!gtk_text_iter_is_end (&iter))
    {
      count++;
      if (!gtk_text_iter_forward_line (&iter))
        break;
    }

  lines = g_strdup_printf ("%d", count);
  gtk_label_set_text (GTK_LABEL (priv->lines), lines);
  g_free (lines);
}
示例#7
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 );
		}
	}
}
示例#8
0
/*******************************************************************************
 * Advance the cursor n positions on the tutor text view
 */
gint
cursor_advance (gint n)
{
	gint i;
	gboolean cursor_out_screen;
	GtkWidget *wg;
	GtkTextBuffer *buf;
	GtkTextIter new_start;
	GtkTextIter old_start;
	GtkTextIter end;
	GtkTextMark *mark;

	wg = get_wg ("text_tutor");
	buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (wg));

	/* Get current position for the iter old_start */
	gtk_text_buffer_get_iter_at_mark (buf, &new_start, gtk_text_buffer_get_insert (buf));
	old_start = new_start;

	/* Get new position for the iter new_start */
	if (n > 0)
		for (i = 0; i < n && gtk_text_iter_forward_cursor_position (&new_start); i++);
	else
		for (i = 0; i > n && gtk_text_iter_backward_cursor_position (&new_start); i--);

	/* Move cursor blinking */
	end = new_start;
	gtk_text_iter_forward_char (&end);
	gtk_text_buffer_apply_tag_by_name (buf, "cursor_blink", &new_start, &end);

	end = old_start;
	gtk_text_iter_forward_char (&end);
	gtk_text_buffer_remove_tag_by_name (buf, "cursor_blink", &old_start, &end);

	/* Move cursor */
	gtk_text_buffer_place_cursor (buf, &new_start);

	/* Check need for auto-scrolling */
	if (i == n)
	{
		end = new_start;
		gtk_text_iter_forward_line (&end);
		mark = gtk_text_buffer_create_mark (buf, "aux", &end, FALSE);
		cursor_out_screen = gtk_text_view_move_mark_onscreen (GTK_TEXT_VIEW (wg), mark);
		if (cursor_out_screen)
		{
			gtk_text_view_scroll_to_mark (GTK_TEXT_VIEW (wg),
				       	gtk_text_buffer_get_insert (buf), 0.0, TRUE, 0.5, 0.12);
		}
	}
	return (i);
}
示例#9
0
文件: logging.c 项目: 42p/linphone
static void linphone_gtk_display_log(GtkTextView *v, OrtpLogLevel lev, const char *msg){
	GtkTextIter iter,begin;
	int off;
	GtkTextBuffer *b;
	const char *lname="undef";

	b=gtk_text_view_get_buffer(v);
	switch(lev){
		case ORTP_DEBUG:
			lname="debug";
			break;
		case ORTP_MESSAGE:
			lname="message";
			break;
		case ORTP_WARNING:
			lname="warning";
			break;
		case ORTP_ERROR:
			lname="error";
			break;
		case ORTP_FATAL:
			lname="fatal";
			break;
		default:
			g_error("Bad level !");
	}

	gtk_text_buffer_get_end_iter(b,&iter);
	off=gtk_text_iter_get_offset(&iter);
	gtk_text_buffer_insert(b,&iter,lname,-1);
	gtk_text_buffer_get_end_iter(b,&iter);
	gtk_text_buffer_insert(b,&iter,": ",-1);
	gtk_text_buffer_get_end_iter(b,&iter);
	gtk_text_buffer_insert(b,&iter,msg,-1);
	gtk_text_buffer_get_end_iter(b,&iter);
	gtk_text_buffer_insert(b,&iter,"\n",-1);
	gtk_text_buffer_get_end_iter(b,&iter);
	gtk_text_buffer_get_iter_at_offset(b,&begin,off);
	if (lev==ORTP_ERROR || lev==ORTP_FATAL) gtk_text_buffer_apply_tag_by_name(b,"red",&begin,&iter);
	else if (lev==ORTP_WARNING) gtk_text_buffer_apply_tag_by_name(b,"orange",&begin,&iter);

	while(gtk_text_buffer_get_char_count(b)>LOG_MAX_CHARS){
		GtkTextIter iter_line_after;
		gtk_text_buffer_get_start_iter(b,&iter);
		iter_line_after=iter;
		if (gtk_text_iter_forward_line(&iter_line_after)){
			gtk_text_buffer_delete(b,&iter,&iter_line_after);
		}
	}

}
示例#10
0
文件: main.c 项目: Distrotech/gtk
/* 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;
    }
}
示例#11
0
Gobby::OperationSave::OperationSave(Operations& operations,
                                    TextSessionView& view,
                                    const Glib::RefPtr<Gio::File>& file,
                                    const std::string& encoding,
                                    DocumentInfoStorage::EolStyle eol_style):
	Operation(operations), m_file(file), m_view(&view),
	m_start_time(std::time(NULL)), m_current_line_index(0),
	m_encoding(encoding), m_eol_style(eol_style),
	m_storage_key(view.get_info_storage_key()),
	m_iconv(encoding.c_str(), "UTF-8"),
	m_buffer_size(0), m_buffer_index(0)
{
	const Folder& folder = get_folder_manager().get_text_folder();
	folder.signal_document_removed().connect(
		sigc::mem_fun(*this, &OperationSave::on_document_removed));

	// Load content so that the session can go on while saving
	GtkTextBuffer* buffer = GTK_TEXT_BUFFER(view.get_text_buffer());
	GtkTextIter prev;
	GtkTextIter pos;
	GtkTextIter old_pos;

	gtk_text_buffer_get_start_iter(buffer, &prev);
	pos = prev;

	if(!gtk_text_iter_ends_line(&pos))
		gtk_text_iter_forward_to_line_end(&pos);

	do
	{
		Line line;
		line.first =
			gtk_text_buffer_get_text(buffer, &prev, &pos, TRUE);
		line.second = gtk_text_iter_get_line_index(&pos);
		m_lines.push_back(line);

		//if(gtk_text_iter_is_end(&prev))
		//	break;

		old_pos = pos;
		gtk_text_iter_forward_line(&prev);
		gtk_text_iter_forward_to_line_end(&pos);
	} while(!gtk_text_iter_equal(&pos, &old_pos));

	m_current_line = m_lines.begin();
}
static gint
get_last_visible_line_number (GtkSourceGutterRendererLines *lines)
{
	GtkTextView *view;
	GdkRectangle visible_rect;
	GtkTextIter iter;

	view = gtk_source_gutter_renderer_get_view (GTK_SOURCE_GUTTER_RENDERER (lines));

	gtk_text_view_get_visible_rect (view, &visible_rect);

	gtk_text_view_get_line_at_y (view,
				     &iter,
				     visible_rect.y + visible_rect.height,
				     NULL);

	gtk_text_iter_forward_line (&iter);

	return gtk_text_iter_get_line (&iter);
}
示例#13
0
/**
 * gtk_source_iter_forward_search:
 * @iter: start of search.
 * @str: a search string.
 * @flags: flags affecting how the search is done.
 * @match_start: return location for start of match, or %%NULL.
 * @match_end: return location for end of match, or %%NULL.
 * @limit: bound for the search, or %%NULL for the end of the buffer.
 * 
 * Searches forward for @str. Any match is returned by setting 
 * @match_start to the first character of the match and @match_end to the 
 * first character after the match. The search will not continue past
 * @limit. Note that a search is a linear or O(n) operation, so you
 * may wish to use @limit to avoid locking up your UI on large
 * buffers.
 * 
 * If the #GTK_SOURCE_SEARCH_VISIBLE_ONLY flag is present, the match may
 * have invisible text interspersed in @str. i.e. @str will be a
 * possibly-noncontiguous subsequence of the matched range. similarly,
 * if you specify #GTK_SOURCE_SEARCH_TEXT_ONLY, the match may have
 * pixbufs or child widgets mixed inside the matched range. If these
 * flags are not given, the match must be exact; the special 0xFFFC
 * character in @str will match embedded pixbufs or child widgets.
 * If you specify the #GTK_SOURCE_SEARCH_CASE_INSENSITIVE flag, the text will
 * be matched regardless of what case it is in.
 *
 * Same as gtk_text_iter_forward_search(), but supports case insensitive
 * searching.
 * 
 * Return value: whether a match was found.
 **/
gboolean
gtk_source_iter_forward_search (const GtkTextIter   *iter,
				const gchar         *str,
				GtkSourceSearchFlags flags,
				GtkTextIter         *match_start,
				GtkTextIter         *match_end,
				const GtkTextIter   *limit)
{
	gchar **lines = NULL;
	GtkTextIter match;
	gboolean retval = FALSE;
	GtkTextIter search;
	gboolean visible_only;
	gboolean slice;

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

	if ((flags & GTK_SOURCE_SEARCH_CASE_INSENSITIVE) == 0)
		return gtk_text_iter_forward_search (iter, str, flags,
						     match_start, match_end,
						     limit); 

	if (limit && gtk_text_iter_compare (iter, limit) >= 0)
		return FALSE;

	if (*str == '\0')
	{
		/* If we can move one char, return the empty string there */
		match = *iter;

		if (gtk_text_iter_forward_char (&match))
		{
			if (limit && gtk_text_iter_equal (&match, limit))
				return FALSE;

			if (match_start)
				*match_start = match;
			if (match_end)
				*match_end = match;
			return TRUE;
		}
		else
		{
			return FALSE;
		}
	}

	visible_only = (flags & GTK_SOURCE_SEARCH_VISIBLE_ONLY) != 0;
	slice = (flags & GTK_SOURCE_SEARCH_TEXT_ONLY) == 0;

	/* locate all lines */
	lines = strbreakup (str, "\n", -1);

	search = *iter;

	do
	{
		/* This loop has an inefficient worst-case, where
		 * gtk_text_iter_get_text () is called repeatedly on
		 * a single line.
		 */
		GtkTextIter end;

		if (limit && gtk_text_iter_compare (&search, limit) >= 0)
			break;

		if (lines_match (&search, (const gchar**)lines,
				 visible_only, slice, &match, &end))
		{
			if (limit == NULL ||
			    (limit && gtk_text_iter_compare (&end, limit) <= 0))
			{
				retval = TRUE;

				if (match_start)
					*match_start = match;
				if (match_end)
					*match_end = end;
			}
			break;
		}
	} while (gtk_text_iter_forward_line (&search));

	g_strfreev ((gchar**)lines);

	return retval;
}
示例#14
0
static void
dma_sparse_view_paint_margin (DmaSparseView *view,
			      GdkEventExpose *event)
{
	GtkTextView *text_view;
	GdkWindow *win;
	PangoLayout *layout;
	gint y1, y2;
	gint y, height;
	gchar str [16];
	gint margin_width;
	gint margin_length;
	gint text_width;
	DmaSparseIter buf_iter;
	GtkTextIter text_iter;
	guint prev_address = G_MAXUINT;

	
	text_view = GTK_TEXT_VIEW (view);

	if (!view->priv->show_line_numbers && !view->priv->show_line_markers)
	{
		gtk_text_view_set_border_window_size (text_view,
						      GTK_TEXT_WINDOW_LEFT,
						      0);

		return;
	}
	
	win = gtk_text_view_get_window (text_view,
					GTK_TEXT_WINDOW_LEFT);	

	y1 = event->area.y;
	y2 = y1 + event->area.height;

	/* get the extents of the line printing */
	gtk_text_view_window_to_buffer_coords (text_view,
					       GTK_TEXT_WINDOW_LEFT,
					       0,
					       y1,
					       NULL,
					       &y1);

	gtk_text_view_window_to_buffer_coords (text_view,
					       GTK_TEXT_WINDOW_LEFT,
					       0,
					       y2,
					       NULL,
					       &y2);

	/* set size. */
	g_snprintf (str, sizeof (str), "0x%X", G_MAXUINT);
	margin_length = strlen(str) - 2;
	layout = gtk_widget_create_pango_layout (GTK_WIDGET (view), str);

	pango_layout_get_pixel_size (layout, &text_width, NULL);
	
	pango_layout_set_width (layout, text_width);
	pango_layout_set_alignment (layout, PANGO_ALIGN_RIGHT);

	/* determine the width of the left margin. */
	if (view->priv->show_line_numbers)
		margin_width = text_width + 4;
	else
		margin_width = 0;
	
	if (view->priv->show_line_markers)
		margin_width += GUTTER_PIXMAP;

	g_return_if_fail (margin_width != 0);
	
	gtk_text_view_set_border_window_size (GTK_TEXT_VIEW (text_view),
					      GTK_TEXT_WINDOW_LEFT,
					      margin_width);

	/* Display all addresses */
	dma_sparse_iter_copy (&buf_iter, &view->priv->start);
	gtk_text_buffer_get_start_iter (gtk_text_view_get_buffer (text_view), &text_iter);
	

	
	/* Skip line while position doesn't need to be repaint */
	gtk_text_view_get_line_yrange (text_view, &text_iter, &y, &height);
	if (y < y1)
	{
		do
		{
			if (!dma_sparse_iter_forward_lines (&buf_iter, 1)) return;
			if (!gtk_text_iter_forward_line (&text_iter)) return;
			gtk_text_view_get_line_yrange (text_view, &text_iter, &y, &height);
		} while (y < y1);
	}
		

	/* Display address */
	do
	{
		gint pos;
		guint address;
		
		gtk_text_view_buffer_to_window_coords (text_view,
						       GTK_TEXT_WINDOW_LEFT,
						       0,
						       y,
						       NULL,
						       &pos);

		address = dma_sparse_iter_get_address (&buf_iter);
		
		if (view->priv->show_line_numbers) 
		{
			g_snprintf (str, sizeof (str),"0x%0*lX", margin_length, (long unsigned int)address);
			pango_layout_set_markup (layout, str, -1);

			gtk_paint_layout (gtk_widget_get_style (GTK_WIDGET (view)),
					  win,
					  gtk_widget_get_state (GTK_WIDGET (view)),
					  FALSE,
					  NULL,
					  GTK_WIDGET (view),
					  NULL,
					  text_width + 2, 
					  pos,
					  layout);
		}

		/* Display marker */
		if ((prev_address != address) && (view->priv->show_line_markers)) 
		{
			gint current_marker = dma_sparse_buffer_get_marks (view->priv->buffer, address);

			if (current_marker)
			{
				gint x;
				
				if (view->priv->show_line_numbers)
					x = text_width + 4;
				else
					x = 0;
				
				draw_line_markers (view, current_marker, x, pos);
				prev_address = address;
			}
		}
		
		if (!dma_sparse_iter_forward_lines (&buf_iter, 1)) return;
		if (!gtk_text_iter_forward_line (&text_iter)) return;
		gtk_text_view_get_line_yrange (text_view, &text_iter, &y, &height);
		
	} while (y < y2);
		
	g_object_unref (G_OBJECT (layout));	
}
示例#15
0
static gboolean
lines_match (const GtkTextIter *start,
	     const gchar      **lines,
	     gboolean           visible_only,
	     gboolean           slice,
	     GtkTextIter       *match_start,
	     GtkTextIter       *match_end)
{
	GtkTextIter next;
	gchar *line_text;
	const gchar *found;
	gint offset;

	if (*lines == NULL || **lines == '\0')
	{
		if (match_start)
			*match_start = *start;
		if (match_end)
			*match_end = *start;
		return TRUE;
	}

	next = *start;
	gtk_text_iter_forward_line (&next);

	/* No more text in buffer, but *lines is nonempty */
	if (gtk_text_iter_equal (start, &next))
		return FALSE;

	if (slice)
	{
		if (visible_only)
			line_text = gtk_text_iter_get_visible_slice (start, &next);
		else
			line_text = gtk_text_iter_get_slice (start, &next);
	}
	else
	{
		if (visible_only)
			line_text = gtk_text_iter_get_visible_text (start, &next);
		else
			line_text = gtk_text_iter_get_text (start, &next);
	}

	if (match_start) /* if this is the first line we're matching */
	{
		found = g_utf8_strcasestr (line_text, *lines);
	}
	else
	{
		/* If it's not the first line, we have to match from the
		 * start of the line.
		 */
		if (g_utf8_caselessnmatch (line_text, *lines, strlen (line_text),
					   strlen (*lines)))
			found = line_text;
		else
			found = NULL;
	}

	if (found == NULL)
	{
		g_free (line_text);
		return FALSE;
	}

	/* Get offset to start of search string */
	offset = g_utf8_strlen (line_text, found - line_text);

	next = *start;

	/* If match start needs to be returned, set it to the
	 * start of the search string.
	 */
	forward_chars_with_skipping (&next, offset, visible_only, !slice, FALSE);
	if (match_start)
	{
		*match_start = next;
	}

	/* Go to end of search string */
	forward_chars_with_skipping (&next, g_utf8_strlen (*lines, -1), visible_only, !slice, TRUE);

	g_free (line_text);

	++lines;

	if (match_end)
		*match_end = next;

	/* pass NULL for match_start, since we don't need to find the
	 * start again.
	 */
	return lines_match (&next, lines, visible_only, slice, NULL, match_end);
}
示例#16
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;
}
示例#17
0
/* Format->Renumber All Sections */
void
action_renumber_all_sections(GtkAction *action, I7Document *document)
{
	GtkTextIter pos, end;
	int volume = 1, book = 1, part = 1, chapter = 1, section = 1;
	GtkTextBuffer *buffer = GTK_TEXT_BUFFER(i7_document_get_buffer(document));

	gtk_text_buffer_get_start_iter(buffer, &pos);

	/* Renumbering sections counts as one action for Undo */
	gtk_text_buffer_begin_user_action(buffer);

	while(gtk_text_iter_get_char(&pos) != 0) {
		if(gtk_text_iter_get_char(&pos) != '\n') {
			gtk_text_iter_forward_line(&pos);
			continue;
		}
		gtk_text_iter_forward_line(&pos);
		end = pos;
		gboolean not_last = gtk_text_iter_forward_line(&end);
		if(!not_last || gtk_text_iter_get_char(&end) == '\n') {
			/* Preceded and followed by a blank line,
			or only preceded by one and current line is last line */
			/* Get the entire line and its line number, chop the \n */
			gchar *text = gtk_text_iter_get_text(&pos, &end);
			gchar *lcase = g_utf8_strdown(text, -1);
			gchar *title = strchr(text, '-');
			if(title && g_str_has_suffix(title, "\n"))
				*(strrchr(title, '\n')) = '\0'; /* remove trailing \n */
			gchar *newtitle;

			if(g_str_has_prefix(lcase, "volume")) {
				newtitle = g_strdup_printf("Volume %d %s\n", volume++, title);
				gtk_text_buffer_delete(buffer, &pos, &end);
				gtk_text_buffer_insert(buffer, &pos, newtitle, -1);
				g_free(newtitle);
				book = part = chapter = section = 1;
			} else if(g_str_has_prefix(lcase, "book")) {
				newtitle = g_strdup_printf("Book %d %s\n", book++, title);
				gtk_text_buffer_delete(buffer, &pos, &end);
				gtk_text_buffer_insert(buffer, &pos, newtitle, -1);
				g_free(newtitle);
				part = chapter = section = 1;
			} else if(g_str_has_prefix(lcase, "part")) {
				newtitle = g_strdup_printf("Part %d %s\n", part++, title);
				gtk_text_buffer_delete(buffer, &pos, &end);
				gtk_text_buffer_insert(buffer, &pos, newtitle, -1);
				g_free(newtitle);
				chapter = section = 1;
			} else if(g_str_has_prefix(lcase, "chapter")) {
				newtitle = g_strdup_printf("Chapter %d %s\n", chapter++, title);
				gtk_text_buffer_delete(buffer, &pos, &end);
				gtk_text_buffer_insert(buffer, &pos, newtitle, -1);
				g_free(newtitle);
				section = 1;
			} else if(g_str_has_prefix(lcase, "section")) {
				newtitle = g_strdup_printf("Section %d %s\n", section++, title);
				gtk_text_buffer_delete(buffer, &pos, &end);
				gtk_text_buffer_insert(buffer, &pos, newtitle, -1);
				g_free(newtitle);
			}
			g_free(text);
			g_free(lcase);
		}
	}

	gtk_text_buffer_end_user_action(buffer);
}
示例#18
0
/* Internal function: flush a window's text buffer to the screen. */
void
flush_window_buffer(winid_t win)
{
#ifdef DEBUG_STYLES
	g_printf("%s\n", win->buffer->str);
#endif
	if(win->type != wintype_TextBuffer && win->type != wintype_TextGrid)
		return;

	if(win->buffer->len == 0)
		return;

	gdk_threads_enter();

	GtkTextBuffer *buffer = gtk_text_view_get_buffer( GTK_TEXT_VIEW(win->widget) );

	switch(win->type) {
	case wintype_TextBuffer:
	{
		GtkTextIter start, end;
		gtk_text_buffer_get_end_iter(buffer, &end);
		gint start_offset;

		start_offset = gtk_text_iter_get_offset(&end);
		gtk_text_buffer_insert(buffer, &end, win->buffer->str, -1);
		gtk_text_buffer_get_iter_at_offset(buffer, &start, start_offset);
		style_apply(win, &start, &end);

		ChimaraGlk *glk = CHIMARA_GLK(gtk_widget_get_ancestor(win->widget, CHIMARA_TYPE_GLK));
		g_assert(glk);
		g_signal_emit_by_name(glk, "text-buffer-output", win->rock, win->librock, win->buffer->str);
	}
		break;

	case wintype_TextGrid:
	{
		/* Number of characters to insert */
		glong length = win->buffer->len;
		glong chars_left = length;
		
		GtkTextMark *cursor = gtk_text_buffer_get_mark(buffer, "cursor_position");
		
		/* Get cursor position */
		GtkTextIter start, insert;
		gint start_offset;

		gtk_text_buffer_get_iter_at_mark(buffer, &insert, cursor);

		while(chars_left > 0 && !gtk_text_iter_is_end(&insert))
		{
			/* Spaces available on this line */
			gint available_space = win->width - gtk_text_iter_get_line_offset(&insert);
		
			GtkTextIter end = insert;
			if(chars_left <= available_space)
				gtk_text_iter_forward_chars(&end, chars_left);
			else
				gtk_text_iter_forward_to_line_end(&end);

			gtk_text_buffer_delete(buffer, &insert, &end);

			start_offset = gtk_text_iter_get_offset(&insert);
			gtk_text_buffer_insert(buffer, &insert, win->buffer->str + (length - chars_left), MIN(chars_left, available_space));
			gtk_text_buffer_get_iter_at_offset(buffer, &start, start_offset);
			style_apply(win, &start, &insert);
			
			chars_left -= available_space;

			if(gtk_text_iter_get_line_offset(&insert) >= win->width)
				gtk_text_iter_forward_line(&insert);
		}

		gtk_text_buffer_move_mark(buffer, cursor, &insert);
	}
		break;
	}

	gdk_threads_leave();

	g_string_truncate(win->buffer, 0);
}
示例#19
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;
        }
示例#20
0
/**
@brief scan forwards from @a start for text which matches @a lines
This performs line-by-line case-insensitive comparisons
It may be re-entrant, when @a lines has > 1 member
@param start pointer to textiter in buffer where the search is to commence
@param lines array of \n-trailing line-strings, together comprising the search string
@param visible_only TRUE to ignore hidden chars in the text
@param slice TRUE to include "unknown" (0xFFFC) chars in the text
@param match_start textiter to store the start of a matching string, or NULL when re-entering to process line(s) after 1st
@param match_end textiter store the start of a matching string, or NULL

@return TRUE if a match was found
*/
static gboolean _e2_textiter_forward_lines_match (
		const GtkTextIter *start,
		const gchar      **lines,
		gboolean           visible_only,
		gboolean           slice,
		GtkTextIter       *match_start,
		GtkTextIter       *match_end)
{
	GtkTextIter next;
	gchar *line_text;
	const gchar *found;
	gint offset;

	if (*lines == NULL || **lines == '\0')
	{	//nothing to match, so everything matches
		if (match_start)
			*match_start = *start;
		if (match_end)
			*match_end = *start;
		return TRUE;
	}

	//CHECKME why break search into lines ?
	next = *start;
	if (!gtk_text_iter_forward_line (&next))
	{
		if (gtk_text_iter_is_end (start))
			return FALSE;
		else
		{
			next = *start;
			gtk_text_iter_forward_to_end (&next);	//CHECKME
		}
	}
	else if (gtk_text_iter_equal (start, &next)) //no more text in buffer
		return FALSE;

	if (slice)
	{
		if (visible_only)
			line_text = gtk_text_iter_get_visible_slice (start, &next);
		else
			line_text = gtk_text_iter_get_slice (start, &next);
	}
	else
	{
		if (visible_only)
			line_text = gtk_text_iter_get_visible_text (start, &next);
		else
			line_text = gtk_text_iter_get_text (start, &next);
	}

	if (match_start != NULL) //if this is the first line we're matching
	{
		found = e2_utf8_strcasestr (line_text, *lines);
	}
	else
	{
		//not the first line, we have to match from the start of the line
		if (e2_utf8_caseless_match (line_text, *lines, -1, -1))
			found = line_text;
		else
			found = NULL;
	}

	if (found == NULL)
	{
		g_free (line_text);
		return FALSE;
	}

	//get offset to start of search string
	offset = g_utf8_strlen (line_text, found - line_text);

	next = *start;

	/* If match start needs to be returned, set it to the
	   start of the search string */
	_e2_textiter_forward_chars_with_skipping (&next, offset, visible_only,
		!slice, FALSE);
	if (match_start != NULL)
	{
		*match_start = next;
	}

	//go to end of search string
	_e2_textiter_forward_chars_with_skipping (&next, g_utf8_strlen (*lines, -1),
		visible_only, !slice, TRUE);

	g_free (line_text);

	++lines;

	if (match_end != NULL)
		*match_end = next;

	/* try to match the rest of the lines forward, passing NULL for
	   match_start so lines_match will try to match the entire line */
	return _e2_textiter_forward_lines_match (&next, lines, visible_only, slice,
		NULL, match_end);
}
示例#21
0
void
modeline_parser_apply_modeline (GtkSourceView *view)
{
	ModelineOptions options;
	GtkTextBuffer *buffer;
	GtkTextIter iter, liter;
	gint line_count;
	
	options.language_id = NULL;
	options.set = MODELINE_SET_NONE;

	buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
	gtk_text_buffer_get_start_iter (buffer, &iter);

	line_count = gtk_text_buffer_get_line_count (buffer);

	/* Parse the modelines on the 10 first lines... */
	while ((gtk_text_iter_get_line (&iter) < 10) &&
	       !gtk_text_iter_is_end (&iter))
	{
		gchar *line;

		liter = iter;
		gtk_text_iter_forward_to_line_end (&iter);
		line = gtk_text_buffer_get_text (buffer, &liter, &iter, TRUE);

		parse_modeline (line,
				1 + gtk_text_iter_get_line (&iter),
				line_count,
				&options);

		gtk_text_iter_forward_line (&iter);

		g_free (line);
	}

	/* ...and on the 10 last ones (modelines are not allowed in between) */
	if (!gtk_text_iter_is_end (&iter))
	{
		gint cur_line;
		guint remaining_lines;

		/* we are on the 11th line (count from 0) */
		cur_line = gtk_text_iter_get_line (&iter);
		/* g_assert (10 == cur_line); */

		remaining_lines = line_count - cur_line - 1;

		if (remaining_lines > 10)
		{
			gtk_text_buffer_get_end_iter (buffer, &iter);
			gtk_text_iter_backward_lines (&iter, 9);
		}
	}

	while (!gtk_text_iter_is_end (&iter))
	{
		gchar *line;

		liter = iter;
		gtk_text_iter_forward_to_line_end (&iter);
		line = gtk_text_buffer_get_text (buffer, &liter, &iter, TRUE);

		parse_modeline (line,
				1 + gtk_text_iter_get_line (&iter),
				line_count,
				&options);

		gtk_text_iter_forward_line (&iter);

		g_free (line);
	}

	/* Try to set language */
	if (has_option (&options, MODELINE_SET_LANGUAGE) && options.language_id)
	{
		GtkSourceLanguageManager *manager;
		GtkSourceLanguage *language;

		manager = pluma_get_language_manager ();
		language = gtk_source_language_manager_get_language
				(manager, options.language_id);

		if (language != NULL)
		{
			gtk_source_buffer_set_language (GTK_SOURCE_BUFFER (buffer),
							language);
		}
	}

	ModelineOptions *previous = g_object_get_data (G_OBJECT (buffer), 
	                                               MODELINE_OPTIONS_DATA_KEY);

	/* Apply the options we got from modelines and restore defaults if
	   we set them before */
	if (has_option (&options, MODELINE_SET_INSERT_SPACES))
	{
		gtk_source_view_set_insert_spaces_instead_of_tabs
							(view, options.insert_spaces);
	}
	else if (check_previous (view, previous, MODELINE_SET_INSERT_SPACES))
	{
		gtk_source_view_set_insert_spaces_instead_of_tabs
							(view,
							 pluma_prefs_manager_get_insert_spaces ());
	}
	
	if (has_option (&options, MODELINE_SET_TAB_WIDTH))
	{
		gtk_source_view_set_tab_width (view, options.tab_width);
	}
	else if (check_previous (view, previous, MODELINE_SET_TAB_WIDTH))
	{
		gtk_source_view_set_tab_width (view, 
		                               pluma_prefs_manager_get_tabs_size ());
	}
	
	if (has_option (&options, MODELINE_SET_INDENT_WIDTH))
	{
		gtk_source_view_set_indent_width (view, options.indent_width);
	}
	else if (check_previous (view, previous, MODELINE_SET_INDENT_WIDTH))
	{
		gtk_source_view_set_indent_width (view, -1);
	}
	
	if (has_option (&options, MODELINE_SET_WRAP_MODE))
	{
		gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (view), options.wrap_mode);
	}
	else if (check_previous (view, previous, MODELINE_SET_WRAP_MODE))
	{
		gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (view), 
		                             pluma_prefs_manager_get_wrap_mode ());
	}
	
	if (has_option (&options, MODELINE_SET_RIGHT_MARGIN_POSITION))
	{
		gtk_source_view_set_right_margin_position (view, options.right_margin_position);
	}
	else if (check_previous (view, previous, MODELINE_SET_RIGHT_MARGIN_POSITION))
	{
		gtk_source_view_set_right_margin_position (view, 
		                                           pluma_prefs_manager_get_right_margin_position ());
	}
	
	if (has_option (&options, MODELINE_SET_SHOW_RIGHT_MARGIN))
	{
		gtk_source_view_set_show_right_margin (view, options.display_right_margin);
	}
	else if (check_previous (view, previous, MODELINE_SET_SHOW_RIGHT_MARGIN))
	{
		gtk_source_view_set_show_right_margin (view, 
		                                       pluma_prefs_manager_get_display_right_margin ());
	}
	
	if (previous)
	{
		*previous = options;
		previous->language_id = g_strdup (options.language_id);
	}
	else
	{
		previous = g_slice_new (ModelineOptions);
		*previous = options;
		previous->language_id = g_strdup (options.language_id);
		
		g_object_set_data_full (G_OBJECT (buffer), 
		                        MODELINE_OPTIONS_DATA_KEY, 
		                        previous,
		                        (GDestroyNotify)free_modeline_options);
	}
	
	g_free (options.language_id);
}
示例#22
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;
}
示例#23
0
/**
@brief Search forward from @a iter to try to to find next match of @a str in textbuffer

This is like gtk_text_iter_forward_search(), but supports case-insensitive
and whole-word searching.

Any match is returned by setting @a match_start to the first character of
the match and @a match_end to the first character after the match. The search
will not continue past @a limit.
Note that a search is a linear or O(n) operation, so you may wish to use
@a limit to avoid locking up your UI on large buffers.

If the GTK_SOURCE_SEARCH_VISIBLE_ONLY flag is present, the match may have
invisible text interspersed in @a str. i.e. @a str will be a
possibly-noncontiguous subset of the matched range. Similarly, if you
specify GTK_SOURCE_SEARCH_TEXT_ONLY, the match may have pixbufs or child
widgets inside the matched range. If these flags are not given, the match
must be exact; the special 0xFFFC character in @a str will match embedded
pixbufs or child widgets. If you specify the GTK_SOURCE_SEARCH_CASE_INSENSITIVE
flag, the text will be matched regardless of its case.

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

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

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

	if (!(flags & E2_SEARCH_CASE_INSENSITIVE))
	{
		search = *iter;
rescan:
		retval = gtk_text_iter_forward_search (&search, str, flags,
					match_start, match_end, limit);
		if (retval && (flags & E2_SEARCH_WHOLE_WORD)
					&& (!gtk_text_iter_starts_word (match_start)
		//to allow incremental searching, whole_words option causes only a check
		//for word start here, the end-check is done when highlighting
						//|| !gtk_text_iter_ends_word (match_end)
		))
		{
			search = *match_start;
			if (gtk_text_iter_forward_char (&search))
				goto rescan;
			retval = FALSE;
		}
		return retval;
	}

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

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

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

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

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

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

	g_strfreev (lines);

	return retval;
}
示例#24
0
void
modeline_parser_apply_modeline (GtkSourceView *view)
{
	ModelineOptions options;
	GtkTextBuffer *buffer;
	GtkTextIter iter, liter;
	gint line_count;
	GSettings *settings;

	options.language_id = NULL;
	options.set = MODELINE_SET_NONE;

	buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
	gtk_text_buffer_get_start_iter (buffer, &iter);

	line_count = gtk_text_buffer_get_line_count (buffer);

	/* Parse the modelines on the 10 first lines... */
	while ((gtk_text_iter_get_line (&iter) < 10) &&
	       !gtk_text_iter_is_end (&iter))
	{
		gchar *line;

		liter = iter;
		gtk_text_iter_forward_to_line_end (&iter);
		line = gtk_text_buffer_get_text (buffer, &liter, &iter, TRUE);

		parse_modeline (line,
				1 + gtk_text_iter_get_line (&iter),
				line_count,
				&options);

		gtk_text_iter_forward_line (&iter);

		g_free (line);
	}

	/* ...and on the 10 last ones (modelines are not allowed in between) */
	if (!gtk_text_iter_is_end (&iter))
	{
		gint cur_line;
		guint remaining_lines;

		/* we are on the 11th line (count from 0) */
		cur_line = gtk_text_iter_get_line (&iter);
		/* g_assert (10 == cur_line); */

		remaining_lines = line_count - cur_line - 1;

		if (remaining_lines > 10)
		{
			gtk_text_buffer_get_end_iter (buffer, &iter);
			gtk_text_iter_backward_lines (&iter, 9);
		}
	}

	while (!gtk_text_iter_is_end (&iter))
	{
		gchar *line;

		liter = iter;
		gtk_text_iter_forward_to_line_end (&iter);
		line = gtk_text_buffer_get_text (buffer, &liter, &iter, TRUE);

		parse_modeline (line,
				1 + gtk_text_iter_get_line (&iter),
				line_count,
				&options);

		gtk_text_iter_forward_line (&iter);

		g_free (line);
	}

	/* Try to set language */
	if (has_option (&options, MODELINE_SET_LANGUAGE) && options.language_id)
	{
		if (g_ascii_strcasecmp (options.language_id, "text") == 0)
		{
			gedit_document_set_language (GEDIT_DOCUMENT (buffer),
			                             NULL);
		}
		else
		{
		        GtkSourceLanguageManager *manager;
		        GtkSourceLanguage *language;

		        manager = gedit_get_language_manager ();

			language = gtk_source_language_manager_get_language
					(manager, options.language_id);
			if (language != NULL)
			{
				gedit_document_set_language (GEDIT_DOCUMENT (buffer),
				                             language);
			}
			else
			{
				gedit_debug_message (DEBUG_PLUGINS,
						     "Unknown language `%s'",
						     options.language_id);
			}
		}
	}

	ModelineOptions *previous = g_object_get_data (G_OBJECT (buffer), 
	                                               MODELINE_OPTIONS_DATA_KEY);

	settings = g_settings_new ("org.gnome.gedit.preferences.editor");

	/* Apply the options we got from modelines and restore defaults if
	   we set them before */
	if (has_option (&options, MODELINE_SET_INSERT_SPACES))
	{
		gtk_source_view_set_insert_spaces_instead_of_tabs
							(view, options.insert_spaces);
	}
	else if (check_previous (view, previous, MODELINE_SET_INSERT_SPACES))
	{
		gboolean insert_spaces;
		
		insert_spaces = g_settings_get_boolean (settings, GEDIT_SETTINGS_INSERT_SPACES);
	
		gtk_source_view_set_insert_spaces_instead_of_tabs (view, insert_spaces);
	}
	
	if (has_option (&options, MODELINE_SET_TAB_WIDTH))
	{
		gtk_source_view_set_tab_width (view, options.tab_width);
	}
	else if (check_previous (view, previous, MODELINE_SET_TAB_WIDTH))
	{
		guint tab_width;
		
		g_settings_get (settings, GEDIT_SETTINGS_TABS_SIZE, "u", &tab_width);
	
		gtk_source_view_set_tab_width (view, tab_width);
	}
	
	if (has_option (&options, MODELINE_SET_INDENT_WIDTH))
	{
		gtk_source_view_set_indent_width (view, options.indent_width);
	}
	else if (check_previous (view, previous, MODELINE_SET_INDENT_WIDTH))
	{
		gtk_source_view_set_indent_width (view, -1);
	}
	
	if (has_option (&options, MODELINE_SET_WRAP_MODE))
	{
		gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (view), options.wrap_mode);
	}
	else if (check_previous (view, previous, MODELINE_SET_WRAP_MODE))
	{
		GtkWrapMode mode;
		
		mode = g_settings_get_enum (settings,
					    GEDIT_SETTINGS_WRAP_MODE);
		gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (view), mode);
	}
	
	if (has_option (&options, MODELINE_SET_RIGHT_MARGIN_POSITION))
	{
		gtk_source_view_set_right_margin_position (view, options.right_margin_position);
	}
	else if (check_previous (view, previous, MODELINE_SET_RIGHT_MARGIN_POSITION))
	{
		guint right_margin_pos;
		
		g_settings_get (settings, GEDIT_SETTINGS_RIGHT_MARGIN_POSITION, "u",
				&right_margin_pos);
		gtk_source_view_set_right_margin_position (view, 
		                                           right_margin_pos);
	}
	
	if (has_option (&options, MODELINE_SET_SHOW_RIGHT_MARGIN))
	{
		gtk_source_view_set_show_right_margin (view, options.display_right_margin);
	}
	else if (check_previous (view, previous, MODELINE_SET_SHOW_RIGHT_MARGIN))
	{
		gboolean display_right_margin;
		
		display_right_margin = g_settings_get_boolean (settings,
							       GEDIT_SETTINGS_DISPLAY_RIGHT_MARGIN);
		gtk_source_view_set_show_right_margin (view, display_right_margin);
	}
	
	if (previous)
	{
		g_free (previous->language_id);
		*previous = options;
		previous->language_id = g_strdup (options.language_id);
	}
	else
	{
		previous = g_slice_new (ModelineOptions);
		*previous = options;
		previous->language_id = g_strdup (options.language_id);
		
		g_object_set_data_full (G_OBJECT (buffer), 
		                        MODELINE_OPTIONS_DATA_KEY, 
		                        previous,
		                        (GDestroyNotify)free_modeline_options);
	}

	g_object_unref (settings);
	g_free (options.language_id);
}
示例#25
0
type_noeud_comment *validate_comments(type_noeud_comment *anchor_comment, GtkWidget * entry)
{
  GtkTextIter start, end, iter;
  GtkTextBuffer *buffer;
  char *text;
  gboolean is_not_the_end;
  type_noeud_comment *pt_comment;
  int longueur;
  type_noeud_comment *pt_prec = NULL, *pt_fin = NULL;

  pt_comment = anchor_comment;

  buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(entry));

  gtk_text_buffer_get_line_count(buffer);

  gtk_text_buffer_get_bounds(buffer, &start, &end);

  iter = start;
  do
  {
     is_not_the_end = gtk_text_iter_forward_line(&iter);
     text = gtk_text_iter_get_text(&start, &iter);
     start = iter;

     if (pt_comment == NULL)
     {
	pt_comment = ALLOCATION(type_noeud_comment);
	pt_comment->suiv = NULL;
	if (anchor_comment == NULL)
	{
	   anchor_comment = pt_comment;
	}
	else
	{
	   pt_prec->suiv = pt_comment;
	}
     }

     longueur = strlen(text) + 1;
     if (longueur > TAILLE_CHAINE) 
     {
	printf("WARNING: la chaine de char: %s a ete tronquee dans validate_comments car sa taille est superieure a %d\n", text, TAILLE_CHAINE);
	longueur = TAILLE_CHAINE;
     }

     /* recopie dans le champs comment en rajoutant un % au debut s'il a ete oublie */
     /* on ne fait rien pour les lignes vides */
     if (test_comment(text) == 1 || empty_line(text) == 1)
     {
	memcpy(pt_comment->chaine, text, longueur * sizeof(char)); 
     }
     else
     {
	pt_comment->chaine[0] = '%';
	memcpy(&(pt_comment->chaine[1]), text, longueur * sizeof(char)); 
     }
     pt_prec = pt_comment;
     pt_comment = pt_comment->suiv;
 
     g_free (text);
  }
  while (is_not_the_end == TRUE);
  if (strlen(pt_prec->chaine) > 0 && pt_prec->chaine[strlen(pt_prec->chaine)-1] != '\n')
  {
     strcat(pt_prec->chaine, "\n");
  }

  /* Suppression des donnees du buffer */
  gtk_text_buffer_get_start_iter(buffer, &start);
  gtk_text_buffer_get_end_iter(buffer, &end);
  gtk_text_buffer_delete(buffer, &start, &end);
  
  /* Suppression du reste de la liste chainee des commentaire ==> utile si on a supprime des commentaires*/
  pt_fin = pt_prec;
  while (pt_comment != NULL)
  {
     pt_prec = pt_comment;
     pt_comment = pt_comment->suiv;
     free(pt_prec);    
  }
  pt_fin->suiv = NULL;
  return anchor_comment;
}
示例#26
0
/* This function is taken and adapted from gtk+/tests/testtext.c */
static LinesInfo *
get_lines_info (GtkTextView *text_view,
		gint         first_y_buffer_coord,
		gint         last_y_buffer_coord)
{
	LinesInfo *info;
	GtkTextIter iter;
	gint last_line_num = -1;

	info = lines_info_new ();

	/* Get iter at first y */
	gtk_text_view_get_line_at_y (text_view, &iter, first_y_buffer_coord, NULL);

	info->start = iter;

	/* For each iter, get its location and add it to the arrays.
	 * Stop when we pass last_y_buffer_coord.
	 */
	while (!gtk_text_iter_is_end (&iter))
	{
		gint y;
		gint height;
		gint line_num;

		gtk_text_view_get_line_yrange (text_view, &iter, &y, &height);

		g_array_append_val (info->buffer_coords, y);
		g_array_append_val (info->line_heights, height);

		info->total_height += height;

		line_num = gtk_text_iter_get_line (&iter);
		g_array_append_val (info->line_numbers, line_num);

		last_line_num = line_num;

		info->lines_count++;

		if (last_y_buffer_coord <= (y + height))
		{
			break;
		}

		gtk_text_iter_forward_line (&iter);
	}

	if (gtk_text_iter_is_end (&iter))
	{
		gint y;
		gint height;
		gint line_num;

		gtk_text_view_get_line_yrange (text_view, &iter, &y, &height);

		line_num = gtk_text_iter_get_line (&iter);

		if (line_num != last_line_num)
		{
			g_array_append_val (info->buffer_coords, y);
			g_array_append_val (info->line_heights, height);

			info->total_height += height;

			g_array_append_val (info->line_numbers, line_num);
			info->lines_count++;
		}
	}

	if (info->lines_count == 0)
	{
		gint y = 0;
		gint n = 0;
		gint height;

		info->lines_count = 1;

		g_array_append_val (info->buffer_coords, y);
		g_array_append_val (info->line_numbers, n);

		gtk_text_view_get_line_yrange (text_view, &iter, &y, &height);
		g_array_append_val (info->line_heights, height);

		info->total_height += height;
	}

	info->end = iter;

	return info;
}
示例#27
0
static gboolean
smie_gtk_source_buffer_forward_line (gpointer data)
{
  smie_gtk_source_buffer_context_t *context = data;
  return gtk_text_iter_forward_line (&context->iter);
}
示例#28
0
/*
 * Apply styles to the string based on the tags
 */
gboolean apply_tag(GtkTextView *text_view, tag in_tag, int ignore)
{
	/*
	 * TODO: Create GTK_TAGs for the following tags:
	 * 2) body: All done except for the width=100% portion
	 */

	GtkTextTag *style;
	GtkTextBuffer *buffer = gtk_text_view_get_buffer(text_view);

	/* HEAD */
	if (!g_ascii_strncasecmp(in_tag.name, "head", 4)) {

		GtkTextIter start, end;
		gtk_text_buffer_get_iter_at_mark(buffer, &start,
			&(in_tag.start));
		gtk_text_buffer_get_iter_at_mark(buffer, &end, &(in_tag.end));

		gtk_text_buffer_delete(buffer, &start, &end);

		return TRUE;
	}

	/* HORIZONTAL LINE */
	if (!g_ascii_strncasecmp(in_tag.name, "hr", 4)) {
		GtkTextIter start;
		GtkWidget *line;
		GtkTextChildAnchor *anchor;
		GtkRequisition r;

		gtk_text_buffer_get_iter_at_mark(buffer, &start,
			&(in_tag.start));
		gtk_text_buffer_insert(buffer, &start, "\n", -1);

		/* Reinitialized since the insert invalidates the iter */
		gtk_text_buffer_get_iter_at_mark(buffer, &start,
			&(in_tag.start));
		gtk_text_iter_forward_line(&start);

		line = gtk_hseparator_new();

		anchor = gtk_text_buffer_create_child_anchor(buffer, &start);
		gtk_text_view_add_child_at_anchor(text_view, line, anchor);

		/* FIXME: Need a way to stretch the HR on resize */
		gtk_widget_size_request(GTK_WIDGET(text_view), &r);
		gtk_widget_set_size_request(line, r.width, 2);

		gtk_widget_show(line);

		return TRUE;
	}

	/* BR */
	if (!g_ascii_strncasecmp(in_tag.name, "br", 2)) {

		GtkTextIter start;
		gtk_text_buffer_get_iter_at_mark(buffer, &start,
			&(in_tag.start));
		gtk_text_buffer_insert(buffer, &start, "\n", -1);

		return TRUE;
	}

	/* BODY */
	if (!g_ascii_strncasecmp(in_tag.name, "body", 4)) {
		char *param = NULL;
		char attr_val[255];
		GtkTextIter start, end;

		bzero(attr_val, 255);

		gtk_text_buffer_get_iter_at_mark(buffer, &start,
			&(in_tag.start));
		gtk_text_buffer_get_iter_at_mark(buffer, &end, &(in_tag.end));

		if ((param = ay_strcasestr(in_tag.name, "bgcolor=")) != NULL) {
			param += 8;	/* length of bgcolor= */
			_extract_parameter(param, attr_val, 255);
			style = gtk_text_buffer_create_tag(buffer, in_tag.id,
				"background", attr_val, NULL);

			gtk_text_buffer_apply_tag(buffer, style, &start, &end);
		}

		return TRUE;
	}

	/* BOLD */
	if (!g_ascii_strcasecmp(in_tag.name, "b")) {
		GtkTextIter start, end;

		gtk_text_buffer_get_iter_at_mark(buffer, &start,
			&(in_tag.start));
		gtk_text_buffer_get_iter_at_mark(buffer, &end, &(in_tag.end));

		style = gtk_text_buffer_create_tag(buffer, in_tag.id,
			"weight", PANGO_WEIGHT_BOLD, NULL);
		gtk_text_buffer_apply_tag(buffer, style, &start, &end);
		return TRUE;
	}

	/* UNDERLINE */
	if (!g_ascii_strcasecmp(in_tag.name, "u")) {
		GtkTextIter start, end;

		gtk_text_buffer_get_iter_at_mark(buffer, &start,
			&(in_tag.start));
		gtk_text_buffer_get_iter_at_mark(buffer, &end, &(in_tag.end));

		style = gtk_text_buffer_create_tag(buffer, in_tag.id,
			"underline", PANGO_UNDERLINE_SINGLE, NULL);
		gtk_text_buffer_apply_tag(buffer, style, &start, &end);
		return TRUE;
	}

	/* ITALICS */
	if (!g_ascii_strcasecmp(in_tag.name, "i")) {
		GtkTextIter start, end;

		gtk_text_buffer_get_iter_at_mark(buffer, &start,
			&(in_tag.start));
		gtk_text_buffer_get_iter_at_mark(buffer, &end, &(in_tag.end));

		style = gtk_text_buffer_create_tag(buffer, in_tag.id,
			"style", PANGO_STYLE_ITALIC, NULL);
		gtk_text_buffer_apply_tag(buffer, style, &start, &end);
		return TRUE;
	}

	/* FONT */
	if (!g_ascii_strncasecmp(in_tag.name, "font", 4)) {
		GtkTextIter start, end;
		char *param = NULL;
		char attr_val[255];

		bzero(attr_val, 255);

		gtk_text_buffer_get_iter_at_mark(buffer, &start,
			&(in_tag.start));
		gtk_text_buffer_get_iter_at_mark(buffer, &end, &(in_tag.end));

		style = gtk_text_buffer_create_tag(buffer, in_tag.id, NULL);

		/* Font Face */
		if (!(ignore & HTML_IGNORE_FONT) &&
			(param = ay_strcasestr(in_tag.name, "face=")) != NULL) {
			param += 5;	/* length of face= */
			_extract_parameter(param, attr_val, 255);

			g_object_set(style, "family", attr_val, NULL);
		}

		/* Font color */
		if (!(ignore & HTML_IGNORE_FOREGROUND) &&
			(param = ay_strcasestr(in_tag.name, "color=")) != NULL)
		{
			param += 6;	/* length of color= */
			_extract_parameter(param, attr_val, 255);

			g_object_set(style, "foreground", attr_val, NULL);
		}

		/* Font Size */
		if ((param = ay_strcasestr(in_tag.name, "ptsize=")) != NULL) {
			param += 7;	/*length of ptsize= */
			_extract_parameter(param, attr_val, 255);

			g_object_set(style, "size-points", strtod(attr_val,
					NULL), NULL);
		} else if ((param =
				ay_strcasestr(in_tag.name, "absz=")) != NULL) {
			param += 5;	/*length of absz= */
			_extract_parameter(param, attr_val, 255);

			g_object_set(style, "size-points", strtod(attr_val,
					NULL), NULL);
		} else if ((param =
				ay_strcasestr(in_tag.name, "size=")) != NULL) {
			/* Get the current font size */
			gint cur_size = 0;
			PangoContext *context =
				gtk_widget_get_pango_context(GTK_WIDGET
				(text_view));
			PangoFontDescription *desc =
				pango_context_get_font_description(context);

			param += 5;	/*length of size= */

			cur_size =
				pango_font_description_get_size(desc) /
				PANGO_SCALE;

			_extract_parameter(param, attr_val, 255);

			if (attr_val == NULL) {
				/* Do nothing */
			} else if (*attr_val == '+') {
				int font_size = atoi(attr_val + 1) * 4;
				g_object_set(style, "size-points",
					(double)cur_size + font_size, NULL);
			} else if (*attr_val == '-') {
				int font_size = atoi(attr_val + 1) * 4;
				g_object_set(style, "size-points",
					(double)cur_size - font_size, NULL);
			} else {
				int font_size = atoi(attr_val) * 4;
				g_object_set(style, "size-points",
					(double)font_size, NULL);
			}

		}

		gtk_text_buffer_apply_tag(buffer, style, &start, &end);

		return TRUE;
	}

	/* ANCHOR */
	if (!g_ascii_strncasecmp(in_tag.name, "a ", 2)) {
		GtkTextIter start, end;
		char *param = NULL;
		gchar *attr_val = (gchar *)malloc(1024);

		bzero(attr_val, 1024);

		gtk_text_buffer_get_iter_at_mark(buffer, &start,
			&(in_tag.start));
		gtk_text_buffer_get_iter_at_mark(buffer, &end, &(in_tag.end));

		/* Font Face */
		if ((param = ay_strcasestr(in_tag.name, "href=")) != NULL) {
			param += 5;	/*length of href= */
			_extract_parameter(param, attr_val, 1024);

			style = gtk_text_buffer_create_tag(buffer, in_tag.id,
				"underline", PANGO_UNDERLINE_SINGLE,
				"foreground", "blue", NULL);
			g_object_set_data(G_OBJECT(style), "href", attr_val);

			gtk_text_buffer_apply_tag(buffer, style, &start, &end);
		}
		return TRUE;
	}

	/* SMILEY */
	if (!g_ascii_strncasecmp(in_tag.name, "smiley", 6)) {
		GtkTextIter start;

		char *param = NULL;
		char smiley_name[64];
		char smiley_protocol[64];
		smiley *smile = NULL;
		bzero(smiley_name, 64);
		bzero(smiley_protocol, 64);

		gtk_text_buffer_get_iter_at_mark(buffer, &start,
			&(in_tag.start));

		if ((param = ay_strcasestr(in_tag.name, "name=")) != NULL) {

			param += 5;	/*length of name= */
			_extract_parameter(param, smiley_name, 64);

			if ((param = ay_strcasestr(in_tag.name,
						"protocol=")) != NULL) {
				param += 9;	/*length of protocol= */
				_extract_parameter(param, smiley_protocol, 64);
				smile = get_smiley_by_name_and_service
					(smiley_name, smiley_protocol);
			} else {
				smile = get_smiley_by_name(smiley_name);
			}

			if (smile) {
				insert_xpm_at_iter(text_view, &start,
					smile->pixmap);
			} else if ((param =
					ay_strcasestr(in_tag.name,
						"alt=")) != NULL) {
				param += 4;	/*length of alt= */
				_extract_parameter(param, smiley_name, 64);
				gtk_text_buffer_insert(buffer, &start,
					smiley_name, -1);
			} else {
				insert_xpm_at_iter(text_view, &start,
					no_such_smiley_xpm);
			}
		}

		return TRUE;
	}

	/* IMAGE */
	if (!g_ascii_strncasecmp(in_tag.name, "img", 3)) {
		GtkTextIter start;
		char *param = NULL;
		char img_loc[1024];

		bzero(img_loc, 1024);

		gtk_text_buffer_get_iter_at_mark(buffer, &start,
			&(in_tag.start));

		if ((param = ay_strcasestr(in_tag.name, "src=")) != NULL) {

			param += 4;	/*length of src= */
			_extract_parameter(param, img_loc, 1024);

			if (!strcmp(img_loc, "aol_icon.gif"))
				insert_xpm_at_iter(text_view, &start,
					aol_icon_xpm);
			else if (!strcmp(img_loc, "free_icon.gif"))
				insert_xpm_at_iter(text_view, &start,
					free_icon_xpm);
			else if (!strcmp(img_loc, "dt_icon.gif"))
				insert_xpm_at_iter(text_view, &start,
					dt_icon_xpm);
			else if (!strcmp(img_loc, "admin_icon.gif"))
				insert_xpm_at_iter(text_view, &start,
					admin_icon_xpm);
		}

		return TRUE;
	}

	return FALSE;
}
示例#29
0
static void
get_lines (GtkTextView  *text_view,
           gint          y1,
           gint          y2,
           GArray       *buffer_coords,
           GArray       *numbers,
           gint         *countp)
{
	GtkTextIter iter;
	gint count;
	gint size;
		gint last_line_num;
	
	g_array_set_size (buffer_coords, 0);
	g_array_set_size (numbers, 0);
	
	/* Get iter at first y */
	gtk_text_view_get_line_at_y (text_view, &iter, y1, NULL);
	
	/* For each iter, get its location and add it to the arrays.
	 * Stop when we pass y2
	 */
	count = 0;
	size = 0;
	
	while (!gtk_text_iter_is_end (&iter))
	{
		gint y, height;
		
		gtk_text_view_get_line_yrange (text_view, &iter, &y, &height);
		
		g_array_append_val (buffer_coords, y);
		last_line_num = gtk_text_iter_get_line (&iter);
		g_array_append_val (numbers, last_line_num);
		
		++count;
		
		if ((y + height) >= y2)
		break;
		
		gtk_text_iter_forward_line (&iter);
	}
	
	if (gtk_text_iter_is_end (&iter))
	{
		gint y, height;
		gint line_num;
		
		gtk_text_view_get_line_yrange (text_view, &iter, &y, &height);
		
		line_num = gtk_text_iter_get_line (&iter);
		
		if (line_num != last_line_num) {
			g_array_append_val (buffer_coords, y);
			g_array_append_val (numbers, line_num);
			++count;
		}
	}
	
	*countp = count;
}
示例#30
0
static void
save_buffer(gchar *file, gchar *file_type, void *unused)
{
  GtkTextIter iter_start, iter_end;
  GSList *tags = NULL, *tagp = NULL;
  gchar *tag_name;
  FILE *filefd;
  int style_index = get_style_current_index();
  int color_index = get_color_style_current_index();

  filefd = g_fopen(file, "w+");

  /*
   * XHTML Header
   */
  fprintf(filefd,
	  "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
	  "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n"
	  "<html xmlns=\"http://www.w3.org/1999/xhtml\">\n"
	  "<head>\n"
	  "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />\n"
	  "<meta http-equiv=\"GCompris-doctype\" content=\"%s\" />\n"
	  "<meta http-equiv=\"GCompris-color-style\" content=\"%s\" />\n"
	  "<title>GCompris</title>\n",
	  doctype_list[style_index]->name,
	  color_style_list[color_index][0]);

  /*
   * HTML Style
   */
  fprintf(filefd,
	  "<style type=\"text/css\">\n");

  {
    int i;
    int font_size[NUMBER_OF_STYLE] = { 28, 22, 16, 14, 12 };
    char *align[NUMBER_OF_STYLE] = { "center", "left", "left", "justify" };
    int left_margin[NUMBER_OF_STYLE] = { 0, 10, 20, 30 };

    for(i=0; i<NUMBER_OF_STYLE; i++)
      {
	style_t style = doctype_list[style_index]->style[i];
	fprintf(filefd,
		"%s {\n"
		"  color : %s;\n"
		"  font-size : %dpx;\n"
		"  text-align : %s;\n"
		"  margin-left : %dpx;\n"
		"}\n",
		style.name,
		color_style_list[color_index][i+1],
		font_size[i],
		align[i],
		left_margin[i]);
      }

  }
  fprintf(filefd,
	  "</style>\n"
	  "</head>\n");

  /*
   * Header end
   */
  fprintf(filefd,
	  "<body>\n");

  gtk_text_buffer_get_iter_at_offset(buffer,
				     &iter_start,
				     0);

  do
    {
      iter_end = iter_start;
      gtk_text_iter_forward_to_line_end(&iter_end);

      if(gtk_text_iter_ends_line(&iter_start))
	continue;

      tags = gtk_text_iter_get_tags (&iter_start);
      if(g_slist_length(tags) == 0)
	{
	  gtk_text_iter_backward_char (&iter_end);
	  tags = gtk_text_iter_get_tags (&iter_end);
	  gtk_text_iter_forward_char (&iter_end);
	}

      tag_name = "p";
      for (tagp = tags;  tagp != NULL;  tagp = tagp->next)
	{
	  GtkTextTag *tag = tagp->data;
	  g_object_get (G_OBJECT (tag), "name", &tag_name, NULL);

	}

      char *result = escape(gtk_text_buffer_get_text(buffer,
						     &iter_start,
						     &iter_end,
						     0));

      for (tagp = tags;  tagp != NULL;  tagp = tagp->next)
	{
	  GtkTextTag *tag = tagp->data;
	  g_object_get (G_OBJECT (tag), "name", &tag_name, NULL);

	}

      if ( g_ascii_strcasecmp(tag_name, "link") == 0)
	fprintf(filefd, "<a href='%s'>%s</a>\n", result, result);
      else
	fprintf(filefd, "<%s>%s</%s>\n", tag_name, result, tag_name);

      g_free(result);

      if (tags)
	g_slist_free (tags);

    } while(gtk_text_iter_forward_line(&iter_start));

  /*
   * HTML Footer
   */
  fprintf(filefd, ""
	  "</body>\n"
	  "</html>\n");

  fclose(filefd);

  pause_board(FALSE);

}