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 if (plugin->Provides(CPluginSource::VIDEO))
570 cmd.Format("ActivateWindow(Video,plugin://%s,return)",params[0]);
571 else if (plugin->Provides(CPluginSource::AUDIO))
572 cmd.Format("ActivateWindow(Music,plugin://%s,return)",params[0]);
573 else if (plugin->Provides(CPluginSource::EXECUTABLE))
574 cmd.Format("ActivateWindow(Programs,plugin://%s,return)",params[0]);
575 else if (plugin->Provides(CPluginSource::IMAGE))
576 cmd.Format("ActivateWindow(Pictures,plugin://%s,return)",params[0]);
578 // Pass the script name (params[0]) and all the parameters
579 // (params[1] ... params[x]) separated by a comma to RunPlugin
580 cmd.Format("RunPlugin(%s)", StringUtils::JoinString(params, ","));
582 else if (addon->Type() >= ADDON_SCRIPT && addon->Type() <= ADDON_SCRIPT_LYRICS)
583 // Pass the script name (params[0]) and all the parameters
584 // (params[1] ... params[x]) separated by a comma to RunScript
585 cmd.Format("RunScript(%s)", StringUtils::JoinString(params, ","));
592 CLog::Log(LOGERROR, "XBMC.RunAddon called with no arguments.");
595 else if (execute.Equals("notifyall"))
597 if (params.size() > 1)
600 if (params.size() > 2)
601 data = CJSONVariantParser::Parse((const unsigned char *)params[2].c_str(), params[2].size());
603 ANNOUNCEMENT::CAnnouncementManager::Announce(ANNOUNCEMENT::Other, params[0], params[1], data);
606 CLog::Log(LOGERROR, "XBMC.NotifyAll needs two parameters");
608 else if (execute.Equals("playmedia"))
612 CLog::Log(LOGERROR, "XBMC.PlayMedia called with empty parameter");
616 CFileItem item(params[0], false);
617 if (URIUtils::HasSlashAtEnd(params[0]))
618 item.m_bIsFolder = true;
620 // restore to previous window if needed
621 if( g_windowManager.GetActiveWindow() == WINDOW_SLIDESHOW ||
622 g_windowManager.GetActiveWindow() == WINDOW_FULLSCREEN_VIDEO ||
623 g_windowManager.GetActiveWindow() == WINDOW_VISUALISATION )
624 g_windowManager.PreviousWindow();
627 g_application.ResetScreenSaver();
628 g_application.WakeUpScreenSaverAndDPMS();
630 // ask if we need to check guisettings to resume
631 bool askToResume = true;
633 for (unsigned int i = 1 ; i < params.size() ; i++)
635 if (params[i].Equals("isdir"))
636 item.m_bIsFolder = true;
637 else if (params[i].Equals("1")) // set fullscreen or windowed
638 CMediaSettings::Get().SetVideoStartWindowed(true);
639 else if (params[i].Equals("resume"))
641 // force the item to resume (if applicable) (see CApplication::PlayMedia)
642 item.m_lStartOffset = STARTOFFSET_RESUME;
645 else if (params[i].Equals("noresume"))
647 // force the item to start at the beginning (m_lStartOffset is initialized to 0)
650 else if (StringUtils::StartsWithNoCase(params[i], "playoffset=")) {
651 playOffset = atoi(params[i].Mid(11)) - 1;
652 item.SetProperty("playlist_starting_track", playOffset);
656 if (!item.m_bIsFolder && item.IsPlugin())
657 item.SetProperty("IsPlayable", true);
659 if ( askToResume == true )
661 if ( CGUIWindowVideoBase::ShowResumeMenu(item) == false )
664 if (item.m_bIsFolder)
667 CStdString extensions = g_advancedSettings.m_videoExtensions + "|" + g_advancedSettings.m_musicExtensions;
668 CDirectory::GetDirectory(item.GetPath(),items,extensions);
670 bool containsMusic = false, containsVideo = false;
671 for (int i = 0; i < items.Size(); i++)
673 bool isVideo = items[i]->IsVideo();
674 containsMusic |= !isVideo;
675 containsVideo |= isVideo;
677 if (containsMusic && containsVideo)
681 int playlist = containsVideo? PLAYLIST_VIDEO : PLAYLIST_MUSIC;;
682 if (containsMusic && containsVideo) //mixed content found in the folder
684 for (int i = items.Size() - 1; i >= 0; i--) //remove music entries
686 if (!items[i]->IsVideo())
691 g_playlistPlayer.ClearPlaylist(playlist);
692 g_playlistPlayer.Add(playlist, items);
693 g_playlistPlayer.SetCurrentPlaylist(playlist);
694 g_playlistPlayer.Play(playOffset);
698 int playlist = item.IsAudio() ? PLAYLIST_MUSIC : PLAYLIST_VIDEO;
699 g_playlistPlayer.ClearPlaylist(playlist);
700 g_playlistPlayer.SetCurrentPlaylist(playlist);
703 if (!g_application.PlayMedia(item, playlist))
705 CLog::Log(LOGERROR, "XBMC.PlayMedia could not play media: %s", params[0].c_str());
710 else if (execute.Equals("showPicture"))
714 CLog::Log(LOGERROR, "XBMC.ShowPicture called with empty parameter");
717 CGUIMessage msg(GUI_MSG_SHOW_PICTURE, 0, 0);
718 msg.SetStringParam(params[0]);
719 CGUIWindow *pWindow = g_windowManager.GetWindow(WINDOW_SLIDESHOW);
720 if (pWindow) pWindow->OnMessage(msg);
722 else if (execute.Equals("slideShow") || execute.Equals("recursiveslideShow"))
726 CLog::Log(LOGERROR, "XBMC.SlideShow called with empty parameter");
729 std::string beginSlidePath;
730 // leave RecursiveSlideShow command as-is
731 unsigned int flags = 0;
732 if (execute.Equals("RecursiveSlideShow"))
735 // SlideShow(dir[,recursive][,[not]random][,pause][,beginslide="/path/to/start/slide.jpg"])
736 // the beginslide value need be escaped (for '"' or '\' in it, by backslash)
737 // and then quoted, or not. See CUtil::SplitParams()
740 for (unsigned int i = 1 ; i < params.size() ; i++)
742 if (params[i].Equals("recursive"))
744 else if (params[i].Equals("random")) // set fullscreen or windowed
746 else if (params[i].Equals("notrandom"))
748 else if (params[i].Equals("pause"))
750 else if (StringUtils::StartsWithNoCase(params[i], "beginslide="))
751 beginSlidePath = params[i].Mid(11);
755 CGUIMessage msg(GUI_MSG_START_SLIDESHOW, 0, 0, flags);
756 vector<CStdString> strParams;
757 strParams.push_back(params[0]);
758 strParams.push_back(beginSlidePath);
759 msg.SetStringParams(strParams);
760 CGUIWindow *pWindow = g_windowManager.GetWindow(WINDOW_SLIDESHOW);
761 if (pWindow) pWindow->OnMessage(msg);
763 else if (execute.Equals("reloadskin"))
766 g_application.ReloadSkin(!params.empty() && StringUtils::EqualsNoCase(params[0], "confirm"));
768 else if (execute.Equals("unloadskin"))
770 g_application.UnloadSkin(true); // we're reloading the skin after this
772 else if (execute.Equals("refreshrss"))
774 CRssManager::Get().Reload();
776 else if (execute.Equals("playercontrol"))
778 g_application.ResetScreenSaver();
779 g_application.WakeUpScreenSaverAndDPMS();
782 CLog::Log(LOGERROR, "XBMC.PlayerControl called with empty parameter");
785 if (parameter.Equals("play"))
787 // either resume playing, or pause
788 if (g_application.m_pPlayer->IsPlaying())
790 if (g_application.m_pPlayer->GetPlaySpeed() != 1)
791 g_application.m_pPlayer->SetPlaySpeed(1, g_application.IsMutedInternal());
793 g_application.m_pPlayer->Pause();
796 else if (parameter.Equals("stop"))
798 g_application.StopPlaying();
800 else if (parameter.Equals("rewind") || parameter.Equals("forward"))
802 if (g_application.m_pPlayer->IsPlaying() && !g_application.m_pPlayer->IsPaused())
804 int iPlaySpeed = g_application.m_pPlayer->GetPlaySpeed();
805 if (parameter.Equals("rewind") && iPlaySpeed == 1) // Enables Rewinding
807 else if (parameter.Equals("rewind") && iPlaySpeed > 1) //goes down a notch if you're FFing
809 else if (parameter.Equals("forward") && iPlaySpeed < 1) //goes up a notch if you're RWing
812 if (iPlaySpeed == -1) iPlaySpeed = 1;
817 if (iPlaySpeed > 32 || iPlaySpeed < -32)
820 g_application.m_pPlayer->SetPlaySpeed(iPlaySpeed, g_application.IsMutedInternal());
823 else if (parameter.Equals("next"))
825 g_application.OnAction(CAction(ACTION_NEXT_ITEM));
827 else if (parameter.Equals("previous"))
829 g_application.OnAction(CAction(ACTION_PREV_ITEM));
831 else if (parameter.Equals("bigskipbackward"))
833 if (g_application.m_pPlayer->IsPlaying())
834 g_application.m_pPlayer->Seek(false, true);
836 else if (parameter.Equals("bigskipforward"))
838 if (g_application.m_pPlayer->IsPlaying())
839 g_application.m_pPlayer->Seek(true, true);
841 else if (parameter.Equals("smallskipbackward"))
843 if (g_application.m_pPlayer->IsPlaying())
844 g_application.m_pPlayer->Seek(false, false);
846 else if (parameter.Equals("smallskipforward"))
848 if (g_application.m_pPlayer->IsPlaying())
849 g_application.m_pPlayer->Seek(true, false);
851 else if (StringUtils::StartsWithNoCase(parameter, "seekpercentage"))
853 CStdString offset = "";
854 if (parameter.size() == 14)
855 CLog::Log(LOGERROR,"PlayerControl(seekpercentage(n)) called with no argument");
856 else if (parameter.size() < 17) // arg must be at least "(N)"
857 CLog::Log(LOGERROR,"PlayerControl(seekpercentage(n)) called with invalid argument: \"%s\"", parameter.Mid(14).c_str());
860 // Don't bother checking the argument: an invalid arg will do seek(0)
861 offset = parameter.Mid(15).TrimRight(")");
862 float offsetpercent = (float) atof(offset.c_str());
863 if (offsetpercent < 0 || offsetpercent > 100)
864 CLog::Log(LOGERROR,"PlayerControl(seekpercentage(n)) argument, %f, must be 0-100", offsetpercent);
865 else if (g_application.m_pPlayer->IsPlaying())
866 g_application.SeekPercentage(offsetpercent);
869 else if( parameter.Equals("showvideomenu") )
871 if( g_application.m_pPlayer->IsPlaying() )
872 g_application.m_pPlayer->OnAction(CAction(ACTION_SHOW_VIDEOMENU));
874 else if( parameter.Equals("record") )
876 if( g_application.m_pPlayer->IsPlaying() && g_application.m_pPlayer->CanRecord())
877 g_application.m_pPlayer->Record(!g_application.m_pPlayer->IsRecording());
879 else if (StringUtils::StartsWithNoCase(parameter, "partymode"))
881 CStdString strXspPath = "";
882 //empty param=music, "music"=music, "video"=video, else xsp path
883 PartyModeContext context = PARTYMODECONTEXT_MUSIC;
884 if (parameter.size() > 9)
886 if (parameter.size() == 16 && StringUtils::EndsWithNoCase(parameter, "video)"))
887 context = PARTYMODECONTEXT_VIDEO;
888 else if (parameter.size() != 16 || !StringUtils::EndsWithNoCase(parameter, "music)"))
890 strXspPath = parameter.Mid(10).TrimRight(")");
891 context = PARTYMODECONTEXT_UNKNOWN;
894 if (g_partyModeManager.IsEnabled())
895 g_partyModeManager.Disable();
897 g_partyModeManager.Enable(context, strXspPath);
899 else if (parameter.Equals("random") ||
900 parameter.Equals("randomoff") ||
901 parameter.Equals("randomon"))
903 // get current playlist
904 int iPlaylist = g_playlistPlayer.GetCurrentPlaylist();
906 // reverse the current setting
907 bool shuffled = g_playlistPlayer.IsShuffled(iPlaylist);
908 if ((shuffled && parameter.Equals("randomon")) || (!shuffled && parameter.Equals("randomoff")))
911 // check to see if we should notify the user
912 bool notify = (params.size() == 2 && params[1].Equals("notify"));
913 g_playlistPlayer.SetShuffle(iPlaylist, !shuffled, notify);
915 // save settings for now playing windows
919 CMediaSettings::Get().SetMusicPlaylistShuffled(g_playlistPlayer.IsShuffled(iPlaylist));
920 CSettings::Get().Save();
923 CMediaSettings::Get().SetVideoPlaylistShuffled(g_playlistPlayer.IsShuffled(iPlaylist));
924 CSettings::Get().Save();
928 CGUIMessage msg(GUI_MSG_PLAYLISTPLAYER_RANDOM, 0, 0, iPlaylist, g_playlistPlayer.IsShuffled(iPlaylist));
929 g_windowManager.SendThreadMessage(msg);
932 else if (StringUtils::StartsWithNoCase(parameter, "repeat"))
934 // get current playlist
935 int iPlaylist = g_playlistPlayer.GetCurrentPlaylist();
936 PLAYLIST::REPEAT_STATE previous_state = g_playlistPlayer.GetRepeat(iPlaylist);
938 PLAYLIST::REPEAT_STATE state;
939 if (parameter.Equals("repeatall"))
940 state = PLAYLIST::REPEAT_ALL;
941 else if (parameter.Equals("repeatone"))
942 state = PLAYLIST::REPEAT_ONE;
943 else if (parameter.Equals("repeatoff"))
944 state = PLAYLIST::REPEAT_NONE;
945 else if (previous_state == PLAYLIST::REPEAT_NONE)
946 state = PLAYLIST::REPEAT_ALL;
947 else if (previous_state == PLAYLIST::REPEAT_ALL)
948 state = PLAYLIST::REPEAT_ONE;
950 state = PLAYLIST::REPEAT_NONE;
952 if (state == previous_state)
955 // check to see if we should notify the user
956 bool notify = (params.size() == 2 && params[1].Equals("notify"));
957 g_playlistPlayer.SetRepeat(iPlaylist, state, notify);
959 // save settings for now playing windows
963 CMediaSettings::Get().SetMusicPlaylistRepeat(state == PLAYLIST::REPEAT_ALL);
964 CSettings::Get().Save();
967 CMediaSettings::Get().SetVideoPlaylistRepeat(state == PLAYLIST::REPEAT_ALL);
968 CSettings::Get().Save();
971 // send messages so now playing window can get updated
972 CGUIMessage msg(GUI_MSG_PLAYLISTPLAYER_REPEAT, 0, 0, iPlaylist, (int)state);
973 g_windowManager.SendThreadMessage(msg);
976 else if (execute.Equals("playwith"))
978 g_application.m_eForcedNextPlayer = CPlayerCoreFactory::Get().GetPlayerCore(parameter);
979 g_application.OnAction(CAction(ACTION_PLAYER_PLAY));
981 else if (execute.Equals("mute"))
983 g_application.ToggleMute();
985 else if (execute.Equals("setvolume"))
987 float oldVolume = g_application.GetVolume();
988 float volume = (float)strtod(parameter.c_str(), NULL);
990 g_application.SetVolume(volume);
991 if(oldVolume != volume)
993 if(params.size() > 1 && params[1].Equals("showVolumeBar"))
995 CApplicationMessenger::Get().ShowVolumeBar(oldVolume < volume);
999 else if (execute.Equals("playlist.playoffset"))
1001 // playlist.playoffset(offset)
1002 // playlist.playoffset(music|video,offset)
1003 CStdString strPos = parameter;
1004 if (params.size() > 1)
1006 // ignore any other parameters if present
1007 CStdString strPlaylist = params[0];
1010 int iPlaylist = PLAYLIST_NONE;
1011 if (strPlaylist.Equals("music"))
1012 iPlaylist = PLAYLIST_MUSIC;
1013 else if (strPlaylist.Equals("video"))
1014 iPlaylist = PLAYLIST_VIDEO;
1017 if (iPlaylist == PLAYLIST_NONE)
1019 CLog::Log(LOGERROR,"Playlist.PlayOffset called with unknown playlist: %s", strPlaylist.c_str());
1023 // user wants to play the 'other' playlist
1024 if (iPlaylist != g_playlistPlayer.GetCurrentPlaylist())
1026 g_application.StopPlaying();
1027 g_playlistPlayer.Reset();
1028 g_playlistPlayer.SetCurrentPlaylist(iPlaylist);
1031 // play the desired offset
1032 int pos = atol(strPos.c_str());
1033 // playlist is already playing
1034 if (g_application.m_pPlayer->IsPlaying())
1035 g_playlistPlayer.PlayNext(pos);
1036 // we start playing the 'other' playlist so we need to use play to initialize the player state
1038 g_playlistPlayer.Play(pos);
1040 else if (execute.Equals("playlist.clear"))
1042 g_playlistPlayer.Clear();
1044 #ifdef HAS_DVD_DRIVE
1045 else if (execute.Equals("ejecttray"))
1047 g_mediaManager.ToggleTray();
1050 else if( execute.Equals("alarmclock") && params.size() > 1 )
1052 // format is alarmclock(name,command[,seconds,true]);
1054 if (params.size() > 2)
1056 if (params[2].Find(':') == -1)
1057 seconds = static_cast<float>(atoi(params[2].c_str())*60);
1059 seconds = (float)StringUtils::TimeStringToSeconds(params[2]);
1062 { // check if shutdown is specified in particular, and get the time for it
1063 CStdString strHeading;
1064 if (parameter.CompareNoCase("shutdowntimer") == 0)
1065 strHeading = g_localizeStrings.Get(20145);
1067 strHeading = g_localizeStrings.Get(13209);
1069 if( CGUIDialogNumeric::ShowAndGetNumber(strTime, strHeading) )
1070 seconds = static_cast<float>(atoi(strTime.c_str())*60);
1074 bool silent = false;
1076 for (unsigned int i = 3; i < params.size() ; i++)
1078 // check "true" for backward comp
1079 if (params[i].CompareNoCase("true") == 0 || params[i].CompareNoCase("silent") == 0)
1081 else if (params[i].CompareNoCase("loop") == 0)
1085 if( g_alarmClock.IsRunning() )
1086 g_alarmClock.Stop(params[0],silent);
1087 // no negative times not allowed, loop must have a positive time
1088 if (seconds < 0 || (seconds == 0 && loop))
1090 g_alarmClock.Start(params[0], seconds, params[1], silent, loop);
1092 else if (execute.Equals("notification"))
1094 if (params.size() < 2)
1096 if (params.size() == 4)
1097 CGUIDialogKaiToast::QueueNotification(params[3],params[0],params[1],atoi(params[2].c_str()));
1098 else if (params.size() == 3)
1099 CGUIDialogKaiToast::QueueNotification("",params[0],params[1],atoi(params[2].c_str()));
1101 CGUIDialogKaiToast::QueueNotification(params[0],params[1]);
1103 else if (execute.Equals("cancelalarm"))
1105 bool silent = false;
1106 if (params.size() > 1 && params[1].CompareNoCase("true") == 0)
1108 g_alarmClock.Stop(params[0],silent);
1110 else if (execute.Equals("playdvd"))
1112 #ifdef HAS_DVD_DRIVE
1113 bool restart = false;
1114 if (params.size() > 0 && params[0].CompareNoCase("restart") == 0)
1116 CAutorun::PlayDisc(g_mediaManager.GetDiscPath(), true, restart);
1119 else if (execute.Equals("ripcd"))
1121 #ifdef HAS_CDDA_RIPPER
1122 CCDDARipper::GetInstance().RipCD();
1125 else if (execute.Equals("skin.togglesetting"))
1127 int setting = CSkinSettings::Get().TranslateBool(parameter);
1128 CSkinSettings::Get().SetBool(setting, !CSkinSettings::Get().GetBool(setting));
1129 CSettings::Get().Save();
1131 else if (execute.Equals("skin.setbool") && params.size())
1133 if (params.size() > 1)
1135 int string = CSkinSettings::Get().TranslateBool(params[0]);
1136 CSkinSettings::Get().SetBool(string, params[1].CompareNoCase("true") == 0);
1137 CSettings::Get().Save();
1140 // default is to set it to true
1141 int setting = CSkinSettings::Get().TranslateBool(params[0]);
1142 CSkinSettings::Get().SetBool(setting, true);
1143 CSettings::Get().Save();
1145 else if (execute.Equals("skin.reset"))
1147 CSkinSettings::Get().Reset(parameter);
1148 CSettings::Get().Save();
1150 else if (execute.Equals("skin.resetsettings"))
1152 CSkinSettings::Get().Reset();
1153 CSettings::Get().Save();
1155 else if (execute.Equals("skin.theme"))
1158 vector<CStdString> vecTheme;
1159 CUtil::GetSkinThemes(vecTheme);
1163 // find current theme
1164 if (!StringUtils::EqualsNoCase(CSettings::Get().GetString("lookandfeel.skintheme"), "SKINDEFAULT"))
1166 for (unsigned int i=0;i<vecTheme.size();++i)
1168 CStdString strTmpTheme(CSettings::Get().GetString("lookandfeel.skintheme"));
1169 URIUtils::RemoveExtension(strTmpTheme);
1170 if (vecTheme[i].Equals(strTmpTheme))
1178 int iParam = atoi(parameter.c_str());
1179 if (iParam == 0 || iParam == 1)
1181 else if (iParam == -1)
1183 if (iTheme > (int)vecTheme.size()-1)
1186 iTheme = vecTheme.size()-1;
1188 CStdString strSkinTheme = "SKINDEFAULT";
1189 if (iTheme != -1 && iTheme < (int)vecTheme.size())
1190 strSkinTheme = vecTheme[iTheme];
1192 CSettings::Get().SetString("lookandfeel.skintheme", strSkinTheme);
1193 // also set the default color theme
1194 CStdString colorTheme(URIUtils::ReplaceExtension(strSkinTheme, ".xml"));
1195 if (colorTheme.Equals("Textures.xml"))
1196 colorTheme = "defaults.xml";
1197 CSettings::Get().SetString("lookandfeel.skincolors", colorTheme);
1198 g_application.ReloadSkin();
1200 else if (execute.Equals("skin.setstring") || execute.Equals("skin.setimage") || execute.Equals("skin.setfile") ||
1201 execute.Equals("skin.setpath") || execute.Equals("skin.setnumeric") || execute.Equals("skin.setlargeimage"))
1203 // break the parameter up if necessary
1205 if (params.size() > 1)
1207 string = CSkinSettings::Get().TranslateString(params[0]);
1208 if (execute.Equals("skin.setstring"))
1210 CSkinSettings::Get().SetString(string, params[1]);
1211 CSettings::Get().Save();
1216 string = CSkinSettings::Get().TranslateString(params[0]);
1217 CStdString value = CSkinSettings::Get().GetString(string);
1218 VECSOURCES localShares;
1219 g_mediaManager.GetLocalDrives(localShares);
1220 if (execute.Equals("skin.setstring"))
1222 if (CGUIKeyboardFactory::ShowAndGetInput(value, g_localizeStrings.Get(1029), true))
1223 CSkinSettings::Get().SetString(string, value);
1225 else if (execute.Equals("skin.setnumeric"))
1227 if (CGUIDialogNumeric::ShowAndGetNumber(value, g_localizeStrings.Get(611)))
1228 CSkinSettings::Get().SetString(string, value);
1230 else if (execute.Equals("skin.setimage"))
1232 if (CGUIDialogFileBrowser::ShowAndGetImage(localShares, g_localizeStrings.Get(1030), value))
1233 CSkinSettings::Get().SetString(string, value);
1235 else if (execute.Equals("skin.setlargeimage"))
1237 VECSOURCES *shares = CMediaSourceSettings::Get().GetSources("pictures");
1238 if (!shares) shares = &localShares;
1239 if (CGUIDialogFileBrowser::ShowAndGetImage(*shares, g_localizeStrings.Get(1030), value))
1240 CSkinSettings::Get().SetString(string, value);
1242 else if (execute.Equals("skin.setfile"))
1244 // Note. can only browse one addon type from here
1245 // if browsing for addons, required param[1] is addontype string, with optional param[2]
1246 // as contenttype string see IAddon.h & ADDON::TranslateXX
1247 CStdString strMask = (params.size() > 1) ? params[1] : "";
1250 if ((type = TranslateType(strMask)) != ADDON_UNKNOWN)
1253 url.SetProtocol("addons");
1254 url.SetHostName("enabled");
1255 url.SetFileName(strMask+"/");
1256 localShares.clear();
1257 CStdString content = (params.size() > 2) ? params[2] : "";
1259 url.SetPassword(content);
1261 if (type == ADDON_SCRIPT)
1264 if (CGUIDialogFileBrowser::ShowAndGetFile(url.Get(), strMask, TranslateType(type, true), replace, true, true, true))
1266 if (StringUtils::StartsWithNoCase(replace, "addons://"))
1267 CSkinSettings::Get().SetString(string, URIUtils::GetFileName(replace));
1269 CSkinSettings::Get().SetString(string, replace);
1274 if (params.size() > 2)
1277 URIUtils::AddSlashAtEnd(value);
1279 if (CUtil::GetMatchingSource(value,localShares,bIsSource) < 0) // path is outside shares - add it as a separate one
1282 share.strName = g_localizeStrings.Get(13278);
1283 share.strPath = value;
1284 localShares.push_back(share);
1287 if (CGUIDialogFileBrowser::ShowAndGetFile(localShares, strMask, g_localizeStrings.Get(1033), value))
1288 CSkinSettings::Get().SetString(string, value);
1291 else // execute.Equals("skin.setpath"))
1293 g_mediaManager.GetNetworkLocations(localShares);
1294 if (params.size() > 1)
1297 URIUtils::AddSlashAtEnd(value);
1299 if (CUtil::GetMatchingSource(value,localShares,bIsSource) < 0) // path is outside shares - add it as a separate one
1302 share.strName = g_localizeStrings.Get(13278);
1303 share.strPath = value;
1304 localShares.push_back(share);
1307 if (CGUIDialogFileBrowser::ShowAndGetDirectory(localShares, g_localizeStrings.Get(1031), value))
1308 CSkinSettings::Get().SetString(string, value);
1310 CSettings::Get().Save();
1312 else if (execute.Equals("skin.setaddon") && params.size() > 1)
1314 int string = CSkinSettings::Get().TranslateString(params[0]);
1315 vector<ADDON::TYPE> types;
1316 for (unsigned int i = 1 ; i < params.size() ; i++)
1318 ADDON::TYPE type = TranslateType(params[i]);
1319 if (type != ADDON_UNKNOWN)
1320 types.push_back(type);
1323 if (types.size() > 0 && CGUIWindowAddonBrowser::SelectAddonID(types, result, true) == 1)
1325 CSkinSettings::Get().SetString(string, result);
1326 CSettings::Get().Save();
1329 else if (execute.Equals("dialog.close") && params.size())
1331 bool bForce = false;
1332 if (params.size() > 1 && params[1].CompareNoCase("true") == 0)
1334 if (params[0].CompareNoCase("all") == 0)
1336 g_windowManager.CloseDialogs(bForce);
1340 int id = CButtonTranslator::TranslateWindow(params[0]);
1341 CGUIWindow *window = (CGUIWindow *)g_windowManager.GetWindow(id);
1342 if (window && window->IsDialog())
1343 ((CGUIDialog *)window)->Close(bForce);
1346 else if (execute.Equals("system.logoff"))
1348 // there was a commit from cptspiff here which was reverted
1349 // for keeping the behaviour from Eden in Frodo - see
1350 // git rev 9ee5f0047b
1351 if (g_windowManager.GetActiveWindow() == WINDOW_LOGIN_SCREEN)
1354 g_application.StopPlaying();
1355 if (g_application.IsMusicScanning())
1356 g_application.StopMusicScan();
1358 if (g_application.IsVideoScanning())
1359 g_application.StopVideoScan();
1361 ADDON::CAddonMgr::Get().StopServices(true);
1363 g_application.getNetwork().NetworkMessage(CNetwork::SERVICES_DOWN,1);
1364 CProfilesManager::Get().LoadMasterProfileForLogin();
1365 g_passwordManager.bMasterUser = false;
1366 g_windowManager.ActivateWindow(WINDOW_LOGIN_SCREEN);
1367 if (!CNetworkServices::Get().StartEventServer()) // event server could be needed in some situations
1368 CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Warning, g_localizeStrings.Get(33102), g_localizeStrings.Get(33100));
1370 else if (execute.Equals("pagedown"))
1372 int id = atoi(parameter.c_str());
1373 CGUIMessage message(GUI_MSG_PAGE_DOWN, g_windowManager.GetFocusedWindow(), id);
1374 g_windowManager.SendMessage(message);
1376 else if (execute.Equals("pageup"))
1378 int id = atoi(parameter.c_str());
1379 CGUIMessage message(GUI_MSG_PAGE_UP, g_windowManager.GetFocusedWindow(), id);
1380 g_windowManager.SendMessage(message);
1382 else if (execute.Equals("updatelibrary") && params.size())
1384 if (params[0].Equals("music"))
1386 if (g_application.IsMusicScanning())
1387 g_application.StopMusicScan();
1389 g_application.StartMusicScan(params.size() > 1 ? params[1] : "");
1391 if (params[0].Equals("video"))
1393 if (g_application.IsVideoScanning())
1394 g_application.StopVideoScan();
1396 g_application.StartVideoScan(params.size() > 1 ? params[1] : "");
1399 else if (execute.Equals("cleanlibrary"))
1401 if (!params.size() || params[0].Equals("video"))
1403 if (!g_application.IsVideoScanning())
1404 g_application.StartVideoCleanup();
1406 CLog::Log(LOGERROR, "XBMC.CleanLibrary is not possible while scanning or cleaning");
1408 else if (params[0].Equals("music"))
1410 if (!g_application.IsMusicScanning())
1412 CMusicDatabase musicdatabase;
1414 musicdatabase.Open();
1415 musicdatabase.Cleanup();
1416 musicdatabase.Close();
1419 CLog::Log(LOGERROR, "XBMC.CleanLibrary is not possible while scanning for media info");
1422 else if (execute.Equals("exportlibrary"))
1425 if (params[0].Equals("music"))
1429 g_mediaManager.GetLocalDrives(shares);
1432 bool actorThumbs=false;
1433 bool overwrite=false;
1434 bool cancelled=false;
1436 if (params.size() > 1)
1437 singleFile = params[1].Equals("true");
1439 singleFile = CGUIDialogYesNo::ShowAndGetInput(iHeading,20426,20427,-1,20428,20429,cancelled);
1446 if (params.size() > 2)
1447 thumbs = params[2].Equals("true");
1449 thumbs = CGUIDialogYesNo::ShowAndGetInput(iHeading,20430,-1,-1,cancelled);
1455 if (thumbs && params[0].Equals("video"))
1457 if (params.size() > 4)
1458 actorThumbs = params[4].Equals("true");
1460 actorThumbs = CGUIDialogYesNo::ShowAndGetInput(iHeading,20436,-1,-1,cancelled);
1468 if (params.size() > 3)
1469 overwrite = params[3].Equals("true");
1471 overwrite = CGUIDialogYesNo::ShowAndGetInput(iHeading,20431,-1,-1,cancelled);
1477 if (params.size() > 2)
1479 if (singleFile || !path.IsEmpty() ||
1480 CGUIDialogFileBrowser::ShowAndGetDirectory(shares,
1481 g_localizeStrings.Get(661), path, true))
1483 if (params[0].Equals("video"))
1485 CVideoDatabase videodatabase;
1486 videodatabase.Open();
1487 videodatabase.ExportToXML(path, singleFile, thumbs, actorThumbs, overwrite);
1488 videodatabase.Close();
1492 if (URIUtils::HasSlashAtEnd(path))
1493 path = URIUtils::AddFileToFolder(path, "musicdb.xml");
1494 CMusicDatabase musicdatabase;
1495 musicdatabase.Open();
1496 musicdatabase.ExportToXML(path, singleFile, thumbs, overwrite);
1497 musicdatabase.Close();
1501 else if (execute.Equals("control.move") && params.size() > 1)
1503 CGUIMessage message(GUI_MSG_MOVE_OFFSET, g_windowManager.GetFocusedWindow(), atoi(params[0].c_str()), atoi(params[1].c_str()));
1504 g_windowManager.SendMessage(message);
1506 else if (execute.Equals("container.refresh"))
1507 { // NOTE: These messages require a media window, thus they're sent to the current activewindow.
1508 // This shouldn't stop a dialog intercepting it though.
1509 CGUIMessage message(GUI_MSG_NOTIFY_ALL, g_windowManager.GetActiveWindow(), 0, GUI_MSG_UPDATE, 1); // 1 to reset the history
1510 message.SetStringParam(parameter);
1511 g_windowManager.SendMessage(message);
1513 else if (execute.Equals("container.update") && params.size())
1515 CGUIMessage message(GUI_MSG_NOTIFY_ALL, g_windowManager.GetActiveWindow(), 0, GUI_MSG_UPDATE, 0);
1516 message.SetStringParam(params[0]);
1517 if (params.size() > 1 && params[1].CompareNoCase("replace") == 0)
1518 message.SetParam2(1); // reset the history
1519 g_windowManager.SendMessage(message);
1521 else if (execute.Equals("container.nextviewmode"))
1523 CGUIMessage message(GUI_MSG_CHANGE_VIEW_MODE, g_windowManager.GetActiveWindow(), 0, 0, 1);
1524 g_windowManager.SendMessage(message);
1526 else if (execute.Equals("container.previousviewmode"))
1528 CGUIMessage message(GUI_MSG_CHANGE_VIEW_MODE, g_windowManager.GetActiveWindow(), 0, 0, -1);
1529 g_windowManager.SendMessage(message);
1531 else if (execute.Equals("container.setviewmode"))
1533 CGUIMessage message(GUI_MSG_CHANGE_VIEW_MODE, g_windowManager.GetActiveWindow(), 0, atoi(parameter.c_str()));
1534 g_windowManager.SendMessage(message);
1536 else if (execute.Equals("container.nextsortmethod"))
1538 CGUIMessage message(GUI_MSG_CHANGE_SORT_METHOD, g_windowManager.GetActiveWindow(), 0, 0, 1);
1539 g_windowManager.SendMessage(message);
1541 else if (execute.Equals("container.previoussortmethod"))
1543 CGUIMessage message(GUI_MSG_CHANGE_SORT_METHOD, g_windowManager.GetActiveWindow(), 0, 0, -1);
1544 g_windowManager.SendMessage(message);
1546 else if (execute.Equals("container.setsortmethod"))
1548 CGUIMessage message(GUI_MSG_CHANGE_SORT_METHOD, g_windowManager.GetActiveWindow(), 0, atoi(parameter.c_str()));
1549 g_windowManager.SendMessage(message);
1551 else if (execute.Equals("container.sortdirection"))
1553 CGUIMessage message(GUI_MSG_CHANGE_SORT_DIRECTION, g_windowManager.GetActiveWindow(), 0, 0);
1554 g_windowManager.SendMessage(message);
1556 else if (execute.Equals("control.message") && params.size() >= 2)
1558 int controlID = atoi(params[0].c_str());
1559 int windowID = (params.size() == 3) ? CButtonTranslator::TranslateWindow(params[2]) : g_windowManager.GetActiveWindow();
1560 if (params[1] == "moveup")
1561 g_windowManager.SendMessage(GUI_MSG_MOVE_OFFSET, windowID, controlID, 1);
1562 else if (params[1] == "movedown")
1563 g_windowManager.SendMessage(GUI_MSG_MOVE_OFFSET, windowID, controlID, -1);
1564 else if (params[1] == "pageup")
1565 g_windowManager.SendMessage(GUI_MSG_PAGE_UP, windowID, controlID);
1566 else if (params[1] == "pagedown")
1567 g_windowManager.SendMessage(GUI_MSG_PAGE_DOWN, windowID, controlID);
1568 else if (params[1] == "click")
1569 g_windowManager.SendMessage(GUI_MSG_CLICKED, controlID, windowID);
1571 else if (execute.Equals("sendclick") && params.size())
1573 if (params.size() == 2)
1575 // have a window - convert it
1576 int windowID = CButtonTranslator::TranslateWindow(params[0]);
1577 CGUIMessage message(GUI_MSG_CLICKED, atoi(params[1].c_str()), windowID);
1578 g_windowManager.SendMessage(message);
1581 { // single param - assume you meant the active window
1582 CGUIMessage message(GUI_MSG_CLICKED, atoi(params[0].c_str()), g_windowManager.GetActiveWindow());
1583 g_windowManager.SendMessage(message);
1586 else if (execute.Equals("action") && params.size())
1588 // try translating the action from our ButtonTranslator
1590 if (CButtonTranslator::TranslateActionString(params[0].c_str(), actionID))
1592 int windowID = params.size() == 2 ? CButtonTranslator::TranslateWindow(params[1]) : WINDOW_INVALID;
1593 CApplicationMessenger::Get().SendAction(CAction(actionID), windowID);
1596 else if (execute.Equals("setproperty") && params.size() >= 2)
1598 CGUIWindow *window = g_windowManager.GetWindow(params.size() > 2 ? CButtonTranslator::TranslateWindow(params[2]) : g_windowManager.GetFocusedWindow());
1600 window->SetProperty(params[0],params[1]);
1602 else if (execute.Equals("clearproperty") && params.size())
1604 CGUIWindow *window = g_windowManager.GetWindow(params.size() > 1 ? CButtonTranslator::TranslateWindow(params[1]) : g_windowManager.GetFocusedWindow());
1606 window->SetProperty(params[0],"");
1608 else if (execute.Equals("wakeonlan"))
1610 g_application.getNetwork().WakeOnLan((char*)params[0].c_str());
1612 else if (execute.Equals("addon.default.opensettings") && params.size() == 1)
1615 ADDON::TYPE type = TranslateType(params[0]);
1616 if (CAddonMgr::Get().GetDefault(type, addon))
1618 CGUIDialogAddonSettings::ShowAndGetInput(addon);
1619 if (type == ADDON_VIZ)
1620 g_windowManager.SendMessage(GUI_MSG_VISUALISATION_RELOAD, 0, 0);
1623 else if (execute.Equals("addon.default.set") && params.size() == 1)
1626 TYPE type = TranslateType(params[0]);
1627 bool allowNone = false;
1628 if (type == ADDON_VIZ)
1631 if (type != ADDON_UNKNOWN &&
1632 CGUIWindowAddonBrowser::SelectAddonID(type,addonID,allowNone))
1634 CAddonMgr::Get().SetDefault(type,addonID);
1635 if (type == ADDON_VIZ)
1636 g_windowManager.SendMessage(GUI_MSG_VISUALISATION_RELOAD, 0, 0);
1639 else if (execute.Equals("addon.opensettings") && params.size() == 1)
1642 if (CAddonMgr::Get().GetAddon(params[0], addon))
1643 CGUIDialogAddonSettings::ShowAndGetInput(addon);
1645 else if (execute.Equals("updateaddonrepos"))
1647 CAddonInstaller::Get().UpdateRepos(true);
1649 else if (execute.Equals("updatelocaladdons"))
1651 CAddonMgr::Get().FindAddons();
1653 else if (execute.Equals("toggledpms"))
1655 g_application.ToggleDPMS(true);
1657 else if (execute.Equals("cectogglestate"))
1659 CApplicationMessenger::Get().CECToggleState();
1661 else if (execute.Equals("cecactivatesource"))
1663 CApplicationMessenger::Get().CECActivateSource();
1665 else if (execute.Equals("cecstandby"))
1667 CApplicationMessenger::Get().CECStandby();
1669 #if defined(HAS_LIRC) || defined(HAS_IRSERVERSUITE)
1670 else if (execute.Equals("lirc.stop"))
1672 g_RemoteControl.Disconnect();
1673 g_RemoteControl.setUsed(false);
1675 else if (execute.Equals("lirc.start"))
1677 g_RemoteControl.setUsed(true);
1678 g_RemoteControl.Initialize();
1680 else if (execute.Equals("lirc.send"))
1683 for (int i = 0; i < (int)params.size(); i++)
1685 command += params[i];
1686 if (i < (int)params.size() - 1)
1689 g_RemoteControl.AddSendCommand(command);
1692 else if (execute.Equals("weather.locationset"))
1694 int loc = atoi(params[0]);
1695 CGUIMessage msg(GUI_MSG_ITEM_SELECT, 0, 0, loc);
1696 g_windowManager.SendMessage(msg, WINDOW_WEATHER);
1698 else if (execute.Equals("weather.locationnext"))
1700 CGUIMessage msg(GUI_MSG_MOVE_OFFSET, 0, 0, 1);
1701 g_windowManager.SendMessage(msg, WINDOW_WEATHER);
1703 else if (execute.Equals("weather.locationprevious"))
1705 CGUIMessage msg(GUI_MSG_MOVE_OFFSET, 0, 0, -1);
1706 g_windowManager.SendMessage(msg, WINDOW_WEATHER);
1708 else if (execute.Equals("weather.refresh"))
1710 CGUIMessage msg(GUI_MSG_MOVE_OFFSET, 0, 0, 0);
1711 g_windowManager.SendMessage(msg, WINDOW_WEATHER);
1713 else if (execute.Equals("videolibrary.search"))
1715 CGUIMessage msg(GUI_MSG_SEARCH, 0, 0, 0);
1716 g_windowManager.SendMessage(msg, WINDOW_VIDEO_NAV);
1718 else if (execute.Equals("toggledebug"))
1720 bool debug = CSettings::Get().GetBool("debug.showloginfo");
1721 CSettings::Get().SetBool("debug.showloginfo", !debug);
1722 g_advancedSettings.SetDebugMode(!debug);
1724 else if (execute.Equals("startpvrmanager"))
1726 g_application.StartPVRManager();
1728 else if (execute.Equals("stoppvrmanager"))
1730 g_application.StopPVRManager();
1732 else if (execute.Equals("StartAndroidActivity") && params.size() > 0)
1734 CApplicationMessenger::Get().StartAndroidActivity(params);
1736 else if (execute.Equals("SetStereoMode") && !parameter.IsEmpty())
1738 CAction action = CStereoscopicsManager::Get().ConvertActionCommandToAction(execute, parameter);
1739 if (action.GetID() != ACTION_NONE)
1740 CApplicationMessenger::Get().SendAction(action);
1743 CLog::Log(LOGERROR,"Builtin 'SetStereoMode' called with unknown parameter: %s", parameter.c_str());