Exemple #1
0
MPlist *
lookup (MPlist *args)
{
  MInputContext *ic;
  MPlist *actions = NULL, *candidates, *plist;
  MSymbol init_state;
  MSymbol select_state;
  TableContext *context;
  MText *mt;

  ic = mplist_value (args);
  context = get_context (ic);

  args = mplist_next (args);
  init_state = (MSymbol) mplist_value (args);
  args = mplist_next (args);
  select_state = (MSymbol) mplist_value (args);

  if (context->desc)
    candidates = (*context->desc->lookup) (context, args);
  else
    candidates = mplist ();

  if (mplist_length (candidates) == 0) {
    m17n_object_unref (candidates);
    return NULL;
  }

#if 0
  /* FIXME: if only one candidate is matching, we should insert it and
     commit immediately.  However, this feature is disabled for now
     since users would type extra characters after the match.  For
     example, with mr-inscript-typing-booster, an Indic word
     "Epgyepgne" is only one candidate when a user type "Epgyepgn",
     but the user will likely to type "e" after commit.
  */
  if (mplist_length (candidates) == 1) {
    actions = mplist ();
    add_action (actions, msymbol ("delete"), Msymbol,  msymbol ("@<"));
    add_action (actions, msymbol ("insert"), Mtext, mplist_value (candidates));
    add_action (actions, msymbol ("commit"), Mnil, NULL);
    m17n_object_unref (candidates);
    return actions;
  }
#endif

  actions = mplist ();

  mt = mtext_dup (ic->preedit);
  mplist_push (candidates, Mtext, mt);
  m17n_object_unref (mt);
  plist = paginate (candidates);
  m17n_object_unref (candidates);

  add_action (actions, msymbol ("delete"), Msymbol,  msymbol ("@<"));
  mplist_add (actions, Mplist, plist);
  m17n_object_unref (plist);
  add_action (actions, msymbol ("select"), Minteger, (void *)1);
  add_action (actions, msymbol ("show"), Mnil, NULL);
  add_action (actions, msymbol ("shift"), Msymbol, select_state);

  return actions;
}
Exemple #2
0
static MPlist *
lookup_ibus (TableContext *context, MPlist *args)
{
  unsigned char buf[256];
  char *word = NULL, *sql = NULL, *msql = NULL;
  MPlist *candidates = mplist ();
  int len, xlen, wlen, mlen;
  int i, rc;
  int *m = NULL;
  sqlite3_stmt *stmt;
  MText *mt;

  if (!context->db)
    goto out;

  rc = mtext_to_utf8 (context, context->ic->preedit, buf, sizeof (buf));
  if (rc < 0)
    goto out;
  word = strdup ((const char *)buf);
  len = rc;

  mlen = CLAMP(context->mlen, 0, 99);

  rc = encode_phrase ((const unsigned char *)word, &m);
  if (rc)
    goto out;

  /* strlen(" AND mXX = XX") = 13 */
  if (len > mlen)
    len = mlen;
  msql = calloc (sizeof (char), 13 * len + 1);
  if (!msql)
    goto out;
  for (i = 0; i < len; i++)
    {
      char s[14];
      sqlite3_snprintf (13, s, " AND m%d = %d", i, m[i]);
      strcat (msql, s);
    }

  sql = calloc (sizeof (char), 128 + strlen (msql) + 1);
  if (!sql)
    goto out;

  /* issue query repeatedly until at least one candidates are found or
     the key length is exceeds mlen */
  xlen = context->xlen;
  wlen = mlen - len + 1;
  for (; xlen <= wlen + 1; xlen++)
    {
      sqlite3_snprintf (128,
			sql,
			"SELECT id, phrase FROM phrases WHERE mlen < %lu",
			len + xlen);
      strcat (sql, msql);
      strcat (sql, " ORDER BY mlen ASC, user_freq DESC, freq DESC, id ASC");
      if (context->max_candidates)
	sqlite3_snprintf (128,
			  sql + strlen (sql),
			  " LIMIT %lu",
			  context->max_candidates);

#ifdef DEBUG
      fprintf (stderr, "%s\n", sql);
#endif
      rc = sqlite3_prepare (context->db, sql, strlen (sql), &stmt, NULL);
      if (rc != SQLITE_OK)
	{
	  sqlite3_finalize (stmt);
	  goto out;
	}

      while (sqlite3_step (stmt) == SQLITE_ROW)
	{
	  const unsigned char *text;

	  text = sqlite3_column_text (stmt, 1);
#ifdef DEBUG
	  fprintf (stderr, " %s\n", text);
#endif
	  mt = mtext_from_utf8 (context, text, strlen ((const char *)text));
	  mplist_add (candidates, Mtext, mt);
	  m17n_object_unref (mt);
	}
      sqlite3_finalize (stmt);
      if (mplist_length (candidates) > 0)
	break;
    }

 out:
  if (word)
    free (word);
  if (m)
    free (m);
  if (sql)
    free (sql);
  if (msql)
    free (msql);

  return candidates;
}
Exemple #3
0
static MPlist *
lookup_scim (TableContext *context, MPlist *args)
{
  unsigned char buf[256];
  char *word = NULL;
  MPlist *candidates = mplist ();
  MText *mt;
  int rc, len, xlen;
  TablePhrase *phrases;
  int n_phrases, n_allocated_phrases;

  if (!context->content || !context->offsets)
    goto out;

  rc = mtext_to_utf8 (context, context->ic->preedit, buf, sizeof (buf));
  if (rc < 0 || rc >= context->mlen)
    goto out;
  word = strdup ((const char *)buf);
  len = rc;

  n_allocated_phrases = 2;
  phrases = calloc (sizeof (TablePhrase), n_allocated_phrases);
  for (n_phrases = 0, xlen = context->xlen; xlen <= context->mlen
	 && n_phrases == 0; xlen++)
    {
      int j;

      for (j = xlen; j > 0; j--)
	{
	  TableOffsetArray *array = &context->offsets[j - 1];
	  int i;

	  for (i = 0; i < array->len; i++)
	    {
	      unsigned char *data = &context->content[array->data[i]];
	      int klen = *data & 0x3F;
	      int plen = *(data + 1);

	      if (strncmp ((const char *)(data + 4), word, len) == 0)
		{
		  int freq = scim_bytestouint16 (data + 2);

		  if (++n_phrases > n_allocated_phrases)
		    {
		      n_allocated_phrases *= 2;
		      phrases = realloc (phrases,
					 sizeof (TablePhrase)
					 * n_allocated_phrases);
		    }
		  phrases[n_phrases - 1].text =
		    strndup ((const char *)(data + 4 + klen), plen);
		  phrases[n_phrases - 1].freq = freq;
		}
	    }
	}
    }

  qsort (phrases, n_phrases, sizeof (TablePhrase), cmp_phrases_by_freq);
  while (n_phrases--)
    {
      mt = mtext_from_utf8 (context,
			    (const unsigned char *)phrases[n_phrases].text,
			    strlen (phrases[n_phrases].text));
      free (phrases[n_phrases].text);

      if (!context->max_candidates
	  || mplist_length (candidates) < context->max_candidates)
	{
	  mplist_push (candidates, Mtext, mt);
#ifdef DEBUG
	  mdebug_dump_mtext (mt, 0, 0);
#endif
	  m17n_object_unref (mt);
	}
    }
  free (phrases);

 out:
  if (word)
    free (word);

  return candidates;
}
Exemple #4
0
static void
ibus_m17n_engine_update_lookup_table (IBusM17NEngine *m17n)
{
    ibus_lookup_table_clear (m17n->table);

    if (m17n->context->candidate_list && m17n->context->candidate_show) {
        IBusText *text;
        MPlist *group;
        group = m17n->context->candidate_list;
        gint i = 0;
        gint page = 1;
        IBusM17NEngineClass *klass = (IBusM17NEngineClass *) G_OBJECT_GET_CLASS (m17n);

        while (1) {
            gint len;
            if (mplist_key (group) == Mtext)
                len = mtext_len ((MText *) mplist_value (group));
            else
                len = mplist_length ((MPlist *) mplist_value (group));

            if (i + len > m17n->context->candidate_index)
                break;

            i += len;
            group = mplist_next (group);
            page ++;
        }

        if (mplist_key (group) == Mtext) {
            MText *mt;
            gunichar *buf;
            glong nchars, i;

            mt = (MText *) mplist_value (group);
            ibus_lookup_table_set_page_size (m17n->table, mtext_len (mt));

            buf = ibus_m17n_mtext_to_ucs4 (mt, &nchars);
            for (i = 0; i < nchars; i++) {
                ibus_lookup_table_append_candidate (m17n->table, ibus_text_new_from_unichar (buf[i]));
            }
            g_free (buf);
        }
        else {
            MPlist *p;

            p = (MPlist *) mplist_value (group);
            ibus_lookup_table_set_page_size (m17n->table, mplist_length (p));

            for (; mplist_key (p) != Mnil; p = mplist_next (p)) {
                MText *mtext;
                gchar *buf;

                mtext = (MText *) mplist_value (p);
                buf = ibus_m17n_mtext_to_utf8 (mtext);
                if (buf) {
                    ibus_lookup_table_append_candidate (m17n->table, ibus_text_new_from_string (buf));
                    g_free (buf);
                }
            }
        }

        ibus_lookup_table_set_cursor_pos (m17n->table, m17n->context->candidate_index - i);
        ibus_lookup_table_set_orientation (m17n->table, klass->lookup_table_orientation);

        text = ibus_text_new_from_printf ("( %d / %d )", page, mplist_length (m17n->context->candidate_list));

        ibus_engine_update_lookup_table ((IBusEngine *)m17n, m17n->table, TRUE);
        ibus_engine_update_auxiliary_text ((IBusEngine *)m17n, text, TRUE);
    }
    else {
        ibus_engine_hide_lookup_table ((IBusEngine *)m17n);
        ibus_engine_hide_auxiliary_text ((IBusEngine *)m17n);
    }
}