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