Merge pull request #3198 from sraue/dvdread-config-fix
[vuplus_xbmc] / xbmc / interfaces / Builtins.cpp
1 /*
2  *      Copyright (C) 2005-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 "network/Network.h"
22 #include "system.h"
23 #include "utils/AlarmClock.h"
24 #include "utils/Screenshot.h"
25 #include "Application.h"
26 #include "ApplicationMessenger.h"
27 #include "Autorun.h"
28 #include "Builtins.h"
29 #include "input/ButtonTranslator.h"
30 #include "FileItem.h"
31 #include "addons/GUIDialogAddonSettings.h"
32 #include "dialogs/GUIDialogFileBrowser.h"
33 #include "guilib/GUIKeyboardFactory.h"
34 #include "guilib/Key.h"
35 #include "guilib/StereoscopicsManager.h"
36 #include "dialogs/GUIDialogKaiToast.h"
37 #include "dialogs/GUIDialogNumeric.h"
38 #include "dialogs/GUIDialogProgress.h"
39 #include "dialogs/GUIDialogYesNo.h"
40 #include "GUIUserMessages.h"
41 #include "windows/GUIWindowLoginScreen.h"
42 #include "video/windows/GUIWindowVideoBase.h"
43 #include "addons/GUIWindowAddonBrowser.h"
44 #include "addons/Addon.h" // for TranslateType, TranslateContent
45 #include "addons/AddonInstaller.h"
46 #include "addons/AddonManager.h"
47 #include "addons/PluginSource.h"
48 #include "interfaces/generic/ScriptInvocationManager.h"
49 #include "interfaces/AnnouncementManager.h"
50 #include "network/NetworkServices.h"
51 #include "utils/log.h"
52 #include "storage/MediaManager.h"
53 #include "utils/RssManager.h"
54 #include "utils/JSONVariantParser.h"
55 #include "PartyModeManager.h"
56 #include "profiles/ProfilesManager.h"
57 #include "settings/DisplaySettings.h"
58 #include "settings/Settings.h"
59 #include "settings/MediaSettings.h"
60 #include "settings/MediaSourceSettings.h"
61 #include "settings/SkinSettings.h"
62 #include "utils/StringUtils.h"
63 #include "utils/URIUtils.h"
64 #include "Util.h"
65 #include "URL.h"
66 #include "music/MusicDatabase.h"
67 #include "cores/IPlayer.h"
68
69 #include "filesystem/PluginDirectory.h"
70 #ifdef HAS_FILESYSTEM_RAR
71 #include "filesystem/RarManager.h"
72 #endif
73 #include "filesystem/ZipManager.h"
74
75 #include "guilib/GUIWindowManager.h"
76 #include "guilib/LocalizeStrings.h"
77
78 #ifdef HAS_LIRC
79 #include "input/linux/LIRC.h"
80 #endif
81 #ifdef HAS_IRSERVERSUITE
82
83   #include "input/windows/IRServerSuite.h"
84
85 #endif
86
87 #if defined(TARGET_DARWIN)
88 #include "filesystem/SpecialProtocol.h"
89 #include "osx/CocoaInterface.h"
90 #endif
91
92 #ifdef HAS_CDDA_RIPPER
93 #include "cdrip/CDDARipper.h"
94 #endif
95
96 #include <vector>
97 #include "settings/AdvancedSettings.h"
98 #include "settings/DisplaySettings.h"
99
100 using namespace std;
101 using namespace XFILE;
102 using namespace ADDON;
103
104 #ifdef HAS_DVD_DRIVE
105 using namespace MEDIA_DETECT;
106 #endif
107
108 typedef struct
109 {
110   const char* command;
111   bool needsParameters;
112   const char* description;
113 } BUILT_IN;
114
115 const BUILT_IN commands[] = {
116   { "Help",                       false,  "This help message" },
117   { "Reboot",                     false,  "Reboot the system" },
118   { "Restart",                    false,  "Restart the system (same as reboot)" },
119   { "ShutDown",                   false,  "Shutdown the system" },
120   { "Powerdown",                  false,  "Powerdown system" },
121   { "Quit",                       false,  "Quit XBMC" },
122   { "Hibernate",                  false,  "Hibernates the system" },
123   { "Suspend",                    false,  "Suspends the system" },
124   { "InhibitIdleShutdown",        false,  "Inhibit idle shutdown" },
125   { "AllowIdleShutdown",          false,  "Allow idle shutdown" },
126   { "ActivateScreensaver",        false,  "Activate Screensaver" },
127   { "RestartApp",                 false,  "Restart XBMC" },
128   { "Minimize",                   false,  "Minimize XBMC" },
129   { "Reset",                      false,  "Reset the system (same as reboot)" },
130   { "Mastermode",                 false,  "Control master mode" },
131   { "SetGUILanguage",             true,   "Set GUI Language" },
132   { "ActivateWindow",             true,   "Activate the specified window" },
133   { "ActivateWindowAndFocus",     true,   "Activate the specified window and sets focus to the specified id" },
134   { "ReplaceWindowAndFocus",      true,   "Replaces the current window with the new one and sets focus to the specified id" },
135   { "ReplaceWindow",              true,   "Replaces the current window with the new one" },
136   { "TakeScreenshot",             false,  "Takes a Screenshot" },
137   { "RunScript",                  true,   "Run the specified script" },
138   { "StopScript",                 true,   "Stop the script by ID or path, if running" },
139 #if defined(TARGET_DARWIN)
140   { "RunAppleScript",             true,   "Run the specified AppleScript command" },
141 #endif
142   { "RunPlugin",                  true,   "Run the specified plugin" },
143   { "RunAddon",                   true,   "Run the specified plugin/script" },
144   { "NotifyAll",                  true,   "Notify all connected clients" },
145   { "Extract",                    true,   "Extracts the specified archive" },
146   { "PlayMedia",                  true,   "Play the specified media file (or playlist)" },
147   { "SlideShow",                  true,   "Run a slideshow from the specified directory" },
148   { "RecursiveSlideShow",         true,   "Run a slideshow from the specified directory, including all subdirs" },
149   { "ReloadSkin",                 false,  "Reload XBMC's skin" },
150   { "UnloadSkin",                 false,  "Unload XBMC's skin" },
151   { "RefreshRSS",                 false,  "Reload RSS feeds from RSSFeeds.xml"},
152   { "PlayerControl",              true,   "Control the music or video player" },
153   { "Playlist.PlayOffset",        true,   "Start playing from a particular offset in the playlist" },
154   { "Playlist.Clear",             false,  "Clear the current playlist" },
155   { "EjectTray",                  false,  "Close or open the DVD tray" },
156   { "AlarmClock",                 true,   "Prompt for a length of time and start an alarm clock" },
157   { "CancelAlarm",                true,   "Cancels an alarm" },
158   { "Action",                     true,   "Executes an action for the active window (same as in keymap)" },
159   { "Notification",               true,   "Shows a notification on screen, specify header, then message, and optionally time in milliseconds and a icon." },
160   { "PlayDVD",                    false,  "Plays the inserted CD or DVD media from the DVD-ROM Drive!" },
161   { "RipCD",                      false,  "Rip the currently inserted audio CD"},
162   { "Skin.ToggleSetting",         true,   "Toggles a skin setting on or off" },
163   { "Skin.SetString",             true,   "Prompts and sets skin string" },
164   { "Skin.SetNumeric",            true,   "Prompts and sets numeric input" },
165   { "Skin.SetPath",               true,   "Prompts and sets a skin path" },
166   { "Skin.Theme",                 true,   "Control skin theme" },
167   { "Skin.SetImage",              true,   "Prompts and sets a skin image" },
168   { "Skin.SetLargeImage",         true,   "Prompts and sets a large skin images" },
169   { "Skin.SetFile",               true,   "Prompts and sets a file" },
170   { "Skin.SetAddon",              true,   "Prompts and set an addon" },
171   { "Skin.SetBool",               true,   "Sets a skin setting on" },
172   { "Skin.Reset",                 true,   "Resets a skin setting to default" },
173   { "Skin.ResetSettings",         false,  "Resets all skin settings" },
174   { "Mute",                       false,  "Mute the player" },
175   { "SetVolume",                  true,   "Set the current volume" },
176   { "Dialog.Close",               true,   "Close a dialog" },
177   { "System.LogOff",              false,  "Log off current user" },
178   { "System.Exec",                true,   "Execute shell commands" },
179   { "System.ExecWait",            true,   "Execute shell commands and freezes XBMC until shell is closed" },
180   { "Resolution",                 true,   "Change XBMC's Resolution" },
181   { "SetFocus",                   true,   "Change current focus to a different control id" },
182   { "UpdateLibrary",              true,   "Update the selected library (music or video)" },
183   { "CleanLibrary",               true,   "Clean the video/music library" },
184   { "ExportLibrary",              true,   "Export the video/music library" },
185   { "PageDown",                   true,   "Send a page down event to the pagecontrol with given id" },
186   { "PageUp",                     true,   "Send a page up event to the pagecontrol with given id" },
187   { "Container.Refresh",          false,  "Refresh current listing" },
188   { "Container.Update",           false,  "Update current listing. Send Container.Update(path,replace) to reset the path history" },
189   { "Container.NextViewMode",     false,  "Move to the next view type (and refresh the listing)" },
190   { "Container.PreviousViewMode", false,  "Move to the previous view type (and refresh the listing)" },
191   { "Container.SetViewMode",      true,   "Move to the view with the given id" },
192   { "Container.NextSortMethod",   false,  "Change to the next sort method" },
193   { "Container.PreviousSortMethod",false, "Change to the previous sort method" },
194   { "Container.SetSortMethod",    true,   "Change to the specified sort method" },
195   { "Container.SortDirection",    false,  "Toggle the sort direction" },
196   { "Control.Move",               true,   "Tells the specified control to 'move' to another entry specified by offset" },
197   { "Control.SetFocus",           true,   "Change current focus to a different control id" },
198   { "Control.Message",            true,   "Send a given message to a control within a given window" },
199   { "SendClick",                  true,   "Send a click message from the given control to the given window" },
200   { "LoadProfile",                true,   "Load the specified profile (note; if locks are active it won't work)" },
201   { "SetProperty",                true,   "Sets a window property for the current focused window/dialog (key,value)" },
202   { "ClearProperty",              true,   "Clears a window property for the current focused window/dialog (key,value)" },
203   { "PlayWith",                   true,   "Play the selected item with the specified core" },
204   { "WakeOnLan",                  true,   "Sends the wake-up packet to the broadcast address for the specified MAC address" },
205   { "Addon.Default.OpenSettings", true,   "Open a settings dialog for the default addon of the given type" },
206   { "Addon.Default.Set",          true,   "Open a select dialog to allow choosing the default addon of the given type" },
207   { "Addon.OpenSettings",         true,   "Open a settings dialog for the addon of the given id" },
208   { "UpdateAddonRepos",           false,  "Check add-on repositories for updates" },
209   { "UpdateLocalAddons",          false,  "Check for local add-on changes" },
210   { "ToggleDPMS",                 false,  "Toggle DPMS mode manually"},
211   { "CECToggleState",             false,  "Toggle state of playing device via a CEC peripheral"},
212   { "CECActivateSource",          false,  "Wake up playing device via a CEC peripheral"},
213   { "CECStandby",                 false,  "Put playing device on standby via a CEC peripheral"},
214   { "Weather.Refresh",            false,  "Force weather data refresh"},
215   { "Weather.LocationNext",       false,  "Switch to next weather location"},
216   { "Weather.LocationPrevious",   false,  "Switch to previous weather location"},
217   { "Weather.LocationSet",        true,   "Switch to given weather location (parameter can be 1-3)"},
218 #if defined(HAS_LIRC) || defined(HAS_IRSERVERSUITE)
219   { "LIRC.Stop",                  false,  "Removes XBMC as LIRC client" },
220   { "LIRC.Start",                 false,  "Adds XBMC as LIRC client" },
221   { "LIRC.Send",                  true,   "Sends a command to LIRC" },
222 #endif
223   { "VideoLibrary.Search",        false,  "Brings up a search dialog which will search the library" },
224   { "ToggleDebug",                false,  "Enables/disables debug mode" },
225   { "StartPVRManager",            false,  "(Re)Starts the PVR manager" },
226   { "StopPVRManager",             false,  "Stops the PVR manager" },
227 #if defined(TARGET_ANDROID)
228   { "StartAndroidActivity",       true,   "Launch an Android native app with the given package name.  Optional parms (in order): intent, dataType, dataURI." },
229 #endif
230   { "SetStereoMode",              true,   "Changes the stereo mode of the GUI. Params can be: toggle, next, previous, select, tomono or any of the supported stereomodes (off, split_vertical, split_horizontal, row_interleaved, hardware_based, anaglyph_cyan_red, anaglyph_green_magenta, monoscopic)" }
231 };
232
233 bool CBuiltins::HasCommand(const CStdString& execString)
234 {
235   CStdString function;
236   vector<CStdString> parameters;
237   CUtil::SplitExecFunction(execString, function, parameters);
238   for (unsigned int i = 0; i < sizeof(commands)/sizeof(BUILT_IN); i++)
239   {
240     if (StringUtils::EqualsNoCase(function, commands[i].command) && (!commands[i].needsParameters || parameters.size()))
241       return true;
242   }
243   return false;
244 }
245
246 void CBuiltins::GetHelp(CStdString &help)
247 {
248   help.clear();
249   for (unsigned int i = 0; i < sizeof(commands)/sizeof(BUILT_IN); i++)
250   {
251     help += commands[i].command;
252     help += "\t";
253     help += commands[i].description;
254     help += "\n";
255   }
256 }
257
258 int CBuiltins::Execute(const CStdString& execString)
259 {
260   // Get the text after the "XBMC."
261   CStdString execute;
262   vector<CStdString> params;
263   CUtil::SplitExecFunction(execString, execute, params);
264   StringUtils::ToLower(execute);
265   CStdString parameter = params.size() ? params[0] : "";
266   CStdString strParameterCaseIntact = parameter;
267
268   if (execute.Equals("reboot") || execute.Equals("restart") || execute.Equals("reset"))  //Will reboot the system
269   {
270     CApplicationMessenger::Get().Restart();
271   }
272   else if (execute.Equals("shutdown"))
273   {
274     CApplicationMessenger::Get().Shutdown();
275   }
276   else if (execute.Equals("powerdown"))
277   {
278     CApplicationMessenger::Get().Powerdown();
279   }
280   else if (execute.Equals("restartapp"))
281   {
282     CApplicationMessenger::Get().RestartApp();
283   }
284   else if (execute.Equals("hibernate"))
285   {
286     CApplicationMessenger::Get().Hibernate();
287   }
288   else if (execute.Equals("suspend"))
289   {
290     CApplicationMessenger::Get().Suspend();
291   }
292   else if (execute.Equals("quit"))
293   {
294     CApplicationMessenger::Get().Quit();
295   }
296   else if (execute.Equals("inhibitidleshutdown"))
297   {
298     bool inhibit = (params.size() == 1 && params[0].Equals("true"));
299     CApplicationMessenger::Get().InhibitIdleShutdown(inhibit);
300   }
301   else if (execute.Equals("activatescreensaver"))
302   {
303     CApplicationMessenger::Get().ActivateScreensaver();
304   }
305   else if (execute.Equals("minimize"))
306   {
307     CApplicationMessenger::Get().Minimize();
308   }
309   else if (execute.Equals("loadprofile"))
310   {
311     int index = CProfilesManager::Get().GetProfileIndex(parameter);
312     bool prompt = (params.size() == 2 && params[1].Equals("prompt"));
313     bool bCanceled;
314     if (index >= 0
315         && (CProfilesManager::Get().GetMasterProfile().getLockMode() == LOCK_MODE_EVERYONE
316             || g_passwordManager.IsProfileLockUnlocked(index,bCanceled,prompt)))
317     {
318       CApplicationMessenger::Get().LoadProfile(index);
319     }
320   }
321   else if (execute.Equals("mastermode"))
322   {
323     if (g_passwordManager.bMasterUser)
324     {
325       g_passwordManager.bMasterUser = false;
326       g_passwordManager.LockSources(true);
327       CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Warning, g_localizeStrings.Get(20052),g_localizeStrings.Get(20053));
328     }
329     else if (g_passwordManager.IsMasterLockUnlocked(true))
330     {
331       g_passwordManager.LockSources(false);
332       g_passwordManager.bMasterUser = true;
333       CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Warning, g_localizeStrings.Get(20052),g_localizeStrings.Get(20054));
334     }
335
336     CUtil::DeleteVideoDatabaseDirectoryCache();
337     CGUIMessage msg(GUI_MSG_NOTIFY_ALL, 0, 0, GUI_MSG_UPDATE);
338     g_windowManager.SendMessage(msg);
339   }
340   else if (execute.Equals("setguilanguage"))
341   {
342     if (params.size())
343     {
344       CApplicationMessenger::Get().SetGUILanguage(params[0]);
345     }
346   }
347   else if (execute.Equals("takescreenshot"))
348   {
349     if (params.size())
350     {
351       // get the parameters
352       CStdString strSaveToPath = params[0];
353       bool sync = false;
354       if (params.size() >= 2)
355         sync = params[1].Equals("sync");
356
357       if (!strSaveToPath.empty())
358       {
359         if (CDirectory::Exists(strSaveToPath))
360         {
361           CStdString file = CUtil::GetNextFilename(URIUtils::AddFileToFolder(strSaveToPath, "screenshot%03d.png"), 999);
362
363           if (!file.empty())
364           {
365             CScreenShot::TakeScreenshot(file, sync);
366           }
367           else
368           {
369             CLog::Log(LOGWARNING, "Too many screen shots or invalid folder %s", strSaveToPath.c_str());
370           }
371         }
372         else
373           CScreenShot::TakeScreenshot(strSaveToPath, sync);
374       }
375     }
376     else
377       CScreenShot::TakeScreenshot();
378   }
379   else if (execute.Equals("activatewindow") || execute.Equals("replacewindow"))
380   {
381     // get the parameters
382     CStdString strWindow;
383     if (params.size())
384     {
385       strWindow = params[0];
386       params.erase(params.begin());
387     }
388
389     // confirm the window destination is valid prior to switching
390     int iWindow = CButtonTranslator::TranslateWindow(strWindow);
391     if (iWindow != WINDOW_INVALID)
392     {
393       // disable the screensaver
394       g_application.WakeUpScreenSaverAndDPMS();
395       g_windowManager.ActivateWindow(iWindow, params, !execute.Equals("activatewindow"));
396     }
397     else
398     {
399       CLog::Log(LOGERROR, "Activate/ReplaceWindow called with invalid destination window: %s", strWindow.c_str());
400       return false;
401     }
402   }
403   else if ((execute.Equals("setfocus") || execute.Equals("control.setfocus")) && params.size())
404   {
405     int controlID = atol(params[0].c_str());
406     int subItem = (params.size() > 1) ? atol(params[1].c_str())+1 : 0;
407     CGUIMessage msg(GUI_MSG_SETFOCUS, g_windowManager.GetFocusedWindow(), controlID, subItem);
408     g_windowManager.SendMessage(msg);
409   }
410   else if ((execute.Equals("activatewindowandfocus") || execute.Equals("replacewindowandfocus")) && params.size())
411   {
412     CStdString strWindow = params[0];
413
414     // confirm the window destination is valid prior to switching
415     int iWindow = CButtonTranslator::TranslateWindow(strWindow);
416     if (iWindow != WINDOW_INVALID)
417     {
418       // disable the screensaver
419       g_application.WakeUpScreenSaverAndDPMS();
420       vector<CStdString> dummy;
421       g_windowManager.ActivateWindow(iWindow, dummy, !execute.Equals("activatewindowandfocus"));
422
423       unsigned int iPtr = 1;
424       while (params.size() > iPtr + 1)
425       {
426         CGUIMessage msg(GUI_MSG_SETFOCUS, g_windowManager.GetFocusedWindow(),
427             atol(params[iPtr].c_str()),
428             (params.size() >= iPtr + 2) ? atol(params[iPtr + 1].c_str())+1 : 0);
429         g_windowManager.SendMessage(msg);
430         iPtr += 2;
431       }
432     }
433     else
434     {
435       CLog::Log(LOGERROR, "Replace/ActivateWindowAndFocus called with invalid destination window: %s", strWindow.c_str());
436       return false;
437     }
438   }
439   else if (execute.Equals("runscript") && params.size())
440   {
441 #if defined(TARGET_DARWIN_OSX)
442     if (URIUtils::HasExtension(strParameterCaseIntact, ".applescript|.scpt"))
443     {
444       CStdString osxPath = CSpecialProtocol::TranslatePath(strParameterCaseIntact);
445       Cocoa_DoAppleScriptFile(osxPath.c_str());
446     }
447     else
448 #endif
449     {
450       vector<string> argv;
451       for (vector<CStdString>::const_iterator param = params.begin(); param != params.end(); ++param)
452         argv.push_back(*param);
453
454       vector<CStdString> path;
455       //split the path up to find the filename
456       StringUtils::SplitString(params[0],"\\",path);
457       if (path.size())
458         argv[0] = path[path.size() - 1];
459
460       AddonPtr script;
461       CStdString scriptpath(params[0]);
462       if (CAddonMgr::Get().GetAddon(params[0], script))
463         scriptpath = script->LibPath();
464
465       CScriptInvocationManager::Get().Execute(scriptpath, script, argv);
466     }
467   }
468 #if defined(TARGET_DARWIN_OSX)
469   else if (execute.Equals("runapplescript"))
470   {
471     Cocoa_DoAppleScript(strParameterCaseIntact.c_str());
472   }
473 #endif
474   else if (execute.Equals("stopscript"))
475   {
476     CStdString scriptpath(params[0]);
477
478     // Test to see if the param is an addon ID
479     AddonPtr script;
480     if (CAddonMgr::Get().GetAddon(params[0], script))
481       scriptpath = script->LibPath();
482
483     CScriptInvocationManager::Get().Stop(scriptpath);
484   }
485   else if (execute.Equals("system.exec"))
486   {
487     CApplicationMessenger::Get().Minimize();
488     CApplicationMessenger::Get().ExecOS(parameter, false);
489   }
490   else if (execute.Equals("system.execwait"))
491   {
492     CApplicationMessenger::Get().Minimize();
493     CApplicationMessenger::Get().ExecOS(parameter, true);
494   }
495   else if (execute.Equals("resolution"))
496   {
497     RESOLUTION res = RES_PAL_4x3;
498     if (parameter.Equals("pal")) res = RES_PAL_4x3;
499     else if (parameter.Equals("pal16x9")) res = RES_PAL_16x9;
500     else if (parameter.Equals("ntsc")) res = RES_NTSC_4x3;
501     else if (parameter.Equals("ntsc16x9")) res = RES_NTSC_16x9;
502     else if (parameter.Equals("720p")) res = RES_HDTV_720p;
503     else if (parameter.Equals("720pSBS")) res = RES_HDTV_720pSBS;
504     else if (parameter.Equals("720pTB")) res = RES_HDTV_720pTB;
505     else if (parameter.Equals("1080pSBS")) res = RES_HDTV_1080pSBS;
506     else if (parameter.Equals("1080pTB")) res = RES_HDTV_1080pTB;
507     else if (parameter.Equals("1080i")) res = RES_HDTV_1080i;
508     if (g_graphicsContext.IsValidResolution(res))
509     {
510       CDisplaySettings::Get().SetCurrentResolution(res, true);
511       g_application.ReloadSkin();
512     }
513   }
514   else if (execute.Equals("extract") && params.size())
515   {
516     // Detects if file is zip or rar then extracts
517     CStdString strDestDirect;
518     if (params.size() < 2)
519       strDestDirect = URIUtils::GetDirectory(params[0]);
520     else
521       strDestDirect = params[1];
522
523     URIUtils::AddSlashAtEnd(strDestDirect);
524
525     if (URIUtils::IsZIP(params[0]))
526       g_ZipManager.ExtractArchive(params[0],strDestDirect);
527 #ifdef HAS_FILESYSTEM_RAR
528     else if (URIUtils::IsRAR(params[0]))
529       g_RarManager.ExtractArchive(params[0],strDestDirect);
530 #endif
531     else
532       CLog::Log(LOGERROR, "XBMC.Extract, No archive given");
533   }
534   else if (execute.Equals("runplugin"))
535   {
536     if (params.size())
537     {
538       CFileItem item(params[0]);
539       if (!item.m_bIsFolder)
540       {
541         item.SetPath(params[0]);
542         CPluginDirectory::RunScriptWithParams(item.GetPath());
543       }
544     }
545     else
546     {
547       CLog::Log(LOGERROR, "XBMC.RunPlugin called with no arguments.");
548     }
549   }
550   else if (execute.Equals("runaddon"))
551   {
552     if (params.size())
553     {
554       AddonPtr addon;
555       if (CAddonMgr::Get().GetAddon(params[0],addon) && addon)
556       {
557         PluginPtr plugin = boost::dynamic_pointer_cast<CPluginSource>(addon);
558         CStdString cmd;
559         if (plugin && addon->Type() == ADDON_PLUGIN)
560         {
561           CStdString addonid = params[0];
562           CStdString urlParameters;
563           CStdStringArray parameters;
564           if (params.size() == 2 &&
565              (StringUtils::StartsWith(params[1], "/") || StringUtils::StartsWith(params[1], "?")))
566             urlParameters = params[1];
567           else if (params.size() > 1)
568           {
569             parameters.insert(parameters.begin(), params.begin() + 1, params.end());
570             urlParameters = "?" + StringUtils::JoinString(parameters, "&");
571           }
572
573           if (plugin->Provides(CPluginSource::VIDEO))
574             cmd = StringUtils::Format("ActivateWindow(Video,plugin://%s%s,return)", addonid.c_str(), urlParameters.c_str());
575           else if (plugin->Provides(CPluginSource::AUDIO))
576             cmd = StringUtils::Format("ActivateWindow(Music,plugin://%s%s,return)", addonid.c_str(), urlParameters.c_str());
577           else if (plugin->Provides(CPluginSource::EXECUTABLE))
578             cmd = StringUtils::Format("ActivateWindow(Programs,plugin://%s%s,return)", addonid.c_str(), urlParameters.c_str());
579           else if (plugin->Provides(CPluginSource::IMAGE))
580             cmd = StringUtils::Format("ActivateWindow(Pictures,plugin://%s%s,return)", addonid.c_str(), urlParameters.c_str());
581           else
582             // Pass the script name (params[0]) and all the parameters
583             // (params[1] ... params[x]) separated by a comma to RunPlugin
584             cmd = StringUtils::Format("RunPlugin(%s)", StringUtils::JoinString(params, ",").c_str());
585         }
586         else if (addon->Type() >= ADDON_SCRIPT && addon->Type() <= ADDON_SCRIPT_LYRICS)
587           // Pass the script name (params[0]) and all the parameters
588           // (params[1] ... params[x]) separated by a comma to RunScript
589           cmd = StringUtils::Format("RunScript(%s)", StringUtils::JoinString(params, ",").c_str());
590
591         return Execute(cmd);
592       }
593     }
594     else
595     {
596       CLog::Log(LOGERROR, "XBMC.RunAddon called with no arguments.");
597     }
598   }
599   else if (execute.Equals("notifyall"))
600   {
601     if (params.size() > 1)
602     {
603       CVariant data;
604       if (params.size() > 2)
605         data = CJSONVariantParser::Parse((const unsigned char *)params[2].c_str(), params[2].size());
606
607       ANNOUNCEMENT::CAnnouncementManager::Announce(ANNOUNCEMENT::Other, params[0], params[1], data);
608     }
609     else
610       CLog::Log(LOGERROR, "XBMC.NotifyAll needs two parameters");
611   }
612   else if (execute.Equals("playmedia"))
613   {
614     if (!params.size())
615     {
616       CLog::Log(LOGERROR, "XBMC.PlayMedia called with empty parameter");
617       return -3;
618     }
619
620     CFileItem item(params[0], false);
621     if (URIUtils::HasSlashAtEnd(params[0]))
622       item.m_bIsFolder = true;
623
624     // restore to previous window if needed
625     if( g_windowManager.GetActiveWindow() == WINDOW_SLIDESHOW ||
626         g_windowManager.GetActiveWindow() == WINDOW_FULLSCREEN_VIDEO ||
627         g_windowManager.GetActiveWindow() == WINDOW_VISUALISATION )
628         g_windowManager.PreviousWindow();
629
630     // reset screensaver
631     g_application.ResetScreenSaver();
632     g_application.WakeUpScreenSaverAndDPMS();
633
634     // ask if we need to check guisettings to resume
635     bool askToResume = true;
636     int playOffset = 0;
637     for (unsigned int i = 1 ; i < params.size() ; i++)
638     {
639       if (params[i].Equals("isdir"))
640         item.m_bIsFolder = true;
641       else if (params[i].Equals("1")) // set fullscreen or windowed
642         CMediaSettings::Get().SetVideoStartWindowed(true);
643       else if (params[i].Equals("resume"))
644       {
645         // force the item to resume (if applicable) (see CApplication::PlayMedia)
646         item.m_lStartOffset = STARTOFFSET_RESUME;
647         askToResume = false;
648       }
649       else if (params[i].Equals("noresume"))
650       {
651         // force the item to start at the beginning (m_lStartOffset is initialized to 0)
652         askToResume = false;
653       }
654       else if (StringUtils::StartsWithNoCase(params[i], "playoffset=")) {
655         playOffset = atoi(params[i].substr(11).c_str()) - 1;
656         item.SetProperty("playlist_starting_track", playOffset);
657       }
658     }
659
660     if (!item.m_bIsFolder && item.IsPlugin())
661       item.SetProperty("IsPlayable", true);
662
663     if ( askToResume == true )
664     {
665       if ( CGUIWindowVideoBase::ShowResumeMenu(item) == false )
666         return false;
667     }
668     if (item.m_bIsFolder)
669     {
670       CFileItemList items;
671       CStdString extensions = g_advancedSettings.m_videoExtensions + "|" + g_advancedSettings.m_musicExtensions;
672       CDirectory::GetDirectory(item.GetPath(),items,extensions);
673       
674       bool containsMusic = false, containsVideo = false;
675       for (int i = 0; i < items.Size(); i++)
676       {
677         bool isVideo = items[i]->IsVideo();
678         containsMusic |= !isVideo;
679         containsVideo |= isVideo;
680         
681         if (containsMusic && containsVideo)
682           break;
683       }
684       
685       int playlist = containsVideo? PLAYLIST_VIDEO : PLAYLIST_MUSIC;;
686       if (containsMusic && containsVideo) //mixed content found in the folder
687       {
688         for (int i = items.Size() - 1; i >= 0; i--) //remove music entries
689         {
690           if (!items[i]->IsVideo())
691             items.Remove(i);
692         }
693       }
694       
695       g_playlistPlayer.ClearPlaylist(playlist);
696       g_playlistPlayer.Add(playlist, items);
697       g_playlistPlayer.SetCurrentPlaylist(playlist);
698       g_playlistPlayer.Play(playOffset);
699     }
700     else
701     {
702       int playlist = item.IsAudio() ? PLAYLIST_MUSIC : PLAYLIST_VIDEO;
703       g_playlistPlayer.ClearPlaylist(playlist);
704       g_playlistPlayer.SetCurrentPlaylist(playlist);
705
706       // play media
707       if (!g_application.PlayMedia(item, playlist))
708       {
709         CLog::Log(LOGERROR, "XBMC.PlayMedia could not play media: %s", params[0].c_str());
710         return false;
711       }
712     }
713   }
714   else if (execute.Equals("showPicture"))
715   {
716     if (!params.size())
717     {
718       CLog::Log(LOGERROR, "XBMC.ShowPicture called with empty parameter");
719       return -2;
720     }
721     CGUIMessage msg(GUI_MSG_SHOW_PICTURE, 0, 0);
722     msg.SetStringParam(params[0]);
723     CGUIWindow *pWindow = g_windowManager.GetWindow(WINDOW_SLIDESHOW);
724     if (pWindow) pWindow->OnMessage(msg);
725   }
726   else if (execute.Equals("slideShow") || execute.Equals("recursiveslideShow"))
727   {
728     if (!params.size())
729     {
730       CLog::Log(LOGERROR, "XBMC.SlideShow called with empty parameter");
731       return -2;
732     }
733     std::string beginSlidePath;
734     // leave RecursiveSlideShow command as-is
735     unsigned int flags = 0;
736     if (execute.Equals("RecursiveSlideShow"))
737       flags |= 1;
738
739     // SlideShow(dir[,recursive][,[not]random][,pause][,beginslide="/path/to/start/slide.jpg"])
740     // the beginslide value need be escaped (for '"' or '\' in it, by backslash)
741     // and then quoted, or not. See CUtil::SplitParams()
742     else
743     {
744       for (unsigned int i = 1 ; i < params.size() ; i++)
745       {
746         if (params[i].Equals("recursive"))
747           flags |= 1;
748         else if (params[i].Equals("random")) // set fullscreen or windowed
749           flags |= 2;
750         else if (params[i].Equals("notrandom"))
751           flags |= 4;
752         else if (params[i].Equals("pause"))
753           flags |= 8;
754         else if (StringUtils::StartsWithNoCase(params[i], "beginslide="))
755           beginSlidePath = params[i].substr(11);
756       }
757     }
758
759     CGUIMessage msg(GUI_MSG_START_SLIDESHOW, 0, 0, flags);
760     vector<CStdString> strParams;
761     strParams.push_back(params[0]);
762     strParams.push_back(beginSlidePath);
763     msg.SetStringParams(strParams);
764     CGUIWindow *pWindow = g_windowManager.GetWindow(WINDOW_SLIDESHOW);
765     if (pWindow) pWindow->OnMessage(msg);
766   }
767   else if (execute.Equals("reloadskin"))
768   {
769     //  Reload the skin
770     g_application.ReloadSkin(!params.empty() && StringUtils::EqualsNoCase(params[0], "confirm"));
771   }
772   else if (execute.Equals("unloadskin"))
773   {
774     g_application.UnloadSkin(true); // we're reloading the skin after this
775   }
776   else if (execute.Equals("refreshrss"))
777   {
778     CRssManager::Get().Reload();
779   }
780   else if (execute.Equals("playercontrol"))
781   {
782     g_application.ResetScreenSaver();
783     g_application.WakeUpScreenSaverAndDPMS();
784     if (!params.size())
785     {
786       CLog::Log(LOGERROR, "XBMC.PlayerControl called with empty parameter");
787       return -3;
788     }
789     if (parameter.Equals("play"))
790     { // play/pause
791       // either resume playing, or pause
792       if (g_application.m_pPlayer->IsPlaying())
793       {
794         if (g_application.m_pPlayer->GetPlaySpeed() != 1)
795           g_application.m_pPlayer->SetPlaySpeed(1, g_application.IsMutedInternal());
796         else
797           g_application.m_pPlayer->Pause();
798       }
799     }
800     else if (parameter.Equals("stop"))
801     {
802       g_application.StopPlaying();
803     }
804     else if (parameter.Equals("rewind") || parameter.Equals("forward"))
805     {
806       if (g_application.m_pPlayer->IsPlaying() && !g_application.m_pPlayer->IsPaused())
807       {
808         int iPlaySpeed = g_application.m_pPlayer->GetPlaySpeed();
809         if (parameter.Equals("rewind") && iPlaySpeed == 1) // Enables Rewinding
810           iPlaySpeed *= -2;
811         else if (parameter.Equals("rewind") && iPlaySpeed > 1) //goes down a notch if you're FFing
812           iPlaySpeed /= 2;
813         else if (parameter.Equals("forward") && iPlaySpeed < 1) //goes up a notch if you're RWing
814         {
815           iPlaySpeed /= 2;
816           if (iPlaySpeed == -1) iPlaySpeed = 1;
817         }
818         else
819           iPlaySpeed *= 2;
820
821         if (iPlaySpeed > 32 || iPlaySpeed < -32)
822           iPlaySpeed = 1;
823
824         g_application.m_pPlayer->SetPlaySpeed(iPlaySpeed, g_application.IsMutedInternal());
825       }
826     }
827     else if (parameter.Equals("next"))
828     {
829       g_application.OnAction(CAction(ACTION_NEXT_ITEM));
830     }
831     else if (parameter.Equals("previous"))
832     {
833       g_application.OnAction(CAction(ACTION_PREV_ITEM));
834     }
835     else if (parameter.Equals("bigskipbackward"))
836     {
837       if (g_application.m_pPlayer->IsPlaying())
838         g_application.m_pPlayer->Seek(false, true);
839     }
840     else if (parameter.Equals("bigskipforward"))
841     {
842       if (g_application.m_pPlayer->IsPlaying())
843         g_application.m_pPlayer->Seek(true, true);
844     }
845     else if (parameter.Equals("smallskipbackward"))
846     {
847       if (g_application.m_pPlayer->IsPlaying())
848         g_application.m_pPlayer->Seek(false, false);
849     }
850     else if (parameter.Equals("smallskipforward"))
851     {
852       if (g_application.m_pPlayer->IsPlaying())
853         g_application.m_pPlayer->Seek(true, false);
854     }
855     else if (StringUtils::StartsWithNoCase(parameter, "seekpercentage"))
856     {
857       CStdString offset = "";
858       if (parameter.size() == 14)
859         CLog::Log(LOGERROR,"PlayerControl(seekpercentage(n)) called with no argument");
860       else if (parameter.size() < 17) // arg must be at least "(N)"
861         CLog::Log(LOGERROR,"PlayerControl(seekpercentage(n)) called with invalid argument: \"%s\"", parameter.substr(14).c_str());
862       else
863       {
864         // Don't bother checking the argument: an invalid arg will do seek(0)
865         offset = parameter.substr(15);
866         StringUtils::TrimRight(offset, ")");
867         float offsetpercent = (float) atof(offset.c_str());
868         if (offsetpercent < 0 || offsetpercent > 100)
869           CLog::Log(LOGERROR,"PlayerControl(seekpercentage(n)) argument, %f, must be 0-100", offsetpercent);
870         else if (g_application.m_pPlayer->IsPlaying())
871           g_application.SeekPercentage(offsetpercent);
872       }
873     }
874     else if( parameter.Equals("showvideomenu") )
875     {
876       if( g_application.m_pPlayer->IsPlaying() )
877         g_application.m_pPlayer->OnAction(CAction(ACTION_SHOW_VIDEOMENU));
878     }
879     else if( parameter.Equals("record") )
880     {
881       if( g_application.m_pPlayer->IsPlaying() && g_application.m_pPlayer->CanRecord())
882         g_application.m_pPlayer->Record(!g_application.m_pPlayer->IsRecording());
883     }
884     else if (StringUtils::StartsWithNoCase(parameter, "partymode"))
885     {
886       CStdString strXspPath = "";
887       //empty param=music, "music"=music, "video"=video, else xsp path
888       PartyModeContext context = PARTYMODECONTEXT_MUSIC;
889       if (parameter.size() > 9)
890       {
891         if (parameter.size() == 16 && StringUtils::EndsWithNoCase(parameter, "video)"))
892           context = PARTYMODECONTEXT_VIDEO;
893         else if (parameter.size() != 16 || !StringUtils::EndsWithNoCase(parameter, "music)"))
894         {
895           strXspPath = parameter.substr(10);
896           StringUtils::TrimRight(strXspPath, ")");
897           context = PARTYMODECONTEXT_UNKNOWN;
898         }
899       }
900       if (g_partyModeManager.IsEnabled())
901         g_partyModeManager.Disable();
902       else
903         g_partyModeManager.Enable(context, strXspPath);
904     }
905     else if (parameter.Equals("random")    ||
906              parameter.Equals("randomoff") ||
907              parameter.Equals("randomon"))
908     {
909       // get current playlist
910       int iPlaylist = g_playlistPlayer.GetCurrentPlaylist();
911
912       // reverse the current setting
913       bool shuffled = g_playlistPlayer.IsShuffled(iPlaylist);
914       if ((shuffled && parameter.Equals("randomon")) || (!shuffled && parameter.Equals("randomoff")))
915         return 0;
916
917       // check to see if we should notify the user
918       bool notify = (params.size() == 2 && params[1].Equals("notify"));
919       g_playlistPlayer.SetShuffle(iPlaylist, !shuffled, notify);
920
921       // save settings for now playing windows
922       switch (iPlaylist)
923       {
924       case PLAYLIST_MUSIC:
925         CMediaSettings::Get().SetMusicPlaylistShuffled(g_playlistPlayer.IsShuffled(iPlaylist));
926         CSettings::Get().Save();
927         break;
928       case PLAYLIST_VIDEO:
929         CMediaSettings::Get().SetVideoPlaylistShuffled(g_playlistPlayer.IsShuffled(iPlaylist));
930         CSettings::Get().Save();
931       }
932
933       // send message
934       CGUIMessage msg(GUI_MSG_PLAYLISTPLAYER_RANDOM, 0, 0, iPlaylist, g_playlistPlayer.IsShuffled(iPlaylist));
935       g_windowManager.SendThreadMessage(msg);
936
937     }
938     else if (StringUtils::StartsWithNoCase(parameter, "repeat"))
939     {
940       // get current playlist
941       int iPlaylist = g_playlistPlayer.GetCurrentPlaylist();
942       PLAYLIST::REPEAT_STATE previous_state = g_playlistPlayer.GetRepeat(iPlaylist);
943
944       PLAYLIST::REPEAT_STATE state;
945       if (parameter.Equals("repeatall"))
946         state = PLAYLIST::REPEAT_ALL;
947       else if (parameter.Equals("repeatone"))
948         state = PLAYLIST::REPEAT_ONE;
949       else if (parameter.Equals("repeatoff"))
950         state = PLAYLIST::REPEAT_NONE;
951       else if (previous_state == PLAYLIST::REPEAT_NONE)
952         state = PLAYLIST::REPEAT_ALL;
953       else if (previous_state == PLAYLIST::REPEAT_ALL)
954         state = PLAYLIST::REPEAT_ONE;
955       else
956         state = PLAYLIST::REPEAT_NONE;
957
958       if (state == previous_state)
959         return 0;
960
961       // check to see if we should notify the user
962       bool notify = (params.size() == 2 && params[1].Equals("notify"));
963       g_playlistPlayer.SetRepeat(iPlaylist, state, notify);
964
965       // save settings for now playing windows
966       switch (iPlaylist)
967       {
968       case PLAYLIST_MUSIC:
969         CMediaSettings::Get().SetMusicPlaylistRepeat(state == PLAYLIST::REPEAT_ALL);
970         CSettings::Get().Save();
971         break;
972       case PLAYLIST_VIDEO:
973         CMediaSettings::Get().SetVideoPlaylistRepeat(state == PLAYLIST::REPEAT_ALL);
974         CSettings::Get().Save();
975       }
976
977       // send messages so now playing window can get updated
978       CGUIMessage msg(GUI_MSG_PLAYLISTPLAYER_REPEAT, 0, 0, iPlaylist, (int)state);
979       g_windowManager.SendThreadMessage(msg);
980     }
981   }
982   else if (execute.Equals("playwith"))
983   {
984     g_application.m_eForcedNextPlayer = CPlayerCoreFactory::Get().GetPlayerCore(parameter);
985     g_application.OnAction(CAction(ACTION_PLAYER_PLAY));
986   }
987   else if (execute.Equals("mute"))
988   {
989     g_application.ToggleMute();
990   }
991   else if (execute.Equals("setvolume"))
992   {
993     float oldVolume = g_application.GetVolume();
994     float volume = (float)strtod(parameter.c_str(), NULL);
995
996     g_application.SetVolume(volume);
997     if(oldVolume != volume)
998     {
999       if(params.size() > 1 && params[1].Equals("showVolumeBar"))    
1000       {
1001         CApplicationMessenger::Get().ShowVolumeBar(oldVolume < volume);  
1002       }
1003     }
1004   }
1005   else if (execute.Equals("playlist.playoffset"))
1006   {
1007     // playlist.playoffset(offset)
1008     // playlist.playoffset(music|video,offset)
1009     CStdString strPos = parameter;
1010     if (params.size() > 1)
1011     {
1012       // ignore any other parameters if present
1013       CStdString strPlaylist = params[0];
1014       strPos = params[1];
1015
1016       int iPlaylist = PLAYLIST_NONE;
1017       if (strPlaylist.Equals("music"))
1018         iPlaylist = PLAYLIST_MUSIC;
1019       else if (strPlaylist.Equals("video"))
1020         iPlaylist = PLAYLIST_VIDEO;
1021
1022       // unknown playlist
1023       if (iPlaylist == PLAYLIST_NONE)
1024       {
1025         CLog::Log(LOGERROR,"Playlist.PlayOffset called with unknown playlist: %s", strPlaylist.c_str());
1026         return false;
1027       }
1028
1029       // user wants to play the 'other' playlist
1030       if (iPlaylist != g_playlistPlayer.GetCurrentPlaylist())
1031       {
1032         g_application.StopPlaying();
1033         g_playlistPlayer.Reset();
1034         g_playlistPlayer.SetCurrentPlaylist(iPlaylist);
1035       }
1036     }
1037     // play the desired offset
1038     int pos = atol(strPos.c_str());
1039     // playlist is already playing
1040     if (g_application.m_pPlayer->IsPlaying())
1041       g_playlistPlayer.PlayNext(pos);
1042     // we start playing the 'other' playlist so we need to use play to initialize the player state
1043     else
1044       g_playlistPlayer.Play(pos);
1045   }
1046   else if (execute.Equals("playlist.clear"))
1047   {
1048     g_playlistPlayer.Clear();
1049   }
1050 #ifdef HAS_DVD_DRIVE
1051   else if (execute.Equals("ejecttray"))
1052   {
1053     g_mediaManager.ToggleTray();
1054   }
1055 #endif
1056   else if( execute.Equals("alarmclock") && params.size() > 1 )
1057   {
1058     // format is alarmclock(name,command[,seconds,true]);
1059     float seconds = 0;
1060     if (params.size() > 2)
1061     {
1062       if (params[2].find(':') == std::string::npos)
1063         seconds = static_cast<float>(atoi(params[2].c_str())*60);
1064       else
1065         seconds = (float)StringUtils::TimeStringToSeconds(params[2]);
1066     }
1067     else
1068     { // check if shutdown is specified in particular, and get the time for it
1069       CStdString strHeading;
1070       if (StringUtils::EqualsNoCase(parameter, "shutdowntimer"))
1071         strHeading = g_localizeStrings.Get(20145);
1072       else
1073         strHeading = g_localizeStrings.Get(13209);
1074       CStdString strTime;
1075       if( CGUIDialogNumeric::ShowAndGetNumber(strTime, strHeading) )
1076         seconds = static_cast<float>(atoi(strTime.c_str())*60);
1077       else
1078         return false;
1079     }
1080     bool silent = false;
1081     bool loop = false;
1082     for (unsigned int i = 3; i < params.size() ; i++)
1083     {
1084       // check "true" for backward comp
1085       if (StringUtils::EqualsNoCase(params[i], "true") || StringUtils::EqualsNoCase(params[i], "silent"))
1086         silent = true;
1087       else if (StringUtils::EqualsNoCase(params[i], "loop"))
1088         loop = true;
1089     }
1090
1091     if( g_alarmClock.IsRunning() )
1092       g_alarmClock.Stop(params[0],silent);
1093     // no negative times not allowed, loop must have a positive time
1094     if (seconds < 0 || (seconds == 0 && loop))
1095       return false;
1096     g_alarmClock.Start(params[0], seconds, params[1], silent, loop);
1097   }
1098   else if (execute.Equals("notification"))
1099   {
1100     if (params.size() < 2)
1101       return -1;
1102     if (params.size() == 4)
1103       CGUIDialogKaiToast::QueueNotification(params[3],params[0],params[1],atoi(params[2].c_str()));
1104     else if (params.size() == 3)
1105       CGUIDialogKaiToast::QueueNotification("",params[0],params[1],atoi(params[2].c_str()));
1106     else
1107       CGUIDialogKaiToast::QueueNotification(params[0],params[1]);
1108   }
1109   else if (execute.Equals("cancelalarm"))
1110   {
1111     bool silent = false;
1112     if (params.size() > 1 && StringUtils::EqualsNoCase(params[1], "true"))
1113       silent = true;
1114     g_alarmClock.Stop(params[0],silent);
1115   }
1116   else if (execute.Equals("playdvd"))
1117   {
1118 #ifdef HAS_DVD_DRIVE
1119     bool restart = false;
1120     if (params.size() > 0 && StringUtils::EqualsNoCase(params[0], "restart"))
1121       restart = true;
1122     CAutorun::PlayDisc(g_mediaManager.GetDiscPath(), true, restart);
1123 #endif
1124   }
1125   else if (execute.Equals("ripcd"))
1126   {
1127 #ifdef HAS_CDDA_RIPPER
1128     CCDDARipper::GetInstance().RipCD();
1129 #endif
1130   }
1131   else if (execute.Equals("skin.togglesetting"))
1132   {
1133     int setting = CSkinSettings::Get().TranslateBool(parameter);
1134     CSkinSettings::Get().SetBool(setting, !CSkinSettings::Get().GetBool(setting));
1135     CSettings::Get().Save();
1136   }
1137   else if (execute.Equals("skin.setbool") && params.size())
1138   {
1139     if (params.size() > 1)
1140     {
1141       int string = CSkinSettings::Get().TranslateBool(params[0]);
1142       CSkinSettings::Get().SetBool(string, StringUtils::EqualsNoCase(params[1], "true"));
1143       CSettings::Get().Save();
1144       return 0;
1145     }
1146     // default is to set it to true
1147     int setting = CSkinSettings::Get().TranslateBool(params[0]);
1148     CSkinSettings::Get().SetBool(setting, true);
1149     CSettings::Get().Save();
1150   }
1151   else if (execute.Equals("skin.reset"))
1152   {
1153     CSkinSettings::Get().Reset(parameter);
1154     CSettings::Get().Save();
1155   }
1156   else if (execute.Equals("skin.resetsettings"))
1157   {
1158     CSkinSettings::Get().Reset();
1159     CSettings::Get().Save();
1160   }
1161   else if (execute.Equals("skin.theme"))
1162   {
1163     // enumerate themes
1164     vector<CStdString> vecTheme;
1165     CUtil::GetSkinThemes(vecTheme);
1166
1167     int iTheme = -1;
1168
1169     // find current theme
1170     if (!StringUtils::EqualsNoCase(CSettings::Get().GetString("lookandfeel.skintheme"), "SKINDEFAULT"))
1171     {
1172       for (unsigned int i=0;i<vecTheme.size();++i)
1173       {
1174         CStdString strTmpTheme(CSettings::Get().GetString("lookandfeel.skintheme"));
1175         URIUtils::RemoveExtension(strTmpTheme);
1176         if (vecTheme[i].Equals(strTmpTheme))
1177         {
1178           iTheme=i;
1179           break;
1180         }
1181       }
1182     }
1183
1184     int iParam = atoi(parameter.c_str());
1185     if (iParam == 0 || iParam == 1)
1186       iTheme++;
1187     else if (iParam == -1)
1188       iTheme--;
1189     if (iTheme > (int)vecTheme.size()-1)
1190       iTheme = -1;
1191     if (iTheme < -1)
1192       iTheme = vecTheme.size()-1;
1193
1194     CStdString strSkinTheme = "SKINDEFAULT";
1195     if (iTheme != -1 && iTheme < (int)vecTheme.size())
1196       strSkinTheme = vecTheme[iTheme];
1197
1198     CSettings::Get().SetString("lookandfeel.skintheme", strSkinTheme);
1199     // also set the default color theme
1200     CStdString colorTheme(URIUtils::ReplaceExtension(strSkinTheme, ".xml"));
1201     if (colorTheme.Equals("Textures.xml"))
1202       colorTheme = "defaults.xml";
1203     CSettings::Get().SetString("lookandfeel.skincolors", colorTheme);
1204     g_application.ReloadSkin();
1205   }
1206   else if (execute.Equals("skin.setstring") || execute.Equals("skin.setimage") || execute.Equals("skin.setfile") ||
1207            execute.Equals("skin.setpath") || execute.Equals("skin.setnumeric") || execute.Equals("skin.setlargeimage"))
1208   {
1209     // break the parameter up if necessary
1210     int string = 0;
1211     if (params.size() > 1)
1212     {
1213       string = CSkinSettings::Get().TranslateString(params[0]);
1214       if (execute.Equals("skin.setstring"))
1215       {
1216         CSkinSettings::Get().SetString(string, params[1]);
1217         CSettings::Get().Save();
1218         return 0;
1219       }
1220     }
1221     else
1222       string = CSkinSettings::Get().TranslateString(params[0]);
1223     CStdString value = CSkinSettings::Get().GetString(string);
1224     VECSOURCES localShares;
1225     g_mediaManager.GetLocalDrives(localShares);
1226     if (execute.Equals("skin.setstring"))
1227     {
1228       if (CGUIKeyboardFactory::ShowAndGetInput(value, g_localizeStrings.Get(1029), true))
1229         CSkinSettings::Get().SetString(string, value);
1230     }
1231     else if (execute.Equals("skin.setnumeric"))
1232     {
1233       if (CGUIDialogNumeric::ShowAndGetNumber(value, g_localizeStrings.Get(611)))
1234         CSkinSettings::Get().SetString(string, value);
1235     }
1236     else if (execute.Equals("skin.setimage"))
1237     {
1238       if (CGUIDialogFileBrowser::ShowAndGetImage(localShares, g_localizeStrings.Get(1030), value))
1239         CSkinSettings::Get().SetString(string, value);
1240     }
1241     else if (execute.Equals("skin.setlargeimage"))
1242     {
1243       VECSOURCES *shares = CMediaSourceSettings::Get().GetSources("pictures");
1244       if (!shares) shares = &localShares;
1245       if (CGUIDialogFileBrowser::ShowAndGetImage(*shares, g_localizeStrings.Get(1030), value))
1246         CSkinSettings::Get().SetString(string, value);
1247     }
1248     else if (execute.Equals("skin.setfile"))
1249     {
1250       // Note. can only browse one addon type from here
1251       // if browsing for addons, required param[1] is addontype string, with optional param[2]
1252       // as contenttype string see IAddon.h & ADDON::TranslateXX
1253       CStdString strMask = (params.size() > 1) ? params[1] : "";
1254       StringUtils::ToLower(strMask);
1255       ADDON::TYPE type;
1256       if ((type = TranslateType(strMask)) != ADDON_UNKNOWN)
1257       {
1258         CURL url;
1259         url.SetProtocol("addons");
1260         url.SetHostName("enabled");
1261         url.SetFileName(strMask+"/");
1262         localShares.clear();
1263         CStdString content = (params.size() > 2) ? params[2] : "";
1264         StringUtils::ToLower(content);
1265         url.SetPassword(content);
1266         CStdString strMask;
1267         if (type == ADDON_SCRIPT)
1268           strMask = ".py";
1269         CStdString replace;
1270         if (CGUIDialogFileBrowser::ShowAndGetFile(url.Get(), strMask, TranslateType(type, true), replace, true, true, true))
1271         {
1272           if (StringUtils::StartsWithNoCase(replace, "addons://"))
1273             CSkinSettings::Get().SetString(string, URIUtils::GetFileName(replace));
1274           else
1275             CSkinSettings::Get().SetString(string, replace);
1276         }
1277       }
1278       else 
1279       {
1280         if (params.size() > 2)
1281         {
1282           value = params[2];
1283           URIUtils::AddSlashAtEnd(value);
1284           bool bIsSource;
1285           if (CUtil::GetMatchingSource(value,localShares,bIsSource) < 0) // path is outside shares - add it as a separate one
1286           {
1287             CMediaSource share;
1288             share.strName = g_localizeStrings.Get(13278);
1289             share.strPath = value;
1290             localShares.push_back(share);
1291           }
1292         }
1293         if (CGUIDialogFileBrowser::ShowAndGetFile(localShares, strMask, g_localizeStrings.Get(1033), value))
1294           CSkinSettings::Get().SetString(string, value);
1295       }
1296     }
1297     else // execute.Equals("skin.setpath"))
1298     {
1299       g_mediaManager.GetNetworkLocations(localShares);
1300       if (params.size() > 1)
1301       {
1302         value = params[1];
1303         URIUtils::AddSlashAtEnd(value);
1304         bool bIsSource;
1305         if (CUtil::GetMatchingSource(value,localShares,bIsSource) < 0) // path is outside shares - add it as a separate one
1306         {
1307           CMediaSource share;
1308           share.strName = g_localizeStrings.Get(13278);
1309           share.strPath = value;
1310           localShares.push_back(share);
1311         }
1312       }
1313       if (CGUIDialogFileBrowser::ShowAndGetDirectory(localShares, g_localizeStrings.Get(1031), value))
1314         CSkinSettings::Get().SetString(string, value);
1315     }
1316     CSettings::Get().Save();
1317   }
1318   else if (execute.Equals("skin.setaddon") && params.size() > 1)
1319   {
1320     int string = CSkinSettings::Get().TranslateString(params[0]);
1321     vector<ADDON::TYPE> types;
1322     for (unsigned int i = 1 ; i < params.size() ; i++)
1323     {
1324       ADDON::TYPE type = TranslateType(params[i]);
1325       if (type != ADDON_UNKNOWN)
1326         types.push_back(type);
1327     }
1328     CStdString result;
1329     if (types.size() > 0 && CGUIWindowAddonBrowser::SelectAddonID(types, result, true) == 1)
1330     {
1331       CSkinSettings::Get().SetString(string, result);
1332       CSettings::Get().Save();
1333     }
1334   }
1335   else if (execute.Equals("dialog.close") && params.size())
1336   {
1337     bool bForce = false;
1338     if (params.size() > 1 && StringUtils::EqualsNoCase(params[1], "true"))
1339       bForce = true;
1340     if (StringUtils::EqualsNoCase(params[0], "all"))
1341     {
1342       g_windowManager.CloseDialogs(bForce);
1343     }
1344     else
1345     {
1346       int id = CButtonTranslator::TranslateWindow(params[0]);
1347       CGUIWindow *window = (CGUIWindow *)g_windowManager.GetWindow(id);
1348       if (window && window->IsDialog())
1349         ((CGUIDialog *)window)->Close(bForce);
1350     }
1351   }
1352   else if (execute.Equals("system.logoff"))
1353   {
1354     // there was a commit from cptspiff here which was reverted
1355     // for keeping the behaviour from Eden in Frodo - see
1356     // git rev 9ee5f0047b
1357     if (g_windowManager.GetActiveWindow() == WINDOW_LOGIN_SCREEN)
1358       return -1;
1359
1360     g_application.StopPlaying();
1361     if (g_application.IsMusicScanning())
1362       g_application.StopMusicScan();
1363
1364     if (g_application.IsVideoScanning())
1365       g_application.StopVideoScan();
1366
1367     ADDON::CAddonMgr::Get().StopServices(true);
1368
1369     g_application.getNetwork().NetworkMessage(CNetwork::SERVICES_DOWN,1);
1370     CProfilesManager::Get().LoadMasterProfileForLogin();
1371     g_passwordManager.bMasterUser = false;
1372     g_windowManager.ActivateWindow(WINDOW_LOGIN_SCREEN);
1373     if (!CNetworkServices::Get().StartEventServer()) // event server could be needed in some situations
1374       CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Warning, g_localizeStrings.Get(33102), g_localizeStrings.Get(33100));
1375   }
1376   else if (execute.Equals("pagedown"))
1377   {
1378     int id = atoi(parameter.c_str());
1379     CGUIMessage message(GUI_MSG_PAGE_DOWN, g_windowManager.GetFocusedWindow(), id);
1380     g_windowManager.SendMessage(message);
1381   }
1382   else if (execute.Equals("pageup"))
1383   {
1384     int id = atoi(parameter.c_str());
1385     CGUIMessage message(GUI_MSG_PAGE_UP, g_windowManager.GetFocusedWindow(), id);
1386     g_windowManager.SendMessage(message);
1387   }
1388   else if (execute.Equals("updatelibrary") && params.size())
1389   {
1390     if (params[0].Equals("music"))
1391     {
1392       if (g_application.IsMusicScanning())
1393         g_application.StopMusicScan();
1394       else
1395         g_application.StartMusicScan(params.size() > 1 ? params[1] : "");
1396     }
1397     if (params[0].Equals("video"))
1398     {
1399       if (g_application.IsVideoScanning())
1400         g_application.StopVideoScan();
1401       else
1402         g_application.StartVideoScan(params.size() > 1 ? params[1] : "");
1403     }
1404   }
1405   else if (execute.Equals("cleanlibrary"))
1406   {
1407     if (!params.size() || params[0].Equals("video"))
1408     {
1409       if (!g_application.IsVideoScanning())
1410          g_application.StartVideoCleanup();
1411       else
1412         CLog::Log(LOGERROR, "XBMC.CleanLibrary is not possible while scanning or cleaning");
1413     }
1414     else if (params[0].Equals("music"))
1415     {
1416       if (!g_application.IsMusicScanning())
1417       {
1418         CMusicDatabase musicdatabase;
1419
1420         musicdatabase.Open();
1421         musicdatabase.Cleanup();
1422         musicdatabase.Close();
1423       }
1424       else
1425         CLog::Log(LOGERROR, "XBMC.CleanLibrary is not possible while scanning for media info");
1426     }
1427   }
1428   else if (execute.Equals("exportlibrary"))
1429   {
1430     int iHeading = 647;
1431     if (params[0].Equals("music"))
1432       iHeading = 20196;
1433     CStdString path;
1434     VECSOURCES shares;
1435     g_mediaManager.GetLocalDrives(shares);
1436     g_mediaManager.GetNetworkLocations(shares);
1437     g_mediaManager.GetRemovableDrives(shares);
1438     bool singleFile;
1439     bool thumbs=false;
1440     bool actorThumbs=false;
1441     bool overwrite=false;
1442     bool cancelled=false;
1443
1444     if (params.size() > 1)
1445       singleFile = params[1].Equals("true");
1446     else
1447       singleFile = CGUIDialogYesNo::ShowAndGetInput(iHeading,20426,20427,-1,20428,20429,cancelled);
1448
1449     if (cancelled)
1450         return -1;
1451
1452     if (singleFile)
1453     {
1454       if (params.size() > 2)
1455         thumbs = params[2].Equals("true");
1456       else
1457         thumbs = CGUIDialogYesNo::ShowAndGetInput(iHeading,20430,-1,-1,cancelled);
1458     }
1459
1460     if (cancelled)
1461       return -1;
1462
1463     if (thumbs && params[0].Equals("video"))
1464     {
1465       if (params.size() > 4)
1466         actorThumbs = params[4].Equals("true");
1467       else
1468         actorThumbs = CGUIDialogYesNo::ShowAndGetInput(iHeading,20436,-1,-1,cancelled);
1469     }
1470
1471     if (cancelled)
1472       return -1;
1473
1474     if (singleFile)
1475     {
1476       if (params.size() > 3)
1477         overwrite = params[3].Equals("true");
1478       else
1479         overwrite = CGUIDialogYesNo::ShowAndGetInput(iHeading,20431,-1,-1,cancelled);
1480     }
1481
1482     if (cancelled)
1483       return -1;
1484
1485     if (params.size() > 2)
1486       path=params[2];
1487     if (singleFile || !path.empty() ||
1488         CGUIDialogFileBrowser::ShowAndGetDirectory(shares,
1489                                   g_localizeStrings.Get(661), path, true))
1490     {
1491       if (params[0].Equals("video"))
1492       {
1493         CVideoDatabase videodatabase;
1494         videodatabase.Open();
1495         videodatabase.ExportToXML(path, singleFile, thumbs, actorThumbs, overwrite);
1496         videodatabase.Close();
1497       }
1498       else
1499       {
1500         if (URIUtils::HasSlashAtEnd(path))
1501           path = URIUtils::AddFileToFolder(path, "musicdb.xml");
1502         CMusicDatabase musicdatabase;
1503         musicdatabase.Open();
1504         musicdatabase.ExportToXML(path, singleFile, thumbs, overwrite);
1505         musicdatabase.Close();
1506       }
1507     }
1508   }
1509   else if (execute.Equals("control.move") && params.size() > 1)
1510   {
1511     CGUIMessage message(GUI_MSG_MOVE_OFFSET, g_windowManager.GetFocusedWindow(), atoi(params[0].c_str()), atoi(params[1].c_str()));
1512     g_windowManager.SendMessage(message);
1513   }
1514   else if (execute.Equals("container.refresh"))
1515   { // NOTE: These messages require a media window, thus they're sent to the current activewindow.
1516     //       This shouldn't stop a dialog intercepting it though.
1517     CGUIMessage message(GUI_MSG_NOTIFY_ALL, g_windowManager.GetActiveWindow(), 0, GUI_MSG_UPDATE, 1); // 1 to reset the history
1518     message.SetStringParam(parameter);
1519     g_windowManager.SendMessage(message);
1520   }
1521   else if (execute.Equals("container.update") && params.size())
1522   {
1523     CGUIMessage message(GUI_MSG_NOTIFY_ALL, g_windowManager.GetActiveWindow(), 0, GUI_MSG_UPDATE, 0);
1524     message.SetStringParam(params[0]);
1525     if (params.size() > 1 && StringUtils::EqualsNoCase(params[1], "replace"))
1526       message.SetParam2(1); // reset the history
1527     g_windowManager.SendMessage(message);
1528   }
1529   else if (execute.Equals("container.nextviewmode"))
1530   {
1531     CGUIMessage message(GUI_MSG_CHANGE_VIEW_MODE, g_windowManager.GetActiveWindow(), 0, 0, 1);
1532     g_windowManager.SendMessage(message);
1533   }
1534   else if (execute.Equals("container.previousviewmode"))
1535   {
1536     CGUIMessage message(GUI_MSG_CHANGE_VIEW_MODE, g_windowManager.GetActiveWindow(), 0, 0, -1);
1537     g_windowManager.SendMessage(message);
1538   }
1539   else if (execute.Equals("container.setviewmode"))
1540   {
1541     CGUIMessage message(GUI_MSG_CHANGE_VIEW_MODE, g_windowManager.GetActiveWindow(), 0, atoi(parameter.c_str()));
1542     g_windowManager.SendMessage(message);
1543   }
1544   else if (execute.Equals("container.nextsortmethod"))
1545   {
1546     CGUIMessage message(GUI_MSG_CHANGE_SORT_METHOD, g_windowManager.GetActiveWindow(), 0, 0, 1);
1547     g_windowManager.SendMessage(message);
1548   }
1549   else if (execute.Equals("container.previoussortmethod"))
1550   {
1551     CGUIMessage message(GUI_MSG_CHANGE_SORT_METHOD, g_windowManager.GetActiveWindow(), 0, 0, -1);
1552     g_windowManager.SendMessage(message);
1553   }
1554   else if (execute.Equals("container.setsortmethod"))
1555   {
1556     CGUIMessage message(GUI_MSG_CHANGE_SORT_METHOD, g_windowManager.GetActiveWindow(), 0, atoi(parameter.c_str()));
1557     g_windowManager.SendMessage(message);
1558   }
1559   else if (execute.Equals("container.sortdirection"))
1560   {
1561     CGUIMessage message(GUI_MSG_CHANGE_SORT_DIRECTION, g_windowManager.GetActiveWindow(), 0, 0);
1562     g_windowManager.SendMessage(message);
1563   }
1564   else if (execute.Equals("control.message") && params.size() >= 2)
1565   {
1566     int controlID = atoi(params[0].c_str());
1567     int windowID = (params.size() == 3) ? CButtonTranslator::TranslateWindow(params[2]) : g_windowManager.GetActiveWindow();
1568     if (params[1] == "moveup")
1569       g_windowManager.SendMessage(GUI_MSG_MOVE_OFFSET, windowID, controlID, 1);
1570     else if (params[1] == "movedown")
1571       g_windowManager.SendMessage(GUI_MSG_MOVE_OFFSET, windowID, controlID, -1);
1572     else if (params[1] == "pageup")
1573       g_windowManager.SendMessage(GUI_MSG_PAGE_UP, windowID, controlID);
1574     else if (params[1] == "pagedown")
1575       g_windowManager.SendMessage(GUI_MSG_PAGE_DOWN, windowID, controlID);
1576     else if (params[1] == "click")
1577       g_windowManager.SendMessage(GUI_MSG_CLICKED, controlID, windowID);
1578   }
1579   else if (execute.Equals("sendclick") && params.size())
1580   {
1581     if (params.size() == 2)
1582     {
1583       // have a window - convert it
1584       int windowID = CButtonTranslator::TranslateWindow(params[0]);
1585       CGUIMessage message(GUI_MSG_CLICKED, atoi(params[1].c_str()), windowID);
1586       g_windowManager.SendMessage(message);
1587     }
1588     else
1589     { // single param - assume you meant the active window
1590       CGUIMessage message(GUI_MSG_CLICKED, atoi(params[0].c_str()), g_windowManager.GetActiveWindow());
1591       g_windowManager.SendMessage(message);
1592     }
1593   }
1594   else if (execute.Equals("action") && params.size())
1595   {
1596     // try translating the action from our ButtonTranslator
1597     int actionID;
1598     if (CButtonTranslator::TranslateActionString(params[0].c_str(), actionID))
1599     {
1600       int windowID = params.size() == 2 ? CButtonTranslator::TranslateWindow(params[1]) : WINDOW_INVALID;
1601       CApplicationMessenger::Get().SendAction(CAction(actionID), windowID);
1602     }
1603   }
1604   else if (execute.Equals("setproperty") && params.size() >= 2)
1605   {
1606     CGUIWindow *window = g_windowManager.GetWindow(params.size() > 2 ? CButtonTranslator::TranslateWindow(params[2]) : g_windowManager.GetFocusedWindow());
1607     if (window)
1608       window->SetProperty(params[0],params[1]);
1609   }
1610   else if (execute.Equals("clearproperty") && params.size())
1611   {
1612     CGUIWindow *window = g_windowManager.GetWindow(params.size() > 1 ? CButtonTranslator::TranslateWindow(params[1]) : g_windowManager.GetFocusedWindow());
1613     if (window)
1614       window->SetProperty(params[0],"");
1615   }
1616   else if (execute.Equals("wakeonlan"))
1617   {
1618     g_application.getNetwork().WakeOnLan((char*)params[0].c_str());
1619   }
1620   else if (execute.Equals("addon.default.opensettings") && params.size() == 1)
1621   {
1622     AddonPtr addon;
1623     ADDON::TYPE type = TranslateType(params[0]);
1624     if (CAddonMgr::Get().GetDefault(type, addon))
1625     {
1626       CGUIDialogAddonSettings::ShowAndGetInput(addon);
1627       if (type == ADDON_VIZ)
1628         g_windowManager.SendMessage(GUI_MSG_VISUALISATION_RELOAD, 0, 0);
1629     }
1630   }
1631   else if (execute.Equals("addon.default.set") && params.size() == 1)
1632   {
1633     CStdString addonID;
1634     TYPE type = TranslateType(params[0]);
1635     bool allowNone = false;
1636     if (type == ADDON_VIZ)
1637       allowNone = true;
1638
1639     if (type != ADDON_UNKNOWN && 
1640         CGUIWindowAddonBrowser::SelectAddonID(type,addonID,allowNone))
1641     {
1642       CAddonMgr::Get().SetDefault(type,addonID);
1643       if (type == ADDON_VIZ)
1644         g_windowManager.SendMessage(GUI_MSG_VISUALISATION_RELOAD, 0, 0);
1645     }
1646   }
1647   else if (execute.Equals("addon.opensettings") && params.size() == 1)
1648   {
1649     AddonPtr addon;
1650     if (CAddonMgr::Get().GetAddon(params[0], addon))
1651       CGUIDialogAddonSettings::ShowAndGetInput(addon);
1652   }
1653   else if (execute.Equals("updateaddonrepos"))
1654   {
1655     CAddonInstaller::Get().UpdateRepos(true);
1656   }
1657   else if (execute.Equals("updatelocaladdons"))
1658   {
1659     CAddonMgr::Get().FindAddons();
1660   }
1661   else if (execute.Equals("toggledpms"))
1662   {
1663     g_application.ToggleDPMS(true);
1664   }
1665   else if (execute.Equals("cectogglestate"))
1666   {
1667     CApplicationMessenger::Get().CECToggleState();
1668   }
1669   else if (execute.Equals("cecactivatesource"))
1670   {
1671     CApplicationMessenger::Get().CECActivateSource();
1672   }
1673   else if (execute.Equals("cecstandby"))
1674   {
1675     CApplicationMessenger::Get().CECStandby();
1676   }
1677 #if defined(HAS_LIRC) || defined(HAS_IRSERVERSUITE)
1678   else if (execute.Equals("lirc.stop"))
1679   {
1680     g_RemoteControl.Disconnect();
1681     g_RemoteControl.setUsed(false);
1682   }
1683   else if (execute.Equals("lirc.start"))
1684   {
1685     g_RemoteControl.setUsed(true);
1686     g_RemoteControl.Initialize();
1687   }
1688   else if (execute.Equals("lirc.send"))
1689   {
1690     CStdString command;
1691     for (int i = 0; i < (int)params.size(); i++)
1692     {
1693       command += params[i];
1694       if (i < (int)params.size() - 1)
1695         command += ' ';
1696     }
1697     g_RemoteControl.AddSendCommand(command);
1698   }
1699 #endif
1700   else if (execute.Equals("weather.locationset"))
1701   {
1702     int loc = atoi(params[0]);
1703     CGUIMessage msg(GUI_MSG_ITEM_SELECT, 0, 0, loc);
1704     g_windowManager.SendMessage(msg, WINDOW_WEATHER);
1705   }
1706   else if (execute.Equals("weather.locationnext"))
1707   {
1708     CGUIMessage msg(GUI_MSG_MOVE_OFFSET, 0, 0, 1);
1709     g_windowManager.SendMessage(msg, WINDOW_WEATHER);
1710   }
1711   else if (execute.Equals("weather.locationprevious"))
1712   {
1713     CGUIMessage msg(GUI_MSG_MOVE_OFFSET, 0, 0, -1);
1714     g_windowManager.SendMessage(msg, WINDOW_WEATHER);
1715   }
1716   else if (execute.Equals("weather.refresh"))
1717   {
1718     CGUIMessage msg(GUI_MSG_MOVE_OFFSET, 0, 0, 0);
1719     g_windowManager.SendMessage(msg, WINDOW_WEATHER);
1720   }
1721   else if (execute.Equals("videolibrary.search"))
1722   {
1723     CGUIMessage msg(GUI_MSG_SEARCH, 0, 0, 0);
1724     g_windowManager.SendMessage(msg, WINDOW_VIDEO_NAV);
1725   }
1726   else if (execute.Equals("toggledebug"))
1727   {
1728     bool debug = CSettings::Get().GetBool("debug.showloginfo");
1729     CSettings::Get().SetBool("debug.showloginfo", !debug);
1730     g_advancedSettings.SetDebugMode(!debug);
1731   }
1732   else if (execute.Equals("startpvrmanager"))
1733   {
1734     g_application.StartPVRManager();
1735   }
1736   else if (execute.Equals("stoppvrmanager"))
1737   {
1738     g_application.StopPVRManager();
1739   }
1740   else if (execute.Equals("StartAndroidActivity") && params.size() > 0)
1741   {
1742     CApplicationMessenger::Get().StartAndroidActivity(params);
1743   }
1744   else if (execute.Equals("SetStereoMode") && !parameter.empty())
1745   {
1746     CAction action = CStereoscopicsManager::Get().ConvertActionCommandToAction(execute, parameter);
1747     if (action.GetID() != ACTION_NONE)
1748       CApplicationMessenger::Get().SendAction(action);
1749     else
1750     {
1751       CLog::Log(LOGERROR,"Builtin 'SetStereoMode' called with unknown parameter: %s", parameter.c_str());
1752       return -2;
1753     }
1754   }
1755   else
1756     return -1;
1757   return 0;
1758 }