Merge pull request #4676 from jmarshallnz/dont_set_scraper_on_tvshow_on_nfo
[vuplus_xbmc] / xbmc / addons / AddonCallbacksGUI.cpp
1 /*
2  *      Copyright (C) 2012-2013 Team XBMC
3  *      http://xbmc.org
4  *
5  *  This Program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; either version 2, or (at your option)
8  *  any later version.
9  *
10  *  This Program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with XBMC; see the file COPYING.  If not, see
17  *  <http://www.gnu.org/licenses/>.
18  *
19  */
20
21 #include "Application.h"
22 #include "ApplicationMessenger.h"
23 #include "Addon.h"
24 #include "AddonCallbacksGUI.h"
25 #include "utils/log.h"
26 #include "Skin.h"
27 #include "FileItem.h"
28 #include "filesystem/File.h"
29 #include "utils/URIUtils.h"
30 #include "utils/TimeUtils.h"
31 #include "utils/StringUtils.h"
32 #include "guilib/GUIWindowManager.h"
33 #include "guilib/Key.h"
34 #include "guilib/TextureManager.h"
35 #include "guilib/GUISpinControlEx.h"
36 #include "guilib/GUIRadioButtonControl.h"
37 #include "guilib/GUISettingsSliderControl.h"
38 #include "guilib/GUIEditControl.h"
39 #include "guilib/GUIProgressControl.h"
40 #include "guilib/GUIRenderingControl.h"
41
42 #define CONTROL_BTNVIEWASICONS  2
43 #define CONTROL_BTNSORTBY       3
44 #define CONTROL_BTNSORTASC      4
45 #define CONTROL_LABELFILES      12
46
47 using namespace std;
48
49 namespace ADDON
50 {
51
52 static int iXBMCGUILockRef = 0;
53
54 CAddonCallbacksGUI::CAddonCallbacksGUI(CAddon* addon)
55 {
56   m_addon     = addon;
57   m_callbacks = new CB_GUILib;
58
59   /* GUI Helper functions */
60   m_callbacks->Lock                           = CAddonCallbacksGUI::Lock;
61   m_callbacks->Unlock                         = CAddonCallbacksGUI::Unlock;
62   m_callbacks->GetScreenHeight                = CAddonCallbacksGUI::GetScreenHeight;
63   m_callbacks->GetScreenWidth                 = CAddonCallbacksGUI::GetScreenWidth;
64   m_callbacks->GetVideoResolution             = CAddonCallbacksGUI::GetVideoResolution;
65   m_callbacks->Window_New                     = CAddonCallbacksGUI::Window_New;
66   m_callbacks->Window_Delete                  = CAddonCallbacksGUI::Window_Delete;
67   m_callbacks->Window_SetCallbacks            = CAddonCallbacksGUI::Window_SetCallbacks;
68   m_callbacks->Window_Show                    = CAddonCallbacksGUI::Window_Show;
69   m_callbacks->Window_Close                   = CAddonCallbacksGUI::Window_Close;
70   m_callbacks->Window_DoModal                 = CAddonCallbacksGUI::Window_DoModal;
71   m_callbacks->Window_SetFocusId              = CAddonCallbacksGUI::Window_SetFocusId;
72   m_callbacks->Window_GetFocusId              = CAddonCallbacksGUI::Window_GetFocusId;
73   m_callbacks->Window_SetCoordinateResolution = CAddonCallbacksGUI::Window_SetCoordinateResolution;
74   m_callbacks->Window_SetProperty             = CAddonCallbacksGUI::Window_SetProperty;
75   m_callbacks->Window_SetPropertyInt          = CAddonCallbacksGUI::Window_SetPropertyInt;
76   m_callbacks->Window_SetPropertyBool         = CAddonCallbacksGUI::Window_SetPropertyBool;
77   m_callbacks->Window_SetPropertyDouble       = CAddonCallbacksGUI::Window_SetPropertyDouble;
78   m_callbacks->Window_GetProperty             = CAddonCallbacksGUI::Window_GetProperty;
79   m_callbacks->Window_GetPropertyInt          = CAddonCallbacksGUI::Window_GetPropertyInt;
80   m_callbacks->Window_GetPropertyBool         = CAddonCallbacksGUI::Window_GetPropertyBool;
81   m_callbacks->Window_GetPropertyDouble       = CAddonCallbacksGUI::Window_GetPropertyDouble;
82   m_callbacks->Window_ClearProperties         = CAddonCallbacksGUI::Window_ClearProperties;
83
84   m_callbacks->Window_GetListSize             = CAddonCallbacksGUI::Window_GetListSize;
85   m_callbacks->Window_ClearList               = CAddonCallbacksGUI::Window_ClearList;
86   m_callbacks->Window_AddItem                 = CAddonCallbacksGUI::Window_AddItem;
87   m_callbacks->Window_AddStringItem           = CAddonCallbacksGUI::Window_AddStringItem;
88   m_callbacks->Window_RemoveItem              = CAddonCallbacksGUI::Window_RemoveItem;
89   m_callbacks->Window_GetListItem             = CAddonCallbacksGUI::Window_GetListItem;
90   m_callbacks->Window_SetCurrentListPosition  = CAddonCallbacksGUI::Window_SetCurrentListPosition;
91   m_callbacks->Window_GetCurrentListPosition  = CAddonCallbacksGUI::Window_GetCurrentListPosition;
92
93   m_callbacks->Window_GetControl_Spin         = CAddonCallbacksGUI::Window_GetControl_Spin;
94   m_callbacks->Window_GetControl_Button       = CAddonCallbacksGUI::Window_GetControl_Button;
95   m_callbacks->Window_GetControl_RadioButton  = CAddonCallbacksGUI::Window_GetControl_RadioButton;
96   m_callbacks->Window_GetControl_Edit         = CAddonCallbacksGUI::Window_GetControl_Edit;
97   m_callbacks->Window_GetControl_Progress     = CAddonCallbacksGUI::Window_GetControl_Progress;
98   m_callbacks->Window_GetControl_RenderAddon  = CAddonCallbacksGUI::Window_GetControl_RenderAddon;
99
100   m_callbacks->Window_SetControlLabel         = CAddonCallbacksGUI::Window_SetControlLabel;
101   m_callbacks->Window_MarkDirtyRegion         = CAddonCallbacksGUI::Window_MarkDirtyRegion;
102
103   m_callbacks->Control_Spin_SetVisible        = CAddonCallbacksGUI::Control_Spin_SetVisible;
104   m_callbacks->Control_Spin_SetText           = CAddonCallbacksGUI::Control_Spin_SetText;
105   m_callbacks->Control_Spin_Clear             = CAddonCallbacksGUI::Control_Spin_Clear;
106   m_callbacks->Control_Spin_AddLabel          = CAddonCallbacksGUI::Control_Spin_AddLabel;
107   m_callbacks->Control_Spin_GetValue          = CAddonCallbacksGUI::Control_Spin_GetValue;
108   m_callbacks->Control_Spin_SetValue          = CAddonCallbacksGUI::Control_Spin_SetValue;
109
110   m_callbacks->Control_RadioButton_SetVisible = CAddonCallbacksGUI::Control_RadioButton_SetVisible;
111   m_callbacks->Control_RadioButton_SetText    = CAddonCallbacksGUI::Control_RadioButton_SetText;
112   m_callbacks->Control_RadioButton_SetSelected= CAddonCallbacksGUI::Control_RadioButton_SetSelected;
113   m_callbacks->Control_RadioButton_IsSelected = CAddonCallbacksGUI::Control_RadioButton_IsSelected;
114
115   m_callbacks->Control_Progress_SetPercentage = CAddonCallbacksGUI::Control_Progress_SetPercentage;
116   m_callbacks->Control_Progress_GetPercentage = CAddonCallbacksGUI::Control_Progress_GetPercentage;
117   m_callbacks->Control_Progress_SetInfo       = CAddonCallbacksGUI::Control_Progress_SetInfo;
118   m_callbacks->Control_Progress_GetInfo       = CAddonCallbacksGUI::Control_Progress_GetInfo;
119   m_callbacks->Control_Progress_GetDescription= CAddonCallbacksGUI::Control_Progress_GetDescription;
120
121   m_callbacks->ListItem_Create                = CAddonCallbacksGUI::ListItem_Create;
122   m_callbacks->ListItem_GetLabel              = CAddonCallbacksGUI::ListItem_GetLabel;
123   m_callbacks->ListItem_SetLabel              = CAddonCallbacksGUI::ListItem_SetLabel;
124   m_callbacks->ListItem_GetLabel2             = CAddonCallbacksGUI::ListItem_GetLabel2;
125   m_callbacks->ListItem_SetLabel2             = CAddonCallbacksGUI::ListItem_SetLabel2;
126   m_callbacks->ListItem_SetIconImage          = CAddonCallbacksGUI::ListItem_SetIconImage;
127   m_callbacks->ListItem_SetThumbnailImage     = CAddonCallbacksGUI::ListItem_SetThumbnailImage;
128   m_callbacks->ListItem_SetInfo               = CAddonCallbacksGUI::ListItem_SetInfo;
129   m_callbacks->ListItem_SetProperty           = CAddonCallbacksGUI::ListItem_SetProperty;
130   m_callbacks->ListItem_GetProperty           = CAddonCallbacksGUI::ListItem_GetProperty;
131   m_callbacks->ListItem_SetPath               = CAddonCallbacksGUI::ListItem_SetPath;
132
133   m_callbacks->RenderAddon_SetCallbacks       = CAddonCallbacksGUI::RenderAddon_SetCallbacks;
134   m_callbacks->RenderAddon_Delete             = CAddonCallbacksGUI::RenderAddon_Delete;
135 }
136
137 CAddonCallbacksGUI::~CAddonCallbacksGUI()
138 {
139   delete m_callbacks;
140 }
141
142 void CAddonCallbacksGUI::Lock()
143 {
144   if (iXBMCGUILockRef == 0) g_graphicsContext.Lock();
145   iXBMCGUILockRef++;
146 }
147
148 void CAddonCallbacksGUI::Unlock()
149 {
150   if (iXBMCGUILockRef > 0)
151   {
152     iXBMCGUILockRef--;
153     if (iXBMCGUILockRef == 0) g_graphicsContext.Unlock();
154   }
155 }
156
157 int CAddonCallbacksGUI::GetScreenHeight()
158 {
159   return g_graphicsContext.GetHeight();
160 }
161
162 int CAddonCallbacksGUI::GetScreenWidth()
163 {
164   return g_graphicsContext.GetWidth();
165 }
166
167 int CAddonCallbacksGUI::GetVideoResolution()
168 {
169   return (int)g_graphicsContext.GetVideoResolution();
170 }
171
172 GUIHANDLE CAddonCallbacksGUI::Window_New(void *addonData, const char *xmlFilename, const char *defaultSkin, bool forceFallback, bool asDialog)
173 {
174   CAddonCallbacks* helper = (CAddonCallbacks*) addonData;
175   if (!helper)
176     return NULL;
177
178   CAddonCallbacksGUI* guiHelper = helper->GetHelperGUI();
179
180   RESOLUTION_INFO res;
181   CStdString strSkinPath;
182   if (!forceFallback)
183   {
184     /* Check to see if the XML file exists in current skin. If not use
185        fallback path to find a skin for the addon */
186     strSkinPath = g_SkinInfo->GetSkinPath(xmlFilename, &res);
187
188     if (!XFILE::CFile::Exists(strSkinPath))
189     {
190       /* Check for the matching folder for the skin in the fallback skins folder */
191       CStdString basePath = URIUtils::AddFileToFolder(guiHelper->m_addon->Path(), "resources");
192       basePath = URIUtils::AddFileToFolder(basePath, "skins");
193       basePath = URIUtils::AddFileToFolder(basePath, URIUtils::GetFileName(g_SkinInfo->Path()));
194       strSkinPath = g_SkinInfo->GetSkinPath(xmlFilename, &res, basePath);
195       if (!XFILE::CFile::Exists(strSkinPath))
196       {
197         /* Finally fallback to the DefaultSkin as it didn't exist in either the
198            XBMC Skin folder or the fallback skin folder */
199         forceFallback = true;
200       }
201     }
202   }
203
204   if (forceFallback)
205   {
206     //FIXME make this static method of current skin?
207     CStdString str("none");
208     AddonProps props(str, ADDON_SKIN, str, str);
209     CStdString basePath = URIUtils::AddFileToFolder(guiHelper->m_addon->Path(), "resources");
210     basePath = URIUtils::AddFileToFolder(basePath, "skins");
211     basePath = URIUtils::AddFileToFolder(basePath, defaultSkin);
212     props.path = basePath;
213
214     CSkinInfo skinInfo(props);
215     skinInfo.Start();
216     strSkinPath = skinInfo.GetSkinPath(xmlFilename, &res, basePath);
217
218     if (!XFILE::CFile::Exists(strSkinPath))
219     {
220       CLog::Log(LOGERROR, "Window_New: %s/%s - XML File '%s' for Window is missing, contact Developer '%s' of this AddOn", TranslateType(guiHelper->m_addon->Type()).c_str(), guiHelper->m_addon->Name().c_str(), strSkinPath.c_str(), guiHelper->m_addon->Author().c_str());
221       return NULL;
222     }
223   }
224   // window id's 14000 - 14100 are reserved for addons
225   // get first window id that is not in use
226   int id = WINDOW_ADDON_START;
227   // if window 14099 is in use it means addon can't create more windows
228   Lock();
229   if (g_windowManager.GetWindow(WINDOW_ADDON_END))
230   {
231     Unlock();
232     CLog::Log(LOGERROR, "Window_New: %s/%s - maximum number of windows reached", TranslateType(guiHelper->m_addon->Type()).c_str(), guiHelper->m_addon->Name().c_str());
233     return NULL;
234   }
235   while(id < WINDOW_ADDON_END && g_windowManager.GetWindow(id) != NULL) id++;
236   Unlock();
237
238   CGUIWindow *window;
239   if (!asDialog)
240     window = new CGUIAddonWindow(id, strSkinPath, guiHelper->m_addon);
241   else
242     window = new CGUIAddonWindowDialog(id, strSkinPath, guiHelper->m_addon);
243
244   Lock();
245   g_windowManager.Add(window);
246   Unlock();
247
248   window->SetCoordsRes(res);
249
250   return window;
251 }
252
253 void CAddonCallbacksGUI::Window_Delete(void *addonData, GUIHANDLE handle)
254 {
255   CAddonCallbacks* helper = (CAddonCallbacks*) addonData;
256   if (!helper)
257     return;
258
259   CAddonCallbacksGUI* guiHelper = helper->GetHelperGUI();
260
261   if (!handle)
262   {
263     CLog::Log(LOGERROR, "Window_Show: %s/%s - No Window", TranslateType(guiHelper->m_addon->Type()).c_str(), guiHelper->m_addon->Name().c_str());
264     return;
265   }
266
267   CGUIAddonWindow *pAddonWindow = (CGUIAddonWindow*)handle;
268   CGUIWindow      *pWindow      = (CGUIWindow*)g_windowManager.GetWindow(pAddonWindow->m_iWindowId);
269   if (!pWindow)
270     return;
271
272   Lock();
273   // first change to an existing window
274   if (g_windowManager.GetActiveWindow() == pAddonWindow->m_iWindowId && !g_application.m_bStop)
275   {
276     if(g_windowManager.GetWindow(pAddonWindow->m_iOldWindowId))
277       g_windowManager.ActivateWindow(pAddonWindow->m_iOldWindowId);
278     else // old window does not exist anymore, switch to home
279       g_windowManager.ActivateWindow(WINDOW_HOME);
280   }
281   // Free any window properties
282   pAddonWindow->ClearProperties();
283   // free the window's resources and unload it (free all guicontrols)
284   pAddonWindow->FreeResources(true);
285
286   g_windowManager.Remove(pAddonWindow->GetID());
287   delete pAddonWindow;
288   Unlock();
289 }
290
291 void CAddonCallbacksGUI::Window_SetCallbacks(void *addonData, GUIHANDLE handle, GUIHANDLE clienthandle, bool (*initCB)(GUIHANDLE), bool (*clickCB)(GUIHANDLE, int), bool (*focusCB)(GUIHANDLE, int), bool (*onActionCB)(GUIHANDLE handle, int))
292 {
293   CAddonCallbacks* helper = (CAddonCallbacks*) addonData;
294   if (!helper || !handle)
295     return;
296
297   CGUIAddonWindow *pAddonWindow = (CGUIAddonWindow*)handle;
298
299   Lock();
300   pAddonWindow->m_clientHandle  = clienthandle;
301   pAddonWindow->CBOnInit        = initCB;
302   pAddonWindow->CBOnClick       = clickCB;
303   pAddonWindow->CBOnFocus       = focusCB;
304   pAddonWindow->CBOnAction      = onActionCB;
305   Unlock();
306 }
307
308 bool CAddonCallbacksGUI::Window_Show(void *addonData, GUIHANDLE handle)
309 {
310   CAddonCallbacks* helper = (CAddonCallbacks*) addonData;
311   if (!helper)
312     return false;
313
314   CAddonCallbacksGUI* guiHelper = helper->GetHelperGUI();
315
316   if (!handle)
317   {
318     CLog::Log(LOGERROR, "Window_Show: %s/%s - No Window", TranslateType(guiHelper->m_addon->Type()).c_str(), guiHelper->m_addon->Name().c_str());
319     return false;
320   }
321
322   CGUIAddonWindow *pAddonWindow = (CGUIAddonWindow*)handle;
323   CGUIWindow      *pWindow      = (CGUIWindow*)g_windowManager.GetWindow(pAddonWindow->m_iWindowId);
324   if (!pWindow)
325     return false;
326
327   if (pAddonWindow->m_iOldWindowId != pAddonWindow->m_iWindowId && pAddonWindow->m_iWindowId != g_windowManager.GetActiveWindow())
328     pAddonWindow->m_iOldWindowId = g_windowManager.GetActiveWindow();
329
330   Lock();
331   if (pAddonWindow->IsDialog())
332     ((CGUIAddonWindowDialog*)pAddonWindow)->Show();
333   else
334     g_windowManager.ActivateWindow(pAddonWindow->m_iWindowId);
335   Unlock();
336
337   return true;
338 }
339
340 bool CAddonCallbacksGUI::Window_Close(void *addonData, GUIHANDLE handle)
341 {
342   CAddonCallbacks* helper = (CAddonCallbacks*) addonData;
343   if (!helper)
344     return false;
345
346   CAddonCallbacksGUI* guiHelper = helper->GetHelperGUI();
347
348   if (!handle)
349   {
350     CLog::Log(LOGERROR, "Window_Close: %s/%s - No Window", TranslateType(guiHelper->m_addon->Type()).c_str(), guiHelper->m_addon->Name().c_str());
351     return false;
352   }
353
354   CGUIAddonWindow *pAddonWindow = (CGUIAddonWindow*)handle;
355   CGUIWindow      *pWindow      = (CGUIWindow*)g_windowManager.GetWindow(pAddonWindow->m_iWindowId);
356   if (!pWindow)
357     return false;
358
359   pAddonWindow->m_bModal = false;
360   if (pAddonWindow->IsDialog())
361     ((CGUIAddonWindowDialog*)pAddonWindow)->PulseActionEvent();
362   else
363     ((CGUIAddonWindow*)pAddonWindow)->PulseActionEvent();
364
365   Lock();
366   // if it's a dialog, we have to close it a bit different
367   if (pAddonWindow->IsDialog())
368     ((CGUIAddonWindowDialog*)pAddonWindow)->Show(false);
369   else
370     g_windowManager.ActivateWindow(pAddonWindow->m_iOldWindowId);
371   pAddonWindow->m_iOldWindowId = 0;
372
373   Unlock();
374
375   return true;
376 }
377
378 bool CAddonCallbacksGUI::Window_DoModal(void *addonData, GUIHANDLE handle)
379 {
380   CAddonCallbacks* helper = (CAddonCallbacks*) addonData;
381   if (!helper)
382     return false;
383
384   CAddonCallbacksGUI* guiHelper = helper->GetHelperGUI();
385
386   if (!handle)
387   {
388     CLog::Log(LOGERROR, "Window_DoModal: %s/%s - No Window", TranslateType(guiHelper->m_addon->Type()).c_str(), guiHelper->m_addon->Name().c_str());
389     return false;
390   }
391
392   CGUIAddonWindow *pAddonWindow = (CGUIAddonWindow*)handle;
393   CGUIWindow      *pWindow      = (CGUIWindow*)g_windowManager.GetWindow(pAddonWindow->m_iWindowId);
394   if (!pWindow)
395     return false;
396
397   pAddonWindow->m_bModal = true;
398
399   if (pAddonWindow->m_iWindowId != g_windowManager.GetActiveWindow())
400     Window_Show(addonData, handle);
401
402   return true;
403 }
404
405 bool CAddonCallbacksGUI::Window_SetFocusId(void *addonData, GUIHANDLE handle, int iControlId)
406 {
407   CAddonCallbacks* helper = (CAddonCallbacks*) addonData;
408   if (!helper)
409     return false;
410
411   CAddonCallbacksGUI* guiHelper = helper->GetHelperGUI();
412
413   if (!handle)
414   {
415     CLog::Log(LOGERROR, "Window_SetFocusId: %s/%s - No Window", TranslateType(guiHelper->m_addon->Type()).c_str(), guiHelper->m_addon->Name().c_str());
416     return false;
417   }
418
419   CGUIAddonWindow *pAddonWindow = (CGUIAddonWindow*)handle;
420   CGUIWindow      *pWindow      = (CGUIWindow*)g_windowManager.GetWindow(pAddonWindow->m_iWindowId);
421   if (!pWindow)
422     return false;
423
424   if(!pWindow->GetControl(iControlId))
425   {
426     CLog::Log(LOGERROR, "Window_SetFocusId: %s/%s - Control does not exist in window", TranslateType(guiHelper->m_addon->Type()).c_str(), guiHelper->m_addon->Name().c_str());
427     return false;
428   }
429
430   Lock();
431   CGUIMessage msg = CGUIMessage(GUI_MSG_SETFOCUS, pAddonWindow->m_iWindowId, iControlId);
432   pWindow->OnMessage(msg);
433   Unlock();
434
435   return true;
436 }
437
438 int CAddonCallbacksGUI::Window_GetFocusId(void *addonData, GUIHANDLE handle)
439 {
440   int iControlId = -1;
441
442   CAddonCallbacks* helper = (CAddonCallbacks*) addonData;
443   if (!helper)
444     return iControlId;
445
446   CAddonCallbacksGUI* guiHelper = helper->GetHelperGUI();
447
448   if (!handle)
449   {
450     CLog::Log(LOGERROR, "Window_GetFocusId: %s/%s - No Window", TranslateType(guiHelper->m_addon->Type()).c_str(), guiHelper->m_addon->Name().c_str());
451     return iControlId;
452   }
453
454   CGUIAddonWindow *pAddonWindow = (CGUIAddonWindow*)handle;
455   CGUIWindow      *pWindow      = (CGUIWindow*)g_windowManager.GetWindow(pAddonWindow->m_iWindowId);
456   if (!pWindow)
457     return iControlId;
458
459   Lock();
460   iControlId = pWindow->GetFocusedControlID();
461   Unlock();
462
463   if (iControlId == -1)
464   {
465     CLog::Log(LOGERROR, "Window_GetFocusId: %s/%s - No control in this window has focus", TranslateType(guiHelper->m_addon->Type()).c_str(), guiHelper->m_addon->Name().c_str());
466     return iControlId;
467   }
468
469   return iControlId;
470 }
471
472 bool CAddonCallbacksGUI::Window_SetCoordinateResolution(void *addonData, GUIHANDLE handle, int res)
473 {
474   CAddonCallbacks* helper = (CAddonCallbacks*) addonData;
475   if (!helper)
476     return false;
477
478   CAddonCallbacksGUI* guiHelper = helper->GetHelperGUI();
479
480   if (!handle)
481   {
482     CLog::Log(LOGERROR, "SetCoordinateResolution: %s/%s - No Window", TranslateType(guiHelper->m_addon->Type()).c_str(), guiHelper->m_addon->Name().c_str());
483     return false;
484   }
485
486   if (res < RES_HDTV_1080i || res > RES_AUTORES)
487   {
488     CLog::Log(LOGERROR, "SetCoordinateResolution: %s/%s - Invalid resolution", TranslateType(guiHelper->m_addon->Type()).c_str(), guiHelper->m_addon->Name().c_str());
489     return false;
490   }
491
492   CGUIAddonWindow *pAddonWindow = (CGUIAddonWindow*)handle;
493   CGUIWindow      *pWindow      = (CGUIWindow*)g_windowManager.GetWindow(pAddonWindow->m_iWindowId);
494   if (!pWindow)
495     return false;
496
497   pWindow->SetCoordsRes((RESOLUTION)res);
498
499   return true;
500 }
501
502 void CAddonCallbacksGUI::Window_SetProperty(void *addonData, GUIHANDLE handle, const char *key, const char *value)
503 {
504   CAddonCallbacks* helper = (CAddonCallbacks*) addonData;
505   if (!helper)
506     return;
507
508   CAddonCallbacksGUI* guiHelper = helper->GetHelperGUI();
509
510   if (!handle)
511   {
512     CLog::Log(LOGERROR, "Window_SetProperty: %s/%s - No Window", TranslateType(guiHelper->m_addon->Type()).c_str(), guiHelper->m_addon->Name().c_str());
513     return;
514   }
515
516   CGUIAddonWindow *pAddonWindow = (CGUIAddonWindow*)handle;
517   CGUIWindow      *pWindow      = (CGUIWindow*)g_windowManager.GetWindow(pAddonWindow->m_iWindowId);
518   if (!pWindow)
519     return;
520
521   CStdString lowerKey = key;
522   StringUtils::ToLower(lowerKey);
523
524   Lock();
525   pWindow->SetProperty(lowerKey, value);
526   Unlock();
527 }
528
529 void CAddonCallbacksGUI::Window_SetPropertyInt(void *addonData, GUIHANDLE handle, const char *key, int value)
530 {
531   CAddonCallbacks* helper = (CAddonCallbacks*) addonData;
532   if (!helper)
533     return;
534
535   CAddonCallbacksGUI* guiHelper = helper->GetHelperGUI();
536
537   if (!handle)
538   {
539     CLog::Log(LOGERROR, "Window_SetPropertyInt: %s/%s - No Window", TranslateType(guiHelper->m_addon->Type()).c_str(), guiHelper->m_addon->Name().c_str());
540     return;
541   }
542
543   CGUIAddonWindow *pAddonWindow = (CGUIAddonWindow*)handle;
544   CGUIWindow      *pWindow      = (CGUIWindow*)g_windowManager.GetWindow(pAddonWindow->m_iWindowId);
545   if (!pWindow)
546     return;
547
548   CStdString lowerKey = key;
549   StringUtils::ToLower(lowerKey);
550
551   Lock();
552   pWindow->SetProperty(lowerKey, value);
553   Unlock();
554 }
555
556 void CAddonCallbacksGUI::Window_SetPropertyBool(void *addonData, GUIHANDLE handle, const char *key, bool value)
557 {
558   CAddonCallbacks* helper = (CAddonCallbacks*) addonData;
559   if (!helper)
560     return;
561
562   CAddonCallbacksGUI* guiHelper = helper->GetHelperGUI();
563
564   if (!handle)
565   {
566     CLog::Log(LOGERROR, "Window_SetPropertyBool: %s/%s - No Window", TranslateType(guiHelper->m_addon->Type()).c_str(), guiHelper->m_addon->Name().c_str());
567     return;
568   }
569
570   CGUIAddonWindow *pAddonWindow = (CGUIAddonWindow*)handle;
571   CGUIWindow      *pWindow      = (CGUIWindow*)g_windowManager.GetWindow(pAddonWindow->m_iWindowId);
572   if (!pWindow)
573     return;
574
575   CStdString lowerKey = key;
576   StringUtils::ToLower(lowerKey);
577
578   Lock();
579   pWindow->SetProperty(lowerKey, value);
580   Unlock();
581 }
582
583 void CAddonCallbacksGUI::Window_SetPropertyDouble(void *addonData, GUIHANDLE handle, const char *key, double value)
584 {
585   CAddonCallbacks* helper = (CAddonCallbacks*) addonData;
586   if (!helper)
587     return;
588
589   CAddonCallbacksGUI* guiHelper = helper->GetHelperGUI();
590
591   if (!handle)
592   {
593     CLog::Log(LOGERROR, "Window_SetPropertyDouble: %s/%s - No Window", TranslateType(guiHelper->m_addon->Type()).c_str(), guiHelper->m_addon->Name().c_str());
594     return;
595   }
596
597   CGUIAddonWindow *pAddonWindow = (CGUIAddonWindow*)handle;
598   CGUIWindow      *pWindow      = (CGUIWindow*)g_windowManager.GetWindow(pAddonWindow->m_iWindowId);
599   if (!pWindow)
600     return;
601
602   CStdString lowerKey = key;
603   StringUtils::ToLower(lowerKey);
604
605   Lock();
606   pWindow->SetProperty(lowerKey, value);
607   Unlock();
608 }
609
610 const char* CAddonCallbacksGUI::Window_GetProperty(void *addonData, GUIHANDLE handle, const char *key)
611 {
612   CAddonCallbacks* helper = (CAddonCallbacks*) addonData;
613   if (!helper)
614     return NULL;
615
616   CAddonCallbacksGUI* guiHelper = helper->GetHelperGUI();
617
618   if (!handle)
619   {
620     CLog::Log(LOGERROR, "Window_GetProperty: %s/%s - No Window", TranslateType(guiHelper->m_addon->Type()).c_str(), guiHelper->m_addon->Name().c_str());
621     return NULL;
622   }
623
624   CGUIAddonWindow *pAddonWindow = (CGUIAddonWindow*)handle;
625   CGUIWindow      *pWindow      = (CGUIWindow*)g_windowManager.GetWindow(pAddonWindow->m_iWindowId);
626   if (!pWindow)
627     return NULL;
628
629   CStdString lowerKey = key;
630   StringUtils::ToLower(lowerKey);
631
632   Lock();
633   string value = pWindow->GetProperty(lowerKey).asString();
634   Unlock();
635
636   return strdup(value.c_str());
637 }
638
639 int CAddonCallbacksGUI::Window_GetPropertyInt(void *addonData, GUIHANDLE handle, const char *key)
640 {
641   CAddonCallbacks* helper = (CAddonCallbacks*) addonData;
642   if (!helper)
643     return -1;
644
645   CAddonCallbacksGUI* guiHelper = helper->GetHelperGUI();
646
647   if (!handle)
648   {
649     CLog::Log(LOGERROR, "Window_GetPropertyInt: %s/%s - No Window", TranslateType(guiHelper->m_addon->Type()).c_str(), guiHelper->m_addon->Name().c_str());
650     return -1;
651   }
652
653   CGUIAddonWindow *pAddonWindow = (CGUIAddonWindow*)handle;
654   CGUIWindow      *pWindow      = (CGUIWindow*)g_windowManager.GetWindow(pAddonWindow->m_iWindowId);
655   if (!pWindow)
656     return -1;
657
658   CStdString lowerKey = key;
659   StringUtils::ToLower(lowerKey);
660
661   Lock();
662   int value = (int)pWindow->GetProperty(lowerKey).asInteger();
663   Unlock();
664
665   return value;
666 }
667
668 bool CAddonCallbacksGUI::Window_GetPropertyBool(void *addonData, GUIHANDLE handle, const char *key)
669 {
670   CAddonCallbacks* helper = (CAddonCallbacks*) addonData;
671   if (!helper)
672     return false;
673
674   CAddonCallbacksGUI* guiHelper = helper->GetHelperGUI();
675
676   if (!handle)
677   {
678     CLog::Log(LOGERROR, "Window_GetPropertyBool: %s/%s - No Window", TranslateType(guiHelper->m_addon->Type()).c_str(), guiHelper->m_addon->Name().c_str());
679     return false;
680   }
681
682   CGUIAddonWindow *pAddonWindow = (CGUIAddonWindow*)handle;
683   CGUIWindow      *pWindow      = (CGUIWindow*)g_windowManager.GetWindow(pAddonWindow->m_iWindowId);
684   if (!pWindow)
685     return false;
686   
687   CStdString lowerKey = key;
688   StringUtils::ToLower(lowerKey);
689
690   Lock();
691   bool value = pWindow->GetProperty(lowerKey).asBoolean();
692   Unlock();
693
694   return value;
695 }
696
697 double CAddonCallbacksGUI::Window_GetPropertyDouble(void *addonData, GUIHANDLE handle, const char *key)
698 {
699   CAddonCallbacks* helper = (CAddonCallbacks*) addonData;
700   if (!helper)
701     return 0.0;
702
703   CAddonCallbacksGUI* guiHelper = helper->GetHelperGUI();
704
705   if (!handle)
706   {
707     CLog::Log(LOGERROR, "Window_GetPropertyDouble: %s/%s - No Window", TranslateType(guiHelper->m_addon->Type()).c_str(), guiHelper->m_addon->Name().c_str());
708     return 0.0;
709   }
710
711   CGUIAddonWindow *pAddonWindow = (CGUIAddonWindow*)handle;
712   CGUIWindow      *pWindow      = (CGUIWindow*)g_windowManager.GetWindow(pAddonWindow->m_iWindowId);
713   if (!pWindow)
714     return 0.0;
715   
716   CStdString lowerKey = key;
717   StringUtils::ToLower(lowerKey);
718
719   Lock();
720   double value = pWindow->GetProperty(lowerKey).asDouble();
721   Unlock();
722
723   return value;
724 }
725
726 void CAddonCallbacksGUI::Window_ClearProperties(void *addonData, GUIHANDLE handle)
727 {
728   CAddonCallbacks* helper = (CAddonCallbacks*) addonData;
729   if (!helper)
730     return;
731
732   CAddonCallbacksGUI* guiHelper = helper->GetHelperGUI();
733
734   if (!handle)
735   {
736     CLog::Log(LOGERROR, "Window_ClearProperties: %s/%s - No Window", TranslateType(guiHelper->m_addon->Type()).c_str(), guiHelper->m_addon->Name().c_str());
737     return;
738   }
739
740   CGUIAddonWindow *pAddonWindow = (CGUIAddonWindow*)handle;
741   CGUIWindow      *pWindow      = (CGUIWindow*)g_windowManager.GetWindow(pAddonWindow->m_iWindowId);
742   if (!pWindow)
743     return;
744
745   Lock();
746   pWindow->ClearProperties();
747   Unlock();
748 }
749
750 int CAddonCallbacksGUI::Window_GetListSize(void *addonData, GUIHANDLE handle)
751 {
752   CAddonCallbacks* helper = (CAddonCallbacks*) addonData;
753   if (!helper || !handle)
754     return -1;
755
756   CGUIAddonWindow *pAddonWindow = (CGUIAddonWindow*)handle;
757
758   Lock();
759   int listSize = pAddonWindow->GetListSize();
760   Unlock();
761
762   return listSize;
763 }
764
765 void CAddonCallbacksGUI::Window_ClearList(void *addonData, GUIHANDLE handle)
766 {
767   CAddonCallbacks* helper = (CAddonCallbacks*) addonData;
768   if (!helper || !handle)
769     return;
770
771   CGUIAddonWindow *pAddonWindow = (CGUIAddonWindow*)handle;
772
773   Lock();
774   pAddonWindow->ClearList();
775   Unlock();
776
777   return;
778 }
779
780 GUIHANDLE CAddonCallbacksGUI::Window_AddItem(void *addonData, GUIHANDLE handle, GUIHANDLE item, int itemPosition)
781 {
782   CAddonCallbacks* helper = (CAddonCallbacks*) addonData;
783   if (!helper || !handle || !item)
784     return NULL;
785
786   CGUIAddonWindow *pAddonWindow = (CGUIAddonWindow*)handle;
787   CFileItemPtr pItem((CFileItem*)item);
788   Lock();
789   pAddonWindow->AddItem(pItem, itemPosition);
790   Unlock();
791
792   return item;
793 }
794
795 GUIHANDLE CAddonCallbacksGUI::Window_AddStringItem(void *addonData, GUIHANDLE handle, const char *itemName, int itemPosition)
796 {
797   CAddonCallbacks* helper = (CAddonCallbacks*) addonData;
798   if (!helper || !handle || !itemName)
799     return NULL;
800
801   CGUIAddonWindow *pAddonWindow = (CGUIAddonWindow*)handle;
802   CFileItemPtr item(new CFileItem(itemName));
803   Lock();
804   pAddonWindow->AddItem(item, itemPosition);
805   Unlock();
806
807   return item.get();
808 }
809
810 void CAddonCallbacksGUI::Window_RemoveItem(void *addonData, GUIHANDLE handle, int itemPosition)
811 {
812   CAddonCallbacks* helper = (CAddonCallbacks*) addonData;
813   if (!helper || !handle)
814     return;
815
816   CGUIAddonWindow *pAddonWindow = (CGUIAddonWindow*)handle;
817
818   Lock();
819   pAddonWindow->RemoveItem(itemPosition);
820   Unlock();
821
822   return;
823 }
824
825 GUIHANDLE CAddonCallbacksGUI::Window_GetListItem(void *addonData, GUIHANDLE handle, int listPos)
826 {
827   CAddonCallbacks* helper = (CAddonCallbacks*) addonData;
828   if (!helper || !handle)
829     return NULL;
830
831   CAddonCallbacksGUI* guiHelper = helper->GetHelperGUI();
832   CGUIAddonWindow *pAddonWindow = (CGUIAddonWindow*)handle;
833
834   Lock();
835   CFileItemPtr fi = pAddonWindow->GetListItem(listPos);
836   if (fi == NULL)
837   {
838     Unlock();
839     CLog::Log(LOGERROR, "Window_GetListItem: %s/%s - Index out of range", TranslateType(guiHelper->m_addon->Type()).c_str(), guiHelper->m_addon->Name().c_str());
840     return NULL;
841   }
842   Unlock();
843
844   return fi.get();
845 }
846
847 void CAddonCallbacksGUI::Window_SetCurrentListPosition(void *addonData, GUIHANDLE handle, int listPos)
848 {
849   CAddonCallbacks* helper = (CAddonCallbacks*) addonData;
850   if (!helper || !handle)
851     return;
852
853   CGUIAddonWindow *pAddonWindow = (CGUIAddonWindow*)handle;
854
855   Lock();
856   pAddonWindow->SetCurrentListPosition(listPos);
857   Unlock();
858
859   return;
860 }
861
862 int CAddonCallbacksGUI::Window_GetCurrentListPosition(void *addonData, GUIHANDLE handle)
863 {
864   CAddonCallbacks* helper = (CAddonCallbacks*) addonData;
865   if (!helper || !handle)
866     return -1;
867
868   CGUIAddonWindow *pAddonWindow = (CGUIAddonWindow*)handle;
869
870   Lock();
871   int listPos = pAddonWindow->GetCurrentListPosition();
872   Unlock();
873
874   return listPos;
875 }
876
877 GUIHANDLE CAddonCallbacksGUI::Window_GetControl_Spin(void *addonData, GUIHANDLE handle, int controlId)
878 {
879   CAddonCallbacks* helper = (CAddonCallbacks*) addonData;
880   if (!helper || !handle)
881     return NULL;
882
883   CGUIAddonWindow *pAddonWindow = (CGUIAddonWindow*)handle;
884   CGUIControl* pGUIControl = (CGUIControl*)pAddonWindow->GetControl(controlId);
885   if (pGUIControl && pGUIControl->GetControlType() != CGUIControl::GUICONTROL_SPINEX)
886     return NULL;
887
888   return pGUIControl;
889 }
890
891 GUIHANDLE CAddonCallbacksGUI::Window_GetControl_Button(void *addonData, GUIHANDLE handle, int controlId)
892 {
893   CAddonCallbacks* helper = (CAddonCallbacks*) addonData;
894   if (!helper || !handle)
895     return NULL;
896
897   CGUIAddonWindow *pAddonWindow = (CGUIAddonWindow*)handle;
898   CGUIControl* pGUIControl = (CGUIControl*)pAddonWindow->GetControl(controlId);
899   if (pGUIControl && pGUIControl->GetControlType() != CGUIControl::GUICONTROL_BUTTON)
900     return NULL;
901
902   return pGUIControl;
903 }
904
905 GUIHANDLE CAddonCallbacksGUI::Window_GetControl_RadioButton(void *addonData, GUIHANDLE handle, int controlId)
906 {
907   CAddonCallbacks* helper = (CAddonCallbacks*) addonData;
908   if (!helper || !handle)
909     return NULL;
910
911   CGUIAddonWindow *pAddonWindow = (CGUIAddonWindow*)handle;
912   CGUIControl* pGUIControl = (CGUIControl*)pAddonWindow->GetControl(controlId);
913   if (pGUIControl && pGUIControl->GetControlType() != CGUIControl::GUICONTROL_RADIO)
914     return NULL;
915
916   return pGUIControl;
917 }
918
919 GUIHANDLE CAddonCallbacksGUI::Window_GetControl_Edit(void *addonData, GUIHANDLE handle, int controlId)
920 {
921   CAddonCallbacks* helper = (CAddonCallbacks*) addonData;
922   if (!helper || !handle)
923     return NULL;
924
925   CGUIAddonWindow *pAddonWindow = (CGUIAddonWindow*)handle;
926   CGUIControl* pGUIControl = (CGUIControl*)pAddonWindow->GetControl(controlId);
927   if (pGUIControl && pGUIControl->GetControlType() != CGUIControl::GUICONTROL_EDIT)
928     return NULL;
929
930   return pGUIControl;
931 }
932
933 GUIHANDLE CAddonCallbacksGUI::Window_GetControl_Progress(void *addonData, GUIHANDLE handle, int controlId)
934 {
935   CAddonCallbacks* helper = (CAddonCallbacks*) addonData;
936   if (!helper || !handle)
937     return NULL;
938
939   CGUIAddonWindow *pAddonWindow = (CGUIAddonWindow*)handle;
940   CGUIControl* pGUIControl = (CGUIControl*)pAddonWindow->GetControl(controlId);
941   if (pGUIControl && pGUIControl->GetControlType() != CGUIControl::GUICONTROL_PROGRESS)
942     return NULL;
943
944   return pGUIControl;
945 }
946
947 GUIHANDLE CAddonCallbacksGUI::Window_GetControl_RenderAddon(void *addonData, GUIHANDLE handle, int controlId)
948 {
949   CAddonCallbacks* helper = (CAddonCallbacks*) addonData;
950   if (!helper || !handle)
951     return NULL;
952
953   CGUIAddonWindow *pAddonWindow = (CGUIAddonWindow*)handle;
954   CGUIControl* pGUIControl = (CGUIControl*)pAddonWindow->GetControl(controlId);
955   if (pGUIControl && pGUIControl->GetControlType() != CGUIControl::GUICONTROL_RENDERADDON)
956     return NULL;
957
958   CGUIAddonRenderingControl *pProxyControl;
959   pProxyControl = new CGUIAddonRenderingControl((CGUIRenderingControl*)pGUIControl);
960   return pProxyControl;
961 }
962
963 void CAddonCallbacksGUI::Window_SetControlLabel(void *addonData, GUIHANDLE handle, int controlId, const char *label)
964 {
965   CAddonCallbacks* helper = (CAddonCallbacks*) addonData;
966   if (!helper || !handle)
967     return;
968
969   CGUIAddonWindow *pAddonWindow = (CGUIAddonWindow*)handle;
970
971   CGUIMessage msg(GUI_MSG_LABEL_SET, pAddonWindow->m_iWindowId, controlId);
972   msg.SetLabel(label);
973   pAddonWindow->OnMessage(msg);
974 }
975
976 void CAddonCallbacksGUI::Window_MarkDirtyRegion(void *addonData, GUIHANDLE handle)
977 {
978   CAddonCallbacks* helper = (CAddonCallbacks*) addonData;
979   if (!helper || !handle)
980     return;
981
982   CGUIAddonWindow *pAddonWindow = (CGUIAddonWindow*)handle;
983
984   pAddonWindow->MarkDirtyRegion();
985 }
986
987 void CAddonCallbacksGUI::Control_Spin_SetVisible(void *addonData, GUIHANDLE spinhandle, bool yesNo)
988 {
989   CAddonCallbacks* helper = (CAddonCallbacks*) addonData;
990   if (!helper || !spinhandle)
991     return;
992
993   CGUISpinControlEx *pSpin = (CGUISpinControlEx*)spinhandle;
994   pSpin->SetVisible(yesNo);
995 }
996
997 void CAddonCallbacksGUI::Control_Spin_SetText(void *addonData, GUIHANDLE spinhandle, const char *label)
998 {
999   CAddonCallbacks* helper = (CAddonCallbacks*) addonData;
1000   if (!helper || !spinhandle)
1001     return;
1002
1003   CGUISpinControlEx *pSpin = (CGUISpinControlEx*)spinhandle;
1004   pSpin->SetText(label);
1005 }
1006
1007 void CAddonCallbacksGUI::Control_Spin_Clear(void *addonData, GUIHANDLE spinhandle)
1008 {
1009   CAddonCallbacks* helper = (CAddonCallbacks*) addonData;
1010   if (!helper || !spinhandle)
1011     return;
1012
1013   CGUISpinControlEx *pSpin = (CGUISpinControlEx*)spinhandle;
1014   pSpin->Clear();
1015 }
1016
1017 void CAddonCallbacksGUI::Control_Spin_AddLabel(void *addonData, GUIHANDLE spinhandle, const char *label, int iValue)
1018 {
1019   CAddonCallbacks* helper = (CAddonCallbacks*) addonData;
1020   if (!helper || !spinhandle)
1021     return;
1022
1023   CGUISpinControlEx *pSpin = (CGUISpinControlEx*)spinhandle;
1024   pSpin->AddLabel(label, iValue);
1025 }
1026
1027 int CAddonCallbacksGUI::Control_Spin_GetValue(void *addonData, GUIHANDLE spinhandle)
1028 {
1029   CAddonCallbacks* helper = (CAddonCallbacks*) addonData;
1030   if (!helper || !spinhandle)
1031     return -1;
1032
1033   CGUISpinControlEx *pSpin = (CGUISpinControlEx*)spinhandle;
1034   return pSpin->GetValue();
1035 }
1036
1037 void CAddonCallbacksGUI::Control_Spin_SetValue(void *addonData, GUIHANDLE spinhandle, int iValue)
1038 {
1039   CAddonCallbacks* helper = (CAddonCallbacks*) addonData;
1040   if (!helper || !spinhandle)
1041     return;
1042
1043   CGUISpinControlEx *pSpin = (CGUISpinControlEx*)spinhandle;
1044   pSpin->SetValue(iValue);
1045 }
1046
1047 void CAddonCallbacksGUI::Control_RadioButton_SetVisible(void *addonData, GUIHANDLE handle, bool yesNo)
1048 {
1049   CAddonCallbacks* helper = (CAddonCallbacks*) addonData;
1050   if (!helper || !handle)
1051     return;
1052
1053   CGUIRadioButtonControl *pRadioButton = (CGUIRadioButtonControl*)handle;
1054   pRadioButton->SetVisible(yesNo);
1055 }
1056
1057 void CAddonCallbacksGUI::Control_RadioButton_SetText(void *addonData, GUIHANDLE handle, const char *label)
1058 {
1059   CAddonCallbacks* helper = (CAddonCallbacks*) addonData;
1060   if (!helper || !handle)
1061     return;
1062
1063   CGUIRadioButtonControl *pRadioButton = (CGUIRadioButtonControl*)handle;
1064   pRadioButton->SetLabel(label);
1065 }
1066
1067 void CAddonCallbacksGUI::Control_RadioButton_SetSelected(void *addonData, GUIHANDLE handle, bool yesNo)
1068 {
1069   CAddonCallbacks* helper = (CAddonCallbacks*) addonData;
1070   if (!helper || !handle)
1071     return;
1072
1073   CGUIRadioButtonControl *pRadioButton = (CGUIRadioButtonControl*)handle;
1074   pRadioButton->SetSelected(yesNo);
1075 }
1076
1077 bool CAddonCallbacksGUI::Control_RadioButton_IsSelected(void *addonData, GUIHANDLE handle)
1078 {
1079   CAddonCallbacks* helper = (CAddonCallbacks*) addonData;
1080   if (!helper || !handle)
1081     return false;
1082
1083   CGUIRadioButtonControl *pRadioButton = (CGUIRadioButtonControl*)handle;
1084   return pRadioButton->IsSelected();
1085 }
1086
1087 void CAddonCallbacksGUI::Control_Progress_SetPercentage(void *addonData, GUIHANDLE handle, float fPercent)
1088 {
1089   CAddonCallbacks* helper = (CAddonCallbacks*) addonData;
1090   if (!helper || !handle)
1091     return;
1092
1093   CGUIProgressControl *pControl = (CGUIProgressControl*)handle;
1094   pControl->SetPercentage(fPercent);
1095 }
1096
1097 float CAddonCallbacksGUI::Control_Progress_GetPercentage(void *addonData, GUIHANDLE handle)
1098 {
1099   CAddonCallbacks* helper = (CAddonCallbacks*) addonData;
1100   if (!helper || !handle)
1101     return 0.0;
1102
1103   CGUIProgressControl *pControl = (CGUIProgressControl*)handle;
1104   return pControl->GetPercentage();
1105 }
1106
1107 void CAddonCallbacksGUI::Control_Progress_SetInfo(void *addonData, GUIHANDLE handle, int iInfo)
1108 {
1109   CAddonCallbacks* helper = (CAddonCallbacks*) addonData;
1110   if (!helper || !handle)
1111     return;
1112
1113   CGUIProgressControl *pControl = (CGUIProgressControl*)handle;
1114   pControl->SetInfo(iInfo);
1115 }
1116
1117 int CAddonCallbacksGUI::Control_Progress_GetInfo(void *addonData, GUIHANDLE handle)
1118 {
1119   CAddonCallbacks* helper = (CAddonCallbacks*) addonData;
1120   if (!helper || !handle)
1121     return -1;
1122
1123   CGUIProgressControl *pControl = (CGUIProgressControl*)handle;
1124   return pControl->GetInfo();
1125 }
1126
1127 const char* CAddonCallbacksGUI::Control_Progress_GetDescription(void *addonData, GUIHANDLE handle)
1128 {
1129   CAddonCallbacks* helper = (CAddonCallbacks*) addonData;
1130   if (!helper || !handle)
1131     return NULL;
1132
1133   CGUIProgressControl *pControl = (CGUIProgressControl*)handle;
1134   CStdString string = pControl->GetDescription();
1135
1136   char *buffer = (char*) malloc (string.length()+1);
1137   strcpy(buffer, string.c_str());
1138   return buffer;
1139 }
1140
1141 GUIHANDLE CAddonCallbacksGUI::ListItem_Create(void *addonData, const char *label, const char *label2, const char *iconImage, const char *thumbnailImage, const char *path)
1142 {
1143   CAddonCallbacks* helper = (CAddonCallbacks*) addonData;
1144   if (!helper)
1145     return NULL;
1146
1147   // create CFileItem
1148   CFileItem *pItem = new CFileItem();
1149   if (!pItem)
1150     return NULL;
1151
1152   if (label)
1153     pItem->SetLabel(label);
1154   if (label2)
1155     pItem->SetLabel2(label2);
1156   if (iconImage)
1157     pItem->SetIconImage(iconImage);
1158   if (thumbnailImage)
1159     pItem->SetArt("thumb", thumbnailImage);
1160   if (path)
1161     pItem->SetPath(path);
1162
1163   return pItem;
1164 }
1165
1166 const char* CAddonCallbacksGUI::ListItem_GetLabel(void *addonData, GUIHANDLE handle)
1167 {
1168   CAddonCallbacks* helper = (CAddonCallbacks*) addonData;
1169   if (!helper || !handle)
1170     return NULL;
1171
1172   CStdString string = ((CFileItem*)handle)->GetLabel();
1173   char *buffer = (char*) malloc (string.length()+1);
1174   strcpy(buffer, string.c_str());
1175   return buffer;
1176 }
1177
1178 void CAddonCallbacksGUI::ListItem_SetLabel(void *addonData, GUIHANDLE handle, const char *label)
1179 {
1180   CAddonCallbacks* helper = (CAddonCallbacks*) addonData;
1181   if (!helper || !handle)
1182     return;
1183
1184   ((CFileItem*)handle)->SetLabel(label);
1185 }
1186
1187 const char* CAddonCallbacksGUI::ListItem_GetLabel2(void *addonData, GUIHANDLE handle)
1188 {
1189   CAddonCallbacks* helper = (CAddonCallbacks*) addonData;
1190   if (!helper || !handle)
1191     return NULL;
1192
1193   CStdString string = ((CFileItem*)handle)->GetLabel2();
1194
1195   char *buffer = (char*) malloc (string.length()+1);
1196   strcpy(buffer, string.c_str());
1197   return buffer;
1198 }
1199
1200 void CAddonCallbacksGUI::ListItem_SetLabel2(void *addonData, GUIHANDLE handle, const char *label)
1201 {
1202   CAddonCallbacks* helper = (CAddonCallbacks*) addonData;
1203   if (!helper || !handle)
1204     return;
1205
1206   ((CFileItem*)handle)->SetLabel2(label);
1207 }
1208
1209 void CAddonCallbacksGUI::ListItem_SetIconImage(void *addonData, GUIHANDLE handle, const char *image)
1210 {
1211   CAddonCallbacks* helper = (CAddonCallbacks*) addonData;
1212   if (!helper || !handle)
1213     return;
1214
1215   ((CFileItem*)handle)->SetIconImage(image);
1216 }
1217
1218 void CAddonCallbacksGUI::ListItem_SetThumbnailImage(void *addonData, GUIHANDLE handle, const char *image)
1219 {
1220   CAddonCallbacks* helper = (CAddonCallbacks*) addonData;
1221   if (!helper || !handle)
1222     return;
1223
1224   ((CFileItem*)handle)->SetArt("thumb", image);
1225 }
1226
1227 void CAddonCallbacksGUI::ListItem_SetInfo(void *addonData, GUIHANDLE handle, const char *info)
1228 {
1229   CAddonCallbacks* helper = (CAddonCallbacks*) addonData;
1230   if (!helper || !handle)
1231     return;
1232
1233 }
1234
1235 void CAddonCallbacksGUI::ListItem_SetProperty(void *addonData, GUIHANDLE handle, const char *key, const char *value)
1236 {
1237   CAddonCallbacks* helper = (CAddonCallbacks*) addonData;
1238   if (!helper || !handle)
1239     return;
1240
1241   ((CFileItem*)handle)->SetProperty(key, value);
1242 }
1243
1244 const char* CAddonCallbacksGUI::ListItem_GetProperty(void *addonData, GUIHANDLE handle, const char *key)
1245 {
1246   CAddonCallbacks* helper = (CAddonCallbacks*) addonData;
1247   if (!helper || !handle)
1248     return NULL;
1249
1250   string string = ((CFileItem*)handle)->GetProperty(key).asString();
1251   char *buffer = (char*) malloc (string.length()+1);
1252   strcpy(buffer, string.c_str());
1253   return buffer;
1254 }
1255
1256 void CAddonCallbacksGUI::ListItem_SetPath(void *addonData, GUIHANDLE handle, const char *path)
1257 {
1258   CAddonCallbacks* helper = (CAddonCallbacks*) addonData;
1259   if (!helper || !handle)
1260     return;
1261
1262   ((CFileItem*)handle)->SetPath(path);
1263 }
1264
1265 void CAddonCallbacksGUI::RenderAddon_SetCallbacks(void *addonData, GUIHANDLE handle, GUIHANDLE clienthandle, bool (*createCB)(GUIHANDLE,int,int,int,int,void*), void (*renderCB)(GUIHANDLE), void (*stopCB)(GUIHANDLE), bool (*dirtyCB)(GUIHANDLE))
1266 {
1267   CAddonCallbacks* helper = (CAddonCallbacks*) addonData;
1268   if (!helper || !handle)
1269     return;
1270
1271   CGUIAddonRenderingControl *pAddonControl = (CGUIAddonRenderingControl*)handle;
1272
1273   Lock();
1274   pAddonControl->m_clientHandle  = clienthandle;
1275   pAddonControl->CBCreate        = createCB;
1276   pAddonControl->CBRender        = renderCB;
1277   pAddonControl->CBStop          = stopCB;
1278   pAddonControl->CBDirty         = dirtyCB;
1279   Unlock();
1280
1281   pAddonControl->m_pControl->InitCallback(pAddonControl);
1282 }
1283
1284 void CAddonCallbacksGUI::RenderAddon_Delete(void *addonData, GUIHANDLE handle)
1285 {
1286   CAddonCallbacks* helper = (CAddonCallbacks*) addonData;
1287   if (!helper || !handle)
1288     return;
1289
1290   CGUIAddonRenderingControl *pAddonControl = (CGUIAddonRenderingControl*)handle;
1291
1292   Lock();
1293   pAddonControl->Delete();
1294   Unlock();
1295 }
1296
1297
1298
1299 CGUIAddonWindow::CGUIAddonWindow(int id, CStdString strXML, CAddon* addon)
1300  : CGUIMediaWindow(id, strXML)
1301  , m_iWindowId(id)
1302  , m_iOldWindowId(0)
1303  , m_bModal(false)
1304  , m_bIsDialog(false)
1305  , m_actionEvent(true)
1306  , m_addon(addon)
1307 {
1308   m_loadType = LOAD_ON_GUI_INIT;
1309   CBOnInit        = NULL;
1310   CBOnFocus       = NULL;
1311   CBOnClick       = NULL;
1312   CBOnAction      = NULL;
1313 }
1314
1315 CGUIAddonWindow::~CGUIAddonWindow(void)
1316 {
1317 }
1318
1319 bool CGUIAddonWindow::OnAction(const CAction &action)
1320 {
1321   // Let addon decide whether it wants to hande action first
1322   if (CBOnAction && CBOnAction(m_clientHandle, action.GetID()))
1323     return true;
1324
1325   return CGUIWindow::OnAction(action);
1326 }
1327
1328 bool CGUIAddonWindow::OnMessage(CGUIMessage& message)
1329 {
1330   // TODO: We shouldn't be dropping down to CGUIWindow in any of this ideally.
1331   //       We have to make up our minds about what python should be doing and
1332   //       what this side of things should be doing
1333   switch (message.GetMessage())
1334   {
1335     case GUI_MSG_WINDOW_DEINIT:
1336     {
1337       return CGUIMediaWindow::OnMessage(message);
1338     }
1339     break;
1340
1341     case GUI_MSG_WINDOW_INIT:
1342     {
1343       CGUIMediaWindow::OnMessage(message);
1344       if (CBOnInit)
1345         CBOnInit(m_clientHandle);
1346
1347       return true;
1348     }
1349     break;
1350
1351     case GUI_MSG_SETFOCUS:
1352     {
1353       if (m_viewControl.HasControl(message.GetControlId()) && m_viewControl.GetCurrentControl() != (int)message.GetControlId())
1354       {
1355         m_viewControl.SetFocused();
1356         return true;
1357       }
1358       // check if our focused control is one of our category buttons
1359       int iControl = message.GetControlId();
1360       if (CBOnFocus)
1361       {
1362         CBOnFocus(m_clientHandle, iControl);
1363       }
1364     }
1365     break;
1366
1367     case GUI_MSG_FOCUSED:
1368     {
1369       if (HasID(message.GetSenderId()) && CBOnFocus)
1370       {
1371         CBOnFocus(m_clientHandle, message.GetControlId());
1372       }
1373     }
1374     break;
1375
1376     case GUI_MSG_CLICKED:
1377     {
1378       int iControl=message.GetSenderId();
1379       // Handle Sort/View internally. Scripters shouldn't use ID 2, 3 or 4.
1380       if (iControl == CONTROL_BTNSORTASC) // sort asc
1381       {
1382         CLog::Log(LOGINFO, "WindowXML: Internal asc/dsc button not implemented");
1383         /*if (m_guiState.get())
1384           m_guiState->SetNextSortOrder();
1385         UpdateFileList();*/
1386         return true;
1387       }
1388       else if (iControl == CONTROL_BTNSORTBY) // sort by
1389       {
1390         CLog::Log(LOGINFO, "WindowXML: Internal sort button not implemented");
1391         /*if (m_guiState.get())
1392           m_guiState->SetNextSortMethod();
1393         UpdateFileList();*/
1394         return true;
1395       }
1396
1397       if (CBOnClick && iControl && iControl != (int)this->GetID())
1398       {
1399         CGUIControl* controlClicked = (CGUIControl*)this->GetControl(iControl);
1400
1401         // The old python way used to check list AND SELECITEM method or if its a button, checkmark.
1402         // Its done this way for now to allow other controls without a python version like togglebutton to still raise a onAction event
1403         if (controlClicked) // Will get problems if we the id is not on the window and we try to do GetControlType on it. So check to make sure it exists
1404         {
1405           if ((controlClicked->IsContainer() && (message.GetParam1() == ACTION_SELECT_ITEM ||
1406                                                  message.GetParam1() == ACTION_MOUSE_LEFT_CLICK)) ||
1407                                                  !controlClicked->IsContainer())
1408           {
1409             if (CBOnClick(m_clientHandle, iControl))
1410               return true;
1411           }
1412           else if (controlClicked->IsContainer() && message.GetParam1() == ACTION_MOUSE_RIGHT_CLICK)
1413           {
1414 //            PyXBMCAction* inf = new PyXBMCAction;
1415 //            inf->pObject = Action_FromAction(CAction(ACTION_CONTEXT_MENU));
1416 //            inf->pCallbackWindow = pCallbackWindow;
1417 //
1418 //            // aquire lock?
1419 //            PyXBMC_AddPendingCall(Py_XBMC_Event_OnAction, inf);
1420 //            PulseActionEvent();
1421           }
1422         }
1423       }
1424     }
1425     break;
1426   }
1427
1428   return CGUIMediaWindow::OnMessage(message);
1429 }
1430
1431 void CGUIAddonWindow::AllocResources(bool forceLoad /*= FALSE */)
1432 {
1433   CStdString tmpDir = URIUtils::GetDirectory(GetProperty("xmlfile").asString());
1434   CStdString fallbackMediaPath;
1435   URIUtils::GetParentPath(tmpDir, fallbackMediaPath);
1436   URIUtils::RemoveSlashAtEnd(fallbackMediaPath);
1437   m_mediaDir = fallbackMediaPath;
1438
1439   //CLog::Log(LOGDEBUG, "CGUIPythonWindowXML::AllocResources called: %s", fallbackMediaPath.c_str());
1440   g_TextureManager.AddTexturePath(m_mediaDir);
1441   CGUIMediaWindow::AllocResources(forceLoad);
1442   g_TextureManager.RemoveTexturePath(m_mediaDir);
1443 }
1444
1445 void CGUIAddonWindow::FreeResources(bool forceUnLoad /*= FALSE */)
1446 {
1447   CGUIMediaWindow::FreeResources(forceUnLoad);
1448 }
1449
1450 void CGUIAddonWindow::Render()
1451 {
1452   g_TextureManager.AddTexturePath(m_mediaDir);
1453   CGUIMediaWindow::Render();
1454   g_TextureManager.RemoveTexturePath(m_mediaDir);
1455 }
1456
1457 void CGUIAddonWindow::Update()
1458 {
1459 }
1460
1461 void CGUIAddonWindow::AddItem(CFileItemPtr fileItem, int itemPosition)
1462 {
1463   if (itemPosition == -1 || itemPosition > m_vecItems->Size())
1464   {
1465     m_vecItems->Add(fileItem);
1466   }
1467   else if (itemPosition <  -1 &&  !(itemPosition-1 < m_vecItems->Size()))
1468   {
1469     m_vecItems->AddFront(fileItem,0);
1470   }
1471   else
1472   {
1473     m_vecItems->AddFront(fileItem,itemPosition);
1474   }
1475   m_viewControl.SetItems(*m_vecItems);
1476   UpdateButtons();
1477 }
1478
1479 void CGUIAddonWindow::RemoveItem(int itemPosition)
1480 {
1481   m_vecItems->Remove(itemPosition);
1482   m_viewControl.SetItems(*m_vecItems);
1483   UpdateButtons();
1484 }
1485
1486 int CGUIAddonWindow::GetCurrentListPosition()
1487 {
1488   return m_viewControl.GetSelectedItem();
1489 }
1490
1491 void CGUIAddonWindow::SetCurrentListPosition(int item)
1492 {
1493   m_viewControl.SetSelectedItem(item);
1494 }
1495
1496 int CGUIAddonWindow::GetListSize()
1497 {
1498   return m_vecItems->Size();
1499 }
1500
1501 CFileItemPtr CGUIAddonWindow::GetListItem(int position)
1502 {
1503   if (position < 0 || position >= m_vecItems->Size()) return CFileItemPtr();
1504   return m_vecItems->Get(position);
1505 }
1506
1507 void CGUIAddonWindow::ClearList()
1508 {
1509   ClearFileItems();
1510
1511   m_viewControl.SetItems(*m_vecItems);
1512   UpdateButtons();
1513 }
1514
1515 void CGUIAddonWindow::GetContextButtons(int itemNumber, CContextButtons &buttons)
1516 {
1517   // maybe on day we can make an easy way to do this context menu
1518   // with out this method overriding the MediaWindow version, it will display 'Add to Favorites'
1519 }
1520
1521 void CGUIAddonWindow::WaitForActionEvent(unsigned int timeout)
1522 {
1523   m_actionEvent.WaitMSec(timeout);
1524   m_actionEvent.Reset();
1525 }
1526
1527 void CGUIAddonWindow::PulseActionEvent()
1528 {
1529   m_actionEvent.Set();
1530 }
1531
1532 bool CGUIAddonWindow::OnClick(int iItem)
1533 {
1534   // Hook Over calling  CGUIMediaWindow::OnClick(iItem) results in it trying to PLAY the file item
1535   // which if its not media is BAD and 99 out of 100 times undesireable.
1536   return false;
1537 }
1538
1539 // SetupShares();
1540 /*
1541  CGUIMediaWindow::OnWindowLoaded() calls SetupShares() so override it
1542 and just call UpdateButtons();
1543 */
1544 void CGUIAddonWindow::SetupShares()
1545 {
1546   UpdateButtons();
1547 }
1548
1549
1550 CGUIAddonWindowDialog::CGUIAddonWindowDialog(int id, CStdString strXML, CAddon* addon)
1551 : CGUIAddonWindow(id,strXML,addon)
1552 {
1553   m_bRunning = false;
1554   m_bIsDialog = true;
1555 }
1556
1557 CGUIAddonWindowDialog::~CGUIAddonWindowDialog(void)
1558 {
1559 }
1560
1561 bool CGUIAddonWindowDialog::OnMessage(CGUIMessage &message)
1562 {
1563   if (message.GetMessage() == GUI_MSG_WINDOW_DEINIT)
1564   {
1565     CGUIWindow *pWindow = g_windowManager.GetWindow(g_windowManager.GetActiveWindow());
1566     if (pWindow)
1567       g_windowManager.ShowOverlay(pWindow->GetOverlayState());
1568     return CGUIWindow::OnMessage(message);
1569   }
1570   return CGUIAddonWindow::OnMessage(message);
1571 }
1572
1573 void CGUIAddonWindowDialog::Show(bool show /* = true */)
1574 {
1575   unsigned int iCount = g_graphicsContext.exit();
1576   ThreadMessage tMsg = {TMSG_GUI_ADDON_DIALOG, 1, show ? 1u : 0u};
1577   tMsg.lpVoid = this;
1578   CApplicationMessenger::Get().SendMessage(tMsg, true);
1579   g_graphicsContext.restore(iCount);
1580 }
1581
1582 void CGUIAddonWindowDialog::Show_Internal(bool show /* = true */)
1583 {
1584   if (show)
1585   {
1586     m_bModal = true;
1587     m_bRunning = true;
1588     g_windowManager.RouteToWindow(this);
1589
1590     // active this window...
1591     CGUIMessage msg(GUI_MSG_WINDOW_INIT, 0, 0, WINDOW_INVALID, m_iWindowId);
1592     OnMessage(msg);
1593
1594     while (m_bRunning && !g_application.m_bStop)
1595     {
1596       g_windowManager.ProcessRenderLoop();
1597     }
1598   }
1599   else // hide
1600   {
1601     m_bRunning = false;
1602
1603     CGUIMessage msg(GUI_MSG_WINDOW_DEINIT,0,0);
1604     OnMessage(msg);
1605
1606     g_windowManager.RemoveDialog(GetID());
1607   }
1608 }
1609
1610 CGUIAddonRenderingControl::CGUIAddonRenderingControl(CGUIRenderingControl *pControl)
1611 {
1612   m_pControl = pControl;
1613   m_refCount = 1;
1614 }
1615
1616 bool CGUIAddonRenderingControl::Create(int x, int y, int w, int h, void *device)
1617 {
1618   if (CBCreate)
1619   {
1620     if (CBCreate(m_clientHandle, x, y, w, h, device))
1621     {
1622       m_refCount++;
1623       return true;
1624     }
1625   }
1626   return false;
1627 }
1628
1629 void CGUIAddonRenderingControl::Render()
1630 {
1631   if (CBRender)
1632   {
1633     g_graphicsContext.BeginPaint();
1634     CBRender(m_clientHandle);
1635     g_graphicsContext.EndPaint();
1636   }
1637 }
1638
1639 void CGUIAddonRenderingControl::Stop()
1640 {
1641   if (CBStop)
1642   {
1643     CBStop(m_clientHandle);
1644   }
1645   m_refCount--;
1646   if (m_refCount <= 0)
1647     delete this;
1648 }
1649
1650 void CGUIAddonRenderingControl::Delete()
1651 {
1652   m_refCount--;
1653   if (m_refCount <= 0)
1654     delete this;
1655 }
1656
1657 bool CGUIAddonRenderingControl::IsDirty()
1658 {
1659   bool ret = true;
1660   if (CBDirty)
1661   {
1662     ret = CBDirty(m_clientHandle);
1663   }
1664   return ret;
1665 }
1666
1667 }; /* namespace ADDON */