PageRenderTime 85ms CodeModel.GetById 20ms app.highlight 32ms RepoModel.GetById 18ms app.codeStats 0ms

/src/scim-python-factory.cpp

http://scim-python.googlecode.com/
C++ | 383 lines | 294 code | 62 blank | 27 comment | 30 complexity | ac195da15057f82dd39a4635c82263c0 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.h"
 27#include <glib.h>
 28
 29using namespace scim;
 30
 31struct PyIMEngineFactoryObject {
 32	PyListObject list;
 33	/* Type-specific fields go here. */
 34	PyIMEngineFactory factory;
 35};
 36
 37PyIMEngineFactory::PyIMEngineFactory (PyObject *self, PyObject *config)
 38	:self (self), config (config)
 39{
 40	Py_INCREF (self);
 41	Py_INCREF (config);
 42
 43	reload_signal_connection = 
 44		PyConfig_from_pyobject (config)->signal_connect_reload (slot (this, &PyIMEngineFactory::reload_config));
 45
 46};
 47
 48PyIMEngineFactory::~PyIMEngineFactory () 
 49{
 50	PyObject *pFunc = NULL;
 51	PyObject *pArgs = NULL;
 52	PyObject *result = NULL;
 53
 54	reload_signal_connection.disconnect ();
 55	if (!PyObject_HasAttrString (self, "destroy"))
 56		goto _success_out;
 57
 58	pFunc = PyObject_GetAttrString (self, "destroy");
 59	if (pFunc == NULL) {
 60		goto _failed_out;
 61	}
 62
 63	pArgs = Py_BuildValue ("()");
 64	result = PyObject_CallObject (pFunc, pArgs);
 65	if (result == NULL)
 66		goto _failed_out;
 67
 68	goto _success_out;
 69
 70_failed_out:
 71	PyErr_Print ();
 72
 73_success_out:
 74	Py_XDECREF (result);
 75	Py_XDECREF (pArgs);
 76	Py_XDECREF (pFunc);
 77	Py_XDECREF (self);
 78	Py_XDECREF (config);
 79}
 80
 81void
 82PyIMEngineFactory::operator delete (void *p)
 83{
 84	// do nothing
 85}
 86
 87String 
 88PyIMEngineFactory::get_attr_string (char *name) const
 89{
 90	PyObject *pValue;
 91	String result;
 92
 93	pValue = PyObject_GetAttrString (self, name);
 94
 95	if (pValue) {
 96		if (PyString_Check (pValue)) {
 97			char *str = PyString_AsString (pValue);
 98			result = str;
 99		}
100		else if (PyUnicode_Check (pValue)) {
101			gchar *str = NULL;
102		#if Py_UNICODE_SIZE == 4
103			str = g_ucs4_to_utf8 ((gunichar *)PyUnicode_AS_UNICODE (pValue), 
104						PyUnicode_GET_SIZE (pValue), NULL, NULL, NULL);
105			result = str;
106			g_free (str);
107		#else
108			str = g_utf16_to_utf8 ((gunichar2 *)PyUnicode_AS_UNICODE (pValue),
109						PyUnicode_GET_SIZE (pValue), NULL, NULL, NULL);
110			result = str;
111			g_free (str);
112		#endif
113		}
114		Py_DECREF (pValue);
115	}
116	else {
117		PyErr_Print ();
118	}
119	return result;
120}
121
122WideString
123PyIMEngineFactory::get_attr_unicode (char *name) const
124{
125	PyObject *pValue;
126	WideString result;
127
128	pValue = PyObject_GetAttrString (self, name);
129
130	if (pValue) {
131		if (PyUnicode_Check (pValue)) {
132		#if Py_UNICODE_SIZE == 4
133			result = (wchar_t *)PyUnicode_AS_UNICODE (pValue);
134		#else
135			gunichar *unistr = g_utf16_to_ucs4 (PyUnicode_AS_UNICODE (pValue),
136						PyUnicode_GET_SIZE (pValue), NULL, NULL, NULL);
137			result = (wchar_t *) unistr;
138			g_free (unistr);
139		#endif
140		}
141		else if (PyString_Check (pValue)) {
142			gunichar *unistr = g_utf8_to_ucs4 (PyString_AsString (pValue),
143						PyString_GET_SIZE (pValue), NULL, NULL, NULL);
144			result = (wchar_t *)unistr;
145			g_free (unistr);
146		}
147		Py_DECREF (pValue);
148	}
149	else {
150		PyErr_Print ();
151	}
152	return result;
153}
154
155WideString
156PyIMEngineFactory::get_name () const 
157{
158	return get_attr_unicode ("name");
159}
160
161String
162PyIMEngineFactory::get_uuid () const 
163{ 
164	return get_attr_string ("uuid");
165}
166
167String
168PyIMEngineFactory::get_icon_file () const 
169{
170	return get_attr_string ("icon_file");
171}
172
173WideString
174PyIMEngineFactory::get_authors () const 
175{
176	return get_attr_unicode ("authors");
177}
178
179WideString
180PyIMEngineFactory::get_credits () const 
181{
182	return get_attr_unicode ("credits");
183}
184
185WideString
186PyIMEngineFactory::get_help () const 
187{
188	return get_attr_unicode ("help");
189}
190
191bool 
192PyIMEngineFactory::validate_encoding (const String& encoding)
193{ 
194	return true; 
195}
196
197bool
198PyIMEngineFactory::validate_locale (const String& locale)
199{
200	return true; 
201}
202
203
204PyObject *
205PyIMEngineFactory::py_set_languages (PyIMEngineFactoryObject *self, PyObject *args)
206{
207	char * languages;
208
209	if (!PyArg_ParseTuple (args, "s:set_language", &languages))
210			return NULL;
211
212	self->factory.set_languages (languages);
213
214	Py_INCREF (Py_None);
215	return Py_None;
216}
217
218IMEngineInstancePointer
219PyIMEngineFactory::create_instance (const String& encoding, int id) 
220{
221	PyObject *pFunc = NULL;
222	PyObject *pEngine = NULL;
223	PyObject *pArgs = NULL;
224
225	IMEngineInstancePointer result (0);
226
227	pFunc = PyObject_GetAttrString (self, "create_instance");
228	if (pFunc == NULL)
229		goto _failed_out;
230
231	pArgs = Py_BuildValue ("(si)", encoding.c_str (), id);
232
233	pEngine = PyObject_CallObject (pFunc, pArgs);
234
235	if (pEngine == NULL) {
236		/* will create a dummy engine */
237		PyErr_Print ();
238
239		extern PyTypeObject PyIMEngineType;
240		pEngine = PyObject_New (PyObject, &PyIMEngineType);
241		pEngine = PyObject_Init (pEngine, &PyIMEngineType);
242
243		Py_XDECREF (pArgs);
244		pArgs = Py_BuildValue ("(OOsi)", self, config, encoding.c_str (), id); 
245		PyIMEngineType.tp_init (pEngine, pArgs, NULL);
246	}
247
248	result = PyIMEngine::from_pyobject (pEngine);
249	goto _success_out;
250
251_failed_out:
252	PyErr_Print ();
253_success_out:
254	Py_XDECREF (pArgs);
255	Py_XDECREF (pFunc);
256	Py_XDECREF (pEngine);
257
258	return result;
259}
260
261
262void 
263PyIMEngineFactory::reload_config (const ConfigPointer &config)
264{
265	PyObject *pFunc = NULL;
266	PyObject *pValue = NULL;
267	PyObject *pArgs = NULL;
268
269	pFunc = PyObject_GetAttrString (this->self, "reload_config");
270	if (pFunc == NULL)
271		goto _failed_out;
272
273	pArgs = Py_BuildValue ("(O)", this->config);
274	if (pArgs == NULL)
275		goto _failed_out;
276
277	pValue = PyObject_CallObject (pFunc, pArgs);
278	if (pValue == NULL)
279		goto _failed_out;
280	goto _success_out;
281
282_failed_out:
283	PyErr_Print ();
284_success_out:
285	Py_XDECREF (pArgs);
286	Py_XDECREF (pFunc);
287	Py_XDECREF (pValue);
288}
289
290PyMethodDef 
291PyIMEngineFactory::py_methods[] = { 
292		{	"set_languages", (PyCFunction)PyIMEngineFactory::py_set_languages, METH_VARARGS,
293			"Set languages"
294		},
295		{ NULL }
296};
297
298PyObject *
299PyIMEngineFactory::py_new (PyTypeObject *type, PyObject *args, PyObject *kwds)
300{
301	PyIMEngineFactoryObject *self;
302
303	self = (PyIMEngineFactoryObject *)type->tp_alloc (type, 0);
304	return (PyObject *)self;
305}
306
307int
308PyIMEngineFactory::py_init (PyIMEngineFactoryObject *self, PyObject *args, PyObject *kwds)
309{
310	PyObject *config;
311
312	if (!PyArg_ParseTuple (args, "O:__init__", &config))
313			return -1;
314	new (&self->factory) PyIMEngineFactory ((PyObject *)self, config);
315
316	return 0;
317}
318
319void
320PyIMEngineFactory::py_dealloc (PyIMEngineFactoryObject *self)
321{
322	((PyObject *) self)->ob_type->tp_free (self);
323}
324
325
326IMEngineFactoryBase *
327PyIMEngineFactory::from_pyobject (PyObject *object)
328{
329	PyIMEngineFactoryObject *self = (PyIMEngineFactoryObject *) object;
330	return (IMEngineFactoryBase *)&self->factory;
331}
332
333PyTypeObject PyIMEngineFactoryType = {
334	PyObject_HEAD_INIT (NULL)
335	0,						 							/*ob_size*/
336	"scim.IMEngineFactory", 							/*tp_name*/
337	sizeof (PyIMEngineFactoryObject),					/*tp_basicsize*/
338	0,						 							/*tp_itemsize*/
339	0 /* (destructor)PyIMEngineFactory::py_dealloc */,			/*tp_dealloc*/
340	0,			  										/*tp_print*/
341	0,						 							/*tp_getattr*/
342	0,													/*tp_setattr*/
343	0,													/*tp_compare*/
344	0,									/*tp_repr*/
345	0,									/*tp_as_number*/
346	0,									/*tp_as_sequence*/
347	0,									/*tp_as_mapping*/
348	0,									/*tp_hash */
349	0,									/*tp_call*/
350	0,		  							/*tp_str*/
351	0,					   				/*tp_getattro*/
352	0,									/*tp_setattro*/
353	0,					 				/*tp_as_buffer*/
354	Py_TPFLAGS_DEFAULT | 
355	Py_TPFLAGS_BASETYPE,				/*tp_flags*/
356	"IMEngineInstanceBase objects",		/* tp_doc */
357	0,					   /* tp_traverse */
358	0,					   /* tp_clear */
359	0,					   /* tp_richcompare */
360	0,					   /* tp_weaklistoffset */
361	0,					   /* tp_iter */
362	0,					   /* tp_iternext */
363	PyIMEngineFactory::py_methods,			 /* tp_methods */
364	0,			 /* tp_members */
365	0,						 /* tp_getset */
366	0,						 /* tp_base */
367	0,						 /* tp_dict */
368	0,						 /* tp_descr_get */
369	0,						 /* tp_descr_set */
370	0,						 /* tp_dictoffset */
371	(initproc)PyIMEngineFactory::py_init,	  /* tp_init */
372	0,						 /* tp_alloc */
373	PyIMEngineFactory::py_new,				 /* tp_new */
374};
375
376void init_factory (PyObject *module)
377{
378	if (PyType_Ready (&PyIMEngineFactoryType) < 0)
379		return;
380
381	Py_INCREF (&PyIMEngineFactoryType);
382	PyModule_AddObject (module, "IMEngineFactory", (PyObject *)&PyIMEngineFactoryType);
383}