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 "dialogs/GUIDialogKaiToast.h"
36 #include "dialogs/GUIDialogNumeric.h"
37 #include "dialogs/GUIDialogProgress.h"
38 #include "dialogs/GUIDialogYesNo.h"
39 #include "GUIUserMessages.h"
40 #include "windows/GUIWindowLoginScreen.h"
41 #include "video/windows/GUIWindowVideoBase.h"
42 #include "addons/GUIWindowAddonBrowser.h"
43 #include "addons/Addon.h" // for TranslateType, TranslateContent
44 #include "addons/AddonInstaller.h"
45 #include "addons/AddonManager.h"
46 #include "addons/PluginSource.h"
47 #include "network/NetworkServices.h"
48 #include "utils/log.h"
49 #include "storage/MediaManager.h"
50 #include "utils/RssManager.h"
51 #include "PartyModeManager.h"
52 #include "profiles/ProfilesManager.h"
53 #include "settings/DisplaySettings.h"
54 #include "settings/Settings.h"
55 #include "settings/MediaSettings.h"
56 #include "settings/MediaSourceSettings.h"
57 #include "settings/SkinSettings.h"
58 #include "utils/StringUtils.h"
59 #include "utils/URIUtils.h"
62 #include "music/MusicDatabase.h"
63 #include "cores/IPlayer.h"
65 #include "filesystem/PluginDirectory.h"
66 #ifdef HAS_FILESYSTEM_RAR
67 #include "filesystem/RarManager.h"
69 #include "filesystem/ZipManager.h"
71 #include "guilib/GUIWindowManager.h"
72 #include "guilib/LocalizeStrings.h"
75 #include "input/linux/LIRC.h"
77 #ifdef HAS_IRSERVERSUITE
79 #include "input/windows/IRServerSuite.h"
84 #include "interfaces/python/XBPython.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 { "Extract", true, "Extracts the specified archive" },
145 { "PlayMedia", true, "Play the specified media file (or playlist)" },
146 { "SlideShow", true, "Run a slideshow from the specified directory" },
147 { "RecursiveSlideShow", true, "Run a slideshow from the specified directory, including all subdirs" },
148 { "ReloadSkin", false, "Reload XBMC's skin" },
149 { "UnloadSkin", false, "Unload XBMC's skin" },
150 { "RefreshRSS", false, "Reload RSS feeds from RSSFeeds.xml"},
151 { "PlayerControl", true, "Control the music or video player" },
152 { "Playlist.PlayOffset", true, "Start playing from a particular offset in the playlist" },
153 { "Playlist.Clear", false, "Clear the current playlist" },
154 { "EjectTray", false, "Close or open the DVD tray" },
155 { "AlarmClock", true, "Prompt for a length of time and start an alarm clock" },
156 { "CancelAlarm", true, "Cancels an alarm" },
157 { "Action", true, "Executes an action for the active window (same as in keymap)" },
158 { "Notification", true, "Shows a notification on screen, specify header, then message, and optionally time in milliseconds and a icon." },
159 { "PlayDVD", false, "Plays the inserted CD or DVD media from the DVD-ROM Drive!" },
160 { "RipCD", false, "Rip the currently inserted audio CD"},
161 { "Skin.ToggleSetting", true, "Toggles a skin setting on or off" },
162 { "Skin.SetString", true, "Prompts and sets skin string" },
163 { "Skin.SetNumeric", true, "Prompts and sets numeric input" },
164 { "Skin.SetPath", true, "Prompts and sets a skin path" },
165 { "Skin.Theme", true, "Control skin theme" },
166 { "Skin.SetImage", true, "Prompts and sets a skin image" },
167 { "Skin.SetLargeImage", true, "Prompts and sets a large skin images" },
168 { "Skin.SetFile", true, "Prompts and sets a file" },
169 { "Skin.SetAddon", true, "Prompts and set an addon" },
170 { "Skin.SetBool", true, "Sets a skin setting on" },
171 { "Skin.Reset", true, "Resets a skin setting to default" },
172 { "Skin.ResetSettings", false, "Resets all skin settings" },
173 { "Mute", false, "Mute the player" },
174 { "SetVolume", true, "Set the current volume" },
175 { "Dialog.Close", true, "Close a dialog" },
176 { "System.LogOff", false, "Log off current user" },
177 { "System.Exec", true, "Execute shell commands" },
178 { "System.ExecWait", true, "Execute shell commands and freezes XBMC until shell is closed" },
179 { "Resolution", true, "Change XBMC's Resolution" },
180 { "SetFocus", true, "Change current focus to a different control id" },
181 { "UpdateLibrary", true, "Update the selected library (music or video)" },
182 { "CleanLibrary", true, "Clean the video/music library" },
183 { "ExportLibrary", true, "Export the video/music library" },
184 { "PageDown", true, "Send a page down event to the pagecontrol with given id" },
185 { "PageUp", true, "Send a page up event to the pagecontrol with given id" },
186 { "Container.Refresh", false, "Refresh current listing" },
187 { "Container.Update", false, "Update current listing. Send Container.Update(path,replace) to reset the path history" },
188 { "Container.NextViewMode", false, "Move to the next view type (and refresh the listing)" },
189 { "Container.PreviousViewMode", false, "Move to the previous view type (and refresh the listing)" },
190 { "Container.SetViewMode", true, "Move to the view with the given id" },
191 { "Container.NextSortMethod", false, "Change to the next sort method" },
192 { "Container.PreviousSortMethod",false, "Change to the previous sort method" },
193 { "Container.SetSortMethod", true, "Change to the specified sort method" },
194 { "Container.SortDirection", false, "Toggle the sort direction" },
195 { "Control.Move", true, "Tells the specified control to 'move' to another entry specified by offset" },
196 { "Control.SetFocus", true, "Change current focus to a different control id" },
197 { "Control.Message", true, "Send a given message to a control within a given window" },
198 { "SendClick", true, "Send a click message from the given control to the given window" },
199 { "LoadProfile", true, "Load the specified profile (note; if locks are active it won't work)" },
200 { "SetProperty", true, "Sets a window property for the current focused window/dialog (key,value)" },
201 { "ClearProperty", true, "Clears a window property for the current focused window/dialog (key,value)" },
202 { "PlayWith", true, "Play the selected item with the specified core" },
203 { "WakeOnLan", true, "Sends the wake-up packet to the broadcast address for the specified MAC address" },
204 { "Addon.Default.OpenSettings", true, "Open a settings dialog for the default addon of the given type" },
205 { "Addon.Default.Set", true, "Open a select dialog to allow choosing the default addon of the given type" },
206 { "Addon.OpenSettings", true, "Open a settings dialog for the addon of the given id" },
207 { "UpdateAddonRepos", false, "Check add-on repositories for updates" },
208 { "UpdateLocalAddons", false, "Check for local add-on changes" },
209 { "ToggleDPMS", false, "Toggle DPMS mode manually"},
210 { "Weather.Refresh", false, "Force weather data refresh"},
211 { "Weather.LocationNext", false, "Switch to next weather location"},
212 { "Weather.LocationPrevious", false, "Switch to previous weather location"},
213 { "Weather.LocationSet", true, "Switch to given weather location (parameter can be 1-3)"},
214 #if defined(HAS_LIRC) || defined(HAS_IRSERVERSUITE)
215 { "LIRC.Stop", false, "Removes XBMC as LIRC client" },
216 { "LIRC.Start", false, "Adds XBMC as LIRC client" },
217 { "LIRC.Send", true, "Sends a command to LIRC" },
219 { "VideoLibrary.Search", false, "Brings up a search dialog which will search the library" },
220 { "ToggleDebug", false, "Enables/disables debug mode" },
221 { "StartPVRManager", false, "(Re)Starts the PVR manager" },
222 { "StopPVRManager", false, "Stops the PVR manager" },
223 #if defined(TARGET_ANDROID)
224 { "StartAndroidActivity", true, "Launch an Android native app with the given package name. Optional parms (in order): intent, dataType, dataURI." },
228 bool CBuiltins::HasCommand(const CStdString& execString)
231 vector<CStdString> parameters;
232 CUtil::SplitExecFunction(execString, function, parameters);
233 for (unsigned int i = 0; i < sizeof(commands)/sizeof(BUILT_IN); i++)
235 if (function.CompareNoCase(commands[i].command) == 0 && (!commands[i].needsParameters || parameters.size()))
241 void CBuiltins::GetHelp(CStdString &help)
244 for (unsigned int i = 0; i < sizeof(commands)/sizeof(BUILT_IN); i++)
246 help += commands[i].command;
248 help += commands[i].description;
253 int CBuiltins::Execute(const CStdString& execString)
255 // Get the text after the "XBMC."
257 vector<CStdString> params;
258 CUtil::SplitExecFunction(execString, execute, params);
260 CStdString parameter = params.size() ? params[0] : "";
261 CStdString strParameterCaseIntact = parameter;
263 if (execute.Equals("reboot") || execute.Equals("restart") || execute.Equals("reset")) //Will reboot the system
265 CApplicationMessenger::Get().Restart();
267 else if (execute.Equals("shutdown"))
269 CApplicationMessenger::Get().Shutdown();
271 else if (execute.Equals("powerdown"))
273 CApplicationMessenger::Get().Powerdown();
275 else if (execute.Equals("restartapp"))
277 CApplicationMessenger::Get().RestartApp();
279 else if (execute.Equals("hibernate"))
281 CApplicationMessenger::Get().Hibernate();
283 else if (execute.Equals("suspend"))
285 CApplicationMessenger::Get().Suspend();
287 else if (execute.Equals("quit"))
289 CApplicationMessenger::Get().Quit();
291 else if (execute.Equals("inhibitidleshutdown"))
293 bool inhibit = (params.size() == 1 && params[0].Equals("true"));
294 CApplicationMessenger::Get().InhibitIdleShutdown(inhibit);
296 else if (execute.Equals("activatescreensaver"))
298 CApplicationMessenger::Get().ActivateScreensaver();
300 else if (execute.Equals("minimize"))
302 CApplicationMessenger::Get().Minimize();
304 else if (execute.Equals("loadprofile"))
306 int index = CProfilesManager::Get().GetProfileIndex(parameter);
307 bool prompt = (params.size() == 2 && params[1].Equals("prompt"));
310 && (CProfilesManager::Get().GetMasterProfile().getLockMode() == LOCK_MODE_EVERYONE
311 || g_passwordManager.IsProfileLockUnlocked(index,bCanceled,prompt)))
313 CApplicationMessenger::Get().LoadProfile(index);
316 else if (execute.Equals("mastermode"))
318 if (g_passwordManager.bMasterUser)
320 g_passwordManager.bMasterUser = false;
321 g_passwordManager.LockSources(true);
322 CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Warning, g_localizeStrings.Get(20052),g_localizeStrings.Get(20053));
324 else if (g_passwordManager.IsMasterLockUnlocked(true))
326 g_passwordManager.LockSources(false);
327 g_passwordManager.bMasterUser = true;
328 CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Warning, g_localizeStrings.Get(20052),g_localizeStrings.Get(20054));
331 CUtil::DeleteVideoDatabaseDirectoryCache();
332 CGUIMessage msg(GUI_MSG_NOTIFY_ALL, 0, 0, GUI_MSG_UPDATE);
333 g_windowManager.SendMessage(msg);
335 else if (execute.Equals("setguilanguage"))
339 CApplicationMessenger::Get().SetGUILanguage(params[0]);
342 else if (execute.Equals("takescreenshot"))
344 CScreenShot::TakeScreenshot();
346 else if (execute.Equals("activatewindow") || execute.Equals("replacewindow"))
348 // get the parameters
349 CStdString strWindow;
352 strWindow = params[0];
353 params.erase(params.begin());
356 // confirm the window destination is valid prior to switching
357 int iWindow = CButtonTranslator::TranslateWindow(strWindow);
358 if (iWindow != WINDOW_INVALID)
360 // disable the screensaver
361 g_application.WakeUpScreenSaverAndDPMS();
362 #if defined(TARGET_DARWIN_IOS)
363 if (params[0].Equals("shutdownmenu"))
364 CBuiltins::Execute("Quit");
366 g_windowManager.ActivateWindow(iWindow, params, !execute.Equals("activatewindow"));
370 CLog::Log(LOGERROR, "Activate/ReplaceWindow called with invalid destination window: %s", strWindow.c_str());
374 else if ((execute.Equals("setfocus") || execute.Equals("control.setfocus")) && params.size())
376 int controlID = atol(params[0].c_str());
377 int subItem = (params.size() > 1) ? atol(params[1].c_str())+1 : 0;
378 CGUIMessage msg(GUI_MSG_SETFOCUS, g_windowManager.GetFocusedWindow(), controlID, subItem);
379 g_windowManager.SendMessage(msg);
381 else if ((execute.Equals("activatewindowandfocus") || execute.Equals("replacewindowandfocus")) && params.size())
383 CStdString strWindow = params[0];
385 // confirm the window destination is valid prior to switching
386 int iWindow = CButtonTranslator::TranslateWindow(strWindow);
387 if (iWindow != WINDOW_INVALID)
389 // disable the screensaver
390 g_application.WakeUpScreenSaverAndDPMS();
391 #if defined(TARGET_DARWIN_IOS)
392 if (params[0].Equals("shutdownmenu"))
393 CBuiltins::Execute("Quit");
395 vector<CStdString> dummy;
396 g_windowManager.ActivateWindow(iWindow, dummy, !execute.Equals("activatewindowandfocus"));
398 unsigned int iPtr = 1;
399 while (params.size() > iPtr + 1)
401 CGUIMessage msg(GUI_MSG_SETFOCUS, g_windowManager.GetFocusedWindow(),
402 atol(params[iPtr].c_str()),
403 (params.size() >= iPtr + 2) ? atol(params[iPtr + 1].c_str())+1 : 0);
404 g_windowManager.SendMessage(msg);
410 CLog::Log(LOGERROR, "Replace/ActivateWindowAndFocus called with invalid destination window: %s", strWindow.c_str());
414 else if (execute.Equals("runscript") && params.size())
416 #if defined(TARGET_DARWIN_OSX)
417 if (URIUtils::HasExtension(strParameterCaseIntact, ".applescript|.scpt"))
419 CStdString osxPath = CSpecialProtocol::TranslatePath(strParameterCaseIntact);
420 Cocoa_DoAppleScriptFile(osxPath.c_str());
426 vector<CStdString> argv = params;
428 vector<CStdString> path;
429 //split the path up to find the filename
430 StringUtils::SplitString(params[0],"\\",path);
432 argv[0] = path[path.size() - 1];
435 CStdString scriptpath(params[0]);
436 if (CAddonMgr::Get().GetAddon(params[0], script))
437 scriptpath = script->LibPath();
439 g_pythonParser.evalFile(scriptpath, argv,script);
443 #if defined(TARGET_DARWIN_OSX)
444 else if (execute.Equals("runapplescript"))
446 Cocoa_DoAppleScript(strParameterCaseIntact.c_str());
449 else if (execute.Equals("stopscript"))
452 CStdString scriptpath(params[0]);
454 // Test to see if the param is an addon ID
456 if (CAddonMgr::Get().GetAddon(params[0], script))
457 scriptpath = script->LibPath();
459 g_pythonParser.StopScript(scriptpath);
462 else if (execute.Equals("system.exec"))
464 CApplicationMessenger::Get().Minimize();
465 CApplicationMessenger::Get().ExecOS(parameter, false);
467 else if (execute.Equals("system.execwait"))
469 CApplicationMessenger::Get().Minimize();
470 CApplicationMessenger::Get().ExecOS(parameter, true);
472 else if (execute.Equals("resolution"))
474 RESOLUTION res = RES_PAL_4x3;
475 if (parameter.Equals("pal")) res = RES_PAL_4x3;
476 else if (parameter.Equals("pal16x9")) res = RES_PAL_16x9;
477 else if (parameter.Equals("ntsc")) res = RES_NTSC_4x3;
478 else if (parameter.Equals("ntsc16x9")) res = RES_NTSC_16x9;
479 else if (parameter.Equals("720p")) res = RES_HDTV_720p;
480 else if (parameter.Equals("720pSBS")) res = RES_HDTV_720pSBS;
481 else if (parameter.Equals("720pTB")) res = RES_HDTV_720pTB;
482 else if (parameter.Equals("1080pSBS")) res = RES_HDTV_1080pSBS;
483 else if (parameter.Equals("1080pTB")) res = RES_HDTV_1080pTB;
484 else if (parameter.Equals("1080i")) res = RES_HDTV_1080i;
485 if (g_graphicsContext.IsValidResolution(res))
487 CDisplaySettings::Get().SetCurrentResolution(res, true);
488 g_application.ReloadSkin();
491 else if (execute.Equals("extract") && params.size())
493 // Detects if file is zip or zip then extracts
494 CStdString strDestDirect = "";
495 if (params.size() < 2)
496 URIUtils::GetDirectory(params[0],strDestDirect);
498 strDestDirect = params[1];
500 URIUtils::AddSlashAtEnd(strDestDirect);
502 if (URIUtils::IsZIP(params[0]))
503 g_ZipManager.ExtractArchive(params[0],strDestDirect);
504 #ifdef HAS_FILESYSTEM_RAR
505 else if (URIUtils::IsRAR(params[0]))
506 g_RarManager.ExtractArchive(params[0],strDestDirect);
509 CLog::Log(LOGERROR, "XBMC.Extract, No archive given");
511 else if (execute.Equals("runplugin"))
515 CFileItem item(params[0]);
516 if (!item.m_bIsFolder)
518 item.SetPath(params[0]);
519 CPluginDirectory::RunScriptWithParams(item.GetPath());
524 CLog::Log(LOGERROR, "XBMC.RunPlugin called with no arguments.");
527 else if (execute.Equals("runaddon"))
532 if (CAddonMgr::Get().GetAddon(params[0],addon) && addon)
534 PluginPtr plugin = boost::dynamic_pointer_cast<CPluginSource>(addon);
536 if (plugin && addon->Type() == ADDON_PLUGIN)
538 if (plugin->Provides(CPluginSource::VIDEO))
539 cmd.Format("ActivateWindow(Video,plugin://%s,return)",params[0]);
540 else if (plugin->Provides(CPluginSource::AUDIO))
541 cmd.Format("ActivateWindow(Music,plugin://%s,return)",params[0]);
542 else if (plugin->Provides(CPluginSource::EXECUTABLE))
543 cmd.Format("ActivateWindow(Programs,plugin://%s,return)",params[0]);
544 else if (plugin->Provides(CPluginSource::IMAGE))
545 cmd.Format("ActivateWindow(Pictures,plugin://%s,return)",params[0]);
547 // Pass the script name (params[0]) and all the parameters
548 // (params[1] ... params[x]) separated by a comma to RunPlugin
549 cmd.Format("RunPlugin(%s)", StringUtils::JoinString(params, ","));
551 else if (addon->Type() >= ADDON_SCRIPT && addon->Type() <= ADDON_SCRIPT_LYRICS)
552 // Pass the script name (params[0]) and all the parameters
553 // (params[1] ... params[x]) separated by a comma to RunScript
554 cmd.Format("RunScript(%s)", StringUtils::JoinString(params, ","));
561 CLog::Log(LOGERROR, "XBMC.RunAddon called with no arguments.");
564 else if (execute.Equals("playmedia"))
568 CLog::Log(LOGERROR, "XBMC.PlayMedia called with empty parameter");
572 CFileItem item(params[0], false);
573 if (URIUtils::HasSlashAtEnd(params[0]))
574 item.m_bIsFolder = true;
576 // restore to previous window if needed
577 if( g_windowManager.GetActiveWindow() == WINDOW_SLIDESHOW ||
578 g_windowManager.GetActiveWindow() == WINDOW_FULLSCREEN_VIDEO ||
579 g_windowManager.GetActiveWindow() == WINDOW_VISUALISATION )
580 g_windowManager.PreviousWindow();
583 g_application.ResetScreenSaver();
584 g_application.WakeUpScreenSaverAndDPMS();
586 // ask if we need to check guisettings to resume
587 bool askToResume = true;
589 for (unsigned int i = 1 ; i < params.size() ; i++)
591 if (params[i].Equals("isdir"))
592 item.m_bIsFolder = true;
593 else if (params[i].Equals("1")) // set fullscreen or windowed
594 CMediaSettings::Get().SetVideoStartWindowed(true);
595 else if (params[i].Equals("resume"))
597 // force the item to resume (if applicable) (see CApplication::PlayMedia)
598 item.m_lStartOffset = STARTOFFSET_RESUME;
601 else if (params[i].Equals("noresume"))
603 // force the item to start at the beginning (m_lStartOffset is initialized to 0)
606 else if (params[i].Left(11).Equals("playoffset=")) {
607 playOffset = atoi(params[i].Mid(11)) - 1;
608 item.SetProperty("playlist_starting_track", playOffset);
612 if (!item.m_bIsFolder && item.IsPlugin())
613 item.SetProperty("IsPlayable", true);
615 if ( askToResume == true )
617 if ( CGUIWindowVideoBase::ShowResumeMenu(item) == false )
620 if (item.m_bIsFolder)
623 CDirectory::GetDirectory(item.GetPath(),items,g_advancedSettings.m_videoExtensions);
624 int playlist = PLAYLIST_MUSIC;
625 for (int i = 0; i < items.Size(); i++)
627 if (items[i]->IsVideo())
629 playlist = PLAYLIST_VIDEO;
633 g_playlistPlayer.ClearPlaylist(playlist);
634 g_playlistPlayer.Add(playlist, items);
635 g_playlistPlayer.SetCurrentPlaylist(playlist);
636 g_playlistPlayer.Play(playOffset);
640 int playlist = item.IsAudio() ? PLAYLIST_MUSIC : PLAYLIST_VIDEO;
641 g_playlistPlayer.ClearPlaylist(playlist);
642 g_playlistPlayer.SetCurrentPlaylist(playlist);
645 if (!g_application.PlayMedia(item, playlist))
647 CLog::Log(LOGERROR, "XBMC.PlayMedia could not play media: %s", params[0].c_str());
652 else if (execute.Equals("showPicture"))
656 CLog::Log(LOGERROR, "XBMC.ShowPicture called with empty parameter");
659 CGUIMessage msg(GUI_MSG_SHOW_PICTURE, 0, 0);
660 msg.SetStringParam(params[0]);
661 CGUIWindow *pWindow = g_windowManager.GetWindow(WINDOW_SLIDESHOW);
662 if (pWindow) pWindow->OnMessage(msg);
664 else if (execute.Equals("slideShow") || execute.Equals("recursiveslideShow"))
668 CLog::Log(LOGERROR, "XBMC.SlideShow called with empty parameter");
671 std::string beginSlidePath;
672 // leave RecursiveSlideShow command as-is
673 unsigned int flags = 0;
674 if (execute.Equals("RecursiveSlideShow"))
677 // SlideShow(dir[,recursive][,[not]random][,pause][,beginslide="/path/to/start/slide.jpg"])
678 // the beginslide value need be escaped (for '"' or '\' in it, by backslash)
679 // and then quoted, or not. See CUtil::SplitParams()
682 for (unsigned int i = 1 ; i < params.size() ; i++)
684 if (params[i].Equals("recursive"))
686 else if (params[i].Equals("random")) // set fullscreen or windowed
688 else if (params[i].Equals("notrandom"))
690 else if (params[i].Equals("pause"))
692 else if (params[i].Left(11).Equals("beginslide="))
693 beginSlidePath = params[i].Mid(11);
697 CGUIMessage msg(GUI_MSG_START_SLIDESHOW, 0, 0, flags);
698 vector<CStdString> strParams;
699 strParams.push_back(params[0]);
700 strParams.push_back(beginSlidePath);
701 msg.SetStringParams(strParams);
702 CGUIWindow *pWindow = g_windowManager.GetWindow(WINDOW_SLIDESHOW);
703 if (pWindow) pWindow->OnMessage(msg);
705 else if (execute.Equals("reloadskin"))
708 g_application.ReloadSkin();
710 else if (execute.Equals("unloadskin"))
712 g_application.UnloadSkin(true); // we're reloading the skin after this
714 else if (execute.Equals("refreshrss"))
716 CRssManager::Get().Reload();
718 else if (execute.Equals("playercontrol"))
720 g_application.ResetScreenSaver();
721 g_application.WakeUpScreenSaverAndDPMS();
724 CLog::Log(LOGERROR, "XBMC.PlayerControl called with empty parameter");
727 if (parameter.Equals("play"))
729 // either resume playing, or pause
730 if (g_application.IsPlaying())
732 if (g_application.GetPlaySpeed() != 1)
733 g_application.SetPlaySpeed(1);
735 g_application.m_pPlayer->Pause();
738 else if (parameter.Equals("stop"))
740 g_application.StopPlaying();
742 else if (parameter.Equals("rewind") || parameter.Equals("forward"))
744 if (g_application.IsPlaying() && !g_application.m_pPlayer->IsPaused())
746 int iPlaySpeed = g_application.GetPlaySpeed();
747 if (parameter.Equals("rewind") && iPlaySpeed == 1) // Enables Rewinding
749 else if (parameter.Equals("rewind") && iPlaySpeed > 1) //goes down a notch if you're FFing
751 else if (parameter.Equals("forward") && iPlaySpeed < 1) //goes up a notch if you're RWing
754 if (iPlaySpeed == -1) iPlaySpeed = 1;
759 if (iPlaySpeed > 32 || iPlaySpeed < -32)
762 g_application.SetPlaySpeed(iPlaySpeed);
765 else if (parameter.Equals("next"))
767 g_application.OnAction(CAction(ACTION_NEXT_ITEM));
769 else if (parameter.Equals("previous"))
771 g_application.OnAction(CAction(ACTION_PREV_ITEM));
773 else if (parameter.Equals("bigskipbackward"))
775 if (g_application.IsPlaying())
776 g_application.m_pPlayer->Seek(false, true);
778 else if (parameter.Equals("bigskipforward"))
780 if (g_application.IsPlaying())
781 g_application.m_pPlayer->Seek(true, true);
783 else if (parameter.Equals("smallskipbackward"))
785 if (g_application.IsPlaying())
786 g_application.m_pPlayer->Seek(false, false);
788 else if (parameter.Equals("smallskipforward"))
790 if (g_application.IsPlaying())
791 g_application.m_pPlayer->Seek(true, false);
793 else if (parameter.Left(14).Equals("seekpercentage"))
795 CStdString offset = "";
796 if (parameter.size() == 14)
797 CLog::Log(LOGERROR,"PlayerControl(seekpercentage(n)) called with no argument");
798 else if (parameter.size() < 17) // arg must be at least "(N)"
799 CLog::Log(LOGERROR,"PlayerControl(seekpercentage(n)) called with invalid argument: \"%s\"", parameter.Mid(14).c_str());
802 // Don't bother checking the argument: an invalid arg will do seek(0)
803 offset = parameter.Mid(15).TrimRight(")");
804 float offsetpercent = (float) atof(offset.c_str());
805 if (offsetpercent < 0 || offsetpercent > 100)
806 CLog::Log(LOGERROR,"PlayerControl(seekpercentage(n)) argument, %f, must be 0-100", offsetpercent);
807 else if (g_application.IsPlaying())
808 g_application.SeekPercentage(offsetpercent);
811 else if( parameter.Equals("showvideomenu") )
813 if( g_application.IsPlaying() && g_application.m_pPlayer )
814 g_application.m_pPlayer->OnAction(CAction(ACTION_SHOW_VIDEOMENU));
816 else if( parameter.Equals("record") )
818 if( g_application.IsPlaying() && g_application.m_pPlayer && g_application.m_pPlayer->CanRecord())
819 g_application.m_pPlayer->Record(!g_application.m_pPlayer->IsRecording());
821 else if (parameter.Left(9).Equals("partymode"))
823 CStdString strXspPath = "";
824 //empty param=music, "music"=music, "video"=video, else xsp path
825 PartyModeContext context = PARTYMODECONTEXT_MUSIC;
826 if (parameter.size() > 9)
828 if (parameter.Mid(10).Equals("video)"))
829 context = PARTYMODECONTEXT_VIDEO;
830 else if (!parameter.Mid(10).Equals("music)"))
832 strXspPath = parameter.Mid(10).TrimRight(")");
833 context = PARTYMODECONTEXT_UNKNOWN;
836 if (g_partyModeManager.IsEnabled())
837 g_partyModeManager.Disable();
839 g_partyModeManager.Enable(context, strXspPath);
841 else if (parameter.Equals("random") ||
842 parameter.Equals("randomoff") ||
843 parameter.Equals("randomon"))
845 // get current playlist
846 int iPlaylist = g_playlistPlayer.GetCurrentPlaylist();
848 // reverse the current setting
849 bool shuffled = g_playlistPlayer.IsShuffled(iPlaylist);
850 if ((shuffled && parameter.Equals("randomon")) || (!shuffled && parameter.Equals("randomoff")))
853 // check to see if we should notify the user
854 bool notify = (params.size() == 2 && params[1].Equals("notify"));
855 g_playlistPlayer.SetShuffle(iPlaylist, !shuffled, notify);
857 // save settings for now playing windows
861 CMediaSettings::Get().SetMusicPlaylistShuffled(g_playlistPlayer.IsShuffled(iPlaylist));
862 CSettings::Get().Save();
865 CMediaSettings::Get().SetVideoPlaylistShuffled(g_playlistPlayer.IsShuffled(iPlaylist));
866 CSettings::Get().Save();
870 CGUIMessage msg(GUI_MSG_PLAYLISTPLAYER_RANDOM, 0, 0, iPlaylist, g_playlistPlayer.IsShuffled(iPlaylist));
871 g_windowManager.SendThreadMessage(msg);
874 else if (parameter.Left(6).Equals("repeat"))
876 // get current playlist
877 int iPlaylist = g_playlistPlayer.GetCurrentPlaylist();
878 PLAYLIST::REPEAT_STATE previous_state = g_playlistPlayer.GetRepeat(iPlaylist);
880 PLAYLIST::REPEAT_STATE state;
881 if (parameter.Equals("repeatall"))
882 state = PLAYLIST::REPEAT_ALL;
883 else if (parameter.Equals("repeatone"))
884 state = PLAYLIST::REPEAT_ONE;
885 else if (parameter.Equals("repeatoff"))
886 state = PLAYLIST::REPEAT_NONE;
887 else if (previous_state == PLAYLIST::REPEAT_NONE)
888 state = PLAYLIST::REPEAT_ALL;
889 else if (previous_state == PLAYLIST::REPEAT_ALL)
890 state = PLAYLIST::REPEAT_ONE;
892 state = PLAYLIST::REPEAT_NONE;
894 if (state == previous_state)
897 // check to see if we should notify the user
898 bool notify = (params.size() == 2 && params[1].Equals("notify"));
899 g_playlistPlayer.SetRepeat(iPlaylist, state, notify);
901 // save settings for now playing windows
905 CMediaSettings::Get().SetMusicPlaylistRepeat(state == PLAYLIST::REPEAT_ALL);
906 CSettings::Get().Save();
909 CMediaSettings::Get().SetVideoPlaylistRepeat(state == PLAYLIST::REPEAT_ALL);
910 CSettings::Get().Save();
913 // send messages so now playing window can get updated
914 CGUIMessage msg(GUI_MSG_PLAYLISTPLAYER_REPEAT, 0, 0, iPlaylist, (int)state);
915 g_windowManager.SendThreadMessage(msg);
918 else if (execute.Equals("playwith"))
920 g_application.m_eForcedNextPlayer = CPlayerCoreFactory::Get().GetPlayerCore(parameter);
921 g_application.OnAction(CAction(ACTION_PLAYER_PLAY));
923 else if (execute.Equals("mute"))
925 g_application.ToggleMute();
927 else if (execute.Equals("setvolume"))
929 float oldVolume = g_application.GetVolume();
930 float volume = (float)strtod(parameter.c_str(), NULL);
932 g_application.SetVolume(volume);
933 if(oldVolume != volume)
935 if(params.size() > 1 && params[1].Equals("showVolumeBar"))
937 CApplicationMessenger::Get().ShowVolumeBar(oldVolume < volume);
941 else if (execute.Equals("playlist.playoffset"))
943 // playlist.playoffset(offset)
944 // playlist.playoffset(music|video,offset)
945 CStdString strPos = parameter;
946 if (params.size() > 1)
948 // ignore any other parameters if present
949 CStdString strPlaylist = params[0];
952 int iPlaylist = PLAYLIST_NONE;
953 if (strPlaylist.Equals("music"))
954 iPlaylist = PLAYLIST_MUSIC;
955 else if (strPlaylist.Equals("video"))
956 iPlaylist = PLAYLIST_VIDEO;
959 if (iPlaylist == PLAYLIST_NONE)
961 CLog::Log(LOGERROR,"Playlist.PlayOffset called with unknown playlist: %s", strPlaylist.c_str());
965 // user wants to play the 'other' playlist
966 if (iPlaylist != g_playlistPlayer.GetCurrentPlaylist())
968 g_application.StopPlaying();
969 g_playlistPlayer.Reset();
970 g_playlistPlayer.SetCurrentPlaylist(iPlaylist);
973 // play the desired offset
974 int pos = atol(strPos.c_str());
975 // playlist is already playing
976 if (g_application.IsPlaying())
977 g_playlistPlayer.PlayNext(pos);
978 // we start playing the 'other' playlist so we need to use play to initialize the player state
980 g_playlistPlayer.Play(pos);
982 else if (execute.Equals("playlist.clear"))
984 g_playlistPlayer.Clear();
987 else if (execute.Equals("ejecttray"))
989 g_mediaManager.ToggleTray();
992 else if( execute.Equals("alarmclock") && params.size() > 1 )
994 // format is alarmclock(name,command[,seconds,true]);
996 if (params.size() > 2)
998 if (params[2].Find(':') == -1)
999 seconds = static_cast<float>(atoi(params[2].c_str())*60);
1001 seconds = (float)StringUtils::TimeStringToSeconds(params[2]);
1004 { // check if shutdown is specified in particular, and get the time for it
1005 CStdString strHeading;
1006 if (parameter.CompareNoCase("shutdowntimer") == 0)
1007 strHeading = g_localizeStrings.Get(20145);
1009 strHeading = g_localizeStrings.Get(13209);
1011 if( CGUIDialogNumeric::ShowAndGetNumber(strTime, strHeading) )
1012 seconds = static_cast<float>(atoi(strTime.c_str())*60);
1016 bool silent = false;
1018 for (unsigned int i = 3; i < params.size() ; i++)
1020 // check "true" for backward comp
1021 if (params[i].CompareNoCase("true") == 0 || params[i].CompareNoCase("silent") == 0)
1023 else if (params[i].CompareNoCase("loop") == 0)
1027 if( g_alarmClock.IsRunning() )
1028 g_alarmClock.Stop(params[0],silent);
1029 // no negative times not allowed, loop must have a positive time
1030 if (seconds < 0 || (seconds == 0 && loop))
1032 g_alarmClock.Start(params[0], seconds, params[1], silent, loop);
1034 else if (execute.Equals("notification"))
1036 if (params.size() < 2)
1038 if (params.size() == 4)
1039 CGUIDialogKaiToast::QueueNotification(params[3],params[0],params[1],atoi(params[2].c_str()));
1040 else if (params.size() == 3)
1041 CGUIDialogKaiToast::QueueNotification("",params[0],params[1],atoi(params[2].c_str()));
1043 CGUIDialogKaiToast::QueueNotification(params[0],params[1]);
1045 else if (execute.Equals("cancelalarm"))
1047 bool silent = false;
1048 if (params.size() > 1 && params[1].CompareNoCase("true") == 0)
1050 g_alarmClock.Stop(params[0],silent);
1052 else if (execute.Equals("playdvd"))
1054 #ifdef HAS_DVD_DRIVE
1055 bool restart = false;
1056 if (params.size() > 0 && params[0].CompareNoCase("restart") == 0)
1058 CAutorun::PlayDisc(g_mediaManager.GetDiscPath(), true, restart);
1061 else if (execute.Equals("ripcd"))
1063 #ifdef HAS_CDDA_RIPPER
1064 CCDDARipper::GetInstance().RipCD();
1067 else if (execute.Equals("skin.togglesetting"))
1069 int setting = CSkinSettings::Get().TranslateBool(parameter);
1070 CSkinSettings::Get().SetBool(setting, !CSkinSettings::Get().GetBool(setting));
1071 CSettings::Get().Save();
1073 else if (execute.Equals("skin.setbool") && params.size())
1075 if (params.size() > 1)
1077 int string = CSkinSettings::Get().TranslateBool(params[0]);
1078 CSkinSettings::Get().SetBool(string, params[1].CompareNoCase("true") == 0);
1079 CSettings::Get().Save();
1082 // default is to set it to true
1083 int setting = CSkinSettings::Get().TranslateBool(params[0]);
1084 CSkinSettings::Get().SetBool(setting, true);
1085 CSettings::Get().Save();
1087 else if (execute.Equals("skin.reset"))
1089 CSkinSettings::Get().Reset(parameter);
1090 CSettings::Get().Save();
1092 else if (execute.Equals("skin.resetsettings"))
1094 CSkinSettings::Get().Reset();
1095 CSettings::Get().Save();
1097 else if (execute.Equals("skin.theme"))
1100 vector<CStdString> vecTheme;
1101 CUtil::GetSkinThemes(vecTheme);
1105 // find current theme
1106 if (!StringUtils::EqualsNoCase(CSettings::Get().GetString("lookandfeel.skintheme"), "SKINDEFAULT"))
1108 for (unsigned int i=0;i<vecTheme.size();++i)
1110 CStdString strTmpTheme(CSettings::Get().GetString("lookandfeel.skintheme"));
1111 URIUtils::RemoveExtension(strTmpTheme);
1112 if (vecTheme[i].Equals(strTmpTheme))
1120 int iParam = atoi(parameter.c_str());
1121 if (iParam == 0 || iParam == 1)
1123 else if (iParam == -1)
1125 if (iTheme > (int)vecTheme.size()-1)
1128 iTheme = vecTheme.size()-1;
1130 CStdString strSkinTheme = "SKINDEFAULT";
1131 if (iTheme != -1 && iTheme < (int)vecTheme.size())
1132 strSkinTheme = vecTheme[iTheme];
1134 CSettings::Get().SetString("lookandfeel.skintheme", strSkinTheme);
1135 // also set the default color theme
1136 CStdString colorTheme(URIUtils::ReplaceExtension(strSkinTheme, ".xml"));
1137 if (colorTheme.Equals("Textures.xml"))
1138 colorTheme = "defaults.xml";
1139 CSettings::Get().SetString("lookandfeel.skincolors", colorTheme);
1140 g_application.ReloadSkin();
1142 else if (execute.Equals("skin.setstring") || execute.Equals("skin.setimage") || execute.Equals("skin.setfile") ||
1143 execute.Equals("skin.setpath") || execute.Equals("skin.setnumeric") || execute.Equals("skin.setlargeimage"))
1145 // break the parameter up if necessary
1147 if (params.size() > 1)
1149 string = CSkinSettings::Get().TranslateString(params[0]);
1150 if (execute.Equals("skin.setstring"))
1152 CSkinSettings::Get().SetString(string, params[1]);
1153 CSettings::Get().Save();
1158 string = CSkinSettings::Get().TranslateString(params[0]);
1159 CStdString value = CSkinSettings::Get().GetString(string);
1160 VECSOURCES localShares;
1161 g_mediaManager.GetLocalDrives(localShares);
1162 if (execute.Equals("skin.setstring"))
1164 if (CGUIKeyboardFactory::ShowAndGetInput(value, g_localizeStrings.Get(1029), true))
1165 CSkinSettings::Get().SetString(string, value);
1167 else if (execute.Equals("skin.setnumeric"))
1169 if (CGUIDialogNumeric::ShowAndGetNumber(value, g_localizeStrings.Get(611)))
1170 CSkinSettings::Get().SetString(string, value);
1172 else if (execute.Equals("skin.setimage"))
1174 if (CGUIDialogFileBrowser::ShowAndGetImage(localShares, g_localizeStrings.Get(1030), value))
1175 CSkinSettings::Get().SetString(string, value);
1177 else if (execute.Equals("skin.setlargeimage"))
1179 VECSOURCES *shares = CMediaSourceSettings::Get().GetSources("pictures");
1180 if (!shares) shares = &localShares;
1181 if (CGUIDialogFileBrowser::ShowAndGetImage(*shares, g_localizeStrings.Get(1030), value))
1182 CSkinSettings::Get().SetString(string, value);
1184 else if (execute.Equals("skin.setfile"))
1186 // Note. can only browse one addon type from here
1187 // if browsing for addons, required param[1] is addontype string, with optional param[2]
1188 // as contenttype string see IAddon.h & ADDON::TranslateXX
1189 CStdString strMask = (params.size() > 1) ? params[1] : "";
1192 if ((type = TranslateType(strMask)) != ADDON_UNKNOWN)
1195 url.SetProtocol("addons");
1196 url.SetHostName("enabled");
1197 url.SetFileName(strMask+"/");
1198 localShares.clear();
1199 CStdString content = (params.size() > 2) ? params[2] : "";
1201 url.SetPassword(content);
1203 if (type == ADDON_SCRIPT)
1206 if (CGUIDialogFileBrowser::ShowAndGetFile(url.Get(), strMask, TranslateType(type, true), replace, true, true, true))
1208 if (replace.Mid(0,9).Equals("addons://"))
1209 CSkinSettings::Get().SetString(string, URIUtils::GetFileName(replace));
1211 CSkinSettings::Get().SetString(string, replace);
1216 if (params.size() > 2)
1219 URIUtils::AddSlashAtEnd(value);
1221 if (CUtil::GetMatchingSource(value,localShares,bIsSource) < 0) // path is outside shares - add it as a separate one
1224 share.strName = g_localizeStrings.Get(13278);
1225 share.strPath = value;
1226 localShares.push_back(share);
1229 if (CGUIDialogFileBrowser::ShowAndGetFile(localShares, strMask, g_localizeStrings.Get(1033), value))
1230 CSkinSettings::Get().SetString(string, value);
1233 else // execute.Equals("skin.setpath"))
1235 g_mediaManager.GetNetworkLocations(localShares);
1236 if (params.size() > 1)
1239 URIUtils::AddSlashAtEnd(value);
1241 if (CUtil::GetMatchingSource(value,localShares,bIsSource) < 0) // path is outside shares - add it as a separate one
1244 share.strName = g_localizeStrings.Get(13278);
1245 share.strPath = value;
1246 localShares.push_back(share);
1249 if (CGUIDialogFileBrowser::ShowAndGetDirectory(localShares, g_localizeStrings.Get(1031), value))
1250 CSkinSettings::Get().SetString(string, value);
1252 CSettings::Get().Save();
1254 else if (execute.Equals("skin.setaddon") && params.size() > 1)
1256 int string = CSkinSettings::Get().TranslateString(params[0]);
1257 vector<ADDON::TYPE> types;
1258 for (unsigned int i = 1 ; i < params.size() ; i++)
1260 ADDON::TYPE type = TranslateType(params[i]);
1261 if (type != ADDON_UNKNOWN)
1262 types.push_back(type);
1265 if (types.size() > 0 && CGUIWindowAddonBrowser::SelectAddonID(types, result, true) == 1)
1267 CSkinSettings::Get().SetString(string, result);
1268 CSettings::Get().Save();
1271 else if (execute.Equals("dialog.close") && params.size())
1273 bool bForce = false;
1274 if (params.size() > 1 && params[1].CompareNoCase("true") == 0)
1276 if (params[0].CompareNoCase("all") == 0)
1278 g_windowManager.CloseDialogs(bForce);
1282 int id = CButtonTranslator::TranslateWindow(params[0]);
1283 CGUIWindow *window = (CGUIWindow *)g_windowManager.GetWindow(id);
1284 if (window && window->IsDialog())
1285 ((CGUIDialog *)window)->Close(bForce);
1288 else if (execute.Equals("system.logoff"))
1290 // there was a commit from cptspiff here which was reverted
1291 // for keeping the behaviour from Eden in Frodo - see
1292 // git rev 9ee5f0047b
1293 if (g_windowManager.GetActiveWindow() == WINDOW_LOGIN_SCREEN)
1296 g_application.StopPlaying();
1297 if (g_application.IsMusicScanning())
1298 g_application.StopMusicScan();
1300 if (g_application.IsVideoScanning())
1301 g_application.StopVideoScan();
1303 ADDON::CAddonMgr::Get().StopServices(true);
1305 g_application.getNetwork().NetworkMessage(CNetwork::SERVICES_DOWN,1);
1306 CProfilesManager::Get().LoadMasterProfileForLogin();
1307 g_passwordManager.bMasterUser = false;
1308 g_windowManager.ActivateWindow(WINDOW_LOGIN_SCREEN);
1309 if (!CNetworkServices::Get().StartEventServer()) // event server could be needed in some situations
1310 CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Warning, g_localizeStrings.Get(33102), g_localizeStrings.Get(33100));
1312 else if (execute.Equals("pagedown"))
1314 int id = atoi(parameter.c_str());
1315 CGUIMessage message(GUI_MSG_PAGE_DOWN, g_windowManager.GetFocusedWindow(), id);
1316 g_windowManager.SendMessage(message);
1318 else if (execute.Equals("pageup"))
1320 int id = atoi(parameter.c_str());
1321 CGUIMessage message(GUI_MSG_PAGE_UP, g_windowManager.GetFocusedWindow(), id);
1322 g_windowManager.SendMessage(message);
1324 else if (execute.Equals("updatelibrary") && params.size())
1326 if (params[0].Equals("music"))
1328 if (g_application.IsMusicScanning())
1329 g_application.StopMusicScan();
1331 g_application.StartMusicScan(params.size() > 1 ? params[1] : "");
1333 if (params[0].Equals("video"))
1335 if (g_application.IsVideoScanning())
1336 g_application.StopVideoScan();
1338 g_application.StartVideoScan(params.size() > 1 ? params[1] : "");
1341 else if (execute.Equals("cleanlibrary"))
1343 if (!params.size() || params[0].Equals("video"))
1345 if (!g_application.IsVideoScanning())
1346 g_application.StartVideoCleanup();
1348 CLog::Log(LOGERROR, "XBMC.CleanLibrary is not possible while scanning or cleaning");
1350 else if (params[0].Equals("music"))
1352 if (!g_application.IsMusicScanning())
1354 CMusicDatabase musicdatabase;
1356 musicdatabase.Open();
1357 musicdatabase.Cleanup();
1358 musicdatabase.Close();
1361 CLog::Log(LOGERROR, "XBMC.CleanLibrary is not possible while scanning for media info");
1364 else if (execute.Equals("exportlibrary"))
1367 if (params[0].Equals("music"))
1371 g_mediaManager.GetLocalDrives(shares);
1374 bool actorThumbs=false;
1375 bool overwrite=false;
1376 bool cancelled=false;
1378 if (params.size() > 1)
1379 singleFile = params[1].Equals("true");
1381 singleFile = CGUIDialogYesNo::ShowAndGetInput(iHeading,20426,20427,-1,20428,20429,cancelled);
1388 if (params.size() > 2)
1389 thumbs = params[2].Equals("true");
1391 thumbs = CGUIDialogYesNo::ShowAndGetInput(iHeading,20430,-1,-1,cancelled);
1397 if (thumbs && params[0].Equals("video"))
1399 if (params.size() > 4)
1400 actorThumbs = params[4].Equals("true");
1402 actorThumbs = CGUIDialogYesNo::ShowAndGetInput(iHeading,20436,-1,-1,cancelled);
1410 if (params.size() > 3)
1411 overwrite = params[3].Equals("true");
1413 overwrite = CGUIDialogYesNo::ShowAndGetInput(iHeading,20431,-1,-1,cancelled);
1419 if (params.size() > 2)
1421 if (singleFile || !path.IsEmpty() ||
1422 CGUIDialogFileBrowser::ShowAndGetDirectory(shares,
1423 g_localizeStrings.Get(661), path, true))
1425 if (params[0].Equals("video"))
1427 CVideoDatabase videodatabase;
1428 videodatabase.Open();
1429 videodatabase.ExportToXML(path, singleFile, thumbs, actorThumbs, overwrite);
1430 videodatabase.Close();
1434 if (URIUtils::HasSlashAtEnd(path))
1435 path = URIUtils::AddFileToFolder(path, "musicdb.xml");
1436 CMusicDatabase musicdatabase;
1437 musicdatabase.Open();
1438 musicdatabase.ExportToXML(path, singleFile, thumbs, overwrite);
1439 musicdatabase.Close();
1443 else if (execute.Equals("control.move") && params.size() > 1)
1445 CGUIMessage message(GUI_MSG_MOVE_OFFSET, g_windowManager.GetFocusedWindow(), atoi(params[0].c_str()), atoi(params[1].c_str()));
1446 g_windowManager.SendMessage(message);
1448 else if (execute.Equals("container.refresh"))
1449 { // NOTE: These messages require a media window, thus they're sent to the current activewindow.
1450 // This shouldn't stop a dialog intercepting it though.
1451 CGUIMessage message(GUI_MSG_NOTIFY_ALL, g_windowManager.GetActiveWindow(), 0, GUI_MSG_UPDATE, 1); // 1 to reset the history
1452 message.SetStringParam(parameter);
1453 g_windowManager.SendMessage(message);
1455 else if (execute.Equals("container.update") && params.size())
1457 CGUIMessage message(GUI_MSG_NOTIFY_ALL, g_windowManager.GetActiveWindow(), 0, GUI_MSG_UPDATE, 0);
1458 message.SetStringParam(params[0]);
1459 if (params.size() > 1 && params[1].CompareNoCase("replace") == 0)
1460 message.SetParam2(1); // reset the history
1461 g_windowManager.SendMessage(message);
1463 else if (execute.Equals("container.nextviewmode"))
1465 CGUIMessage message(GUI_MSG_CHANGE_VIEW_MODE, g_windowManager.GetActiveWindow(), 0, 0, 1);
1466 g_windowManager.SendMessage(message);
1468 else if (execute.Equals("container.previousviewmode"))
1470 CGUIMessage message(GUI_MSG_CHANGE_VIEW_MODE, g_windowManager.GetActiveWindow(), 0, 0, -1);
1471 g_windowManager.SendMessage(message);
1473 else if (execute.Equals("container.setviewmode"))
1475 CGUIMessage message(GUI_MSG_CHANGE_VIEW_MODE, g_windowManager.GetActiveWindow(), 0, atoi(parameter.c_str()));
1476 g_windowManager.SendMessage(message);
1478 else if (execute.Equals("container.nextsortmethod"))
1480 CGUIMessage message(GUI_MSG_CHANGE_SORT_METHOD, g_windowManager.GetActiveWindow(), 0, 0, 1);
1481 g_windowManager.SendMessage(message);
1483 else if (execute.Equals("container.previoussortmethod"))
1485 CGUIMessage message(GUI_MSG_CHANGE_SORT_METHOD, g_windowManager.GetActiveWindow(), 0, 0, -1);
1486 g_windowManager.SendMessage(message);
1488 else if (execute.Equals("container.setsortmethod"))
1490 CGUIMessage message(GUI_MSG_CHANGE_SORT_METHOD, g_windowManager.GetActiveWindow(), 0, atoi(parameter.c_str()));
1491 g_windowManager.SendMessage(message);
1493 else if (execute.Equals("container.sortdirection"))
1495 CGUIMessage message(GUI_MSG_CHANGE_SORT_DIRECTION, g_windowManager.GetActiveWindow(), 0, 0);
1496 g_windowManager.SendMessage(message);
1498 else if (execute.Equals("control.message") && params.size() >= 2)
1500 int controlID = atoi(params[0].c_str());
1501 int windowID = (params.size() == 3) ? CButtonTranslator::TranslateWindow(params[2]) : g_windowManager.GetActiveWindow();
1502 if (params[1] == "moveup")
1503 g_windowManager.SendMessage(GUI_MSG_MOVE_OFFSET, windowID, controlID, 1);
1504 else if (params[1] == "movedown")
1505 g_windowManager.SendMessage(GUI_MSG_MOVE_OFFSET, windowID, controlID, -1);
1506 else if (params[1] == "pageup")
1507 g_windowManager.SendMessage(GUI_MSG_PAGE_UP, windowID, controlID);
1508 else if (params[1] == "pagedown")
1509 g_windowManager.SendMessage(GUI_MSG_PAGE_DOWN, windowID, controlID);
1510 else if (params[1] == "click")
1511 g_windowManager.SendMessage(GUI_MSG_CLICKED, controlID, windowID);
1513 else if (execute.Equals("sendclick") && params.size())
1515 if (params.size() == 2)
1517 // have a window - convert it
1518 int windowID = CButtonTranslator::TranslateWindow(params[0]);
1519 CGUIMessage message(GUI_MSG_CLICKED, atoi(params[1].c_str()), windowID);
1520 g_windowManager.SendMessage(message);
1523 { // single param - assume you meant the active window
1524 CGUIMessage message(GUI_MSG_CLICKED, atoi(params[0].c_str()), g_windowManager.GetActiveWindow());
1525 g_windowManager.SendMessage(message);
1528 else if (execute.Equals("action") && params.size())
1530 // try translating the action from our ButtonTranslator
1532 if (CButtonTranslator::TranslateActionString(params[0].c_str(), actionID))
1534 int windowID = params.size() == 2 ? CButtonTranslator::TranslateWindow(params[1]) : WINDOW_INVALID;
1535 CApplicationMessenger::Get().SendAction(CAction(actionID), windowID);
1538 else if (execute.Equals("setproperty") && params.size() >= 2)
1540 CGUIWindow *window = g_windowManager.GetWindow(params.size() > 2 ? CButtonTranslator::TranslateWindow(params[2]) : g_windowManager.GetFocusedWindow());
1542 window->SetProperty(params[0],params[1]);
1544 else if (execute.Equals("clearproperty") && params.size())
1546 CGUIWindow *window = g_windowManager.GetWindow(params.size() > 1 ? CButtonTranslator::TranslateWindow(params[1]) : g_windowManager.GetFocusedWindow());
1548 window->SetProperty(params[0],"");
1550 else if (execute.Equals("wakeonlan"))
1552 g_application.getNetwork().WakeOnLan((char*)params[0].c_str());
1554 else if (execute.Equals("addon.default.opensettings") && params.size() == 1)
1557 ADDON::TYPE type = TranslateType(params[0]);
1558 if (CAddonMgr::Get().GetDefault(type, addon))
1560 CGUIDialogAddonSettings::ShowAndGetInput(addon);
1561 if (type == ADDON_VIZ)
1562 g_windowManager.SendMessage(GUI_MSG_VISUALISATION_RELOAD, 0, 0);
1565 else if (execute.Equals("addon.default.set") && params.size() == 1)
1568 TYPE type = TranslateType(params[0]);
1569 bool allowNone = false;
1570 if (type == ADDON_VIZ)
1573 if (type != ADDON_UNKNOWN &&
1574 CGUIWindowAddonBrowser::SelectAddonID(type,addonID,allowNone))
1576 CAddonMgr::Get().SetDefault(type,addonID);
1577 if (type == ADDON_VIZ)
1578 g_windowManager.SendMessage(GUI_MSG_VISUALISATION_RELOAD, 0, 0);
1581 else if (execute.Equals("addon.opensettings") && params.size() == 1)
1584 if (CAddonMgr::Get().GetAddon(params[0], addon))
1585 CGUIDialogAddonSettings::ShowAndGetInput(addon);
1587 else if (execute.Equals("updateaddonrepos"))
1589 CAddonInstaller::Get().UpdateRepos(true);
1591 else if (execute.Equals("updatelocaladdons"))
1593 CAddonMgr::Get().FindAddons();
1595 else if (execute.Equals("toggledpms"))
1597 g_application.ToggleDPMS(true);
1599 #if defined(HAS_LIRC) || defined(HAS_IRSERVERSUITE)
1600 else if (execute.Equals("lirc.stop"))
1602 g_RemoteControl.Disconnect();
1603 g_RemoteControl.setUsed(false);
1605 else if (execute.Equals("lirc.start"))
1607 g_RemoteControl.setUsed(true);
1608 g_RemoteControl.Initialize();
1610 else if (execute.Equals("lirc.send"))
1613 for (int i = 0; i < (int)params.size(); i++)
1615 command += params[i];
1616 if (i < (int)params.size() - 1)
1619 g_RemoteControl.AddSendCommand(command);
1622 else if (execute.Equals("weather.locationset"))
1624 int loc = atoi(params[0]);
1625 CGUIMessage msg(GUI_MSG_ITEM_SELECT, 0, 0, loc);
1626 g_windowManager.SendMessage(msg, WINDOW_WEATHER);
1628 else if (execute.Equals("weather.locationnext"))
1630 CGUIMessage msg(GUI_MSG_MOVE_OFFSET, 0, 0, 1);
1631 g_windowManager.SendMessage(msg, WINDOW_WEATHER);
1633 else if (execute.Equals("weather.locationprevious"))
1635 CGUIMessage msg(GUI_MSG_MOVE_OFFSET, 0, 0, -1);
1636 g_windowManager.SendMessage(msg, WINDOW_WEATHER);
1638 else if (execute.Equals("weather.refresh"))
1640 CGUIMessage msg(GUI_MSG_MOVE_OFFSET, 0, 0, 0);
1641 g_windowManager.SendMessage(msg, WINDOW_WEATHER);
1643 else if (execute.Equals("videolibrary.search"))
1645 CGUIMessage msg(GUI_MSG_SEARCH, 0, 0, 0);
1646 g_windowManager.SendMessage(msg, WINDOW_VIDEO_NAV);
1648 else if (execute.Equals("toggledebug"))
1650 bool debug = CSettings::Get().GetBool("debug.showloginfo");
1651 CSettings::Get().SetBool("debug.showloginfo", !debug);
1652 g_advancedSettings.SetDebugMode(!debug);
1654 else if (execute.Equals("startpvrmanager"))
1656 g_application.StartPVRManager();
1658 else if (execute.Equals("stoppvrmanager"))
1660 g_application.StopPVRManager();
1662 else if (execute.Equals("StartAndroidActivity") && params.size() > 0)
1664 CApplicationMessenger::Get().StartAndroidActivity(params);