68cb1bdcb9dd2449ff73742f58746bd7055f5e22
[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       CStdString cmd;
556       if (CAddonMgr::Get().GetAddon(params[0],addon,ADDON_PLUGIN))
557       {
558         PluginPtr plugin = boost::dynamic_pointer_cast<CPluginSource>(addon);
559         CStdString addonid = params[0];
560         CStdString urlParameters;
561         CStdStringArray parameters;
562         if (params.size() == 2 &&
563            (StringUtils::StartsWith(params[1], "/") || StringUtils::StartsWith(params[1], "?")))
564           urlParameters = params[1];
565         else if (params.size() > 1)
566         {
567           parameters.insert(parameters.begin(), params.begin() + 1, params.end());
568           urlParameters = "?" + StringUtils::JoinString(parameters, "&");
569         }
570         else
571         {
572           // Add '/' if addon is run without params (will be removed later so it's safe)
573           // Otherwise there are 2 entries for the same plugin in ViewModesX.db
574           urlParameters = "/";
575         }
576
577         if (plugin->Provides(CPluginSource::VIDEO))
578           cmd = StringUtils::Format("ActivateWindow(Videos,plugin://%s%s,return)", addonid.c_str(), urlParameters.c_str());
579         else if (plugin->Provides(CPluginSource::AUDIO))
580           cmd = StringUtils::Format("ActivateWindow(Music,plugin://%s%s,return)", addonid.c_str(), urlParameters.c_str());
581         else if (plugin->Provides(CPluginSource::EXECUTABLE))
582           cmd = StringUtils::Format("ActivateWindow(Programs,plugin://%s%s,return)", addonid.c_str(), urlParameters.c_str());
583         else if (plugin->Provides(CPluginSource::IMAGE))
584           cmd = StringUtils::Format("ActivateWindow(Pictures,plugin://%s%s,return)", addonid.c_str(), urlParameters.c_str());
585         else
586           // Pass the script name (params[0]) and all the parameters
587           // (params[1] ... params[x]) separated by a comma to RunPlugin
588           cmd = StringUtils::Format("RunPlugin(%s)", StringUtils::JoinString(params, ",").c_str());
589       }
590       else if (CAddonMgr::Get().GetAddon(params[0], addon, ADDON_SCRIPT) ||
591                CAddonMgr::Get().GetAddon(params[0], addon, ADDON_SCRIPT_WEATHER) ||
592                CAddonMgr::Get().GetAddon(params[0], addon, ADDON_SCRIPT_LYRICS))
593         // Pass the script name (params[0]) and all the parameters
594         // (params[1] ... params[x]) separated by a comma to RunScript
595         cmd = StringUtils::Format("RunScript(%s)", StringUtils::JoinString(params, ",").c_str());
596
597       return Execute(cmd);
598     }
599     else
600     {
601       CLog::Log(LOGERROR, "XBMC.RunAddon called with no arguments.");
602     }
603   }
604   else if (execute.Equals("notifyall"))
605   {
606     if (params.size() > 1)
607     {
608       CVariant data;
609       if (params.size() > 2)
610         data = CJSONVariantParser::Parse((const unsigned char *)params[2].c_str(), params[2].size());
611
612       ANNOUNCEMENT::CAnnouncementManager::Announce(ANNOUNCEMENT::Other, params[0], params[1], data);
613     }
614     else
615       CLog::Log(LOGERROR, "XBMC.NotifyAll needs two parameters");
616   }
617   else if (execute.Equals("playmedia"))
618   {
619     if (!params.size())
620     {
621       CLog::Log(LOGERROR, "XBMC.PlayMedia called with empty parameter");
622       return -3;
623     }
624
625     CFileItem item(params[0], false);
626     if (URIUtils::HasSlashAtEnd(params[0]))
627       item.m_bIsFolder = true;
628
629     // restore to previous window if needed
630     if( g_windowManager.GetActiveWindow() == WINDOW_SLIDESHOW ||
631         g_windowManager.GetActiveWindow() == WINDOW_FULLSCREEN_VIDEO ||
632         g_windowManager.GetActiveWindow() == WINDOW_VISUALISATION )
633         g_windowManager.PreviousWindow();
634
635     // reset screensaver
636     g_application.ResetScreenSaver();
637     g_application.WakeUpScreenSaverAndDPMS();
638
639     // ask if we need to check guisettings to resume
640     bool askToResume = true;
641     int playOffset = 0;
642     for (unsigned int i = 1 ; i < params.size() ; i++)
643     {
644       if (params[i].Equals("isdir"))
645         item.m_bIsFolder = true;
646       else if (params[i].Equals("1")) // set fullscreen or windowed
647         CMediaSettings::Get().SetVideoStartWindowed(true);
648       else if (params[i].Equals("resume"))
649       {
650         // force the item to resume (if applicable) (see CApplication::PlayMedia)
651         item.m_lStartOffset = STARTOFFSET_RESUME;
652         askToResume = false;
653       }
654       else if (params[i].Equals("noresume"))
655       {
656         // force the item to start at the beginning (m_lStartOffset is initialized to 0)
657         askToResume = false;
658       }
659       else if (StringUtils::StartsWithNoCase(params[i], "playoffset=")) {
660         playOffset = atoi(params[i].substr(11).c_str()) - 1;
661         item.SetProperty("playlist_starting_track", playOffset);
662       }
663     }
664
665     if (!item.m_bIsFolder && item.IsPlugin())
666       item.SetProperty("IsPlayable", true);
667
668     if ( askToResume == true )
669     {
670       if ( CGUIWindowVideoBase::ShowResumeMenu(item) == false )
671         return false;
672     }
673     if (item.m_bIsFolder)
674     {
675       CFileItemList items;
676       CStdString extensions = g_advancedSettings.m_videoExtensions + "|" + g_advancedSettings.m_musicExtensions;
677       CDirectory::GetDirectory(item.GetPath(),items,extensions);
678       items.Sort(SortByLabel, SortOrderAscending);
679
680       bool containsMusic = false, containsVideo = false;
681       for (int i = 0; i < items.Size(); i++)
682       {
683         bool isVideo = items[i]->IsVideo();
684         containsMusic |= !isVideo;
685         containsVideo |= isVideo;
686         
687         if (containsMusic && containsVideo)
688           break;
689       }
690       
691       int playlist = containsVideo? PLAYLIST_VIDEO : PLAYLIST_MUSIC;;
692       if (containsMusic && containsVideo) //mixed content found in the folder
693       {
694         for (int i = items.Size() - 1; i >= 0; i--) //remove music entries
695         {
696           if (!items[i]->IsVideo())
697             items.Remove(i);
698         }
699       }
700       
701       g_playlistPlayer.ClearPlaylist(playlist);
702       g_playlistPlayer.Add(playlist, items);
703       g_playlistPlayer.SetCurrentPlaylist(playlist);
704       g_playlistPlayer.Play(playOffset);
705     }
706     else
707     {
708       int playlist = item.IsAudio() ? PLAYLIST_MUSIC : PLAYLIST_VIDEO;
709       g_playlistPlayer.ClearPlaylist(playlist);
710       g_playlistPlayer.SetCurrentPlaylist(playlist);
711
712       // play media
713       if (!g_application.PlayMedia(item, playlist))
714       {
715         CLog::Log(LOGERROR, "XBMC.PlayMedia could not play media: %s", params[0].c_str());
716         return false;
717       }
718     }
719   }
720   else if (execute.Equals("showPicture"))
721   {
722     if (!params.size())
723     {
724       CLog::Log(LOGERROR, "XBMC.ShowPicture called with empty parameter");
725       return -2;
726     }
727     CGUIMessage msg(GUI_MSG_SHOW_PICTURE, 0, 0);
728     msg.SetStringParam(params[0]);
729     CGUIWindow *pWindow = g_windowManager.GetWindow(WINDOW_SLIDESHOW);
730     if (pWindow) pWindow->OnMessage(msg);
731   }
732   else if (execute.Equals("slideShow") || execute.Equals("recursiveslideShow"))
733   {
734     if (!params.size())
735     {
736       CLog::Log(LOGERROR, "XBMC.SlideShow called with empty parameter");
737       return -2;
738     }
739     std::string beginSlidePath;
740     // leave RecursiveSlideShow command as-is
741     unsigned int flags = 0;
742     if (execute.Equals("RecursiveSlideShow"))
743       flags |= 1;
744
745     // SlideShow(dir[,recursive][,[not]random][,pause][,beginslide="/path/to/start/slide.jpg"])
746     // the beginslide value need be escaped (for '"' or '\' in it, by backslash)
747     // and then quoted, or not. See CUtil::SplitParams()
748     else
749     {
750       for (unsigned int i = 1 ; i < params.size() ; i++)
751       {
752         if (params[i].Equals("recursive"))
753           flags |= 1;
754         else if (params[i].Equals("random")) // set fullscreen or windowed
755           flags |= 2;
756         else if (params[i].Equals("notrandom"))
757           flags |= 4;
758         else if (params[i].Equals("pause"))
759           flags |= 8;
760         else if (StringUtils::StartsWithNoCase(params[i], "beginslide="))
761           beginSlidePath = params[i].substr(11);
762       }
763     }
764
765     CGUIMessage msg(GUI_MSG_START_SLIDESHOW, 0, 0, flags);
766     vector<CStdString> strParams;
767     strParams.push_back(params[0]);
768     strParams.push_back(beginSlidePath);
769     msg.SetStringParams(strParams);
770     CGUIWindow *pWindow = g_windowManager.GetWindow(WINDOW_SLIDESHOW);
771     if (pWindow) pWindow->OnMessage(msg);
772   }
773   else if (execute.Equals("reloadskin"))
774   {
775     //  Reload the skin
776     g_application.ReloadSkin(!params.empty() && StringUtils::EqualsNoCase(params[0], "confirm"));
777   }
778   else if (execute.Equals("unloadskin"))
779   {
780     g_application.UnloadSkin(true); // we're reloading the skin after this
781   }
782   else if (execute.Equals("refreshrss"))
783   {
784     CRssManager::Get().Reload();
785   }
786   else if (execute.Equals("playercontrol"))
787   {
788     g_application.ResetScreenSaver();
789     g_application.WakeUpScreenSaverAndDPMS();
790     if (!params.size())
791     {
792       CLog::Log(LOGERROR, "XBMC.PlayerControl called with empty parameter");
793       return -3;
794     }
795     if (parameter.Equals("play"))
796     { // play/pause
797       // either resume playing, or pause
798       if (g_application.m_pPlayer->IsPlaying())
799       {
800         if (g_application.m_pPlayer->GetPlaySpeed() != 1)
801           g_application.m_pPlayer->SetPlaySpeed(1, g_application.IsMutedInternal());
802         else
803           g_application.m_pPlayer->Pause();
804       }
805     }
806     else if (parameter.Equals("stop"))
807     {
808       g_application.StopPlaying();
809     }
810     else if (parameter.Equals("rewind") || parameter.Equals("forward"))
811     {
812       if (g_application.m_pPlayer->IsPlaying() && !g_application.m_pPlayer->IsPaused())
813       {
814         int iPlaySpeed = g_application.m_pPlayer->GetPlaySpeed();
815         if (parameter.Equals("rewind") && iPlaySpeed == 1) // Enables Rewinding
816           iPlaySpeed *= -2;
817         else if (parameter.Equals("rewind") && iPlaySpeed > 1) //goes down a notch if you're FFing
818           iPlaySpeed /= 2;
819         else if (parameter.Equals("forward") && iPlaySpeed < 1) //goes up a notch if you're RWing
820         {
821           iPlaySpeed /= 2;
822           if (iPlaySpeed == -1) iPlaySpeed = 1;
823         }
824         else
825           iPlaySpeed *= 2;
826
827         if (iPlaySpeed > 32 || iPlaySpeed < -32)
828           iPlaySpeed = 1;
829
830         g_application.m_pPlayer->SetPlaySpeed(iPlaySpeed, g_application.IsMutedInternal());
831       }
832     }
833     else if (parameter.Equals("next"))
834     {
835       g_application.OnAction(CAction(ACTION_NEXT_ITEM));
836     }
837     else if (parameter.Equals("previous"))
838     {
839       g_application.OnAction(CAction(ACTION_PREV_ITEM));
840     }
841     else if (parameter.Equals("bigskipbackward"))
842     {
843       if (g_application.m_pPlayer->IsPlaying())
844         g_application.m_pPlayer->Seek(false, true);
845     }
846     else if (parameter.Equals("bigskipforward"))
847     {
848       if (g_application.m_pPlayer->IsPlaying())
849         g_application.m_pPlayer->Seek(true, true);
850     }
851     else if (parameter.Equals("smallskipbackward"))
852     {
853       if (g_application.m_pPlayer->IsPlaying())
854         g_application.m_pPlayer->Seek(false, false);
855     }
856     else if (parameter.Equals("smallskipforward"))
857     {
858       if (g_application.m_pPlayer->IsPlaying())
859         g_application.m_pPlayer->Seek(true, false);
860     }
861     else if (StringUtils::StartsWithNoCase(parameter, "seekpercentage"))
862     {
863       CStdString offset = "";
864       if (parameter.size() == 14)
865         CLog::Log(LOGERROR,"PlayerControl(seekpercentage(n)) called with no argument");
866       else if (parameter.size() < 17) // arg must be at least "(N)"
867         CLog::Log(LOGERROR,"PlayerControl(seekpercentage(n)) called with invalid argument: \"%s\"", parameter.substr(14).c_str());
868       else
869       {
870         // Don't bother checking the argument: an invalid arg will do seek(0)
871         offset = parameter.substr(15);
872         StringUtils::TrimRight(offset, ")");
873         float offsetpercent = (float) atof(offset.c_str());
874         if (offsetpercent < 0 || offsetpercent > 100)
875           CLog::Log(LOGERROR,"PlayerControl(seekpercentage(n)) argument, %f, must be 0-100", offsetpercent);
876         else if (g_application.m_pPlayer->IsPlaying())
877           g_application.SeekPercentage(offsetpercent);
878       }
879     }
880     else if( parameter.Equals("showvideomenu") )
881     {
882       if( g_application.m_pPlayer->IsPlaying() )
883         g_application.m_pPlayer->OnAction(CAction(ACTION_SHOW_VIDEOMENU));
884     }
885     else if( parameter.Equals("record") )
886     {
887       if( g_application.m_pPlayer->IsPlaying() && g_application.m_pPlayer->CanRecord())
888         g_application.m_pPlayer->Record(!g_application.m_pPlayer->IsRecording());
889     }
890     else if (StringUtils::StartsWithNoCase(parameter, "partymode"))
891     {
892       CStdString strXspPath = "";
893       //empty param=music, "music"=music, "video"=video, else xsp path
894       PartyModeContext context = PARTYMODECONTEXT_MUSIC;
895       if (parameter.size() > 9)
896       {
897         if (parameter.size() == 16 && StringUtils::EndsWithNoCase(parameter, "video)"))
898           context = PARTYMODECONTEXT_VIDEO;
899         else if (parameter.size() != 16 || !StringUtils::EndsWithNoCase(parameter, "music)"))
900         {
901           strXspPath = parameter.substr(10);
902           StringUtils::TrimRight(strXspPath, ")");
903           context = PARTYMODECONTEXT_UNKNOWN;
904         }
905       }
906       if (g_partyModeManager.IsEnabled())
907         g_partyModeManager.Disable();
908       else
909         g_partyModeManager.Enable(context, strXspPath);
910     }
911     else if (parameter.Equals("random")    ||
912              parameter.Equals("randomoff") ||
913              parameter.Equals("randomon"))
914     {
915       // get current playlist
916       int iPlaylist = g_playlistPlayer.GetCurrentPlaylist();
917
918       // reverse the current setting
919       bool shuffled = g_playlistPlayer.IsShuffled(iPlaylist);
920       if ((shuffled && parameter.Equals("randomon")) || (!shuffled && parameter.Equals("randomoff")))
921         return 0;
922
923       // check to see if we should notify the user
924       bool notify = (params.size() == 2 && params[1].Equals("notify"));
925       g_playlistPlayer.SetShuffle(iPlaylist, !shuffled, notify);
926
927       // save settings for now playing windows
928       switch (iPlaylist)
929       {
930       case PLAYLIST_MUSIC:
931         CMediaSettings::Get().SetMusicPlaylistShuffled(g_playlistPlayer.IsShuffled(iPlaylist));
932         CSettings::Get().Save();
933         break;
934       case PLAYLIST_VIDEO:
935         CMediaSettings::Get().SetVideoPlaylistShuffled(g_playlistPlayer.IsShuffled(iPlaylist));
936         CSettings::Get().Save();
937       }
938
939       // send message
940       CGUIMessage msg(GUI_MSG_PLAYLISTPLAYER_RANDOM, 0, 0, iPlaylist, g_playlistPlayer.IsShuffled(iPlaylist));
941       g_windowManager.SendThreadMessage(msg);
942
943     }
944     else if (StringUtils::StartsWithNoCase(parameter, "repeat"))
945     {
946       // get current playlist
947       int iPlaylist = g_playlistPlayer.GetCurrentPlaylist();
948       PLAYLIST::REPEAT_STATE previous_state = g_playlistPlayer.GetRepeat(iPlaylist);
949
950       PLAYLIST::REPEAT_STATE state;
951       if (parameter.Equals("repeatall"))
952         state = PLAYLIST::REPEAT_ALL;
953       else if (parameter.Equals("repeatone"))
954         state = PLAYLIST::REPEAT_ONE;
955       else if (parameter.Equals("repeatoff"))
956         state = PLAYLIST::REPEAT_NONE;
957       else if (previous_state == PLAYLIST::REPEAT_NONE)
958         state = PLAYLIST::REPEAT_ALL;
959       else if (previous_state == PLAYLIST::REPEAT_ALL)
960         state = PLAYLIST::REPEAT_ONE;
961       else
962         state = PLAYLIST::REPEAT_NONE;
963
964       if (state == previous_state)
965         return 0;
966
967       // check to see if we should notify the user
968       bool notify = (params.size() == 2 && params[1].Equals("notify"));
969       g_playlistPlayer.SetRepeat(iPlaylist, state, notify);
970
971       // save settings for now playing windows
972       switch (iPlaylist)
973       {
974       case PLAYLIST_MUSIC:
975         CMediaSettings::Get().SetMusicPlaylistRepeat(state == PLAYLIST::REPEAT_ALL);
976         CSettings::Get().Save();
977         break;
978       case PLAYLIST_VIDEO:
979         CMediaSettings::Get().SetVideoPlaylistRepeat(state == PLAYLIST::REPEAT_ALL);
980         CSettings::Get().Save();
981       }
982
983       // send messages so now playing window can get updated
984       CGUIMessage msg(GUI_MSG_PLAYLISTPLAYER_REPEAT, 0, 0, iPlaylist, (int)state);
985       g_windowManager.SendThreadMessage(msg);
986     }
987   }
988   else if (execute.Equals("playwith"))
989   {
990     g_application.m_eForcedNextPlayer = CPlayerCoreFactory::Get().GetPlayerCore(parameter);
991     g_application.OnAction(CAction(ACTION_PLAYER_PLAY));
992   }
993   else if (execute.Equals("mute"))
994   {
995     g_application.ToggleMute();
996   }
997   else if (execute.Equals("setvolume"))
998   {
999     float oldVolume = g_application.GetVolume();
1000     float volume = (float)strtod(parameter.c_str(), NULL);
1001
1002     g_application.SetVolume(volume);
1003     if(oldVolume != volume)
1004     {
1005       if(params.size() > 1 && params[1].Equals("showVolumeBar"))    
1006       {
1007         CApplicationMessenger::Get().ShowVolumeBar(oldVolume < volume);  
1008       }
1009     }
1010   }
1011   else if (execute.Equals("playlist.playoffset"))
1012   {
1013     // playlist.playoffset(offset)
1014     // playlist.playoffset(music|video,offset)
1015     CStdString strPos = parameter;
1016     if (params.size() > 1)
1017     {
1018       // ignore any other parameters if present
1019       CStdString strPlaylist = params[0];
1020       strPos = params[1];
1021
1022       int iPlaylist = PLAYLIST_NONE;
1023       if (strPlaylist.Equals("music"))
1024         iPlaylist = PLAYLIST_MUSIC;
1025       else if (strPlaylist.Equals("video"))
1026         iPlaylist = PLAYLIST_VIDEO;
1027
1028       // unknown playlist
1029       if (iPlaylist == PLAYLIST_NONE)
1030       {
1031         CLog::Log(LOGERROR,"Playlist.PlayOffset called with unknown playlist: %s", strPlaylist.c_str());
1032         return false;
1033       }
1034
1035       // user wants to play the 'other' playlist
1036       if (iPlaylist != g_playlistPlayer.GetCurrentPlaylist())
1037       {
1038         g_application.StopPlaying();
1039         g_playlistPlayer.Reset();
1040         g_playlistPlayer.SetCurrentPlaylist(iPlaylist);
1041       }
1042     }
1043     // play the desired offset
1044     int pos = atol(strPos.c_str());
1045     // playlist is already playing
1046     if (g_application.m_pPlayer->IsPlaying())
1047       g_playlistPlayer.PlayNext(pos);
1048     // we start playing the 'other' playlist so we need to use play to initialize the player state
1049     else
1050       g_playlistPlayer.Play(pos);
1051   }
1052   else if (execute.Equals("playlist.clear"))
1053   {
1054     g_playlistPlayer.Clear();
1055   }
1056 #ifdef HAS_DVD_DRIVE
1057   else if (execute.Equals("ejecttray"))
1058   {
1059     g_mediaManager.ToggleTray();
1060   }
1061 #endif
1062   else if( execute.Equals("alarmclock") && params.size() > 1 )
1063   {
1064     // format is alarmclock(name,command[,seconds,true]);
1065     float seconds = 0;
1066     if (params.size() > 2)
1067     {
1068       if (params[2].find(':') == std::string::npos)
1069         seconds = static_cast<float>(atoi(params[2].c_str())*60);
1070       else
1071         seconds = (float)StringUtils::TimeStringToSeconds(params[2]);
1072     }
1073     else
1074     { // check if shutdown is specified in particular, and get the time for it
1075       CStdString strHeading;
1076       if (StringUtils::EqualsNoCase(parameter, "shutdowntimer"))
1077         strHeading = g_localizeStrings.Get(20145);
1078       else
1079         strHeading = g_localizeStrings.Get(13209);
1080       CStdString strTime;
1081       if( CGUIDialogNumeric::ShowAndGetNumber(strTime, strHeading) )
1082         seconds = static_cast<float>(atoi(strTime.c_str())*60);
1083       else
1084         return false;
1085     }
1086     bool silent = false;
1087     bool loop = false;
1088     for (unsigned int i = 3; i < params.size() ; i++)
1089     {
1090       // check "true" for backward comp
1091       if (StringUtils::EqualsNoCase(params[i], "true") || StringUtils::EqualsNoCase(params[i], "silent"))
1092         silent = true;
1093       else if (StringUtils::EqualsNoCase(params[i], "loop"))
1094         loop = true;
1095     }
1096
1097     if( g_alarmClock.IsRunning() )
1098       g_alarmClock.Stop(params[0],silent);
1099     // no negative times not allowed, loop must have a positive time
1100     if (seconds < 0 || (seconds == 0 && loop))
1101       return false;
1102     g_alarmClock.Start(params[0], seconds, params[1], silent, loop);
1103   }
1104   else if (execute.Equals("notification"))
1105   {
1106     if (params.size() < 2)
1107       return -1;
1108     if (params.size() == 4)
1109       CGUIDialogKaiToast::QueueNotification(params[3],params[0],params[1],atoi(params[2].c_str()));
1110     else if (params.size() == 3)
1111       CGUIDialogKaiToast::QueueNotification("",params[0],params[1],atoi(params[2].c_str()));
1112     else
1113       CGUIDialogKaiToast::QueueNotification(params[0],params[1]);
1114   }
1115   else if (execute.Equals("cancelalarm"))
1116   {
1117     bool silent = false;
1118     if (params.size() > 1 && StringUtils::EqualsNoCase(params[1], "true"))
1119       silent = true;
1120     g_alarmClock.Stop(params[0],silent);
1121   }
1122   else if (execute.Equals("playdvd"))
1123   {
1124 #ifdef HAS_DVD_DRIVE
1125     bool restart = false;
1126     if (params.size() > 0 && StringUtils::EqualsNoCase(params[0], "restart"))
1127       restart = true;
1128     CAutorun::PlayDisc(g_mediaManager.GetDiscPath(), true, restart);
1129 #endif
1130   }
1131   else if (execute.Equals("ripcd"))
1132   {
1133 #ifdef HAS_CDDA_RIPPER
1134     CCDDARipper::GetInstance().RipCD();
1135 #endif
1136   }
1137   else if (execute.Equals("skin.togglesetting"))
1138   {
1139     int setting = CSkinSettings::Get().TranslateBool(parameter);
1140     CSkinSettings::Get().SetBool(setting, !CSkinSettings::Get().GetBool(setting));
1141     CSettings::Get().Save();
1142   }
1143   else if (execute.Equals("skin.setbool") && params.size())
1144   {
1145     if (params.size() > 1)
1146     {
1147       int string = CSkinSettings::Get().TranslateBool(params[0]);
1148       CSkinSettings::Get().SetBool(string, StringUtils::EqualsNoCase(params[1], "true"));
1149       CSettings::Get().Save();
1150       return 0;
1151     }
1152     // default is to set it to true
1153     int setting = CSkinSettings::Get().TranslateBool(params[0]);
1154     CSkinSettings::Get().SetBool(setting, true);
1155     CSettings::Get().Save();
1156   }
1157   else if (execute.Equals("skin.reset"))
1158   {
1159     CSkinSettings::Get().Reset(parameter);
1160     CSettings::Get().Save();
1161   }
1162   else if (execute.Equals("skin.resetsettings"))
1163   {
1164     CSkinSettings::Get().Reset();
1165     CSettings::Get().Save();
1166   }
1167   else if (execute.Equals("skin.theme"))
1168   {
1169     // enumerate themes
1170     vector<CStdString> vecTheme;
1171     CUtil::GetSkinThemes(vecTheme);
1172
1173     int iTheme = -1;
1174
1175     // find current theme
1176     if (!StringUtils::EqualsNoCase(CSettings::Get().GetString("lookandfeel.skintheme"), "SKINDEFAULT"))
1177     {
1178       for (unsigned int i=0;i<vecTheme.size();++i)
1179       {
1180         CStdString strTmpTheme(CSettings::Get().GetString("lookandfeel.skintheme"));
1181         URIUtils::RemoveExtension(strTmpTheme);
1182         if (vecTheme[i].Equals(strTmpTheme))
1183         {
1184           iTheme=i;
1185           break;
1186         }
1187       }
1188     }
1189
1190     int iParam = atoi(parameter.c_str());
1191     if (iParam == 0 || iParam == 1)
1192       iTheme++;
1193     else if (iParam == -1)
1194       iTheme--;
1195     if (iTheme > (int)vecTheme.size()-1)
1196       iTheme = -1;
1197     if (iTheme < -1)
1198       iTheme = vecTheme.size()-1;
1199
1200     CStdString strSkinTheme = "SKINDEFAULT";
1201     if (iTheme != -1 && iTheme < (int)vecTheme.size())
1202       strSkinTheme = vecTheme[iTheme];
1203
1204     CSettings::Get().SetString("lookandfeel.skintheme", strSkinTheme);
1205     // also set the default color theme
1206     CStdString colorTheme(URIUtils::ReplaceExtension(strSkinTheme, ".xml"));
1207     if (colorTheme.Equals("Textures.xml"))
1208       colorTheme = "defaults.xml";
1209     CSettings::Get().SetString("lookandfeel.skincolors", colorTheme);
1210     g_application.ReloadSkin();
1211   }
1212   else if (execute.Equals("skin.setstring") || execute.Equals("skin.setimage") || execute.Equals("skin.setfile") ||
1213            execute.Equals("skin.setpath") || execute.Equals("skin.setnumeric") || execute.Equals("skin.setlargeimage"))
1214   {
1215     // break the parameter up if necessary
1216     int string = 0;
1217     if (params.size() > 1)
1218     {
1219       string = CSkinSettings::Get().TranslateString(params[0]);
1220       if (execute.Equals("skin.setstring"))
1221       {
1222         CSkinSettings::Get().SetString(string, params[1]);
1223         CSettings::Get().Save();
1224         return 0;
1225       }
1226     }
1227     else
1228       string = CSkinSettings::Get().TranslateString(params[0]);
1229     CStdString value = CSkinSettings::Get().GetString(string);
1230     VECSOURCES localShares;
1231     g_mediaManager.GetLocalDrives(localShares);
1232     if (execute.Equals("skin.setstring"))
1233     {
1234       if (CGUIKeyboardFactory::ShowAndGetInput(value, g_localizeStrings.Get(1029), true))
1235         CSkinSettings::Get().SetString(string, value);
1236     }
1237     else if (execute.Equals("skin.setnumeric"))
1238     {
1239       if (CGUIDialogNumeric::ShowAndGetNumber(value, g_localizeStrings.Get(611)))
1240         CSkinSettings::Get().SetString(string, value);
1241     }
1242     else if (execute.Equals("skin.setimage"))
1243     {
1244       if (CGUIDialogFileBrowser::ShowAndGetImage(localShares, g_localizeStrings.Get(1030), value))
1245         CSkinSettings::Get().SetString(string, value);
1246     }
1247     else if (execute.Equals("skin.setlargeimage"))
1248     {
1249       VECSOURCES *shares = CMediaSourceSettings::Get().GetSources("pictures");
1250       if (!shares) shares = &localShares;
1251       if (CGUIDialogFileBrowser::ShowAndGetImage(*shares, g_localizeStrings.Get(1030), value))
1252         CSkinSettings::Get().SetString(string, value);
1253     }
1254     else if (execute.Equals("skin.setfile"))
1255     {
1256       // Note. can only browse one addon type from here
1257       // if browsing for addons, required param[1] is addontype string, with optional param[2]
1258       // as contenttype string see IAddon.h & ADDON::TranslateXX
1259       CStdString strMask = (params.size() > 1) ? params[1] : "";
1260       StringUtils::ToLower(strMask);
1261       ADDON::TYPE type;
1262       if ((type = TranslateType(strMask)) != ADDON_UNKNOWN)
1263       {
1264         CURL url;
1265         url.SetProtocol("addons");
1266         url.SetHostName("enabled");
1267         url.SetFileName(strMask+"/");
1268         localShares.clear();
1269         CStdString content = (params.size() > 2) ? params[2] : "";
1270         StringUtils::ToLower(content);
1271         url.SetPassword(content);
1272         CStdString strMask;
1273         if (type == ADDON_SCRIPT)
1274           strMask = ".py";
1275         CStdString replace;
1276         if (CGUIDialogFileBrowser::ShowAndGetFile(url.Get(), strMask, TranslateType(type, true), replace, true, true, true))
1277         {
1278           if (StringUtils::StartsWithNoCase(replace, "addons://"))
1279             CSkinSettings::Get().SetString(string, URIUtils::GetFileName(replace));
1280           else
1281             CSkinSettings::Get().SetString(string, replace);
1282         }
1283       }
1284       else 
1285       {
1286         if (params.size() > 2)
1287         {
1288           value = params[2];
1289           URIUtils::AddSlashAtEnd(value);
1290           bool bIsSource;
1291           if (CUtil::GetMatchingSource(value,localShares,bIsSource) < 0) // path is outside shares - add it as a separate one
1292           {
1293             CMediaSource share;
1294             share.strName = g_localizeStrings.Get(13278);
1295             share.strPath = value;
1296             localShares.push_back(share);
1297           }
1298         }
1299         if (CGUIDialogFileBrowser::ShowAndGetFile(localShares, strMask, g_localizeStrings.Get(1033), value))
1300           CSkinSettings::Get().SetString(string, value);
1301       }
1302     }
1303     else // execute.Equals("skin.setpath"))
1304     {
1305       g_mediaManager.GetNetworkLocations(localShares);
1306       if (params.size() > 1)
1307       {
1308         value = params[1];
1309         URIUtils::AddSlashAtEnd(value);
1310         bool bIsSource;
1311         if (CUtil::GetMatchingSource(value,localShares,bIsSource) < 0) // path is outside shares - add it as a separate one
1312         {
1313           CMediaSource share;
1314           share.strName = g_localizeStrings.Get(13278);
1315           share.strPath = value;
1316           localShares.push_back(share);
1317         }
1318       }
1319       if (CGUIDialogFileBrowser::ShowAndGetDirectory(localShares, g_localizeStrings.Get(1031), value))
1320         CSkinSettings::Get().SetString(string, value);
1321     }
1322     CSettings::Get().Save();
1323   }
1324   else if (execute.Equals("skin.setaddon") && params.size() > 1)
1325   {
1326     int string = CSkinSettings::Get().TranslateString(params[0]);
1327     vector<ADDON::TYPE> types;
1328     for (unsigned int i = 1 ; i < params.size() ; i++)
1329     {
1330       ADDON::TYPE type = TranslateType(params[i]);
1331       if (type != ADDON_UNKNOWN)
1332         types.push_back(type);
1333     }
1334     CStdString result;
1335     if (types.size() > 0 && CGUIWindowAddonBrowser::SelectAddonID(types, result, true) == 1)
1336     {
1337       CSkinSettings::Get().SetString(string, result);
1338       CSettings::Get().Save();
1339     }
1340   }
1341   else if (execute.Equals("dialog.close") && params.size())
1342   {
1343     bool bForce = false;
1344     if (params.size() > 1 && StringUtils::EqualsNoCase(params[1], "true"))
1345       bForce = true;
1346     if (StringUtils::EqualsNoCase(params[0], "all"))
1347     {
1348       g_windowManager.CloseDialogs(bForce);
1349     }
1350     else
1351     {
1352       int id = CButtonTranslator::TranslateWindow(params[0]);
1353       CGUIWindow *window = (CGUIWindow *)g_windowManager.GetWindow(id);
1354       if (window && window->IsDialog())
1355         ((CGUIDialog *)window)->Close(bForce);
1356     }
1357   }
1358   else if (execute.Equals("system.logoff"))
1359   {
1360     // there was a commit from cptspiff here which was reverted
1361     // for keeping the behaviour from Eden in Frodo - see
1362     // git rev 9ee5f0047b
1363     if (g_windowManager.GetActiveWindow() == WINDOW_LOGIN_SCREEN)
1364       return -1;
1365
1366     g_application.StopPlaying();
1367     if (g_application.IsMusicScanning())
1368       g_application.StopMusicScan();
1369
1370     if (g_application.IsVideoScanning())
1371       g_application.StopVideoScan();
1372
1373     ADDON::CAddonMgr::Get().StopServices(true);
1374
1375     g_application.getNetwork().NetworkMessage(CNetwork::SERVICES_DOWN,1);
1376     CProfilesManager::Get().LoadMasterProfileForLogin();
1377     g_passwordManager.bMasterUser = false;
1378     g_windowManager.ActivateWindow(WINDOW_LOGIN_SCREEN);
1379     if (!CNetworkServices::Get().StartEventServer()) // event server could be needed in some situations
1380       CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Warning, g_localizeStrings.Get(33102), g_localizeStrings.Get(33100));
1381   }
1382   else if (execute.Equals("pagedown"))
1383   {
1384     int id = atoi(parameter.c_str());
1385     CGUIMessage message(GUI_MSG_PAGE_DOWN, g_windowManager.GetFocusedWindow(), id);
1386     g_windowManager.SendMessage(message);
1387   }
1388   else if (execute.Equals("pageup"))
1389   {
1390     int id = atoi(parameter.c_str());
1391     CGUIMessage message(GUI_MSG_PAGE_UP, g_windowManager.GetFocusedWindow(), id);
1392     g_windowManager.SendMessage(message);
1393   }
1394   else if (execute.Equals("updatelibrary") && params.size())
1395   {
1396     if (params[0].Equals("music"))
1397     {
1398       if (g_application.IsMusicScanning())
1399         g_application.StopMusicScan();
1400       else
1401         g_application.StartMusicScan(params.size() > 1 ? params[1] : "");
1402     }
1403     if (params[0].Equals("video"))
1404     {
1405       if (g_application.IsVideoScanning())
1406         g_application.StopVideoScan();
1407       else
1408         g_application.StartVideoScan(params.size() > 1 ? params[1] : "");
1409     }
1410   }
1411   else if (execute.Equals("cleanlibrary"))
1412   {
1413     if (!params.size() || params[0].Equals("video"))
1414     {
1415       if (!g_application.IsVideoScanning())
1416          g_application.StartVideoCleanup();
1417       else
1418         CLog::Log(LOGERROR, "XBMC.CleanLibrary is not possible while scanning or cleaning");
1419     }
1420     else if (params[0].Equals("music"))
1421     {
1422       if (!g_application.IsMusicScanning())
1423       {
1424         CMusicDatabase musicdatabase;
1425
1426         musicdatabase.Open();
1427         musicdatabase.Cleanup();
1428         musicdatabase.Close();
1429       }
1430       else
1431         CLog::Log(LOGERROR, "XBMC.CleanLibrary is not possible while scanning for media info");
1432     }
1433   }
1434   else if (execute.Equals("exportlibrary"))
1435   {
1436     int iHeading = 647;
1437     if (params[0].Equals("music"))
1438       iHeading = 20196;
1439     CStdString path;
1440     VECSOURCES shares;
1441     g_mediaManager.GetLocalDrives(shares);
1442     g_mediaManager.GetNetworkLocations(shares);
1443     g_mediaManager.GetRemovableDrives(shares);
1444     bool singleFile;
1445     bool thumbs=false;
1446     bool actorThumbs=false;
1447     bool overwrite=false;
1448     bool cancelled=false;
1449
1450     if (params.size() > 1)
1451       singleFile = params[1].Equals("true");
1452     else
1453       singleFile = CGUIDialogYesNo::ShowAndGetInput(iHeading,20426,20427,-1,20428,20429,cancelled);
1454
1455     if (cancelled)
1456         return -1;
1457
1458     if (singleFile)
1459     {
1460       if (params.size() > 2)
1461         thumbs = params[2].Equals("true");
1462       else
1463         thumbs = CGUIDialogYesNo::ShowAndGetInput(iHeading,20430,-1,-1,cancelled);
1464     }
1465
1466     if (cancelled)
1467       return -1;
1468
1469     if (thumbs && params[0].Equals("video"))
1470     {
1471       if (params.size() > 4)
1472         actorThumbs = params[4].Equals("true");
1473       else
1474         actorThumbs = CGUIDialogYesNo::ShowAndGetInput(iHeading,20436,-1,-1,cancelled);
1475     }
1476
1477     if (cancelled)
1478       return -1;
1479
1480     if (singleFile)
1481     {
1482       if (params.size() > 3)
1483         overwrite = params[3].Equals("true");
1484       else
1485         overwrite = CGUIDialogYesNo::ShowAndGetInput(iHeading,20431,-1,-1,cancelled);
1486     }
1487
1488     if (cancelled)
1489       return -1;
1490
1491     if (params.size() > 2)
1492       path=params[2];
1493     if (singleFile || !path.empty() ||
1494         CGUIDialogFileBrowser::ShowAndGetDirectory(shares,
1495                                   g_localizeStrings.Get(661), path, true))
1496     {
1497       if (params[0].Equals("video"))
1498       {
1499         CVideoDatabase videodatabase;
1500         videodatabase.Open();
1501         videodatabase.ExportToXML(path, singleFile, thumbs, actorThumbs, overwrite);
1502         videodatabase.Close();
1503       }
1504       else
1505       {
1506         if (URIUtils::HasSlashAtEnd(path))
1507           path = URIUtils::AddFileToFolder(path, "musicdb.xml");
1508         CMusicDatabase musicdatabase;
1509         musicdatabase.Open();
1510         musicdatabase.ExportToXML(path, singleFile, thumbs, overwrite);
1511         musicdatabase.Close();
1512       }
1513     }
1514   }
1515   else if (execute.Equals("control.move") && params.size() > 1)
1516   {
1517     CGUIMessage message(GUI_MSG_MOVE_OFFSET, g_windowManager.GetFocusedWindow(), atoi(params[0].c_str()), atoi(params[1].c_str()));
1518     g_windowManager.SendMessage(message);
1519   }
1520   else if (execute.Equals("container.refresh"))
1521   { // NOTE: These messages require a media window, thus they're sent to the current activewindow.
1522     //       This shouldn't stop a dialog intercepting it though.
1523     CGUIMessage message(GUI_MSG_NOTIFY_ALL, g_windowManager.GetActiveWindow(), 0, GUI_MSG_UPDATE, 1); // 1 to reset the history
1524     message.SetStringParam(parameter);
1525     g_windowManager.SendMessage(message);
1526   }
1527   else if (execute.Equals("container.update") && params.size())
1528   {
1529     CGUIMessage message(GUI_MSG_NOTIFY_ALL, g_windowManager.GetActiveWindow(), 0, GUI_MSG_UPDATE, 0);
1530     message.SetStringParam(params[0]);
1531     if (params.size() > 1 && StringUtils::EqualsNoCase(params[1], "replace"))
1532       message.SetParam2(1); // reset the history
1533     g_windowManager.SendMessage(message);
1534   }
1535   else if (execute.Equals("container.nextviewmode"))
1536   {
1537     CGUIMessage message(GUI_MSG_CHANGE_VIEW_MODE, g_windowManager.GetActiveWindow(), 0, 0, 1);
1538     g_windowManager.SendMessage(message);
1539   }
1540   else if (execute.Equals("container.previousviewmode"))
1541   {
1542     CGUIMessage message(GUI_MSG_CHANGE_VIEW_MODE, g_windowManager.GetActiveWindow(), 0, 0, -1);
1543     g_windowManager.SendMessage(message);
1544   }
1545   else if (execute.Equals("container.setviewmode"))
1546   {
1547     CGUIMessage message(GUI_MSG_CHANGE_VIEW_MODE, g_windowManager.GetActiveWindow(), 0, atoi(parameter.c_str()));
1548     g_windowManager.SendMessage(message);
1549   }
1550   else if (execute.Equals("container.nextsortmethod"))
1551   {
1552     CGUIMessage message(GUI_MSG_CHANGE_SORT_METHOD, g_windowManager.GetActiveWindow(), 0, 0, 1);
1553     g_windowManager.SendMessage(message);
1554   }
1555   else if (execute.Equals("container.previoussortmethod"))
1556   {
1557     CGUIMessage message(GUI_MSG_CHANGE_SORT_METHOD, g_windowManager.GetActiveWindow(), 0, 0, -1);
1558     g_windowManager.SendMessage(message);
1559   }
1560   else if (execute.Equals("container.setsortmethod"))
1561   {
1562     CGUIMessage message(GUI_MSG_CHANGE_SORT_METHOD, g_windowManager.GetActiveWindow(), 0, atoi(parameter.c_str()));
1563     g_windowManager.SendMessage(message);
1564   }
1565   else if (execute.Equals("container.sortdirection"))
1566   {
1567     CGUIMessage message(GUI_MSG_CHANGE_SORT_DIRECTION, g_windowManager.GetActiveWindow(), 0, 0);
1568     g_windowManager.SendMessage(message);
1569   }
1570   else if (execute.Equals("control.message") && params.size() >= 2)
1571   {
1572     int controlID = atoi(params[0].c_str());
1573     int windowID = (params.size() == 3) ? CButtonTranslator::TranslateWindow(params[2]) : g_windowManager.GetActiveWindow();
1574     if (params[1] == "moveup")
1575       g_windowManager.SendMessage(GUI_MSG_MOVE_OFFSET, windowID, controlID, 1);
1576     else if (params[1] == "movedown")
1577       g_windowManager.SendMessage(GUI_MSG_MOVE_OFFSET, windowID, controlID, -1);
1578     else if (params[1] == "pageup")
1579       g_windowManager.SendMessage(GUI_MSG_PAGE_UP, windowID, controlID);
1580     else if (params[1] == "pagedown")
1581       g_windowManager.SendMessage(GUI_MSG_PAGE_DOWN, windowID, controlID);
1582     else if (params[1] == "click")
1583       g_windowManager.SendMessage(GUI_MSG_CLICKED, controlID, windowID);
1584   }
1585   else if (execute.Equals("sendclick") && params.size())
1586   {
1587     if (params.size() == 2)
1588     {
1589       // have a window - convert it
1590       int windowID = CButtonTranslator::TranslateWindow(params[0]);
1591       CGUIMessage message(GUI_MSG_CLICKED, atoi(params[1].c_str()), windowID);
1592       g_windowManager.SendMessage(message);
1593     }
1594     else
1595     { // single param - assume you meant the active window
1596       CGUIMessage message(GUI_MSG_CLICKED, atoi(params[0].c_str()), g_windowManager.GetActiveWindow());
1597       g_windowManager.SendMessage(message);
1598     }
1599   }
1600   else if (execute.Equals("action") && params.size())
1601   {
1602     // try translating the action from our ButtonTranslator
1603     int actionID;
1604     if (CButtonTranslator::TranslateActionString(params[0].c_str(), actionID))
1605     {
1606       int windowID = params.size() == 2 ? CButtonTranslator::TranslateWindow(params[1]) : WINDOW_INVALID;
1607       CApplicationMessenger::Get().SendAction(CAction(actionID), windowID);
1608     }
1609   }
1610   else if (execute.Equals("setproperty") && params.size() >= 2)
1611   {
1612     CGUIWindow *window = g_windowManager.GetWindow(params.size() > 2 ? CButtonTranslator::TranslateWindow(params[2]) : g_windowManager.GetFocusedWindow());
1613     if (window)
1614       window->SetProperty(params[0],params[1]);
1615   }
1616   else if (execute.Equals("clearproperty") && params.size())
1617   {
1618     CGUIWindow *window = g_windowManager.GetWindow(params.size() > 1 ? CButtonTranslator::TranslateWindow(params[1]) : g_windowManager.GetFocusedWindow());
1619     if (window)
1620       window->SetProperty(params[0],"");
1621   }
1622   else if (execute.Equals("wakeonlan"))
1623   {
1624     g_application.getNetwork().WakeOnLan((char*)params[0].c_str());
1625   }
1626   else if (execute.Equals("addon.default.opensettings") && params.size() == 1)
1627   {
1628     AddonPtr addon;
1629     ADDON::TYPE type = TranslateType(params[0]);
1630     if (CAddonMgr::Get().GetDefault(type, addon))
1631     {
1632       CGUIDialogAddonSettings::ShowAndGetInput(addon);
1633       if (type == ADDON_VIZ)
1634         g_windowManager.SendMessage(GUI_MSG_VISUALISATION_RELOAD, 0, 0);
1635     }
1636   }
1637   else if (execute.Equals("addon.default.set") && params.size() == 1)
1638   {
1639     CStdString addonID;
1640     TYPE type = TranslateType(params[0]);
1641     bool allowNone = false;
1642     if (type == ADDON_VIZ)
1643       allowNone = true;
1644
1645     if (type != ADDON_UNKNOWN && 
1646         CGUIWindowAddonBrowser::SelectAddonID(type,addonID,allowNone))
1647     {
1648       CAddonMgr::Get().SetDefault(type,addonID);
1649       if (type == ADDON_VIZ)
1650         g_windowManager.SendMessage(GUI_MSG_VISUALISATION_RELOAD, 0, 0);
1651     }
1652   }
1653   else if (execute.Equals("addon.opensettings") && params.size() == 1)
1654   {
1655     AddonPtr addon;
1656     if (CAddonMgr::Get().GetAddon(params[0], addon))
1657       CGUIDialogAddonSettings::ShowAndGetInput(addon);
1658   }
1659   else if (execute.Equals("updateaddonrepos"))
1660   {
1661     CAddonInstaller::Get().UpdateRepos(true);
1662   }
1663   else if (execute.Equals("updatelocaladdons"))
1664   {
1665     CAddonMgr::Get().FindAddons();
1666   }
1667   else if (execute.Equals("toggledpms"))
1668   {
1669     g_application.ToggleDPMS(true);
1670   }
1671   else if (execute.Equals("cectogglestate"))
1672   {
1673     CApplicationMessenger::Get().CECToggleState();
1674   }
1675   else if (execute.Equals("cecactivatesource"))
1676   {
1677     CApplicationMessenger::Get().CECActivateSource();
1678   }
1679   else if (execute.Equals("cecstandby"))
1680   {
1681     CApplicationMessenger::Get().CECStandby();
1682   }
1683 #if defined(HAS_LIRC) || defined(HAS_IRSERVERSUITE)
1684   else if (execute.Equals("lirc.stop"))
1685   {
1686     g_RemoteControl.Disconnect();
1687     g_RemoteControl.setUsed(false);
1688   }
1689   else if (execute.Equals("lirc.start"))
1690   {
1691     g_RemoteControl.setUsed(true);
1692     g_RemoteControl.Initialize();
1693   }
1694   else if (execute.Equals("lirc.send"))
1695   {
1696     CStdString command;
1697     for (int i = 0; i < (int)params.size(); i++)
1698     {
1699       command += params[i];
1700       if (i < (int)params.size() - 1)
1701         command += ' ';
1702     }
1703     g_RemoteControl.AddSendCommand(command);
1704   }
1705 #endif
1706   else if (execute.Equals("weather.locationset"))
1707   {
1708     int loc = atoi(params[0]);
1709     CGUIMessage msg(GUI_MSG_ITEM_SELECT, 0, 0, loc);
1710     g_windowManager.SendMessage(msg, WINDOW_WEATHER);
1711   }
1712   else if (execute.Equals("weather.locationnext"))
1713   {
1714     CGUIMessage msg(GUI_MSG_MOVE_OFFSET, 0, 0, 1);
1715     g_windowManager.SendMessage(msg, WINDOW_WEATHER);
1716   }
1717   else if (execute.Equals("weather.locationprevious"))
1718   {
1719     CGUIMessage msg(GUI_MSG_MOVE_OFFSET, 0, 0, -1);
1720     g_windowManager.SendMessage(msg, WINDOW_WEATHER);
1721   }
1722   else if (execute.Equals("weather.refresh"))
1723   {
1724     CGUIMessage msg(GUI_MSG_MOVE_OFFSET, 0, 0, 0);
1725     g_windowManager.SendMessage(msg, WINDOW_WEATHER);
1726   }
1727   else if (execute.Equals("videolibrary.search"))
1728   {
1729     CGUIMessage msg(GUI_MSG_SEARCH, 0, 0, 0);
1730     g_windowManager.SendMessage(msg, WINDOW_VIDEO_NAV);
1731   }
1732   else if (execute.Equals("toggledebug"))
1733   {
1734     bool debug = CSettings::Get().GetBool("debug.showloginfo");
1735     CSettings::Get().SetBool("debug.showloginfo", !debug);
1736     g_advancedSettings.SetDebugMode(!debug);
1737   }
1738   else if (execute.Equals("startpvrmanager"))
1739   {
1740     g_application.StartPVRManager();
1741   }
1742   else if (execute.Equals("stoppvrmanager"))
1743   {
1744     g_application.StopPVRManager();
1745   }
1746   else if (execute.Equals("StartAndroidActivity") && params.size() > 0)
1747   {
1748     CApplicationMessenger::Get().StartAndroidActivity(params);
1749   }
1750   else if (execute.Equals("SetStereoMode") && !parameter.empty())
1751   {
1752     CAction action = CStereoscopicsManager::Get().ConvertActionCommandToAction(execute, parameter);
1753     if (action.GetID() != ACTION_NONE)
1754       CApplicationMessenger::Get().SendAction(action);
1755     else
1756     {
1757       CLog::Log(LOGERROR,"Builtin 'SetStereoMode' called with unknown parameter: %s", parameter.c_str());
1758       return -2;
1759     }
1760   }
1761   else
1762     return -1;
1763   return 0;
1764 }