Esempio n. 1
0
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;
}
Esempio n. 2
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;
}
Esempio n. 3
0
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;
}
Esempio n. 4
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;
}
Esempio n. 5
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;
}
Esempio n. 6
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;
}
Esempio n. 7
0
/**
 * 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);
}
Esempio n. 9
0
/*
 * 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 );
}
Esempio n. 10
0
File: fkeys.c Progetto: n2i/xvnkb
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;
}
Esempio n. 11
0
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);
	}
}
Esempio n. 12
0
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;
}