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 (function.CompareNoCase(commands[i].command) == 0 && (!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);
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.IsEmpty())
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 #if defined(TARGET_DARWIN_IOS)
396 if (params[0].Equals("shutdownmenu"))
397 CBuiltins::Execute("Quit");
399 g_windowManager.ActivateWindow(iWindow, params, !execute.Equals("activatewindow"));
403 CLog::Log(LOGERROR, "Activate/ReplaceWindow called with invalid destination window: %s", strWindow.c_str());
407 else if ((execute.Equals("setfocus") || execute.Equals("control.setfocus")) && params.size())
409 int controlID = atol(params[0].c_str());
410 int subItem = (params.size() > 1) ? atol(params[1].c_str())+1 : 0;
411 CGUIMessage msg(GUI_MSG_SETFOCUS, g_windowManager.GetFocusedWindow(), controlID, subItem);
412 g_windowManager.SendMessage(msg);
414 else if ((execute.Equals("activatewindowandfocus") || execute.Equals("replacewindowandfocus")) && params.size())
416 CStdString strWindow = params[0];
418 // confirm the window destination is valid prior to switching
419 int iWindow = CButtonTranslator::TranslateWindow(strWindow);
420 if (iWindow != WINDOW_INVALID)
422 // disable the screensaver
423 g_application.WakeUpScreenSaverAndDPMS();
424 #if defined(TARGET_DARWIN_IOS)
425 if (params[0].Equals("shutdownmenu"))
426 CBuiltins::Execute("Quit");
428 vector<CStdString> dummy;
429 g_windowManager.ActivateWindow(iWindow, dummy, !execute.Equals("activatewindowandfocus"));
431 unsigned int iPtr = 1;
432 while (params.size() > iPtr + 1)
434 CGUIMessage msg(GUI_MSG_SETFOCUS, g_windowManager.GetFocusedWindow(),
435 atol(params[iPtr].c_str()),
436 (params.size() >= iPtr + 2) ? atol(params[iPtr + 1].c_str())+1 : 0);
437 g_windowManager.SendMessage(msg);
443 CLog::Log(LOGERROR, "Replace/ActivateWindowAndFocus called with invalid destination window: %s", strWindow.c_str());
447 else if (execute.Equals("runscript") && params.size())
449 #if defined(TARGET_DARWIN_OSX)
450 if (URIUtils::HasExtension(strParameterCaseIntact, ".applescript|.scpt"))
452 CStdString osxPath = CSpecialProtocol::TranslatePath(strParameterCaseIntact);
453 Cocoa_DoAppleScriptFile(osxPath.c_str());
459 for (vector<CStdString>::const_iterator param = params.begin(); param != params.end(); ++param)
460 argv.push_back(*param);
462 vector<CStdString> path;
463 //split the path up to find the filename
464 StringUtils::SplitString(params[0],"\\",path);
466 argv[0] = path[path.size() - 1];
469 CStdString scriptpath(params[0]);
470 if (CAddonMgr::Get().GetAddon(params[0], script))
471 scriptpath = script->LibPath();
473 CScriptInvocationManager::Get().Execute(scriptpath, script, argv);
476 #if defined(TARGET_DARWIN_OSX)
477 else if (execute.Equals("runapplescript"))
479 Cocoa_DoAppleScript(strParameterCaseIntact.c_str());
482 else if (execute.Equals("stopscript"))
484 CStdString scriptpath(params[0]);
486 // Test to see if the param is an addon ID
488 if (CAddonMgr::Get().GetAddon(params[0], script))
489 scriptpath = script->LibPath();
491 CScriptInvocationManager::Get().Stop(scriptpath);
493 else if (execute.Equals("system.exec"))
495 CApplicationMessenger::Get().Minimize();
496 CApplicationMessenger::Get().ExecOS(parameter, false);
498 else if (execute.Equals("system.execwait"))
500 CApplicationMessenger::Get().Minimize();
501 CApplicationMessenger::Get().ExecOS(parameter, true);
503 else if (execute.Equals("resolution"))
505 RESOLUTION res = RES_PAL_4x3;
506 if (parameter.Equals("pal")) res = RES_PAL_4x3;
507 else if (parameter.Equals("pal16x9")) res = RES_PAL_16x9;
508 else if (parameter.Equals("ntsc")) res = RES_NTSC_4x3;
509 else if (parameter.Equals("ntsc16x9")) res = RES_NTSC_16x9;
510 else if (parameter.Equals("720p")) res = RES_HDTV_720p;
511 else if (parameter.Equals("720pSBS")) res = RES_HDTV_720pSBS;
512 else if (parameter.Equals("720pTB")) res = RES_HDTV_720pTB;
513 else if (parameter.Equals("1080pSBS")) res = RES_HDTV_1080pSBS;
514 else if (parameter.Equals("1080pTB")) res = RES_HDTV_1080pTB;
515 else if (parameter.Equals("1080i")) res = RES_HDTV_1080i;
516 if (g_graphicsContext.IsValidResolution(res))
518 CDisplaySettings::Get().SetCurrentResolution(res, true);
519 g_application.ReloadSkin();
522 else if (execute.Equals("extract") && params.size())
524 // Detects if file is zip or rar then extracts
525 CStdString strDestDirect;
526 if (params.size() < 2)
527 strDestDirect = URIUtils::GetDirectory(params[0]);
529 strDestDirect = params[1];
531 URIUtils::AddSlashAtEnd(strDestDirect);
533 if (URIUtils::IsZIP(params[0]))
534 g_ZipManager.ExtractArchive(params[0],strDestDirect);
535 #ifdef HAS_FILESYSTEM_RAR
536 else if (URIUtils::IsRAR(params[0]))
537 g_RarManager.ExtractArchive(params[0],strDestDirect);
540 CLog::Log(LOGERROR, "XBMC.Extract, No archive given");
542 else if (execute.Equals("runplugin"))
546 CFileItem item(params[0]);
547 if (!item.m_bIsFolder)
549 item.SetPath(params[0]);
550 CPluginDirectory::RunScriptWithParams(item.GetPath());
555 CLog::Log(LOGERROR, "XBMC.RunPlugin called with no arguments.");
558 else if (execute.Equals("runaddon"))
563 if (CAddonMgr::Get().GetAddon(params[0],addon) && addon)
565 PluginPtr plugin = boost::dynamic_pointer_cast<CPluginSource>(addon);
567 if (plugin && addon->Type() == ADDON_PLUGIN)
569 CStdString addonid = params[0];
570 CStdString urlParameters;
571 CStdStringArray parameters;
572 if (params.size() == 2 &&
573 (StringUtils::StartsWith(params[1], "/") || StringUtils::StartsWith(params[1], "?")))
574 urlParameters = params[1];
575 else if (params.size() > 1)
577 parameters.insert(parameters.begin(), params.begin() + 1, params.end());
578 urlParameters = "?" + StringUtils::JoinString(parameters, "&");
581 if (plugin->Provides(CPluginSource::VIDEO))
582 cmd.Format("ActivateWindow(Video,plugin://%s%s,return)", addonid, urlParameters);
583 else if (plugin->Provides(CPluginSource::AUDIO))
584 cmd.Format("ActivateWindow(Music,plugin://%s%s,return)", addonid, urlParameters);
585 else if (plugin->Provides(CPluginSource::EXECUTABLE))
586 cmd.Format("ActivateWindow(Programs,plugin://%s%s,return)", addonid, urlParameters);
587 else if (plugin->Provides(CPluginSource::IMAGE))
588 cmd.Format("ActivateWindow(Pictures,plugin://%s%s,return)", addonid, urlParameters);
590 // Pass the script name (params[0]) and all the parameters
591 // (params[1] ... params[x]) separated by a comma to RunPlugin
592 cmd.Format("RunPlugin(%s)", StringUtils::JoinString(params, ","));
594 else if (addon->Type() >= ADDON_SCRIPT && addon->Type() <= ADDON_SCRIPT_LYRICS)
595 // Pass the script name (params[0]) and all the parameters
596 // (params[1] ... params[x]) separated by a comma to RunScript
597 cmd.Format("RunScript(%s)", StringUtils::JoinString(params, ","));
604 CLog::Log(LOGERROR, "XBMC.RunAddon called with no arguments.");
607 else if (execute.Equals("notifyall"))
609 if (params.size() > 1)
612 if (params.size() > 2)
613 data = CJSONVariantParser::Parse((const unsigned char *)params[2].c_str(), params[2].size());
615 ANNOUNCEMENT::CAnnouncementManager::Announce(ANNOUNCEMENT::Other, params[0], params[1], data);
618 CLog::Log(LOGERROR, "XBMC.NotifyAll needs two parameters");
620 else if (execute.Equals("playmedia"))
624 CLog::Log(LOGERROR, "XBMC.PlayMedia called with empty parameter");
628 CFileItem item(params[0], false);
629 if (URIUtils::HasSlashAtEnd(params[0]))
630 item.m_bIsFolder = true;
632 // restore to previous window if needed
633 if( g_windowManager.GetActiveWindow() == WINDOW_SLIDESHOW ||
634 g_windowManager.GetActiveWindow() == WINDOW_FULLSCREEN_VIDEO ||
635 g_windowManager.GetActiveWindow() == WINDOW_VISUALISATION )
636 g_windowManager.PreviousWindow();
639 g_application.ResetScreenSaver();
640 g_application.WakeUpScreenSaverAndDPMS();
642 // ask if we need to check guisettings to resume
643 bool askToResume = true;
645 for (unsigned int i = 1 ; i < params.size() ; i++)
647 if (params[i].Equals("isdir"))
648 item.m_bIsFolder = true;
649 else if (params[i].Equals("1")) // set fullscreen or windowed
650 CMediaSettings::Get().SetVideoStartWindowed(true);
651 else if (params[i].Equals("resume"))
653 // force the item to resume (if applicable) (see CApplication::PlayMedia)
654 item.m_lStartOffset = STARTOFFSET_RESUME;
657 else if (params[i].Equals("noresume"))
659 // force the item to start at the beginning (m_lStartOffset is initialized to 0)
662 else if (StringUtils::StartsWithNoCase(params[i], "playoffset=")) {
663 playOffset = atoi(params[i].Mid(11)) - 1;
664 item.SetProperty("playlist_starting_track", playOffset);
668 if (!item.m_bIsFolder && item.IsPlugin())
669 item.SetProperty("IsPlayable", true);
671 if ( askToResume == true )
673 if ( CGUIWindowVideoBase::ShowResumeMenu(item) == false )
676 if (item.m_bIsFolder)
679 CStdString extensions = g_advancedSettings.m_videoExtensions + "|" + g_advancedSettings.m_musicExtensions;
680 CDirectory::GetDirectory(item.GetPath(),items,extensions);
682 bool containsMusic = false, containsVideo = false;
683 for (int i = 0; i < items.Size(); i++)
685 bool isVideo = items[i]->IsVideo();
686 containsMusic |= !isVideo;
687 containsVideo |= isVideo;
689 if (containsMusic && containsVideo)
693 int playlist = containsVideo? PLAYLIST_VIDEO : PLAYLIST_MUSIC;;
694 if (containsMusic && containsVideo) //mixed content found in the folder
696 for (int i = items.Size() - 1; i >= 0; i--) //remove music entries
698 if (!items[i]->IsVideo())
703 g_playlistPlayer.ClearPlaylist(playlist);
704 g_playlistPlayer.Add(playlist, items);
705 g_playlistPlayer.SetCurrentPlaylist(playlist);
706 g_playlistPlayer.Play(playOffset);
710 int playlist = item.IsAudio() ? PLAYLIST_MUSIC : PLAYLIST_VIDEO;
711 g_playlistPlayer.ClearPlaylist(playlist);
712 g_playlistPlayer.SetCurrentPlaylist(playlist);
715 if (!g_application.PlayMedia(item, playlist))
717 CLog::Log(LOGERROR, "XBMC.PlayMedia could not play media: %s", params[0].c_str());
722 else if (execute.Equals("showPicture"))
726 CLog::Log(LOGERROR, "XBMC.ShowPicture called with empty parameter");
729 CGUIMessage msg(GUI_MSG_SHOW_PICTURE, 0, 0);
730 msg.SetStringParam(params[0]);
731 CGUIWindow *pWindow = g_windowManager.GetWindow(WINDOW_SLIDESHOW);
732 if (pWindow) pWindow->OnMessage(msg);
734 else if (execute.Equals("slideShow") || execute.Equals("recursiveslideShow"))
738 CLog::Log(LOGERROR, "XBMC.SlideShow called with empty parameter");
741 std::string beginSlidePath;
742 // leave RecursiveSlideShow command as-is
743 unsigned int flags = 0;
744 if (execute.Equals("RecursiveSlideShow"))
747 // SlideShow(dir[,recursive][,[not]random][,pause][,beginslide="/path/to/start/slide.jpg"])
748 // the beginslide value need be escaped (for '"' or '\' in it, by backslash)
749 // and then quoted, or not. See CUtil::SplitParams()
752 for (unsigned int i = 1 ; i < params.size() ; i++)
754 if (params[i].Equals("recursive"))
756 else if (params[i].Equals("random")) // set fullscreen or windowed
758 else if (params[i].Equals("notrandom"))
760 else if (params[i].Equals("pause"))
762 else if (StringUtils::StartsWithNoCase(params[i], "beginslide="))
763 beginSlidePath = params[i].Mid(11);
767 CGUIMessage msg(GUI_MSG_START_SLIDESHOW, 0, 0, flags);
768 vector<CStdString> strParams;
769 strParams.push_back(params[0]);
770 strParams.push_back(beginSlidePath);
771 msg.SetStringParams(strParams);
772 CGUIWindow *pWindow = g_windowManager.GetWindow(WINDOW_SLIDESHOW);
773 if (pWindow) pWindow->OnMessage(msg);
775 else if (execute.Equals("reloadskin"))
778 g_application.ReloadSkin(!params.empty() && StringUtils::EqualsNoCase(params[0], "confirm"));
780 else if (execute.Equals("unloadskin"))
782 g_application.UnloadSkin(true); // we're reloading the skin after this
784 else if (execute.Equals("refreshrss"))
786 CRssManager::Get().Reload();
788 else if (execute.Equals("playercontrol"))
790 g_application.ResetScreenSaver();
791 g_application.WakeUpScreenSaverAndDPMS();
794 CLog::Log(LOGERROR, "XBMC.PlayerControl called with empty parameter");
797 if (parameter.Equals("play"))
799 // either resume playing, or pause
800 if (g_application.m_pPlayer->IsPlaying())
802 if (g_application.m_pPlayer->GetPlaySpeed() != 1)
803 g_application.m_pPlayer->SetPlaySpeed(1, g_application.IsMutedInternal());
805 g_application.m_pPlayer->Pause();
808 else if (parameter.Equals("stop"))
810 g_application.StopPlaying();
812 else if (parameter.Equals("rewind") || parameter.Equals("forward"))
814 if (g_application.m_pPlayer->IsPlaying() && !g_application.m_pPlayer->IsPaused())
816 int iPlaySpeed = g_application.m_pPlayer->GetPlaySpeed();
817 if (parameter.Equals("rewind") && iPlaySpeed == 1) // Enables Rewinding
819 else if (parameter.Equals("rewind") && iPlaySpeed > 1) //goes down a notch if you're FFing
821 else if (parameter.Equals("forward") && iPlaySpeed < 1) //goes up a notch if you're RWing
824 if (iPlaySpeed == -1) iPlaySpeed = 1;
829 if (iPlaySpeed > 32 || iPlaySpeed < -32)
832 g_application.m_pPlayer->SetPlaySpeed(iPlaySpeed, g_application.IsMutedInternal());
835 else if (parameter.Equals("next"))
837 g_application.OnAction(CAction(ACTION_NEXT_ITEM));
839 else if (parameter.Equals("previous"))
841 g_application.OnAction(CAction(ACTION_PREV_ITEM));
843 else if (parameter.Equals("bigskipbackward"))
845 if (g_application.m_pPlayer->IsPlaying())
846 g_application.m_pPlayer->Seek(false, true);
848 else if (parameter.Equals("bigskipforward"))
850 if (g_application.m_pPlayer->IsPlaying())
851 g_application.m_pPlayer->Seek(true, true);
853 else if (parameter.Equals("smallskipbackward"))
855 if (g_application.m_pPlayer->IsPlaying())
856 g_application.m_pPlayer->Seek(false, false);
858 else if (parameter.Equals("smallskipforward"))
860 if (g_application.m_pPlayer->IsPlaying())
861 g_application.m_pPlayer->Seek(true, false);
863 else if (StringUtils::StartsWithNoCase(parameter, "seekpercentage"))
865 CStdString offset = "";
866 if (parameter.size() == 14)
867 CLog::Log(LOGERROR,"PlayerControl(seekpercentage(n)) called with no argument");
868 else if (parameter.size() < 17) // arg must be at least "(N)"
869 CLog::Log(LOGERROR,"PlayerControl(seekpercentage(n)) called with invalid argument: \"%s\"", parameter.Mid(14).c_str());
872 // Don't bother checking the argument: an invalid arg will do seek(0)
873 offset = parameter.Mid(15).TrimRight(")");
874 float offsetpercent = (float) atof(offset.c_str());
875 if (offsetpercent < 0 || offsetpercent > 100)
876 CLog::Log(LOGERROR,"PlayerControl(seekpercentage(n)) argument, %f, must be 0-100", offsetpercent);
877 else if (g_application.m_pPlayer->IsPlaying())
878 g_application.SeekPercentage(offsetpercent);
881 else if( parameter.Equals("showvideomenu") )
883 if( g_application.m_pPlayer->IsPlaying() )
884 g_application.m_pPlayer->OnAction(CAction(ACTION_SHOW_VIDEOMENU));
886 else if( parameter.Equals("record") )
888 if( g_application.m_pPlayer->IsPlaying() && g_application.m_pPlayer->CanRecord())
889 g_application.m_pPlayer->Record(!g_application.m_pPlayer->IsRecording());
891 else if (StringUtils::StartsWithNoCase(parameter, "partymode"))
893 CStdString strXspPath = "";
894 //empty param=music, "music"=music, "video"=video, else xsp path
895 PartyModeContext context = PARTYMODECONTEXT_MUSIC;
896 if (parameter.size() > 9)
898 if (parameter.size() == 16 && StringUtils::EndsWithNoCase(parameter, "video)"))
899 context = PARTYMODECONTEXT_VIDEO;
900 else if (parameter.size() != 16 || !StringUtils::EndsWithNoCase(parameter, "music)"))
902 strXspPath = parameter.Mid(10).TrimRight(")");
903 context = PARTYMODECONTEXT_UNKNOWN;
906 if (g_partyModeManager.IsEnabled())
907 g_partyModeManager.Disable();
909 g_partyModeManager.Enable(context, strXspPath);
911 else if (parameter.Equals("random") ||
912 parameter.Equals("randomoff") ||
913 parameter.Equals("randomon"))
915 // get current playlist
916 int iPlaylist = g_playlistPlayer.GetCurrentPlaylist();
918 // reverse the current setting
919 bool shuffled = g_playlistPlayer.IsShuffled(iPlaylist);
920 if ((shuffled && parameter.Equals("randomon")) || (!shuffled && parameter.Equals("randomoff")))
923 // check to see if we should notify the user
924 bool notify = (params.size() == 2 && params[1].Equals("notify"));
925 g_playlistPlayer.SetShuffle(iPlaylist, !shuffled, notify);
927 // save settings for now playing windows
931 CMediaSettings::Get().SetMusicPlaylistShuffled(g_playlistPlayer.IsShuffled(iPlaylist));
932 CSettings::Get().Save();
935 CMediaSettings::Get().SetVideoPlaylistShuffled(g_playlistPlayer.IsShuffled(iPlaylist));
936 CSettings::Get().Save();
940 CGUIMessage msg(GUI_MSG_PLAYLISTPLAYER_RANDOM, 0, 0, iPlaylist, g_playlistPlayer.IsShuffled(iPlaylist));
941 g_windowManager.SendThreadMessage(msg);
944 else if (StringUtils::StartsWithNoCase(parameter, "repeat"))
946 // get current playlist
947 int iPlaylist = g_playlistPlayer.GetCurrentPlaylist();
948 PLAYLIST::REPEAT_STATE previous_state = g_playlistPlayer.GetRepeat(iPlaylist);
950 PLAYLIST::REPEAT_STATE state;
951 if (parameter.Equals("repeatall"))
952 state = PLAYLIST::REPEAT_ALL;
953 else if (parameter.Equals("repeatone"))
954 state = PLAYLIST::REPEAT_ONE;
955 else if (parameter.Equals("repeatoff"))
956 state = PLAYLIST::REPEAT_NONE;
957 else if (previous_state == PLAYLIST::REPEAT_NONE)
958 state = PLAYLIST::REPEAT_ALL;
959 else if (previous_state == PLAYLIST::REPEAT_ALL)
960 state = PLAYLIST::REPEAT_ONE;
962 state = PLAYLIST::REPEAT_NONE;
964 if (state == previous_state)
967 // check to see if we should notify the user
968 bool notify = (params.size() == 2 && params[1].Equals("notify"));
969 g_playlistPlayer.SetRepeat(iPlaylist, state, notify);
971 // save settings for now playing windows
975 CMediaSettings::Get().SetMusicPlaylistRepeat(state == PLAYLIST::REPEAT_ALL);
976 CSettings::Get().Save();
979 CMediaSettings::Get().SetVideoPlaylistRepeat(state == PLAYLIST::REPEAT_ALL);
980 CSettings::Get().Save();
983 // send messages so now playing window can get updated
984 CGUIMessage msg(GUI_MSG_PLAYLISTPLAYER_REPEAT, 0, 0, iPlaylist, (int)state);
985 g_windowManager.SendThreadMessage(msg);
988 else if (execute.Equals("playwith"))
990 g_application.m_eForcedNextPlayer = CPlayerCoreFactory::Get().GetPlayerCore(parameter);
991 g_application.OnAction(CAction(ACTION_PLAYER_PLAY));
993 else if (execute.Equals("mute"))
995 g_application.ToggleMute();
997 else if (execute.Equals("setvolume"))
999 float oldVolume = g_application.GetVolume();
1000 float volume = (float)strtod(parameter.c_str(), NULL);
1002 g_application.SetVolume(volume);
1003 if(oldVolume != volume)
1005 if(params.size() > 1 && params[1].Equals("showVolumeBar"))
1007 CApplicationMessenger::Get().ShowVolumeBar(oldVolume < volume);
1011 else if (execute.Equals("playlist.playoffset"))
1013 // playlist.playoffset(offset)
1014 // playlist.playoffset(music|video,offset)
1015 CStdString strPos = parameter;
1016 if (params.size() > 1)
1018 // ignore any other parameters if present
1019 CStdString strPlaylist = params[0];
1022 int iPlaylist = PLAYLIST_NONE;
1023 if (strPlaylist.Equals("music"))
1024 iPlaylist = PLAYLIST_MUSIC;
1025 else if (strPlaylist.Equals("video"))
1026 iPlaylist = PLAYLIST_VIDEO;
1029 if (iPlaylist == PLAYLIST_NONE)
1031 CLog::Log(LOGERROR,"Playlist.PlayOffset called with unknown playlist: %s", strPlaylist.c_str());
1035 // user wants to play the 'other' playlist
1036 if (iPlaylist != g_playlistPlayer.GetCurrentPlaylist())
1038 g_application.StopPlaying();
1039 g_playlistPlayer.Reset();
1040 g_playlistPlayer.SetCurrentPlaylist(iPlaylist);
1043 // play the desired offset
1044 int pos = atol(strPos.c_str());
1045 // playlist is already playing
1046 if (g_application.m_pPlayer->IsPlaying())
1047 g_playlistPlayer.PlayNext(pos);
1048 // we start playing the 'other' playlist so we need to use play to initialize the player state
1050 g_playlistPlayer.Play(pos);
1052 else if (execute.Equals("playlist.clear"))
1054 g_playlistPlayer.Clear();
1056 #ifdef HAS_DVD_DRIVE
1057 else if (execute.Equals("ejecttray"))
1059 g_mediaManager.ToggleTray();
1062 else if( execute.Equals("alarmclock") && params.size() > 1 )
1064 // format is alarmclock(name,command[,seconds,true]);
1066 if (params.size() > 2)
1068 if (params[2].Find(':') == -1)
1069 seconds = static_cast<float>(atoi(params[2].c_str())*60);
1071 seconds = (float)StringUtils::TimeStringToSeconds(params[2]);
1074 { // check if shutdown is specified in particular, and get the time for it
1075 CStdString strHeading;
1076 if (parameter.CompareNoCase("shutdowntimer") == 0)
1077 strHeading = g_localizeStrings.Get(20145);
1079 strHeading = g_localizeStrings.Get(13209);
1081 if( CGUIDialogNumeric::ShowAndGetNumber(strTime, strHeading) )
1082 seconds = static_cast<float>(atoi(strTime.c_str())*60);
1086 bool silent = false;
1088 for (unsigned int i = 3; i < params.size() ; i++)
1090 // check "true" for backward comp
1091 if (params[i].CompareNoCase("true") == 0 || params[i].CompareNoCase("silent") == 0)
1093 else if (params[i].CompareNoCase("loop") == 0)
1097 if( g_alarmClock.IsRunning() )
1098 g_alarmClock.Stop(params[0],silent);
1099 // no negative times not allowed, loop must have a positive time
1100 if (seconds < 0 || (seconds == 0 && loop))
1102 g_alarmClock.Start(params[0], seconds, params[1], silent, loop);
1104 else if (execute.Equals("notification"))
1106 if (params.size() < 2)
1108 if (params.size() == 4)
1109 CGUIDialogKaiToast::QueueNotification(params[3],params[0],params[1],atoi(params[2].c_str()));
1110 else if (params.size() == 3)
1111 CGUIDialogKaiToast::QueueNotification("",params[0],params[1],atoi(params[2].c_str()));
1113 CGUIDialogKaiToast::QueueNotification(params[0],params[1]);
1115 else if (execute.Equals("cancelalarm"))
1117 bool silent = false;
1118 if (params.size() > 1 && params[1].CompareNoCase("true") == 0)
1120 g_alarmClock.Stop(params[0],silent);
1122 else if (execute.Equals("playdvd"))
1124 #ifdef HAS_DVD_DRIVE
1125 bool restart = false;
1126 if (params.size() > 0 && params[0].CompareNoCase("restart") == 0)
1128 CAutorun::PlayDisc(g_mediaManager.GetDiscPath(), true, restart);
1131 else if (execute.Equals("ripcd"))
1133 #ifdef HAS_CDDA_RIPPER
1134 CCDDARipper::GetInstance().RipCD();
1137 else if (execute.Equals("skin.togglesetting"))
1139 int setting = CSkinSettings::Get().TranslateBool(parameter);
1140 CSkinSettings::Get().SetBool(setting, !CSkinSettings::Get().GetBool(setting));
1141 CSettings::Get().Save();
1143 else if (execute.Equals("skin.setbool") && params.size())
1145 if (params.size() > 1)
1147 int string = CSkinSettings::Get().TranslateBool(params[0]);
1148 CSkinSettings::Get().SetBool(string, params[1].CompareNoCase("true") == 0);
1149 CSettings::Get().Save();
1152 // default is to set it to true
1153 int setting = CSkinSettings::Get().TranslateBool(params[0]);
1154 CSkinSettings::Get().SetBool(setting, true);
1155 CSettings::Get().Save();
1157 else if (execute.Equals("skin.reset"))
1159 CSkinSettings::Get().Reset(parameter);
1160 CSettings::Get().Save();
1162 else if (execute.Equals("skin.resetsettings"))
1164 CSkinSettings::Get().Reset();
1165 CSettings::Get().Save();
1167 else if (execute.Equals("skin.theme"))
1170 vector<CStdString> vecTheme;
1171 CUtil::GetSkinThemes(vecTheme);
1175 // find current theme
1176 if (!StringUtils::EqualsNoCase(CSettings::Get().GetString("lookandfeel.skintheme"), "SKINDEFAULT"))
1178 for (unsigned int i=0;i<vecTheme.size();++i)
1180 CStdString strTmpTheme(CSettings::Get().GetString("lookandfeel.skintheme"));
1181 URIUtils::RemoveExtension(strTmpTheme);
1182 if (vecTheme[i].Equals(strTmpTheme))
1190 int iParam = atoi(parameter.c_str());
1191 if (iParam == 0 || iParam == 1)
1193 else if (iParam == -1)
1195 if (iTheme > (int)vecTheme.size()-1)
1198 iTheme = vecTheme.size()-1;
1200 CStdString strSkinTheme = "SKINDEFAULT";
1201 if (iTheme != -1 && iTheme < (int)vecTheme.size())
1202 strSkinTheme = vecTheme[iTheme];
1204 CSettings::Get().SetString("lookandfeel.skintheme", strSkinTheme);
1205 // also set the default color theme
1206 CStdString colorTheme(URIUtils::ReplaceExtension(strSkinTheme, ".xml"));
1207 if (colorTheme.Equals("Textures.xml"))
1208 colorTheme = "defaults.xml";
1209 CSettings::Get().SetString("lookandfeel.skincolors", colorTheme);
1210 g_application.ReloadSkin();
1212 else if (execute.Equals("skin.setstring") || execute.Equals("skin.setimage") || execute.Equals("skin.setfile") ||
1213 execute.Equals("skin.setpath") || execute.Equals("skin.setnumeric") || execute.Equals("skin.setlargeimage"))
1215 // break the parameter up if necessary
1217 if (params.size() > 1)
1219 string = CSkinSettings::Get().TranslateString(params[0]);
1220 if (execute.Equals("skin.setstring"))
1222 CSkinSettings::Get().SetString(string, params[1]);
1223 CSettings::Get().Save();
1228 string = CSkinSettings::Get().TranslateString(params[0]);
1229 CStdString value = CSkinSettings::Get().GetString(string);
1230 VECSOURCES localShares;
1231 g_mediaManager.GetLocalDrives(localShares);
1232 if (execute.Equals("skin.setstring"))
1234 if (CGUIKeyboardFactory::ShowAndGetInput(value, g_localizeStrings.Get(1029), true))
1235 CSkinSettings::Get().SetString(string, value);
1237 else if (execute.Equals("skin.setnumeric"))
1239 if (CGUIDialogNumeric::ShowAndGetNumber(value, g_localizeStrings.Get(611)))
1240 CSkinSettings::Get().SetString(string, value);
1242 else if (execute.Equals("skin.setimage"))
1244 if (CGUIDialogFileBrowser::ShowAndGetImage(localShares, g_localizeStrings.Get(1030), value))
1245 CSkinSettings::Get().SetString(string, value);
1247 else if (execute.Equals("skin.setlargeimage"))
1249 VECSOURCES *shares = CMediaSourceSettings::Get().GetSources("pictures");
1250 if (!shares) shares = &localShares;
1251 if (CGUIDialogFileBrowser::ShowAndGetImage(*shares, g_localizeStrings.Get(1030), value))
1252 CSkinSettings::Get().SetString(string, value);
1254 else if (execute.Equals("skin.setfile"))
1256 // Note. can only browse one addon type from here
1257 // if browsing for addons, required param[1] is addontype string, with optional param[2]
1258 // as contenttype string see IAddon.h & ADDON::TranslateXX
1259 CStdString strMask = (params.size() > 1) ? params[1] : "";
1262 if ((type = TranslateType(strMask)) != ADDON_UNKNOWN)
1265 url.SetProtocol("addons");
1266 url.SetHostName("enabled");
1267 url.SetFileName(strMask+"/");
1268 localShares.clear();
1269 CStdString content = (params.size() > 2) ? params[2] : "";
1271 url.SetPassword(content);
1273 if (type == ADDON_SCRIPT)
1276 if (CGUIDialogFileBrowser::ShowAndGetFile(url.Get(), strMask, TranslateType(type, true), replace, true, true, true))
1278 if (StringUtils::StartsWithNoCase(replace, "addons://"))
1279 CSkinSettings::Get().SetString(string, URIUtils::GetFileName(replace));
1281 CSkinSettings::Get().SetString(string, replace);
1286 if (params.size() > 2)
1289 URIUtils::AddSlashAtEnd(value);
1291 if (CUtil::GetMatchingSource(value,localShares,bIsSource) < 0) // path is outside shares - add it as a separate one
1294 share.strName = g_localizeStrings.Get(13278);
1295 share.strPath = value;
1296 localShares.push_back(share);
1299 if (CGUIDialogFileBrowser::ShowAndGetFile(localShares, strMask, g_localizeStrings.Get(1033), value))
1300 CSkinSettings::Get().SetString(string, value);
1303 else // execute.Equals("skin.setpath"))
1305 g_mediaManager.GetNetworkLocations(localShares);
1306 if (params.size() > 1)
1309 URIUtils::AddSlashAtEnd(value);
1311 if (CUtil::GetMatchingSource(value,localShares,bIsSource) < 0) // path is outside shares - add it as a separate one
1314 share.strName = g_localizeStrings.Get(13278);
1315 share.strPath = value;
1316 localShares.push_back(share);
1319 if (CGUIDialogFileBrowser::ShowAndGetDirectory(localShares, g_localizeStrings.Get(1031), value))
1320 CSkinSettings::Get().SetString(string, value);
1322 CSettings::Get().Save();
1324 else if (execute.Equals("skin.setaddon") && params.size() > 1)
1326 int string = CSkinSettings::Get().TranslateString(params[0]);
1327 vector<ADDON::TYPE> types;
1328 for (unsigned int i = 1 ; i < params.size() ; i++)
1330 ADDON::TYPE type = TranslateType(params[i]);
1331 if (type != ADDON_UNKNOWN)
1332 types.push_back(type);
1335 if (types.size() > 0 && CGUIWindowAddonBrowser::SelectAddonID(types, result, true) == 1)
1337 CSkinSettings::Get().SetString(string, result);
1338 CSettings::Get().Save();
1341 else if (execute.Equals("dialog.close") && params.size())
1343 bool bForce = false;
1344 if (params.size() > 1 && params[1].CompareNoCase("true") == 0)
1346 if (params[0].CompareNoCase("all") == 0)
1348 g_windowManager.CloseDialogs(bForce);
1352 int id = CButtonTranslator::TranslateWindow(params[0]);
1353 CGUIWindow *window = (CGUIWindow *)g_windowManager.GetWindow(id);
1354 if (window && window->IsDialog())
1355 ((CGUIDialog *)window)->Close(bForce);
1358 else if (execute.Equals("system.logoff"))
1360 // there was a commit from cptspiff here which was reverted
1361 // for keeping the behaviour from Eden in Frodo - see
1362 // git rev 9ee5f0047b
1363 if (g_windowManager.GetActiveWindow() == WINDOW_LOGIN_SCREEN)
1366 g_application.StopPlaying();
1367 if (g_application.IsMusicScanning())
1368 g_application.StopMusicScan();
1370 if (g_application.IsVideoScanning())
1371 g_application.StopVideoScan();
1373 ADDON::CAddonMgr::Get().StopServices(true);
1375 g_application.getNetwork().NetworkMessage(CNetwork::SERVICES_DOWN,1);
1376 CProfilesManager::Get().LoadMasterProfileForLogin();
1377 g_passwordManager.bMasterUser = false;
1378 g_windowManager.ActivateWindow(WINDOW_LOGIN_SCREEN);
1379 if (!CNetworkServices::Get().StartEventServer()) // event server could be needed in some situations
1380 CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Warning, g_localizeStrings.Get(33102), g_localizeStrings.Get(33100));
1382 else if (execute.Equals("pagedown"))
1384 int id = atoi(parameter.c_str());
1385 CGUIMessage message(GUI_MSG_PAGE_DOWN, g_windowManager.GetFocusedWindow(), id);
1386 g_windowManager.SendMessage(message);
1388 else if (execute.Equals("pageup"))
1390 int id = atoi(parameter.c_str());
1391 CGUIMessage message(GUI_MSG_PAGE_UP, g_windowManager.GetFocusedWindow(), id);
1392 g_windowManager.SendMessage(message);
1394 else if (execute.Equals("updatelibrary") && params.size())
1396 if (params[0].Equals("music"))
1398 if (g_application.IsMusicScanning())
1399 g_application.StopMusicScan();
1401 g_application.StartMusicScan(params.size() > 1 ? params[1] : "");
1403 if (params[0].Equals("video"))
1405 if (g_application.IsVideoScanning())
1406 g_application.StopVideoScan();
1408 g_application.StartVideoScan(params.size() > 1 ? params[1] : "");
1411 else if (execute.Equals("cleanlibrary"))
1413 if (!params.size() || params[0].Equals("video"))
1415 if (!g_application.IsVideoScanning())
1416 g_application.StartVideoCleanup();
1418 CLog::Log(LOGERROR, "XBMC.CleanLibrary is not possible while scanning or cleaning");
1420 else if (params[0].Equals("music"))
1422 if (!g_application.IsMusicScanning())
1424 CMusicDatabase musicdatabase;
1426 musicdatabase.Open();
1427 musicdatabase.Cleanup();
1428 musicdatabase.Close();
1431 CLog::Log(LOGERROR, "XBMC.CleanLibrary is not possible while scanning for media info");
1434 else if (execute.Equals("exportlibrary"))
1437 if (params[0].Equals("music"))
1441 g_mediaManager.GetLocalDrives(shares);
1444 bool actorThumbs=false;
1445 bool overwrite=false;
1446 bool cancelled=false;
1448 if (params.size() > 1)
1449 singleFile = params[1].Equals("true");
1451 singleFile = CGUIDialogYesNo::ShowAndGetInput(iHeading,20426,20427,-1,20428,20429,cancelled);
1458 if (params.size() > 2)
1459 thumbs = params[2].Equals("true");
1461 thumbs = CGUIDialogYesNo::ShowAndGetInput(iHeading,20430,-1,-1,cancelled);
1467 if (thumbs && params[0].Equals("video"))
1469 if (params.size() > 4)
1470 actorThumbs = params[4].Equals("true");
1472 actorThumbs = CGUIDialogYesNo::ShowAndGetInput(iHeading,20436,-1,-1,cancelled);
1480 if (params.size() > 3)
1481 overwrite = params[3].Equals("true");
1483 overwrite = CGUIDialogYesNo::ShowAndGetInput(iHeading,20431,-1,-1,cancelled);
1489 if (params.size() > 2)
1491 if (singleFile || !path.IsEmpty() ||
1492 CGUIDialogFileBrowser::ShowAndGetDirectory(shares,
1493 g_localizeStrings.Get(661), path, true))
1495 if (params[0].Equals("video"))
1497 CVideoDatabase videodatabase;
1498 videodatabase.Open();
1499 videodatabase.ExportToXML(path, singleFile, thumbs, actorThumbs, overwrite);
1500 videodatabase.Close();
1504 if (URIUtils::HasSlashAtEnd(path))
1505 path = URIUtils::AddFileToFolder(path, "musicdb.xml");
1506 CMusicDatabase musicdatabase;
1507 musicdatabase.Open();
1508 musicdatabase.ExportToXML(path, singleFile, thumbs, overwrite);
1509 musicdatabase.Close();
1513 else if (execute.Equals("control.move") && params.size() > 1)
1515 CGUIMessage message(GUI_MSG_MOVE_OFFSET, g_windowManager.GetFocusedWindow(), atoi(params[0].c_str()), atoi(params[1].c_str()));
1516 g_windowManager.SendMessage(message);
1518 else if (execute.Equals("container.refresh"))
1519 { // NOTE: These messages require a media window, thus they're sent to the current activewindow.
1520 // This shouldn't stop a dialog intercepting it though.
1521 CGUIMessage message(GUI_MSG_NOTIFY_ALL, g_windowManager.GetActiveWindow(), 0, GUI_MSG_UPDATE, 1); // 1 to reset the history
1522 message.SetStringParam(parameter);
1523 g_windowManager.SendMessage(message);
1525 else if (execute.Equals("container.update") && params.size())
1527 CGUIMessage message(GUI_MSG_NOTIFY_ALL, g_windowManager.GetActiveWindow(), 0, GUI_MSG_UPDATE, 0);
1528 message.SetStringParam(params[0]);
1529 if (params.size() > 1 && params[1].CompareNoCase("replace") == 0)
1530 message.SetParam2(1); // reset the history
1531 g_windowManager.SendMessage(message);
1533 else if (execute.Equals("container.nextviewmode"))
1535 CGUIMessage message(GUI_MSG_CHANGE_VIEW_MODE, g_windowManager.GetActiveWindow(), 0, 0, 1);
1536 g_windowManager.SendMessage(message);
1538 else if (execute.Equals("container.previousviewmode"))
1540 CGUIMessage message(GUI_MSG_CHANGE_VIEW_MODE, g_windowManager.GetActiveWindow(), 0, 0, -1);
1541 g_windowManager.SendMessage(message);
1543 else if (execute.Equals("container.setviewmode"))
1545 CGUIMessage message(GUI_MSG_CHANGE_VIEW_MODE, g_windowManager.GetActiveWindow(), 0, atoi(parameter.c_str()));
1546 g_windowManager.SendMessage(message);
1548 else if (execute.Equals("container.nextsortmethod"))
1550 CGUIMessage message(GUI_MSG_CHANGE_SORT_METHOD, g_windowManager.GetActiveWindow(), 0, 0, 1);
1551 g_windowManager.SendMessage(message);
1553 else if (execute.Equals("container.previoussortmethod"))
1555 CGUIMessage message(GUI_MSG_CHANGE_SORT_METHOD, g_windowManager.GetActiveWindow(), 0, 0, -1);
1556 g_windowManager.SendMessage(message);
1558 else if (execute.Equals("container.setsortmethod"))
1560 CGUIMessage message(GUI_MSG_CHANGE_SORT_METHOD, g_windowManager.GetActiveWindow(), 0, atoi(parameter.c_str()));
1561 g_windowManager.SendMessage(message);
1563 else if (execute.Equals("container.sortdirection"))
1565 CGUIMessage message(GUI_MSG_CHANGE_SORT_DIRECTION, g_windowManager.GetActiveWindow(), 0, 0);
1566 g_windowManager.SendMessage(message);
1568 else if (execute.Equals("control.message") && params.size() >= 2)
1570 int controlID = atoi(params[0].c_str());
1571 int windowID = (params.size() == 3) ? CButtonTranslator::TranslateWindow(params[2]) : g_windowManager.GetActiveWindow();
1572 if (params[1] == "moveup")
1573 g_windowManager.SendMessage(GUI_MSG_MOVE_OFFSET, windowID, controlID, 1);
1574 else if (params[1] == "movedown")
1575 g_windowManager.SendMessage(GUI_MSG_MOVE_OFFSET, windowID, controlID, -1);
1576 else if (params[1] == "pageup")
1577 g_windowManager.SendMessage(GUI_MSG_PAGE_UP, windowID, controlID);
1578 else if (params[1] == "pagedown")
1579 g_windowManager.SendMessage(GUI_MSG_PAGE_DOWN, windowID, controlID);
1580 else if (params[1] == "click")
1581 g_windowManager.SendMessage(GUI_MSG_CLICKED, controlID, windowID);
1583 else if (execute.Equals("sendclick") && params.size())
1585 if (params.size() == 2)
1587 // have a window - convert it
1588 int windowID = CButtonTranslator::TranslateWindow(params[0]);
1589 CGUIMessage message(GUI_MSG_CLICKED, atoi(params[1].c_str()), windowID);
1590 g_windowManager.SendMessage(message);
1593 { // single param - assume you meant the active window
1594 CGUIMessage message(GUI_MSG_CLICKED, atoi(params[0].c_str()), g_windowManager.GetActiveWindow());
1595 g_windowManager.SendMessage(message);
1598 else if (execute.Equals("action") && params.size())
1600 // try translating the action from our ButtonTranslator
1602 if (CButtonTranslator::TranslateActionString(params[0].c_str(), actionID))
1604 int windowID = params.size() == 2 ? CButtonTranslator::TranslateWindow(params[1]) : WINDOW_INVALID;
1605 CApplicationMessenger::Get().SendAction(CAction(actionID), windowID);
1608 else if (execute.Equals("setproperty") && params.size() >= 2)
1610 CGUIWindow *window = g_windowManager.GetWindow(params.size() > 2 ? CButtonTranslator::TranslateWindow(params[2]) : g_windowManager.GetFocusedWindow());
1612 window->SetProperty(params[0],params[1]);
1614 else if (execute.Equals("clearproperty") && params.size())
1616 CGUIWindow *window = g_windowManager.GetWindow(params.size() > 1 ? CButtonTranslator::TranslateWindow(params[1]) : g_windowManager.GetFocusedWindow());
1618 window->SetProperty(params[0],"");
1620 else if (execute.Equals("wakeonlan"))
1622 g_application.getNetwork().WakeOnLan((char*)params[0].c_str());
1624 else if (execute.Equals("addon.default.opensettings") && params.size() == 1)
1627 ADDON::TYPE type = TranslateType(params[0]);
1628 if (CAddonMgr::Get().GetDefault(type, addon))
1630 CGUIDialogAddonSettings::ShowAndGetInput(addon);
1631 if (type == ADDON_VIZ)
1632 g_windowManager.SendMessage(GUI_MSG_VISUALISATION_RELOAD, 0, 0);
1635 else if (execute.Equals("addon.default.set") && params.size() == 1)
1638 TYPE type = TranslateType(params[0]);
1639 bool allowNone = false;
1640 if (type == ADDON_VIZ)
1643 if (type != ADDON_UNKNOWN &&
1644 CGUIWindowAddonBrowser::SelectAddonID(type,addonID,allowNone))
1646 CAddonMgr::Get().SetDefault(type,addonID);
1647 if (type == ADDON_VIZ)
1648 g_windowManager.SendMessage(GUI_MSG_VISUALISATION_RELOAD, 0, 0);
1651 else if (execute.Equals("addon.opensettings") && params.size() == 1)
1654 if (CAddonMgr::Get().GetAddon(params[0], addon))
1655 CGUIDialogAddonSettings::ShowAndGetInput(addon);
1657 else if (execute.Equals("updateaddonrepos"))
1659 CAddonInstaller::Get().UpdateRepos(true);
1661 else if (execute.Equals("updatelocaladdons"))
1663 CAddonMgr::Get().FindAddons();
1665 else if (execute.Equals("toggledpms"))
1667 g_application.ToggleDPMS(true);
1669 else if (execute.Equals("cectogglestate"))
1671 CApplicationMessenger::Get().CECToggleState();
1673 else if (execute.Equals("cecactivatesource"))
1675 CApplicationMessenger::Get().CECActivateSource();
1677 else if (execute.Equals("cecstandby"))
1679 CApplicationMessenger::Get().CECStandby();
1681 #if defined(HAS_LIRC) || defined(HAS_IRSERVERSUITE)
1682 else if (execute.Equals("lirc.stop"))
1684 g_RemoteControl.Disconnect();
1685 g_RemoteControl.setUsed(false);
1687 else if (execute.Equals("lirc.start"))
1689 g_RemoteControl.setUsed(true);
1690 g_RemoteControl.Initialize();
1692 else if (execute.Equals("lirc.send"))
1695 for (int i = 0; i < (int)params.size(); i++)
1697 command += params[i];
1698 if (i < (int)params.size() - 1)
1701 g_RemoteControl.AddSendCommand(command);
1704 else if (execute.Equals("weather.locationset"))
1706 int loc = atoi(params[0]);
1707 CGUIMessage msg(GUI_MSG_ITEM_SELECT, 0, 0, loc);
1708 g_windowManager.SendMessage(msg, WINDOW_WEATHER);
1710 else if (execute.Equals("weather.locationnext"))
1712 CGUIMessage msg(GUI_MSG_MOVE_OFFSET, 0, 0, 1);
1713 g_windowManager.SendMessage(msg, WINDOW_WEATHER);
1715 else if (execute.Equals("weather.locationprevious"))
1717 CGUIMessage msg(GUI_MSG_MOVE_OFFSET, 0, 0, -1);
1718 g_windowManager.SendMessage(msg, WINDOW_WEATHER);
1720 else if (execute.Equals("weather.refresh"))
1722 CGUIMessage msg(GUI_MSG_MOVE_OFFSET, 0, 0, 0);
1723 g_windowManager.SendMessage(msg, WINDOW_WEATHER);
1725 else if (execute.Equals("videolibrary.search"))
1727 CGUIMessage msg(GUI_MSG_SEARCH, 0, 0, 0);
1728 g_windowManager.SendMessage(msg, WINDOW_VIDEO_NAV);
1730 else if (execute.Equals("toggledebug"))
1732 bool debug = CSettings::Get().GetBool("debug.showloginfo");
1733 CSettings::Get().SetBool("debug.showloginfo", !debug);
1734 g_advancedSettings.SetDebugMode(!debug);
1736 else if (execute.Equals("startpvrmanager"))
1738 g_application.StartPVRManager();
1740 else if (execute.Equals("stoppvrmanager"))
1742 g_application.StopPVRManager();
1744 else if (execute.Equals("StartAndroidActivity") && params.size() > 0)
1746 CApplicationMessenger::Get().StartAndroidActivity(params);
1748 else if (execute.Equals("SetStereoMode") && !parameter.IsEmpty())
1750 CAction action = CStereoscopicsManager::Get().ConvertActionCommandToAction(execute, parameter);
1751 if (action.GetID() != ACTION_NONE)
1752 CApplicationMessenger::Get().SendAction(action);
1755 CLog::Log(LOGERROR,"Builtin 'SetStereoMode' called with unknown parameter: %s", parameter.c_str());