int main (int argc, char *argv[]) { GCompletion *cmp; GList *items; gchar *prefix; #ifdef __SYMBIAN32__ g_log_set_handler (NULL, G_LOG_FLAG_FATAL| G_LOG_FLAG_RECURSION | G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING | G_LOG_LEVEL_MESSAGE | G_LOG_LEVEL_INFO | G_LOG_LEVEL_DEBUG, &mrtLogHandler, NULL); g_set_print_handler(mrtPrintHandler); #endif /*__SYMBIAN32__*/ cmp = g_completion_new (NULL); items = NULL; items = g_list_append (items, "a\302\243"); items = g_list_append (items, "a\302\244"); items = g_list_append (items, "bb"); items = g_list_append (items, "bc"); g_completion_add_items (cmp, items); items = g_completion_complete (cmp, "a", &prefix); g_assert (!strcmp ("a\302", prefix)); g_assert (g_list_length (items) == 2); g_free (prefix); items = g_completion_complete_utf8 (cmp, "a", &prefix); g_assert (!strcmp ("a", prefix)); g_assert (g_list_length (items) == 2); g_free (prefix); items = g_completion_complete (cmp, "b", &prefix); g_assert (!strcmp ("b", prefix)); g_assert (g_list_length (items) == 2); g_free (prefix); items = g_completion_complete_utf8 (cmp, "b", &prefix); g_assert (!strcmp ("b", prefix)); g_assert (g_list_length (items) == 2); g_free (prefix); items = g_completion_complete (cmp, "a", NULL); g_assert (g_list_length (items) == 2); items = g_completion_complete_utf8 (cmp, "a", NULL); g_assert (g_list_length (items) == 2); g_completion_free (cmp); #if __SYMBIAN32__ testResultXml("completion-test"); #endif /* EMULATOR */ return 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; }
int main (int argc, char *argv[]) { GCompletion *cmp; GList *items; gchar *prefix; #ifdef SYMBIAN g_log_set_handler (NULL, G_LOG_FLAG_FATAL| G_LOG_FLAG_RECURSION | G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING | G_LOG_LEVEL_MESSAGE | G_LOG_LEVEL_INFO | G_LOG_LEVEL_DEBUG, &mrtLogHandler, NULL); #endif cmp = g_completion_new (NULL); items = NULL; items = g_list_append (items, "Abcdef"); items = g_list_append (items, "AbcDEF"); items = g_list_append (items, "bc"); items = g_list_append (items, "bd"); g_completion_add_items (cmp, items); g_completion_set_compare(cmp,strncasecmp); items = g_completion_complete (cmp, "aB", &prefix); g_assert (!strcmp ("aBc", prefix)); g_free (prefix); g_completion_remove_items(cmp,items); items = g_completion_complete (cmp, "aB", &prefix); // g_assert(items == NULL); items = g_completion_complete (cmp, "b", &prefix); g_assert(!strcmp("b",prefix)); g_free(prefix); g_completion_clear_items(cmp); items = g_completion_complete (cmp, "b", &prefix); g_assert(items == NULL); #if SYMBIAN testResultXml("completion_test"); #endif /* EMULATOR */ return 0; }
int main (int argc, char *argv[]) { GCompletion *cmp; GList *items; gchar *prefix; cmp = g_completion_new (NULL); items = NULL; items = g_list_append (items, "a\302\243"); items = g_list_append (items, "a\302\244"); items = g_list_append (items, "bb"); items = g_list_append (items, "bc"); g_completion_add_items (cmp, items); items = g_completion_complete (cmp, "a", &prefix); g_assert (!strcmp ("a\302", prefix)); g_assert (g_list_length (items) == 2); g_free (prefix); items = g_completion_complete_utf8 (cmp, "a", &prefix); g_assert (!strcmp ("a", prefix)); g_assert (g_list_length (items) == 2); g_free (prefix); items = g_completion_complete (cmp, "b", &prefix); g_assert (!strcmp ("b", prefix)); g_assert (g_list_length (items) == 2); g_free (prefix); items = g_completion_complete_utf8 (cmp, "b", &prefix); g_assert (!strcmp ("b", prefix)); g_assert (g_list_length (items) == 2); g_free (prefix); items = g_completion_complete (cmp, "a", NULL); g_assert (g_list_length (items) == 2); items = g_completion_complete_utf8 (cmp, "a", NULL); g_assert (g_list_length (items) == 2); g_completion_free (cmp); return 0; }
int main (int argc, char* argv[]) { FILE *file; gchar buf[1024]; GList *list; GList *result; GList *tmp; GCompletion *cmp; gint i; gchar *longp = NULL; if (argc < 3) { g_warning ("Usage: %s filename prefix1 [prefix2 ...]\n", argv[0]); return 1; } file = fopen (argv[1], "r"); if (!file) { g_warning ("Cannot open %s\n", argv[1]); return 1; } cmp = g_completion_new (NULL); list = g_list_alloc (); while (fgets (buf, 1024, file)) { list->data = g_strdup (buf); g_completion_add_items (cmp, list); } fclose (file); for (i = 2; i < argc; ++i) { printf ("COMPLETING: %s\n", argv[i]); result = g_completion_complete (cmp, argv[i], &longp); g_list_foreach (result, (GFunc) printf, NULL); printf ("LONG MATCH: %s\n", longp); g_free (longp); longp = NULL; } g_list_foreach (cmp->items, (GFunc) g_free, NULL); g_completion_free (cmp); g_list_free (list); return 0; }
/** * Attempt to complete an address, and returns the number of addresses found. * Use <code>get_complete_address()</code> to get an entry from the index. * * \param str Search string to find. * \return Zero if no match was found, otherwise the number of addresses; the * original prefix (search string) will appear at index 0. */ guint complete_address(const gchar *str) { GList *result = NULL; gchar *d = NULL; guint count = 0; guint cpl = 0; completion_entry *ce = NULL; cm_return_val_if_fail(str != NULL, 0); /* g_completion is case sensitive */ d = g_utf8_strdown(str, -1); clear_completion_cache(); g_completion_prefix = g_strdup(str); result = g_completion_complete(g_completion, d, NULL); count = g_list_length(result); if (count) { /* create list with unique addresses */ for (cpl = 0, result = g_list_first(result); result != NULL; result = g_list_next(result)) { ce = (completion_entry *)(result->data); if (NULL == g_slist_find(g_completion_addresses, ce->ref)) { cpl++; g_completion_addresses = g_slist_append(g_completion_addresses, ce->ref); } } count = cpl + 1; /* index 0 is the original prefix */ g_completion_next = 1; /* we start at the first completed one */ if (prefs_common.address_search_wildcard) g_completion_addresses = g_slist_sort(g_completion_addresses, addr_comparison_func); } else { g_free(g_completion_prefix); g_completion_prefix = NULL; } g_completion_count = count; g_free(d); return count; }
/** * complete_matches_found() returns the number of matched addresses according * to the completion mechanism. Unlike complete_address(), the returned value * doesn't count str itself. If there's no match, it returns 0. * To get a list of completion matches, see complete_address() instead. */ guint complete_matches_found(const gchar *str) { GList *result = NULL; gchar *d = NULL; cm_return_val_if_fail(str != NULL, 0); /* g_completion is case sensitive */ d = g_utf8_strdown(str, -1); clear_completion_cache(); g_completion_prefix = g_strdup(str); result = g_completion_complete(g_completion, d, NULL); g_free(g_completion_prefix); g_free(d); return g_list_length(result); }
static VALUE rg_complete(VALUE self, VALUE prefix) { gchar* new_prefix; VALUE ary = rb_ary_new(); #if GLIB_CHECK_VERSION(2,4,0) GList* list = g_completion_complete_utf8(_SELF(self), (const gchar*)RVAL2CSTR(prefix), &new_prefix); #else GList* list = g_completion_complete(_SELF(self), RVAL2CSTR(prefix), &new_prefix); #endif while (list) { rb_ary_push(ary, RARRAY_PTR((VALUE)list->data)[1]); list = list->next; } return rb_assoc_new(ary, new_prefix ? CSTR2RVAL(new_prefix) : Qnil); }
/* * cmdc() -- command completion function. * * cmdc takes a char* and returns a GList* of possible completions. * * Initial version by Travis Hume <*****@*****.**>. * */ static GList * cmdc( char *s ) { GCompletion *completion = NULL; GList *ret_list = NULL; static GHashTable *path_hash = NULL; static char *path = NULL; gchar *path_elem; struct stat buf; static gboolean inited = FALSE; gpointer hash_key = NULL; /* * Only want to build the GCompletion once. At some point I'd like to add * code to refresh the GCompletion, either at a regular interval, or when * there is a completion failure, ... * */ if(!inited) { /* Make a local copy of the path variable. Otherwise the path environment variable would be modified. */ path = (char *) malloc(sizeof(char) * (strlen(getenv("PATH")) + 1)); strcpy(path, getenv("PATH")); path_hash = g_hash_table_new( g_str_hash, g_str_equal ); for( path_elem = strtok( path, ":" ); path_elem; path_elem = strtok( NULL, ":" )) { if( stat( path_elem, &buf )) continue; if( buf.st_mode & S_IFDIR ) { /* keep a hash of processed paths, to avoid reprocessing * dupped path entries. */ hash_key = g_hash_table_lookup( path_hash, path_elem ); if( hash_key ) continue; /* duplicate $PATH entry */ else { g_hash_table_insert( path_hash, (gpointer)path_elem, (gpointer)path_elem ); process_dir( path_elem ); } } } /* atexit() we want to free the completion. */ g_atexit( cleanup ); inited = TRUE; } completion = g_completion_new( NULL ); g_completion_add_items( completion, path_elements ); ret_list = g_list_copy( g_completion_complete( completion, s, NULL )); g_completion_free( completion ); return g_list_sort( ret_list, (GCompareFunc)g_list_str_cmp ); }
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, found = 0, prefix_len, skip_len = 0, is_nick, is_cmd = 0; char buf[COMP_BUF], ent[CHANLEN], *postfix = NULL, *result, *ch; GList *list = NULL, *tmp_list = NULL; const char *text; GCompletion *gcomp = NULL; /* 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); buf[0] = 0; /* make sure we don't get garbage in the buffer */ /* 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) == prefs.nick_suffix[0])) { 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.cmdchar[0]) { ent_start++; is_cmd = 1; } prefix_len = ent_start; elen = cursor_pos - ent_start; g_utf8_strncpy (ent, g_utf8_offset_to_pointer (text, prefix_len), elen); is_nick = (ent[0] == '#' || ent[0] == '&' || is_cmd) ? 0 : 1; 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 = 0; } 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.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; } #if GLIB_CHECK_VERSION(2,4,0) list = g_completion_complete_utf8 (gcomp, comp ? old_gcomp.data : ent, &result); #else list = g_completion_complete (gcomp, comp ? old_gcomp.data : ent, &result); #endif 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 = 1; 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.completion_amount && g_list_length (list) <= prefs.completion_amount) { g_free(result); result = (char*)list->data; } else { /* bash style completion */ if (g_list_next(list) != NULL) { if (strlen (result) > elen) /* the largest common prefix is larger than nick, change the data */ { if (prefix_len) g_utf8_strncpy (buf, text, prefix_len); strncat (buf, result, COMP_BUF - prefix_len); cursor_pos = strlen (buf); g_free(result); #if !GLIB_CHECK_VERSION(2,4,0) g_utf8_validate (buf, -1, (const gchar **)&result); (*result) = 0; #endif if (postfix) { strcat (buf, " "); strncat (buf, postfix, COMP_BUF - cursor_pos -1); } SPELL_ENTRY_SET_TEXT (t, buf); SPELL_ENTRY_SET_POS (t, g_utf8_pointer_to_offset(buf, buf + cursor_pos)); buf[0] = 0; } else g_free(result); while (list) { len = strlen (buf); /* current buffer */ elen = strlen (list->data); /* next item to add */ if (len + elen + 2 >= COMP_BUF) /* +2 is space + null */ { PrintText (sess, buf); buf[0] = 0; len = 0; } strcpy (buf + len, (char *) list->data); strcpy (buf + len + elen, " "); list = list->next; } PrintText (sess, buf); g_completion_free(gcomp); return 2; } /* Only one matching entry */ g_free(result); result = list->data; } } } if(result) { if (prefix_len) g_utf8_strncpy(buf, text, prefix_len); strncat (buf, result, COMP_BUF - (prefix_len + 3)); /* make sure nicksuffix and space fits */ if(!prefix_len && is_nick) strcat (buf, &prefs.nick_suffix[0]); strcat (buf, " "); cursor_pos = strlen (buf); if (postfix) strncat (buf, postfix, COMP_BUF - cursor_pos - 2); SPELL_ENTRY_SET_TEXT (t, buf); SPELL_ENTRY_SET_POS (t, g_utf8_pointer_to_offset(buf, buf + cursor_pos)); } if (gcomp) g_completion_free(gcomp); return 2; }
void autocomp_run(BluefishTextView * btv, gboolean user_requested) { GtkTextIter cursorpos, iter; BluefishTextView *master = BLUEFISH_TEXT_VIEW(btv->master); gint contextnum; gunichar uc; Tfound *found=NULL; Tfoundblock *fblock = NULL; /* needed for the special case to close generix xml tags based on the top of the blockstack, or to match conditional autocompletion strings */ if (G_UNLIKELY(!master->bflang || !master->bflang->st)) return; gtk_text_buffer_get_iter_at_mark(btv->buffer, &cursorpos, gtk_text_buffer_get_insert(btv->buffer)); iter = cursorpos; gtk_text_iter_set_line_offset(&iter, 0); scan_for_autocomp_prefix(master, &iter, &cursorpos, &contextnum); DBG_AUTOCOMP("autocomp_run, got possible match start at %d in context %d, cursor is at %d\n", gtk_text_iter_get_offset(&iter), contextnum, gtk_text_iter_get_offset(&cursorpos)); /* see if character at cursor is end or symbol */ uc = gtk_text_iter_get_char(&cursorpos); if (G_UNLIKELY(uc > NUMSCANCHARS)) return; /*identstate = g_array_index(master->bflang->st->contexts, Tcontext, contextnum).identstate;*/ if (!character_is_symbol(master->bflang->st,contextnum,uc)) { /* current character is not a symbol! */ DBG_AUTOCOMP("autocomp_run, character at cursor %d '%c' is not a symbol, return\n", uc, (char) uc); acwin_cleanup(btv); return; } /* see if we have enough characters */ if (!user_requested && gtk_text_iter_get_offset(&cursorpos) - gtk_text_iter_get_offset(&iter) < main_v->props.autocomp_min_prefix_len) { DBG_AUTOCOMP("autocomp_run, prefix len %d < autocomp_min_prefix_len (%d), abort!\n" , gtk_text_iter_get_offset(&cursorpos) - gtk_text_iter_get_offset(&iter) , main_v->props.autocomp_min_prefix_len); acwin_cleanup(btv); return; } if (g_array_index(master->bflang->st->contexts, Tcontext, contextnum).has_tagclose_from_blockstack) { found = get_foundcache_at_offset(btv, gtk_text_iter_get_offset(&cursorpos), NULL); if (found) { fblock = found->numblockchange < 0 ? pop_blocks(found->numblockchange, found->fblock) : found->fblock; if (fblock && fblock->start2_o != BF_OFFSET_UNDEFINED) { DBG_AUTOCOMP("abort offering closing tag: block has an end already\n"); fblock = NULL; } /* if (g_array_index(btv->bflang->st->matches, Tpattern, fblock->patternum).tagclose_from_blockstack) { gchar *start; gtk_text_buffer_get_iter_at_mark(buffer, &it1, fblock->start1); gtk_text_buffer_get_iter_at_mark(buffer, &it2, fblock->end1); gtk_text_iter_forward_char(&it1); start = gtk_text_buffer_get_text(buffer,&it1,&it2,TRUE); g_print("close tag %s\n",start); g_free(start); }*/ } } if ((user_requested || !gtk_text_iter_equal(&iter, &cursorpos)) && (g_array_index(master->bflang->st->contexts, Tcontext, contextnum).ac != NULL || (fblock && g_array_index(master->bflang->st->matches, Tpattern, fblock->patternum).tagclose_from_blockstack) ) ) { /* we have a prefix or it is user requested, and we have a context with autocompletion or we have blockstack-tag-auto-closing */ gchar *newprefix = NULL, *prefix, *closetag = NULL; GList *items = NULL, *items2 = NULL; gboolean free_items=FALSE; /*print_ac_items(g_array_index(btv->bflang->st->contexts,Tcontext, contextnum).ac); */ prefix = gtk_text_buffer_get_text(btv->buffer, &iter, &cursorpos, TRUE); if (fblock) { GString *tmpstr; gint plen; GtkTextIter it1; gtk_text_buffer_get_iter_at_offset(btv->buffer, &it1, fblock->start1_o); tmpstr = g_string_new("</"); while(gtk_text_iter_forward_char(&it1)) { gunichar uc = gtk_text_iter_get_char(&it1); if (!g_unichar_isalnum(uc) && uc != '_') { break; } g_string_append_c(tmpstr, uc); } g_string_append_c(tmpstr, '>'); closetag = g_string_free(tmpstr, FALSE); DBG_AUTOCOMP("closetag=%s, prefix=%s\n", closetag, prefix); plen = strlen(prefix); if (plen == strlen(closetag) || strncmp(closetag, prefix, plen) != 0) { g_free(closetag); closetag = NULL; } } if (g_array_index(master->bflang->st->contexts, Tcontext, contextnum).ac) { items = g_completion_complete(g_array_index(master->bflang->st->contexts, Tcontext, contextnum).ac, prefix, &newprefix); DBG_AUTOCOMP("got %d autocompletion items for prefix %s in context %d, newprefix=%s\n", g_list_length(items), prefix, contextnum, newprefix); if (G_UNLIKELY(g_array_index(master->bflang->st->contexts, Tcontext, contextnum).autocomplete_has_conditions)) { if (found==NULL) { found = get_foundcache_at_offset(btv, gtk_text_iter_get_offset(&cursorpos), NULL); } items = process_conditional_items(btv, found, contextnum, items); free_items=TRUE; } { GCompletion *compl = identifier_ac_get_completion(master, contextnum, FALSE); DBG_IDENTIFIER("got completion %p for context %d\n", compl, contextnum); if (compl) { gchar *newprefix2 = NULL; items2 = g_completion_complete(compl, prefix, &newprefix2); DBG_IDENTIFIER("got %d identifier_items for prefix %s, newprefix=%s\n", g_list_length(items2), prefix, newprefix2); if (!newprefix) newprefix = newprefix2; else g_free(newprefix2); } } } if (closetag || items2 || (items != NULL && (items->next != NULL || strcmp(items->data, prefix) != 0))) { /* do not popup if there are 0 items, and also not if there is 1 item which equals the prefix */ GtkTreeSelection *selection; GtkTreeIter it; gboolean below; gint numitems=0; /* create the GUI */ if (!btv->autocomp) { btv->autocomp = acwin_create(btv); } else { ACWIN(btv->autocomp)->in_fill=TRUE; g_free(ACWIN(btv->autocomp)->prefix); g_free(ACWIN(btv->autocomp)->newprefix); ACWIN(btv->autocomp)->prefix = NULL; ACWIN(btv->autocomp)->newprefix = NULL; gtk_list_store_clear(ACWIN(btv->autocomp)->store); } ACWIN(btv->autocomp)->contextnum = contextnum; ACWIN(btv->autocomp)->prefix = g_strdup(prefix); if (newprefix) { ACWIN(btv->autocomp)->newprefix = g_strdup(newprefix); } acwin_calculate_window_size(ACWIN(btv->autocomp), items, items2, closetag, &numitems); below = acwin_position_at_cursor(btv); acwin_fill_tree(ACWIN(btv->autocomp), items, items2, closetag, !below, numitems); gtk_widget_show(ACWIN(btv->autocomp)->win); selection = gtk_tree_view_get_selection(ACWIN(btv->autocomp)->tree); if (below) { DBG_AUTOCOMP("autocomp_run, popup-below, get first iter for selection\n"); gtk_tree_model_get_iter_first(GTK_TREE_MODEL(ACWIN(btv->autocomp)->store), &it); } else { GtkTreePath *path; DBG_AUTOCOMP("autocomp_run, popup-above, select last iter and scroll max down\n"); gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(ACWIN(btv->autocomp)->store), &it, NULL, gtk_tree_model_iter_n_children(GTK_TREE_MODEL (ACWIN(btv->autocomp)->store), NULL) - 1); path = gtk_tree_model_get_path(GTK_TREE_MODEL(ACWIN(btv->autocomp)->store), &it); gtk_tree_view_scroll_to_cell(ACWIN(btv->autocomp)->tree, path, NULL, FALSE, 1.0, 1.0); gtk_tree_path_free(path); } /* this forces that selection changed will be called two lines below*/ gtk_tree_selection_unselect_all(selection); ACWIN(btv->autocomp)->in_fill=FALSE; DBG_AUTOCOMP("call select_iter on autocomp window\n"); gtk_tree_selection_select_iter(selection, &it); g_free(closetag); } else { acwin_cleanup(btv); } if (free_items) { g_list_free(items); } g_free(newprefix); g_free(prefix); } else { DBG_AUTOCOMP("no autocompletion data for context %d (ac=%p), or no prefix\n", contextnum, g_array_index(master->bflang->st->contexts, Tcontext, contextnum).ac); acwin_cleanup(btv); } }
static int gtk_combo_entry_key_press (GtkEntry * entry, GdkEventKey * event, GtkCombo * combo) { GList *li; /* completion */ if ((event->keyval == GDK_Tab) && (event->state & GDK_MOD1_MASK)) { GCompletion * cmpl; gchar* prefix; gchar* nprefix = NULL; gint pos; if ( !GTK_LIST (combo->list)->children ) return FALSE; gtk_signal_emit_stop_by_name (GTK_OBJECT (entry), "key_press_event"); cmpl = g_completion_new ((GCompletionFunc)gtk_combo_func); g_completion_add_items (cmpl, GTK_LIST (combo->list)->children); pos = GTK_EDITABLE (entry)->current_pos; prefix = gtk_editable_get_chars (GTK_EDITABLE (entry), 0, pos); g_completion_complete(cmpl, prefix, &nprefix); if (nprefix && strlen (nprefix) > strlen (prefix)) { gtk_editable_insert_text (GTK_EDITABLE (entry), nprefix + pos, strlen (nprefix) - strlen (prefix), &pos); GTK_EDITABLE (entry)->current_pos = pos; } if (nprefix) g_free (nprefix); g_free (prefix); g_completion_free (cmpl); return TRUE; } if (!combo->use_arrows || !GTK_LIST (combo->list)->children) return FALSE; li = g_list_find (GTK_LIST (combo->list)->children, gtk_combo_find (combo)); if ((event->keyval == GDK_Up) || (event->keyval == GDK_KP_Up) || ((event->state & GDK_MOD1_MASK) && ((event->keyval == 'p') || (event->keyval == 'P')))) { if (li) li = li->prev; if (!li && combo->use_arrows_always) { li = g_list_last (GTK_LIST (combo->list)->children); } if (li) { gtk_list_select_child (GTK_LIST (combo->list), GTK_WIDGET (li->data)); gtk_signal_emit_stop_by_name (GTK_OBJECT (entry), "key_press_event"); return TRUE; } } else if ((event->keyval == GDK_Down) || (event->keyval == GDK_KP_Down) || ((event->state & GDK_MOD1_MASK) && ((event->keyval == 'n') || (event->keyval == 'N')))) { if (li) li = li->next; if (!li && combo->use_arrows_always) { li = GTK_LIST (combo->list)->children; } if (li) { gtk_list_select_child (GTK_LIST (combo->list), GTK_WIDGET (li->data)); gtk_signal_emit_stop_by_name (GTK_OBJECT (entry), "key_press_event"); return TRUE; } } return FALSE; }