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