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