Beispiel #1
0
static gboolean
backspace(GntBindable *bind, GList *null)
{
	int len;
	GntEntry *entry = GNT_ENTRY(bind);

	if (entry->cursor <= entry->start)
		return TRUE;

	len = entry->cursor - g_utf8_find_prev_char(entry->start, entry->cursor);
	update_kill_ring(entry, ENTRY_JAIL, entry->cursor, -len);
	entry->cursor -= len;

	memmove(entry->cursor, entry->cursor + len, entry->end - entry->cursor);
	entry->end -= len;

	if (entry->scroll > entry->start)
		entry->scroll = g_utf8_find_prev_char(entry->start, entry->scroll);

	entry_redraw(GNT_WIDGET(entry));
	if (entry->ddown)
		show_suggest_dropdown(entry);
	entry_text_changed(entry);
	return TRUE;
}
Beispiel #2
0
/* query user for a string and jump to the entry
 * which begins with this string while the users types */
void
screen_jump(struct list_window *lw,
		list_window_callback_fn_t callback_fn,
	    list_window_paint_callback_t paint_callback,
		void *callback_data)
{
	char *search_str, *iter, *temp;
	const int WRLN_MAX_LINE_SIZE = 1024;
	int key = 65;
	command_t cmd;

	if (screen.findbuf) {
		g_free(screen.findbuf);
		screen.findbuf = NULL;
	}
	screen.findbuf = g_malloc0(WRLN_MAX_LINE_SIZE);
	/* In screen.findbuf is the whole string which is displayed in the status_window
	 * and search_str is the string the user entered (without the prompt) */
	search_str = screen.findbuf + g_snprintf(screen.findbuf, WRLN_MAX_LINE_SIZE, "%s: ", JUMP_PROMPT);
	iter = search_str;

	while(1) {
		key = screen_getch(screen.findbuf);
		/* if backspace or delete was pressed, process instead of ending loop */
		if (key == KEY_BACKSPACE || key == KEY_DC) {
			int i;
			if (search_str <= g_utf8_find_prev_char(screen.findbuf, iter))
				iter = g_utf8_find_prev_char(screen.findbuf, iter);
			for (i = 0; *(iter + i) != '\0'; i++)
				*(iter + i) = '\0';
			continue;
		}
		/* if a control key was pressed, end loop */
		else if (g_ascii_iscntrl(key) || key == KEY_NPAGE || key == KEY_PPAGE) {
			break;
		}
		else {
			*iter = key;
			if (iter < screen.findbuf + WRLN_MAX_LINE_SIZE - 3)
				++iter;
		}
		list_window_jump(lw, callback_fn, callback_data, search_str);

		/* repaint the list_window */
		if (paint_callback != NULL)
			list_window_paint2(lw, paint_callback, callback_data);
		else
			list_window_paint(lw, callback_fn, callback_data);
		wrefresh(lw->w);
	}

	/* ncmpc should get the command */
	ungetch(key);
	if ((cmd=get_keyboard_command()) != CMD_NONE)
		do_input_event(cmd);

	temp = g_strdup(search_str);
	g_free(screen.findbuf);
	screen.findbuf = temp;
}
Beispiel #3
0
static gboolean
transpose_chars(GntBindable *bind, GList *null)
{
	GntEntry *entry = GNT_ENTRY(bind);
	char *current, *prev;
	char hold[8];  /* that's right */

	if (entry->cursor <= entry->start)
		return FALSE;

	if (!*entry->cursor)
		entry->cursor = g_utf8_find_prev_char(entry->start, entry->cursor);

	current = entry->cursor;
	prev = g_utf8_find_prev_char(entry->start, entry->cursor);
	move_forward(bind, null);

	/* Let's do this dance! */
	memcpy(hold, prev, current - prev);
	memmove(prev, current, entry->cursor - current);
	memcpy(prev + (entry->cursor - current), hold, current - prev);

	update_kill_ring(entry, ENTRY_JAIL, NULL, 0);
	entry_redraw(GNT_WIDGET(entry));
	entry_text_changed(entry);
	return TRUE;
}
Beispiel #4
0
char *TextEdit::prevChar(const char *p) const
{
  if (p >= gapend) {
    if ((p = g_utf8_find_prev_char(gapend, p)))
      return const_cast<char*>(p);
    else
      p = gapstart;
  }

  if ((p = g_utf8_find_prev_char(buffer, p)))
    return const_cast<char*>(p);
  else
    return const_cast<char*>(buffer);
}
Beispiel #5
0
static const char *
begin_word(const char *text, const char *begin)
{
	gunichar ch = 0;
	while (text > begin && (!*text || g_unichar_isspace(g_utf8_get_char(text))))
		text = g_utf8_find_prev_char(begin, text);
	ch = g_utf8_get_char(text);
	while ((text = g_utf8_find_prev_char(begin, text)) >= begin) {
		gunichar cur = g_utf8_get_char(text);
		if (!SAME(ch, cur))
			break;
	}

	return (text ? g_utf8_find_next_char(text, NULL) : begin);
}
Beispiel #6
0
/**
 * g_completion_complete_utf8:
 * @cmp: the #GCompletion
 * @prefix: the prefix string, typically used by the user, which is compared
 *    with each of the items
 * @new_prefix: if non-%NULL, returns the longest prefix which is common to all
 *    items that matched @prefix, or %NULL if no items matched @prefix.
 *    This string should be freed when no longer needed.
 *
 * Attempts to complete the string @prefix using the #GCompletion target items.
 * In contrast to g_completion_complete(), this function returns the largest common
 * prefix that is a valid UTF-8 string, omitting a possible common partial 
 * character.
 *
 * You should use this function instead of g_completion_complete() if your 
 * items are UTF-8 strings.
 *
 * Return value: the list of items whose strings begin with @prefix. This should
 * not be changed.
 *
 * Since: 2.4
 *
 * Deprecated: 2.26: Rarely used API
 **/
GList*
g_completion_complete_utf8 (GCompletion  *cmp,
			    const gchar  *prefix,
			    gchar       **new_prefix)
{
  GList *list;
  gchar *p, *q;

  list = g_completion_complete (cmp, prefix, new_prefix);

  if (new_prefix && *new_prefix)
    {
      p = *new_prefix + strlen (*new_prefix);
      q = g_utf8_find_prev_char (*new_prefix, p);
      
      switch (g_utf8_get_char_validated (q, p - q))
	{
	case (gunichar)-2:
	case (gunichar)-1:
	  *q = 0;
	  break;
	default: ;
	}

    }

  return list;
}
Beispiel #7
0
static gboolean
del_prev_word(GntBindable *bind, GList *null)
{
	GntWidget *widget = GNT_WIDGET(bind);
	GntEntry *entry = GNT_ENTRY(bind);
	char *iter = g_utf8_find_prev_char(entry->start, entry->cursor);
	int count;

	if (iter < entry->start)
		return TRUE;
	iter = (char*)begin_word(iter, entry->start);
	count = entry->cursor - iter;
	update_kill_ring(entry, ENTRY_DEL_BWD_WORD, iter, count);
	memmove(iter, entry->cursor, entry->end - entry->cursor);
	entry->end -= count;
	entry->cursor = iter;
	if (entry->cursor <= entry->scroll) {
		entry->scroll = entry->cursor - widget->priv.width + 2;
		if (entry->scroll < entry->start)
			entry->scroll = entry->start;
	}
	memset(entry->end, '\0', entry->buffer - (entry->end - entry->start));
	entry_redraw(widget);
	entry_text_changed(entry);

	return TRUE;
}
Beispiel #8
0
static gchar *line_from_buffer(gchar *buffer, guint offset) {
	gint i,j;
	i=j=offset;
	while (i >=0 && i > (offset-40)) {
		if (buffer[i] == '\n' || buffer[i] == '\r') {
			break;
		}
		i--;
	}
	if (i <= offset-40) {
		gchar *tmp = g_utf8_find_next_char(buffer+i, NULL);
		if (tmp)
			i = tmp-buffer;
	} else {
		i++;
	}
	while (buffer[j] !='\0' && j < (offset+40)) {
		if (buffer[j] == '\n' || buffer[j] == '\r') {
			break;
		}
		j++;
	}
	if (j >= offset+40) {
		gchar *tmp = g_utf8_find_prev_char(buffer, buffer+j);
		if (tmp)
			j = tmp-buffer;
	}
	return g_strndup(buffer+i, j-i);
}
Beispiel #9
0
/* Try to move the cursor backward n characters.  Does not modify command line
   if unsuccessful. */
gboolean cmd_backward(struct cmdline* cmd, gint n, gboolean do_it) {
	g_return_val_if_fail(n >= 0, FALSE);

	if (cmd->is_utf8) {
		gint i;
		gint new_pos = cmd->pos;
		for (i = 0; i < n; i++) {
			gchar* prev = g_utf8_find_prev_char(cmd->data->str,
					cmd->data->str + new_pos);
			if (!prev)
				return FALSE;

			new_pos = prev - cmd->data->str;
		}
		if (do_it)
			cmd->pos = new_pos;
	}
	else {
		/* Just need to shift by n. */
		if (cmd->pos - n >= 0) {
			if (do_it)
				cmd->pos -= n;
		}
		else
			return FALSE;
	}

	return TRUE;
}
Beispiel #10
0
/*! \brief Get name and value from an attribute 'name=value' string.
 *  \par Function Description
 *  This function parses the character string \a string expected to be
 *  an attribute string of the form 'name=value'.
 *
 *  It returns TRUE if it has been able to parse the string into the
 *  name and value parts of an attribute. Otherwise it returns FALSE,
 *  in that case \a *name_ptr and \a *value_ptr are set to NULL.
 *
 *  \a name_ptr and/or \a value_ptr can be NULL.
 *  If not NULL, the caller must g_free these returned strings.
 *
 *  \note
 *  If you get an invalid attribute (improper) with a name and no
 *  value, then it is NOT an attribute. Also, there cannot be any
 *  spaces beside the equals sign
 *
 *  \param [in]  string     String to split into name/value pair.
 *  \param [out] name_ptr   The return location for the name, or NULL.
 *  \param [out] value_ptr  The return location for the value, or NULL.
 *  \return TRUE on success, FALSE otherwise.
 */
gboolean
o_attrib_string_get_name_value (const gchar *string, gchar **name_ptr, gchar **value_ptr)
{
  gchar *ptr, *prev_char, *next_char;

  if (name_ptr != NULL)
    *name_ptr = NULL;
  if (value_ptr != NULL)
    *value_ptr = NULL;

  g_return_val_if_fail (string != NULL, FALSE);

  ptr = g_utf8_strchr (string, -1, g_utf8_get_char ("="));
  if (ptr == NULL) {
    return FALSE;
  }

  prev_char = g_utf8_find_prev_char (string, ptr);
  next_char = g_utf8_find_next_char (ptr, NULL);
  if (prev_char == NULL || *prev_char == ' ' ||
      next_char == NULL || *next_char == ' ' || *next_char == '\0' ) {
    return FALSE;
  }

  if (name_ptr != NULL) {
    *name_ptr = g_strndup (string, (ptr - string));
  }

  if (value_ptr != NULL) {
    *value_ptr = g_strdup (next_char);
  }

  return TRUE;
}
Beispiel #11
0
/**************************************************************************
  Autocompletes the input line with a player or user name.
  Returns FALSE if there is no string to complete.
**************************************************************************/
static bool chatline_autocomplete(GtkEditable *editable)
{
#define MAX_MATCHES 10
  const char *name[MAX_MATCHES];
  char buf[MAX_LEN_NAME * MAX_MATCHES];
  gint pos;
  gchar *chars, *p, *prev;
  int num, i;
  size_t prefix_len;

  /* Part 1: get the string to complete. */
  pos = gtk_editable_get_position(editable);
  chars = gtk_editable_get_chars(editable, 0, pos);

  p = chars + strlen(chars);
  while ((prev = g_utf8_find_prev_char(chars, p))) {
    if (!g_unichar_isalnum(g_utf8_get_char(prev))) {
      break;
    }
    p = prev;
  }
  /* p points to the start of the last word, or the start of the string. */

  prefix_len = g_utf8_strlen(p, -1);
  if (0 == prefix_len) {
    /* Empty: nothing to complete, propagate the event. */
    g_free(chars);
    return FALSE;
  }

  /* Part 2: compare with player and user names. */
  num = check_player_or_user_name(p, name, MAX_MATCHES);
  if (1 == num) {
    gtk_editable_delete_text(editable, pos - prefix_len, pos);
    pos -= prefix_len;
    gtk_editable_insert_text(editable, name[0], strlen(name[0]), &pos);
    gtk_editable_set_position(editable, pos);
    g_free(chars);
    return TRUE;
  } else if (num > 1) {
    if (get_common_prefix(name, num, buf, sizeof(buf)) > prefix_len) {
      gtk_editable_delete_text(editable, pos - prefix_len, pos);
      pos -= prefix_len;
      gtk_editable_insert_text(editable, buf, strlen(buf), &pos);
      gtk_editable_set_position(editable, pos);
    }
    sz_strlcpy(buf, name[0]);
    for (i = 1; i < num; i++) {
      cat_snprintf(buf, sizeof(buf), ", %s", name[i]);
    }
    /* TRANS: comma-separated list of player/user names for completion */
    output_window_printf(ftc_client, _("Suggestions: %s."), buf);
  }

  g_free(chars);
  return TRUE;
}
Beispiel #12
0
static char *
truncate_name (const char *name)
{
	const char *end;

	end = g_utf8_find_prev_char (name, name + 64);
	g_assert (end != NULL);
	return g_strndup (name, end - name);
}
Beispiel #13
0
static void
text_move_cursor(Text *text, CursorMovement mv)
{
  gchar *str = text_line_get_string(text->lines[text->cursor_row]);
  gchar *p = str;
  int curmax = text_get_line_strlen(text, text->cursor_row);
  if (text->cursor_pos > 0 && text->cursor_pos <= curmax) {
    int i;
    for (i = 0; i < text->cursor_pos; ++i)
      p = g_utf8_next_char (p);
  } 
  if (WORD_START == mv && text->cursor_pos < 1) {
    if (text->cursor_row) {
      text->cursor_row--;
      text->cursor_pos = text_get_line_strlen(text, text->cursor_row);
    }
    return;
  } else if (WORD_END == mv && text->cursor_pos == curmax) {
    if (text->cursor_row < text->numlines - 1) {
      text->cursor_row++;
      text->cursor_pos = 0;
    }
    return;
  }
  while (!g_unichar_isalnum (g_utf8_get_char (p))) {
    p = (WORD_START == mv ? g_utf8_find_prev_char (str, p) : g_utf8_next_char (p));
    if (p) text->cursor_pos += (WORD_START == mv ? -1 : 1);
    if (!p || !*p)
      return;
    if (!text->cursor_pos || text->cursor_pos == curmax)
      return;
  }
  while (g_unichar_isalnum (g_utf8_get_char (p))) {
    p = (WORD_START == mv ? g_utf8_find_prev_char (str, p) : g_utf8_next_char (p));
    if (p) text->cursor_pos += (WORD_START == mv ? -1 : 1);
    if (!p || !*p)
      return;
    if (!text->cursor_pos || text->cursor_pos == curmax)
      return;
  }
}
Beispiel #14
0
const char* mime_cache_lookup_suffix( MimeCache* cache, const char* filename, const char** suffix_pos )
{
    const char* root = cache->suffix_roots;
    int i, n = cache->n_suffix_roots;
    const char* mime_type = NULL, *ret = NULL, *prev_suffix_pos = (const char*)-1;
    int fn_len, n_nodes;

    if( G_UNLIKELY( ! filename || ! *filename || 0 == n ) )
        return NULL;

    if( cache->has_reverse_suffix )  /* since mime.cache ver: 1.1 */
    {
        const char *suffix, *leaf_node, *_suffix_pos = (const char*)-1;
        fn_len = strlen( filename );
        suffix = g_utf8_find_prev_char( filename, filename + fn_len );
        leaf_node = lookup_reverse_suffix_nodes( cache->buffer, root, n, filename, suffix, &_suffix_pos );

        if( leaf_node )
        {
            mime_type = cache->buffer + VAL32( leaf_node, 4 );
            /* g_debug( "found: %s", mime_type ); */
            *suffix_pos = _suffix_pos;
            ret = mime_type;
        }
    }
    else  /* before mime.cache ver: 1.1 */
    {
        for( i = 0; i <n; ++i, root += 16 )
        {
            guint32 first_child_off;
            guint32 ch = VAL32( root, 0 );
            const char* suffix;

            suffix = strchr( filename, ch );
            if( ! suffix )
                continue;

            first_child_off = VAL32( root, 12 );
            // FIXME: is this correct???
            n = VAL32( root, 8 );
            do{
                mime_type = lookup_suffix_nodes( cache->buffer, cache->buffer + first_child_off, n, g_utf8_next_char(suffix) );
                if( mime_type && suffix < prev_suffix_pos ) /* we want the longest suffix matched. */
                {
                    ret = mime_type;
                    prev_suffix_pos = suffix;
                }
            }while( (suffix = strchr( suffix + 1, ch )) );
        }
        *suffix_pos = ret ? prev_suffix_pos : (const char*)-1;
    }
    return ret;
}
static void
test_find (void)
{
  /* U+0B0B Oriya Letter Vocalic R (\340\254\213)
   * U+10900 Phoenician Letter Alf (\360\220\244\200)
   * U+0041 Latin Capital Letter A (\101)
   * U+1EB6 Latin Capital Letter A With Breve And Dot Below (\341\272\266)
   */
  const gchar *str = "\340\254\213\360\220\244\200\101\341\272\266\0\101";
  const gchar *p = str + strlen (str);
  const gchar *q;

  q = g_utf8_find_prev_char (str, p);
  g_assert (q == str + 8);
  q = g_utf8_find_prev_char (str, q);
  g_assert (q == str + 7);
  q = g_utf8_find_prev_char (str, q);
  g_assert (q == str + 3);
  q = g_utf8_find_prev_char (str, q);
  g_assert (q == str);
  q = g_utf8_find_prev_char (str, q);
  g_assert (q == NULL);

  p = str + 2;
  q = g_utf8_find_next_char (p, NULL);
  g_assert (q == str + 3);
  q = g_utf8_find_next_char (q, NULL);
  g_assert (q == str + 7);

  q = g_utf8_find_next_char (p, str + 6);
  g_assert (q == str + 3);
  q = g_utf8_find_next_char (q, str + 6);
  g_assert (q == NULL);

  q = g_utf8_find_next_char (str, str);
  g_assert (q == NULL);

  q = g_utf8_find_next_char (str + strlen (str), NULL);
  g_assert (q == str + strlen (str) + 1);
}
Beispiel #16
0
static gboolean
move_back(GntBindable *bind, GList *null)
{
	GntEntry *entry = GNT_ENTRY(bind);
	if (entry->cursor <= entry->start)
		return FALSE;
	entry->cursor = g_utf8_find_prev_char(entry->start, entry->cursor);
	if (entry->cursor < entry->scroll)
		entry->scroll = entry->cursor;
	update_kill_ring(entry, ENTRY_JAIL, NULL, 0);
	entry_redraw(GNT_WIDGET(entry));
	return TRUE;
}
Beispiel #17
0
void mosaic_search_box_remove_symbols (MosaicSearchBox *box, guint size)
{
  gchar *text = g_strdup (mosaic_search_box_get_text (box));
  if (strlen (text)) {
    gchar *p = text + strlen (text);
    for (int i = 0; i < size; i++) {
      p = g_utf8_find_prev_char (text, p);
      *p = '\0';
    }
    mosaic_search_box_set_text (box, text);
  }
  g_free (text);
}
Beispiel #18
0
static char *
get_beginning_of_word(GntEntry *entry)
{
	char *s = entry->cursor;
	while (s > entry->start)
	{
		char *t = g_utf8_find_prev_char(entry->start, s);
		if (isspace(*t))
			break;
		s = t;
	}
	return s;
}
Beispiel #19
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;
}
static gchar *
video_sanitise_string (const gchar *str)
{
  int    i;
  gchar *line, *line_end;
  GRegex *regex;

  line = (gchar *) str;
  for (i = 0; video_blacklisted_prefix[i]; i++) {
    if (g_str_has_prefix (str, video_blacklisted_prefix[i])) {
      int len = strlen (video_blacklisted_prefix[i]);

      line = (gchar *) str + len;
    }
  }

  /* Get the substring limited by the first blacklisted word */
  line_end = line + strlen (line);
  for (i = 0; video_blacklisted_words[i]; i++) {
    gchar *end;

    end = strcasestr (line, video_blacklisted_words[i]);
    if (end && end < line_end) {
      line_end = end;
    }
  }

  if (*line_end != '\0') {
    /* After removing substring with blacklisted word, ignore non alpha-numeric
     * char in the end of the sanitised string */
    do {
      line_end = g_utf8_find_prev_char (line, line_end);
    } while (is_nonalnum (line_end));

    /* If everything in the string is blacklisted, just ignore
     * the blackisting logic.
     */
    if (line_end == NULL) {
      return g_strdup (str);
    }

    return g_strndup (line, line_end - line);
  }

  regex = g_regex_new ("\\.-\\.", 0, 0, NULL);
  line = g_regex_replace_literal(regex, line, -1, 0, ".", 0, NULL);
  g_regex_unref(regex);

  return line;
}
static guint
bastile_secure_buffer_real_insert_text (GtkEntryBuffer *buffer, guint position,
                                         const gchar *chars, guint n_chars)
{
	BastileSecureBuffer *self = BASTILE_SECURE_BUFFER (buffer);
	BastileSecureBufferPrivate *pv = self->priv;
	gsize n_bytes;
	gsize at;

	n_bytes = g_utf8_offset_to_pointer (chars, n_chars) - chars;

	/* Need more memory */
	if (n_bytes + pv->text_bytes + 1 > pv->text_size) {

		/* Calculate our new buffer size */
		while (n_bytes + pv->text_bytes + 1 > pv->text_size) {
			if (pv->text_size == 0) {
				pv->text_size = MIN_SIZE;
			} else {
				if (2 * pv->text_size < GTK_ENTRY_BUFFER_MAX_SIZE) {
					pv->text_size *= 2;
				} else {
					pv->text_size = GTK_ENTRY_BUFFER_MAX_SIZE;
					if (n_bytes > pv->text_size - pv->text_bytes - 1) {
						n_bytes = pv->text_size - pv->text_bytes - 1;
						n_bytes = g_utf8_find_prev_char (chars, chars + n_bytes + 1) - chars;
						n_chars = g_utf8_strlen (chars, n_bytes);
					}
					break;
				}
			}
		}

		pv->text = mate_keyring_memory_realloc (pv->text, pv->text_size);
	}

	/* Actual text insertion */
	at = g_utf8_offset_to_pointer (pv->text, position) - pv->text;
	g_memmove (pv->text + at + n_bytes, pv->text + at, pv->text_bytes - at);
	memcpy (pv->text + at, chars, n_bytes);

	/* Book keeping */
	pv->text_bytes += n_bytes;
	pv->text_chars += n_chars;
	pv->text[pv->text_bytes] = '\0';

	gtk_entry_buffer_emit_inserted_text (buffer, position, chars, n_chars);
	return n_chars;
}
Beispiel #22
0
static gboolean
move_back_word(GntBindable *bind, GList *null)
{
	GntEntry *entry = GNT_ENTRY(bind);
	const char *iter = g_utf8_find_prev_char(entry->start, entry->cursor);

	if (iter < entry->start)
		return TRUE;
	iter = begin_word(iter, entry->start);
	entry->cursor = (char*)iter;
	if (entry->cursor < entry->scroll)
		entry->scroll = entry->cursor;
	update_kill_ring(entry, ENTRY_JAIL, NULL, 0);
	entry_redraw(GNT_WIDGET(bind));
	return TRUE;
}
Beispiel #23
0
void mosaic_search_box_kill_word (MosaicSearchBox *box)
{
  const gchar *text = mosaic_search_box_get_text (box);
  gint size = strlen (text);
  if (size) {
    const gchar *p = text + size;
    int len = 0;
    while (p > text) {
      p = g_utf8_find_prev_char (text, p);
      gunichar c = g_utf8_get_char (p);
      if (g_unichar_isspace (c) && len > 0)
	break;

      len++;
    }
    mosaic_search_box_remove_symbols (box, len);
  }
}
Beispiel #24
0
void str_rtrim(char *str)
{
	int len = strlen(str);
	char *last = str + len;
	char *curr = last - 1;

	if (len == 0)
		return;
	
	while (*curr == ' ' || *curr == '\t' || *curr == '\r' || *curr == '\n') {
		last = curr;
		curr = g_utf8_find_prev_char(str, curr);
		if (curr == NULL)
			break;
	}

	*last = 0;
}
Beispiel #25
0
gsize
qof_strftime(gchar *buf, gsize max, const gchar *format, const struct tm *tm)
{
    gsize convlen, retval;
    gchar *convbuf;

    g_return_val_if_fail(buf, 0);
    g_return_val_if_fail(max > 0, 0);
    g_return_val_if_fail(format, 0);
    g_return_val_if_fail(tm, 0);

    convbuf = qof_format_time(format, tm);
    if (!convbuf)
    {
        buf[0] = '\0';
        return 0;
    }

    convlen = strlen(convbuf);

    if (max <= convlen)
    {
        /* Ensure only whole characters are copied into the buffer. */
        gchar *end = g_utf8_find_prev_char(convbuf, convbuf + max);
        g_assert(end != NULL);
        convlen = end - convbuf;

        /* Return 0 because the buffer isn't large enough. */
        retval = 0;
    }
    else
    {
        retval = convlen;
    }

    memcpy(buf, convbuf, convlen);
    buf[convlen] = '\0';
    g_free(convbuf);

    return retval;
}
Beispiel #26
0
gsize
e_utf8_strftime_fix_am_pm (gchar *str,
                           gsize max,
                           const gchar *fmt,
                           const struct tm *tm)
{
  gsize sz, ret;
  gchar *locale_fmt, *buf;

  locale_fmt = g_locale_from_utf8 (fmt, -1, NULL, &sz, NULL);
  if (!locale_fmt)
    return 0;

  ret = e_strftime_fix_am_pm (str, max, locale_fmt, tm);
  if (!ret) {
    g_free (locale_fmt);
    return 0;
  }

  buf = g_locale_to_utf8 (str, ret, NULL, &sz, NULL);
  if (!buf) {
    g_free (locale_fmt);
    return 0;
  }

  if (sz >= max) {
    gchar *tmp = buf + max - 1;
    tmp = g_utf8_find_prev_char (buf, tmp);
    if (tmp)
      sz = tmp - buf;
    else
      sz = 0;
  }
  memcpy (str, buf, sz);
  str[sz] = '\0';
  g_free (locale_fmt);
  g_free (buf);
  return sz;
}
Beispiel #27
0
/* Determine whether there is whitespace to the left of the cursor. */
gboolean cmd_whitespace_to_left(struct cmdline* cmd, gchar* holdover) {
	gboolean result;

	if ( (cmd->pos == 0) ||
	     /* Kludge: if the shell buffer has a holdover, which consists
			only of a space, it's reasonable to assume it won't
			complete a sequence and will end up being added to the
			command line. */
			 (holdover && strlen(holdover) == 1 && *(holdover) == ' ') )
		result = TRUE;
	else {
		if (cmd->is_utf8) {
			gchar* previous = g_utf8_find_prev_char(
					cmd->data->str, cmd->data->str + cmd->pos);

			result = previous && g_unichar_isspace(g_utf8_get_char(previous));
		}
		else
			result = isspace( *(cmd->data->str + cmd->pos - 1) );
	}

	return result;
}
static void
validate_and_insert (GeditDocumentOutputStream *stream,
                     const gchar               *buffer,
                     gsize                      count)
{
	GtkTextBuffer *text_buffer;
	GtkTextIter   *iter;
	gsize len;

	text_buffer = GTK_TEXT_BUFFER (stream->priv->doc);
	iter = &stream->priv->pos;
	len = count;

	while (len != 0)
	{
		const gchar *end;
		gboolean valid;
		gsize nvalid;

		/* validate */
		valid = g_utf8_validate (buffer, len, &end);
		nvalid = end - buffer;

		/* Note: this is a workaround for a 'bug' in GtkTextBuffer where
		   inserting first a \r and then in a second insert, a \n,
		   will result in two lines being added instead of a single
		   one */

		if (valid)
		{
			gchar *ptr;

			ptr = g_utf8_find_prev_char (buffer, buffer + len);

			if (ptr && *ptr == '\r' && ptr - buffer == len - 1)
			{
				stream->priv->buffer = g_new (gchar, 1);
				stream->priv->buffer[0] = '\r';
				stream->priv->buflen = 1;

				/* Decrease also the len so in the check
				   nvalid == len we get out of this method */
				--nvalid;
				--len;
			}
		}

		/* if we've got any valid char we must tag the invalid chars */
		if (nvalid > 0)
		{
			apply_error_tag (stream);
		}

		gtk_text_buffer_insert (text_buffer, iter, buffer, nvalid);

		/* If we inserted all return */
		if (nvalid == len)
		{
			break;
		}

		buffer += nvalid;
		len = len - nvalid;

		if ((len < MAX_UNICHAR_LEN) &&
		    (g_utf8_get_char_validated (buffer, len) == (gunichar)-2))
		{
			stream->priv->buffer = g_strndup (end, len);
			stream->priv->buflen = len;

			break;
		}

		/* we need the start of the chunk of invalid chars */
		if (stream->priv->error_offset == -1)
		{
			stream->priv->error_offset = gtk_text_iter_get_offset (&stream->priv->pos);
		}

		insert_fallback (stream, buffer);
		++buffer;
		--len;
	}
}
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);
}
Beispiel #30
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;
}