2 * Copyright (C) 2005-2013 Team XBMC
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)
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.
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/>.
21 #include "network/Network.h"
23 #include "utils/AlarmClock.h"
24 #include "utils/Screenshot.h"
25 #include "Application.h"
26 #include "ApplicationMessenger.h"
29 #include "input/ButtonTranslator.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"
66 #include "music/MusicDatabase.h"
67 #include "cores/IPlayer.h"
69 #include "filesystem/PluginDirectory.h"
70 #ifdef HAS_FILESYSTEM_RAR
71 #include "filesystem/RarManager.h"
73 #include "filesystem/ZipManager.h"
75 #include "guilib/GUIWindowManager.h"
76 #include "guilib/LocalizeStrings.h"
79 #include "input/linux/LIRC.h"
81 #ifdef HAS_IRSERVERSUITE
83 #include "input/windows/IRServerSuite.h"
87 #if defined(TARGET_DARWIN)
88 #include "filesystem/SpecialProtocol.h"
89 #include "osx/CocoaInterface.h"
92 #ifdef HAS_CDDA_RIPPER
93 #include "cdrip/CDDARipper.h"
97 #include "settings/AdvancedSettings.h"
98 #include "settings/DisplaySettings.h"
101 using namespace XFILE;
102 using namespace ADDON;
105 using namespace MEDIA_DETECT;
111 bool needsParameters;
112 const char* description;
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" },
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" },
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." },
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)" }
233 bool CBuiltins::HasCommand(const CStdString& execString)
236 vector<CStdString> parameters;
237 CUtil::SplitExecFunction(execString, function, parameters);
238 for (unsigned int i = 0; i < sizeof(commands)/sizeof(BUILT_IN); i++)
240 if (StringUtils::EqualsNoCase(function, commands[i].command) && (!commands[i].needsParameters || parameters.size()))
246 void CBuiltins::GetHelp(CStdString &help)
249 for (unsigned int i = 0; i < sizeof(commands)/sizeof(BUILT_IN); i++)
251 help += commands[i].command;
253 help += commands[i].description;
258 int CBuiltins::Execute(const CStdString& execString)
260 // Get the text after the "XBMC."
262 vector<CStdString> params;
263 CUtil::SplitExecFunction(execString, execute, params);
264 StringUtils::ToLower(execute);
265 CStdString parameter = params.size() ? params[0] : "";
266 CStdString strParameterCaseIntact = parameter;
268 if (execute.Equals("reboot") || execute.Equals("restart") || execute.Equals("reset")) //Will reboot the system
270 CApplicationMessenger::Get().Restart();
272 else if (execute.Equals("shutdown"))
274 CApplicationMessenger::Get().Shutdown();
276 else if (execute.Equals("powerdown"))
278 CApplicationMessenger::Get().Powerdown();
280 else if (execute.Equals("restartapp"))
282 CApplicationMessenger::Get().RestartApp();
284 else if (execute.Equals("hibernate"))
286 CApplicationMessenger::Get().Hibernate();
288 else if (execute.Equals("suspend"))
290 CApplicationMessenger::Get().Suspend();
292 else if (execute.Equals("quit"))
294 CApplicationMessenger::Get().Quit();
296 else if (execute.Equals("inhibitidleshutdown"))
298 bool inhibit = (params.size() == 1 && params[0].Equals("true"));
299 CApplicationMessenger::Get().InhibitIdleShutdown(inhibit);
301 else if (execute.Equals("activatescreensaver"))
303 CApplicationMessenger::Get().ActivateScreensaver();
305 else if (execute.Equals("minimize"))
307 CApplicationMessenger::Get().Minimize();
309 else if (execute.Equals("loadprofile"))
311 int index = CProfilesManager::Get().GetProfileIndex(parameter);
312 bool prompt = (params.size() == 2 && params[1].Equals("prompt"));
315 && (CProfilesManager::Get().GetMasterProfile().getLockMode() == LOCK_MODE_EVERYONE
316 || g_passwordManager.IsProfileLockUnlocked(index,bCanceled,prompt)))
318 CApplicationMessenger::Get().LoadProfile(index);
321 else if (execute.Equals("mastermode"))
323 if (g_passwordManager.bMasterUser)
325 g_passwordManager.bMasterUser = false;
326 g_passwordManager.LockSources(true);
327 CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Warning, g_localizeStrings.Get(20052),g_localizeStrings.Get(20053));
329 else if (g_passwordManager.IsMasterLockUnlocked(true))
331 g_passwordManager.LockSources(false);
332 g_passwordManager.bMasterUser = true;
333 CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Warning, g_localizeStrings.Get(20052),g_localizeStrings.Get(20054));
336 CUtil::DeleteVideoDatabaseDirectoryCache();
337 CGUIMessage msg(GUI_MSG_NOTIFY_ALL, 0, 0, GUI_MSG_UPDATE);
338 g_windowManager.SendMessage(msg);
340 else if (execute.Equals("setguilanguage"))
344 CApplicationMessenger::Get().SetGUILanguage(params[0]);
347 else if (execute.Equals("takescreenshot"))
351 // get the parameters
352 CStdString strSaveToPath = params[0];
354 if (params.size() >= 2)
355 sync = params[1].Equals("sync");
357 if (!strSaveToPath.empty())
359 if (CDirectory::Exists(strSaveToPath))
361 CStdString file = CUtil::GetNextFilename(URIUtils::AddFileToFolder(strSaveToPath, "screenshot%03d.png"), 999);
365 CScreenShot::TakeScreenshot(file, sync);
369 CLog::Log(LOGWARNING, "Too many screen shots or invalid folder %s", strSaveToPath.c_str());
373 CScreenShot::TakeScreenshot(strSaveToPath, sync);
377 CScreenShot::TakeScreenshot();
379 else if (execute.Equals("activatewindow") || execute.Equals("replacewindow"))
381 // get the parameters
382 CStdString strWindow;
385 strWindow = params[0];
386 params.erase(params.begin());
389 // confirm the window destination is valid prior to switching
390 int iWindow = CButtonTranslator::TranslateWindow(strWindow);
391 if (iWindow != WINDOW_INVALID)
393 // disable the screensaver
394 g_application.WakeUpScreenSaverAndDPMS();
395 g_windowManager.ActivateWindow(iWindow, params, !execute.Equals("activatewindow"));
399 CLog::Log(LOGERROR, "Activate/ReplaceWindow called with invalid destination window: %s", strWindow.c_str());
403 else if ((execute.Equals("setfocus") || execute.Equals("control.setfocus")) && params.size())
405 int controlID = atol(params[0].c_str());
406 int subItem = (params.size() > 1) ? atol(params[1].c_str())+1 : 0;
407 CGUIMessage msg(GUI_MSG_SETFOCUS, g_windowManager.GetFocusedWindow(), controlID, subItem);
408 g_windowManager.SendMessage(msg);
410 else if ((execute.Equals("activatewindowandfocus") || execute.Equals("replacewindowandfocus")) && params.size())
412 CStdString strWindow = params[0];
414 // confirm the window destination is valid prior to switching
415 int iWindow = CButtonTranslator::TranslateWindow(strWindow);
416 if (iWindow != WINDOW_INVALID)
418 // disable the screensaver
419 g_application.WakeUpScreenSaverAndDPMS();
420 vector<CStdString> dummy;
421 g_windowManager.ActivateWindow(iWindow, dummy, !execute.Equals("activatewindowandfocus"));
423 unsigned int iPtr = 1;
424 while (params.size() > iPtr + 1)
426 CGUIMessage msg(GUI_MSG_SETFOCUS, g_windowManager.GetFocusedWindow(),
427 atol(params[iPtr].c_str()),
428 (params.size() >= iPtr + 2) ? atol(params[iPtr + 1].c_str())+1 : 0);
429 g_windowManager.SendMessage(msg);
435 CLog::Log(LOGERROR, "Replace/ActivateWindowAndFocus called with invalid destination window: %s", strWindow.c_str());
439 else if (execute.Equals("runscript") && params.size())
441 #if defined(TARGET_DARWIN_OSX)
442 if (URIUtils::HasExtension(strParameterCaseIntact, ".applescript|.scpt"))
444 CStdString osxPath = CSpecialProtocol::TranslatePath(strParameterCaseIntact);
445 Cocoa_DoAppleScriptFile(osxPath.c_str());
451 for (vector<CStdString>::const_iterator param = params.begin(); param != params.end(); ++param)
452 argv.push_back(*param);
454 vector<CStdString> path;
455 //split the path up to find the filename
456 StringUtils::SplitString(params[0],"\\",path);
458 argv[0] = path[path.size() - 1];
461 CStdString scriptpath(params[0]);
462 if (CAddonMgr::Get().GetAddon(params[0], script))
463 scriptpath = script->LibPath();
465 CScriptInvocationManager::Get().Execute(scriptpath, script, argv);
468 #if defined(TARGET_DARWIN_OSX)
469 else if (execute.Equals("runapplescript"))
471 Cocoa_DoAppleScript(strParameterCaseIntact.c_str());
474 else if (execute.Equals("stopscript"))
476 CStdString scriptpath(params[0]);
478 // Test to see if the param is an addon ID
480 if (CAddonMgr::Get().GetAddon(params[0], script))
481 scriptpath = script->LibPath();
483 CScriptInvocationManager::Get().Stop(scriptpath);
485 else if (execute.Equals("system.exec"))
487 CApplicationMessenger::Get().Minimize();
488 CApplicationMessenger::Get().ExecOS(parameter, false);
490 else if (execute.Equals("system.execwait"))
492 CApplicationMessenger::Get().Minimize();
493 CApplicationMessenger::Get().ExecOS(parameter, true);
495 else if (execute.Equals("resolution"))
497 RESOLUTION res = RES_PAL_4x3;
498 if (parameter.Equals("pal")) res = RES_PAL_4x3;
499 else if (parameter.Equals("pal16x9")) res = RES_PAL_16x9;
500 else if (parameter.Equals("ntsc")) res = RES_NTSC_4x3;
501 else if (parameter.Equals("ntsc16x9")) res = RES_NTSC_16x9;
502 else if (parameter.Equals("720p")) res = RES_HDTV_720p;
503 else if (parameter.Equals("720pSBS")) res = RES_HDTV_720pSBS;
504 else if (parameter.Equals("720pTB")) res = RES_HDTV_720pTB;
505 else if (parameter.Equals("1080pSBS")) res = RES_HDTV_1080pSBS;
506 else if (parameter.Equals("1080pTB")) res = RES_HDTV_1080pTB;
507 else if (parameter.Equals("1080i")) res = RES_HDTV_1080i;
508 if (g_graphicsContext.IsValidResolution(res))
510 CDisplaySettings::Get().SetCurrentResolution(res, true);
511 g_application.ReloadSkin();
514 else if (execute.Equals("extract") && params.size())
516 // Detects if file is zip or rar then extracts
517 CStdString strDestDirect;
518 if (params.size() < 2)
519 strDestDirect = URIUtils::GetDirectory(params[0]);
521 strDestDirect = params[1];
523 URIUtils::AddSlashAtEnd(strDestDirect);
525 if (URIUtils::IsZIP(params[0]))
526 g_ZipManager.ExtractArchive(params[0],strDestDirect);
527 #ifdef HAS_FILESYSTEM_RAR
528 else if (URIUtils::IsRAR(params[0]))
529 g_RarManager.ExtractArchive(params[0],strDestDirect);
532 CLog::Log(LOGERROR, "XBMC.Extract, No archive given");
534 else if (execute.Equals("runplugin"))
538 CFileItem item(params[0]);
539 if (!item.m_bIsFolder)
541 item.SetPath(params[0]);
542 CPluginDirectory::RunScriptWithParams(item.GetPath());
547 CLog::Log(LOGERROR, "XBMC.RunPlugin called with no arguments.");
550 else if (execute.Equals("runaddon"))
556 if (CAddonMgr::Get().GetAddon(params[0],addon,ADDON_PLUGIN))
558 PluginPtr plugin = boost::dynamic_pointer_cast<CPluginSource>(addon);
559 CStdString addonid = params[0];
560 CStdString urlParameters;
561 CStdStringArray parameters;
562 if (params.size() == 2 &&
563 (StringUtils::StartsWith(params[1], "/") || StringUtils::StartsWith(params[1], "?")))
564 urlParameters = params[1];
565 else if (params.size() > 1)
567 parameters.insert(parameters.begin(), params.begin() + 1, params.end());
568 urlParameters = "?" + StringUtils::JoinString(parameters, "&");
572 // Add '/' if addon is run without params (will be removed later so it's safe)
573 // Otherwise there are 2 entries for the same plugin in ViewModesX.db
577 if (plugin->Provides(CPluginSource::VIDEO))
578 cmd = StringUtils::Format("ActivateWindow(Videos,plugin://%s%s,return)", addonid.c_str(), urlParameters.c_str());
579 else if (plugin->Provides(CPluginSource::AUDIO))
580 cmd = StringUtils::Format("ActivateWindow(Music,plugin://%s%s,return)", addonid.c_str(), urlParameters.c_str());
581 else if (plugin->Provides(CPluginSource::EXECUTABLE))
582 cmd = StringUtils::Format("ActivateWindow(Programs,plugin://%s%s,return)", addonid.c_str(), urlParameters.c_str());
583 else if (plugin->Provides(CPluginSource::IMAGE))
584 cmd = StringUtils::Format("ActivateWindow(Pictures,plugin://%s%s,return)", addonid.c_str(), urlParameters.c_str());
586 // Pass the script name (params[0]) and all the parameters
587 // (params[1] ... params[x]) separated by a comma to RunPlugin
588 cmd = StringUtils::Format("RunPlugin(%s)", StringUtils::JoinString(params, ",").c_str());
590 else if (CAddonMgr::Get().GetAddon(params[0], addon, ADDON_SCRIPT) ||
591 CAddonMgr::Get().GetAddon(params[0], addon, ADDON_SCRIPT_WEATHER) ||
592 CAddonMgr::Get().GetAddon(params[0], addon, ADDON_SCRIPT_LYRICS))
593 // Pass the script name (params[0]) and all the parameters
594 // (params[1] ... params[x]) separated by a comma to RunScript
595 cmd = StringUtils::Format("RunScript(%s)", StringUtils::JoinString(params, ",").c_str());
601 CLog::Log(LOGERROR, "XBMC.RunAddon called with no arguments.");
604 else if (execute.Equals("notifyall"))
606 if (params.size() > 1)
609 if (params.size() > 2)
610 data = CJSONVariantParser::Parse((const unsigned char *)params[2].c_str(), params[2].size());
612 ANNOUNCEMENT::CAnnouncementManager::Announce(ANNOUNCEMENT::Other, params[0], params[1], data);
615 CLog::Log(LOGERROR, "XBMC.NotifyAll needs two parameters");
617 else if (execute.Equals("playmedia"))
621 CLog::Log(LOGERROR, "XBMC.PlayMedia called with empty parameter");
625 CFileItem item(params[0], false);
626 if (URIUtils::HasSlashAtEnd(params[0]))
627 item.m_bIsFolder = true;
629 // restore to previous window if needed
630 if( g_windowManager.GetActiveWindow() == WINDOW_SLIDESHOW ||
631 g_windowManager.GetActiveWindow() == WINDOW_FULLSCREEN_VIDEO ||
632 g_windowManager.GetActiveWindow() == WINDOW_VISUALISATION )
633 g_windowManager.PreviousWindow();
636 g_application.ResetScreenSaver();
637 g_application.WakeUpScreenSaverAndDPMS();
639 // ask if we need to check guisettings to resume
640 bool askToResume = true;
642 for (unsigned int i = 1 ; i < params.size() ; i++)
644 if (params[i].Equals("isdir"))
645 item.m_bIsFolder = true;
646 else if (params[i].Equals("1")) // set fullscreen or windowed
647 CMediaSettings::Get().SetVideoStartWindowed(true);
648 else if (params[i].Equals("resume"))
650 // force the item to resume (if applicable) (see CApplication::PlayMedia)
651 item.m_lStartOffset = STARTOFFSET_RESUME;
654 else if (params[i].Equals("noresume"))
656 // force the item to start at the beginning (m_lStartOffset is initialized to 0)
659 else if (StringUtils::StartsWithNoCase(params[i], "playoffset=")) {
660 playOffset = atoi(params[i].substr(11).c_str()) - 1;
661 item.SetProperty("playlist_starting_track", playOffset);
665 if (!item.m_bIsFolder && item.IsPlugin())
666 item.SetProperty("IsPlayable", true);
668 if ( askToResume == true )
670 if ( CGUIWindowVideoBase::ShowResumeMenu(item) == false )
673 if (item.m_bIsFolder)
676 CStdString extensions = g_advancedSettings.m_videoExtensions + "|" + g_advancedSettings.m_musicExtensions;
677 CDirectory::GetDirectory(item.GetPath(),items,extensions);
679 bool containsMusic = false, containsVideo = false;
680 for (int i = 0; i < items.Size(); i++)
682 bool isVideo = items[i]->IsVideo();
683 containsMusic |= !isVideo;
684 containsVideo |= isVideo;
686 if (containsMusic && containsVideo)
690 CGUIViewState *state = CGUIViewState::GetViewState(containsVideo ? WINDOW_VIDEO_NAV : WINDOW_MUSIC, items);
692 items.Sort(state->GetSortMethod());
694 items.Sort(SortByLabel, SortOrderAscending);
696 int playlist = containsVideo? PLAYLIST_VIDEO : PLAYLIST_MUSIC;;
697 if (containsMusic && containsVideo) //mixed content found in the folder
699 for (int i = items.Size() - 1; i >= 0; i--) //remove music entries
701 if (!items[i]->IsVideo())
706 g_playlistPlayer.ClearPlaylist(playlist);
707 g_playlistPlayer.Add(playlist, items);
708 g_playlistPlayer.SetCurrentPlaylist(playlist);
709 g_playlistPlayer.Play(playOffset);
713 int playlist = item.IsAudio() ? PLAYLIST_MUSIC : PLAYLIST_VIDEO;
714 g_playlistPlayer.ClearPlaylist(playlist);
715 g_playlistPlayer.SetCurrentPlaylist(playlist);
718 if (!g_application.PlayMedia(item, playlist))
720 CLog::Log(LOGERROR, "XBMC.PlayMedia could not play media: %s", params[0].c_str());
725 else if (execute.Equals("showPicture"))
729 CLog::Log(LOGERROR, "XBMC.ShowPicture called with empty parameter");
732 CGUIMessage msg(GUI_MSG_SHOW_PICTURE, 0, 0);
733 msg.SetStringParam(params[0]);
734 CGUIWindow *pWindow = g_windowManager.GetWindow(WINDOW_SLIDESHOW);
735 if (pWindow) pWindow->OnMessage(msg);
737 else if (execute.Equals("slideShow") || execute.Equals("recursiveslideShow"))
741 CLog::Log(LOGERROR, "XBMC.SlideShow called with empty parameter");
744 std::string beginSlidePath;
745 // leave RecursiveSlideShow command as-is
746 unsigned int flags = 0;
747 if (execute.Equals("RecursiveSlideShow"))
750 // SlideShow(dir[,recursive][,[not]random][,pause][,beginslide="/path/to/start/slide.jpg"])
751 // the beginslide value need be escaped (for '"' or '\' in it, by backslash)
752 // and then quoted, or not. See CUtil::SplitParams()
755 for (unsigned int i = 1 ; i < params.size() ; i++)
757 if (params[i].Equals("recursive"))
759 else if (params[i].Equals("random")) // set fullscreen or windowed
761 else if (params[i].Equals("notrandom"))
763 else if (params[i].Equals("pause"))
765 else if (StringUtils::StartsWithNoCase(params[i], "beginslide="))
766 beginSlidePath = params[i].substr(11);
770 CGUIMessage msg(GUI_MSG_START_SLIDESHOW, 0, 0, flags);
771 vector<CStdString> strParams;
772 strParams.push_back(params[0]);
773 strParams.push_back(beginSlidePath);
774 msg.SetStringParams(strParams);
775 CGUIWindow *pWindow = g_windowManager.GetWindow(WINDOW_SLIDESHOW);
776 if (pWindow) pWindow->OnMessage(msg);
778 else if (execute.Equals("reloadskin"))
781 g_application.ReloadSkin(!params.empty() && StringUtils::EqualsNoCase(params[0], "confirm"));
783 else if (execute.Equals("unloadskin"))
785 g_application.UnloadSkin(true); // we're reloading the skin after this
787 else if (execute.Equals("refreshrss"))
789 CRssManager::Get().Reload();
791 else if (execute.Equals("playercontrol"))
793 g_application.ResetScreenSaver();
794 g_application.WakeUpScreenSaverAndDPMS();
797 CLog::Log(LOGERROR, "XBMC.PlayerControl called with empty parameter");
800 if (parameter.Equals("play"))
802 // either resume playing, or pause
803 if (g_application.m_pPlayer->IsPlaying())
805 if (g_application.m_pPlayer->GetPlaySpeed() != 1)
806 g_application.m_pPlayer->SetPlaySpeed(1, g_application.IsMutedInternal());
808 g_application.m_pPlayer->Pause();
811 else if (parameter.Equals("stop"))
813 g_application.StopPlaying();
815 else if (parameter.Equals("rewind") || parameter.Equals("forward"))
817 if (g_application.m_pPlayer->IsPlaying() && !g_application.m_pPlayer->IsPaused())
819 int iPlaySpeed = g_application.m_pPlayer->GetPlaySpeed();
820 if (parameter.Equals("rewind") && iPlaySpeed == 1) // Enables Rewinding
822 else if (parameter.Equals("rewind") && iPlaySpeed > 1) //goes down a notch if you're FFing
824 else if (parameter.Equals("forward") && iPlaySpeed < 1) //goes up a notch if you're RWing
827 if (iPlaySpeed == -1) iPlaySpeed = 1;
832 if (iPlaySpeed > 32 || iPlaySpeed < -32)
835 g_application.m_pPlayer->SetPlaySpeed(iPlaySpeed, g_application.IsMutedInternal());
838 else if (parameter.Equals("next"))
840 g_application.OnAction(CAction(ACTION_NEXT_ITEM));
842 else if (parameter.Equals("previous"))
844 g_application.OnAction(CAction(ACTION_PREV_ITEM));
846 else if (parameter.Equals("bigskipbackward"))
848 if (g_application.m_pPlayer->IsPlaying())
849 g_application.m_pPlayer->Seek(false, true);
851 else if (parameter.Equals("bigskipforward"))
853 if (g_application.m_pPlayer->IsPlaying())
854 g_application.m_pPlayer->Seek(true, true);
856 else if (parameter.Equals("smallskipbackward"))
858 if (g_application.m_pPlayer->IsPlaying())
859 g_application.m_pPlayer->Seek(false, false);
861 else if (parameter.Equals("smallskipforward"))
863 if (g_application.m_pPlayer->IsPlaying())
864 g_application.m_pPlayer->Seek(true, false);
866 else if (StringUtils::StartsWithNoCase(parameter, "seekpercentage"))
868 CStdString offset = "";
869 if (parameter.size() == 14)
870 CLog::Log(LOGERROR,"PlayerControl(seekpercentage(n)) called with no argument");
871 else if (parameter.size() < 17) // arg must be at least "(N)"
872 CLog::Log(LOGERROR,"PlayerControl(seekpercentage(n)) called with invalid argument: \"%s\"", parameter.substr(14).c_str());
875 // Don't bother checking the argument: an invalid arg will do seek(0)
876 offset = parameter.substr(15);
877 StringUtils::TrimRight(offset, ")");
878 float offsetpercent = (float) atof(offset.c_str());
879 if (offsetpercent < 0 || offsetpercent > 100)
880 CLog::Log(LOGERROR,"PlayerControl(seekpercentage(n)) argument, %f, must be 0-100", offsetpercent);
881 else if (g_application.m_pPlayer->IsPlaying())
882 g_application.SeekPercentage(offsetpercent);
885 else if( parameter.Equals("showvideomenu") )
887 if( g_application.m_pPlayer->IsPlaying() )
888 g_application.m_pPlayer->OnAction(CAction(ACTION_SHOW_VIDEOMENU));
890 else if( parameter.Equals("record") )
892 if( g_application.m_pPlayer->IsPlaying() && g_application.m_pPlayer->CanRecord())
893 g_application.m_pPlayer->Record(!g_application.m_pPlayer->IsRecording());
895 else if (StringUtils::StartsWithNoCase(parameter, "partymode"))
897 CStdString strXspPath = "";
898 //empty param=music, "music"=music, "video"=video, else xsp path
899 PartyModeContext context = PARTYMODECONTEXT_MUSIC;
900 if (parameter.size() > 9)
902 if (parameter.size() == 16 && StringUtils::EndsWithNoCase(parameter, "video)"))
903 context = PARTYMODECONTEXT_VIDEO;
904 else if (parameter.size() != 16 || !StringUtils::EndsWithNoCase(parameter, "music)"))
906 strXspPath = parameter.substr(10);
907 StringUtils::TrimRight(strXspPath, ")");
908 context = PARTYMODECONTEXT_UNKNOWN;
911 if (g_partyModeManager.IsEnabled())
912 g_partyModeManager.Disable();
914 g_partyModeManager.Enable(context, strXspPath);
916 else if (parameter.Equals("random") ||
917 parameter.Equals("randomoff") ||
918 parameter.Equals("randomon"))
920 // get current playlist
921 int iPlaylist = g_playlistPlayer.GetCurrentPlaylist();
923 // reverse the current setting
924 bool shuffled = g_playlistPlayer.IsShuffled(iPlaylist);
925 if ((shuffled && parameter.Equals("randomon")) || (!shuffled && parameter.Equals("randomoff")))
928 // check to see if we should notify the user
929 bool notify = (params.size() == 2 && params[1].Equals("notify"));
930 g_playlistPlayer.SetShuffle(iPlaylist, !shuffled, notify);
932 // save settings for now playing windows
936 CMediaSettings::Get().SetMusicPlaylistShuffled(g_playlistPlayer.IsShuffled(iPlaylist));
937 CSettings::Get().Save();
940 CMediaSettings::Get().SetVideoPlaylistShuffled(g_playlistPlayer.IsShuffled(iPlaylist));
941 CSettings::Get().Save();
945 CGUIMessage msg(GUI_MSG_PLAYLISTPLAYER_RANDOM, 0, 0, iPlaylist, g_playlistPlayer.IsShuffled(iPlaylist));
946 g_windowManager.SendThreadMessage(msg);
949 else if (StringUtils::StartsWithNoCase(parameter, "repeat"))
951 // get current playlist
952 int iPlaylist = g_playlistPlayer.GetCurrentPlaylist();
953 PLAYLIST::REPEAT_STATE previous_state = g_playlistPlayer.GetRepeat(iPlaylist);
955 PLAYLIST::REPEAT_STATE state;
956 if (parameter.Equals("repeatall"))
957 state = PLAYLIST::REPEAT_ALL;
958 else if (parameter.Equals("repeatone"))
959 state = PLAYLIST::REPEAT_ONE;
960 else if (parameter.Equals("repeatoff"))
961 state = PLAYLIST::REPEAT_NONE;
962 else if (previous_state == PLAYLIST::REPEAT_NONE)
963 state = PLAYLIST::REPEAT_ALL;
964 else if (previous_state == PLAYLIST::REPEAT_ALL)
965 state = PLAYLIST::REPEAT_ONE;
967 state = PLAYLIST::REPEAT_NONE;
969 if (state == previous_state)
972 // check to see if we should notify the user
973 bool notify = (params.size() == 2 && params[1].Equals("notify"));
974 g_playlistPlayer.SetRepeat(iPlaylist, state, notify);
976 // save settings for now playing windows
980 CMediaSettings::Get().SetMusicPlaylistRepeat(state == PLAYLIST::REPEAT_ALL);
981 CSettings::Get().Save();
984 CMediaSettings::Get().SetVideoPlaylistRepeat(state == PLAYLIST::REPEAT_ALL);
985 CSettings::Get().Save();
988 // send messages so now playing window can get updated
989 CGUIMessage msg(GUI_MSG_PLAYLISTPLAYER_REPEAT, 0, 0, iPlaylist, (int)state);
990 g_windowManager.SendThreadMessage(msg);
993 else if (execute.Equals("playwith"))
995 g_application.m_eForcedNextPlayer = CPlayerCoreFactory::Get().GetPlayerCore(parameter);
996 g_application.OnAction(CAction(ACTION_PLAYER_PLAY));
998 else if (execute.Equals("mute"))
1000 g_application.ToggleMute();
1002 else if (execute.Equals("setvolume"))
1004 float oldVolume = g_application.GetVolume();
1005 float volume = (float)strtod(parameter.c_str(), NULL);
1007 g_application.SetVolume(volume);
1008 if(oldVolume != volume)
1010 if(params.size() > 1 && params[1].Equals("showVolumeBar"))
1012 CApplicationMessenger::Get().ShowVolumeBar(oldVolume < volume);
1016 else if (execute.Equals("playlist.playoffset"))
1018 // playlist.playoffset(offset)
1019 // playlist.playoffset(music|video,offset)
1020 CStdString strPos = parameter;
1021 if (params.size() > 1)
1023 // ignore any other parameters if present
1024 CStdString strPlaylist = params[0];
1027 int iPlaylist = PLAYLIST_NONE;
1028 if (strPlaylist.Equals("music"))
1029 iPlaylist = PLAYLIST_MUSIC;
1030 else if (strPlaylist.Equals("video"))
1031 iPlaylist = PLAYLIST_VIDEO;
1034 if (iPlaylist == PLAYLIST_NONE)
1036 CLog::Log(LOGERROR,"Playlist.PlayOffset called with unknown playlist: %s", strPlaylist.c_str());
1040 // user wants to play the 'other' playlist
1041 if (iPlaylist != g_playlistPlayer.GetCurrentPlaylist())
1043 g_application.StopPlaying();
1044 g_playlistPlayer.Reset();
1045 g_playlistPlayer.SetCurrentPlaylist(iPlaylist);
1048 // play the desired offset
1049 int pos = atol(strPos.c_str());
1050 // playlist is already playing
1051 if (g_application.m_pPlayer->IsPlaying())
1052 g_playlistPlayer.PlayNext(pos);
1053 // we start playing the 'other' playlist so we need to use play to initialize the player state
1055 g_playlistPlayer.Play(pos);
1057 else if (execute.Equals("playlist.clear"))
1059 g_playlistPlayer.Clear();
1061 #ifdef HAS_DVD_DRIVE
1062 else if (execute.Equals("ejecttray"))
1064 g_mediaManager.ToggleTray();
1067 else if( execute.Equals("alarmclock") && params.size() > 1 )
1069 // format is alarmclock(name,command[,seconds,true]);
1071 if (params.size() > 2)
1073 if (params[2].find(':') == std::string::npos)
1074 seconds = static_cast<float>(atoi(params[2].c_str())*60);
1076 seconds = (float)StringUtils::TimeStringToSeconds(params[2]);
1079 { // check if shutdown is specified in particular, and get the time for it
1080 CStdString strHeading;
1081 if (StringUtils::EqualsNoCase(parameter, "shutdowntimer"))
1082 strHeading = g_localizeStrings.Get(20145);
1084 strHeading = g_localizeStrings.Get(13209);
1086 if( CGUIDialogNumeric::ShowAndGetNumber(strTime, strHeading) )
1087 seconds = static_cast<float>(atoi(strTime.c_str())*60);
1091 bool silent = false;
1093 for (unsigned int i = 3; i < params.size() ; i++)
1095 // check "true" for backward comp
1096 if (StringUtils::EqualsNoCase(params[i], "true") || StringUtils::EqualsNoCase(params[i], "silent"))
1098 else if (StringUtils::EqualsNoCase(params[i], "loop"))
1102 if( g_alarmClock.IsRunning() )
1103 g_alarmClock.Stop(params[0],silent);
1104 // no negative times not allowed, loop must have a positive time
1105 if (seconds < 0 || (seconds == 0 && loop))
1107 g_alarmClock.Start(params[0], seconds, params[1], silent, loop);
1109 else if (execute.Equals("notification"))
1111 if (params.size() < 2)
1113 if (params.size() == 4)
1114 CGUIDialogKaiToast::QueueNotification(params[3],params[0],params[1],atoi(params[2].c_str()));
1115 else if (params.size() == 3)
1116 CGUIDialogKaiToast::QueueNotification("",params[0],params[1],atoi(params[2].c_str()));
1118 CGUIDialogKaiToast::QueueNotification(params[0],params[1]);
1120 else if (execute.Equals("cancelalarm"))
1122 bool silent = false;
1123 if (params.size() > 1 && StringUtils::EqualsNoCase(params[1], "true"))
1125 g_alarmClock.Stop(params[0],silent);
1127 else if (execute.Equals("playdvd"))
1129 #ifdef HAS_DVD_DRIVE
1130 bool restart = false;
1131 if (params.size() > 0 && StringUtils::EqualsNoCase(params[0], "restart"))
1133 CAutorun::PlayDisc(g_mediaManager.GetDiscPath(), true, restart);
1136 else if (execute.Equals("ripcd"))
1138 #ifdef HAS_CDDA_RIPPER
1139 CCDDARipper::GetInstance().RipCD();
1142 else if (execute.Equals("skin.togglesetting"))
1144 int setting = CSkinSettings::Get().TranslateBool(parameter);
1145 CSkinSettings::Get().SetBool(setting, !CSkinSettings::Get().GetBool(setting));
1146 CSettings::Get().Save();
1148 else if (execute.Equals("skin.setbool") && params.size())
1150 if (params.size() > 1)
1152 int string = CSkinSettings::Get().TranslateBool(params[0]);
1153 CSkinSettings::Get().SetBool(string, StringUtils::EqualsNoCase(params[1], "true"));
1154 CSettings::Get().Save();
1157 // default is to set it to true
1158 int setting = CSkinSettings::Get().TranslateBool(params[0]);
1159 CSkinSettings::Get().SetBool(setting, true);
1160 CSettings::Get().Save();
1162 else if (execute.Equals("skin.reset"))
1164 CSkinSettings::Get().Reset(parameter);
1165 CSettings::Get().Save();
1167 else if (execute.Equals("skin.resetsettings"))
1169 CSkinSettings::Get().Reset();
1170 CSettings::Get().Save();
1172 else if (execute.Equals("skin.theme"))
1175 vector<CStdString> vecTheme;
1176 CUtil::GetSkinThemes(vecTheme);
1180 // find current theme
1181 if (!StringUtils::EqualsNoCase(CSettings::Get().GetString("lookandfeel.skintheme"), "SKINDEFAULT"))
1183 for (unsigned int i=0;i<vecTheme.size();++i)
1185 CStdString strTmpTheme(CSettings::Get().GetString("lookandfeel.skintheme"));
1186 URIUtils::RemoveExtension(strTmpTheme);
1187 if (vecTheme[i].Equals(strTmpTheme))
1195 int iParam = atoi(parameter.c_str());
1196 if (iParam == 0 || iParam == 1)
1198 else if (iParam == -1)
1200 if (iTheme > (int)vecTheme.size()-1)
1203 iTheme = vecTheme.size()-1;
1205 CStdString strSkinTheme = "SKINDEFAULT";
1206 if (iTheme != -1 && iTheme < (int)vecTheme.size())
1207 strSkinTheme = vecTheme[iTheme];
1209 CSettings::Get().SetString("lookandfeel.skintheme", strSkinTheme);
1210 // also set the default color theme
1211 CStdString colorTheme(URIUtils::ReplaceExtension(strSkinTheme, ".xml"));
1212 if (colorTheme.Equals("Textures.xml"))
1213 colorTheme = "defaults.xml";
1214 CSettings::Get().SetString("lookandfeel.skincolors", colorTheme);
1215 g_application.ReloadSkin();
1217 else if (execute.Equals("skin.setstring") || execute.Equals("skin.setimage") || execute.Equals("skin.setfile") ||
1218 execute.Equals("skin.setpath") || execute.Equals("skin.setnumeric") || execute.Equals("skin.setlargeimage"))
1220 // break the parameter up if necessary
1222 if (params.size() > 1)
1224 string = CSkinSettings::Get().TranslateString(params[0]);
1225 if (execute.Equals("skin.setstring"))
1227 CSkinSettings::Get().SetString(string, params[1]);
1228 CSettings::Get().Save();
1233 string = CSkinSettings::Get().TranslateString(params[0]);
1234 CStdString value = CSkinSettings::Get().GetString(string);
1235 VECSOURCES localShares;
1236 g_mediaManager.GetLocalDrives(localShares);
1237 if (execute.Equals("skin.setstring"))
1239 if (CGUIKeyboardFactory::ShowAndGetInput(value, g_localizeStrings.Get(1029), true))
1240 CSkinSettings::Get().SetString(string, value);
1242 else if (execute.Equals("skin.setnumeric"))
1244 if (CGUIDialogNumeric::ShowAndGetNumber(value, g_localizeStrings.Get(611)))
1245 CSkinSettings::Get().SetString(string, value);
1247 else if (execute.Equals("skin.setimage"))
1249 if (CGUIDialogFileBrowser::ShowAndGetImage(localShares, g_localizeStrings.Get(1030), value))
1250 CSkinSettings::Get().SetString(string, value);
1252 else if (execute.Equals("skin.setlargeimage"))
1254 VECSOURCES *shares = CMediaSourceSettings::Get().GetSources("pictures");
1255 if (!shares) shares = &localShares;
1256 if (CGUIDialogFileBrowser::ShowAndGetImage(*shares, g_localizeStrings.Get(1030), value))
1257 CSkinSettings::Get().SetString(string, value);
1259 else if (execute.Equals("skin.setfile"))
1261 // Note. can only browse one addon type from here
1262 // if browsing for addons, required param[1] is addontype string, with optional param[2]
1263 // as contenttype string see IAddon.h & ADDON::TranslateXX
1264 CStdString strMask = (params.size() > 1) ? params[1] : "";
1265 StringUtils::ToLower(strMask);
1267 if ((type = TranslateType(strMask)) != ADDON_UNKNOWN)
1270 url.SetProtocol("addons");
1271 url.SetHostName("enabled");
1272 url.SetFileName(strMask+"/");
1273 localShares.clear();
1274 CStdString content = (params.size() > 2) ? params[2] : "";
1275 StringUtils::ToLower(content);
1276 url.SetPassword(content);
1278 if (type == ADDON_SCRIPT)
1281 if (CGUIDialogFileBrowser::ShowAndGetFile(url.Get(), strMask, TranslateType(type, true), replace, true, true, true))
1283 if (StringUtils::StartsWithNoCase(replace, "addons://"))
1284 CSkinSettings::Get().SetString(string, URIUtils::GetFileName(replace));
1286 CSkinSettings::Get().SetString(string, replace);
1291 if (params.size() > 2)
1294 URIUtils::AddSlashAtEnd(value);
1296 if (CUtil::GetMatchingSource(value,localShares,bIsSource) < 0) // path is outside shares - add it as a separate one
1299 share.strName = g_localizeStrings.Get(13278);
1300 share.strPath = value;
1301 localShares.push_back(share);
1304 if (CGUIDialogFileBrowser::ShowAndGetFile(localShares, strMask, g_localizeStrings.Get(1033), value))
1305 CSkinSettings::Get().SetString(string, value);
1308 else // execute.Equals("skin.setpath"))
1310 g_mediaManager.GetNetworkLocations(localShares);
1311 if (params.size() > 1)
1314 URIUtils::AddSlashAtEnd(value);
1316 if (CUtil::GetMatchingSource(value,localShares,bIsSource) < 0) // path is outside shares - add it as a separate one
1319 share.strName = g_localizeStrings.Get(13278);
1320 share.strPath = value;
1321 localShares.push_back(share);
1324 if (CGUIDialogFileBrowser::ShowAndGetDirectory(localShares, g_localizeStrings.Get(1031), value))
1325 CSkinSettings::Get().SetString(string, value);
1327 CSettings::Get().Save();
1329 else if (execute.Equals("skin.setaddon") && params.size() > 1)
1331 int string = CSkinSettings::Get().TranslateString(params[0]);
1332 vector<ADDON::TYPE> types;
1333 for (unsigned int i = 1 ; i < params.size() ; i++)
1335 ADDON::TYPE type = TranslateType(params[i]);
1336 if (type != ADDON_UNKNOWN)
1337 types.push_back(type);
1340 if (types.size() > 0 && CGUIWindowAddonBrowser::SelectAddonID(types, result, true) == 1)
1342 CSkinSettings::Get().SetString(string, result);
1343 CSettings::Get().Save();
1346 else if (execute.Equals("dialog.close") && params.size())
1348 bool bForce = false;
1349 if (params.size() > 1 && StringUtils::EqualsNoCase(params[1], "true"))
1351 if (StringUtils::EqualsNoCase(params[0], "all"))
1353 g_windowManager.CloseDialogs(bForce);
1357 int id = CButtonTranslator::TranslateWindow(params[0]);
1358 CGUIWindow *window = (CGUIWindow *)g_windowManager.GetWindow(id);
1359 if (window && window->IsDialog())
1360 ((CGUIDialog *)window)->Close(bForce);
1363 else if (execute.Equals("system.logoff"))
1365 // there was a commit from cptspiff here which was reverted
1366 // for keeping the behaviour from Eden in Frodo - see
1367 // git rev 9ee5f0047b
1368 if (g_windowManager.GetActiveWindow() == WINDOW_LOGIN_SCREEN)
1371 g_application.StopPlaying();
1372 if (g_application.IsMusicScanning())
1373 g_application.StopMusicScan();
1375 if (g_application.IsVideoScanning())
1376 g_application.StopVideoScan();
1378 ADDON::CAddonMgr::Get().StopServices(true);
1380 g_application.getNetwork().NetworkMessage(CNetwork::SERVICES_DOWN,1);
1381 CProfilesManager::Get().LoadMasterProfileForLogin();
1382 g_passwordManager.bMasterUser = false;
1383 g_windowManager.ActivateWindow(WINDOW_LOGIN_SCREEN);
1384 if (!CNetworkServices::Get().StartEventServer()) // event server could be needed in some situations
1385 CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Warning, g_localizeStrings.Get(33102), g_localizeStrings.Get(33100));
1387 else if (execute.Equals("pagedown"))
1389 int id = atoi(parameter.c_str());
1390 CGUIMessage message(GUI_MSG_PAGE_DOWN, g_windowManager.GetFocusedWindow(), id);
1391 g_windowManager.SendMessage(message);
1393 else if (execute.Equals("pageup"))
1395 int id = atoi(parameter.c_str());
1396 CGUIMessage message(GUI_MSG_PAGE_UP, g_windowManager.GetFocusedWindow(), id);
1397 g_windowManager.SendMessage(message);
1399 else if (execute.Equals("updatelibrary") && params.size())
1401 if (params[0].Equals("music"))
1403 if (g_application.IsMusicScanning())
1404 g_application.StopMusicScan();
1406 g_application.StartMusicScan(params.size() > 1 ? params[1] : "");
1408 if (params[0].Equals("video"))
1410 if (g_application.IsVideoScanning())
1411 g_application.StopVideoScan();
1413 g_application.StartVideoScan(params.size() > 1 ? params[1] : "");
1416 else if (execute.Equals("cleanlibrary"))
1418 if (!params.size() || params[0].Equals("video"))
1420 if (!g_application.IsVideoScanning())
1421 g_application.StartVideoCleanup();
1423 CLog::Log(LOGERROR, "XBMC.CleanLibrary is not possible while scanning or cleaning");
1425 else if (params[0].Equals("music"))
1427 if (!g_application.IsMusicScanning())
1429 CMusicDatabase musicdatabase;
1431 musicdatabase.Open();
1432 musicdatabase.Cleanup();
1433 musicdatabase.Close();
1436 CLog::Log(LOGERROR, "XBMC.CleanLibrary is not possible while scanning for media info");
1439 else if (execute.Equals("exportlibrary"))
1442 if (params[0].Equals("music"))
1446 g_mediaManager.GetLocalDrives(shares);
1447 g_mediaManager.GetNetworkLocations(shares);
1448 g_mediaManager.GetRemovableDrives(shares);
1451 bool actorThumbs=false;
1452 bool overwrite=false;
1453 bool cancelled=false;
1455 if (params.size() > 1)
1456 singleFile = params[1].Equals("true");
1458 singleFile = CGUIDialogYesNo::ShowAndGetInput(iHeading,20426,20427,-1,20428,20429,cancelled);
1465 if (params.size() > 2)
1466 thumbs = params[2].Equals("true");
1468 thumbs = CGUIDialogYesNo::ShowAndGetInput(iHeading,20430,-1,-1,cancelled);
1474 if (thumbs && params[0].Equals("video"))
1476 if (params.size() > 4)
1477 actorThumbs = params[4].Equals("true");
1479 actorThumbs = CGUIDialogYesNo::ShowAndGetInput(iHeading,20436,-1,-1,cancelled);
1487 if (params.size() > 3)
1488 overwrite = params[3].Equals("true");
1490 overwrite = CGUIDialogYesNo::ShowAndGetInput(iHeading,20431,-1,-1,cancelled);
1496 if (params.size() > 2)
1498 if (singleFile || !path.empty() ||
1499 CGUIDialogFileBrowser::ShowAndGetDirectory(shares,
1500 g_localizeStrings.Get(661), path, true))
1502 if (params[0].Equals("video"))
1504 CVideoDatabase videodatabase;
1505 videodatabase.Open();
1506 videodatabase.ExportToXML(path, singleFile, thumbs, actorThumbs, overwrite);
1507 videodatabase.Close();
1511 if (URIUtils::HasSlashAtEnd(path))
1512 path = URIUtils::AddFileToFolder(path, "musicdb.xml");
1513 CMusicDatabase musicdatabase;
1514 musicdatabase.Open();
1515 musicdatabase.ExportToXML(path, singleFile, thumbs, overwrite);
1516 musicdatabase.Close();
1520 else if (execute.Equals("control.move") && params.size() > 1)
1522 CGUIMessage message(GUI_MSG_MOVE_OFFSET, g_windowManager.GetFocusedWindow(), atoi(params[0].c_str()), atoi(params[1].c_str()));
1523 g_windowManager.SendMessage(message);
1525 else if (execute.Equals("container.refresh"))
1526 { // NOTE: These messages require a media window, thus they're sent to the current activewindow.
1527 // This shouldn't stop a dialog intercepting it though.
1528 CGUIMessage message(GUI_MSG_NOTIFY_ALL, g_windowManager.GetActiveWindow(), 0, GUI_MSG_UPDATE, 1); // 1 to reset the history
1529 message.SetStringParam(parameter);
1530 g_windowManager.SendMessage(message);
1532 else if (execute.Equals("container.update") && params.size())
1534 CGUIMessage message(GUI_MSG_NOTIFY_ALL, g_windowManager.GetActiveWindow(), 0, GUI_MSG_UPDATE, 0);
1535 message.SetStringParam(params[0]);
1536 if (params.size() > 1 && StringUtils::EqualsNoCase(params[1], "replace"))
1537 message.SetParam2(1); // reset the history
1538 g_windowManager.SendMessage(message);
1540 else if (execute.Equals("container.nextviewmode"))
1542 CGUIMessage message(GUI_MSG_CHANGE_VIEW_MODE, g_windowManager.GetActiveWindow(), 0, 0, 1);
1543 g_windowManager.SendMessage(message);
1545 else if (execute.Equals("container.previousviewmode"))
1547 CGUIMessage message(GUI_MSG_CHANGE_VIEW_MODE, g_windowManager.GetActiveWindow(), 0, 0, -1);
1548 g_windowManager.SendMessage(message);
1550 else if (execute.Equals("container.setviewmode"))
1552 CGUIMessage message(GUI_MSG_CHANGE_VIEW_MODE, g_windowManager.GetActiveWindow(), 0, atoi(parameter.c_str()));
1553 g_windowManager.SendMessage(message);
1555 else if (execute.Equals("container.nextsortmethod"))
1557 CGUIMessage message(GUI_MSG_CHANGE_SORT_METHOD, g_windowManager.GetActiveWindow(), 0, 0, 1);
1558 g_windowManager.SendMessage(message);
1560 else if (execute.Equals("container.previoussortmethod"))
1562 CGUIMessage message(GUI_MSG_CHANGE_SORT_METHOD, g_windowManager.GetActiveWindow(), 0, 0, -1);
1563 g_windowManager.SendMessage(message);
1565 else if (execute.Equals("container.setsortmethod"))
1567 CGUIMessage message(GUI_MSG_CHANGE_SORT_METHOD, g_windowManager.GetActiveWindow(), 0, atoi(parameter.c_str()));
1568 g_windowManager.SendMessage(message);
1570 else if (execute.Equals("container.sortdirection"))
1572 CGUIMessage message(GUI_MSG_CHANGE_SORT_DIRECTION, g_windowManager.GetActiveWindow(), 0, 0);
1573 g_windowManager.SendMessage(message);
1575 else if (execute.Equals("control.message") && params.size() >= 2)
1577 int controlID = atoi(params[0].c_str());
1578 int windowID = (params.size() == 3) ? CButtonTranslator::TranslateWindow(params[2]) : g_windowManager.GetActiveWindow();
1579 if (params[1] == "moveup")
1580 g_windowManager.SendMessage(GUI_MSG_MOVE_OFFSET, windowID, controlID, 1);
1581 else if (params[1] == "movedown")
1582 g_windowManager.SendMessage(GUI_MSG_MOVE_OFFSET, windowID, controlID, -1);
1583 else if (params[1] == "pageup")
1584 g_windowManager.SendMessage(GUI_MSG_PAGE_UP, windowID, controlID);
1585 else if (params[1] == "pagedown")
1586 g_windowManager.SendMessage(GUI_MSG_PAGE_DOWN, windowID, controlID);
1587 else if (params[1] == "click")
1588 g_windowManager.SendMessage(GUI_MSG_CLICKED, controlID, windowID);
1590 else if (execute.Equals("sendclick") && params.size())
1592 if (params.size() == 2)
1594 // have a window - convert it
1595 int windowID = CButtonTranslator::TranslateWindow(params[0]);
1596 CGUIMessage message(GUI_MSG_CLICKED, atoi(params[1].c_str()), windowID);
1597 g_windowManager.SendMessage(message);
1600 { // single param - assume you meant the active window
1601 CGUIMessage message(GUI_MSG_CLICKED, atoi(params[0].c_str()), g_windowManager.GetActiveWindow());
1602 g_windowManager.SendMessage(message);
1605 else if (execute.Equals("action") && params.size())
1607 // try translating the action from our ButtonTranslator
1609 if (CButtonTranslator::TranslateActionString(params[0].c_str(), actionID))
1611 int windowID = params.size() == 2 ? CButtonTranslator::TranslateWindow(params[1]) : WINDOW_INVALID;
1612 CApplicationMessenger::Get().SendAction(CAction(actionID), windowID);
1615 else if (execute.Equals("setproperty") && params.size() >= 2)
1617 CGUIWindow *window = g_windowManager.GetWindow(params.size() > 2 ? CButtonTranslator::TranslateWindow(params[2]) : g_windowManager.GetFocusedWindow());
1619 window->SetProperty(params[0],params[1]);
1621 else if (execute.Equals("clearproperty") && params.size())
1623 CGUIWindow *window = g_windowManager.GetWindow(params.size() > 1 ? CButtonTranslator::TranslateWindow(params[1]) : g_windowManager.GetFocusedWindow());
1625 window->SetProperty(params[0],"");
1627 else if (execute.Equals("wakeonlan"))
1629 g_application.getNetwork().WakeOnLan((char*)params[0].c_str());
1631 else if (execute.Equals("addon.default.opensettings") && params.size() == 1)
1634 ADDON::TYPE type = TranslateType(params[0]);
1635 if (CAddonMgr::Get().GetDefault(type, addon))
1637 CGUIDialogAddonSettings::ShowAndGetInput(addon);
1638 if (type == ADDON_VIZ)
1639 g_windowManager.SendMessage(GUI_MSG_VISUALISATION_RELOAD, 0, 0);
1642 else if (execute.Equals("addon.default.set") && params.size() == 1)
1645 TYPE type = TranslateType(params[0]);
1646 bool allowNone = false;
1647 if (type == ADDON_VIZ)
1650 if (type != ADDON_UNKNOWN &&
1651 CGUIWindowAddonBrowser::SelectAddonID(type,addonID,allowNone))
1653 CAddonMgr::Get().SetDefault(type,addonID);
1654 if (type == ADDON_VIZ)
1655 g_windowManager.SendMessage(GUI_MSG_VISUALISATION_RELOAD, 0, 0);
1658 else if (execute.Equals("addon.opensettings") && params.size() == 1)
1661 if (CAddonMgr::Get().GetAddon(params[0], addon))
1662 CGUIDialogAddonSettings::ShowAndGetInput(addon);
1664 else if (execute.Equals("updateaddonrepos"))
1666 CAddonInstaller::Get().UpdateRepos(true);
1668 else if (execute.Equals("updatelocaladdons"))
1670 CAddonMgr::Get().FindAddons();
1672 else if (execute.Equals("toggledpms"))
1674 g_application.ToggleDPMS(true);
1676 else if (execute.Equals("cectogglestate"))
1678 CApplicationMessenger::Get().CECToggleState();
1680 else if (execute.Equals("cecactivatesource"))
1682 CApplicationMessenger::Get().CECActivateSource();
1684 else if (execute.Equals("cecstandby"))
1686 CApplicationMessenger::Get().CECStandby();
1688 #if defined(HAS_LIRC) || defined(HAS_IRSERVERSUITE)
1689 else if (execute.Equals("lirc.stop"))
1691 g_RemoteControl.Disconnect();
1692 g_RemoteControl.setUsed(false);
1694 else if (execute.Equals("lirc.start"))
1696 g_RemoteControl.setUsed(true);
1697 g_RemoteControl.Initialize();
1699 else if (execute.Equals("lirc.send"))
1702 for (int i = 0; i < (int)params.size(); i++)
1704 command += params[i];
1705 if (i < (int)params.size() - 1)
1708 g_RemoteControl.AddSendCommand(command);
1711 else if (execute.Equals("weather.locationset"))
1713 int loc = atoi(params[0]);
1714 CGUIMessage msg(GUI_MSG_ITEM_SELECT, 0, 0, loc);
1715 g_windowManager.SendMessage(msg, WINDOW_WEATHER);
1717 else if (execute.Equals("weather.locationnext"))
1719 CGUIMessage msg(GUI_MSG_MOVE_OFFSET, 0, 0, 1);
1720 g_windowManager.SendMessage(msg, WINDOW_WEATHER);
1722 else if (execute.Equals("weather.locationprevious"))
1724 CGUIMessage msg(GUI_MSG_MOVE_OFFSET, 0, 0, -1);
1725 g_windowManager.SendMessage(msg, WINDOW_WEATHER);
1727 else if (execute.Equals("weather.refresh"))
1729 CGUIMessage msg(GUI_MSG_MOVE_OFFSET, 0, 0, 0);
1730 g_windowManager.SendMessage(msg, WINDOW_WEATHER);
1732 else if (execute.Equals("videolibrary.search"))
1734 CGUIMessage msg(GUI_MSG_SEARCH, 0, 0, 0);
1735 g_windowManager.SendMessage(msg, WINDOW_VIDEO_NAV);
1737 else if (execute.Equals("toggledebug"))
1739 bool debug = CSettings::Get().GetBool("debug.showloginfo");
1740 CSettings::Get().SetBool("debug.showloginfo", !debug);
1741 g_advancedSettings.SetDebugMode(!debug);
1743 else if (execute.Equals("startpvrmanager"))
1745 g_application.StartPVRManager();
1747 else if (execute.Equals("stoppvrmanager"))
1749 g_application.StopPVRManager();
1751 else if (execute.Equals("StartAndroidActivity") && params.size() > 0)
1753 CApplicationMessenger::Get().StartAndroidActivity(params);
1755 else if (execute.Equals("SetStereoMode") && !parameter.empty())
1757 CAction action = CStereoscopicsManager::Get().ConvertActionCommandToAction(execute, parameter);
1758 if (action.GetID() != ACTION_NONE)
1759 CApplicationMessenger::Get().SendAction(action);
1762 CLog::Log(LOGERROR,"Builtin 'SetStereoMode' called with unknown parameter: %s", parameter.c_str());