summaryrefslogtreecommitdiffstats
path: root/xbmc/settings/MediaSettings.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'xbmc/settings/MediaSettings.cpp')
-rw-r--r--xbmc/settings/MediaSettings.cpp415
1 files changed, 415 insertions, 0 deletions
diff --git a/xbmc/settings/MediaSettings.cpp b/xbmc/settings/MediaSettings.cpp
new file mode 100644
index 0000000..09aad05
--- /dev/null
+++ b/xbmc/settings/MediaSettings.cpp
@@ -0,0 +1,415 @@
+/*
+ * Copyright (C) 2013-2018 Team Kodi
+ * This file is part of Kodi - https://kodi.tv
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * See LICENSES/README.md for more information.
+ */
+
+#include "MediaSettings.h"
+
+#include "PlayListPlayer.h"
+#include "ServiceBroker.h"
+#include "cores/RetroPlayer/RetroPlayerUtils.h"
+#include "dialogs/GUIDialogFileBrowser.h"
+#include "guilib/LocalizeStrings.h"
+#include "interfaces/AnnouncementManager.h"
+#include "interfaces/builtins/Builtins.h"
+#include "messaging/helpers/DialogHelper.h"
+#include "messaging/helpers/DialogOKHelper.h"
+#include "music/MusicLibraryQueue.h"
+#include "settings/Settings.h"
+#include "settings/dialogs/GUIDialogLibExportSettings.h"
+#include "settings/lib/Setting.h"
+#include "storage/MediaManager.h"
+#include "utils/StringUtils.h"
+#include "utils/Variant.h"
+#include "utils/XBMCTinyXML.h"
+#include "utils/XMLUtils.h"
+#include "utils/log.h"
+#include "video/VideoDatabase.h"
+#include "video/VideoLibraryQueue.h"
+
+#include <limits.h>
+#include <mutex>
+#include <string>
+
+using namespace KODI;
+using namespace KODI::MESSAGING;
+
+using KODI::MESSAGING::HELPERS::DialogResponse;
+
+CMediaSettings::CMediaSettings()
+{
+ m_watchedModes["files"] = WatchedModeAll;
+ m_watchedModes["movies"] = WatchedModeAll;
+ m_watchedModes["tvshows"] = WatchedModeAll;
+ m_watchedModes["musicvideos"] = WatchedModeAll;
+ m_watchedModes["recordings"] = WatchedModeAll;
+
+ m_musicPlaylistRepeat = false;
+ m_musicPlaylistShuffle = false;
+ m_videoPlaylistRepeat = false;
+ m_videoPlaylistShuffle = false;
+
+ m_mediaStartWindowed = false;
+ m_additionalSubtitleDirectoryChecked = 0;
+
+ m_musicNeedsUpdate = 0;
+ m_videoNeedsUpdate = 0;
+}
+
+CMediaSettings::~CMediaSettings() = default;
+
+CMediaSettings& CMediaSettings::GetInstance()
+{
+ static CMediaSettings sMediaSettings;
+ return sMediaSettings;
+}
+
+bool CMediaSettings::Load(const TiXmlNode *settings)
+{
+ if (settings == NULL)
+ return false;
+
+ std::unique_lock<CCriticalSection> lock(m_critical);
+ const TiXmlElement *pElement = settings->FirstChildElement("defaultvideosettings");
+ if (pElement != NULL)
+ {
+ int interlaceMethod;
+ XMLUtils::GetInt(pElement, "interlacemethod", interlaceMethod, VS_INTERLACEMETHOD_NONE, VS_INTERLACEMETHOD_MAX);
+
+ m_defaultVideoSettings.m_InterlaceMethod = (EINTERLACEMETHOD)interlaceMethod;
+ int scalingMethod;
+ if (!XMLUtils::GetInt(pElement, "scalingmethod", scalingMethod, VS_SCALINGMETHOD_NEAREST, VS_SCALINGMETHOD_MAX))
+ scalingMethod = (int)VS_SCALINGMETHOD_LINEAR;
+ m_defaultVideoSettings.m_ScalingMethod = (ESCALINGMETHOD)scalingMethod;
+
+ XMLUtils::GetInt(pElement, "viewmode", m_defaultVideoSettings.m_ViewMode, ViewModeNormal, ViewModeZoom110Width);
+ if (!XMLUtils::GetFloat(pElement, "zoomamount", m_defaultVideoSettings.m_CustomZoomAmount, 0.5f, 2.0f))
+ m_defaultVideoSettings.m_CustomZoomAmount = 1.0f;
+ if (!XMLUtils::GetFloat(pElement, "pixelratio", m_defaultVideoSettings.m_CustomPixelRatio, 0.5f, 2.0f))
+ m_defaultVideoSettings.m_CustomPixelRatio = 1.0f;
+ if (!XMLUtils::GetFloat(pElement, "verticalshift", m_defaultVideoSettings.m_CustomVerticalShift, -2.0f, 2.0f))
+ m_defaultVideoSettings.m_CustomVerticalShift = 0.0f;
+ if (!XMLUtils::GetFloat(pElement, "volumeamplification", m_defaultVideoSettings.m_VolumeAmplification, VOLUME_DRC_MINIMUM * 0.01f, VOLUME_DRC_MAXIMUM * 0.01f))
+ m_defaultVideoSettings.m_VolumeAmplification = VOLUME_DRC_MINIMUM * 0.01f;
+ if (!XMLUtils::GetFloat(pElement, "noisereduction", m_defaultVideoSettings.m_NoiseReduction, 0.0f, 1.0f))
+ m_defaultVideoSettings.m_NoiseReduction = 0.0f;
+ XMLUtils::GetBoolean(pElement, "postprocess", m_defaultVideoSettings.m_PostProcess);
+ if (!XMLUtils::GetFloat(pElement, "sharpness", m_defaultVideoSettings.m_Sharpness, -1.0f, 1.0f))
+ m_defaultVideoSettings.m_Sharpness = 0.0f;
+ XMLUtils::GetBoolean(pElement, "showsubtitles", m_defaultVideoSettings.m_SubtitleOn);
+ if (!XMLUtils::GetFloat(pElement, "brightness", m_defaultVideoSettings.m_Brightness, 0, 100))
+ m_defaultVideoSettings.m_Brightness = 50;
+ if (!XMLUtils::GetFloat(pElement, "contrast", m_defaultVideoSettings.m_Contrast, 0, 100))
+ m_defaultVideoSettings.m_Contrast = 50;
+ if (!XMLUtils::GetFloat(pElement, "gamma", m_defaultVideoSettings.m_Gamma, 0, 100))
+ m_defaultVideoSettings.m_Gamma = 20;
+ if (!XMLUtils::GetFloat(pElement, "audiodelay", m_defaultVideoSettings.m_AudioDelay, -10.0f, 10.0f))
+ m_defaultVideoSettings.m_AudioDelay = 0.0f;
+ if (!XMLUtils::GetFloat(pElement, "subtitledelay", m_defaultVideoSettings.m_SubtitleDelay, -10.0f, 10.0f))
+ m_defaultVideoSettings.m_SubtitleDelay = 0.0f;
+ XMLUtils::GetBoolean(pElement, "nonlinstretch", m_defaultVideoSettings.m_CustomNonLinStretch);
+ if (!XMLUtils::GetInt(pElement, "stereomode", m_defaultVideoSettings.m_StereoMode))
+ m_defaultVideoSettings.m_StereoMode = 0;
+ if (!XMLUtils::GetInt(pElement, "centermixlevel", m_defaultVideoSettings.m_CenterMixLevel))
+ m_defaultVideoSettings.m_CenterMixLevel = 0;
+
+ int toneMapMethod;
+ if (!XMLUtils::GetInt(pElement, "tonemapmethod", toneMapMethod, VS_TONEMAPMETHOD_OFF,
+ VS_TONEMAPMETHOD_MAX))
+ toneMapMethod = VS_TONEMAPMETHOD_REINHARD;
+ m_defaultVideoSettings.m_ToneMapMethod = static_cast<ETONEMAPMETHOD>(toneMapMethod);
+
+ if (!XMLUtils::GetFloat(pElement, "tonemapparam", m_defaultVideoSettings.m_ToneMapParam, 0.1f, 5.0f))
+ m_defaultVideoSettings.m_ToneMapParam = 1.0f;
+ }
+
+ m_defaultGameSettings.Reset();
+ pElement = settings->FirstChildElement("defaultgamesettings");
+ if (pElement != nullptr)
+ {
+ std::string videoFilter;
+ if (XMLUtils::GetString(pElement, "videofilter", videoFilter))
+ m_defaultGameSettings.SetVideoFilter(videoFilter);
+
+ std::string stretchMode;
+ if (XMLUtils::GetString(pElement, "stretchmode", stretchMode))
+ {
+ RETRO::STRETCHMODE sm = RETRO::CRetroPlayerUtils::IdentifierToStretchMode(stretchMode);
+ m_defaultGameSettings.SetStretchMode(sm);
+ }
+
+ int rotation;
+ if (XMLUtils::GetInt(pElement, "rotation", rotation, 0, 270) && rotation >= 0)
+ m_defaultGameSettings.SetRotationDegCCW(static_cast<unsigned int>(rotation));
+ }
+
+ // mymusic settings
+ pElement = settings->FirstChildElement("mymusic");
+ if (pElement != NULL)
+ {
+ const TiXmlElement *pChild = pElement->FirstChildElement("playlist");
+ if (pChild != NULL)
+ {
+ XMLUtils::GetBoolean(pChild, "repeat", m_musicPlaylistRepeat);
+ XMLUtils::GetBoolean(pChild, "shuffle", m_musicPlaylistShuffle);
+ }
+ if (!XMLUtils::GetInt(pElement, "needsupdate", m_musicNeedsUpdate, 0, INT_MAX))
+ m_musicNeedsUpdate = 0;
+ }
+
+ // Set music playlist player repeat and shuffle from loaded settings
+ if (m_musicPlaylistRepeat)
+ CServiceBroker::GetPlaylistPlayer().SetRepeat(PLAYLIST::TYPE_MUSIC, PLAYLIST::RepeatState::ALL);
+ else
+ CServiceBroker::GetPlaylistPlayer().SetRepeat(PLAYLIST::TYPE_MUSIC,
+ PLAYLIST::RepeatState::NONE);
+ CServiceBroker::GetPlaylistPlayer().SetShuffle(PLAYLIST::TYPE_MUSIC, m_musicPlaylistShuffle);
+
+ // Read the watchmode settings for the various media views
+ pElement = settings->FirstChildElement("myvideos");
+ if (pElement != NULL)
+ {
+ int tmp;
+ if (XMLUtils::GetInt(pElement, "watchmodemovies", tmp, (int)WatchedModeAll, (int)WatchedModeWatched))
+ m_watchedModes["movies"] = (WatchedMode)tmp;
+ if (XMLUtils::GetInt(pElement, "watchmodetvshows", tmp, (int)WatchedModeAll, (int)WatchedModeWatched))
+ m_watchedModes["tvshows"] = (WatchedMode)tmp;
+ if (XMLUtils::GetInt(pElement, "watchmodemusicvideos", tmp, (int)WatchedModeAll, (int)WatchedModeWatched))
+ m_watchedModes["musicvideos"] = (WatchedMode)tmp;
+ if (XMLUtils::GetInt(pElement, "watchmoderecordings", tmp, static_cast<int>(WatchedModeAll), static_cast<int>(WatchedModeWatched)))
+ m_watchedModes["recordings"] = static_cast<WatchedMode>(tmp);
+
+ const TiXmlElement *pChild = pElement->FirstChildElement("playlist");
+ if (pChild != NULL)
+ {
+ XMLUtils::GetBoolean(pChild, "repeat", m_videoPlaylistRepeat);
+ XMLUtils::GetBoolean(pChild, "shuffle", m_videoPlaylistShuffle);
+ }
+ if (!XMLUtils::GetInt(pElement, "needsupdate", m_videoNeedsUpdate, 0, INT_MAX))
+ m_videoNeedsUpdate = 0;
+ }
+
+ // Set video playlist player repeat and shuffle from loaded settings
+ if (m_videoPlaylistRepeat)
+ CServiceBroker::GetPlaylistPlayer().SetRepeat(PLAYLIST::TYPE_VIDEO, PLAYLIST::RepeatState::ALL);
+ else
+ CServiceBroker::GetPlaylistPlayer().SetRepeat(PLAYLIST::TYPE_VIDEO,
+ PLAYLIST::RepeatState::NONE);
+ CServiceBroker::GetPlaylistPlayer().SetShuffle(PLAYLIST::TYPE_VIDEO, m_videoPlaylistShuffle);
+
+ return true;
+}
+
+bool CMediaSettings::Save(TiXmlNode *settings) const
+{
+ if (settings == NULL)
+ return false;
+
+ std::unique_lock<CCriticalSection> lock(m_critical);
+ // default video settings
+ TiXmlElement videoSettingsNode("defaultvideosettings");
+ TiXmlNode *pNode = settings->InsertEndChild(videoSettingsNode);
+ if (pNode == NULL)
+ return false;
+
+ XMLUtils::SetInt(pNode, "interlacemethod", m_defaultVideoSettings.m_InterlaceMethod);
+ XMLUtils::SetInt(pNode, "scalingmethod", m_defaultVideoSettings.m_ScalingMethod);
+ XMLUtils::SetFloat(pNode, "noisereduction", m_defaultVideoSettings.m_NoiseReduction);
+ XMLUtils::SetBoolean(pNode, "postprocess", m_defaultVideoSettings.m_PostProcess);
+ XMLUtils::SetFloat(pNode, "sharpness", m_defaultVideoSettings.m_Sharpness);
+ XMLUtils::SetInt(pNode, "viewmode", m_defaultVideoSettings.m_ViewMode);
+ XMLUtils::SetFloat(pNode, "zoomamount", m_defaultVideoSettings.m_CustomZoomAmount);
+ XMLUtils::SetFloat(pNode, "pixelratio", m_defaultVideoSettings.m_CustomPixelRatio);
+ XMLUtils::SetFloat(pNode, "verticalshift", m_defaultVideoSettings.m_CustomVerticalShift);
+ XMLUtils::SetFloat(pNode, "volumeamplification", m_defaultVideoSettings.m_VolumeAmplification);
+ XMLUtils::SetBoolean(pNode, "showsubtitles", m_defaultVideoSettings.m_SubtitleOn);
+ XMLUtils::SetFloat(pNode, "brightness", m_defaultVideoSettings.m_Brightness);
+ XMLUtils::SetFloat(pNode, "contrast", m_defaultVideoSettings.m_Contrast);
+ XMLUtils::SetFloat(pNode, "gamma", m_defaultVideoSettings.m_Gamma);
+ XMLUtils::SetFloat(pNode, "audiodelay", m_defaultVideoSettings.m_AudioDelay);
+ XMLUtils::SetFloat(pNode, "subtitledelay", m_defaultVideoSettings.m_SubtitleDelay);
+ XMLUtils::SetBoolean(pNode, "nonlinstretch", m_defaultVideoSettings.m_CustomNonLinStretch);
+ XMLUtils::SetInt(pNode, "stereomode", m_defaultVideoSettings.m_StereoMode);
+ XMLUtils::SetInt(pNode, "centermixlevel", m_defaultVideoSettings.m_CenterMixLevel);
+ XMLUtils::SetInt(pNode, "tonemapmethod", m_defaultVideoSettings.m_ToneMapMethod);
+ XMLUtils::SetFloat(pNode, "tonemapparam", m_defaultVideoSettings.m_ToneMapParam);
+
+ // default audio settings for dsp addons
+ TiXmlElement audioSettingsNode("defaultaudiosettings");
+ pNode = settings->InsertEndChild(audioSettingsNode);
+ if (pNode == NULL)
+ return false;
+
+ // Default game settings
+ TiXmlElement gameSettingsNode("defaultgamesettings");
+ pNode = settings->InsertEndChild(gameSettingsNode);
+ if (pNode == nullptr)
+ return false;
+
+ XMLUtils::SetString(pNode, "videofilter", m_defaultGameSettings.VideoFilter());
+ std::string sm = RETRO::CRetroPlayerUtils::StretchModeToIdentifier(m_defaultGameSettings.StretchMode());
+ XMLUtils::SetString(pNode, "stretchmode", sm);
+ XMLUtils::SetInt(pNode, "rotation", m_defaultGameSettings.RotationDegCCW());
+
+ // mymusic
+ pNode = settings->FirstChild("mymusic");
+ if (pNode == NULL)
+ {
+ TiXmlElement videosNode("mymusic");
+ pNode = settings->InsertEndChild(videosNode);
+ if (pNode == NULL)
+ return false;
+ }
+
+ TiXmlElement musicPlaylistNode("playlist");
+ TiXmlNode *playlistNode = pNode->InsertEndChild(musicPlaylistNode);
+ if (playlistNode == NULL)
+ return false;
+ XMLUtils::SetBoolean(playlistNode, "repeat", m_musicPlaylistRepeat);
+ XMLUtils::SetBoolean(playlistNode, "shuffle", m_musicPlaylistShuffle);
+
+ XMLUtils::SetInt(pNode, "needsupdate", m_musicNeedsUpdate);
+
+ // myvideos
+ pNode = settings->FirstChild("myvideos");
+ if (pNode == NULL)
+ {
+ TiXmlElement videosNode("myvideos");
+ pNode = settings->InsertEndChild(videosNode);
+ if (pNode == NULL)
+ return false;
+ }
+
+ XMLUtils::SetInt(pNode, "watchmodemovies", m_watchedModes.find("movies")->second);
+ XMLUtils::SetInt(pNode, "watchmodetvshows", m_watchedModes.find("tvshows")->second);
+ XMLUtils::SetInt(pNode, "watchmodemusicvideos", m_watchedModes.find("musicvideos")->second);
+ XMLUtils::SetInt(pNode, "watchmoderecordings", m_watchedModes.find("recordings")->second);
+
+ TiXmlElement videoPlaylistNode("playlist");
+ playlistNode = pNode->InsertEndChild(videoPlaylistNode);
+ if (playlistNode == NULL)
+ return false;
+ XMLUtils::SetBoolean(playlistNode, "repeat", m_videoPlaylistRepeat);
+ XMLUtils::SetBoolean(playlistNode, "shuffle", m_videoPlaylistShuffle);
+
+ XMLUtils::SetInt(pNode, "needsupdate", m_videoNeedsUpdate);
+
+ return true;
+}
+
+void CMediaSettings::OnSettingAction(const std::shared_ptr<const CSetting>& setting)
+{
+ if (setting == NULL)
+ return;
+
+ const std::string &settingId = setting->GetId();
+ if (settingId == CSettings::SETTING_MUSICLIBRARY_CLEANUP)
+ {
+ if (HELPERS::ShowYesNoDialogText(CVariant{313}, CVariant{333}) == DialogResponse::CHOICE_YES)
+ {
+ if (CMusicLibraryQueue::GetInstance().IsRunning())
+ HELPERS::ShowOKDialogText(CVariant{700}, CVariant{703});
+ else
+ CMusicLibraryQueue::GetInstance().CleanLibrary(true);
+ }
+ }
+ else if (settingId == CSettings::SETTING_MUSICLIBRARY_EXPORT)
+ {
+ CLibExportSettings m_musicExportSettings;
+ if (CGUIDialogLibExportSettings::Show(m_musicExportSettings))
+ {
+ // Export music library showing progress dialog
+ CMusicLibraryQueue::GetInstance().ExportLibrary(m_musicExportSettings, true);
+ }
+ }
+ else if (settingId == CSettings::SETTING_MUSICLIBRARY_IMPORT)
+ {
+ std::string path;
+ VECSOURCES shares;
+ CServiceBroker::GetMediaManager().GetLocalDrives(shares);
+ CServiceBroker::GetMediaManager().GetNetworkLocations(shares);
+ CServiceBroker::GetMediaManager().GetRemovableDrives(shares);
+
+ if (CGUIDialogFileBrowser::ShowAndGetFile(shares, "musicdb.xml", g_localizeStrings.Get(651) , path))
+ {
+ // Import data to music library showing progress dialog
+ CMusicLibraryQueue::GetInstance().ImportLibrary(path, true);
+ }
+ }
+ else if (settingId == CSettings::SETTING_VIDEOLIBRARY_CLEANUP)
+ {
+ if (HELPERS::ShowYesNoDialogText(CVariant{313}, CVariant{333}) == DialogResponse::CHOICE_YES)
+ {
+ if (!CVideoLibraryQueue::GetInstance().CleanLibraryModal())
+ HELPERS::ShowOKDialogText(CVariant{700}, CVariant{703});
+ }
+ }
+ else if (settingId == CSettings::SETTING_VIDEOLIBRARY_EXPORT)
+ CBuiltins::GetInstance().Execute("exportlibrary(video)");
+ else if (settingId == CSettings::SETTING_VIDEOLIBRARY_IMPORT)
+ {
+ std::string path;
+ VECSOURCES shares;
+ CServiceBroker::GetMediaManager().GetLocalDrives(shares);
+ CServiceBroker::GetMediaManager().GetNetworkLocations(shares);
+ CServiceBroker::GetMediaManager().GetRemovableDrives(shares);
+
+ if (CGUIDialogFileBrowser::ShowAndGetDirectory(shares, g_localizeStrings.Get(651) , path))
+ {
+ CVideoDatabase videodatabase;
+ videodatabase.Open();
+ videodatabase.ImportFromXML(path);
+ videodatabase.Close();
+ }
+ }
+}
+
+void CMediaSettings::OnSettingChanged(const std::shared_ptr<const CSetting>& setting)
+{
+ if (setting == nullptr)
+ return;
+
+ if (setting->GetId() == CSettings::SETTING_VIDEOLIBRARY_SHOWUNWATCHEDPLOTS)
+ CServiceBroker::GetAnnouncementManager()->Announce(ANNOUNCEMENT::VideoLibrary, "OnRefresh");
+}
+
+int CMediaSettings::GetWatchedMode(const std::string &content) const
+{
+ std::unique_lock<CCriticalSection> lock(m_critical);
+ WatchedModes::const_iterator it = m_watchedModes.find(GetWatchedContent(content));
+ if (it != m_watchedModes.end())
+ return it->second;
+
+ return WatchedModeAll;
+}
+
+void CMediaSettings::SetWatchedMode(const std::string &content, WatchedMode mode)
+{
+ std::unique_lock<CCriticalSection> lock(m_critical);
+ WatchedModes::iterator it = m_watchedModes.find(GetWatchedContent(content));
+ if (it != m_watchedModes.end())
+ it->second = mode;
+}
+
+void CMediaSettings::CycleWatchedMode(const std::string &content)
+{
+ std::unique_lock<CCriticalSection> lock(m_critical);
+ WatchedModes::iterator it = m_watchedModes.find(GetWatchedContent(content));
+ if (it != m_watchedModes.end())
+ {
+ it->second = (WatchedMode)((int)it->second + 1);
+ if (it->second > WatchedModeWatched)
+ it->second = WatchedModeAll;
+ }
+}
+
+std::string CMediaSettings::GetWatchedContent(const std::string &content)
+{
+ if (content == "seasons" || content == "episodes")
+ return "tvshows";
+
+ return content;
+}