/* vim:set noet ts=4: */ /** * scim-python * * Copyright (c) 2007-2008 Huang Peng * * * 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 #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 &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 _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); }