static void
chat_text_view_maybe_trim_buffer (EmpathyChatTextView *view)
{
	EmpathyChatTextViewPriv *priv;
	GtkTextIter         top, bottom;
	gint                line;
	gint                remove;
	GtkTextTagTable    *table;
	GtkTextTag         *tag;
	
	priv = GET_PRIV (view);
	
	gtk_text_buffer_get_end_iter (priv->buffer, &bottom);
	line = gtk_text_iter_get_line (&bottom);
	if (line < MAX_LINES) {
		return;
	}
	
	remove = line - MAX_LINES;
	gtk_text_buffer_get_start_iter (priv->buffer, &top);
	
	bottom = top;
	if (!gtk_text_iter_forward_lines (&bottom, remove)) {
		return;
	}
	
	/* Track backwords to a place where we can safely cut, we don't do it in
	  * the middle of a tag.
	  */
	table = gtk_text_buffer_get_tag_table (priv->buffer);
	tag = gtk_text_tag_table_lookup (table, EMPATHY_CHAT_TEXT_VIEW_TAG_CUT);
	if (!tag) {
		return;
	}
	
	if (!gtk_text_iter_forward_to_tag_toggle (&bottom, tag)) {
		return;
	}
	
	if (!gtk_text_iter_equal (&top, &bottom)) {
		gtk_text_buffer_delete (priv->buffer, &top, &bottom);
	}
}
/**
 * \fn display_message_receipt
 * \brief Displays the received receipt at the correct position
 */
void display_message_receipt(const char* strId){

	#ifdef DEBUG
	if(strId == NULL)
		printf("NO ID\n");
	else
		printf("id is: %s \n", strId);
	#endif

	if(strId == NULL)
		return;

	message_info* info = (message_info*) g_hash_table_lookup(ht_locations, strId);

	#ifdef DEBUG
	printf("insert...");
	#endif

	if(info != NULL)
	{
		GtkTextIter		location;
		gtk_text_buffer_get_iter_at_offset (info->textbuffer,
											&location,
											info->offset);
		gtk_text_iter_forward_lines (&location, info->lines);
		gtk_text_iter_forward_to_line_end (&location);

		gtk_text_buffer_insert (info->textbuffer,
							&location,
							" ✓",
							-1);

		g_hash_table_remove (ht_locations, strId);
	}
	#ifdef DEBUG
	else
		printf("failed: id not found\n");
	#endif
}
static void
ide_source_view_movements_move_page (Movement *mv)
{
  GtkTextView *text_view = (GtkTextView *)mv->self;
  GtkTextBuffer *buffer;
  GtkTextMark *mark;
  GdkRectangle rect;
  GtkTextIter iter_top;
  GtkTextIter iter_bottom;
  GtkTextIter scroll_iter;
  gint scrolloff;
  gint half_page;
  gint line_top;
  gint line_bottom;

  gtk_text_view_get_visible_rect (text_view, &rect);
  gtk_text_view_get_iter_at_location (text_view, &iter_top, rect.x, rect.y);
  gtk_text_view_get_iter_at_location (text_view, &iter_bottom,
                                      rect.x + rect.width,
                                      rect.y + rect.height);

  buffer = gtk_text_view_get_buffer (text_view);

  line_top = gtk_text_iter_get_line (&iter_top);
  line_bottom = gtk_text_iter_get_line (&iter_bottom);

  half_page = MAX (1, (line_bottom - line_top) / 2);
  scrolloff = MIN (ide_source_view_get_scroll_offset (mv->self), half_page);

  switch ((int)mv->type)
    {
    case IDE_SOURCE_VIEW_MOVEMENT_HALF_PAGE_UP:
      ide_source_view_movements_scroll_by_lines (mv, -half_page);
      gtk_text_iter_backward_lines (&mv->insert, half_page);
      break;

    case IDE_SOURCE_VIEW_MOVEMENT_HALF_PAGE_DOWN:
      ide_source_view_movements_scroll_by_lines (mv, half_page);
      gtk_text_iter_forward_lines (&mv->insert, half_page);
      break;

    case IDE_SOURCE_VIEW_MOVEMENT_PAGE_UP:
      gtk_text_buffer_get_iter_at_line (buffer, &mv->insert, MAX (0, line_top - scrolloff));
      text_iter_forward_to_nonspace_captive (&mv->insert);
      ide_source_view_movements_select_range (mv);

      mark = _ide_source_view_get_scroll_mark (mv->self);
      gtk_text_buffer_get_iter_at_line (buffer, &scroll_iter, line_top);
      gtk_text_buffer_move_mark (buffer, mark, &scroll_iter);
      gtk_text_view_scroll_to_mark (text_view, mark, 0.0, TRUE, 1.0, 1.0);

      mv->ignore_select = TRUE;
      mv->ignore_scroll_to_insert = TRUE;
      break;

    case IDE_SOURCE_VIEW_MOVEMENT_PAGE_DOWN:
      gtk_text_buffer_get_iter_at_line (buffer, &mv->insert, line_bottom + scrolloff);
      text_iter_forward_to_nonspace_captive (&mv->insert);
      ide_source_view_movements_select_range (mv);

      mark = _ide_source_view_get_scroll_mark (mv->self);
      gtk_text_buffer_get_iter_at_line (buffer, &scroll_iter, line_bottom);
      gtk_text_buffer_move_mark (buffer, mark, &scroll_iter);
      gtk_text_view_scroll_to_mark (text_view, mark, 0.0, TRUE, 1.0, 0.0);

      mv->ignore_select = TRUE;
      mv->ignore_scroll_to_insert = TRUE;
      break;

    default:
      g_assert_not_reached();
    }
}