changed: removed setInfoDict() and made setInfo() accept a dictionary of { tag: value...
[xbmc:xbmc-antiquated.git] / xbmc / lib / libPython / xbmcmodule / listitem.cpp
1 #include "stdafx.h"
2 #include "../python/python.h"
3 #include "listitem.h"
4 #include "pyutil.h"
5
6 #pragma code_seg("PY_TEXT")
7 #pragma data_seg("PY_DATA")
8 #pragma bss_seg("PY_BSS")
9 #pragma const_seg("PY_RDATA")
10
11 #ifdef __cplusplus
12 extern "C" {
13 #endif
14
15 namespace PYXBMC
16 {
17   PyObject* ListItem_New(PyTypeObject *type, PyObject *args, PyObject *kwds)
18   {
19     ListItem *self;
20     static char *keywords[] = { "label", "label2",
21       "iconImage", "thumbnailImage", NULL };
22
23     PyObject* label = NULL;
24     PyObject* label2 = NULL;
25     char* cIconImage = NULL;
26     char* cThumbnailImage = NULL;
27
28     // allocate new object
29     self = (ListItem*)type->tp_alloc(type, 0);
30     if (!self) return NULL;
31       self->item = NULL;
32
33     // parse user input
34     if (!PyArg_ParseTupleAndKeywords(
35       args, kwds,
36       "|OOss", keywords,
37       &label, &label2,
38       &cIconImage, &cThumbnailImage))
39     {
40       Py_DECREF( self );
41       return NULL;
42     }
43
44     // create CFileItem
45     self->item = new CFileItem();
46     if (!self->item)
47     {
48       Py_DECREF( self );
49       return NULL;
50     }
51     CStdString utf8String;
52     if (label && PyGetUnicodeString(utf8String, label, 1))
53     {
54       self->item->SetLabel( utf8String );
55     }
56     if (label2 && PyGetUnicodeString(utf8String, label2, 1))
57     {
58       self->item->SetLabel2( utf8String );
59     }
60     if (cIconImage)
61     {
62       self->item->SetIconImage( cIconImage );
63     }
64     if (cThumbnailImage)
65     {
66       self->item->SetThumbnailImage( cThumbnailImage );
67     }
68     return (PyObject*)self;
69   }
70
71   /*
72    * allocate a new listitem. Used for c++ and not the python user
73    * returns a new reference
74    */
75   ListItem* ListItem_FromString(string strLabel)
76   {
77     ListItem* self = (ListItem*)ListItem_Type.tp_alloc(&ListItem_Type, 0);
78     if (!self) return NULL;
79
80     self->item = new CFileItem(strLabel);
81     if (!self->item)
82     {
83       Py_DECREF( self );
84       return NULL;
85     }
86
87     return self;
88   }
89
90   void ListItem_Dealloc(ListItem* self)
91   {
92     if (self->item) delete self->item;
93     self->ob_type->tp_free((PyObject*)self);
94   }
95
96   PyDoc_STRVAR(getLabel__doc__,
97     "getLabel() -- Returns the listitem label.\n"
98     "\n"
99     "example:\n"
100     "  - label = self.list.getSelectedItem().getLabel()\n");
101
102   PyObject* ListItem_GetLabel(ListItem *self, PyObject *args)
103   {
104     if (!self->item) return NULL;
105
106     PyGUILock();
107     const char *cLabel =  self->item->GetLabel().c_str();
108     PyGUIUnlock();
109
110     return Py_BuildValue("s", cLabel);
111   }
112
113   PyDoc_STRVAR(getLabel2__doc__,
114     "getLabel2() -- Returns the listitem's second label.\n"
115     "\n"
116     "example:\n"
117     "  - label2 = self.list.getSelectedItem().getLabel2()\n");
118
119   PyObject* ListItem_GetLabel2(ListItem *self, PyObject *args)
120   {
121     if (!self->item) return NULL;
122
123     PyGUILock();
124     const char *cLabel = self->item->GetLabel2().c_str();
125     PyGUIUnlock();
126
127     return Py_BuildValue("s", cLabel);
128   }
129
130   PyDoc_STRVAR(setLabel__doc__,
131     "setLabel(label) -- Sets the listitem's label.\n"
132     "\n"
133     "label          : string or unicode - text string.\n"
134     "\n"
135     "example:\n"
136     "  - self.list.getSelectedItem().setLabel('Casino Royale')\n");
137
138   PyObject* ListItem_SetLabel(ListItem *self, PyObject *args)
139   {
140     PyObject* unicodeLine = NULL;
141     if (!self->item) return NULL;
142
143     if (!PyArg_ParseTuple(args, "O", &unicodeLine)) return NULL;
144
145     string utf8Line;
146     if (unicodeLine && !PyGetUnicodeString(utf8Line, unicodeLine, 1))
147       return NULL;
148     // set label
149     PyGUILock();
150     self->item->SetLabel(utf8Line);
151     PyGUIUnlock();
152
153     Py_INCREF(Py_None);
154     return Py_None;
155   }
156
157   PyDoc_STRVAR(setLabel2__doc__,
158     "setLabel2(label2) -- Sets the listitem's second label.\n"
159     "\n"
160     "label2         : string or unicode - text string.\n"
161     "\n"
162     "example:\n"
163     "  - self.list.getSelectedItem().setLabel2('[pg-13]')\n");
164   
165   PyObject* ListItem_SetLabel2(ListItem *self, PyObject *args)
166   {
167     PyObject* unicodeLine = NULL;
168     if (!self->item) return NULL;
169
170     if (!PyArg_ParseTuple(args, "O", &unicodeLine)) return NULL;
171
172     string utf8Line;
173     if (unicodeLine && !PyGetUnicodeString(utf8Line, unicodeLine, 1))
174       return NULL;
175     // set label
176     PyGUILock();
177     self->item->SetLabel2(utf8Line);
178     PyGUIUnlock();
179
180     Py_INCREF(Py_None);
181     return Py_None;
182   }
183
184   PyDoc_STRVAR(setIconImage__doc__,
185     "setIconImage(icon) -- Sets the listitem's icon image.\n"
186     "\n"
187     "icon            : string - image filename.\n"
188     "\n"
189     "example:\n"
190     "  - self.list.getSelectedItem().setIconImage('emailread.png')\n");
191
192   PyObject* ListItem_SetIconImage(ListItem *self, PyObject *args)
193   {
194     char *cLine = NULL;
195     if (!self->item) return NULL;
196
197     if (!PyArg_ParseTuple(args, "s", &cLine)) return NULL;
198
199     // set label
200     PyGUILock();
201     self->item->SetIconImage(cLine ? cLine : "");
202     PyGUIUnlock();
203
204     Py_INCREF(Py_None);
205     return Py_None;
206   }
207
208   PyDoc_STRVAR(setThumbnailImage__doc__,
209     "setThumbnailImage(thumb) -- Sets the listitem's thumbnail image.\n"
210     "\n"
211     "thumb           : string - image filename.\n"
212     "\n"
213     "example:\n"
214     "  - self.list.getSelectedItem().setThumbnailImage('emailread.png')\n");
215
216   PyObject* ListItem_SetThumbnailImage(ListItem *self, PyObject *args)
217   {
218     char *cLine = NULL;
219     if (!self->item) return NULL;
220
221     if (!PyArg_ParseTuple(args, "s", &cLine)) return NULL;
222
223     // set label
224     PyGUILock();
225     self->item->SetThumbnailImage(cLine ? cLine : "");
226     PyGUIUnlock();
227
228     Py_INCREF(Py_None);
229     return Py_None;
230   }
231
232   PyDoc_STRVAR(select__doc__,
233     "select(selected) -- Sets the listitem's selected status.\n"
234     "\n"
235     "selected        : bool - True=selected/False=not selected\n"
236     "\n"
237     "example:\n"
238     "  - self.list.getSelectedItem().select(True)\n");
239
240   PyObject* ListItem_Select(ListItem *self, PyObject *args)
241   {
242     if (!self->item) return NULL;
243
244     bool bOnOff = false;
245     if (!PyArg_ParseTuple(args, "b", &bOnOff)) return NULL;
246
247     PyGUILock();
248     self->item->Select(bOnOff);
249     PyGUIUnlock();
250
251     Py_INCREF(Py_None);
252     return Py_None;
253   }
254   
255   PyDoc_STRVAR(isSelected__doc__,
256     "isSelected() -- Returns the listitem's selected status.\n"
257     "\n"
258     "example:\n"
259     "  - is = self.list.getSelectedItem().isSelected()\n");
260
261   PyObject* ListItem_IsSelected(ListItem *self, PyObject *args)
262   {
263     if (!self->item) return NULL;
264
265     PyGUILock();
266     bool bOnOff = self->item->IsSelected();
267     PyGUIUnlock();
268
269     return Py_BuildValue("b", bOnOff);
270   }
271
272   PyDoc_STRVAR(setInfo__doc__,
273     "setInfo(type, tags) -- Sets the listitem's media tags.\n"
274     "\n"
275     "type           : string - type of media(video/music/pictures).\n"
276     "tags           : dictionary - pairs of { tag: value }.\n"
277     "\n"
278     "*Note, You can use the above as keywords for arguments and skip certain optional arguments.\n"
279     "       Once you use a keyword, all following arguments require the keyword.\n"
280     "\n"
281     "example:\n"
282     "  - self.list.getSelectedItem().setInfo('video', { 'Genre': 'Comedy' })\n");
283
284   PyObject* ListItem_SetInfo(ListItem *self, PyObject *args, PyObject *kwds)
285   {
286     static char *keywords[] = { "type", "tags", NULL };
287     char *cType = NULL;
288     PyObject *pTagDict = NULL;
289     if (!PyArg_ParseTupleAndKeywords(
290       args,
291       kwds,
292       "sO",
293       keywords,
294       &cType,
295       &pTagDict))
296     {
297       return NULL;
298     }
299     if (!PyObject_TypeCheck(pTagDict, &PyDict_Type))
300     {
301       PyErr_SetString(PyExc_TypeError, "tags object should be of type Dict");
302       return NULL;
303     }
304     CLog::Log(LOGDEBUG, __FUNCTION__" - Tag Dictionary has %i items", PyDict_Size(pTagDict));
305     if (PyDict_Size(pTagDict) == 0)
306     {
307       PyErr_SetString(PyExc_ValueError, "Empty tags dictionary");
308       return NULL;
309     }
310
311     PyObject *key, *value;
312     int pos = 0;
313
314     PyGUILock();
315     while (PyDict_Next(pTagDict, &pos, &key, &value)) {
316       //CLog::Log(LOGDEBUG, __FUNCTION__" - Tag Dictionary: pos: %i  key: %s  value: %s", pos, PyString_AsString(key), PyString_AsString(value));
317       if (strcmpi(cType, "video") == 0)
318       {
319         //CLog::Log(LOGDEBUG, __FUNCTION__" - Type: %s - Tag: %s - Value: %s ", cType, PyString_AsString(key), PyString_AsString(value));
320         if (strcmpi(PyString_AsString(key), "genre") == 0)
321           self->item->GetVideoInfoTag()->m_strGenre = PyString_AsString(value);
322         else if (strcmpi(PyString_AsString(key), "year") == 0)
323           self->item->GetVideoInfoTag()->m_iYear = PyInt_AsLong(value);
324         else if (strcmpi(PyString_AsString(key), "director") == 0)
325           self->item->GetVideoInfoTag()->m_strDirector = PyString_AsString(value);
326         else if (strcmpi(PyString_AsString(key), "rating") == 0)
327           self->item->GetVideoInfoTag()->m_strMPAARating = PyString_AsString(value);
328         else if (strcmpi(PyString_AsString(key), "plot") == 0)
329           self->item->GetVideoInfoTag()->m_strPlot = PyString_AsString(value);
330         else if (strcmpi(PyString_AsString(key), "plotoutline") == 0)
331           self->item->GetVideoInfoTag()->m_strPlotOutline = PyString_AsString(value);
332         else if (strcmpi(PyString_AsString(key), "runtime") == 0)
333           self->item->GetVideoInfoTag()->m_strRuntime = PyString_AsString(value);
334         else if (strcmpi(PyString_AsString(key), "title") == 0)
335           self->item->GetVideoInfoTag()->m_strTitle = PyString_AsString(value);
336       }
337       else if (strcmpi(cType, "music") == 0)
338       {
339         //CLog::Log(LOGDEBUG, __FUNCTION__" - Type: %s - Tag: %s - Value: %s ", cType, PyString_AsString(key), PyString_AsString(value));
340       }
341       else if (strcmpi(cType, "pictures") == 0)
342       {
343         //CLog::Log(LOGDEBUG, __FUNCTION__" - Type: %s - Tag: %s - Value: %s ", cType, PyString_AsString(key), PyString_AsString(value));
344       }
345     }
346     PyGUIUnlock();
347
348     Py_INCREF(Py_None);
349     return Py_None;
350   }
351   PyMethodDef ListItem_methods[] = {
352     {"getLabel" , (PyCFunction)ListItem_GetLabel, METH_VARARGS, getLabel__doc__},
353     {"setLabel" , (PyCFunction)ListItem_SetLabel, METH_VARARGS, setLabel__doc__},
354     {"getLabel2", (PyCFunction)ListItem_GetLabel2, METH_VARARGS, getLabel2__doc__},
355     {"setLabel2", (PyCFunction)ListItem_SetLabel2, METH_VARARGS, setLabel2__doc__},
356     {"setIconImage", (PyCFunction)ListItem_SetIconImage, METH_VARARGS, setIconImage__doc__},
357     {"setThumbnailImage", (PyCFunction)ListItem_SetThumbnailImage, METH_VARARGS, setThumbnailImage__doc__},
358     {"select", (PyCFunction)ListItem_Select, METH_VARARGS, select__doc__},
359     {"isSelected", (PyCFunction)ListItem_IsSelected, METH_VARARGS, isSelected__doc__},
360     {"setInfo", (PyCFunction)ListItem_SetInfo, METH_KEYWORDS, setInfo__doc__},
361     {NULL, NULL, 0, NULL}
362   };
363
364   PyDoc_STRVAR(listItem__doc__,
365     "ListItem class.\n"
366     "\n"
367     "ListItem([label, label2, iconImage, thumbnailImage]) -- Creates a new ListItem.\n"
368     "\n"
369     "label          : [opt] string or unicode - label1 text.\n"
370     "label2         : [opt] string or unicode - label2 text.\n"
371     "iconImage      : [opt] string - icon filename.\n"
372     "thumbnailImage : [opt] string - thumbnail filename.\n"
373     "\n"
374     "example:\n"
375     "  - listitem = xbmcgui.ListItem('Casino Royale', '[PG-13]', 'blank-poster.tbn', 'poster.tbn')\n");
376
377 // Restore code and data sections to normal.
378 #pragma code_seg()
379 #pragma data_seg()
380 #pragma bss_seg()
381 #pragma const_seg()
382
383   PyTypeObject ListItem_Type;
384
385   void initListItem_Type()
386   {
387     PyInitializeTypeObject(&ListItem_Type);
388
389     ListItem_Type.tp_name = "xbmcgui.ListItem";
390     ListItem_Type.tp_basicsize = sizeof(ListItem);
391     ListItem_Type.tp_dealloc = (destructor)ListItem_Dealloc;
392     ListItem_Type.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE;
393     ListItem_Type.tp_doc = listItem__doc__;
394     ListItem_Type.tp_methods = ListItem_methods;
395     ListItem_Type.tp_base = 0;
396     ListItem_Type.tp_new = ListItem_New;
397   }
398 }
399
400 #ifdef __cplusplus
401 }
402 #endif