Exemplo n.º 1
0
static gunichar 
gail_notebook_page_get_character_at_offset (AtkText *text,
                                            gint    offset)
{
  GtkWidget *label;
  GailNotebookPage *notebook_page;
  const gchar *string;
  gchar *index;

  notebook_page = GAIL_NOTEBOOK_PAGE (text);
  label = get_label_from_notebook_page (notebook_page);

  if (!GTK_IS_LABEL(label))
    return '\0';
  string = gtk_label_get_text (GTK_LABEL (label));
  if (offset >= g_utf8_strlen (string, -1))
    return '\0';
  index = g_utf8_offset_to_pointer (string, offset);

  return g_utf8_get_char (index);
}
Exemplo n.º 2
0
int
utf8_display_len(const char *const str)
{
    if (!str) {
        return 0;
    }

    int len = 0;
    gchar *curr = g_utf8_offset_to_pointer(str, 0);
    while (*curr != '\0') {
        gunichar curru = g_utf8_get_char(curr);
        if (g_unichar_iswide(curru)) {
            len += 2;
        } else {
            len ++;
        }
        curr = g_utf8_next_char(curr);
    }

    return len;
}
Exemplo n.º 3
0
/* TODO: Should be perfectly possible to make this modify the string in-place */
gchar *
gdata_parser_utf8_trim_whitespace (const gchar *s)
{
	glong len;
	const gchar *_s;

	/* Skip the leading whitespace */
	while (*s != '\0' && g_unichar_isspace (g_utf8_get_char (s)))
		s = g_utf8_next_char (s);

	/* Find the end of the string and backtrack until we've passed all the whitespace */
	len = g_utf8_strlen (s, -1);
	_s = g_utf8_offset_to_pointer (s, len - 1);
	while (len > 0 && g_unichar_isspace (g_utf8_get_char (_s))) {
		_s = g_utf8_prev_char (_s);
		len--;
	}
	_s = g_utf8_next_char (_s);

	return g_strndup (s, _s - s);
}
static gboolean
endswith_helper (const gchar *ps1,
                 const gchar *ps2,
                 const gchar *region)
{
	gchar *s1 = e_util_utf8_remove_accents (ps1);
	gchar *s2 = e_util_utf8_remove_accents (ps2);
	gboolean res = FALSE;
	glong s1len = g_utf8_strlen (s1, -1);
	glong s2len = g_utf8_strlen (s2, -1);

	if (s1len < s2len)
		res = FALSE;
	else
		res = e_util_utf8_strstrcase (g_utf8_offset_to_pointer (s1, s1len - s2len), s2) != NULL;

	g_free (s1);
	g_free (s2);

	return res;
}
Exemplo n.º 5
0
Arquivo: gaillabel.c Projeto: BYC/gtk
static gunichar 
gail_label_get_character_at_offset (AtkText	         *text,
                                    gint	         offset)
{
  GtkWidget *widget;
  GtkLabel *label;
  const gchar *string;
  gchar *index;

  widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
  if (widget == NULL)
    /* State is defunct */
    return '\0';

  label = GTK_LABEL (widget);
  string = gtk_label_get_text (label);
  if (offset >= g_utf8_strlen (string, -1))
    return '\0';
  index = g_utf8_offset_to_pointer (string, offset);

  return g_utf8_get_char (index);
}
Exemplo n.º 6
0
static void
text_entry_set_cursor_position(struct text_entry *entry,
			       int32_t x, int32_t y)
{
	int index, trailing;
	const char *text;

	text_entry_commit_and_reset(entry);

	pango_layout_xy_to_index(entry->layout,
				 x * PANGO_SCALE, y * PANGO_SCALE,
				 &index, &trailing);

	text = pango_layout_get_text(entry->layout);
	entry->cursor = g_utf8_offset_to_pointer(text + index, trailing) - text;

	text_entry_update_layout(entry);

	widget_schedule_redraw(entry->widget);

	text_entry_update(entry);
}
Exemplo n.º 7
0
static gboolean on_button_release(GtkEntry      *entry,
                                  GdkEventButton *evt,
                                  gpointer        user_data)
{

    if( GDK_BUTTON_RELEASE == evt->type
            && (evt->state & GDK_CONTROL_MASK)
            && 1 == evt->button )
    {
        int pos;
        const char *text, *sep;
        char *path;

        pos = gtk_editable_get_position( GTK_EDITABLE(entry) );
        text = gtk_entry_get_text( entry );
        if( G_LIKELY( text && *text ) )
        {
            sep = g_utf8_offset_to_pointer( text, pos );
            if( G_LIKELY( sep ) )
            {
                while( *sep && *sep != '/' )
                    sep = g_utf8_next_char(sep);
                if( G_UNLIKELY( sep == text ) )
                {
                    if( '/' == *sep )
                        ++sep;
                    else
                        return FALSE;
                }
                path = g_strndup( text, (sep - text) );
                gtk_entry_set_text( entry, path );
                g_free( path );

                gtk_widget_activate( (GtkWidget*)entry );
            }
        }
    }
    return FALSE;
}
Exemplo n.º 8
0
static gboolean
st_im_text_retrieve_surrounding_cb (GtkIMContext *context,
                                    StIMText     *imtext)
{
  ClutterText *clutter_text = CLUTTER_TEXT (imtext);
  ClutterTextBuffer *buffer;
  const gchar *text;
  gint cursor_pos;

  buffer = clutter_text_get_buffer (clutter_text);
  text = clutter_text_buffer_get_text (buffer);

  cursor_pos = clutter_text_get_cursor_position (clutter_text);
  if (cursor_pos < 0)
    cursor_pos = clutter_text_buffer_get_length (buffer);

  gtk_im_context_set_surrounding (context, text,
                                  /* length and cursor_index are in bytes */
                                  clutter_text_buffer_get_bytes (buffer),
                                  g_utf8_offset_to_pointer (text, cursor_pos) - text);

  return TRUE;
}
static gchar *gfire_sq_ase_fixed_len_string(const gchar *p_str, guint p_len)
{
	if(!p_str)
		return NULL;

	// Pad the string with spaces if necessary
	if(g_utf8_strlen(p_str, -1) < p_len)
	{
		gchar *str = g_strnfill(p_len + strlen(p_str) - g_utf8_strlen(p_str, -1), ' ');
		memcpy(str, p_str, strlen(p_str));
		return str;
	}
	// Copy max p_len bytes
	else if(g_utf8_strlen(p_str, -1) > p_len)
	{
		const gchar *end = g_utf8_offset_to_pointer(p_str, p_len - 3);
		gchar *str = g_strnfill(end - p_str + 3, '.');
		memcpy(str, p_str, end - p_str);
		return str;
	}
	else
		return g_strdup(p_str);
}
Exemplo n.º 10
0
char *gui_entry_get_text_and_pos(GUI_ENTRY_REC *entry, int *pos)
{
	char *buf;
        int i;

	g_return_val_if_fail(entry != NULL, NULL);

	if (entry->utf8) {
		buf = g_ucs4_to_utf8(entry->text, -1, NULL, NULL, NULL);
		*pos = g_utf8_offset_to_pointer(buf, entry->pos) - buf;
	} else {
		buf = g_malloc(entry->text_len*6 + 1);
		if(term_type==TERM_TYPE_BIG5)
			unichars_to_big5_with_pos(entry->text, entry->pos, buf, pos);
		else
		{
			for (i = 0; i <= entry->text_len; i++)
				buf[i] = entry->text[i];
			*pos = entry->pos;
		}
	}
	return buf;
}
Exemplo n.º 11
0
static void
text_entry_set_cursor_position(struct text_entry *entry,
			       int32_t x, int32_t y,
			       bool move_anchor)
{
	int index, trailing;
	const char *text;
	uint32_t cursor;

	pango_layout_xy_to_index(entry->layout,
				 x * PANGO_SCALE, y * PANGO_SCALE,
				 &index, &trailing);

	text = pango_layout_get_text(entry->layout);

	cursor = g_utf8_offset_to_pointer(text + index, trailing) - text;

	if (move_anchor)
		entry->anchor = cursor;

	if (text_entry_has_preedit(entry)) {
		text_entry_commit_and_reset(entry);

		assert(!text_entry_has_preedit(entry));
	}

	if (entry->cursor == cursor)
		return;

	entry->cursor = cursor;

	text_entry_update_layout(entry);

	widget_schedule_redraw(entry->widget);

	text_entry_update(entry);
}
Exemplo n.º 12
0
/*  Determine where, if at all, a UTF8 substring occurs within another
 *  UTF8 string.  Return a pointer to the start of the substring, or
 *  NULL if not found.
 */
static gchar*
find_utf8_substr(gchar *str, gchar *substr) {
    /*  record the first character of substr for scanning  */
    gunichar first = g_utf8_get_char(substr) ;
    /*  record the collation key for substr for comparison  */
    gchar* substr_key = g_utf8_collate_key(substr, -1) ;
    /*  record the length of substr, in bytes, for comparison.  do this by finding the length, in utf8 characters, converting that to a pointer, then using pointer arithmetic to find the byte length.  */
    gssize len = g_utf8_offset_to_pointer(substr, g_utf8_strlen(substr, -1)) - substr ;
    /*  scan the string looking for 'first'  */
    for (
            /*  start at the first occurrence of 'first'  */
            str = g_utf8_strchr(str, -1, first) ;
            /*  continue as long as 'first' was found  */
            str != NULL ;
            /*  for the next iteration, advance to the next occurrence
             *  of 'first'
             */
            str = g_utf8_strchr(g_utf8_next_char(str), -1, first)
    ) {
        /*  compute the collation key for the 'len'-length
         *  substring located at 'str'
         */
        gchar* this_key = g_utf8_collate_key(str, len) ;
        /*  get our comparison value  */
        int  this_comp = strcmp(substr_key, this_key) ;
        /*  free the collation key  */
        g_free(this_key) ;
        /*  if comparison was 0 (equal), break out of the scan loop  */
        if (this_comp == 0) {
            break ; /* out of for(...) loop */
        }
    }
    /*  free up the collation key  */
    g_free(substr_key) ;
    /*  return the result  */
    return(str) ;
}
Exemplo n.º 13
0
/* Strips out all occurances of thousands separators. */
gint
planner_parse_int (const gchar *str)
{
	GString      *tmp;
	const gchar  *p;
	gint          value;
	struct lconv *locality;
	gint          sep_len;

	if (!str || !str[0]) {
		return 0;
	}

	locality = localeconv ();
	sep_len = strlen (locality->thousands_sep);

	if (sep_len == 0) {
		return atoi (str);
	}

	tmp = g_string_new (NULL);

	p = str;
	while (*p) {
		if (strncmp (p, locality->thousands_sep, sep_len) == 0) {
			p = g_utf8_offset_to_pointer (p, sep_len);
		} else {
			g_string_append_unichar (tmp, g_utf8_get_char (p));
			p = g_utf8_next_char (p);
		}
	}

	value = atoi (tmp->str);
	g_string_free (tmp, TRUE);

	return value;
}
Exemplo n.º 14
0
/**
 * ephy_string_shorten: shortens a string
 * @str: the string to shorten, in UTF-8
 * @target_length: the length of the shortened string (in characters)
 *
 * If @str is already short enough, it is returned. Otherwise a new string
 * is allocated and @str is consumed.
 *
 * Return value: a newly allocated string, not longer than target_length
 * characters.
 */
char *
ephy_string_shorten (char *str,
                     gsize target_length)
{
  char *new_str;
  glong actual_length;
  gulong bytes;

  g_return_val_if_fail (target_length > 0, NULL);

  if (!str)
    return NULL;

  /* FIXME: this function is a big mess. While it is utf-8 safe now,
   * it can still split a sequence of combining characters.
   */
  actual_length = g_utf8_strlen (str, -1);

  /* if the string is already short enough, or if it's too short for
   * us to shorten it, return a new copy */
  if ((gsize)actual_length <= target_length)
    return str;

  /* create string */
  bytes = GPOINTER_TO_UINT (g_utf8_offset_to_pointer (str, target_length - 1) - str);

  new_str = g_new (gchar, bytes + strlen (ELLIPSIS) + 1);

  strncpy (new_str, str, bytes);
  strncpy (new_str + bytes, ELLIPSIS, strlen (ELLIPSIS));
  new_str[bytes + strlen (ELLIPSIS)] = '\0';

  g_free (str);

  return new_str;
}
Exemplo n.º 15
0
static gunichar
gtk_icon_view_item_accessible_get_character_at_offset (AtkText *text,
                                                       gint     offset)
{
  GtkIconViewItemAccessible *item;
  gchar *string;
  gchar *index;

  item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (text);
  if (atk_state_set_contains_state (item->state_set, ATK_STATE_DEFUNCT))
    return '\0';

  string = item->text;

  if (!string)
    return '\0';

  if (offset >= g_utf8_strlen (string, -1))
    return '\0';

  index = g_utf8_offset_to_pointer (string, offset);

  return g_utf8_get_char (index);
}
Exemplo n.º 16
0
void
gnc_basic_cell_insert_decimal(BasicCell *bcell,
                              char decimal_point,
                              int *cursor_position,
                              int *start_selection,
                              int *end_selection)
{
    GString *newval_gs;
    gint start, end;
    gchar *buf;

    /* allocate space for newval_ptr : oldval + one letter ( the
       decimal_point ) */
    newval_gs = g_string_new("");

    start = MIN(*start_selection, *end_selection);
    end = MAX(*start_selection, *end_selection);

    /* length in bytes, not chars. do not use g_utf8_strlen. */
    buf = g_malloc0(strlen(bcell->value) + 1);
    g_utf8_strncpy(buf, bcell->value, start);
    g_string_append(newval_gs, buf);
    g_free(buf);

    g_string_append_unichar(newval_gs, decimal_point);

    buf = g_utf8_offset_to_pointer(bcell->value, end);
    g_string_append(newval_gs, buf);

    /* update the cursor position */
    *cursor_position = start + 1;

    gnc_basic_cell_set_value_internal (bcell, newval_gs->str);

    g_string_free (newval_gs, TRUE);
}
Exemplo n.º 17
0
static gboolean
on_entry_draw (GtkWidget *widget,
               cairo_t   *cr,
               gpointer   user_data)
{
  g_debug (G_STRLOC ": %s", G_STRFUNC);

  GtkStyleContext *style_context;
  PangoContext    *pango_context;
  PangoLayout     *layout;
  const char      *text;
  gint             cursor_index;
  gint             x, y;

  style_context = gtk_widget_get_style_context (widget);
  pango_context = gtk_widget_get_pango_context (widget);
  layout = gtk_entry_get_layout (GTK_ENTRY (widget));
  text = pango_layout_get_text (layout);
  gtk_entry_get_layout_offsets (GTK_ENTRY (widget), &x, &y);
  cursor_index = g_utf8_offset_to_pointer (text, gtk_editable_get_position (GTK_EDITABLE (widget))) - text;
  gtk_render_insertion_cursor (style_context, cr, x, y, layout, cursor_index,
                               pango_context_get_base_dir (pango_context));
  return FALSE;
}
Exemplo n.º 18
0
static void midorator_entry_history_down(MidoratorEntry* e) {
	const char *full = gtk_entry_get_text(GTK_ENTRY(e));
	guint pos = gtk_editable_get_position(GTK_EDITABLE(e));
	char *prefix = g_strndup(full, g_utf8_offset_to_pointer(full, pos) - full);
	bool pre = strlen(prefix) == strlen(full);
	KatzeArray *c = e->command_history;
	if (!c)
		return;
	if (!katze_array_is_a(c, G_TYPE_STRING))
		return;
	int i, l = katze_array_get_length(c);
	char *found = NULL;
	for (i = l - 1; i >= 0; i--) {
		char *item = katze_array_get_nth_item(c, i);
		if (!pre && strcmp(item, full) == 0)
			break;
		else if (g_str_has_prefix(item, prefix) && strlen(item) != strlen(prefix))
			found = item;
	}
	if (found) {
		gtk_entry_set_text(GTK_ENTRY(e), found);
		gtk_editable_set_position(GTK_EDITABLE(e), pos);
	}
}
Exemplo n.º 19
0
static void
nimf_m17n_update_candidate (NimfEngine    *engine,
                            NimfServiceIC *target)
{
  g_debug (G_STRLOC ": %s", G_STRFUNC);

  NimfM17n *m17n = NIMF_M17N (engine);

  nimf_candidatable_clear (m17n->candidatable, target);

  MPlist *page;
  m17n->current_page = m17n->ic->candidate_index / 10 + 1;
  m17n->n_pages = 0;

  for (page = m17n->ic->candidate_list;
       page && mplist_key (page) != Mnil;
       page = mplist_next (page))
  {
    MSymbol type = mplist_key (page);
    m17n->n_pages++;

    if (m17n->current_page != m17n->n_pages)
      continue;

    if (type == Mplist)
    {
      MPlist *items;

      for (items = mplist_value (page);
           items && mplist_key (items) != Mnil;
           items = mplist_next (items))
      {
        gchar *item;

        item = nimf_m17n_mtext_to_utf8 (m17n, mplist_value (items));
        nimf_candidatable_append (m17n->candidatable, item, NULL);

        g_free (item);
      }
    }
    else if (type == Mtext)
    {
      gchar *items;
      gint   i, len;

      items = nimf_m17n_mtext_to_utf8 (m17n, (MText *) mplist_value (page));
      len   = g_utf8_strlen (items, -1);

      for (i = 0; i < len; i++)
      {
        gchar  item[4];
        gchar *p = g_utf8_offset_to_pointer (items, i);
        g_utf8_strncpy (item, p, 1);
        nimf_candidatable_append (m17n->candidatable, item, NULL);
      }

      g_free (items);
    }
  }

  nimf_candidatable_select_item_by_index_in_page (m17n->candidatable,
                                                  m17n->ic->candidate_index % 10);
  nimf_candidatable_set_page_values (m17n->candidatable, target,
                                     m17n->current_page, m17n->n_pages, 10);
}
Exemplo n.º 20
0
void Font::drawComplexText(GraphicsContext* context, const TextRun& run, const FloatPoint& point, int from, int to) const
{
#if USE(FREETYPE)
    if (!primaryFont()->platformData().m_pattern) {
        drawSimpleText(context, run, point, from, to);
        return;
    }
#endif

    cairo_t* cr = context->platformContext()->cr();
    PangoLayout* layout = pango_cairo_create_layout(cr);
    setPangoAttributes(this, run, layout);

    gchar* utf8 = convertUniCharToUTF8(run.characters(), run.length(), 0, run.length());
    pango_layout_set_text(layout, utf8, -1);

    // Our layouts are single line
    PangoLayoutLine* layoutLine = pango_layout_get_line_readonly(layout, 0);

    // Get the region where this text will be laid out. We will use it to clip
    // the Cairo context, for when we are only painting part of the text run and
    // to calculate the size of the shadow buffer.
    PangoRegionType partialRegion = 0;
    char* start = g_utf8_offset_to_pointer(utf8, from);
    char* end = g_utf8_offset_to_pointer(start, to - from);
    int ranges[] = {start - utf8, end - utf8};
#if PLATFORM(GTK)
    partialRegion = gdk_pango_layout_line_get_clip_region(layoutLine, 0, 0, ranges, 1);
#else
    partialRegion = getClipRegionFromPangoLayoutLine(layoutLine, ranges);
#endif

    drawGlyphsShadow(context, point, layoutLine, partialRegion);

    cairo_save(cr);
    cairo_translate(cr, point.x(), point.y());

    float red, green, blue, alpha;
    context->fillColor().getRGBA(red, green, blue, alpha);
    cairo_set_source_rgba(cr, red, green, blue, alpha);
#if PLATFORM(GTK)
    gdk_cairo_region(cr, partialRegion);
#else
    appendRegionToCairoContext(cr, partialRegion);
#endif
    cairo_clip(cr);

    pango_cairo_show_layout_line(cr, layoutLine);

    if (context->textDrawingMode() & TextModeStroke) {
        Color strokeColor = context->strokeColor();
        strokeColor.getRGBA(red, green, blue, alpha);
        cairo_set_source_rgba(cr, red, green, blue, alpha);
        pango_cairo_layout_line_path(cr, layoutLine);
        cairo_set_line_width(cr, context->strokeThickness());
        cairo_stroke(cr);
    }

    // Pango sometimes leaves behind paths we don't want
    cairo_new_path(cr);

    destroyPangoRegion(partialRegion);
    g_free(utf8);
    g_object_unref(layout);

    cairo_restore(cr);
}
/* Draw method handler for the icon text item */
static void
mate_icon_text_item_draw (MateCanvasItem *item, GdkDrawable *drawable,
                          int x, int y, int width, int height)
{
    GtkWidget *widget;
    GtkStyle *style;
    int xofs, yofs;
    int text_xofs, text_yofs;
    int w, h;
    MateIconTextItem *iti;
    MateIconTextItemPrivate *priv;
    GtkStateType state;

    widget = GTK_WIDGET (item->canvas);
    iti = MATE_ICON_TEXT_ITEM (item);
    priv = iti->_priv;

    style = GTK_WIDGET (MATE_CANVAS_ITEM (iti)->canvas)->style;

    w = priv->layout_width + 2 * MARGIN_X;
    h = priv->layout_height + 2 * MARGIN_Y;

    xofs = item->x1 - x;
    yofs = item->y1 - y;

    text_xofs = xofs - (iti->width - priv->layout_width - 2 * MARGIN_X) / 2;
    text_yofs = yofs + MARGIN_Y;

    if (iti->selected && GTK_WIDGET_HAS_FOCUS (widget))
        state = GTK_STATE_SELECTED;
    else if (iti->selected)
        state = GTK_STATE_ACTIVE;
    else
        state = GTK_STATE_NORMAL;

    if (iti->selected && !iti->editing)
        gdk_draw_rectangle (drawable,
                            style->base_gc[state],
                            TRUE,
                            xofs + 1, yofs + 1,
                            w - 2, h - 2);

    if (GTK_WIDGET_HAS_FOCUS (widget) && iti->focused && ! iti->editing) {
        GdkRectangle r;

        r.x = xofs;
        r.y = yofs;
        r.width = w - 1;
        r.height = h - 1;
        gtk_paint_focus (style, drawable,
                         iti->selected ? GTK_STATE_SELECTED: GTK_STATE_NORMAL,
                         &r, widget, NULL,
                         xofs, yofs, w - 1, h - 1);
#if 0
        gtk_draw_focus (style,
                        drawable,
                        xofs, yofs,
                        w - 1, h - 1);
#endif
    }

    if (iti->editing) {
        /* FIXME: are these the right graphics contexts? */
        gdk_draw_rectangle (drawable,
                            style->base_gc[GTK_STATE_NORMAL],
                            TRUE,
                            xofs, yofs, w - 1, h - 1);
        gdk_draw_rectangle (drawable,
                            style->fg_gc[GTK_STATE_NORMAL],
                            FALSE,
                            xofs, yofs, w - 1, h - 1);
    }

    gdk_draw_layout (drawable,
                     style->text_gc[iti->editing ? GTK_STATE_NORMAL : state],
                     text_xofs,
                     text_yofs,
                     priv->layout);

    if (iti->editing) {
        int range[2];
        if (gtk_editable_get_selection_bounds (GTK_EDITABLE (priv->entry), &range[0], &range[1])) {
            GdkRegion *clip_region;
            GdkColor *selection_color, *text_color;
            guint8 state;

            range[0] = g_utf8_offset_to_pointer (GTK_ENTRY (priv->entry)->text, range[0]) - GTK_ENTRY (priv->entry)->text;
            range[1] = g_utf8_offset_to_pointer (GTK_ENTRY (priv->entry)->text, range[1]) - GTK_ENTRY (priv->entry)->text;

            state = GTK_WIDGET_HAS_FOCUS (widget) ? GTK_STATE_SELECTED : GTK_STATE_ACTIVE;
            selection_color = &widget->style->base[state];
            text_color = &widget->style->text[state];
            clip_region = gdk_pango_layout_get_clip_region
                          (priv->layout,
                           text_xofs,
                           text_yofs,
                           range, 1);
            gdk_gc_set_clip_region (widget->style->black_gc,
                                    clip_region);
            gdk_draw_layout_with_colors (drawable,
                                         widget->style->black_gc,
                                         text_xofs,
                                         text_yofs,
                                         priv->layout,
                                         text_color,
                                         selection_color);
            gdk_gc_set_clip_region (widget->style->black_gc, NULL);
            gdk_region_destroy (clip_region);
        } else {
            iti_draw_cursor (iti, drawable, text_xofs, text_yofs);
        }
    }
}
Exemplo n.º 22
0
static void
gnc_quickfill_remove_recursive (QuickFill *qf, const gchar *text, gint depth,
                                QuickFillSort sort)
{
    QuickFill *match_qf;
    gchar *child_text;
    gint child_len;

    child_text = NULL;
    child_len = 0;

    if (depth < g_utf8_strlen (text, -1))
    {
        /* process next letter */

        gchar *key_char;
        gunichar key_char_uc;
        guint key;

        key_char = g_utf8_offset_to_pointer (text, depth);
        key_char_uc = g_utf8_get_char (key_char);
        key = g_unichar_toupper (key_char_uc);

        match_qf = g_hash_table_lookup (qf->matches, GUINT_TO_POINTER (key));
        if (match_qf)
        {
            /* remove text from child qf */
            gnc_quickfill_remove_recursive (match_qf, text, depth + 1, sort);

            if (match_qf->text == NULL)
            {
                /* text was the only word with a prefix up to match_qf */
                g_hash_table_remove (qf->matches, GUINT_TO_POINTER (key));
                gnc_quickfill_destroy (match_qf);

            }
            else
            {
                /* remember remaining best child string */
                child_text = match_qf->text;
                child_len = match_qf->len;
            }
        }
    }

    if (qf->text == NULL)
        return;

    if (strcmp (text, qf->text) == 0)
    {
        /* the currently best text is about to be removed */

        gchar *best_text = NULL;
        gint best_len = 0;

        if (child_text != NULL)
        {
            /* other children are pretty good as well */
            best_text = child_text;
            best_len = child_len;

        }
        else
        {
            if (g_hash_table_size (qf->matches) != 0)
            {
                /* otherwise search for another good text */
                struct _BestText bts;
                bts.text = NULL;
                bts.sort = sort;

                g_hash_table_foreach (qf->matches, (GHFunc) best_text_helper, &bts);
                best_text = bts.text;
                best_len = (best_text == NULL) ? 0 : g_utf8_strlen (best_text, -1);
            }
        }

        /* now replace or clear text */
        CACHE_REMOVE(qf->text);
        if (best_text != NULL)
        {
            qf->text = CACHE_INSERT((gpointer) best_text);
            qf->len = best_len;
        }
        else
        {
            qf->text = NULL;
            qf->len = 0;
        }
    }
}
Exemplo n.º 23
0
static void
quickfill_insert_recursive (QuickFill *qf, const char *text, int depth,
                            QuickFillSort sort)
{
    guint key;
    char *old_text;
    QuickFill *match_qf;
    int len;
    char *key_char;
    gunichar key_char_uc;

    if (qf == NULL)
        return;

    if ((text == NULL) || (g_utf8_strlen (text, -1) <= depth))
        return;

    key_char = g_utf8_offset_to_pointer (text, depth);

    key_char_uc = g_utf8_get_char (key_char);
    key = g_unichar_toupper (key_char_uc);

    match_qf = g_hash_table_lookup (qf->matches, GUINT_TO_POINTER (key));
    if (match_qf == NULL)
    {
        match_qf = gnc_quickfill_new ();
        g_hash_table_insert (qf->matches, GUINT_TO_POINTER (key), match_qf);
    }

    old_text = match_qf->text;

    switch (sort)
    {
    case QUICKFILL_ALPHA:
        if (old_text && (g_utf8_collate (text, old_text) >= 0))
            break;
        /* fall through */

    case QUICKFILL_LIFO:
    default:
        len = g_utf8_strlen (text, -1);

        /* If there's no string there already, just put the new one in. */
        if (old_text == NULL)
        {
            match_qf->text = CACHE_INSERT((gpointer) text);
            match_qf->len = len;
            break;
        }

        /* Leave prefixes in place */
        if ((len > match_qf->len) &&
                (strncmp(text, old_text, strlen(old_text)) == 0))
            break;

        CACHE_REMOVE(old_text);
        match_qf->text = CACHE_INSERT((gpointer) text);
        match_qf->len = len;
        break;
    }

    quickfill_insert_recursive (match_qf, text, ++depth, sort);
}
Exemplo n.º 24
0
static inline glong
offset_to_len (const char *str, glong offset)
{
	return g_utf8_offset_to_pointer (str, offset) - str;
}
NS_IMETHODIMP 
sbStringTransformImpl::NormalizeString(const nsAString & aCharset, 
                                       PRUint32 aTransformFlags, 
                                       const nsAString & aInput, 
                                       nsAString & _retval)
{
  nsCString str;
  CopyUTF16toUTF8(aInput, str);

  if(aTransformFlags & sbIStringTransform::TRANSFORM_LOWERCASE) {
    gchar* lowercaseStr = g_utf8_strdown(str.BeginReading(), str.Length());
    NS_ENSURE_TRUE(lowercaseStr, NS_ERROR_OUT_OF_MEMORY);
    str.Assign(lowercaseStr);
    g_free(lowercaseStr);
  }

  if(aTransformFlags & sbIStringTransform::TRANSFORM_UPPERCASE) {
    gchar* uppercaseStr = g_utf8_strup(str.BeginReading(), str.Length());
    NS_ENSURE_TRUE(uppercaseStr, NS_ERROR_OUT_OF_MEMORY);
    str.Assign(uppercaseStr);
    g_free(uppercaseStr);
  }

  if(aTransformFlags & sbIStringTransform::TRANSFORM_IGNORE_NONSPACE) {
    nsString workingStr;

    PRBool leadingOnly = aTransformFlags & 
                         sbIStringTransform::TRANSFORM_IGNORE_LEADING;
    PRBool bypassTest = PR_FALSE;

    gchar* nonspaceStr = g_utf8_normalize(str.BeginReading(), 
                                          str.Length(), 
                                          G_NORMALIZE_ALL);
    NS_ENSURE_TRUE(nonspaceStr, NS_ERROR_OUT_OF_MEMORY);

    glong strLen = g_utf8_strlen(nonspaceStr, -1);
    
    for(glong currentChar = 0; currentChar < strLen; ++currentChar) {

      gchar* offset = g_utf8_offset_to_pointer(nonspaceStr, currentChar);
      gunichar unichar = g_utf8_get_char(offset);
      GUnicodeType unicharType = g_unichar_type(unichar);

      if(bypassTest ||
         (unicharType != G_UNICODE_NON_SPACING_MARK && 
          unicharType != G_UNICODE_COMBINING_MARK &&
          unicharType != G_UNICODE_ENCLOSING_MARK)) {
        workingStr += unichar;
        if(leadingOnly)
          bypassTest = PR_TRUE;
      }
    }

    g_free(nonspaceStr);
    CopyUTF16toUTF8(workingStr, str);
  }

  if(aTransformFlags & sbIStringTransform::TRANSFORM_IGNORE_SYMBOLS) {
    nsString workingStr;

    PRBool leadingOnly = aTransformFlags & 
                         sbIStringTransform::TRANSFORM_IGNORE_LEADING;
    PRBool bypassTest = PR_FALSE;

    gchar* nosymbolsStr = g_utf8_normalize(str.BeginReading(), 
                                           str.Length(), 
                                           G_NORMALIZE_ALL);
    NS_ENSURE_TRUE(nosymbolsStr, NS_ERROR_OUT_OF_MEMORY);

    glong strLen = g_utf8_strlen(nosymbolsStr, -1);
    
    for(glong currentChar = 0; currentChar < strLen; ++currentChar) {
      gchar* offset = g_utf8_offset_to_pointer(nosymbolsStr, currentChar);
      gunichar unichar = g_utf8_get_char(offset);
      GUnicodeType unicharType = g_unichar_type(unichar);

      if (aTransformFlags & sbIStringTransform::TRANSFORM_IGNORE_KEEPNUMBERSYMBOLS) {
        PRInt32 numberLength;
        SB_ExtractLeadingNumber((const gchar *)offset, NULL, NULL, &numberLength);
        if (numberLength > 0) {
          for (glong copychar=0;copychar < numberLength;copychar++) {
            gchar* copyoffset = g_utf8_offset_to_pointer(nosymbolsStr, currentChar+copychar);
            gunichar unichar = g_utf8_get_char(copyoffset);
            workingStr += unichar;
          }
          currentChar += numberLength-1;
          if(leadingOnly)
            bypassTest = PR_TRUE;
          continue;
        }
      }

      if(bypassTest ||
         (unicharType != G_UNICODE_CURRENCY_SYMBOL &&
          unicharType != G_UNICODE_MODIFIER_SYMBOL &&
          unicharType != G_UNICODE_MATH_SYMBOL &&
          unicharType != G_UNICODE_OTHER_SYMBOL)) {
        workingStr += unichar;
        if(leadingOnly)
          bypassTest = PR_TRUE;
      }
    }

    g_free(nosymbolsStr);
    CopyUTF16toUTF8(workingStr, str); 
  }

  if((aTransformFlags & sbIStringTransform::TRANSFORM_IGNORE_NONALPHANUM) ||
     (aTransformFlags & sbIStringTransform::TRANSFORM_IGNORE_NONALPHANUM_IGNORE_SPACE)) {
    nsString workingStr;

    PRBool leadingOnly = aTransformFlags & 
                         sbIStringTransform::TRANSFORM_IGNORE_LEADING;
    PRBool bypassTest = PR_FALSE;

    gchar* nosymbolsStr = g_utf8_normalize(str.BeginReading(), 
                                           str.Length(), 
                                           G_NORMALIZE_ALL);
    NS_ENSURE_TRUE(nosymbolsStr, NS_ERROR_OUT_OF_MEMORY);

    glong strLen = g_utf8_strlen(nosymbolsStr, -1);
    
    for(glong currentChar = 0; currentChar < strLen; ++currentChar) {

      gchar* offset = g_utf8_offset_to_pointer(nosymbolsStr, currentChar);
      gunichar unichar = g_utf8_get_char(offset);
      GUnicodeType unicharType = g_unichar_type(unichar);

      if (aTransformFlags & sbIStringTransform::TRANSFORM_IGNORE_KEEPNUMBERSYMBOLS) {
        PRInt32 numberLength;
        SB_ExtractLeadingNumber((const gchar *)offset, NULL, NULL, &numberLength);
        if (numberLength > 0) {
          for (glong copychar=0;copychar < numberLength;copychar++) {
            gchar* copyoffset = g_utf8_offset_to_pointer(nosymbolsStr, currentChar+copychar);
            gunichar unichar = g_utf8_get_char(copyoffset);
            workingStr += unichar;
          }
          currentChar += numberLength-1;
          if(leadingOnly)
            bypassTest = PR_TRUE;
          continue;
        }
      }

      if(bypassTest ||
         (unicharType == G_UNICODE_LOWERCASE_LETTER ||
          unicharType == G_UNICODE_MODIFIER_LETTER ||
          unicharType == G_UNICODE_OTHER_LETTER ||
          unicharType == G_UNICODE_TITLECASE_LETTER ||
          unicharType == G_UNICODE_UPPERCASE_LETTER ||
          unicharType == G_UNICODE_DECIMAL_NUMBER ||
          unicharType == G_UNICODE_LETTER_NUMBER ||
          unicharType == G_UNICODE_OTHER_NUMBER) ||
          (!(aTransformFlags & sbIStringTransform::TRANSFORM_IGNORE_NONALPHANUM_IGNORE_SPACE) && 
            unichar == ' ')) {
        workingStr += unichar;
        if(leadingOnly)
          bypassTest = PR_TRUE;
      }
    }

    g_free(nosymbolsStr);
    CopyUTF16toUTF8(workingStr, str);
  }

  CopyUTF8toUTF16(str, _retval);

  return NS_OK;
}
Exemplo n.º 26
0
static AtkAttributeSet *
get_run_attributes (PangoAttrList   *attrs,
		    const gchar     *text,
		    gint             offset,
		    gint            *start_offset,
		    gint            *end_offset)
{
	AtkAttributeSet   *atk_attr_set = NULL;
	PangoAttrString   *pango_string;
	PangoAttrInt      *pango_int;
	PangoAttrColor    *pango_color;
	PangoAttrIterator *iter;
	gint               i, start, end;
	gboolean           has_attrs = FALSE;
	glong              text_length;
	gchar             *attr_value;

	text_length = g_utf8_strlen (text, -1);
	if (offset < 0 || offset >= text_length)
		return NULL;

	/* Check if there are attributes for the offset,
	 * and set the attributes range if positive */
	iter = pango_attr_list_get_iterator (attrs);
	i = g_utf8_offset_to_pointer (text, offset) - text;

	do {
		pango_attr_iterator_range (iter, &start, &end);
		if (i >= start && i < end) {
			*start_offset = g_utf8_pointer_to_offset (text, text + start);
			if (end == G_MAXINT) /* Last iterator */
				end = text_length;
			*end_offset = g_utf8_pointer_to_offset (text, text + end);
			 has_attrs = TRUE;
		}
	} while (!has_attrs && pango_attr_iterator_next (iter));

	if (!has_attrs) {
		pango_attr_iterator_destroy (iter);
		return NULL;
	}

	/* Create the AtkAttributeSet from the Pango attributes */
	pango_string = (PangoAttrString *) pango_attr_iterator_get (iter, PANGO_ATTR_FAMILY);
	if (pango_string) {
		attr_value = g_strdup (pango_string->value);
		atk_attr_set = add_attribute (atk_attr_set, ATK_TEXT_ATTR_FAMILY_NAME, attr_value);
	}

	pango_int = (PangoAttrInt *) pango_attr_iterator_get (iter, PANGO_ATTR_SIZE);
	if (pango_int) {
		attr_value = g_strdup_printf ("%i", pango_int->value / PANGO_SCALE);
		atk_attr_set = add_attribute (atk_attr_set, ATK_TEXT_ATTR_SIZE, attr_value);
	}

	pango_int = (PangoAttrInt *) pango_attr_iterator_get (iter, PANGO_ATTR_UNDERLINE);
	if (pango_int) {
		atk_attr_set = add_attribute (atk_attr_set,
					      ATK_TEXT_ATTR_UNDERLINE,
					      g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_UNDERLINE,
										      pango_int->value)));
	}

	pango_color = (PangoAttrColor *) pango_attr_iterator_get (iter, PANGO_ATTR_FOREGROUND);
	if (pango_color) {
		attr_value = g_strdup_printf ("%u,%u,%u",
					      pango_color->color.red,
					      pango_color->color.green,
					      pango_color->color.blue);
		atk_attr_set = add_attribute (atk_attr_set, ATK_TEXT_ATTR_FG_COLOR, attr_value);
	}

	pango_attr_iterator_destroy (iter);

	return atk_attr_set;
}
void scim_bridge_client_imcontext_set_preedit_attributes (ScimBridgeClientIMContext *imcontext, ScimBridgeAttribute** const preedit_attributes, int attribute_count)
{   
    if (imcontext->preedit_attributes != NULL)
        pango_attr_list_unref (imcontext->preedit_attributes);
    
    imcontext->preedit_attributes = pango_attr_list_new ();
    
    int preedit_string_length = 0;
    int preedit_wstring_length = 0;
    if (imcontext->preedit_string != NULL) {
        preedit_string_length = strlen (imcontext->preedit_string);
        preedit_wstring_length = g_utf8_strlen (imcontext->preedit_string, -1);
    }
    
    boolean *has_attribute = alloca (sizeof (boolean) * preedit_string_length);
    int i;
    for (i = 0; i < preedit_string_length; ++i) {
        has_attribute[i] = FALSE;
    }

    for (i = 0; i < attribute_count; ++i) {
        const ScimBridgeAttribute *attr = preedit_attributes[i];
        const int begin_pos = scim_bridge_attribute_get_begin (attr);
        const int end_pos = scim_bridge_attribute_get_end (attr);

        if (begin_pos <= end_pos && 0 <= begin_pos && end_pos <= preedit_wstring_length) {
            const int start_index = g_utf8_offset_to_pointer (imcontext->preedit_string, begin_pos) - imcontext->preedit_string;
            const int end_index = g_utf8_offset_to_pointer (imcontext->preedit_string, end_pos) - imcontext->preedit_string;

            const scim_bridge_attribute_type_t attr_type = scim_bridge_attribute_get_type (attr);
            const scim_bridge_attribute_value_t attr_value = scim_bridge_attribute_get_value (attr);

            boolean valid_attribute = FALSE;
            if (attr_type == ATTRIBUTE_DECORATE) {
                if (attr_value == SCIM_BRIDGE_ATTRIBUTE_DECORATE_UNDERLINE) {
                    valid_attribute = TRUE;

                    PangoAttribute *pango_attr = pango_attr_underline_new (PANGO_UNDERLINE_SINGLE);
                    pango_attr->start_index = start_index;
                    pango_attr->end_index = end_index;
                    pango_attr_list_insert (imcontext->preedit_attributes, pango_attr);
                } else if (attr_value == SCIM_BRIDGE_ATTRIBUTE_DECORATE_REVERSE) {
                    valid_attribute = TRUE;

                    PangoAttribute *pango_attr0 = pango_attr_foreground_new (preedit_normal_background.red, preedit_normal_background.green, preedit_normal_background.blue);
                    pango_attr0->start_index = start_index;
                    pango_attr0->end_index = end_index;
                    pango_attr_list_insert (imcontext->preedit_attributes, pango_attr0);

                    PangoAttribute *pango_attr1 = pango_attr_background_new (preedit_normal_foreground.red, preedit_normal_foreground.green, preedit_normal_foreground.blue);
                    pango_attr1->start_index = start_index;
                    pango_attr1->end_index = end_index;
                    pango_attr_list_insert (imcontext->preedit_attributes, pango_attr1);
                } else if (attr_value == SCIM_BRIDGE_ATTRIBUTE_DECORATE_HIGHLIGHT) {
                    valid_attribute = TRUE;

                    PangoAttribute *pango_attr0 = pango_attr_foreground_new (preedit_active_foreground.red, preedit_active_foreground.green, preedit_active_foreground.blue);
                    pango_attr0->start_index = start_index;
                    pango_attr0->end_index = end_index;
                    pango_attr_list_insert (imcontext->preedit_attributes, pango_attr0);

                    PangoAttribute *pango_attr1 = pango_attr_background_new (preedit_active_background.red, preedit_active_background.green, preedit_active_background.blue);
                    pango_attr1->start_index = start_index;
                    pango_attr1->end_index = end_index;
                    pango_attr_list_insert (imcontext->preedit_attributes, pango_attr1);
                } else {
                    scim_bridge_perrorln ("Unknown preedit decoration!");
                }
            } else if (attr_type == ATTRIBUTE_FOREGROUND) {
                valid_attribute = TRUE;

                const unsigned int red = scim_bridge_attribute_get_red (attr) * 256;
                const unsigned int green = scim_bridge_attribute_get_green (attr) * 256;
                const unsigned int blue = scim_bridge_attribute_get_blue (attr) * 256;

                PangoAttribute *pango_attr = pango_attr_foreground_new (red, green, blue);
                pango_attr->start_index = start_index;
                pango_attr->end_index = end_index;
                pango_attr_list_insert (imcontext->preedit_attributes, pango_attr);
            } else if (attr_type == ATTRIBUTE_BACKGROUND) {
                valid_attribute = TRUE;

                const unsigned int red = scim_bridge_attribute_get_red (attr) * 256;
                const unsigned int green = scim_bridge_attribute_get_green (attr) * 256;
                const unsigned int blue = scim_bridge_attribute_get_blue (attr) * 256;

                PangoAttribute *pango_attr = pango_attr_background_new (red, green, blue);
                pango_attr->start_index = start_index;
                pango_attr->end_index = end_index;
                pango_attr_list_insert (imcontext->preedit_attributes, pango_attr);
            }

            if (valid_attribute) {
                int j;
                for (j = start_index; j < end_index; ++j) {
                    has_attribute[j] = TRUE;
                }
            }
        }

    }

    // Add underlines for the all characters without attributes.
    for (i = 0; i < preedit_string_length; ++i) {
        if (has_attribute[i] == FALSE) {
            PangoAttribute *pango_attr = pango_attr_underline_new (PANGO_UNDERLINE_SINGLE);
            pango_attr->start_index = i;
            for (; i < preedit_string_length && has_attribute[i] == FALSE; ++i);
            pango_attr->end_index = i;
            pango_attr_list_insert (imcontext->preedit_attributes, pango_attr);
        }
    }
}
Exemplo n.º 28
0
static int
key_action_tab_comp (GtkWidget *t, GdkEventKey *entry, char *d1, char *d2,
							struct session *sess)
{
	int len = 0, elen = 0, i = 0, cursor_pos, ent_start = 0, comp = 0, prefix_len, skip_len = 0;
	gboolean is_nick = FALSE, is_cmd = FALSE, found = FALSE, has_nick_prefix = FALSE;
	char ent[CHANLEN], *postfix = NULL, *result, *ch;
	GList *list = NULL, *tmp_list = NULL;
	const char *text;
	GCompletion *gcomp = NULL;
	GString *buf;

	/* force the IM Context to reset */
	SPELL_ENTRY_SET_EDITABLE (t, FALSE);
	SPELL_ENTRY_SET_EDITABLE (t, TRUE);

	text = SPELL_ENTRY_GET_TEXT (t);
	if (text[0] == 0)
		return 1;

	len = g_utf8_strlen (text, -1); /* must be null terminated */

	cursor_pos = SPELL_ENTRY_GET_POS (t);

	/* handle "nick: " or "nick " or "#channel "*/
	ch = g_utf8_find_prev_char(text, g_utf8_offset_to_pointer(text,cursor_pos));
	if (ch && ch[0] == ' ')
	{
		skip_len++;
		ch = g_utf8_find_prev_char(text, ch);
		if (!ch)
			return 2;

		cursor_pos = g_utf8_pointer_to_offset(text, ch);
		if (cursor_pos && (g_utf8_get_char_validated(ch, -1) == ':' || 
					g_utf8_get_char_validated(ch, -1) == ',' ||
					g_utf8_get_char_validated (ch, -1) == g_utf8_get_char_validated (prefs.hex_completion_suffix, -1)))
		{
			skip_len++;
		}
		else
			cursor_pos = g_utf8_pointer_to_offset(text, g_utf8_offset_to_pointer(ch, 1));
	}

	comp = skip_len;
	
	/* store the text following the cursor for reinsertion later */
	if ((cursor_pos + skip_len) < len)
		postfix = g_utf8_offset_to_pointer(text, cursor_pos + skip_len);

	for (ent_start = cursor_pos; ; --ent_start)
	{
		if (ent_start == 0)
			break;
		ch = g_utf8_offset_to_pointer(text, ent_start - 1);
		if (ch && ch[0] == ' ')
			break;
	}

	if (ent_start == 0 && text[0] == prefs.hex_input_command_char[0])
	{
		ent_start++;
		is_cmd = TRUE;
	}
	else if (strchr (sess->server->chantypes, text[ent_start]) == NULL)
	{
		is_nick = TRUE;
		if (strchr (sess->server->nick_prefixes, text[ent_start]) != NULL)
		{
			if (ent_start == 0)
				has_nick_prefix = TRUE;
			ent_start++;
		}
	}

	prefix_len = ent_start;
	elen = cursor_pos - ent_start;

	g_utf8_strncpy (ent, g_utf8_offset_to_pointer (text, prefix_len), elen);
	
	if (sess->type == SESS_DIALOG && is_nick)
	{
		/* tab in a dialog completes the other person's name */
		if (rfc_ncasecmp (sess->channel, ent, elen) == 0)
		{
			result =  sess->channel;
			is_nick = FALSE;
		}
		else
			return 2;
	}
	else
	{
		if (is_nick)
		{
			gcomp = g_completion_new((GCompletionFunc)gcomp_nick_func);
			tmp_list = userlist_double_list(sess); /* create a temp list so we can free the memory */
			if (prefs.hex_completion_sort == 1)	/* sort in last-talk order? */
				tmp_list = g_list_sort (tmp_list, (void *)talked_recent_cmp);
		}
		else
		{
			gcomp = g_completion_new (NULL);
			if (is_cmd)
			{
				tmp_list = cmdlist_double_list (command_list);
				for(i = 0; xc_cmds[i].name != NULL ; i++)
				{
					tmp_list = g_list_prepend (tmp_list, xc_cmds[i].name);
				}
				tmp_list = plugin_command_list(tmp_list);
			}
			else
				tmp_list = chanlist_double_list (sess_list);
		}
		tmp_list = g_list_reverse(tmp_list); /* make the comp entries turn up in the right order */
		g_completion_set_compare (gcomp, (GCompletionStrncmpFunc)rfc_ncasecmp);
		if (tmp_list)
		{
			g_completion_add_items (gcomp, tmp_list);
			g_list_free (tmp_list);
		}

		if (comp && !(rfc_ncasecmp(old_gcomp.data, ent, old_gcomp.elen) == 0))
		{
			key_action_tab_clean ();
			comp = 0;
		}
	
		list = g_completion_complete_utf8 (gcomp, comp ? old_gcomp.data : ent, &result);
		
		if (result == NULL) /* No matches found */
		{
			g_completion_free(gcomp);
			return 2;
		}

		if (comp) /* existing completion */
		{
			while(list) /* find the current entry */
			{
				if(rfc_ncasecmp(list->data, ent, elen) == 0)
				{
					found = TRUE;
					break;
				}
				list = list->next;
			}

			if (found)
			{
				if (!(d1 && d1[0])) /* not holding down shift */
				{
					if (g_list_next(list) == NULL)
						list = g_list_first(list);
					else
						list = g_list_next(list);
				}
				else
				{
					if (g_list_previous(list) == NULL)
						list = g_list_last(list);
					else
						list = g_list_previous(list);
				}
				g_free(result);
				result = (char*)list->data;
			}
			else
			{
				g_free(result);
				g_completion_free(gcomp);
				return 2;
			}
		}
		else
		{
			strcpy(old_gcomp.data, ent);
			old_gcomp.elen = elen;

			/* Get the first nick and put out the data for future nickcompletes */
			if (prefs.hex_completion_amount > 0 && g_list_length (list) <= (guint) prefs.hex_completion_amount)
			{
				g_free(result);
				result = (char*)list->data;
			}
			else
			{
				/* bash style completion */
				if (g_list_next(list) != NULL)
				{
					buf = g_string_sized_new (MAX(COMP_BUF, len + NICKLEN));
					if (strlen (result) > elen) /* the largest common prefix is larger than nick, change the data */
					{
						if (prefix_len)
							g_string_append_len (buf, text, offset_to_len (text, prefix_len));
						g_string_append (buf, result);
						cursor_pos = buf->len;
						g_free(result);
						if (postfix)
						{
							g_string_append_c (buf, ' ');
							g_string_append (buf, postfix);
						}
						SPELL_ENTRY_SET_TEXT (t, buf->str);
						SPELL_ENTRY_SET_POS (t, len_to_offset (buf->str, cursor_pos));
						g_string_erase (buf, 0, -1);
					}
					else
						g_free(result);

					while (list)
					{
						len = buf->len;
						elen = strlen (list->data);	/* next item to add */
						if (len + elen + 2 >= COMP_BUF) /* +2 is space + null */
						{
							PrintText (sess, buf->str);
							g_string_erase (buf, 0, -1);
						}
						g_string_append (buf, (char*)list->data);
						g_string_append_c (buf, ' ');
						list = list->next;
					}
					PrintText (sess, buf->str);
					g_completion_free(gcomp);
					g_string_free (buf, TRUE);
					return 2;
				}
				/* Only one matching entry */
				g_free(result);
				result = list->data;
			}
		}
	}
	
	if(result)
	{
		buf = g_string_sized_new (len + NICKLEN);
		if (prefix_len)
			g_string_append_len (buf, text, offset_to_len (text, prefix_len));
		g_string_append (buf, result);
		if((!prefix_len || has_nick_prefix) && is_nick && prefs.hex_completion_suffix[0] != '\0')
			g_string_append_unichar (buf, g_utf8_get_char_validated (prefs.hex_completion_suffix, -1));
		g_string_append_c (buf, ' ');
		cursor_pos = buf->len;
		if (postfix)
			g_string_append (buf, postfix);
		SPELL_ENTRY_SET_TEXT (t, buf->str);
		SPELL_ENTRY_SET_POS (t, len_to_offset (buf->str, cursor_pos));
		g_string_free (buf, TRUE);
	}
	if (gcomp)
		g_completion_free(gcomp);
	return 2;
}
Exemplo n.º 29
0
static void
gtk_text_cell_accessible_get_character_extents (AtkText      *text,
                                                gint          offset,
                                                gint         *x,
                                                gint         *y,
                                                gint         *width,
                                                gint         *height,
                                                AtkCoordType  coords)
{
  GtkRendererCellAccessible *gail_renderer;
  GtkRequisition min_size;
  GtkCellRendererText *gtk_renderer;
  GdkRectangle rendered_rect;
  GtkWidget *widget;
  AtkObject *parent;
  PangoRectangle char_rect;
  PangoLayout *layout;
  gchar *renderer_text;
  gfloat xalign, yalign;
  gint x_offset, y_offset, index;
  gint xpad, ypad;
  gint x_window, y_window, x_toplevel, y_toplevel;

  if (!GTK_TEXT_CELL_ACCESSIBLE (text)->cell_text)
    {
      *x = *y = *height = *width = 0;
      return;
    }
  if (offset < 0 || offset >= GTK_TEXT_CELL_ACCESSIBLE (text)->cell_length)
    {
      *x = *y = *height = *width = 0;
      return;
    }
  gail_renderer = GTK_RENDERER_CELL_ACCESSIBLE (text);
  gtk_renderer = GTK_CELL_RENDERER_TEXT (gail_renderer->renderer);

  g_object_get (gtk_renderer, "text", &renderer_text, NULL);
  if (text == NULL)
    {
      g_free (renderer_text);
      return;
    }

  parent = atk_object_get_parent (ATK_OBJECT (text));
  if (GTK_IS_CONTAINER_CELL_ACCESSIBLE (parent))
    parent = atk_object_get_parent (parent);
  widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (parent));
  g_return_if_fail (GTK_IS_CELL_ACCESSIBLE_PARENT (parent));
  _gtk_cell_accessible_parent_get_cell_area (GTK_CELL_ACCESSIBLE_PARENT (parent),
                                             GTK_CELL_ACCESSIBLE (text),
                                             &rendered_rect);

  gtk_cell_renderer_get_preferred_size (GTK_CELL_RENDERER (gtk_renderer),
                                        widget,
                                        &min_size, NULL);

  gtk_cell_renderer_get_alignment (GTK_CELL_RENDERER (gtk_renderer), &xalign, &yalign);
  if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
    xalign = 1.0 - xalign;
  x_offset = MAX (0, xalign * (rendered_rect.width - min_size.width));
  y_offset = MAX (0, yalign * (rendered_rect.height - min_size.height));

  layout = create_pango_layout (GTK_TEXT_CELL_ACCESSIBLE (text));

  index = g_utf8_offset_to_pointer (renderer_text, offset) - renderer_text;
  pango_layout_index_to_pos (layout, index, &char_rect);

  gtk_cell_renderer_get_padding (gail_renderer->renderer, &xpad, &ypad);

  get_origins (widget, &x_window, &y_window, &x_toplevel, &y_toplevel);

  *x = (char_rect.x / PANGO_SCALE) + x_offset + rendered_rect.x + xpad + x_window;
  *y = (char_rect.y / PANGO_SCALE) + y_offset + rendered_rect.y + ypad + y_window;
  *height = char_rect.height / PANGO_SCALE;
  *width = char_rect.width / PANGO_SCALE;

  if (coords == ATK_XY_WINDOW)
    {
      *x -= x_toplevel;
      *y -= y_toplevel;
    }
  else if (coords != ATK_XY_SCREEN)
    {
      *x = 0;
      *y = 0;
      *height = 0;
      *width = 0;
    }

  g_free (renderer_text);
  g_object_unref (layout);
}
Exemplo n.º 30
0
static void
rejilla_project_name_label_insert_text (GtkEditable *editable,
				        const gchar *text,
				        gint length,
				        gint *position,
				        gpointer NULL_data)
{
	RejillaProjectNamePrivate *priv;
	const gchar *label;
	gchar *new_text;
	gint new_length;
	gchar *current;
	gint max_len;
	gchar *prev;
	gchar *next;

	priv = REJILLA_PROJECT_NAME_PRIVATE (editable);	

	/* check if this new text will fit in 32 _bytes_ long buffer */
	label = gtk_entry_get_text (GTK_ENTRY (editable));
	max_len = 32 - strlen (label) - length;
	if (max_len >= 0)
		return;

	gdk_beep ();

	/* get the last character '\0' of the text to be inserted */
	new_length = length;
	new_text = g_strdup (text);
	current = g_utf8_offset_to_pointer (new_text, g_utf8_strlen (new_text, -1));

	/* don't just remove one character in case there was many more
	 * that were inserted at the same time through DND, paste, ... */
	prev = g_utf8_find_prev_char (new_text, current);
	if (!prev) {
		/* no more characters so no insertion */
		g_signal_stop_emission_by_name (editable, "insert_text"); 
		g_free (new_text);
		return;
	}

	do {
		next = current;
		current = prev;

		prev = g_utf8_find_prev_char (new_text, current);
		if (!prev) {
			/* no more characters so no insertion */
			g_signal_stop_emission_by_name (editable, "insert_text"); 
			g_free (new_text);
			return;
		}

		new_length -= next - current;
		max_len += next - current;
	} while (max_len < 0 && new_length > 0);

	*current = '\0';
	g_signal_handlers_block_by_func (editable,
					 (gpointer) rejilla_project_name_label_insert_text,
					 NULL_data);
	gtk_editable_insert_text (editable, new_text, new_length, position);
	g_signal_handlers_unblock_by_func (editable,
					   (gpointer) rejilla_project_name_label_insert_text,
					   NULL_data);

	g_signal_stop_emission_by_name (editable, "insert_text");
	g_free (new_text);
}