GtkTextLineSegment*
gtk_text_line_segment_split (const GtkTextIter *iter)
{
    GtkTextLineSegment *prev, *seg;
    GtkTextBTree *tree;
    GtkTextLine *line;
    int count;

    line = _gtk_text_iter_get_text_line (iter);
    tree = _gtk_text_iter_get_btree (iter);

    count = gtk_text_iter_get_line_index (iter);

    if (gtk_debug_flags & GTK_DEBUG_TEXT)
        _gtk_text_iter_check (iter);

    prev = NULL;
    seg = line->segments;

    while (seg != NULL)
    {
        if (seg->byte_count > count)
        {
            if (count == 0)
            {
                return prev;
            }
            else
            {
                g_assert (count != seg->byte_count);
                g_assert (seg->byte_count > 0);

                _gtk_text_btree_segments_changed (tree);

                seg = (*seg->type->splitFunc)(seg, count);

                if (prev == NULL)
                    line->segments = seg;
                else
                    prev->next = seg;

                return seg;
            }
        }
        else if ((seg->byte_count == 0) && (count == 0)
                 && !seg->type->leftGravity)
        {
            return prev;
        }

        count -= seg->byte_count;
        prev = seg;
        seg = seg->next;
    }
    g_error ("split_segment reached end of line!");
    return NULL;
}
Exemple #2
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();
}
Exemple #3
0
/********** 'set_chord_position' function ************************************/
gint set_chord_position(GtkWidget *t_view, GtkTextBuffer *buffer)
{
	GtkTextTag *tag;	

	GtkTextMark *end_chord,
	            *start_chord;	

	GtkTextIter ch,	
	            chord_S,
	            chord_E,
	            match_end,
	            match_start,	
	            start_of_line;
	
	GtkClipboard *clipboard;
		
	gint line_num_1,
	     line_num_2,
	     line_count_V,	
	     line_offset_1,
	     line_offset_2;

	line_count_V = gtk_text_buffer_get_line_count(buffer);
	clipboard = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD);	
	
	gtk_text_buffer_get_start_iter(buffer, &start_of_line);
	
	if(gtk_text_iter_forward_search(&start_of_line, "[", 1, 
									&match_start, &match_end, NULL))
	{		
		gtk_text_buffer_create_mark(buffer, "start_chord", &match_start, FALSE);
		
		start_chord = gtk_text_buffer_get_mark(buffer, "start_chord");
	}
	else 
	{
		return -1;
	}
	
	if(gtk_text_iter_forward_search(&start_of_line, "]", 1, 
									&match_start, &match_end, NULL))		
	{		
		gtk_text_buffer_create_mark(buffer, "end_chord", &match_end, FALSE);
		
		end_chord = gtk_text_buffer_get_mark(buffer, "end_chord");	
	}	
	else 
	{
		return -1;	
	}

	// Initializes iters at mark.
	gtk_text_buffer_get_iter_at_mark(buffer, &chord_S, start_chord);
	gtk_text_buffer_get_iter_at_mark(buffer, &chord_E, end_chord);
	
	// Get line and line offset of iter. If we just obtain the offset 
	// within buffer then chord_S will not format as desired.
	line_num_1 = gtk_text_iter_get_line(&chord_S);
	line_offset_1 = gtk_text_iter_get_line_index(&chord_S);	
	line_num_2 = gtk_text_iter_get_line(&chord_E);
	line_offset_2 = gtk_text_iter_get_line_index(&chord_E);
	
	// This returns with error if end bracket does not have a 
	// matching start bracket.
	if(line_offset_1 > line_offset_2)
	{
		return -1;	
	}
	
	//g_print("Lineoffset of start:end bracket:\n%d\n%d\n", line_offset_1, line_offset_2);
		
	// If chord found is found more than two lines down
	// refresh global values of 'line_count_C' and 'line_num_C'. 
	if(line_num_1 > (line_num_C + 1))	
	{
		line_num_C = line_num_1;
		line_count_C = line_count_V;
	}
	
	// Copy, cut, and add tags to the section between the marks.
	gtk_text_buffer_select_range(buffer, &chord_S, &chord_E);
	tag = gtk_text_buffer_create_tag(buffer, NULL, "background", "gold",
									 "weight", "500", 
									 "foreground-gdk", "black3", NULL);
	gtk_text_buffer_apply_tag(buffer, tag, &chord_S, &chord_E);
	gtk_text_buffer_cut_clipboard(buffer, clipboard, TRUE);
	
	// This finds first chord of line.
	if(line_count_V == line_count_C) 
	{	
		gtk_text_buffer_get_iter_at_line(buffer, &start_of_line, line_num_1);
		gtk_text_buffer_insert(buffer, &start_of_line, "\n", -1);
	}

	// This finds the rest of the chord_S on the same line as the first. 
	if(line_num_1 == (line_num_C + 1))
	{
		line_num_1 = line_num_1 - 1;		
		line_num_2 = line_num_2 - 1;
	}

	gtk_text_buffer_get_iter_at_line(buffer, &ch, line_num_1);
	
	// Insert 110 blank spaces so we can insert chord_S at higher offsets than 0.
	// GtkTextBuffer does not allow us to insert past a newline character
	// so we move it with spaces to allow us to place chord_S at offsets 
	// past a newline character.
	if(gtk_text_iter_get_char(&ch) == '\n')
	{	
		gtk_text_buffer_insert(buffer, &ch, 
	    "                                                                                                              ",
							    -1);		
	}
	
	// Place iter at the same offset one line above.
	gtk_text_buffer_get_iter_at_line_index(buffer, &ch, line_num_1, line_offset_1);
	
	//g_print("Position after cut: %d\n", line_offset_1);
	gtk_text_buffer_paste_clipboard(buffer, clipboard, &ch, TRUE);	
	
	gtk_text_buffer_get_iter_at_line_offset(buffer, &ch, line_num_1, line_offset_2);
	
	// Deletes the end bracket.	
	gtk_text_buffer_backspace(buffer, &ch, FALSE, TRUE);
	gtk_text_buffer_get_iter_at_line_offset(buffer, &ch, line_num_1, line_offset_1 +1);
	
	// Deletes the start bracket. 	
	gtk_text_buffer_backspace(buffer, &ch, FALSE, TRUE);
	gtk_text_buffer_delete_mark_by_name(buffer, "start_chord");
	gtk_text_buffer_delete_mark_by_name(buffer, "end_chord");
	
	return 0;
}
Exemple #4
0
static gint console_key_handler (GtkWidget *cview, GdkEventKey *event, 
				 gpointer p)
{
    guint keyval = event->keyval;
    guint upkey = gdk_keyval_to_upper(keyval);
    GtkTextIter ins, end;
    GtkTextBuffer *buf;
    GtkTextMark *mark;
    gint ctrl = 0;

#ifdef MAC_NATIVE
    if (cmd_key(event)) {
	if (upkey == GDK_C || upkey == GDK_X) {
	    /* allow regular copy/cut behavior */
	    return FALSE;
	}
    }	
#endif

    if (event->state & GDK_CONTROL_MASK) {
	if (keyval == GDK_Control_L || keyval == GDK_Control_R) {
	    return FALSE;
	} else if (upkey == GDK_C || upkey == GDK_X) {
	    /* allow regular copy/cut behavior */
	    return FALSE;
	} else {
	    ctrl = 1;
	}
    }

    buf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(cview));

    /* first find out where the insertion point and end are */
    mark = gtk_text_buffer_get_insert(buf);
    gtk_text_buffer_get_iter_at_mark(buf, &ins, mark);
    gtk_text_buffer_get_end_iter(buf, &end);

    /* if the insertion point is not on the last line, move it */
    if (gtk_text_iter_get_line(&ins) != gtk_text_iter_get_line(&end)) {
	gtk_text_buffer_place_cursor(buf, &end);
	gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(cview), TRUE);
	gtk_text_buffer_get_end_iter(buf, &ins);
    }

    if (keyval == GDK_Home && (event->state & GDK_SHIFT_MASK)) {
	/* "select to start of line" */
	GtkTextIter start = ins;

	gtk_text_iter_set_line_index(&start, 2);	
	gtk_text_buffer_select_range(buf, &start, &ins);
	return TRUE;
    }

    if (IS_BACKKEY(keyval)) {
	/* if we're at the start of the input line, block backspacing */
	if (gtk_text_iter_get_line_index(&ins) < 3) {
	    return TRUE;
	}
    } else if (keyval == GDK_Home || (ctrl && upkey == GDK_A)) {
	/* go to start of typing area */
	gtk_text_iter_set_line_index(&ins, 2);	
	gtk_text_buffer_place_cursor(buf, &ins);
	return TRUE;
    } 

    /* At this point 'ins' indicates the insertion point and
       'end' points to the end of the current line of input,
       These may or may not be the same thing.
    */

    if (keyval == GDK_Return) {
	/* execute the command, unless backslash-continuation 
	   is happening */
	ExecState *state;
	gchar *thisline;
	int contd = 0, err = 0;

	state = g_object_get_data(G_OBJECT(cview), "ExecState");
	thisline = console_get_current_line(buf, &ins);

	if (thisline != NULL) {
	    g_strstrip(thisline);
	    contd = command_continues(state->line, thisline, &err);
	    g_free(thisline);
	}

	if (err) {
	    gui_errmsg(err);
	} else if (contd) {
	    console_insert_prompt(buf, &end, "\n> ");
	    console_scroll_to_end(cview, buf, &end);
	} else {
	    /* request execution of the completed command */
	    command_entered = 1;
	}

	event->keyval = GDK_End;
	return FALSE;
    }

    if (keyval == GDK_Up || keyval == GDK_Down) {
	/* up/down arrows: navigate the command history */
	GtkTextIter start = ins;
	const char *histline;

	if (hpos == hlines && keyval == GDK_Up) {
	    g_free(hist0);
	    hist0 = console_get_current_line(buf, &ins);
	}

	histline = fetch_history_line(keyval);

	if (histline != NULL || keyval == GDK_Down) {
	    gtk_text_iter_set_line_index(&start, 2);
	    gtk_text_buffer_delete(buf, &start, &end);
	    if (histline != NULL) {
		gtk_text_buffer_insert(buf, &start, histline, -1);
	    } else if (hpos == hlines && hist0 != NULL) {
		gtk_text_buffer_insert(buf, &start, hist0, -1);
	    }
	}

	return TRUE;
    }

    if (keyval == GDK_Tab) {
	/* tab completion for gretl commands, variable names */
	return console_complete_word(buf, &ins);
    } 

    return FALSE;
}
Exemple #5
0
void
gtk_text_layout_draw (GtkTextLayout *layout,
                      GtkWidget *widget,
                      GdkDrawable *drawable,
		      GdkGC       *cursor_gc,
                      /* Location of the drawable
                         in layout coordinates */
                      gint x_offset,
                      gint y_offset,
                      /* Region of the layout to
                         render */
                      gint x,
                      gint y,
                      gint width,
                      gint height,
                      /* widgets to expose */
                      GList **widgets)
{
  GdkRectangle clip;
  gint current_y;
  GSList *cursor_list;
  GtkTextRenderState *render_state;
  GtkTextIter selection_start, selection_end;
  gboolean have_selection = FALSE;
  GSList *line_list;
  GSList *tmp_list;
  
  g_return_if_fail (GTK_IS_TEXT_LAYOUT (layout));
  g_return_if_fail (layout->default_style != NULL);
  g_return_if_fail (layout->buffer != NULL);
  g_return_if_fail (drawable != NULL);
  g_return_if_fail (width >= 0);
  g_return_if_fail (height >= 0);

  if (width == 0 || height == 0)
    return;

  line_list =  gtk_text_layout_get_lines (layout, y + y_offset, y + y_offset + height, &current_y);
  current_y -= y_offset;

  if (line_list == NULL)
    return; /* nothing on the screen */

  clip.x = x;
  clip.y = y;
  clip.width = width;
  clip.height = height;

  render_state = gtk_text_render_state_new (widget, drawable, &clip);

  gdk_gc_set_clip_rectangle (render_state->fg_gc, &clip);
  gdk_gc_set_clip_rectangle (render_state->bg_gc, &clip);

  gtk_text_layout_wrap_loop_start (layout);

  if (gtk_text_buffer_get_selection_bounds (layout->buffer,
                                            &selection_start,
                                            &selection_end))
    have_selection = TRUE;

  tmp_list = line_list;
  while (tmp_list != NULL)
    {
      GtkTextLineDisplay *line_display;
      gint selection_start_index = -1;
      gint selection_end_index = -1;
      gboolean have_strong;
      gboolean have_weak;

      GtkTextLine *line = tmp_list->data;

      line_display = gtk_text_layout_get_line_display (layout, line, FALSE);

      if (line_display->height > 0)
        {
          g_assert (line_display->layout != NULL);
          
          if (have_selection)
            {
              GtkTextIter line_start, line_end;
              gint byte_count;
              
              gtk_text_layout_get_iter_at_line (layout,
                                                &line_start,
                                                line, 0);
              line_end = line_start;
	      if (!gtk_text_iter_ends_line (&line_end))
		gtk_text_iter_forward_to_line_end (&line_end);
              byte_count = gtk_text_iter_get_line_index (&line_end);     

              if (gtk_text_iter_compare (&selection_start, &line_end) <= 0 &&
                  gtk_text_iter_compare (&selection_end, &line_start) >= 0)
                {
                  if (gtk_text_iter_compare (&selection_start, &line_start) >= 0)
                    selection_start_index = gtk_text_iter_get_line_index (&selection_start);
                  else
                    selection_start_index = -1;

                  if (gtk_text_iter_compare (&selection_end, &line_end) <= 0)
                    selection_end_index = gtk_text_iter_get_line_index (&selection_end);
                  else
                    selection_end_index = MAX(byte_count, 1);
                }
            }

          render_para (drawable, render_state, line_display,
                       - x_offset,
                       current_y,
                       selection_start_index, selection_end_index,
                       widgets);

          /* We paint the cursors last, because they overlap another chunk
         and need to appear on top. */

 	  have_strong = FALSE;
 	  have_weak = FALSE;
	  
	  cursor_list = line_display->cursors;
	  while (cursor_list)
	    {
	      GtkTextCursorDisplay *cursor = cursor_list->data;
 	      if (cursor->is_strong)
 		have_strong = TRUE;
 	      else
 		have_weak = TRUE;
	      
	      cursor_list = cursor_list->next;
 	    }
	  
          cursor_list = line_display->cursors;
          while (cursor_list)
            {
              GtkTextCursorDisplay *cursor = cursor_list->data;
	      GtkTextDirection dir;
 	      GdkRectangle cursor_location;
              GdkGC *gc;

              dir = line_display->direction;
 	      if (have_strong && have_weak)
 		{
 		  if (!cursor->is_strong)
 		    dir = (dir == GTK_TEXT_DIR_RTL) ? GTK_TEXT_DIR_LTR : GTK_TEXT_DIR_RTL;
 		}
 
 	      cursor_location.x = line_display->x_offset + cursor->x - x_offset;
 	      cursor_location.y = current_y + line_display->top_margin + cursor->y;
 	      cursor_location.width = 0;
 	      cursor_location.height = cursor->height;
 
	      gc = _gtk_get_insertion_cursor_gc (widget, cursor->is_strong);
	      gdk_gc_set_clip_rectangle(gc, &clip);
 	      _gtk_draw_insertion_cursor (widget, drawable, gc, &cursor_location,
                                          dir, have_strong && have_weak);
              gdk_gc_set_clip_rectangle (gc, NULL);

	      g_object_unref (gc);

              cursor_list = cursor_list->next;
            }
        } /* line_display->height > 0 */
          
      current_y += line_display->height;
      gtk_text_layout_free_line_display (layout, line_display);
      render_state->last_appearance = NULL;
      render_state->last_bg_appearance = NULL;
      
      tmp_list = g_slist_next (tmp_list);
    }

  gtk_text_layout_wrap_loop_end (layout);
  gtk_text_render_state_destroy (render_state);

  g_slist_free (line_list);
}