Merge pull request #3507 from jmarshallnz/kill_cstdstring
[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 #if defined(TARGET_DARWIN_IOS)
396       if (params[0].Equals("shutdownmenu"))
397         CBuiltins::Execute("Quit");
398 #endif     
399       g_windowManager.ActivateWindow(iWindow, params, !execute.Equals("activatewindow"));
400     }
401     else
402     {
403       CLog::Log(LOGERROR, "Activate/ReplaceWindow called with invalid destination window: %s", strWindow.c_str());
404       return false;
405     }
406   }
407   else if ((execute.Equals("setfocus") || execute.Equals("control.setfocus")) && params.size())
408   {
409     int controlID = atol(params[0].c_str());
410     int subItem = (params.size() > 1) ? atol(params[1].c_str())+1 : 0;
411     CGUIMessage msg(GUI_MSG_SETFOCUS, g_windowManager.GetFocusedWindow(), controlID, subItem);
412     g_windowManager.SendMessage(msg);
413   }
414   else if ((execute.Equals("activatewindowandfocus") || execute.Equals("replacewindowandfocus")) && params.size())
415   {
416     CStdString strWindow = params[0];
417
418     // confirm the window destination is valid prior to switching
419     int iWindow = CButtonTranslator::TranslateWindow(strWindow);
420     if (iWindow != WINDOW_INVALID)
421     {
422       // disable the screensaver
423       g_application.WakeUpScreenSaverAndDPMS();
424 #if defined(TARGET_DARWIN_IOS)
425       if (params[0].Equals("shutdownmenu"))
426         CBuiltins::Execute("Quit");
427 #endif
428       vector<CStdString> dummy;
429       g_windowManager.ActivateWindow(iWindow, dummy, !execute.Equals("activatewindowandfocus"));
430
431       unsigned int iPtr = 1;
432       while (params.size() > iPtr + 1)
433       {
434         CGUIMessage msg(GUI_MSG_SETFOCUS, g_windowManager.GetFocusedWindow(),
435             atol(params[iPtr].c_str()),
436             (params.size() >= iPtr + 2) ? atol(params[iPtr + 1].c_str())+1 : 0);
437         g_windowManager.SendMessage(msg);
438         iPtr += 2;
439       }
440     }
441     else
442     {
443       CLog::Log(LOGERROR, "Replace/ActivateWindowAndFocus called with invalid destination window: %s", strWindow.c_str());
444       return false;
445     }
446   }
447   else if (execute.Equals("runscript") && params.size())
448   {
449 #if defined(TARGET_DARWIN_OSX)
450     if (URIUtils::HasExtension(strParameterCaseIntact, ".applescript|.scpt"))
451     {
452       CStdString osxPath = CSpecialProtocol::TranslatePath(strParameterCaseIntact);
453       Cocoa_DoAppleScriptFile(osxPath.c_str());
454     }
455     else
456 #endif
457     {
458       vector<string> argv;
459       for (vector<CStdString>::const_iterator param = params.begin(); param != params.end(); ++param)
460         argv.push_back(*param);
461
462       vector<CStdString> path;
463       //split the path up to find the filename
464       StringUtils::SplitString(params[0],"\\",path);
465       if (path.size())
466         argv[0] = path[path.size() - 1];
467
468       AddonPtr script;
469       CStdString scriptpath(params[0]);
470       if (CAddonMgr::Get().GetAddon(params[0], script))
471         scriptpath = script->LibPath();
472
473       CScriptInvocationManager::Get().Execute(scriptpath, script, argv);
474     }
475   }
476 #if defined(TARGET_DARWIN_OSX)
477   else if (execute.Equals("runapplescript"))
478   {
479     Cocoa_DoAppleScript(strParameterCaseIntact.c_str());
480   }
481 #endif
482   else if (execute.Equals("stopscript"))
483   {
484     CStdString scriptpath(params[0]);
485
486     // Test to see if the param is an addon ID
487     AddonPtr script;
488     if (CAddonMgr::Get().GetAddon(params[0], script))
489       scriptpath = script->LibPath();
490
491     CScriptInvocationManager::Get().Stop(scriptpath);
492   }
493   else if (execute.Equals("system.exec"))
494   {
495     CApplicationMessenger::Get().Minimize();
496     CApplicationMessenger::Get().ExecOS(parameter, false);
497   }
498   else if (execute.Equals("system.execwait"))
499   {
500     CApplicationMessenger::Get().Minimize();
501     CApplicationMessenger::Get().ExecOS(parameter, true);
502   }
503   else if (execute.Equals("resolution"))
504   {
505     RESOLUTION res = RES_PAL_4x3;
506     if (parameter.Equals("pal")) res = RES_PAL_4x3;
507     else if (parameter.Equals("pal16x9")) res = RES_PAL_16x9;
508     else if (parameter.Equals("ntsc")) res = RES_NTSC_4x3;
509     else if (parameter.Equals("ntsc16x9")) res = RES_NTSC_16x9;
510     else if (parameter.Equals("720p")) res = RES_HDTV_720p;
511     else if (parameter.Equals("720pSBS")) res = RES_HDTV_720pSBS;
512     else if (parameter.Equals("720pTB")) res = RES_HDTV_720pTB;
513     else if (parameter.Equals("1080pSBS")) res = RES_HDTV_1080pSBS;
514     else if (parameter.Equals("1080pTB")) res = RES_HDTV_1080pTB;
515     else if (parameter.Equals("1080i")) res = RES_HDTV_1080i;
516     if (g_graphicsContext.IsValidResolution(res))
517     {
518       CDisplaySettings::Get().SetCurrentResolution(res, true);
519       g_application.ReloadSkin();
520     }
521   }
522   else if (execute.Equals("extract") && params.size())
523   {
524     // Detects if file is zip or rar then extracts
525     CStdString strDestDirect;
526     if (params.size() < 2)
527       strDestDirect = URIUtils::GetDirectory(params[0]);
528     else
529       strDestDirect = params[1];
530
531     URIUtils::AddSlashAtEnd(strDestDirect);
532
533     if (URIUtils::IsZIP(params[0]))
534       g_ZipManager.ExtractArchive(params[0],strDestDirect);
535 #ifdef HAS_FILESYSTEM_RAR
536     else if (URIUtils::IsRAR(params[0]))
537       g_RarManager.ExtractArchive(params[0],strDestDirect);
538 #endif
539     else
540       CLog::Log(LOGERROR, "XBMC.Extract, No archive given");
541   }
542   else if (execute.Equals("runplugin"))
543   {
544     if (params.size())
545     {
546       CFileItem item(params[0]);
547       if (!item.m_bIsFolder)
548       {
549         item.SetPath(params[0]);
550         CPluginDirectory::RunScriptWithParams(item.GetPath());
551       }
552     }
553     else
554     {
555       CLog::Log(LOGERROR, "XBMC.RunPlugin called with no arguments.");
556     }
557   }
558   else if (execute.Equals("runaddon"))
559   {
560     if (params.size())
561     {
562       AddonPtr addon;
563       if (CAddonMgr::Get().GetAddon(params[0],addon) && addon)
564       {
565         PluginPtr plugin = boost::dynamic_pointer_cast<CPluginSource>(addon);
566         CStdString cmd;
567         if (plugin && addon->Type() == ADDON_PLUGIN)
568         {
569           CStdString addonid = params[0];
570           CStdString urlParameters;
571           CStdStringArray parameters;
572           if (params.size() == 2 &&
573              (StringUtils::StartsWith(params[1], "/") || StringUtils::StartsWith(params[1], "?")))
574             urlParameters = params[1];
575           else if (params.size() > 1)
576           {
577             parameters.insert(parameters.begin(), params.begin() + 1, params.end());
578             urlParameters = "?" + StringUtils::JoinString(parameters, "&");
579           }
580
581           if (plugin->Provides(CPluginSource::VIDEO))
582             cmd = StringUtils::Format("ActivateWindow(Video,plugin://%s%s,return)", addonid.c_str(), urlParameters.c_str());
583           else if (plugin->Provides(CPluginSource::AUDIO))
584             cmd = StringUtils::Format("ActivateWindow(Music,plugin://%s%s,return)", addonid.c_str(), urlParameters.c_str());
585           else if (plugin->Provides(CPluginSource::EXECUTABLE))
586             cmd = StringUtils::Format("ActivateWindow(Programs,plugin://%s%s,return)", addonid.c_str(), urlParameters.c_str());
587           else if (plugin->Provides(CPluginSource::IMAGE))
588             cmd = StringUtils::Format("ActivateWindow(Pictures,plugin://%s%s,return)", addonid.c_str(), urlParameters.c_str());
589           else
590             // Pass the script name (params[0]) and all the parameters
591             // (params[1] ... params[x]) separated by a comma to RunPlugin
592             cmd = StringUtils::Format("RunPlugin(%s)", StringUtils::JoinString(params, ",").c_str());
593         }
594         else if (addon->Type() >= ADDON_SCRIPT && addon->Type() <= ADDON_SCRIPT_LYRICS)
595           // Pass the script name (params[0]) and all the parameters
596           // (params[1] ... params[x]) separated by a comma to RunScript
597           cmd = StringUtils::Format("RunScript(%s)", StringUtils::JoinString(params, ",").c_str());
598
599         return Execute(cmd);
600       }
601     }
602     else
603     {
604       CLog::Log(LOGERROR, "XBMC.RunAddon called with no arguments.");
605     }
606   }
607   else if (execute.Equals("notifyall"))
608   {
609     if (params.size() > 1)
610     {
611       CVariant data;
612       if (params.size() > 2)
613         data = CJSONVariantParser::Parse((const unsigned char *)params[2].c_str(), params[2].size());
614
615       ANNOUNCEMENT::CAnnouncementManager::Announce(ANNOUNCEMENT::Other, params[0], params[1], data);
616     }
617     else
618       CLog::Log(LOGERROR, "XBMC.NotifyAll needs two parameters");
619   }
620   else if (execute.Equals("playmedia"))
621   {
622     if (!params.size())
623     {
624       CLog::Log(LOGERROR, "XBMC.PlayMedia called with empty parameter");
625       return -3;
626     }
627
628     CFileItem item(params[0], false);
629     if (URIUtils::HasSlashAtEnd(params[0]))
630       item.m_bIsFolder = true;
631
632     // restore to previous window if needed
633     if( g_windowManager.GetActiveWindow() == WINDOW_SLIDESHOW ||
634         g_windowManager.GetActiveWindow() == WINDOW_FULLSCREEN_VIDEO ||
635         g_windowManager.GetActiveWindow() == WINDOW_VISUALISATION )
636         g_windowManager.PreviousWindow();
637
638     // reset screensaver
639     g_application.ResetScreenSaver();
640     g_application.WakeUpScreenSaverAndDPMS();
641
642     // ask if we need to check guisettings to resume
643     bool askToResume = true;
644     int playOffset = 0;
645     for (unsigned int i = 1 ; i < params.size() ; i++)
646     {
647       if (params[i].Equals("isdir"))
648         item.m_bIsFolder = true;
649       else if (params[i].Equals("1")) // set fullscreen or windowed
650         CMediaSettings::Get().SetVideoStartWindowed(true);
651       else if (params[i].Equals("resume"))
652       {
653         // force the item to resume (if applicable) (see CApplication::PlayMedia)
654         item.m_lStartOffset = STARTOFFSET_RESUME;
655         askToResume = false;
656       }
657       else if (params[i].Equals("noresume"))
658       {
659         // force the item to start at the beginning (m_lStartOffset is initialized to 0)
660         askToResume = false;
661       }
662       else if (StringUtils::StartsWithNoCase(params[i], "playoffset=")) {
663         playOffset = atoi(params[i].substr(11).c_str()) - 1;
664         item.SetProperty("playlist_starting_track", playOffset);
665       }
666     }
667
668     if (!item.m_bIsFolder && item.IsPlugin())
669       item.SetProperty("IsPlayable", true);
670
671     if ( askToResume == true )
672     {
673       if ( CGUIWindowVideoBase::ShowResumeMenu(item) == false )
674         return false;
675     }
676     if (item.m_bIsFolder)
677     {
678       CFileItemList items;
679       CStdString extensions = g_advancedSettings.m_videoExtensions + "|" + g_advancedSettings.m_musicExtensions;
680       CDirectory::GetDirectory(item.GetPath(),items,extensions);
681       
682       bool containsMusic = false, containsVideo = false;
683       for (int i = 0; i < items.Size(); i++)
684       {
685         bool isVideo = items[i]->IsVideo();
686         containsMusic |= !isVideo;
687         containsVideo |= isVideo;
688         
689         if (containsMusic && containsVideo)
690           break;
691       }
692       
693       int playlist = containsVideo? PLAYLIST_VIDEO : PLAYLIST_MUSIC;;
694       if (containsMusic && containsVideo) //mixed content found in the folder
695       {
696         for (int i = items.Size() - 1; i >= 0; i--) //remove music entries
697         {
698           if (!items[i]->IsVideo())
699             items.Remove(i);
700         }
701       }
702       
703       g_playlistPlayer.ClearPlaylist(playlist);
704       g_playlistPlayer.Add(playlist, items);
705       g_playlistPlayer.SetCurrentPlaylist(playlist);
706       g_playlistPlayer.Play(playOffset);
707     }
708     else
709     {
710       int playlist = item.IsAudio() ? PLAYLIST_MUSIC : PLAYLIST_VIDEO;
711       g_playlistPlayer.ClearPlaylist(playlist);
712       g_playlistPlayer.SetCurrentPlaylist(playlist);
713
714       // play media
715       if (!g_application.PlayMedia(item, playlist))
716       {
717         CLog::Log(LOGERROR, "XBMC.PlayMedia could not play media: %s", params[0].c_str());
718         return false;
719       }
720     }
721   }
722   else if (execute.Equals("showPicture"))
723   {
724     if (!params.size())
725     {
726       CLog::Log(LOGERROR, "XBMC.ShowPicture called with empty parameter");
727       return -2;
728     }
729     CGUIMessage msg(GUI_MSG_SHOW_PICTURE, 0, 0);
730     msg.SetStringParam(params[0]);
731     CGUIWindow *pWindow = g_windowManager.GetWindow(WINDOW_SLIDESHOW);
732     if (pWindow) pWindow->OnMessage(msg);
733   }
734   else if (execute.Equals("slideShow") || execute.Equals("recursiveslideShow"))
735   {
736     if (!params.size())
737     {
738       CLog::Log(LOGERROR, "XBMC.SlideShow called with empty parameter");
739       return -2;
740     }
741     std::string beginSlidePath;
742     // leave RecursiveSlideShow command as-is
743     unsigned int flags = 0;
744     if (execute.Equals("RecursiveSlideShow"))
745       flags |= 1;
746
747     // SlideShow(dir[,recursive][,[not]random][,pause][,beginslide="/path/to/start/slide.jpg"])
748     // the beginslide value need be escaped (for '"' or '\' in it, by backslash)
749     // and then quoted, or not. See CUtil::SplitParams()
750     else
751     {
752       for (unsigned int i = 1 ; i < params.size() ; i++)
753       {
754         if (params[i].Equals("recursive"))
755           flags |= 1;
756         else if (params[i].Equals("random")) // set fullscreen or windowed
757           flags |= 2;
758         else if (params[i].Equals("notrandom"))
759           flags |= 4;
760         else if (params[i].Equals("pause"))
761           flags |= 8;
762         else if (StringUtils::StartsWithNoCase(params[i], "beginslide="))
763           beginSlidePath = params[i].substr(11);
764       }
765     }
766
767     CGUIMessage msg(GUI_MSG_START_SLIDESHOW, 0, 0, flags);
768     vector<CStdString> strParams;
769     strParams.push_back(params[0]);
770     strParams.push_back(beginSlidePath);
771     msg.SetStringParams(strParams);
772     CGUIWindow *pWindow = g_windowManager.GetWindow(WINDOW_SLIDESHOW);
773     if (pWindow) pWindow->OnMessage(msg);
774   }
775   else if (execute.Equals("reloadskin"))
776   {
777     //  Reload the skin
778     g_application.ReloadSkin(!params.empty() && StringUtils::EqualsNoCase(params[0], "confirm"));
779   }
780   else if (execute.Equals("unloadskin"))
781   {
782     g_application.UnloadSkin(true); // we're reloading the skin after this
783   }
784   else if (execute.Equals("refreshrss"))
785   {
786     CRssManager::Get().Reload();
787   }
788   else if (execute.Equals("playercontrol"))
789   {
790     g_application.ResetScreenSaver();
791     g_application.WakeUpScreenSaverAndDPMS();
792     if (!params.size())
793     {
794       CLog::Log(LOGERROR, "XBMC.PlayerControl called with empty parameter");
795       return -3;
796     }
797     if (parameter.Equals("play"))
798     { // play/pause
799       // either resume playing, or pause
800       if (g_application.m_pPlayer->IsPlaying())
801       {
802         if (g_application.m_pPlayer->GetPlaySpeed() != 1)
803           g_application.m_pPlayer->SetPlaySpeed(1, g_application.IsMutedInternal());
804         else
805           g_application.m_pPlayer->Pause();
806       }
807     }
808     else if (parameter.Equals("stop"))
809     {
810       g_application.StopPlaying();
811     }
812     else if (parameter.Equals("rewind") || parameter.Equals("forward"))
813     {
814       if (g_application.m_pPlayer->IsPlaying() && !g_application.m_pPlayer->IsPaused())
815       {
816         int iPlaySpeed = g_application.m_pPlayer->GetPlaySpeed();
817         if (parameter.Equals("rewind") && iPlaySpeed == 1) // Enables Rewinding
818           iPlaySpeed *= -2;
819         else if (parameter.Equals("rewind") && iPlaySpeed > 1) //goes down a notch if you're FFing
820           iPlaySpeed /= 2;
821         else if (parameter.Equals("forward") && iPlaySpeed < 1) //goes up a notch if you're RWing
822         {
823           iPlaySpeed /= 2;
824           if (iPlaySpeed == -1) iPlaySpeed = 1;
825         }
826         else
827           iPlaySpeed *= 2;
828
829         if (iPlaySpeed > 32 || iPlaySpeed < -32)
830           iPlaySpeed = 1;
831
832         g_application.m_pPlayer->SetPlaySpeed(iPlaySpeed, g_application.IsMutedInternal());
833       }
834     }
835     else if (parameter.Equals("next"))
836     {
837       g_application.OnAction(CAction(ACTION_NEXT_ITEM));
838     }
839     else if (parameter.Equals("previous"))
840     {
841       g_application.OnAction(CAction(ACTION_PREV_ITEM));
842     }
843     else if (parameter.Equals("bigskipbackward"))
844     {
845       if (g_application.m_pPlayer->IsPlaying())
846         g_application.m_pPlayer->Seek(false, true);
847     }
848     else if (parameter.Equals("bigskipforward"))
849     {
850       if (g_application.m_pPlayer->IsPlaying())
851         g_application.m_pPlayer->Seek(true, true);
852     }
853     else if (parameter.Equals("smallskipbackward"))
854     {
855       if (g_application.m_pPlayer->IsPlaying())
856         g_application.m_pPlayer->Seek(false, false);
857     }
858     else if (parameter.Equals("smallskipforward"))
859     {
860       if (g_application.m_pPlayer->IsPlaying())
861         g_application.m_pPlayer->Seek(true, false);
862     }
863     else if (StringUtils::StartsWithNoCase(parameter, "seekpercentage"))
864     {
865       CStdString offset = "";
866       if (parameter.size() == 14)
867         CLog::Log(LOGERROR,"PlayerControl(seekpercentage(n)) called with no argument");
868       else if (parameter.size() < 17) // arg must be at least "(N)"
869         CLog::Log(LOGERROR,"PlayerControl(seekpercentage(n)) called with invalid argument: \"%s\"", parameter.substr(14).c_str());
870       else
871       {
872         // Don't bother checking the argument: an invalid arg will do seek(0)
873         offset = parameter.substr(15);
874         StringUtils::TrimRight(offset, ")");
875         float offsetpercent = (float) atof(offset.c_str());
876         if (offsetpercent < 0 || offsetpercent > 100)
877           CLog::Log(LOGERROR,"PlayerControl(seekpercentage(n)) argument, %f, must be 0-100", offsetpercent);
878         else if (g_application.m_pPlayer->IsPlaying())
879           g_application.SeekPercentage(offsetpercent);
880       }
881     }
882     else if( parameter.Equals("showvideomenu") )
883     {
884       if( g_application.m_pPlayer->IsPlaying() )
885         g_application.m_pPlayer->OnAction(CAction(ACTION_SHOW_VIDEOMENU));
886     }
887     else if( parameter.Equals("record") )
888     {
889       if( g_application.m_pPlayer->IsPlaying() && g_application.m_pPlayer->CanRecord())
890         g_application.m_pPlayer->Record(!g_application.m_pPlayer->IsRecording());
891     }
892     else if (StringUtils::StartsWithNoCase(parameter, "partymode"))
893     {
894       CStdString strXspPath = "";
895       //empty param=music, "music"=music, "video"=video, else xsp path
896       PartyModeContext context = PARTYMODECONTEXT_MUSIC;
897       if (parameter.size() > 9)
898       {
899         if (parameter.size() == 16 && StringUtils::EndsWithNoCase(parameter, "video)"))
900           context = PARTYMODECONTEXT_VIDEO;
901         else if (parameter.size() != 16 || !StringUtils::EndsWithNoCase(parameter, "music)"))
902         {
903           strXspPath = parameter.substr(10);
904           StringUtils::TrimRight(strXspPath, ")");
905           context = PARTYMODECONTEXT_UNKNOWN;
906         }
907       }
908       if (g_partyModeManager.IsEnabled())
909         g_partyModeManager.Disable();
910       else
911         g_partyModeManager.Enable(context, strXspPath);
912     }
913     else if (parameter.Equals("random")    ||
914              parameter.Equals("randomoff") ||
915              parameter.Equals("randomon"))
916     {
917       // get current playlist
918       int iPlaylist = g_playlistPlayer.GetCurrentPlaylist();
919
920       // reverse the current setting
921       bool shuffled = g_playlistPlayer.IsShuffled(iPlaylist);
922       if ((shuffled && parameter.Equals("randomon")) || (!shuffled && parameter.Equals("randomoff")))
923         return 0;
924
925       // check to see if we should notify the user
926       bool notify = (params.size() == 2 && params[1].Equals("notify"));
927       g_playlistPlayer.SetShuffle(iPlaylist, !shuffled, notify);
928
929       // save settings for now playing windows
930       switch (iPlaylist)
931       {
932       case PLAYLIST_MUSIC:
933         CMediaSettings::Get().SetMusicPlaylistShuffled(g_playlistPlayer.IsShuffled(iPlaylist));
934         CSettings::Get().Save();
935         break;
936       case PLAYLIST_VIDEO:
937         CMediaSettings::Get().SetVideoPlaylistShuffled(g_playlistPlayer.IsShuffled(iPlaylist));
938         CSettings::Get().Save();
939       }
940
941       // send message
942       CGUIMessage msg(GUI_MSG_PLAYLISTPLAYER_RANDOM, 0, 0, iPlaylist, g_playlistPlayer.IsShuffled(iPlaylist));
943       g_windowManager.SendThreadMessage(msg);
944
945     }
946     else if (StringUtils::StartsWithNoCase(parameter, "repeat"))
947     {
948       // get current playlist
949       int iPlaylist = g_playlistPlayer.GetCurrentPlaylist();
950       PLAYLIST::REPEAT_STATE previous_state = g_playlistPlayer.GetRepeat(iPlaylist);
951
952       PLAYLIST::REPEAT_STATE state;
953       if (parameter.Equals("repeatall"))
954         state = PLAYLIST::REPEAT_ALL;
955       else if (parameter.Equals("repeatone"))
956         state = PLAYLIST::REPEAT_ONE;
957       else if (parameter.Equals("repeatoff"))
958         state = PLAYLIST::REPEAT_NONE;
959       else if (previous_state == PLAYLIST::REPEAT_NONE)
960         state = PLAYLIST::REPEAT_ALL;
961       else if (previous_state == PLAYLIST::REPEAT_ALL)
962         state = PLAYLIST::REPEAT_ONE;
963       else
964         state = PLAYLIST::REPEAT_NONE;
965
966       if (state == previous_state)
967         return 0;
968
969       // check to see if we should notify the user
970       bool notify = (params.size() == 2 && params[1].Equals("notify"));
971       g_playlistPlayer.SetRepeat(iPlaylist, state, notify);
972
973       // save settings for now playing windows
974       switch (iPlaylist)
975       {
976       case PLAYLIST_MUSIC:
977         CMediaSettings::Get().SetMusicPlaylistRepeat(state == PLAYLIST::REPEAT_ALL);
978         CSettings::Get().Save();
979         break;
980       case PLAYLIST_VIDEO:
981         CMediaSettings::Get().SetVideoPlaylistRepeat(state == PLAYLIST::REPEAT_ALL);
982         CSettings::Get().Save();
983       }
984
985       // send messages so now playing window can get updated
986       CGUIMessage msg(GUI_MSG_PLAYLISTPLAYER_REPEAT, 0, 0, iPlaylist, (int)state);
987       g_windowManager.SendThreadMessage(msg);
988     }
989   }
990   else if (execute.Equals("playwith"))
991   {
992     g_application.m_eForcedNextPlayer = CPlayerCoreFactory::Get().GetPlayerCore(parameter);
993     g_application.OnAction(CAction(ACTION_PLAYER_PLAY));
994   }
995   else if (execute.Equals("mute"))
996   {
997     g_application.ToggleMute();
998   }
999   else if (execute.Equals("setvolume"))
1000   {
1001     float oldVolume = g_application.GetVolume();
1002     float volume = (float)strtod(parameter.c_str(), NULL);
1003
1004     g_application.SetVolume(volume);
1005     if(oldVolume != volume)
1006     {
1007       if(params.size() > 1 && params[1].Equals("showVolumeBar"))    
1008       {
1009         CApplicationMessenger::Get().ShowVolumeBar(oldVolume < volume);  
1010       }
1011     }
1012   }
1013   else if (execute.Equals("playlist.playoffset"))
1014   {
1015     // playlist.playoffset(offset)
1016     // playlist.playoffset(music|video,offset)
1017     CStdString strPos = parameter;
1018     if (params.size() > 1)
1019     {
1020       // ignore any other parameters if present
1021       CStdString strPlaylist = params[0];
1022       strPos = params[1];
1023
1024       int iPlaylist = PLAYLIST_NONE;
1025       if (strPlaylist.Equals("music"))
1026         iPlaylist = PLAYLIST_MUSIC;
1027       else if (strPlaylist.Equals("video"))
1028         iPlaylist = PLAYLIST_VIDEO;
1029
1030       // unknown playlist
1031       if (iPlaylist == PLAYLIST_NONE)
1032       {
1033         CLog::Log(LOGERROR,"Playlist.PlayOffset called with unknown playlist: %s", strPlaylist.c_str());
1034         return false;
1035       }
1036
1037       // user wants to play the 'other' playlist
1038       if (iPlaylist != g_playlistPlayer.GetCurrentPlaylist())
1039       {
1040         g_application.StopPlaying();
1041         g_playlistPlayer.Reset();
1042         g_playlistPlayer.SetCurrentPlaylist(iPlaylist);
1043       }
1044     }
1045     // play the desired offset
1046     int pos = atol(strPos.c_str());
1047     // playlist is already playing
1048     if (g_application.m_pPlayer->IsPlaying())
1049       g_playlistPlayer.PlayNext(pos);
1050     // we start playing the 'other' playlist so we need to use play to initialize the player state
1051     else
1052       g_playlistPlayer.Play(pos);
1053   }
1054   else if (execute.Equals("playlist.clear"))
1055   {
1056     g_playlistPlayer.Clear();
1057   }
1058 #ifdef HAS_DVD_DRIVE
1059   else if (execute.Equals("ejecttray"))
1060   {
1061     g_mediaManager.ToggleTray();
1062   }
1063 #endif
1064   else if( execute.Equals("alarmclock") && params.size() > 1 )
1065   {
1066     // format is alarmclock(name,command[,seconds,true]);
1067     float seconds = 0;
1068     if (params.size() > 2)
1069     {
1070       if (params[2].find(':') == std::string::npos)
1071         seconds = static_cast<float>(atoi(params[2].c_str())*60);
1072       else
1073         seconds = (float)StringUtils::TimeStringToSeconds(params[2]);
1074     }
1075     else
1076     { // check if shutdown is specified in particular, and get the time for it
1077       CStdString strHeading;
1078       if (StringUtils::EqualsNoCase(parameter, "shutdowntimer"))
1079         strHeading = g_localizeStrings.Get(20145);
1080       else
1081         strHeading = g_localizeStrings.Get(13209);
1082       CStdString strTime;
1083       if( CGUIDialogNumeric::ShowAndGetNumber(strTime, strHeading) )
1084         seconds = static_cast<float>(atoi(strTime.c_str())*60);
1085       else
1086         return false;
1087     }
1088     bool silent = false;
1089     bool loop = false;
1090     for (unsigned int i = 3; i < params.size() ; i++)
1091     {
1092       // check "true" for backward comp
1093       if (StringUtils::EqualsNoCase(params[i], "true") || StringUtils::EqualsNoCase(params[i], "silent"))
1094         silent = true;
1095       else if (StringUtils::EqualsNoCase(params[i], "loop"))
1096         loop = true;
1097     }
1098
1099     if( g_alarmClock.IsRunning() )
1100       g_alarmClock.Stop(params[0],silent);
1101     // no negative times not allowed, loop must have a positive time
1102     if (seconds < 0 || (seconds == 0 && loop))
1103       return false;
1104     g_alarmClock.Start(params[0], seconds, params[1], silent, loop);
1105   }
1106   else if (execute.Equals("notification"))
1107   {
1108     if (params.size() < 2)
1109       return -1;
1110     if (params.size() == 4)
1111       CGUIDialogKaiToast::QueueNotification(params[3],params[0],params[1],atoi(params[2].c_str()));
1112     else if (params.size() == 3)
1113       CGUIDialogKaiToast::QueueNotification("",params[0],params[1],atoi(params[2].c_str()));
1114     else
1115       CGUIDialogKaiToast::QueueNotification(params[0],params[1]);
1116   }
1117   else if (execute.Equals("cancelalarm"))
1118   {
1119     bool silent = false;
1120     if (params.size() > 1 && StringUtils::EqualsNoCase(params[1], "true"))
1121       silent = true;
1122     g_alarmClock.Stop(params[0],silent);
1123   }
1124   else if (execute.Equals("playdvd"))
1125   {
1126 #ifdef HAS_DVD_DRIVE
1127     bool restart = false;
1128     if (params.size() > 0 && StringUtils::EqualsNoCase(params[0], "restart"))
1129       restart = true;
1130     CAutorun::PlayDisc(g_mediaManager.GetDiscPath(), true, restart);
1131 #endif
1132   }
1133   else if (execute.Equals("ripcd"))
1134   {
1135 #ifdef HAS_CDDA_RIPPER
1136     CCDDARipper::GetInstance().RipCD();
1137 #endif
1138   }
1139   else if (execute.Equals("skin.togglesetting"))
1140   {
1141     int setting = CSkinSettings::Get().TranslateBool(parameter);
1142     CSkinSettings::Get().SetBool(setting, !CSkinSettings::Get().GetBool(setting));
1143     CSettings::Get().Save();
1144   }
1145   else if (execute.Equals("skin.setbool") && params.size())
1146   {
1147     if (params.size() > 1)
1148     {
1149       int string = CSkinSettings::Get().TranslateBool(params[0]);
1150       CSkinSettings::Get().SetBool(string, StringUtils::EqualsNoCase(params[1], "true"));
1151       CSettings::Get().Save();
1152       return 0;
1153     }
1154     // default is to set it to true
1155     int setting = CSkinSettings::Get().TranslateBool(params[0]);
1156     CSkinSettings::Get().SetBool(setting, true);
1157     CSettings::Get().Save();
1158   }
1159   else if (execute.Equals("skin.reset"))
1160   {
1161     CSkinSettings::Get().Reset(parameter);
1162     CSettings::Get().Save();
1163   }
1164   else if (execute.Equals("skin.resetsettings"))
1165   {
1166     CSkinSettings::Get().Reset();
1167     CSettings::Get().Save();
1168   }
1169   else if (execute.Equals("skin.theme"))
1170   {
1171     // enumerate themes
1172     vector<CStdString> vecTheme;
1173     CUtil::GetSkinThemes(vecTheme);
1174
1175     int iTheme = -1;
1176
1177     // find current theme
1178     if (!StringUtils::EqualsNoCase(CSettings::Get().GetString("lookandfeel.skintheme"), "SKINDEFAULT"))
1179     {
1180       for (unsigned int i=0;i<vecTheme.size();++i)
1181       {
1182         CStdString strTmpTheme(CSettings::Get().GetString("lookandfeel.skintheme"));
1183         URIUtils::RemoveExtension(strTmpTheme);
1184         if (vecTheme[i].Equals(strTmpTheme))
1185         {
1186           iTheme=i;
1187           break;
1188         }
1189       }
1190     }
1191
1192     int iParam = atoi(parameter.c_str());
1193     if (iParam == 0 || iParam == 1)
1194       iTheme++;
1195     else if (iParam == -1)
1196       iTheme--;
1197     if (iTheme > (int)vecTheme.size()-1)
1198       iTheme = -1;
1199     if (iTheme < -1)
1200       iTheme = vecTheme.size()-1;
1201
1202     CStdString strSkinTheme = "SKINDEFAULT";
1203     if (iTheme != -1 && iTheme < (int)vecTheme.size())
1204       strSkinTheme = vecTheme[iTheme];
1205
1206     CSettings::Get().SetString("lookandfeel.skintheme", strSkinTheme);
1207     // also set the default color theme
1208     CStdString colorTheme(URIUtils::ReplaceExtension(strSkinTheme, ".xml"));
1209     if (colorTheme.Equals("Textures.xml"))
1210       colorTheme = "defaults.xml";
1211     CSettings::Get().SetString("lookandfeel.skincolors", colorTheme);
1212     g_application.ReloadSkin();
1213   }
1214   else if (execute.Equals("skin.setstring") || execute.Equals("skin.setimage") || execute.Equals("skin.setfile") ||
1215            execute.Equals("skin.setpath") || execute.Equals("skin.setnumeric") || execute.Equals("skin.setlargeimage"))
1216   {
1217     // break the parameter up if necessary
1218     int string = 0;
1219     if (params.size() > 1)
1220     {
1221       string = CSkinSettings::Get().TranslateString(params[0]);
1222       if (execute.Equals("skin.setstring"))
1223       {
1224         CSkinSettings::Get().SetString(string, params[1]);
1225         CSettings::Get().Save();
1226         return 0;
1227       }
1228     }
1229     else
1230       string = CSkinSettings::Get().TranslateString(params[0]);
1231     CStdString value = CSkinSettings::Get().GetString(string);
1232     VECSOURCES localShares;
1233     g_mediaManager.GetLocalDrives(localShares);
1234     if (execute.Equals("skin.setstring"))
1235     {
1236       if (CGUIKeyboardFactory::ShowAndGetInput(value, g_localizeStrings.Get(1029), true))
1237         CSkinSettings::Get().SetString(string, value);
1238     }
1239     else if (execute.Equals("skin.setnumeric"))
1240     {
1241       if (CGUIDialogNumeric::ShowAndGetNumber(value, g_localizeStrings.Get(611)))
1242         CSkinSettings::Get().SetString(string, value);
1243     }
1244     else if (execute.Equals("skin.setimage"))
1245     {
1246       if (CGUIDialogFileBrowser::ShowAndGetImage(localShares, g_localizeStrings.Get(1030), value))
1247         CSkinSettings::Get().SetString(string, value);
1248     }
1249     else if (execute.Equals("skin.setlargeimage"))
1250     {
1251       VECSOURCES *shares = CMediaSourceSettings::Get().GetSources("pictures");
1252       if (!shares) shares = &localShares;
1253       if (CGUIDialogFileBrowser::ShowAndGetImage(*shares, g_localizeStrings.Get(1030), value))
1254         CSkinSettings::Get().SetString(string, value);
1255     }
1256     else if (execute.Equals("skin.setfile"))
1257     {
1258       // Note. can only browse one addon type from here
1259       // if browsing for addons, required param[1] is addontype string, with optional param[2]
1260       // as contenttype string see IAddon.h & ADDON::TranslateXX
1261       CStdString strMask = (params.size() > 1) ? params[1] : "";
1262       StringUtils::ToLower(strMask);
1263       ADDON::TYPE type;
1264       if ((type = TranslateType(strMask)) != ADDON_UNKNOWN)
1265       {
1266         CURL url;
1267         url.SetProtocol("addons");
1268         url.SetHostName("enabled");
1269         url.SetFileName(strMask+"/");
1270         localShares.clear();
1271         CStdString content = (params.size() > 2) ? params[2] : "";
1272         StringUtils::ToLower(content);
1273         url.SetPassword(content);
1274         CStdString strMask;
1275         if (type == ADDON_SCRIPT)
1276           strMask = ".py";
1277         CStdString replace;
1278         if (CGUIDialogFileBrowser::ShowAndGetFile(url.Get(), strMask, TranslateType(type, true), replace, true, true, true))
1279         {
1280           if (StringUtils::StartsWithNoCase(replace, "addons://"))
1281             CSkinSettings::Get().SetString(string, URIUtils::GetFileName(replace));
1282           else
1283             CSkinSettings::Get().SetString(string, replace);
1284         }
1285       }
1286       else 
1287       {
1288         if (params.size() > 2)
1289         {
1290           value = params[2];
1291           URIUtils::AddSlashAtEnd(value);
1292           bool bIsSource;
1293           if (CUtil::GetMatchingSource(value,localShares,bIsSource) < 0) // path is outside shares - add it as a separate one
1294           {
1295             CMediaSource share;
1296             share.strName = g_localizeStrings.Get(13278);
1297             share.strPath = value;
1298             localShares.push_back(share);
1299           }
1300         }
1301         if (CGUIDialogFileBrowser::ShowAndGetFile(localShares, strMask, g_localizeStrings.Get(1033), value))
1302           CSkinSettings::Get().SetString(string, value);
1303       }
1304     }
1305     else // execute.Equals("skin.setpath"))
1306     {
1307       g_mediaManager.GetNetworkLocations(localShares);
1308       if (params.size() > 1)
1309       {
1310         value = params[1];
1311         URIUtils::AddSlashAtEnd(value);
1312         bool bIsSource;
1313         if (CUtil::GetMatchingSource(value,localShares,bIsSource) < 0) // path is outside shares - add it as a separate one
1314         {
1315           CMediaSource share;
1316           share.strName = g_localizeStrings.Get(13278);
1317           share.strPath = value;
1318           localShares.push_back(share);
1319         }
1320       }
1321       if (CGUIDialogFileBrowser::ShowAndGetDirectory(localShares, g_localizeStrings.Get(1031), value))
1322         CSkinSettings::Get().SetString(string, value);
1323     }
1324     CSettings::Get().Save();
1325   }
1326   else if (execute.Equals("skin.setaddon") && params.size() > 1)
1327   {
1328     int string = CSkinSettings::Get().TranslateString(params[0]);
1329     vector<ADDON::TYPE> types;
1330     for (unsigned int i = 1 ; i < params.size() ; i++)
1331     {
1332       ADDON::TYPE type = TranslateType(params[i]);
1333       if (type != ADDON_UNKNOWN)
1334         types.push_back(type);
1335     }
1336     CStdString result;
1337     if (types.size() > 0 && CGUIWindowAddonBrowser::SelectAddonID(types, result, true) == 1)
1338     {
1339       CSkinSettings::Get().SetString(string, result);
1340       CSettings::Get().Save();
1341     }
1342   }
1343   else if (execute.Equals("dialog.close") && params.size())
1344   {
1345     bool bForce = false;
1346     if (params.size() > 1 && StringUtils::EqualsNoCase(params[1], "true"))
1347       bForce = true;
1348     if (StringUtils::EqualsNoCase(params[0], "all"))
1349     {
1350       g_windowManager.CloseDialogs(bForce);
1351     }
1352     else
1353     {
1354       int id = CButtonTranslator::TranslateWindow(params[0]);
1355       CGUIWindow *window = (CGUIWindow *)g_windowManager.GetWindow(id);
1356       if (window && window->IsDialog())
1357         ((CGUIDialog *)window)->Close(bForce);
1358     }
1359   }
1360   else if (execute.Equals("system.logoff"))
1361   {
1362     // there was a commit from cptspiff here which was reverted
1363     // for keeping the behaviour from Eden in Frodo - see
1364     // git rev 9ee5f0047b
1365     if (g_windowManager.GetActiveWindow() == WINDOW_LOGIN_SCREEN)
1366       return -1;
1367
1368     g_application.StopPlaying();
1369     if (g_application.IsMusicScanning())
1370       g_application.StopMusicScan();
1371
1372     if (g_application.IsVideoScanning())
1373       g_application.StopVideoScan();
1374
1375     ADDON::CAddonMgr::Get().StopServices(true);
1376
1377     g_application.getNetwork().NetworkMessage(CNetwork::SERVICES_DOWN,1);
1378     CProfilesManager::Get().LoadMasterProfileForLogin();
1379     g_passwordManager.bMasterUser = false;
1380     g_windowManager.ActivateWindow(WINDOW_LOGIN_SCREEN);
1381     if (!CNetworkServices::Get().StartEventServer()) // event server could be needed in some situations
1382       CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Warning, g_localizeStrings.Get(33102), g_localizeStrings.Get(33100));
1383   }
1384   else if (execute.Equals("pagedown"))
1385   {
1386     int id = atoi(parameter.c_str());
1387     CGUIMessage message(GUI_MSG_PAGE_DOWN, g_windowManager.GetFocusedWindow(), id);
1388     g_windowManager.SendMessage(message);
1389   }
1390   else if (execute.Equals("pageup"))
1391   {
1392     int id = atoi(parameter.c_str());
1393     CGUIMessage message(GUI_MSG_PAGE_UP, g_windowManager.GetFocusedWindow(), id);
1394     g_windowManager.SendMessage(message);
1395   }
1396   else if (execute.Equals("updatelibrary") && params.size())
1397   {
1398     if (params[0].Equals("music"))
1399     {
1400       if (g_application.IsMusicScanning())
1401         g_application.StopMusicScan();
1402       else
1403         g_application.StartMusicScan(params.size() > 1 ? params[1] : "");
1404     }
1405     if (params[0].Equals("video"))
1406     {
1407       if (g_application.IsVideoScanning())
1408         g_application.StopVideoScan();
1409       else
1410         g_application.StartVideoScan(params.size() > 1 ? params[1] : "");
1411     }
1412   }
1413   else if (execute.Equals("cleanlibrary"))
1414   {
1415     if (!params.size() || params[0].Equals("video"))
1416     {
1417       if (!g_application.IsVideoScanning())
1418          g_application.StartVideoCleanup();
1419       else
1420         CLog::Log(LOGERROR, "XBMC.CleanLibrary is not possible while scanning or cleaning");
1421     }
1422     else if (params[0].Equals("music"))
1423     {
1424       if (!g_application.IsMusicScanning())
1425       {
1426         CMusicDatabase musicdatabase;
1427
1428         musicdatabase.Open();
1429         musicdatabase.Cleanup();
1430         musicdatabase.Close();
1431       }
1432       else
1433         CLog::Log(LOGERROR, "XBMC.CleanLibrary is not possible while scanning for media info");
1434     }
1435   }
1436   else if (execute.Equals("exportlibrary"))
1437   {
1438     int iHeading = 647;
1439     if (params[0].Equals("music"))
1440       iHeading = 20196;
1441     CStdString path;
1442     VECSOURCES shares;
1443     g_mediaManager.GetLocalDrives(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 }