예제 #1
0
static gboolean
on_view_draw (GtkSourceView   *view,
              cairo_t         *cr,
              GtkSourceGutter *gutter)
{
	GdkWindow *window;
	GtkTextView *text_view;
	GArray *sizes;
	GdkRectangle clip;
	gint x, y;
	gint y1, y2;
	GArray *numbers;
	GArray *pixels;
	GArray *heights;
	GtkTextIter cur;
	gint cur_line;
	gint count;
	gint i;
	GList *item;
	GtkTextIter start;
	GtkTextIter end;
	GtkTextBuffer *buffer;
	GdkRectangle background_area;
	GdkRectangle cell_area;
	GtkTextIter selection_start;
	GtkTextIter selection_end;
	gboolean has_selection;
	gint idx;
	GtkStyleContext *style_context;
	GdkRGBA fg_color;

	window = gtk_source_gutter_get_window (gutter);

	if (window == NULL || !gtk_cairo_should_draw_window (cr, window))
	{
		return FALSE;
	}

	gtk_cairo_transform_to_window (cr, GTK_WIDGET (view), window);

	text_view = GTK_TEXT_VIEW (view);

	if (!gdk_cairo_get_clip_rectangle (cr, &clip))
	{
		return FALSE;
	}

	gutter->priv->is_drawing = TRUE;

	buffer = gtk_text_view_get_buffer (text_view);

	gdk_window_get_pointer (window, &x, &y, NULL);

	y1 = clip.y;
	y2 = y1 + clip.height;

	/* get the extents of the line printing */
	gtk_text_view_window_to_buffer_coords (text_view,
	                                       gutter->priv->window_type,
	                                       0,
	                                       y1,
	                                       NULL,
	                                       &y1);

	gtk_text_view_window_to_buffer_coords (text_view,
	                                       gutter->priv->window_type,
	                                       0,
	                                       y2,
	                                       NULL,
	                                       &y2);

	numbers = g_array_new (FALSE, FALSE, sizeof (gint));
	pixels = g_array_new (FALSE, FALSE, sizeof (gint));
	heights = g_array_new (FALSE, FALSE, sizeof (gint));
	sizes = g_array_new (FALSE, FALSE, sizeof (gint));

	calculate_gutter_size (gutter, sizes);

	i = 0;
	x = 0;

	background_area.x = 0;
	background_area.height = get_lines (text_view,
	                                    y1,
	                                    y2,
	                                    pixels,
	                                    heights,
	                                    numbers,
	                                    &count,
	                                    &start,
	                                    &end);

	cell_area.x = gutter->priv->xpad;
	cell_area.height = background_area.height;

	gtk_text_view_buffer_to_window_coords (text_view,
	                                       gutter->priv->window_type,
	                                       0,
	                                       g_array_index (pixels, gint, 0),
	                                       NULL,
	                                       &background_area.y);

	cell_area.y = background_area.y;

	item = gutter->priv->renderers;
	idx = 0;

	style_context = gtk_widget_get_style_context (GTK_WIDGET (view));

	gtk_style_context_get_color (style_context,
	                             gtk_widget_get_state (GTK_WIDGET (view)),
	                             &fg_color);

	gdk_cairo_set_source_rgba (cr, &fg_color);

	while (item)
	{
		Renderer *renderer = item->data;
		gint xpad;
		gint width;

		width = g_array_index (sizes, gint, idx++);

		if (gtk_source_gutter_renderer_get_visible (renderer->renderer))
		{
			gtk_source_gutter_renderer_get_padding (renderer->renderer,
			                                        &xpad,
			                                        NULL);

			background_area.width = width;

			cell_area.width = width - 2 * xpad;
			cell_area.x = background_area.x + xpad;

			cairo_save (cr);

			gdk_cairo_rectangle (cr, &background_area);
			cairo_clip (cr);

			gtk_source_gutter_renderer_begin (renderer->renderer,
			                                  cr,
			                                  &background_area,
			                                  &cell_area,
			                                  &start,
			                                  &end);

			cairo_restore (cr);

			background_area.x += background_area.width;
		}

		item = g_list_next (item);
	}

	gtk_text_buffer_get_iter_at_mark (buffer,
	                                  &cur,
	                                  gtk_text_buffer_get_insert (buffer));

	cur_line = gtk_text_iter_get_line (&cur);

	gtk_text_buffer_get_selection_bounds (buffer,
	                                      &selection_start,
	                                      &selection_end);

	has_selection = !gtk_text_iter_equal (&selection_start, &selection_end);

	if (has_selection)
	{
		if (!gtk_text_iter_starts_line (&selection_start))
		{
			gtk_text_iter_set_line_offset (&selection_start, 0);
		}

		if (!gtk_text_iter_ends_line (&selection_end))
		{
			gtk_text_iter_forward_to_line_end (&selection_end);
		}
	}

	for (i = 0; i < count; ++i)
	{
		gint pos;
		gint line_to_paint;

		end = start;

		if (!gtk_text_iter_ends_line (&end))
		{
			gtk_text_iter_forward_to_line_end (&end);
		}

		gtk_text_view_buffer_to_window_coords (text_view,
		                                       gutter->priv->window_type,
		                                       0,
		                                       g_array_index (pixels, gint, i),
		                                       NULL,
		                                       &pos);

		line_to_paint = g_array_index (numbers, gint, i);

		background_area.y = pos;
		background_area.height = g_array_index (heights, gint, i);
		background_area.x = 0;

		idx = 0;

		for (item = gutter->priv->renderers; item; item = g_list_next (item))
		{
			Renderer *renderer;
			gint width;
			GtkSourceGutterRendererState state;
			gint xpad;
			gint ypad;

			renderer = item->data;
			width = g_array_index (sizes, gint, idx++);

			if (!gtk_source_gutter_renderer_get_visible (renderer->renderer))
			{
				continue;
			}

			gtk_source_gutter_renderer_get_padding (renderer->renderer,
			                                        &xpad,
			                                        &ypad);

			background_area.width = width;

			cell_area.y = background_area.y + ypad;
			cell_area.height = background_area.height - 2 * ypad;

			cell_area.x = background_area.x + xpad;
			cell_area.width = background_area.width - 2 * xpad;

			state = GTK_SOURCE_GUTTER_RENDERER_STATE_NORMAL;

			if (line_to_paint == cur_line)
			{
				state |= GTK_SOURCE_GUTTER_RENDERER_STATE_CURSOR;
			}

			if (has_selection &&
			    gtk_text_iter_in_range (&start,
			                            &selection_start,
			                            &selection_end))
			{
				state |= GTK_SOURCE_GUTTER_RENDERER_STATE_SELECTED;
			}

			if (renderer->prelit >= 0 && cell_area.y <= renderer->prelit && cell_area.y + cell_area.height >= renderer->prelit)
			{
				state |= GTK_SOURCE_GUTTER_RENDERER_STATE_PRELIT;
			}

			gtk_source_gutter_renderer_query_data (renderer->renderer,
			                                       &start,
			                                       &end,
			                                       state);

			cairo_save (cr);

			gdk_cairo_rectangle (cr, &background_area);

			cairo_clip (cr);

			/* Call render with correct area */
			gtk_source_gutter_renderer_draw (renderer->renderer,
			                                 cr,
			                                 &background_area,
			                                 &cell_area,
			                                 &start,
			                                 &end,
			                                 state);

			cairo_restore (cr);

			background_area.x += background_area.width;
		}

		gtk_text_iter_forward_line (&start);
	}

	for (item = gutter->priv->renderers; item; item = g_list_next (item))
	{
		Renderer *renderer = item->data;

		if (gtk_source_gutter_renderer_get_visible (renderer->renderer))
		{
			gtk_source_gutter_renderer_end (renderer->renderer);
		}
	}

	g_array_free (numbers, TRUE);
	g_array_free (pixels, TRUE);
	g_array_free (heights, TRUE);

	g_array_free (sizes, TRUE);

	gutter->priv->is_drawing = FALSE;

	return FALSE;
}
예제 #2
0
static gboolean
gimp_text_style_editor_update_idle (GimpTextStyleEditor *editor)
{
  GtkTextBuffer *buffer = GTK_TEXT_BUFFER (editor->buffer);

  if (editor->update_idle_id)
    {
      g_source_remove (editor->update_idle_id);
      editor->update_idle_id = 0;
    }

  if (gtk_text_buffer_get_has_selection (buffer))
    {
      GtkTextIter  start, end;
      GtkTextIter  iter;
      GList       *list;
      gboolean     any_toggle_active = TRUE;
      gboolean     font_differs      = FALSE;
      gboolean     color_differs     = FALSE;
      gboolean     size_differs      = FALSE;
      gboolean     baseline_differs  = FALSE;
      gboolean     kerning_differs   = FALSE;
      GtkTextTag  *font_tag          = NULL;
      GtkTextTag  *color_tag         = NULL;
      GtkTextTag  *size_tag          = NULL;
      GtkTextTag  *baseline_tag      = NULL;
      GtkTextTag  *kerning_tag       = NULL;

      gtk_text_buffer_get_selection_bounds (buffer, &start, &end);
      gtk_text_iter_order (&start, &end);

      /*  first, switch all toggles on  */
      for (list = editor->toggles; list; list = g_list_next (list))
        {
          GtkToggleButton *toggle = list->data;

          gimp_text_style_editor_set_toggle (editor, toggle, TRUE);
        }

      /*  and get some initial values  */
      font_tag     = gimp_text_buffer_get_iter_font (editor->buffer,
                                                     &start, NULL);
      color_tag    = gimp_text_buffer_get_iter_color (editor->buffer,
                                                      &start, NULL);
      size_tag     = gimp_text_buffer_get_iter_size (editor->buffer,
                                                     &start, NULL);
      baseline_tag = gimp_text_buffer_get_iter_baseline (editor->buffer,
                                                         &start, NULL);
      kerning_tag  = gimp_text_buffer_get_iter_kerning (editor->buffer,
                                                        &start, NULL);

      for (iter = start;
           gtk_text_iter_in_range (&iter, &start, &end);
           gtk_text_iter_forward_cursor_position (&iter))
        {
          if (any_toggle_active)
            {
              any_toggle_active = FALSE;

              for (list = editor->toggles; list; list = g_list_next (list))
                {
                  GtkToggleButton *toggle = list->data;
                  GtkTextTag      *tag    = g_object_get_data (G_OBJECT (toggle),
                                                               "tag");

                  if (! gtk_text_iter_has_tag (&iter, tag))
                    {
                      gimp_text_style_editor_set_toggle (editor, toggle, FALSE);
                    }
                  else
                    {
                      any_toggle_active = TRUE;
                    }
                }
            }

          if (! font_differs)
            {
              GtkTextTag *tag;

              tag = gimp_text_buffer_get_iter_font (editor->buffer, &iter,
                                                    NULL);

              if (tag != font_tag)
                font_differs = TRUE;
            }

          if (! color_differs)
            {
              GtkTextTag *tag;

              tag = gimp_text_buffer_get_iter_color (editor->buffer, &iter,
                                                     NULL);

              if (tag != color_tag)
                color_differs = TRUE;
            }

          if (! size_differs)
            {
              GtkTextTag *tag;

              tag = gimp_text_buffer_get_iter_size (editor->buffer, &iter,
                                                    NULL);

              if (tag != size_tag)
                size_differs = TRUE;
            }

          if (! baseline_differs)
            {
              GtkTextTag *tag;

              tag = gimp_text_buffer_get_iter_baseline (editor->buffer, &iter,
                                                        NULL);

              if (tag != baseline_tag)
                baseline_differs = TRUE;
            }

          if (! kerning_differs)
            {
              GtkTextTag *tag;

              tag = gimp_text_buffer_get_iter_kerning (editor->buffer, &iter,
                                                       NULL);

              if (tag != kerning_tag)
                kerning_differs = TRUE;
            }

          if (! any_toggle_active &&
              color_differs       &&
              font_differs        &&
              size_differs        &&
              baseline_differs    &&
              kerning_differs)
            break;
       }

      if (font_differs)
        gimp_text_style_editor_set_font (editor, NULL);
      else if (font_tag)
        gimp_text_style_editor_set_font (editor, font_tag);
      else
        gimp_text_style_editor_set_default_font (editor);

      if (color_differs)
        gimp_text_style_editor_set_color (editor, NULL);
      else if (color_tag)
        gimp_text_style_editor_set_color (editor, color_tag);
      else
        gimp_text_style_editor_set_default_color (editor);

      if (size_differs)
        gimp_text_style_editor_set_size (editor, NULL);
      else if (size_tag)
        gimp_text_style_editor_set_size (editor, size_tag);
      else
        gimp_text_style_editor_set_default_size (editor);

      if (baseline_differs)
        gtk_entry_set_text (GTK_ENTRY (editor->baseline_spinbutton), "");
      else
        gimp_text_style_editor_set_baseline (editor, baseline_tag);

      if (kerning_differs)
        gtk_entry_set_text (GTK_ENTRY (editor->kerning_spinbutton), "");
      else
        gimp_text_style_editor_set_kerning (editor, kerning_tag);
    }
  else /* no selection */
    {
      GtkTextIter  cursor;
      GSList      *tags;
      GSList      *tags_on;
      GSList      *tags_off;
      GList       *list;

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

      tags     = gtk_text_iter_get_tags (&cursor);
      tags_on  = gtk_text_iter_get_toggled_tags (&cursor, TRUE);
      tags_off = gtk_text_iter_get_toggled_tags (&cursor, FALSE);

      for (list = editor->buffer->font_tags; list; list = g_list_next (list))
        {
          GtkTextTag *tag = list->data;

          if ((g_slist_find (tags, tag) &&
               ! g_slist_find (tags_on, tag)) ||
              g_slist_find (tags_off, tag))
            {
              gimp_text_style_editor_set_font (editor, tag);
              break;
            }
        }

      if (! list)
        gimp_text_style_editor_set_default_font (editor);

      for (list = editor->buffer->color_tags; list; list = g_list_next (list))
        {
          GtkTextTag *tag = list->data;

          if ((g_slist_find (tags, tag) &&
               ! g_slist_find (tags_on, tag)) ||
              g_slist_find (tags_off, tag))
            {
              gimp_text_style_editor_set_color (editor, tag);
              break;
            }
        }

      if (! list)
        gimp_text_style_editor_set_default_color (editor);

      for (list = editor->buffer->size_tags; list; list = g_list_next (list))
        {
          GtkTextTag *tag = list->data;

          if ((g_slist_find (tags, tag) &&
               ! g_slist_find (tags_on, tag)) ||
              g_slist_find (tags_off, tag))
            {
              gimp_text_style_editor_set_size (editor, tag);
              break;
            }
        }

      if (! list)
        gimp_text_style_editor_set_default_size (editor);

      for (list = editor->buffer->baseline_tags; list; list = g_list_next (list))
        {
          GtkTextTag *tag = list->data;

          if ((g_slist_find (tags, tag) &&
               ! g_slist_find (tags_on, tag)) ||
              g_slist_find (tags_off, tag))
            {
              gimp_text_style_editor_set_baseline (editor, tag);
              break;
            }
        }

      if (! list)
        gimp_text_style_editor_set_baseline (editor, NULL);

      for (list = editor->toggles; list; list = g_list_next (list))
        {
          GtkToggleButton *toggle = list->data;
          GtkTextTag      *tag    = g_object_get_data (G_OBJECT (toggle),
                                                       "tag");

          gimp_text_style_editor_set_toggle (editor, toggle,
                                             (g_slist_find (tags, tag) &&
                                              ! g_slist_find (tags_on, tag)) ||
                                             g_slist_find (tags_off, tag));
        }

      {
        GtkTextTag *tag;

        tag = gimp_text_buffer_get_iter_kerning (editor->buffer, &cursor, NULL);
        gimp_text_style_editor_set_kerning (editor, tag);
      }

      g_slist_free (tags);
      g_slist_free (tags_on);
      g_slist_free (tags_off);
    }

  return FALSE;
}
gboolean
gtksnippets_inplaceparser_activate(GtkSnippetsInPlaceParser *self, const gchar* content)
{
	gtksnippets_inplaceparser_deactivate(self);
	
	GtkTextBuffer * buffer = gtk_text_view_get_buffer(self->priv->view);
	
	GtkTextMark *insert = gtk_text_buffer_get_insert(buffer);
	/*TODO remove this gsnippets-parser dependency*/
	if (gsnippets_parser_count_vars(content) <= 0)
	{
		GtkTextIter cur;
		gtk_text_buffer_get_iter_at_mark(buffer,&cur,insert);
		gchar *indent = _compute_line_indentation(self->priv->view,&cur);
		gchar *indent_text = _get_text_with_indent(content, indent);
		g_free(indent);
		gtk_text_buffer_insert_at_cursor(buffer,indent_text,-1);
		g_free(indent_text);
		gtk_text_view_scroll_mark_onscreen(self->priv->view,insert);
		return FALSE;
	}
	
	GtkTextIter start_iter;
	gtk_text_buffer_get_iter_at_mark(buffer,&start_iter,insert);
	GtkTextMark *start_mark = gtk_text_buffer_create_mark(buffer,
							      SNIPPET_START_MARK,
							      &start_iter,
							      TRUE);
	GtkTextMark *end_text_mark = gtk_text_buffer_create_mark(buffer,
							      SNIPPET_END_MARK,
							      &start_iter,
							      FALSE);
	GtkTextMark *end_mark;
	
	gchar *indent = _compute_line_indentation(self->priv->view,&start_iter);
	gchar *indent_text = _get_text_with_indent(content, indent);
	g_free(indent);
	gtk_text_buffer_insert_at_cursor(buffer,indent_text,-1);
	g_free(indent_text);
	gtk_text_view_scroll_mark_onscreen(self->priv->view,end_text_mark);

	gsnippets_func_manager_register_func("cursor",
					     gsnippets_func_empty,
					     self);

	/* Searching variables */
	GtkSnippetsGtvVar *var;
	var = search_var(self,buffer,start_mark,end_text_mark);
	while(var!=NULL)
	{
		end_mark = gtksnippets_gtv_var_get_end_mark(var);
		store_var(self,var);
		var = search_var(self,buffer,end_mark,end_text_mark);
	}
	
	/*Sorting varables by index*/
	self->priv->vars = g_list_sort(self->priv->vars,
					sort_variables);
	
	self->priv->active = TRUE;
	active_next_var(self);
	/*The first var is not handled by cursor-changed. We must set moving to FALSE*/
	self->priv->moving = FALSE;
	g_signal_connect(self->priv->view,"key-press-event",G_CALLBACK(view_key_press_cb),self);
	g_signal_connect_after(buffer,"insert-text",G_CALLBACK(view_insert_text_cb),self);
	g_signal_connect_after(buffer,"delete-range",G_CALLBACK(buffer_delete_range_cb),self);
	g_signal_connect_after(buffer,"mark-set",G_CALLBACK(buffer_mark_set_cb),self);
	g_signal_emit (G_OBJECT (self), signals[PARSER_START], 0);
	
	return TRUE;
}
예제 #4
0
/**
 * gtk_text_buffer_insert_markup:
 * @buffer: a #GtkTextBuffer
 * @markup: nul-terminated UTF-8 text with pango markup to insert
 **/
void
gtk_text_buffer_insert_markup (GtkTextBuffer *buffer, GtkTextIter *iter, const gchar *markup)
{
	PangoAttrIterator *paiter;
	PangoAttrList *attrlist;
	GtkTextMark *mark;
	GError *error = NULL;
	gchar *text;

	g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
	g_return_if_fail (markup != NULL);

	if (*markup == '\000')
		return;

	/* invalid */
	if (!pango_parse_markup (markup, -1, 0, &attrlist, &text, NULL, &error)) {
		g_warning ("Invalid markup string: %s", error->message);
		g_error_free (error);
		return;
	}

	/* trivial, no markup */
	if (attrlist == NULL) {
		gtk_text_buffer_insert (buffer, iter, text, -1);
		g_free (text);
		return;
	}

	/* create mark with right gravity */
	mark = gtk_text_buffer_create_mark (buffer, NULL, iter, FALSE);
	paiter = pango_attr_list_get_iterator (attrlist);

	do {
		PangoAttribute *attr;
		GtkTextTag *tag;
		GtkTextTag *tag_para;
		gint start, end;

		pango_attr_iterator_range (paiter, &start, &end);

		if (end == G_MAXINT)	/* last chunk */
			end = start-1; /* resulting in -1 to be passed to _insert */

		tag = gtk_text_tag_new (NULL);

		if ( (attr = pango_attr_iterator_get (paiter, PANGO_ATTR_LANGUAGE)))
			g_object_set (tag, "language", pango_language_to_string ( ( (PangoAttrLanguage*)attr)->value), NULL);

		if ( (attr = pango_attr_iterator_get (paiter, PANGO_ATTR_FAMILY)))
			g_object_set (tag, "family", ( (PangoAttrString*)attr)->value, NULL);

		if ( (attr = pango_attr_iterator_get (paiter, PANGO_ATTR_STYLE)))
			g_object_set (tag, "style", ( (PangoAttrInt*)attr)->value, NULL);

		if ( (attr = pango_attr_iterator_get (paiter, PANGO_ATTR_WEIGHT)))
			g_object_set (tag, "weight", ( (PangoAttrInt*)attr)->value, NULL);

		if ( (attr = pango_attr_iterator_get (paiter, PANGO_ATTR_VARIANT)))
			g_object_set (tag, "variant", ( (PangoAttrInt*)attr)->value, NULL);

		if ( (attr = pango_attr_iterator_get (paiter, PANGO_ATTR_STRETCH)))
			g_object_set (tag, "stretch", ( (PangoAttrInt*)attr)->value, NULL);

		if ( (attr = pango_attr_iterator_get (paiter, PANGO_ATTR_SIZE)))
			g_object_set (tag, "size", ( (PangoAttrInt*)attr)->value, NULL);

		if ( (attr = pango_attr_iterator_get (paiter, PANGO_ATTR_FONT_DESC)))
			g_object_set (tag, "font-desc", ( (PangoAttrFontDesc*)attr)->desc, NULL);

		if ( (attr = pango_attr_iterator_get (paiter, PANGO_ATTR_FOREGROUND))) {
			GdkColor col = { 0,
					( (PangoAttrColor*)attr)->color.red,
					( (PangoAttrColor*)attr)->color.green,
					( (PangoAttrColor*)attr)->color.blue
					};

			g_object_set (tag, "foreground-gdk", &col, NULL);
		}

		if ( (attr = pango_attr_iterator_get (paiter, PANGO_ATTR_BACKGROUND))) {
			GdkColor col = { 0,
					( (PangoAttrColor*)attr)->color.red,
					( (PangoAttrColor*)attr)->color.green,
					( (PangoAttrColor*)attr)->color.blue
					};

			g_object_set (tag, "background-gdk", &col, NULL);
		}

		if ( (attr = pango_attr_iterator_get (paiter, PANGO_ATTR_UNDERLINE)))
			g_object_set (tag, "underline", ( (PangoAttrInt*)attr)->value, NULL);

		if ( (attr = pango_attr_iterator_get (paiter, PANGO_ATTR_STRIKETHROUGH)))
			g_object_set (tag, "strikethrough", (gboolean) ( ( (PangoAttrInt*)attr)->value != 0), NULL);

		if ( (attr = pango_attr_iterator_get (paiter, PANGO_ATTR_RISE)))
			g_object_set (tag, "rise", ( (PangoAttrInt*)attr)->value, NULL);

		if ( (attr = pango_attr_iterator_get (paiter, PANGO_ATTR_SCALE)))
			g_object_set (tag, "scale", ( (PangoAttrFloat*)attr)->value, NULL);

		gtk_text_tag_table_add (gtk_text_buffer_get_tag_table (buffer), tag);

		tag_para = gtk_text_tag_table_lookup (gtk_text_buffer_get_tag_table (buffer), "para");
		gtk_text_buffer_insert_with_tags (buffer, iter, text+start, end - start, tag, tag_para, NULL);

		/* mark had right gravity, so it should be
		 *	at the end of the inserted text now */
		gtk_text_buffer_get_iter_at_mark (buffer, iter, mark);
	} while (pango_attr_iterator_next (paiter));

	gtk_text_buffer_delete_mark (buffer, mark);
	pango_attr_iterator_destroy (paiter);
	pango_attr_list_unref (attrlist);
	g_free (text);
}
static GtkSnippetsGtvVar*
search_var(GtkSnippetsInPlaceParser *self, GtkTextBuffer *buffer,GtkTextMark *init_mark, GtkTextMark *limit_mark)
{
	GtkSnippetsGtvVar *var = NULL;
	GtkTextMark *start_mark, *end_mark, *temp_mark;
	gchar *definition;
	const gchar *default_value;
	GtkTextIter start, end, temp_iter;
	GtkTextIter pos, limit;
	GError *error = NULL;
	gtk_text_buffer_get_iter_at_mark(buffer,&pos, init_mark);
	gtk_text_buffer_get_iter_at_mark(buffer,&limit, limit_mark);
	gboolean found = gtk_text_iter_forward_search(&pos,
				"${",
				GTK_TEXT_SEARCH_VISIBLE_ONLY,
				&start,
				NULL,
				&limit);
	if (found)
	{
		temp_iter = start;
		gtk_text_iter_forward_to_line_end(&temp_iter);
		found = gtk_text_iter_forward_search(&start,
				"}",
				GTK_TEXT_SEARCH_VISIBLE_ONLY,
				&end,
				NULL,
				&temp_iter);
		if (found)
		{
			gtk_text_iter_forward_char(&end);
			start_mark = gtk_text_buffer_create_mark(buffer,
								NULL,
								&start,
								TRUE);
			end_mark = gtk_text_buffer_create_mark(buffer,
								NULL,
								&end,
								FALSE);
			gtk_text_iter_forward_chars(&start,2);
			gtk_text_iter_forward_chars(&end,-1);
			definition = gtk_text_buffer_get_text(buffer,
							&start,
							&end,
							FALSE);
			
			var = gtksnippets_gtv_var_new(definition,
							self->priv->view,
							start_mark,
							end_mark,
							VAR_TAG_NAME,
							VAR_ERROR_TAG_NAME);
			g_free(definition);
			
			default_value = gsnippets_variable_get_default_value(GSNIPPETS_VARIABLE(var));
			if (default_value==NULL)
				default_value = gsnippets_variable_get_name(GSNIPPETS_VARIABLE(var));

			gtk_text_buffer_begin_user_action(buffer);
			gtksnippets_gtv_var_set_text(var,
							default_value,
							&error);
			gtk_text_buffer_end_user_action(buffer);
			if (error != NULL)
			{
				g_warning("Error parsing variable: %s",error->message);
				g_error_free(error);
			}
		}
		else
		{
			/*
			If there is ${ but not } in the line, we must to search
			a new variable because if we return NULL, it is the end
			of the search
			*/
			gtk_text_iter_forward_chars(&start,2);
			temp_mark = gtk_text_buffer_create_mark(buffer,
								NULL,
								&start,
								TRUE);
			gtk_text_buffer_move_mark(buffer,temp_mark,&start);
			var = search_var(self,buffer,temp_mark,limit_mark);
			gtk_text_buffer_delete_mark(buffer,temp_mark);
		}
	}
	
	return var;
}
static gboolean
view_key_press_cb(GtkWidget *view, GdkEventKey *event, gpointer user_data)
{
	GtkSnippetsInPlaceParser *self = GTKSNIPPETS_INPLACEPARSER(user_data);
	if (event->keyval == GDK_Tab
		|| event->keyval == GDK_ISO_Left_Tab
		|| event->keyval == GDK_Return
		|| event->keyval == GDK_KP_Enter)
	{
		if ((event->state & GDK_SHIFT_MASK) == GDK_SHIFT_MASK)
		{
			if (!active_prev_var(self))
			{
				_end_var_replacement(self);
			}
			return TRUE;
		}
		else
		{
			if (!active_next_var(self))
			{
				_end_var_replacement(self);
			}
			return TRUE;
		}
	}
	else if (event->keyval == GDK_Escape)
	{
		gtksnippets_inplaceparser_deactivate(self);
		return TRUE;
	}
	else if (event->keyval == GDK_Home || event->keyval == GDK_KP_Home)
	{
		if (self->priv->active_var_pos!=NULL)
		{
			GtkSnippetsGtvVar *var = GTKSNIPPETS_GTV_VAR(self->priv->active_var_pos->data);
			GtkTextBuffer *buffer = gtk_text_view_get_buffer(self->priv->view);
			GtkTextIter start_iter;
			GtkTextMark *start_mark;
			start_mark = gtksnippets_gtv_var_get_start_mark(var);
			gtk_text_buffer_get_iter_at_mark(buffer,&start_iter,start_mark);
			self->priv->moving = TRUE;
			if ((event->state & GDK_SHIFT_MASK) == GDK_SHIFT_MASK)
			{
				GtkTextMark *imark = gtk_text_buffer_get_insert(buffer);
				GtkTextIter current_iter;
				gtk_text_buffer_get_iter_at_mark(buffer,&current_iter,imark);
				gtk_text_buffer_select_range(buffer,&start_iter,&current_iter);
			}
			else
			{
				gtk_text_buffer_place_cursor(buffer,&start_iter);
			}
			return TRUE;
		}
	}
	else if (event->keyval == GDK_End || event->keyval == GDK_KP_End)
	{
		if (self->priv->active_var_pos!=NULL)
		{
			GtkSnippetsGtvVar *var = GTKSNIPPETS_GTV_VAR(self->priv->active_var_pos->data);
			GtkTextBuffer *buffer = gtk_text_view_get_buffer(self->priv->view);
			GtkTextIter iter;
			GtkTextMark *end_mark;
			end_mark = gtksnippets_gtv_var_get_end_mark(var);
			gtk_text_buffer_get_iter_at_mark(buffer,&iter,end_mark);
			self->priv->moving = TRUE;
			if ((event->state & GDK_SHIFT_MASK) == GDK_SHIFT_MASK)
			{
				GtkTextMark *imark = gtk_text_buffer_get_insert(buffer);
				GtkTextIter current_iter;
				gtk_text_buffer_get_iter_at_mark(buffer,&current_iter,imark);
				gtk_text_buffer_select_range(buffer,&iter,&current_iter);
			}
			else
			{
				gtk_text_buffer_place_cursor(buffer,&iter);
			}
			return TRUE;
		}
	}
	else if (event->keyval == GDK_Left)
	{
		GtkTextBuffer *buffer = gtk_text_view_get_buffer(self->priv->view);
		GtkTextMark *imark = gtk_text_buffer_get_insert(buffer);
		if (!mark_in_current_var(self,imark,-1))
			return TRUE;
	}
	else if (event->keyval == GDK_Right)
	{
		GtkTextBuffer *buffer = gtk_text_view_get_buffer(self->priv->view);
		GtkTextMark *imark = gtk_text_buffer_get_insert(buffer);
		if (!mark_in_current_var(self,imark,1))
			return TRUE;
	}
	return FALSE;
}
예제 #7
0
static int
delete_selection_in_gtk_text_view(GtkTextView *text_view,
				  enum UTextOrigin origin, int former_req_len,
				  int latter_req_len)
{
  GtkTextIter current, start, end, tmp_start, tmp_end;
  gboolean cursor_at_beginning = FALSE;

  if (!gtk_text_view_get_buffer(text_view))
    return -1;

  if (gtk_text_buffer_get_selection_bounds(gtk_text_view_get_buffer(text_view),
      &start, &end)) {
    gtk_text_buffer_get_iter_at_mark(gtk_text_view_get_buffer(text_view),
        &current,
        gtk_text_buffer_get_mark(gtk_text_view_get_buffer(text_view),
        "insert"));
    if (gtk_text_iter_compare(&start, &current) == 0)
      cursor_at_beginning = TRUE;
  } else {
    return -1;
  }

  if (origin == UTextOrigin_Beginning ||
      (origin == UTextOrigin_Cursor && cursor_at_beginning)) {
    tmp_start = start;
    tmp_end = start;

    if (latter_req_len >= 0) {
      gtk_text_iter_forward_chars(&tmp_end, latter_req_len);
      if (gtk_text_iter_compare(&tmp_end, &end) < 0)
	end = tmp_end;
    } else {
      if (latter_req_len == UTextExtent_Line) {
	gtk_text_view_forward_display_line_end(text_view, &tmp_end);
	if (gtk_text_iter_compare(&tmp_end, &end) < 0)
	  end = tmp_end;
      } else {
	if (!(latter_req_len == UTextExtent_Full))
	  return -1;
      }
    }

  } else if (origin == UTextOrigin_End ||
	     (origin == UTextOrigin_Cursor && !cursor_at_beginning)) {
    tmp_start = end;
    tmp_end = end;

    if (former_req_len >= 0) {
      gtk_text_iter_backward_chars(&tmp_start, former_req_len);
      if (gtk_text_iter_compare(&tmp_start, &start) > 0)
	start = tmp_start;
    } else {
      if (former_req_len == UTextExtent_Line) {
	gtk_text_view_backward_display_line_start(text_view, &tmp_start);
	if (gtk_text_iter_compare(&tmp_start, &start) > 0)
	  start = tmp_start;
      } else {
	if (!(former_req_len == UTextExtent_Full))
	  return -1;
      }
    }

  } else {
    return -1;
  }

  gtk_text_buffer_delete_interactive(gtk_text_view_get_buffer(text_view),
      &start, &end, gtk_text_view_get_editable(text_view));

  return 0;
}
예제 #8
0
static void WhatCheck (GtkMenuItem *item, gpointer data) {
  GtkWidget *dialog;
  GtkTextIter start, end;
  char *word;
  gunichar *wword;
  
  // Znajdujemy pozycję kursora
  gtk_text_buffer_get_iter_at_mark(editor_buf, &start,
                                   gtk_text_buffer_get_insert(editor_buf));

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

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

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

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

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

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

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

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

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

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

        // Jeśli chiciał dodać nowe słowo do słownika to dodamy i zapiszemy
        if (gtk_dialog_run(GTK_DIALOG(ask_dialog)) == GTK_RESPONSE_ACCEPT) {
          dictionary_insert(dict, (wchar_t *)wword);
          dictionary_save_lang(dict, dict_location);
        }
        
        gtk_widget_destroy(ask_dialog);
        break;
      }
  
    gtk_widget_destroy(dialog);
  }
  
}
예제 #9
0
static int
acquire_text_in_gtk_text_view(GtkTextView *text_view, enum UTextOrigin origin,
			      int former_req_len, int latter_req_len,
			      char **former, char **latter)
{
  GtkTextIter current, start, end;

  if (!gtk_text_view_get_buffer(text_view))
    return -1;

  gtk_text_buffer_get_iter_at_mark(gtk_text_view_get_buffer(text_view),
      &current,
      gtk_text_buffer_get_mark(gtk_text_view_get_buffer(text_view), "insert"));
  switch (origin) {
  case UTextOrigin_Cursor:
    start = current;
    end = current;

    if (former_req_len >= 0) {
      gtk_text_iter_backward_chars(&start, former_req_len);
    } else {
      if (former_req_len == UTextExtent_Full)
	gtk_text_buffer_get_start_iter(gtk_text_view_get_buffer(text_view), &start);
      else if (former_req_len == UTextExtent_Line)
	gtk_text_view_backward_display_line_start(text_view, &start);
      else
	return -1;
    }
    *former = gtk_text_iter_get_slice(&start, &current);

    if (latter_req_len >= 0)
      gtk_text_iter_forward_chars(&end, latter_req_len);
    else {
      if (latter_req_len == UTextExtent_Full)
	gtk_text_buffer_get_end_iter(gtk_text_view_get_buffer(text_view), &end);
      else if (latter_req_len == UTextExtent_Line)
	gtk_text_view_forward_display_line_end(text_view, &end);
      else {
	g_free(*former);
	return -1;
      }
    }
    *latter = gtk_text_iter_get_slice(&current, &end);
    break;

  case UTextOrigin_Beginning:
    gtk_text_buffer_get_start_iter(gtk_text_view_get_buffer(text_view), &start);
    end = start;

    *former = NULL;

    if (latter_req_len >= 0)
      gtk_text_iter_forward_chars(&end, latter_req_len);
    else {
      if (latter_req_len == UTextExtent_Full)
	gtk_text_buffer_get_end_iter(gtk_text_view_get_buffer(text_view), &end);
      else if (latter_req_len == UTextExtent_Line)
	gtk_text_view_forward_display_line_end(text_view, &end);
      else
        return -1;
    }
    *latter = gtk_text_iter_get_slice(&start, &end);
    break;

  case UTextOrigin_End:
    gtk_text_buffer_get_end_iter(gtk_text_view_get_buffer(text_view), &end);
    start = end;

    if (former_req_len >= 0) {
      gtk_text_iter_backward_chars(&start, former_req_len);
    } else {
      if (former_req_len == UTextExtent_Full)
	gtk_text_buffer_get_start_iter(gtk_text_view_get_buffer(text_view), &start);
      else if (former_req_len == UTextExtent_Line)
	gtk_text_view_backward_display_line_start(text_view, &start);
      else
	return -1;
    }
    *former = gtk_text_iter_get_slice(&start, &end);

    *latter = NULL;
    break;

  case UTextOrigin_Unspecified:
  default:
    return -1;
  }

  return 0;
}
예제 #10
0
static int
delete_text_in_gtk_text_view(GtkTextView *text_view, enum UTextOrigin origin,
			     int former_req_len, int latter_req_len)
{
  GtkTextIter current, start, end;

  if (!gtk_text_view_get_buffer(text_view))
    return -1;

  gtk_text_buffer_get_iter_at_mark(gtk_text_view_get_buffer(text_view),
      &current,
      gtk_text_buffer_get_mark(gtk_text_view_get_buffer(text_view), "insert"));
  start = current;
  end = current;

  switch (origin) {
  case UTextOrigin_Cursor:
    if (former_req_len >= 0) {
      gtk_text_iter_backward_chars(&start, former_req_len);
    } else {
      if (former_req_len == UTextExtent_Full)
	gtk_text_buffer_get_start_iter(gtk_text_view_get_buffer(text_view), &start);
      else if (former_req_len == UTextExtent_Line)
	gtk_text_view_backward_display_line_start(text_view, &start);
      else
	return -1;
    }

    if (latter_req_len >= 0)
      gtk_text_iter_forward_chars(&end, latter_req_len);
    else {
      if (latter_req_len == UTextExtent_Full)
	gtk_text_buffer_get_end_iter(gtk_text_view_get_buffer(text_view), &end);
      else if (latter_req_len == UTextExtent_Line)
	gtk_text_view_forward_display_line_end(text_view, &end);
      else
	return -1;
    }
    break;

  case UTextOrigin_Beginning:
    gtk_text_buffer_get_start_iter(gtk_text_view_get_buffer(text_view), &start);
    end = start;

    if (latter_req_len >= 0)
      gtk_text_iter_forward_chars(&end, latter_req_len);
    else {
      if (latter_req_len == UTextExtent_Full)
	gtk_text_buffer_get_end_iter(gtk_text_view_get_buffer(text_view), &end);
      else if (latter_req_len == UTextExtent_Line)
	gtk_text_view_forward_display_line_end(text_view, &end);
      else
	return -1;
    }
    break;

  case UTextOrigin_End:
    gtk_text_buffer_get_end_iter(gtk_text_view_get_buffer(text_view), &end);
    start = end;

    if (former_req_len >= 0) {
      gtk_text_iter_backward_chars(&start, former_req_len);
    } else {
      if (former_req_len == UTextExtent_Full)
	gtk_text_buffer_get_start_iter(gtk_text_view_get_buffer(text_view), &start);
      else if (former_req_len == UTextExtent_Line)
	gtk_text_view_backward_display_line_start(text_view, &start);
      else
	return -1;
    }
    break;

  case UTextOrigin_Unspecified:
  default:
    return -1;
  }

  gtk_text_buffer_delete_interactive(gtk_text_view_get_buffer(text_view),
      &start, &end, gtk_text_view_get_editable(text_view));

  return 0;
}
예제 #11
0
int
im_uim_acquire_selection_text(IMUIMContext *uic, enum UTextOrigin origin,
			      int former_req_len, int latter_req_len,
			      char **former, char **latter)
{
  gchar *former_start, *text = NULL, *p;
  gint len, text_len;
  int offset, err = 0;
  gboolean cursor_at_beginning = FALSE;

  if (GTK_IS_ENTRY(uic->widget)) {
    gint start, end, current;

    if (gtk_editable_get_selection_bounds(GTK_EDITABLE(uic->widget),
					  &start, &end)) {
      text = gtk_editable_get_chars(GTK_EDITABLE(uic->widget), start, end);
      current = gtk_editable_get_position(GTK_EDITABLE(uic->widget));
      if (current == start)
	cursor_at_beginning = TRUE;
    }
  } else if (GTK_IS_TEXT_VIEW(uic->widget)) {
    GtkTextIter start, end, current;

    if (gtk_text_view_get_buffer(GTK_TEXT_VIEW(uic->widget)) &&
	gtk_text_buffer_get_selection_bounds(gtk_text_view_get_buffer(GTK_TEXT_VIEW(uic->widget)), &start, &end)) {
      text = gtk_text_iter_get_visible_text(&start, &end);
      gtk_text_buffer_get_iter_at_mark(gtk_text_view_get_buffer(GTK_TEXT_VIEW(uic->widget)),
				       &current,
				       gtk_text_buffer_get_mark(gtk_text_view_get_buffer(GTK_TEXT_VIEW(uic->widget)), "insert"));
      if (gtk_text_iter_compare(&start, &current) == 0)
	cursor_at_beginning = TRUE;
    }
  } else {
    /*
     * We use GDK_SELECTION_PRIMARY for the rest of widget, which means it is
     * impossible to guarantee whether the obtained one is the selected text on
     * the target application.
     */ 
    text = gtk_clipboard_wait_for_text(gtk_widget_get_clipboard(GTK_WIDGET(uic->widget), GDK_SELECTION_PRIMARY));
  }

  if (!text)
    return -1;

  len = strlen(text);
  text_len = g_utf8_strlen(text, -1);

  if (origin == UTextOrigin_Beginning ||
      (origin == UTextOrigin_Cursor && cursor_at_beginning)) {
    *former = NULL;

    offset = 0;
    if (latter_req_len >= 0) {
      if (latter_req_len < text_len)
	offset = text + len - g_utf8_offset_to_pointer(text, latter_req_len);
    } else {
      if (!(~latter_req_len & (~UTextExtent_Line | ~UTextExtent_Full))) {
	g_free(text);
	return -1;
      }
    }
    *latter = g_strndup(text, len - offset);
    if (latter_req_len == UTextExtent_Line && (p = strchr(*latter, '\n')))
      *p = '\0';

  } else if (origin == UTextOrigin_End ||
	     (origin == UTextOrigin_Cursor && !cursor_at_beginning)) {
    offset = 0;
    if (former_req_len >= 0) {
      if (former_req_len < text_len)
	offset = text_len - former_req_len;
    } else {
      if (!(~former_req_len & (~UTextExtent_Line | ~UTextExtent_Full))) {
	g_free(text);
	return -1;
      }
    }
    former_start = g_utf8_offset_to_pointer(text, offset);
    if (former_req_len == UTextExtent_Line &&
	(p = strrchr(former_start, '\n')))
      *former = g_strdup(p + 1);
    else
      *former = g_strndup(former_start, text + len - former_start);

    *latter = NULL;

  } else {
    err = -1;
  }
  g_free(text);

  return err;
}
예제 #12
0
static gboolean
ide_xml_highlighter_highlight_timeout_handler (gpointer data)
{
  IdeXmlHighlighter *self = data;
  GtkTextTag *tag;
  GtkTextIter iter;
  GtkTextIter start;
  GtkTextIter end;

  g_assert (IDE_IS_XML_HIGHLIGHTER (self));
  g_assert (self->buffer != NULL);
  g_assert (self->iter_mark != NULL);

  if (self->engine == NULL)
    goto cleanup;

  tag = ide_highlight_engine_get_style (self->engine, XML_TAG_MATCH_STYLE_NAME);

  /*
   * Clear previous tags. We could save the previous
   * iters and clear only those locations but for
   * now this should be ok.
   */
  if (self->has_tags)
    {
      gtk_text_buffer_get_bounds (self->buffer, &start, &end);
      gtk_text_buffer_remove_tag (self->buffer, tag, &start, &end);

      self->has_tags = FALSE;
    }


  gtk_text_buffer_get_iter_at_mark (self->buffer, &iter, self->iter_mark);
  if (ide_xml_in_element (&iter) && ide_xml_get_current_element (&iter,
                                                                 &start,
                                                                 &end))
    {
      GtkTextIter next_start;
      GtkTextIter next_end;
      IdeXmlElementTagType tag_type = ide_xml_get_element_tag_type (&start,
                                                                    &end);

      if ((tag_type == IDE_XML_ELEMENT_TAG_START &&
          ide_xml_find_closing_element (&start,&end,
                                      &next_start,&next_end)) ||
          (tag_type == IDE_XML_ELEMENT_TAG_END &&
          ide_xml_find_opening_element (&start,&end,
                                      &next_start,&next_end)) ||
          tag_type == IDE_XML_ELEMENT_TAG_START_END)
        {

          /*
           * All iters point to the begining of < char and the
           * beginning of > char.In our case we want to highlight everything that is
           * between those two chars.This is the reason we move one char forward
           * from the start iter
           */
          gtk_text_iter_forward_char (&start);
          gtk_text_buffer_apply_tag (GTK_TEXT_BUFFER (self->buffer),
                                     tag,
                                     &start,
                                     &end);

          if (tag_type != IDE_XML_ELEMENT_TAG_START_END)
            {
              gtk_text_iter_forward_char (&next_start);
              gtk_text_buffer_apply_tag (GTK_TEXT_BUFFER (self->buffer),
                                         tag,
                                         &next_start,
                                         &next_end);
            }

          self->has_tags = TRUE;
        }
    }

cleanup:
  self->highlight_timeout = 0;

  return G_SOURCE_REMOVE;
}
예제 #13
0
gint
wikipad_util_search (GtkTextBuffer       *buffer,
                      const gchar         *string,
                      const gchar         *replace,
                      WikipadSearchFlags  flags)
{
  gchar       *reversed = NULL;
  gint         counter = 0;
  gboolean     found, search_again = FALSE;
  gboolean     search_backwards, wrap_around;
  GtkTextIter  start, end, iter;
  GtkTextIter  match_start, match_end;
  GtkTextMark *mark_start, *mark_iter, *mark_end, *mark_replace;

  g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), -1);
  g_return_val_if_fail (string && g_utf8_validate (string, -1, NULL), -1);
  g_return_val_if_fail (replace == NULL || g_utf8_validate (replace, -1, NULL), -1);
  g_return_val_if_fail ((flags & WIKIPAD_SEARCH_FLAGS_ACTION_HIGHTLIGHT) == 0, -1);

  /* freeze buffer notifications */
  g_object_freeze_notify (G_OBJECT (buffer));

  /* get the search iters */
  wikipad_util_search_get_iters (buffer, flags, &start, &end, &iter);

  /* store the initial iters in marks */
  mark_start = gtk_text_buffer_create_mark (buffer, NULL, &start, TRUE);
  mark_iter  = gtk_text_buffer_create_mark (buffer, NULL, &iter, TRUE);
  mark_end   = gtk_text_buffer_create_mark (buffer, NULL, &end, TRUE);

  /* some to make the code easier to read */
  search_backwards = ((flags & WIKIPAD_SEARCH_FLAGS_DIR_BACKWARD) != 0);
  wrap_around = ((flags & WIKIPAD_SEARCH_FLAGS_WRAP_AROUND) != 0 && !gtk_text_iter_equal (&start, &iter));

  /* if we're not really searching anything, reset the cursor */
  if (string == NULL || *string == '\0')
    goto reset_cursor;

  if (search_backwards)
    {
      /* reverse the search string */
      reversed = g_utf8_strreverse (string, -1);

      /* set the new search string */
      string = reversed;
    }

  do
    {
      /* search the string */
      found = wikipad_util_search_iter (&iter, string, flags, &match_start, &match_end, &end);

      /* don't search again unless changed below */
      search_again = FALSE;

      if (found)
        {
          /* handle the action */
          if (flags & WIKIPAD_SEARCH_FLAGS_ACTION_SELECT)
            {
              /* select the match */
              if (! search_backwards)
                gtk_text_buffer_select_range (buffer, &match_start, &match_end);
              else
                gtk_text_buffer_select_range (buffer, &match_end, &match_start);
            }
          else if (flags & WIKIPAD_SEARCH_FLAGS_ACTION_REPLACE)
            {
              /* create text mark */
              mark_replace = gtk_text_buffer_create_mark (buffer, NULL, &match_start, search_backwards);

              /* delete the match */
              gtk_text_buffer_delete (buffer, &match_start, &match_end);

              /* restore the iter */
              gtk_text_buffer_get_iter_at_mark (buffer, &iter, mark_replace);

              /* insert the replacement */
              if (G_LIKELY (replace))
                gtk_text_buffer_insert (buffer, &iter, replace, -1);

              /* remove the mark */
              gtk_text_buffer_delete_mark (buffer, mark_replace);

              /* restore the begin and end iters */
              gtk_text_buffer_get_iter_at_mark (buffer, &start, mark_start);
              gtk_text_buffer_get_iter_at_mark (buffer, &end, mark_end);

              /* when we don't replace all matches, select the next one */
              if ((flags & WIKIPAD_SEARCH_FLAGS_ENTIRE_AREA) == 0)
                flags |= WIKIPAD_SEARCH_FLAGS_ACTION_SELECT;

              /* search again */
              search_again = TRUE;
            }
          else if (flags & WIKIPAD_SEARCH_FLAGS_ACTION_NONE)
            {
              /* keep searching when requested */
              if (flags & WIKIPAD_SEARCH_FLAGS_ENTIRE_AREA)
                search_again = TRUE;

              /* move iter */
              iter = match_end;
            }
          else
            {
              /* no valid action was defined */
              g_assert_not_reached ();
            }

          /* increase the counter */
          counter++;
        }
      else if (wrap_around)
        {
          /* get the start iter (note that the start and iter were already
           * reversed for backwards searching) */
          gtk_text_buffer_get_iter_at_mark (buffer, &iter, mark_start);

          /* get end iter */
          gtk_text_buffer_get_iter_at_mark (buffer, &end, mark_iter);

          /* we wrapped, don't try again */
          wrap_around = FALSE;

          /* search again */
          search_again = TRUE;
        }
      else
        {
          reset_cursor:

          /* get the initial start mark */
          gtk_text_buffer_get_iter_at_mark (buffer, &iter, mark_iter);

          /* reset the cursor */
          gtk_text_buffer_place_cursor (buffer, &iter);
        }
    }
  while (search_again);

  /* make sure the selection is restored */
  if (flags & WIKIPAD_SEARCH_FLAGS_AREA_SELECTION)
    gtk_text_buffer_select_range (buffer, &start, &end);

  /* cleanup */
  g_free (reversed);

  /* cleanup marks */
  gtk_text_buffer_delete_mark (buffer, mark_start);
  gtk_text_buffer_delete_mark (buffer, mark_iter);
  gtk_text_buffer_delete_mark (buffer, mark_end);

  /* thawn buffer notifications */
  g_object_thaw_notify (G_OBJECT (buffer));

  return counter;
}
예제 #14
0
static void
gb_vim_do_search_and_replace (GtkTextBuffer *buffer,
                              GtkTextIter   *begin,
                              GtkTextIter   *end,
                              const gchar   *search_text,
                              const gchar   *replace_text,
                              gboolean       is_global)
{
  GtkSourceSearchContext *search_context;
  GtkSourceSearchSettings *search_settings;
  GtkTextMark *mark;
  GtkTextIter tmp1;
  GtkTextIter tmp2;
  GtkTextIter match_begin;
  GtkTextIter match_end;
  GError *error = NULL;

  g_assert (search_text);
  g_assert (replace_text);
  g_assert ((!begin && !end) || (begin && end));

  search_settings = gtk_source_search_settings_new ();
  search_context = gtk_source_search_context_new (GTK_SOURCE_BUFFER (buffer), search_settings);

  if (!begin)
    {
      gtk_text_buffer_get_start_iter (buffer, &tmp1);
      begin = &tmp1;
    }

  if (!end)
    {
      gtk_text_buffer_get_end_iter (buffer, &tmp2);
      end = &tmp2;
    }

  mark = gtk_text_buffer_create_mark (buffer, NULL, end, FALSE);

  gtk_source_search_settings_set_search_text (search_settings, search_text);
  gtk_source_search_settings_set_case_sensitive (search_settings, TRUE);

  while (gtk_source_search_context_forward (search_context, begin, &match_begin, &match_end))
    {
      if (is_global || gb_vim_match_is_selected (buffer, &match_begin, &match_end))
        {
          GtkTextMark *mark2;

          mark2 = gtk_text_buffer_create_mark (buffer, NULL, &match_end, FALSE);

          if (!gtk_source_search_context_replace (search_context, &match_begin, &match_end,
                                                  replace_text, -1, &error))
            {
              g_warning ("%s", error->message);
              g_clear_error (&error);
              gtk_text_buffer_delete_mark (buffer, mark2);
              break;
            }

          gtk_text_buffer_get_iter_at_mark (buffer, &match_end, mark2);
          gtk_text_buffer_delete_mark (buffer, mark2);
        }

      *begin = match_end;

      gtk_text_buffer_get_iter_at_mark (buffer, end, mark);
    }

  gtk_text_buffer_delete_mark (buffer, mark);

  g_clear_object (&search_settings);
  g_clear_object (&search_context);
}
예제 #15
0
static void
request_join(InfTestGtkBrowserWindow* test,
             const gchar* user_name)
{
  InfcUserRequest* request;
  InfAdoptedStateVector* v;
  GError* error;
  GtkTextBuffer* buffer;
  GtkTextMark* mark;
  GtkTextIter iter;
  GParameter params[3] = {
    { "name", { 0 } },
    { "vector", { 0 } },
    { "caret-position", { 0 } }
  };

  g_value_init(&params[0].value, G_TYPE_STRING);
  g_value_init(&params[1].value, INF_ADOPTED_TYPE_STATE_VECTOR);
  g_value_init(&params[2].value, G_TYPE_UINT);

  g_value_set_static_string(&params[0].value, user_name);

  /* Use current state vector. Infinote should already do this. */
  v = inf_adopted_state_vector_copy(
    inf_adopted_algorithm_get_current(
      inf_adopted_session_get_algorithm(
        INF_ADOPTED_SESSION(infc_session_proxy_get_session(test->proxy))
      )
    )
  );

  g_value_take_boxed(&params[1].value, v);

  buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(test->textview));
  mark = gtk_text_buffer_get_insert(buffer);
  gtk_text_buffer_get_iter_at_mark(buffer, &iter, mark);
  g_value_set_uint(&params[2].value, gtk_text_iter_get_offset(&iter));

  error = NULL;
  request = infc_session_proxy_join_user(test->proxy, params, 3, &error);

  /* TODO: Free GValues? */

  if(request == NULL)
  {
    set_error(test, "Failed to request user join", error->message);
  }
  else
  {
    g_signal_connect_after(
      G_OBJECT(request),
      "failed",
      G_CALLBACK(on_join_failed),
      test
    );

    g_signal_connect_after(
      G_OBJECT(request),
      "finished",
      G_CALLBACK(on_join_finished),
      test
    );
  }
}