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