/src/scim-python-lookup-table.cpp
C++ | 660 lines | 519 code | 116 blank | 25 comment | 36 complexity | a3019f1ecd41d50860f826860987503c MD5 | raw file
- /* vim:set noet ts=4: */
- /**
- * scim-python
- *
- * Copyright (c) 2007-2008 Huang Peng <shawn.p.huang@gmail.com>
- *
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
- * Boston, MA 02111-1307 USA
- *
- * $Id: $
- */
- #include "scim-python-lookup-table.h"
- #include "scim-python-attribute.h"
- #if Py_UNICODE_SIZE == 2
- # include <glib.h>
- #endif
- struct PyLookupTableObject {
- PyObject_HEAD
- /* Type-specific fields go here. */
- PyLookupTable lookup_table;
- };
- PyLookupTable::PyLookupTable (PyLookupTableObject *self, unsigned int page_size)
- : CommonLookupTable (page_size), self (self)
- {
- Py_INCREF (self);
- }
- PyLookupTable::PyLookupTable (PyLookupTableObject *self, unsigned int page_size, const std::vector<WideString> &labels)
- : CommonLookupTable (page_size, labels), self (self)
- {
- Py_INCREF (self);
- }
- PyLookupTable::~PyLookupTable ()
- {
- Py_DECREF (self);
- }
- PyDoc_STRVAR(py_set_candidate_labels__doc__,
- "set_candidate_labels ((unicode, unicode, ...)) -> none\n"
- "Set the strings (it must be unicode strings) to label the candidates in on page.");
- PyObject *
- PyLookupTable::py_set_candidate_labels (PyLookupTableObject *self, PyObject *args)
- {
- PyObject *labels = NULL;
- PyObject **items = NULL;
- std::vector <WideString> _labels;
- int size;
- if (!PyArg_ParseTuple (args, "o:set_candidate_labels", &labels))
- return NULL;
- if (!PySequence_Check (labels)) {
- PyErr_SetString (PyExc_TypeError, "labels must be an array of unicode strings.");
- return NULL;
- }
- size = PySequence_Size (labels);
- items = PySequence_Fast_ITEMS (labels);
- for (int i = 0; i < size; i++ ) {
- if (!PyUnicode_Check (items[i])) {
- PyErr_SetString (PyExc_TypeError, "labels must be an array of unicode strings.");
- return NULL;
- }
- #if Py_UNICODE_SIZE == 4
- _labels.push_back (WideString ((wchar_t *)PyUnicode_AS_UNICODE (items[i])));
- #else
- int usize = PyUnicode_GET_SIZE (items[i]);
- gunichar *unistr = g_utf16_to_ucs4 (PyUnicode_AS_UNICODE (items[i]), usize, NULL, NULL, NULL);
- _labels.push_back (WideString ((wchar_t *)unistr));
- g_free (unistr);
- #endif
- }
- self->lookup_table.set_candidate_labels (_labels);
- Py_INCREF (Py_None);
- return Py_None;
- }
- PyDoc_STRVAR(py_get_candidate_label__doc__,
- "get_candidate_label (int) -> unicode\n"
- "Return the label string of a candidate in page.");
- PyObject *
- PyLookupTable::py_get_candidate_label (PyLookupTableObject *self, PyObject *args)
- {
- unsigned index = 0;
- if (!PyArg_ParseTuple (args, "I:get_candidate_label", &index))
- return NULL;
- WideString candidate = self->lookup_table.get_candidate_label (index);
- #if Py_UNICODE_SIZE == 4
- return PyUnicode_FromUnicode ((Py_UNICODE *)candidate.c_str (), candidate.length ());
- #else
- gunichar2 *utf16_str = g_ucs4_to_utf16 ((gunichar *)candidate.c_str (),
- candidate.length (), NULL, NULL, NULL);
- PyObject * result = PyUnicode_FromUnicode ((Py_UNICODE *)utf16_str, candidate.length ());
- g_free (utf16_str);
- return result;
- #endif
- }
- PyDoc_STRVAR(py_set_page_size__doc__,
- "set_page_size (int) -> none\n"
- "Set the maximum page size.");
- PyObject *
- PyLookupTable::py_set_page_size (PyLookupTableObject *self, PyObject *args)
- {
- unsigned int page_size;
- if (!PyArg_ParseTuple (args, "I:set_page_size", &page_size))
- return NULL;
- self->lookup_table.set_page_size (page_size);
- Py_INCREF (Py_None);
- return Py_None;
- }
- PyDoc_STRVAR(py_get_page_size__doc__,
- "get_page_size () -> int\n"
- "Return the maximum page size.");
- PyObject *
- PyLookupTable::py_get_page_size (PyLookupTableObject *self, PyObject *args)
- {
- long size = self->lookup_table.get_page_size ();
- return PyInt_FromLong (size);
- }
- PyDoc_STRVAR(py_get_current_page_size__doc__,
- "get_current_page_size () -> int\n"
- "Return the current page size.");
- PyObject *
- PyLookupTable::py_get_current_page_size (PyLookupTableObject *self, PyObject *args)
- {
- long size = self->lookup_table.get_current_page_size ();
- return PyInt_FromLong (size);
- }
- PyDoc_STRVAR(py_get_current_page_start__doc__,
- "get_current_page_start () -> int\n"
- "Return the start index of current page.");
- PyObject *
- PyLookupTable::py_get_current_page_start (PyLookupTableObject *self, PyObject *args)
- {
- long index = self->lookup_table.get_current_page_start ();
- return PyInt_FromLong (index);
- }
- PyDoc_STRVAR(py_is_cursor_visible__doc__,
- "is_cursor_visible () -> bool\n"
- "Return true if curosr is visible.");
- PyObject *
- PyLookupTable::py_is_cursor_visible (PyLookupTableObject *self, PyObject *args)
- {
- PyObject * result;
- if (self->lookup_table.is_cursor_visible ()) {
- result = Py_True;
- }
- else {
- result = Py_False;
- }
- Py_INCREF (result);
- return result;
- }
- PyDoc_STRVAR(py_is_page_size_fixed__doc__,
- "is_page_size_fixed () -> bool\n"
- "Return true if the page size is fixed.");
- PyObject *
- PyLookupTable::py_is_page_size_fixed (PyLookupTableObject *self, PyObject *args)
- {
- PyObject * result;
- if (self->lookup_table.is_page_size_fixed ()) {
- result = Py_True;
- }
- else {
- result = Py_False;
- }
- Py_INCREF (result);
- return result;
- }
- PyDoc_STRVAR(py_get_cursor_pos__doc__,
- "get_cursor_pos () -> int\n"
- "Return the cursor position in the table, starting from 0.");
- PyObject *
- PyLookupTable::py_get_cursor_pos (PyLookupTableObject *self, PyObject *args)
- {
- int pos;
- pos = self->lookup_table.get_cursor_pos ();
- return PyInt_FromLong (pos);
- }
- PyDoc_STRVAR(py_get_cursor_pos_in_current_page__doc__,
- "get_cursor_pos_in_current_page () -> int\n"
- "Return the cursor position in the current page, starting from 0.");
- PyObject *
- PyLookupTable::py_get_cursor_pos_in_current_page (PyLookupTableObject *self, PyObject *args)
- {
- int pos;
- pos = self->lookup_table.get_cursor_pos_in_current_page ();
- return PyInt_FromLong (pos);
- }
- PyDoc_STRVAR(py_page_up__doc__,
- "page_up () -> bool\n"
- "Flip to the previous page. Return false if it's already in the first page.");
- PyObject *
- PyLookupTable::py_page_up (PyLookupTableObject *self, PyObject *args)
- {
- PyObject *result;
- if (self->lookup_table.page_up ())
- result = Py_True;
- else
- result = Py_False;
- Py_INCREF (result);
- return result;
- }
- PyDoc_STRVAR(py_page_down__doc__,
- "page_down () -> bool\n"
- "Flip to the next page. Return false if it's already in the last page.");
- PyObject *
- PyLookupTable::py_page_down (PyLookupTableObject *self, PyObject *args)
- {
- PyObject *result;
- if (self->lookup_table.page_down ())
- result = Py_True;
- else
- result = Py_False;
- Py_INCREF (result);
- return result;
- }
- PyDoc_STRVAR(py_cursor_up__doc__,
- "cursor_up () -> bool\n"
- "Move cursor position to the previous entry. Return false if it's already in the first entry.");
- PyObject *
- PyLookupTable::py_cursor_up (PyLookupTableObject *self, PyObject *args)
- {
- PyObject * result;
- if (self->lookup_table.cursor_up ()) {
- result = Py_True;
- }
- else {
- result = Py_False;
- }
- Py_INCREF (result);
- return result;
- }
- PyDoc_STRVAR(py_cursor_down__doc__,
- "cursor_down () -> bool\n"
- "Move cursor position to the next entry. Return false if it's already in the last entry.");
- PyObject *
- PyLookupTable::py_cursor_down (PyLookupTableObject *self, PyObject *args)
- {
- PyObject * result;
- if (self->lookup_table.cursor_down ()) {
- result = Py_True;
- }
- else {
- result = Py_False;
- }
- Py_INCREF (result);
- return result;
- }
- PyDoc_STRVAR(py_show_cursor__doc__,
- "show_cursor (bool) -> none\n"
- "Set the cursor visibility.");
- PyObject *
- PyLookupTable::py_show_cursor (PyLookupTableObject *self, PyObject *args)
- {
- unsigned int show = 1;
- if (!PyArg_ParseTuple (args, "|I:show_cursor", &show))
- return NULL;
- self->lookup_table.show_cursor (show);
- Py_INCREF (Py_None);
- return Py_None;
- }
- PyDoc_STRVAR(py_fix_page_size__doc__,
- "fix_page_size (bool) -> none\n"
- "Set the page size to be fixed, aka. prevent from being changed by FrontEnd.");
- PyObject *
- PyLookupTable::py_fix_page_size (PyLookupTableObject *self, PyObject *args)
- {
- unsigned int fixed = 1;
- if (!PyArg_ParseTuple (args, "|I:fix_page_size", &fixed))
- return NULL;
- self->lookup_table.fix_page_size (fixed);
- Py_INCREF (Py_None);
- return Py_None;
- }
- PyDoc_STRVAR(py_set_cursor_pos__doc__,
- "set_cursor_pos (int) -> none\n"
- "Set the cursor position.");
- PyObject *
- PyLookupTable::py_set_cursor_pos (PyLookupTableObject *self, PyObject *args)
- {
- unsigned int pos;
- if (!PyArg_ParseTuple (args, "I:set_cursor_pos", &pos))
- return NULL;
- self->lookup_table.set_cursor_pos (pos);
- Py_INCREF (Py_None);
- return Py_None;
- }
- PyDoc_STRVAR(py_set_cursor_pos_in_current_page__doc__,
- "set_cursor_pos_in_current_page (int) -> none\n"
- "Set the cursor position in current page.");
- PyObject *
- PyLookupTable::py_set_cursor_pos_in_current_page (PyLookupTableObject *self, PyObject *args)
- {
- unsigned int pos;
- if (!PyArg_ParseTuple (args, "I:set_cursor_pos_in_current_pos", &pos))
- return NULL;
- self->lookup_table.set_cursor_pos_in_current_page (pos);
- Py_INCREF (Py_None);
- return Py_None;
- }
- PyDoc_STRVAR(py_get_candidate_in_current_page__doc__,
- "get_candidate_in_current_page (int) -> unicode\n"
- "Return the content of this candidate.");
- PyObject *
- PyLookupTable::py_get_candidate_in_current_page (PyLookupTableObject *self, PyObject *args)
- {
- unsigned index = 0;
- if (!PyArg_ParseTuple (args, "I:get_candidate_in_current_page", &index))
- return NULL;
- WideString candidate = self->lookup_table.get_candidate_in_current_page (index);
- #if Py_UNICODE_SIZE == 4
- return PyUnicode_FromUnicode ((Py_UNICODE *)candidate.c_str (), candidate.length ());
- #else
- gunichar2 *utf16_str = g_ucs4_to_utf16 ((gunichar *)candidate.c_str (),
- candidate.length (), NULL, NULL, NULL);
- PyObject * result = PyUnicode_FromUnicode ((Py_UNICODE *)utf16_str, candidate.length ());
- g_free (utf16_str);
- return result;
- #endif
- }
- PyDoc_STRVAR(py_get_candidate__doc__,
- "get_candidate (int) -> unicode\n"
- "Return the content of this candidate.");
- PyObject *
- PyLookupTable::py_get_candidate (PyLookupTableObject *self, PyObject *args)
- {
- unsigned index = 0;
- if (!PyArg_ParseTuple (args, "I:get_candidate", &index))
- return NULL;
- WideString candidate = self->lookup_table.get_candidate (index);
- #if Py_UNICODE_SIZE == 4
- return PyUnicode_FromUnicode ((Py_UNICODE *)candidate.c_str (), candidate.length ());
- #else
- gunichar2 *utf16_str = g_ucs4_to_utf16 ((gunichar *)candidate.c_str (),
- candidate.length (), NULL, NULL, NULL);
- PyObject * result = PyUnicode_FromUnicode ((Py_UNICODE *)utf16_str, candidate.length ());
- g_free (utf16_str);
- return result;
- #endif
- }
- PyDoc_STRVAR(py_get_attributes__doc__,
- "get_attributes (int) -> list\n"
- "Return a list holding the attributes of this candidates.");
- PyObject *
- PyLookupTable::py_get_attributes (PyLookupTableObject *self, PyObject *args)
- {
- #if 0
- PyObject *result;
- unsigned index = 0;
- if (!PyArg_ParseTuple (args, "I:get_attributes", &index))
- return NULL;
- AttributeList atts = self->lookup_table.get_attributes (index)
- result = PyTuple_New ();
- #endif
- Py_INCREF (Py_None);
- return Py_None;
- }
- PyDoc_STRVAR(py_get_attributes_in_current_page__doc__,
- "get_attributes_in_current_page (int) -> list\n"
- "Return a list holding the attributes of this candidates.");
- PyObject *
- PyLookupTable::py_get_attributes_in_current_page (PyLookupTableObject *self, PyObject *args)
- {
- #if 0
- PyObject *result;
- unsigned index = 0;
- if (!PyArg_ParseTuple (args, "I:get_attributes", &index))
- return NULL;
- AttributeList atts = self->lookup_table.get_attributes (index)
- result = PyTuple_New ();
- #endif
- Py_INCREF (Py_None);
- return Py_None;
- }
- PyDoc_STRVAR(py_number_of_candidates__doc__,
- "number_of_candidates () -> int\n"
- "Return the number of candidates in the table.");
- PyObject *
- PyLookupTable::py_number_of_candidates (PyLookupTableObject *self, PyObject *args)
- {
- uint32 number;
- number = self->lookup_table.number_of_candidates ();
- return PyInt_FromLong (number);
- }
- PyDoc_STRVAR(py_clear__doc__,
- "clear () -> none\n"
- "Clear the table.");
- PyObject *
- PyLookupTable::py_clear (PyLookupTableObject *self, PyObject *args)
- {
- self->lookup_table.clear ();
- Py_INCREF (Py_None);
- return Py_None;
- }
- PyDoc_STRVAR(py_append_candidate__doc__,
- "append_candidate (unicode, list) -> bool\n"
- "Append a candidate string to the table, the second is a list holding the attributes.\n"
- "Return true if success.");
- PyObject *
- PyLookupTable::py_append_candidate (PyLookupTableObject *self, PyObject *args)
- {
- Py_UNICODE *candidate = NULL;
- PyObject *pAttrs = NULL;
- PyObject *result = Py_False;
- #if Py_UNICODE_SIZE == 4
- if (!PyArg_ParseTuple (args, "u|O:append_candidate", &candidate, &pAttrs))
- return NULL;
- if (self->lookup_table.append_candidate (WideString ((wchar_t *)candidate),
- Attributes_FromTupleOrList (pAttrs)))
- {
- result = Py_True;
- }
- #else
- int size = 0;
- gunichar *unistr = NULL;
- if (!PyArg_ParseTuple (args, "u#|O:append_candidate", &candidate, &size, &pAttrs))
- return NULL;
- unistr = g_utf16_to_ucs4 (candidate, size, NULL, NULL, NULL);
- if (self->lookup_table.append_candidate (WideString ((wchar_t *)unistr),
- Attributes_FromTupleOrList (pAttrs)))
- {
- result = Py_True;
- }
- g_free (unistr);
- #endif
- Py_INCREF (result);
- return result;
- }
- PyMethodDef
- PyLookupTable::py_methods[] = {
- #define ENTRY(name, flags) {#name, (PyCFunction)PyLookupTable::py_##name, flags, py_##name##__doc__}
- ENTRY (set_candidate_labels, METH_VARARGS),
- ENTRY (get_candidate_label, METH_VARARGS),
- ENTRY (set_page_size, METH_VARARGS),
- ENTRY (get_page_size, METH_NOARGS),
- ENTRY (get_current_page_size, METH_NOARGS),
- ENTRY (get_current_page_start, METH_NOARGS),
- ENTRY (is_cursor_visible, METH_NOARGS),
- ENTRY (is_page_size_fixed, METH_NOARGS),
- ENTRY (get_cursor_pos, METH_NOARGS),
- ENTRY (get_cursor_pos_in_current_page, METH_NOARGS),
- ENTRY (page_up, METH_NOARGS),
- ENTRY (page_down, METH_NOARGS),
- ENTRY (cursor_up, METH_NOARGS),
- ENTRY (cursor_down, METH_NOARGS),
- ENTRY (show_cursor, METH_VARARGS),
- ENTRY (fix_page_size, METH_VARARGS),
- ENTRY (set_cursor_pos, METH_VARARGS),
- ENTRY (set_cursor_pos_in_current_page, METH_VARARGS),
- ENTRY (get_candidate_in_current_page, METH_VARARGS),
- ENTRY (get_attributes_in_current_page, METH_VARARGS),
- ENTRY (get_candidate, METH_VARARGS),
- ENTRY (get_attributes, METH_VARARGS),
- ENTRY (number_of_candidates, METH_NOARGS),
- ENTRY (clear, METH_NOARGS),
- ENTRY (append_candidate, METH_VARARGS),
- #undef ENTRY
- { NULL }
- };
- PyObject *
- PyLookupTable::py_new (PyTypeObject *type, PyObject *args, PyObject *kwds)
- {
- PyLookupTable *self;
- self = (PyLookupTable *)type->tp_alloc (type, 0);
- return (PyObject *)self;
- }
- int
- PyLookupTable::py_init (PyLookupTableObject *self, PyObject *args, PyObject *kwds)
- {
- unsigned int page_size = 10;
- if (!PyArg_ParseTuple (args, "|I:__init__", &page_size))
- return -1;
- new (&self->lookup_table) PyLookupTable (self, page_size);
- return 0;
- }
- void
- PyLookupTable::py_dealloc (PyLookupTableObject *self)
- {
- self->lookup_table.~LookupTable ();
- ((PyObject *)self)->ob_type->tp_free (self);
- }
- const PyLookupTable &
- PyLookupTable::from_pyobject (PyObject *object)
- {
- return ((PyLookupTableObject *)object)->lookup_table;
- }
- PyTypeObject PyLookupTableType = {
- PyObject_HEAD_INIT (NULL)
- 0, /*ob_size*/
- "scim.LookupTable", /*tp_name*/
- sizeof (PyLookupTableObject), /*tp_basicsize*/
- 0, /*tp_itemsize*/
- (destructor)PyLookupTable::py_dealloc, /*tp_dealloc*/
- 0, /*tp_print*/
- 0, /*tp_getattr*/
- 0, /*tp_setattr*/
- 0, /*tp_compare*/
- 0, /*tp_repr*/
- 0, /*tp_as_number*/
- 0, /*tp_as_sequence*/
- 0, /*tp_as_mapping*/
- 0, /*tp_hash */
- 0, /*tp_call*/
- 0, /*tp_str*/
- 0, /*tp_getattro*/
- 0, /*tp_setattro*/
- 0, /*tp_as_buffer*/
- Py_TPFLAGS_DEFAULT |
- Py_TPFLAGS_BASETYPE, /*tp_flags*/
- "PyLookupTable objects", /* tp_doc */
- 0, /* tp_traverse */
- 0, /* tp_clear */
- 0, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- 0, /* tp_iter */
- 0, /* tp_iternext */
- PyLookupTable::py_methods, /* tp_methods */
- 0, /* tp_members */
- 0, /* tp_getset */
- 0, /* tp_base */
- 0, /* tp_dict */
- 0, /* tp_descr_get */
- 0, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)PyLookupTable::py_init, /* tp_init */
- 0, /* tp_alloc */
- PyLookupTable::py_new, /* tp_new */
- PyObject_Del, /* tp_free */
- };
- void init_lookup_table (PyObject *module)
- {
- if (PyType_Ready (&PyLookupTableType) < 0)
- return;
- Py_INCREF (&PyLookupTableType);
- PyModule_AddObject (module, "LookupTable", (PyObject *)&PyLookupTableType);
- }