static gint
camel_ustrncasecmp (const gchar *ps1, const gchar *ps2, gsize len)
{
	gunichar u1, u2 = 0;
	const guchar *s1 = (const guchar *)ps1;
	const guchar *s2 = (const guchar *)ps2;

	CAMEL_SEARCH_COMPARE (s1, s2, NULL);

	u1 = camel_utf8_getc (&s1);
	u2 = camel_utf8_getc (&s2);
	while (len > 0 && u1 && u2) {
		u1 = g_unichar_tolower (u1);
		u2 = g_unichar_tolower (u2);
		if (u1 < u2)
			return -1;
		else if (u1 > u2)
			return 1;

		len--;
		u1 = camel_utf8_getc (&s1);
		u2 = camel_utf8_getc (&s2);
	}

	if (len == 0)
		return 0;

	/* end of one of the strings ? */
	CAMEL_SEARCH_COMPARE (u1, u2, 0);

	/* if we have invalid utf8 sequence ?  */
	CAMEL_SEARCH_COMPARE (s1, s2, NULL);

	return 0;
}
Exemple #2
0
unsigned int levenshtein ( const char *needle, const char *haystack )
{
    unsigned int x, y, lastdiag, olddiag;
    size_t       needlelen   = g_utf8_strlen ( needle, -1 );
    size_t       haystacklen = g_utf8_strlen ( haystack, -1 );
    unsigned int column[needlelen + 1];
    for ( y = 0; y <= needlelen; y++ ) {
        column[y] = y;
    }
    for ( x = 1; x <= haystacklen; x++ ) {
        const char *needles = needle;
        column[0] = x;
        gunichar   haystackc = g_utf8_get_char ( haystack );
        if ( !config.case_sensitive ) {
            haystackc = g_unichar_tolower ( haystackc );
        }
        for ( y = 1, lastdiag = x - 1; y <= needlelen; y++ ) {
            gunichar needlec = g_utf8_get_char ( needles );
            if ( !config.case_sensitive ) {
                needlec = g_unichar_tolower ( needlec );
            }
            olddiag   = column[y];
            column[y] = MIN3 ( column[y] + 1, column[y - 1] + 1, lastdiag + ( needlec == haystackc ? 0 : 1 ) );
            lastdiag  = olddiag;
            needles   = g_utf8_next_char ( needles );
        }
        haystack = g_utf8_next_char ( haystack );
    }
    return column[needlelen];
}
Exemple #3
0
static gint32 string_invariant_compare_char (gunichar2 c1, gunichar2 c2,
					     gint32 options)
{
	gint32 result;

	/* Ordinal can not be mixed with other options, and must return the difference, not only -1, 0, 1 */
	if (options & CompareOptions_Ordinal) 
		return (gint32) c1 - c2;
	
	if (options & CompareOptions_IgnoreCase) {
		GUnicodeType c1type, c2type;

		c1type = g_unichar_type (c1);
		c2type = g_unichar_type (c2);
	
		result = (gint32) (c1type != G_UNICODE_LOWERCASE_LETTER ? g_unichar_tolower(c1) : c1) -
			(c2type != G_UNICODE_LOWERCASE_LETTER ? g_unichar_tolower(c2) : c2);
	} else {
		/*
		 * No options. Kana, symbol and spacing options don't
		 * apply to the invariant culture.
		 */

		/*
		 * FIXME: here we must use the information from c1type and c2type
		 * to find out the proper collation, even on the InvariantCulture, the
		 * sorting is not done by computing the unicode values, but their
		 * actual sort order.
		 */
		result = (gint32) c1 - c2;
	}

	return ((result < 0) ? -1 : (result > 0) ? 1 : 0);
}
static int
camel_ustrcasecmp (const char *ps1, const char *ps2)
{
	gunichar u1, u2 = 0;
	const unsigned char *s1 = (const unsigned char *)ps1;
	const unsigned char *s2 = (const unsigned char *)ps2;

	CAMEL_SEARCH_COMPARE (s1, s2, NULL);

	u1 = camel_utf8_getc(&s1);
	u2 = camel_utf8_getc(&s2);
	while (u1 && u2) {
		u1 = g_unichar_tolower (u1);
		u2 = g_unichar_tolower (u2);
		if (u1 < u2)
			return -1;
		else if (u1 > u2)
			return 1;

		u1 = camel_utf8_getc(&s1);
		u2 = camel_utf8_getc(&s2);
	}

	/* end of one of the strings ? */
	CAMEL_SEARCH_COMPARE (u1, u2, 0);

	/* if we have invalid utf8 sequence ?  */
	CAMEL_SEARCH_COMPARE (s1, s2, NULL);

	return 0;
}
const gchar *
camel_ustrstrcase (const gchar *haystack, const gchar *needle)
{
	gunichar *nuni, *puni;
	gunichar u;
	const guchar *p;

	g_return_val_if_fail (haystack != NULL, NULL);
	g_return_val_if_fail (needle != NULL, NULL);

	if (strlen (needle) == 0)
		return haystack;
	if (strlen (haystack) == 0)
		return NULL;

	puni = nuni = g_alloca (sizeof (gunichar) * strlen (needle));

	p = (const guchar *) needle;
	while ((u = camel_utf8_getc (&p)))
		*puni++ = g_unichar_tolower (u);

	/* NULL means there was illegal utf-8 sequence */
	if (!p)
		return NULL;

	p = (const guchar *)haystack;
	while ((u = camel_utf8_getc (&p))) {
		gunichar c;

		c = g_unichar_tolower (u);
		/* We have valid stripped gchar */
		if (c == nuni[0]) {
			const guchar *q = p;
			gint npos = 1;

			while (nuni + npos < puni) {
				u = camel_utf8_getc (&q);
				if (!q || !u)
					return NULL;

				c = g_unichar_tolower (u);
				if (c != nuni[npos])
					break;

				npos++;
			}

			if (nuni + npos == puni)
				return (const gchar *) p;
		}
	}

	return NULL;
}
Exemple #6
0
/* Copied from evolution-data-server/libedataserver/e-util.c:
 * e_util_utf8_strstrcase() */
const char *
panel_g_utf8_strstrcase (const char *haystack, const char *needle)
{
	gunichar *nuni;
	gunichar unival;
	gint nlen;
	const char *o, *p;

	if (haystack == NULL) return NULL;
	if (needle == NULL) return NULL;
	if (strlen (needle) == 0) return haystack;
	if (strlen (haystack) == 0) return NULL;

	nuni = g_alloca (sizeof (gunichar) * strlen (needle));

	nlen = 0;
	for (p = _unicode_get_utf8 (needle, &unival);
	     p && unival;
	     p = _unicode_get_utf8 (p, &unival)) {
		nuni[nlen++] = g_unichar_tolower (unival);
	}
	/* NULL means there was illegal utf-8 sequence */
	if (!p) return NULL;

	o = haystack;
	for (p = _unicode_get_utf8 (o, &unival);
	     p && unival;
	     p = _unicode_get_utf8 (p, &unival)) {
		gint sc;
		sc = g_unichar_tolower (unival);
		/* We have valid stripped char */
		if (sc == nuni[0]) {
			const char *q = p;
			gint npos = 1;
			while (npos < nlen) {
				q = _unicode_get_utf8 (q, &unival);
				if (!q || !unival) return NULL;
				sc = g_unichar_tolower (unival);
				if (sc != nuni[npos]) break;
				npos++;
			}
			if (npos == nlen) {
				return o;
			}
		}
		o = p;
	}

	return NULL;
}
Exemple #7
0
static char *convert_sentence_case(const char *str)
{
	int result_size = strlen(str) + 12;
	char *result = malloc(result_size);
	const char *r = str;
	char *w = result;

	while (*r) {
		int len;
		gunichar c = g_utf8_get_char(r);

		/* ensure there is room for at least 1 more character */
		if (w - result + 7 > result_size) {
			int offset = w - result;
			result_size += max(6, 0.5 * result_size);
			result = realloc(result, result_size);
			w = result + offset;
		}

		if (r == str)
			len = g_unichar_to_utf8(g_unichar_toupper(c), w);
		else
			len = g_unichar_to_utf8(g_unichar_tolower(c), w);
		w += len;

		r = g_utf8_next_char(r);
	}

	*w = 0;
	
	return result;
}
Exemple #8
0
ObMenu* menu_new(const gchar *name, const gchar *title,
                 gboolean allow_shortcut_selection, gpointer data)
{
    ObMenu *self;

    self = g_slice_new0(ObMenu);
    self->name = g_strdup(name);
    self->data = data;

    self->shortcut = parse_shortcut(title, allow_shortcut_selection,
                                    &self->title, &self->shortcut_position,
                                    &self->shortcut_always_show);

    g_hash_table_replace(menu_hash, self->name, self);

    /* Each menu has a single more_menu.  When the menu spills past what
       can fit on the screen, a new menu frame entry is created from this
       more_menu, and a new menu frame for the submenu is created for this
       menu, also pointing to the more_menu.

       This can be done multiple times using the same more_menu.

       more_menu->more_menu will always be NULL, since there is only 1 for
       each menu. */
    self->more_menu = g_slice_new0(ObMenu);
    self->more_menu->name = _("More...");
    self->more_menu->title = _("More...");
    self->more_menu->data = data;
    self->more_menu->shortcut = g_unichar_tolower(g_utf8_get_char("M"));

    return self;
}
/* converts str into utf8 GString in lowercase;
 * returns NULL if str is invalid utf8 string otherwise
 * returns newly allocated GString
*/
static GString *
chars_to_unistring_lowercase (const gchar *pstr)
{
	GString *res;
	gunichar unich;
	gchar *p, *str;

	if (pstr == NULL)
		return NULL;

	str = e_util_utf8_remove_accents (pstr);
	if (!str)
		return NULL;

	res = g_string_new ("");

	for (p = e_util_unicode_get_utf8 (str, &unich); p && unich; p = e_util_unicode_get_utf8 (p, &unich)) {
		g_string_append_unichar (res, g_unichar_tolower (unich));
	}

	g_free (str);

	/* it was invalid unichar string */
	if (p == NULL) {
		g_string_free (res, TRUE);
		return NULL;
	}

	return res;
}
static void
do_invert_case (GtkTextBuffer *buffer,
                GtkTextIter   *start,
                GtkTextIter   *end)
{
	GString *s = g_string_new (NULL);

	while (!gtk_text_iter_is_end (start) &&
	       !gtk_text_iter_equal (start, end))
	{
		gunichar c, nc;

		c = gtk_text_iter_get_char (start);
		if (g_unichar_islower (c))
			nc = g_unichar_toupper (c);
		else
			nc = g_unichar_tolower (c);
		g_string_append_unichar (s, nc);

		gtk_text_iter_forward_char (start);
	}

	gtk_text_buffer_delete_selection (buffer, TRUE, TRUE);
	gtk_text_buffer_insert_at_cursor (buffer, s->str, s->len);

	g_string_free (s, TRUE);
}
/**
 * stripped_char:
 *
 * Returns a stripped version of @ch, removing any case, accentuation
 * mark, or any special mark on it.
 **/
static gunichar
stripped_char (gunichar ch)
{
  gunichar *decomp, retval;
  GUnicodeType utype;
  gsize dlen;

  utype = g_unichar_type (ch);

  switch (utype) {
  case G_UNICODE_CONTROL:
  case G_UNICODE_FORMAT:
  case G_UNICODE_UNASSIGNED:
  case G_UNICODE_COMBINING_MARK:
    /* Ignore those */
    return 0;
    break;
  default:
    /* Convert to lowercase, fall through */
    ch = g_unichar_tolower (ch);
  case G_UNICODE_LOWERCASE_LETTER:
    if ((decomp = g_unicode_canonical_decomposition (ch, &dlen))) {
      retval = decomp[0];
      g_free (decomp);
      return retval;
    }
    break;
  }

  return 0;
}
Exemple #12
0
static char *convert_title_case(const char *str)
{
	int result_size = strlen(str) + 12;
	char *result = malloc(result_size);
	const char *r = str;
	char *w = result;
	gboolean upcase_next = TRUE;

	while (*r) {
		int len;
		gunichar c = g_utf8_get_char(r);

		/* ensure there is room for at least 1 more character */
		if (w - result + 7 > result_size) {
			int offset = w - result;
			result_size += max(6, 0.5 * result_size);
			result = realloc(result, result_size);
			w = result + offset;
		}

		if (upcase_next)
			len = g_unichar_to_utf8(g_unichar_toupper(c), w);
		else
			len = g_unichar_to_utf8(g_unichar_tolower(c), w);
		w += len;

		upcase_next = !g_unichar_isalnum(c) && c != '\'';

		r = g_utf8_next_char(r);
	}

	*w = 0;
	
	return result;
}
Exemple #13
0
gchar *
gb_str_highlight_full (const gchar     *str,
                       const gchar     *match,
                       gboolean         insensitive,
                       GbHighlightType  type)
{
  const gchar *begin = "<u>";
  const gchar *end = "</u>";
  GString *ret;
  gunichar str_ch;
  gunichar match_ch;

  g_return_val_if_fail (str, NULL);
  g_return_val_if_fail (match, NULL);

  if (type == GB_HIGHLIGHT_BOLD)
    {
      begin = "<b>";
      end = "</b>";
    }

  ret = g_string_new (NULL);

  for (; *str; str = g_utf8_next_char (str))
    {
      str_ch = g_utf8_get_char (str);
      match_ch = g_utf8_get_char (match);

      if ((str_ch == match_ch) || (insensitive && (g_unichar_tolower (str_ch) == g_unichar_tolower (match_ch))))
        {
          g_string_append (ret, begin);
          g_string_append_unichar (ret, str_ch);
          g_string_append (ret, end);

          /*
           * TODO: We could seek to the next char and append in a batch.
           */
          match = g_utf8_next_char (match);
        }
      else
        {
          g_string_append_unichar (ret, str_ch);
        }
    }

  return g_string_free (ret, FALSE);
}
void SmkyManufacturerDatabase::setFistAndLastLetters(const std::string & firstLetters, const std::string & lastLetters, int minLength)
{
	if (m_hunspell && m_lastHunspellResult)
	{
		m_hunspell->free_list(&m_lastHunspellResult, m_lastHunspellResultCount);
		m_lastHunspellResult = NULL;
	}
	m_lastFirstLastLetterResults.clear();
	auto_g_free_array<gunichar> first16 = g_utf8_to_ucs4(firstLetters.c_str(), -1, NULL, NULL, NULL);
	auto_g_free_array<gunichar> last16 = g_utf8_to_ucs4(lastLetters.c_str(), -1, NULL, NULL, NULL);
	if (first16 && last16)
	{
		gunichar * p = first16;
		while (*p)
			*p = g_unichar_tolower(*p), ++p;
		p = last16;
		while (*p)
			*p = g_unichar_tolower(*p), ++p;
		for (std::map<std::string, int>::iterator iter = m_words.begin(); iter != m_words.end(); ++iter)
		{
			const std::string & word = iter->first;
			const char * wordStr = word.c_str();
			gunichar firstLetter = g_unichar_tolower(g_utf8_get_char(wordStr));
			if (wcschr(first16.as<wchar_t>(), (wchar_t) firstLetter))
			{	// first letter is a match!
				const char * next = wordStr;
				int wordLength = 1;
				while ((next = g_utf8_next_char(wordStr)) && *next)
					wordStr = next, ++wordLength;
				if (wordLength >= minLength) {
					gunichar lastLetter = g_unichar_tolower(g_utf8_get_char(wordStr));
					if (wcschr(last16.as<wchar_t>(), (wchar_t) lastLetter))
					{
						DEBUG_CALLBACK("First-last letter match: %s-%s -> %s", firstLetters.c_str(), lastLetters.c_str(), word.c_str());
						m_lastFirstLastLetterResults.push_back(word.c_str());
					}
				}
				else {
					DEBUG_CALLBACK("'%s' is discarded because it's too short: %d letters, %d min", word.c_str(), wordLength, minLength);
				}
			}
		}
	}
}
Exemple #15
0
unsigned int
_pcre_ucp_othercase(const unsigned int c)
{
  unsigned int oc = NOTACHAR;

  if ((oc = g_unichar_toupper(c)) != c)
    return oc;
  if ((oc = g_unichar_tolower(c)) != c)
    return oc;

  return c;
}
Exemple #16
0
static gunichar
get_char (const char **str)
{
  gunichar c = g_utf8_get_char (*str);
  *str = g_utf8_next_char (*str);

#ifdef G_PLATFORM_WIN32
  c = g_unichar_tolower (c);
#endif

  return c;
}
Exemple #17
0
static const char* lookup_suffix_nodes( const char* buf, const char* nodes, guint32 n, const char* name )
{
    gunichar uchar;

    uchar = g_unichar_tolower( g_utf8_get_char( name ) );

    /* binary search */
    int upper = n, lower = 0;
    int middle = n/2;

    while( upper >= lower )
    {
        const char* node =nodes + middle * 16;
        guint32 ch = VAL32(node, 0);

        if( uchar < ch )
            upper = middle - 1;
        else if( uchar > ch )
            lower = middle + 1;
        else /* uchar == ch */
        {
            guint32 n_children = VAL32(node, 8);
            name =g_utf8_next_char(name);

            if( n_children > 0 )
            {
                guint32 first_child_off;
                if( uchar == 0 )
                    return NULL;

                if( ! name || 0 == name[0] )
                {
                    guint32 offset = VAL32(node, 4);
                    return offset ? buf + offset : NULL;
                }
                first_child_off = VAL32(node, 12);
                return lookup_suffix_nodes( buf, (buf + first_child_off), n_children, name );
            }
            else
            {
                if( ! name || 0 == name[0] )
                {
                    guint32 offset = VAL32(node, 4);
                    return offset ? buf + offset : NULL;
                }
                return NULL;
            }
        }
        middle = (upper + lower) / 2;
    }
    return NULL;
}
Exemple #18
0
/* Reverse suffix tree is used since mime.cache 1.1 (shared mime info 0.4)
 * Returns the address of the found "node", not mime-type.
 * FIXME: 1. Should be optimized with binary search
 *        2. Should consider weight of suffix nodes
 */
static const char* lookup_reverse_suffix_nodes( const char* buf, const char* nodes, guint32 n, const char* name, const char* suffix, const char** suffix_pos )
{
    const char *ret = NULL;
    const char *_suffix_pos = NULL, *cur_suffix_pos = (const char*)suffix + 1;
    const char* leaf_node = NULL;
    gunichar uchar;

    uchar = suffix ? g_unichar_tolower( g_utf8_get_char( suffix ) ) : 0;
    /* g_debug("%s: suffix= '%s'", name, suffix); */

    int i;
    for( i = 0; i < n; ++i )
    {
        const char* node =nodes + i * 12;
        guint32 ch = VAL32(node, 0);
        _suffix_pos = suffix;

        if( G_LIKELY( ch ) )
        {
            if( ch == uchar )
            {
                guint32 n_children = VAL32(node, 4);
                guint32 first_child_off = VAL32(node, 8);
                leaf_node = lookup_reverse_suffix_nodes( buf,
                                        buf + first_child_off,
                                        n_children,
                                        name,
                                        g_utf8_find_prev_char(name, suffix),
                                        &_suffix_pos );
                if( leaf_node && _suffix_pos < cur_suffix_pos )
                {
                    ret = leaf_node;
                    cur_suffix_pos = _suffix_pos;
                }
            }
        }
        else /* ch == 0 */
        {
            /* guint32 weight = VAL32(node, 8); */
            /* suffix is found in the tree! */

            if( suffix < cur_suffix_pos )
            {
                ret = node;
                cur_suffix_pos = suffix;
            }
        }
    }
    *suffix_pos = cur_suffix_pos;
    return ret;
}
Exemple #19
0
static gint key_press(guint keyval, gchar *commit_str, gchar *preedit_str) {
  gint length_passed, i;

  if(!gcomprisBoard)
    return FALSE;

  /* i suppose even numbers are passed through IM_context */
  if ((commit_str == NULL) && (preedit_str == NULL))
    return FALSE;

  gchar *string_passed;
  if (commit_str)
    string_passed = commit_str;
  else
    string_passed = preedit_str;

  length_passed = g_utf8_strlen(string_passed, -1);

  for (i=0; i < length_passed; i++){
    gunichar ckey = \
      g_unichar_tolower( g_utf8_get_char (string_passed) );
    gunichar cright = \
      g_unichar_tolower( g_utf8_get_char (right_letter) );

    if (ckey == cright){
      gamewon = TRUE;
      process_ok();
      gc_im_reset();
      return TRUE;
    }

    string_passed = g_utf8_next_char (string_passed);
  }

  return TRUE;
}
Exemple #20
0
static gchar *
utf8_case_conv (const gchar *str, gssize len, gboolean upper)
{
	gunichar *ustr;
	glong i, ulen;
	gchar *utf8;
	
	ustr = g_utf8_to_ucs4_fast (str, (glong) len, &ulen);
	for (i = 0; i < ulen; i++)
		ustr[i] = upper ? g_unichar_toupper (ustr[i]) : g_unichar_tolower (ustr[i]);
	utf8 = g_ucs4_to_utf8 (ustr, ulen, NULL, NULL, NULL);
	g_free (ustr);
	
	return utf8;
}
Exemple #21
0
static char*
process_str (const char *str, gboolean xapian_esc, gboolean query_esc)
{
	GString *gstr;
	char *norm, *cur;
	gboolean is_field, is_range_field;

	norm = g_utf8_normalize (str, -1, G_NORMALIZE_ALL);
	if (G_UNLIKELY(!norm)) {  /* not valid utf8? */
		char *u8;
		u8 = mu_str_utf8ify (str);
		norm = g_utf8_normalize (u8, -1, G_NORMALIZE_ALL);
		g_free (u8);
	}

 	if (!norm)
		return NULL;

	/* msg-id needs some special care in queries */
	if (query_esc && is_msgid_field (str))
		return mu_str_process_msgid (str, TRUE);

	check_for_field (str, &is_field, &is_range_field);
	gstr = g_string_sized_new (strlen (norm));

	for (cur = norm; cur && *cur; cur = g_utf8_next_char (cur)) {

		gunichar uc;
		uc = g_utf8_get_char (cur);
		if (xapian_esc)
			if (handle_esc_maybe (gstr, &cur, uc, query_esc,
					      is_range_field))
				continue;

		if (g_unichar_ismark(uc))
			continue;

		if (!is_range_field)
			uc = g_unichar_tolower (uc);
		
		g_string_append_unichar (gstr, uc);
	}

	g_free (norm);
	return g_string_free (gstr, FALSE);
}
static void
output_c (GString *w, guint32 c, gint *type)
{
	gint utf8len;
	gchar utf8[8];

	if (!g_unichar_isalnum (c))
		*type = CAMEL_SEARCH_WORD_COMPLEX | (*type & CAMEL_SEARCH_WORD_8BIT);
	else
		c = g_unichar_tolower (c);

	if (c > 0x80)
		*type |= CAMEL_SEARCH_WORD_8BIT;

	/* FIXME: use camel_utf8_putc */
	utf8len = g_unichar_to_utf8 (c, utf8);
	utf8[utf8len] = 0;
	g_string_append (w, utf8);
}
Exemple #23
0
static int
str_utf8_tolower (const char *text, char **out, size_t * remain)
{
    gunichar uni;
    size_t left;

    uni = g_utf8_get_char_validated (text, -1);
    if (uni == (gunichar) (-1) || uni == (gunichar) (-2))
	return 0;

    uni = g_unichar_tolower (uni);
    left = g_unichar_to_utf8 (uni, NULL);
    if (left >= *remain)
	return 0;

    left = g_unichar_to_utf8 (uni, *out);
    (*out) += left;
    (*remain) -= left;
    return 1;
}
Exemple #24
0
/*
 * g_unichar_tolower
 */
RESULT
test_g_unichar_tolower ()
{
	if (g_unichar_tolower (0) != 0)
		return FAILED ("#0");
	if (g_unichar_tolower ('A') != 'a')
		return FAILED ("#1");
	if (g_unichar_tolower ('1') != '1')
		return FAILED ("#2");
	if (g_unichar_tolower (0x1C5) != 0x1C6)
		return FAILED ("#3");
	if (g_unichar_tolower (0x1F1) != 0x1F3)
		return FAILED ("#4");
	if (g_unichar_tolower (0x1F2) != 0x1F3)
		return FAILED ("#5");
	if (g_unichar_tolower (0xFFFF) != 0xFFFF)
		return FAILED ("#6");
	return NULL;
}
Exemple #25
0
/**
 * gdk_keyval_convert_case:
 * @symbol: a keyval
 * @lower: (out): return location for lowercase version of @symbol
 * @upper: (out): return location for uppercase version of @symbol
 *
 * Obtains the upper- and lower-case versions of the keyval @symbol.
 * Examples of keyvals are #GDK_KEY_a, #GDK_KEY_Enter, #GDK_KEY_F1, etc.
 */
void
gdk_keyval_convert_case (guint symbol,
                         guint *lower,
                         guint *upper)
{
  guint xlower, xupper;

  xlower = symbol;
  xupper = symbol;

  /* Check for directly encoded 24-bit UCS characters: */
  if ((symbol & 0xff000000) == 0x01000000)
    {
      if (lower)
        *lower = gdk_unicode_to_keyval (g_unichar_tolower (symbol & 0x00ffffff));
      if (upper)
        *upper = gdk_unicode_to_keyval (g_unichar_toupper (symbol & 0x00ffffff));
      return;
    }

  switch (symbol >> 8)
    {
    case 0: /* Latin 1 */
      if ((symbol >= GDK_KEY_A) && (symbol <= GDK_KEY_Z))
        xlower += (GDK_KEY_a - GDK_KEY_A);
      else if ((symbol >= GDK_KEY_a) && (symbol <= GDK_KEY_z))
        xupper -= (GDK_KEY_a - GDK_KEY_A);
      else if ((symbol >= GDK_KEY_Agrave) && (symbol <= GDK_KEY_Odiaeresis))
        xlower += (GDK_KEY_agrave - GDK_KEY_Agrave);
      else if ((symbol >= GDK_KEY_agrave) && (symbol <= GDK_KEY_odiaeresis))
        xupper -= (GDK_KEY_agrave - GDK_KEY_Agrave);
      else if ((symbol >= GDK_KEY_Ooblique) && (symbol <= GDK_KEY_Thorn))
        xlower += (GDK_KEY_oslash - GDK_KEY_Ooblique);
      else if ((symbol >= GDK_KEY_oslash) && (symbol <= GDK_KEY_thorn))
        xupper -= (GDK_KEY_oslash - GDK_KEY_Ooblique);
      break;

    case 1: /* Latin 2 */
      /* Assume the KeySym is a legal value (ignore discontinuities) */
      if (symbol == GDK_KEY_Aogonek)
        xlower = GDK_KEY_aogonek;
      else if (symbol >= GDK_KEY_Lstroke && symbol <= GDK_KEY_Sacute)
        xlower += (GDK_KEY_lstroke - GDK_KEY_Lstroke);
      else if (symbol >= GDK_KEY_Scaron && symbol <= GDK_KEY_Zacute)
        xlower += (GDK_KEY_scaron - GDK_KEY_Scaron);
      else if (symbol >= GDK_KEY_Zcaron && symbol <= GDK_KEY_Zabovedot)
        xlower += (GDK_KEY_zcaron - GDK_KEY_Zcaron);
      else if (symbol == GDK_KEY_aogonek)
        xupper = GDK_KEY_Aogonek;
      else if (symbol >= GDK_KEY_lstroke && symbol <= GDK_KEY_sacute)
        xupper -= (GDK_KEY_lstroke - GDK_KEY_Lstroke);
      else if (symbol >= GDK_KEY_scaron && symbol <= GDK_KEY_zacute)
        xupper -= (GDK_KEY_scaron - GDK_KEY_Scaron);
      else if (symbol >= GDK_KEY_zcaron && symbol <= GDK_KEY_zabovedot)
        xupper -= (GDK_KEY_zcaron - GDK_KEY_Zcaron);
      else if (symbol >= GDK_KEY_Racute && symbol <= GDK_KEY_Tcedilla)
        xlower += (GDK_KEY_racute - GDK_KEY_Racute);
      else if (symbol >= GDK_KEY_racute && symbol <= GDK_KEY_tcedilla)
        xupper -= (GDK_KEY_racute - GDK_KEY_Racute);
      break;

    case 2: /* Latin 3 */
      /* Assume the KeySym is a legal value (ignore discontinuities) */
      if (symbol >= GDK_KEY_Hstroke && symbol <= GDK_KEY_Hcircumflex)
        xlower += (GDK_KEY_hstroke - GDK_KEY_Hstroke);
      else if (symbol >= GDK_KEY_Gbreve && symbol <= GDK_KEY_Jcircumflex)
        xlower += (GDK_KEY_gbreve - GDK_KEY_Gbreve);
      else if (symbol >= GDK_KEY_hstroke && symbol <= GDK_KEY_hcircumflex)
        xupper -= (GDK_KEY_hstroke - GDK_KEY_Hstroke);
      else if (symbol >= GDK_KEY_gbreve && symbol <= GDK_KEY_jcircumflex)
        xupper -= (GDK_KEY_gbreve - GDK_KEY_Gbreve);
      else if (symbol >= GDK_KEY_Cabovedot && symbol <= GDK_KEY_Scircumflex)
        xlower += (GDK_KEY_cabovedot - GDK_KEY_Cabovedot);
      else if (symbol >= GDK_KEY_cabovedot && symbol <= GDK_KEY_scircumflex)
        xupper -= (GDK_KEY_cabovedot - GDK_KEY_Cabovedot);
      break;

    case 3: /* Latin 4 */
      /* Assume the KeySym is a legal value (ignore discontinuities) */
      if (symbol >= GDK_KEY_Rcedilla && symbol <= GDK_KEY_Tslash)
        xlower += (GDK_KEY_rcedilla - GDK_KEY_Rcedilla);
      else if (symbol >= GDK_KEY_rcedilla && symbol <= GDK_KEY_tslash)
        xupper -= (GDK_KEY_rcedilla - GDK_KEY_Rcedilla);
      else if (symbol == GDK_KEY_ENG)
        xlower = GDK_KEY_eng;
      else if (symbol == GDK_KEY_eng)
        xupper = GDK_KEY_ENG;
      else if (symbol >= GDK_KEY_Amacron && symbol <= GDK_KEY_Umacron)
        xlower += (GDK_KEY_amacron - GDK_KEY_Amacron);
      else if (symbol >= GDK_KEY_amacron && symbol <= GDK_KEY_umacron)
        xupper -= (GDK_KEY_amacron - GDK_KEY_Amacron);
      break;

    case 6: /* Cyrillic */
      /* Assume the KeySym is a legal value (ignore discontinuities) */
      if (symbol >= GDK_KEY_Serbian_DJE && symbol <= GDK_KEY_Serbian_DZE)
        xlower -= (GDK_KEY_Serbian_DJE - GDK_KEY_Serbian_dje);
      else if (symbol >= GDK_KEY_Serbian_dje && symbol <= GDK_KEY_Serbian_dze)
        xupper += (GDK_KEY_Serbian_DJE - GDK_KEY_Serbian_dje);
      else if (symbol >= GDK_KEY_Cyrillic_YU && symbol <= GDK_KEY_Cyrillic_HARDSIGN)
        xlower -= (GDK_KEY_Cyrillic_YU - GDK_KEY_Cyrillic_yu);
      else if (symbol >= GDK_KEY_Cyrillic_yu && symbol <= GDK_KEY_Cyrillic_hardsign)
        xupper += (GDK_KEY_Cyrillic_YU - GDK_KEY_Cyrillic_yu);
      break;

    case 7: /* Greek */
      /* Assume the KeySym is a legal value (ignore discontinuities) */
      if (symbol >= GDK_KEY_Greek_ALPHAaccent && symbol <= GDK_KEY_Greek_OMEGAaccent)
        xlower += (GDK_KEY_Greek_alphaaccent - GDK_KEY_Greek_ALPHAaccent);
      else if (symbol >= GDK_KEY_Greek_alphaaccent && symbol <= GDK_KEY_Greek_omegaaccent &&
               symbol != GDK_KEY_Greek_iotaaccentdieresis &&
               symbol != GDK_KEY_Greek_upsilonaccentdieresis)
        xupper -= (GDK_KEY_Greek_alphaaccent - GDK_KEY_Greek_ALPHAaccent);
      else if (symbol >= GDK_KEY_Greek_ALPHA && symbol <= GDK_KEY_Greek_OMEGA)
        xlower += (GDK_KEY_Greek_alpha - GDK_KEY_Greek_ALPHA);
      else if (symbol >= GDK_KEY_Greek_alpha && symbol <= GDK_KEY_Greek_omega &&
               symbol != GDK_KEY_Greek_finalsmallsigma)
        xupper -= (GDK_KEY_Greek_alpha - GDK_KEY_Greek_ALPHA);
      break;

    default:
      break;
    }

  if (lower)
    *lower = xlower;
  if (upper)
    *upper = xupper;
}
Exemple #26
0
gchar *strproper (gchar *s) {
#if DISABLE_UTF8
	gchar c;
	gchar *ptr;

	if (!s)
		return NULL;

	ptr = g_strdup(s);
	if (!ptr)
		return NULL;
	s = ptr;
	*s = toupper(*s);
	s++;
	while ((c = tolower(*s)) != '\0')
		*s++ = c;
	return ptr;
#else
	gchar *ptr, *s1, *ptr1;
	gint len, first;
	gunichar c;

	if (!s)
		return NULL;

	len = 0;
	ptr = s;
	first = 1;
	while (*ptr) {
		c = g_utf8_get_char(ptr);
		if (first) {
			c = g_unichar_toupper(c);
			first = 0;
		} else
			c = g_unichar_tolower(c);
		len += g_unichar_to_utf8(c, NULL);
		ptr = g_utf8_next_char(ptr);
	}

	s1 = g_malloc(len + 1);
	if (!s1)
		return NULL;

	ptr = s;
	ptr1 = s1;
	first = 1;
	while (*ptr) {
		c = g_utf8_get_char(ptr);
		if (first) {
			c = g_unichar_toupper(c);
			first = 0;
		} else
			c = g_unichar_tolower(c);
		len = g_unichar_to_utf8(c, ptr1);
		ptr1 += len;
		ptr = g_utf8_next_char(ptr);
	}
	*ptr1 = '\0';

	return s1;
#endif
}
Exemple #27
0
static void
search_text_changed_cb (GtkEntry *entry, TextSearch *tsearch)
{
	GtkTextIter iter, siter, end;
	GtkTextBuffer *buffer;
	const gchar *search_text, *sptr;
	gboolean sensitive;

	buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (tsearch->priv->view));
	
	/* clean all previous search result */
	gtk_text_buffer_get_bounds (buffer, &iter, &end);
	gtk_text_buffer_remove_tag_by_name (buffer, "search", &iter, &end);
	tsearch->priv->current_mark = NULL;
	if (tsearch->priv->search_marks) {
		GList *list;
		for (list = tsearch->priv->search_marks; list; list = list->next)
			gtk_text_buffer_delete_mark (buffer, GTK_TEXT_MARK (list->data));

		g_list_free (tsearch->priv->search_marks);
		tsearch->priv->search_marks = NULL;
	}

	gtk_text_buffer_get_start_iter (buffer, &iter);
	search_text = gtk_entry_get_text (entry);

	if (!search_text || !*search_text)
		return;

	sensitive = gtk_toggle_button_get_active (tsearch->priv->search_sensitive);

	while (1) {
		gboolean high = TRUE;
		siter = iter;
		sptr = search_text;

		/* search for @search_text starting from the @siter position */
		while (1) {
			gunichar c1, c2;
			c1 = gtk_text_iter_get_char (&siter);
			c2 = g_utf8_get_char (sptr);
			if (!sensitive) {
				c1 = g_unichar_tolower (c1);
				c2 = g_unichar_tolower (c2);
			}
			if (c1 != c2) {
				high = FALSE;
				break;
			}
			
			sptr = g_utf8_find_next_char (sptr, NULL);
			if (!sptr || !*sptr)
				break;

			if (! gtk_text_iter_forward_char (&siter)) {
				high = FALSE;
				break;
			}
		}
		if (high) {
			if (gtk_text_iter_forward_char (&siter)) {
				GtkTextMark *mark;
				gtk_text_buffer_apply_tag_by_name (buffer, "search", &iter, &siter);
				mark = gtk_text_buffer_create_mark (buffer, NULL, &iter, FALSE);
				tsearch->priv->search_marks = g_list_prepend (tsearch->priv->search_marks,
									    mark);
			}
			iter = siter;
		}
		else {
			if (! gtk_text_iter_forward_char (&iter))
				break;
		}
	}

	if (tsearch->priv->search_marks) {
		tsearch->priv->search_marks = g_list_reverse (tsearch->priv->search_marks);
		tsearch->priv->current_mark = tsearch->priv->search_marks;
		gtk_text_view_scroll_mark_onscreen (tsearch->priv->view,
						    GTK_TEXT_MARK (tsearch->priv->current_mark->data));
	}
}
/** Examine an extension menu item and see if it needs to have an
 *  accelerator key assigned to it.  If so, find the first character
 *  in the menu name that isn't already assigned as an accelerator in
 *  the same menu, assign it to this item, and add it to the map of
 *  already used accelerator keys.  These maps are maintained per
 *  path, so accelerator keys may be duplicated across different menus
 *  but are guaranteed to be unique within any given menu.
 *
 *  @param info A menu extension.
 *
 *  @param table A hash table of accelerator maps. */
static void
gnc_menu_additions_assign_accel (ExtensionInfo *info, GHashTable *table)
{
    gchar *map, *new_map, *new_label, *start, buf[16];
    const gchar *ptr;
    gunichar uni;
    gint len;
    gboolean map_allocated = FALSE;

    ENTER("Checking %s/%s [%s]", info->path, info->ae.label, info->ae.name);
    if (info->accel_assigned)
    {
        LEAVE("Already processed");
        return;
    }

    /* Get map of used keys */
    map = g_hash_table_lookup(table, info->path);
    if (map == NULL)
    {
        map = g_strdup("");
        map_allocated = TRUE;
    }
    DEBUG("map '%s', path %s", map, info->path);

    for (ptr = info->ae.label; *ptr; ptr = g_utf8_next_char(ptr))
    {
        uni = g_utf8_get_char(ptr);
        if (!g_unichar_isalpha(uni))
            continue;
        uni = g_unichar_tolower(uni);
        len = g_unichar_to_utf8(uni, buf);
        buf[len] = '\0';
        DEBUG("Testing character '%s'", buf);
        if (!g_utf8_strchr(map, -1, uni))
            break;
    }

    if (ptr == NULL)
    {
        /* Ran out of characters. Nothing to do. */
        info->accel_assigned = TRUE;
        if (map_allocated)
        {
            g_free(map);
        }
        LEAVE("All characters already assigned");
        return;
    }

    /* Now build a new string in the form "<start>_<end>". */
    start = g_strndup(info->ae.label, ptr - info->ae.label);
    DEBUG("start %p, len %ld, text '%s'", start, g_utf8_strlen(start, -1), start);
    new_label = g_strconcat(start, "_", ptr, (gchar *)NULL);
    g_free(start);
    DEBUG("label '%s' -> '%s'", info->ae.label, new_label);
    g_free((gchar *)info->ae.label);
    info->ae.label = new_label;

    /* Now build a new map. Old one freed automatically. */
    new_map = g_strconcat(map, buf, (gchar *)NULL);
    DEBUG("map '%s' -> '%s'", map, new_map);
    g_hash_table_replace(table, info->path, new_map);

    info->accel_assigned = TRUE;
    if (map_allocated)
    {
        g_free(map);
    }
    LEAVE("assigned");
}
Exemple #29
0
static unichar i_tolower(unichar c)
{
	if (term_type == TERM_TYPE_UTF8)
		return g_unichar_tolower(c);
	return (c >= 0 && c <= 255) ? tolower(c) : c;
}
Exemple #30
0
static gunichar parse_shortcut(const gchar *label, gboolean allow_shortcut,
                               gchar **strippedlabel, guint *position,
                               gboolean *always_show)
{
    gunichar shortcut = 0;

    *position = 0;
    *always_show = FALSE;

    g_assert(strippedlabel != NULL);

    if (label == NULL) {
        *strippedlabel = NULL;
    } else {
        gchar *i;
        gboolean escape;

        *strippedlabel = g_strdup(label);

        /* if allow_shortcut is false, then you can't use the '_', instead you
           have to just use the first valid character
        */

        /* allow __ to escape an underscore */
        i = *strippedlabel;
        do {
            escape = FALSE;
            i = strchr(i, '_');
            if (i && *(i+1) == '_') {
                gchar *j;

                /* remove the escape '_' from the string */
                for (j = i; *j != '\0'; ++j)
                    *j = *(j+1);

                ++i;
                escape = TRUE;
            }
        } while (escape);

        if (allow_shortcut && i != NULL) {
            /* there is an underscore in the string */

            /* you have to use a printable ascii character for shortcuts
               don't allow space either, so you can have like "a _ b"
            */
            if (VALID_SHORTCUT(*(i+1))) {
                shortcut = g_unichar_tolower(g_utf8_get_char(i+1));
                *position = i - *strippedlabel;
                *always_show = TRUE;

                /* remove the '_' from the string */
                for (; *i != '\0'; ++i)
                    *i = *(i+1);
            } else if (*(i+1) == '\0') {
                /* no default shortcut if the '_' is the last character
                   (eg. "Exit_") for menu entries that you don't want
                   to be executed by mistake
                */
                    *i = '\0';
            }
        } else {
            /* there is no underscore, so find the first valid character to use
               instead */

            for (i = *strippedlabel; *i != '\0'; ++i)
                if (VALID_SHORTCUT(*i)) {
                    *position = i - *strippedlabel;
                    shortcut = g_unichar_tolower(g_utf8_get_char(i));
                    break;
                }
        }
    }
    return shortcut;
}