PageRenderTime 103ms CodeModel.GetById 41ms app.highlight 57ms RepoModel.GetById 1ms app.codeStats 1ms

/src/scim-python-lookup-table.cpp

http://scim-python.googlecode.com/
C++ | 660 lines | 519 code | 116 blank | 25 comment | 36 complexity | a3019f1ecd41d50860f826860987503c MD5 | raw file
  1/* vim:set noet ts=4: */
  2/** 
  3 * scim-python
  4 * 
  5 * Copyright (c) 2007-2008 Huang Peng <shawn.p.huang@gmail.com>
  6 *
  7 *
  8 * This library is free software; you can redistribute it and/or
  9 * modify it under the terms of the GNU Lesser General Public
 10 * License as published by the Free Software Foundation; either
 11 * version 2 of the License, or (at your option) any later version.
 12 *
 13 * This library is distributed in the hope that it will be useful,
 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 16 * GNU Lesser General Public License for more details.
 17 *
 18 * You should have received a copy of the GNU Lesser General Public
 19 * License along with this program; if not, write to the
 20 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 21 * Boston, MA  02111-1307  USA
 22 *
 23 * $Id: $
 24 */
 25
 26#include "scim-python-lookup-table.h"
 27#include "scim-python-attribute.h"
 28#if Py_UNICODE_SIZE == 2
 29#  include <glib.h>
 30#endif
 31
 32struct PyLookupTableObject {
 33	PyObject_HEAD
 34	/* Type-specific fields go here. */
 35	PyLookupTable lookup_table;
 36};
 37
 38PyLookupTable::PyLookupTable (PyLookupTableObject *self, unsigned int page_size)
 39: CommonLookupTable (page_size), self (self)
 40{
 41	Py_INCREF (self);
 42
 43}
 44
 45PyLookupTable::PyLookupTable (PyLookupTableObject *self, unsigned int page_size, const std::vector<WideString> &labels)
 46: CommonLookupTable (page_size, labels), self (self)
 47{
 48	Py_INCREF (self);
 49}
 50
 51PyLookupTable::~PyLookupTable () 
 52{
 53	Py_DECREF (self);
 54}
 55
 56PyDoc_STRVAR(py_set_candidate_labels__doc__,
 57"set_candidate_labels ((unicode, unicode, ...)) -> none\n"
 58"Set the strings (it must be unicode strings) to label the candidates in on page.");
 59PyObject *
 60PyLookupTable::py_set_candidate_labels (PyLookupTableObject *self, PyObject *args)
 61{
 62	PyObject *labels = NULL;
 63	PyObject **items = NULL;
 64	std::vector <WideString> _labels;
 65	int size;
 66
 67
 68	if (!PyArg_ParseTuple (args, "o:set_candidate_labels", &labels))
 69		return NULL;
 70
 71	if (!PySequence_Check (labels)) {
 72		PyErr_SetString (PyExc_TypeError, "labels must be an array of unicode strings.");
 73		return NULL;
 74	}
 75
 76	size = PySequence_Size (labels);
 77	items = PySequence_Fast_ITEMS (labels);
 78
 79	for (int i = 0; i < size; i++ ) {
 80		if (!PyUnicode_Check (items[i])) {
 81			PyErr_SetString (PyExc_TypeError, "labels must be an array of unicode strings.");
 82			return NULL;
 83		}
 84#if Py_UNICODE_SIZE == 4
 85		_labels.push_back (WideString ((wchar_t *)PyUnicode_AS_UNICODE (items[i])));
 86#else
 87		int usize = PyUnicode_GET_SIZE (items[i]);
 88		gunichar *unistr = g_utf16_to_ucs4 (PyUnicode_AS_UNICODE (items[i]), usize, NULL, NULL, NULL);
 89		_labels.push_back (WideString ((wchar_t *)unistr));
 90		g_free (unistr);
 91#endif
 92	}
 93
 94	self->lookup_table.set_candidate_labels (_labels);
 95
 96	Py_INCREF (Py_None);
 97	return Py_None;
 98
 99}
100
101
102PyDoc_STRVAR(py_get_candidate_label__doc__,
103"get_candidate_label (int) -> unicode\n"
104"Return the label string of a candidate in page.");
105PyObject *
106PyLookupTable::py_get_candidate_label (PyLookupTableObject *self, PyObject *args)
107{
108	unsigned index = 0;
109
110	if (!PyArg_ParseTuple (args, "I:get_candidate_label", &index))
111		return NULL;
112
113	WideString candidate = self->lookup_table.get_candidate_label (index);
114#if Py_UNICODE_SIZE == 4
115	return PyUnicode_FromUnicode ((Py_UNICODE *)candidate.c_str (), candidate.length ());
116#else
117	gunichar2 *utf16_str = g_ucs4_to_utf16 ((gunichar *)candidate.c_str (),
118						candidate.length (), NULL, NULL, NULL);
119	PyObject * result = PyUnicode_FromUnicode ((Py_UNICODE *)utf16_str, candidate.length ());
120	g_free (utf16_str);
121	return result;
122#endif
123}
124
125PyDoc_STRVAR(py_set_page_size__doc__,
126"set_page_size (int) -> none\n"
127"Set the maximum page size.");
128PyObject *
129PyLookupTable::py_set_page_size (PyLookupTableObject *self, PyObject *args)
130{
131	unsigned int page_size;
132
133	if (!PyArg_ParseTuple (args, "I:set_page_size", &page_size))
134		return NULL;
135
136	self->lookup_table.set_page_size (page_size);
137
138	Py_INCREF (Py_None);
139	return Py_None;
140}
141
142PyDoc_STRVAR(py_get_page_size__doc__,
143"get_page_size () -> int\n"
144"Return the maximum page size.");
145PyObject *
146PyLookupTable::py_get_page_size (PyLookupTableObject *self, PyObject *args)
147{
148	long size = self->lookup_table.get_page_size ();
149
150	return PyInt_FromLong (size);
151}
152
153PyDoc_STRVAR(py_get_current_page_size__doc__,
154"get_current_page_size () -> int\n"
155"Return the current page size.");
156PyObject *
157PyLookupTable::py_get_current_page_size (PyLookupTableObject *self, PyObject *args)
158{
159	long size = self->lookup_table.get_current_page_size ();
160
161	return PyInt_FromLong (size);
162}
163
164PyDoc_STRVAR(py_get_current_page_start__doc__,
165"get_current_page_start () -> int\n"
166"Return the start index of current page.");
167PyObject *
168PyLookupTable::py_get_current_page_start (PyLookupTableObject *self, PyObject *args)
169{
170	long index = self->lookup_table.get_current_page_start ();
171
172	return PyInt_FromLong (index);
173}
174
175PyDoc_STRVAR(py_is_cursor_visible__doc__,
176"is_cursor_visible () -> bool\n"
177"Return true if curosr is visible.");
178PyObject *
179PyLookupTable::py_is_cursor_visible (PyLookupTableObject *self, PyObject *args)
180{
181	PyObject * result;
182	if (self->lookup_table.is_cursor_visible ()) {
183		result = Py_True;
184	}
185	else {
186		result = Py_False;
187	}
188
189	Py_INCREF (result);
190	return result;
191}
192
193PyDoc_STRVAR(py_is_page_size_fixed__doc__,
194"is_page_size_fixed () -> bool\n"
195"Return true if the page size is fixed.");
196PyObject *
197PyLookupTable::py_is_page_size_fixed (PyLookupTableObject *self, PyObject *args)
198{
199	PyObject * result;
200	if (self->lookup_table.is_page_size_fixed ()) {
201		result = Py_True;
202	}
203	else {
204		result = Py_False;
205	}
206
207	Py_INCREF (result);
208	return result;
209}
210
211PyDoc_STRVAR(py_get_cursor_pos__doc__,
212"get_cursor_pos () -> int\n"
213"Return the cursor position in the table, starting from 0.");
214PyObject *
215PyLookupTable::py_get_cursor_pos (PyLookupTableObject *self, PyObject *args)
216{
217	int pos;
218
219	pos = self->lookup_table.get_cursor_pos ();
220
221	return PyInt_FromLong (pos);
222}
223
224PyDoc_STRVAR(py_get_cursor_pos_in_current_page__doc__,
225"get_cursor_pos_in_current_page () -> int\n"
226"Return the cursor position in the current page, starting from 0.");
227PyObject *
228PyLookupTable::py_get_cursor_pos_in_current_page (PyLookupTableObject *self, PyObject *args)
229{
230	int pos;
231
232	pos = self->lookup_table.get_cursor_pos_in_current_page ();
233
234	return PyInt_FromLong (pos);
235}
236
237PyDoc_STRVAR(py_page_up__doc__,
238"page_up () -> bool\n"
239"Flip to the previous page. Return false if it's already in the first page.");
240PyObject *
241PyLookupTable::py_page_up (PyLookupTableObject *self, PyObject *args)
242{
243	PyObject *result;
244
245	if (self->lookup_table.page_up ())
246		result = Py_True;
247	else
248		result = Py_False;
249
250	Py_INCREF (result);
251	return result;
252}
253
254PyDoc_STRVAR(py_page_down__doc__,
255"page_down () -> bool\n"
256"Flip to the next page. Return false if it's already in the last page.");
257PyObject *
258PyLookupTable::py_page_down (PyLookupTableObject *self, PyObject *args)
259{
260	PyObject *result;
261
262	if (self->lookup_table.page_down ())
263		result = Py_True;
264	else
265		result = Py_False;
266
267	Py_INCREF (result);
268	return result;
269}
270
271PyDoc_STRVAR(py_cursor_up__doc__,
272"cursor_up () -> bool\n"
273"Move cursor position to the previous entry. Return false if it's already in the first entry.");
274PyObject *
275PyLookupTable::py_cursor_up (PyLookupTableObject *self, PyObject *args)
276{
277	PyObject * result;
278
279	if (self->lookup_table.cursor_up ()) {
280		result = Py_True;
281	}
282	else {
283		result = Py_False;
284	}
285
286	Py_INCREF (result);
287	return result;
288}
289
290PyDoc_STRVAR(py_cursor_down__doc__,
291"cursor_down () -> bool\n"
292"Move cursor position to the next entry. Return false if it's already in the last entry.");
293PyObject *
294PyLookupTable::py_cursor_down (PyLookupTableObject *self, PyObject *args)
295{
296	PyObject * result;
297
298	if (self->lookup_table.cursor_down ()) {
299		result = Py_True;
300	}
301	else {
302		result = Py_False;
303	}
304
305	Py_INCREF (result);
306	return result;
307}
308
309PyDoc_STRVAR(py_show_cursor__doc__,
310"show_cursor (bool) -> none\n"
311"Set the cursor visibility.");
312PyObject *
313PyLookupTable::py_show_cursor (PyLookupTableObject *self, PyObject *args)
314{
315	unsigned int show = 1;
316
317	if (!PyArg_ParseTuple (args, "|I:show_cursor", &show))
318		return NULL;
319
320	self->lookup_table.show_cursor (show);
321
322	Py_INCREF (Py_None);
323	return Py_None;
324}
325
326PyDoc_STRVAR(py_fix_page_size__doc__,
327"fix_page_size (bool) -> none\n"
328"Set the page size to be fixed, aka. prevent from being changed by FrontEnd.");
329PyObject *
330PyLookupTable::py_fix_page_size (PyLookupTableObject *self, PyObject *args)
331{
332	unsigned int fixed = 1;
333
334	if (!PyArg_ParseTuple (args, "|I:fix_page_size", &fixed))
335		return NULL;
336
337	self->lookup_table.fix_page_size (fixed);
338
339	Py_INCREF (Py_None);
340	return Py_None;
341}
342
343PyDoc_STRVAR(py_set_cursor_pos__doc__,
344"set_cursor_pos (int) -> none\n"
345"Set the cursor position.");
346PyObject *
347PyLookupTable::py_set_cursor_pos (PyLookupTableObject *self, PyObject *args)
348{
349	unsigned int pos;
350
351	if (!PyArg_ParseTuple (args, "I:set_cursor_pos", &pos))
352		return NULL;
353
354	self->lookup_table.set_cursor_pos (pos);
355
356	Py_INCREF (Py_None);
357	return Py_None;
358}
359
360PyDoc_STRVAR(py_set_cursor_pos_in_current_page__doc__,
361"set_cursor_pos_in_current_page (int) -> none\n"
362"Set the cursor position in current page.");
363PyObject *
364PyLookupTable::py_set_cursor_pos_in_current_page (PyLookupTableObject *self, PyObject *args)
365{
366	unsigned int pos;
367
368	if (!PyArg_ParseTuple (args, "I:set_cursor_pos_in_current_pos", &pos))
369		return NULL;
370
371	self->lookup_table.set_cursor_pos_in_current_page (pos);
372
373	Py_INCREF (Py_None);
374	return Py_None;
375}
376
377PyDoc_STRVAR(py_get_candidate_in_current_page__doc__,
378"get_candidate_in_current_page (int) -> unicode\n"
379"Return the content of this candidate.");
380PyObject *
381PyLookupTable::py_get_candidate_in_current_page (PyLookupTableObject *self, PyObject *args)
382{
383	unsigned index = 0;
384
385	if (!PyArg_ParseTuple (args, "I:get_candidate_in_current_page", &index))
386		return NULL;
387
388	WideString candidate = self->lookup_table.get_candidate_in_current_page (index);
389#if Py_UNICODE_SIZE == 4
390	return PyUnicode_FromUnicode ((Py_UNICODE *)candidate.c_str (), candidate.length ());
391#else
392	gunichar2 *utf16_str = g_ucs4_to_utf16 ((gunichar *)candidate.c_str (),
393						candidate.length (), NULL, NULL, NULL);
394	PyObject * result = PyUnicode_FromUnicode ((Py_UNICODE *)utf16_str, candidate.length ());
395	g_free (utf16_str);
396	return result;
397#endif
398}
399
400PyDoc_STRVAR(py_get_candidate__doc__,
401"get_candidate (int) -> unicode\n"
402"Return the content of this candidate.");
403PyObject *
404PyLookupTable::py_get_candidate (PyLookupTableObject *self, PyObject *args)
405{
406	unsigned index = 0;
407
408	if (!PyArg_ParseTuple (args, "I:get_candidate", &index))
409		return NULL;
410
411	WideString candidate = self->lookup_table.get_candidate (index);
412#if Py_UNICODE_SIZE == 4
413	return PyUnicode_FromUnicode ((Py_UNICODE *)candidate.c_str (), candidate.length ());
414#else
415	gunichar2 *utf16_str = g_ucs4_to_utf16 ((gunichar *)candidate.c_str (),
416						candidate.length (), NULL, NULL, NULL);
417	PyObject * result = PyUnicode_FromUnicode ((Py_UNICODE *)utf16_str, candidate.length ());
418	g_free (utf16_str);
419	return result;
420#endif
421}
422
423
424PyDoc_STRVAR(py_get_attributes__doc__,
425"get_attributes (int) -> list\n"
426"Return a list holding the attributes of this candidates.");
427PyObject *
428PyLookupTable::py_get_attributes (PyLookupTableObject *self, PyObject *args)
429{
430#if 0
431	PyObject *result;
432
433	unsigned index = 0;
434
435	if (!PyArg_ParseTuple (args, "I:get_attributes", &index))
436		return NULL;
437
438	AttributeList atts = self->lookup_table.get_attributes (index)
439
440	result = PyTuple_New ();
441#endif
442	Py_INCREF (Py_None);
443	return Py_None;
444}
445
446PyDoc_STRVAR(py_get_attributes_in_current_page__doc__,
447"get_attributes_in_current_page (int) -> list\n"
448"Return a list holding the attributes of this candidates.");
449PyObject *
450PyLookupTable::py_get_attributes_in_current_page (PyLookupTableObject *self, PyObject *args)
451{
452#if 0
453	PyObject *result;
454
455	unsigned index = 0;
456
457	if (!PyArg_ParseTuple (args, "I:get_attributes", &index))
458		return NULL;
459
460	AttributeList atts = self->lookup_table.get_attributes (index)
461
462	result = PyTuple_New ();
463#endif
464	Py_INCREF (Py_None);
465	return Py_None;
466}
467
468
469PyDoc_STRVAR(py_number_of_candidates__doc__,
470"number_of_candidates () -> int\n"
471"Return the number of candidates in the table.");
472PyObject *
473PyLookupTable::py_number_of_candidates (PyLookupTableObject *self, PyObject *args)
474{
475	uint32 number;
476
477	number = self->lookup_table.number_of_candidates ();
478
479	return PyInt_FromLong (number);
480}
481
482PyDoc_STRVAR(py_clear__doc__,
483"clear () -> none\n"
484"Clear the table.");
485PyObject *
486PyLookupTable::py_clear (PyLookupTableObject *self, PyObject *args)
487{
488	self->lookup_table.clear ();
489	Py_INCREF (Py_None);
490	return Py_None;
491}
492
493PyDoc_STRVAR(py_append_candidate__doc__,
494"append_candidate (unicode, list) -> bool\n"
495"Append a candidate string to the table, the second is a list holding the attributes.\n"
496"Return true if success.");
497PyObject *
498PyLookupTable::py_append_candidate (PyLookupTableObject *self, PyObject *args)
499{
500	Py_UNICODE *candidate = NULL;
501	PyObject *pAttrs = NULL;
502	PyObject *result = Py_False;
503
504#if Py_UNICODE_SIZE == 4
505	if (!PyArg_ParseTuple (args, "u|O:append_candidate", &candidate, &pAttrs))
506		return NULL;
507
508	if (self->lookup_table.append_candidate (WideString ((wchar_t *)candidate),
509								Attributes_FromTupleOrList (pAttrs)))
510	{
511		result = Py_True;
512	}
513#else
514	int size = 0;
515	gunichar *unistr = NULL;
516
517	if (!PyArg_ParseTuple (args, "u#|O:append_candidate", &candidate, &size, &pAttrs))
518		return NULL;
519	unistr = g_utf16_to_ucs4 (candidate, size, NULL, NULL, NULL);
520
521	if (self->lookup_table.append_candidate (WideString ((wchar_t *)unistr),
522								Attributes_FromTupleOrList (pAttrs)))
523	{
524		result = Py_True;
525	}
526	g_free (unistr);
527#endif
528
529	Py_INCREF (result);
530	return result;
531}
532
533
534
535
536
537
538
539
540
541
542PyMethodDef
543PyLookupTable::py_methods[] = {
544#define ENTRY(name, flags) {#name, (PyCFunction)PyLookupTable::py_##name, flags, py_##name##__doc__}
545	ENTRY (set_candidate_labels, METH_VARARGS),
546	ENTRY (get_candidate_label, METH_VARARGS),
547	ENTRY (set_page_size, METH_VARARGS),
548	ENTRY (get_page_size, METH_NOARGS),
549	ENTRY (get_current_page_size, METH_NOARGS),
550	ENTRY (get_current_page_start, METH_NOARGS),
551	ENTRY (is_cursor_visible, METH_NOARGS),
552	ENTRY (is_page_size_fixed, METH_NOARGS),
553	ENTRY (get_cursor_pos, METH_NOARGS),
554	ENTRY (get_cursor_pos_in_current_page, METH_NOARGS),
555	ENTRY (page_up, METH_NOARGS),
556	ENTRY (page_down, METH_NOARGS),
557	ENTRY (cursor_up, METH_NOARGS),
558	ENTRY (cursor_down, METH_NOARGS),
559	ENTRY (show_cursor, METH_VARARGS),
560	ENTRY (fix_page_size, METH_VARARGS),
561	ENTRY (set_cursor_pos, METH_VARARGS),
562	ENTRY (set_cursor_pos_in_current_page, METH_VARARGS),
563	ENTRY (get_candidate_in_current_page, METH_VARARGS),
564	ENTRY (get_attributes_in_current_page, METH_VARARGS),
565	ENTRY (get_candidate, METH_VARARGS),
566	ENTRY (get_attributes, METH_VARARGS),
567	ENTRY (number_of_candidates, METH_NOARGS),
568	ENTRY (clear, METH_NOARGS),
569	ENTRY (append_candidate, METH_VARARGS),
570#undef ENTRY
571		{ NULL }
572};
573
574PyObject *
575PyLookupTable::py_new (PyTypeObject *type, PyObject *args, PyObject *kwds)
576{
577	PyLookupTable *self;
578
579	self = (PyLookupTable *)type->tp_alloc (type, 0);
580	return (PyObject *)self;
581}
582
583int
584PyLookupTable::py_init (PyLookupTableObject *self, PyObject *args, PyObject *kwds)
585{
586	unsigned int page_size = 10;
587
588	if (!PyArg_ParseTuple (args, "|I:__init__", &page_size))
589		return -1;
590
591	new (&self->lookup_table) PyLookupTable (self, page_size);
592
593	return 0;
594}
595
596void
597PyLookupTable::py_dealloc (PyLookupTableObject *self)
598{
599	self->lookup_table.~LookupTable ();
600	((PyObject *)self)->ob_type->tp_free (self);
601}
602
603const PyLookupTable &
604PyLookupTable::from_pyobject (PyObject *object)
605{
606    return ((PyLookupTableObject *)object)->lookup_table;
607}
608
609PyTypeObject PyLookupTableType = {
610	PyObject_HEAD_INIT (NULL)
611	0,						 			/*ob_size*/
612	"scim.LookupTable", 				/*tp_name*/
613	sizeof (PyLookupTableObject), 		/*tp_basicsize*/
614	0,						 			/*tp_itemsize*/
615	(destructor)PyLookupTable::py_dealloc,	/*tp_dealloc*/
616	0,			  						/*tp_print*/
617	0,						 			/*tp_getattr*/
618	0,									/*tp_setattr*/
619	0,									/*tp_compare*/
620	0,			  						/*tp_repr*/
621	0,									/*tp_as_number*/
622	0,			  						/*tp_as_sequence*/
623	0,									/*tp_as_mapping*/
624	0,			  						/*tp_hash */
625	0,									/*tp_call*/
626	0,		  							/*tp_str*/
627	0,					   				/*tp_getattro*/
628	0,									/*tp_setattro*/
629	0,					 				/*tp_as_buffer*/
630	Py_TPFLAGS_DEFAULT | 
631	Py_TPFLAGS_BASETYPE,				/*tp_flags*/
632	"PyLookupTable objects",		 	/* tp_doc */
633	0,					   				/* tp_traverse */
634	0,					   				/* tp_clear */
635	0,					   				/* tp_richcompare */
636	0,					   				/* tp_weaklistoffset */
637	0,					   				/* tp_iter */
638	0,					   				/* tp_iternext */
639	PyLookupTable::py_methods,			/* tp_methods */
640	0,			 						/* tp_members */
641	0,						 			/* tp_getset */
642	0,						 			/* tp_base */
643	0,						 			/* tp_dict */
644	0,						 			/* tp_descr_get */
645	0,						 			/* tp_descr_set */
646	0,									/* tp_dictoffset */
647	(initproc)PyLookupTable::py_init,	/* tp_init */
648	0,						 			/* tp_alloc */
649	PyLookupTable::py_new,				/* tp_new */
650	PyObject_Del,				 		/* tp_free */
651};
652
653void init_lookup_table (PyObject *module)
654{
655	if (PyType_Ready (&PyLookupTableType) < 0)
656		return;
657
658	Py_INCREF (&PyLookupTableType);
659	PyModule_AddObject (module, "LookupTable", (PyObject *)&PyLookupTableType);
660}