Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

1465 lines (1304 sloc) 58.301 kB
/*
* Copyright (C) 2005-2008 Team XBMC
* http://www.xbmc.org
*
* This Program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This Program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with XBMC; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
#include "GUISettings.h"
#include <limits.h>
#include <float.h>
#include "Settings.h"
#include "dialogs/GUIDialogFileBrowser.h"
#include "storage/MediaManager.h"
#ifdef _LINUX
#include "LinuxTimezone.h"
#endif
#include "Application.h"
#include "AdvancedSettings.h"
#include "guilib/LocalizeStrings.h"
#include "utils/StringUtils.h"
#include "utils/SystemInfo.h"
#include "utils/log.h"
#include "utils/XBMCTinyXML.h"
#include "windowing/WindowingFactory.h"
#include "powermanagement/PowerManager.h"
#include "cores/dvdplayer/DVDCodecs/Video/CrystalHD.h"
#include "cores/AudioEngine/AEFactory.h"
#include "cores/AudioEngine/AEAudioFormat.h"
#include "guilib/GUIFont.h" // for FONT_STYLE_* definitions
#if defined(TARGET_DARWIN_OSX)
#include "cores/AudioEngine/Engines/CoreAudio/CoreAudioHardware.h"
#endif
#include "guilib/GUIFontManager.h"
#include "utils/Weather.h"
#include "LangInfo.h"
#include "utils/XMLUtils.h"
#if defined(TARGET_DARWIN)
#include "osx/DarwinUtils.h"
#endif
#include "Util.h"
using namespace std;
using namespace ADDON;
// String id's of the masks
#define MASK_MINS 14044
#define MASK_SECS 14045
#define MASK_MS 14046
#define MASK_PERCENT 14047
#define MASK_KBPS 14048
#define MASK_KB 14049
#define MASK_DB 14050
#define MAX_RESOLUTIONS 128
#define TEXT_OFF 351
#define TEXT_NONE 231
#ifdef _LINUX
#define DEFAULT_VISUALISATION "visualization.glspectrum"
#elif defined(_WIN32)
#ifdef HAS_DX
#define DEFAULT_VISUALISATION "visualization.milkdrop"
#else
#define DEFAULT_VISUALISATION "visualization.glspectrum"
#endif
#endif
struct sortsettings
{
bool operator()(const CSetting* pSetting1, const CSetting* pSetting2)
{
return pSetting1->GetOrder() < pSetting2->GetOrder();
}
};
void CSettingBool::FromString(const CStdString &strValue)
{
m_bData = (strValue == "true");
}
CStdString CSettingBool::ToString() const
{
return m_bData ? "true" : "false";
}
CSettingSeparator::CSettingSeparator(int iOrder, const char *strSetting)
: CSetting(iOrder, strSetting, 0, SEPARATOR_CONTROL)
{
}
CSettingFloat::CSettingFloat(int iOrder, const char *strSetting, int iLabel, float fData, float fMin, float fStep, float fMax, int iControlType)
: CSetting(iOrder, strSetting, iLabel, iControlType)
{
m_fData = fData;
m_fMin = fMin;
m_fStep = fStep;
m_fMax = fMax;
}
void CSettingFloat::FromString(const CStdString &strValue)
{
SetData((float)atof(strValue.c_str()));
}
CStdString CSettingFloat::ToString() const
{
CStdString strValue;
strValue.Format("%f", m_fData);
return strValue;
}
CSettingInt::CSettingInt(int iOrder, const char *strSetting, int iLabel, int iData, int iMin, int iStep, int iMax, int iControlType, const char *strFormat)
: CSetting(iOrder, strSetting, iLabel, iControlType)
{
m_iData = iData;
m_iMin = iMin;
m_iMax = iMax;
m_iStep = iStep;
m_iFormat = -1;
m_iLabelMin = -1;
if (strFormat)
m_strFormat = strFormat;
else
m_strFormat = "%i";
}
CSettingInt::CSettingInt(int iOrder, const char *strSetting, int iLabel, int iData, int iMin, int iStep, int iMax, int iControlType, int iFormat, int iLabelMin)
: CSetting(iOrder, strSetting, iLabel, iControlType)
{
m_iData = iData;
m_iMin = iMin;
m_iMax = iMax;
m_iStep = iStep;
m_iLabelMin = iLabelMin;
m_iFormat = iFormat;
if (m_iFormat < 0)
m_strFormat = "%i";
}
CSettingInt::CSettingInt(int iOrder, const char *strSetting, int iLabel,
int iData, const map<int,int>& entries, int iControlType)
: CSetting(iOrder, strSetting, iLabel, iControlType),
m_entries(entries)
{
m_iData = iData;
m_iMin = -1;
m_iMax = -1;
m_iStep = 1;
m_iLabelMin = -1;
}
void CSettingInt::FromString(const CStdString &strValue)
{
int id = atoi(strValue.c_str());
SetData(id);
}
CStdString CSettingInt::ToString() const
{
CStdString strValue;
strValue.Format("%i", m_iData);
return strValue;
}
void CSettingHex::FromString(const CStdString &strValue)
{
int iHexValue;
if (sscanf(strValue, "%x", (unsigned int *)&iHexValue))
SetData(iHexValue);
}
CStdString CSettingHex::ToString() const
{
CStdString strValue;
strValue.Format("%x", m_iData);
return strValue;
}
CSettingString::CSettingString(int iOrder, const char *strSetting, int iLabel, const char *strData, int iControlType, bool bAllowEmpty, int iHeadingString)
: CSetting(iOrder, strSetting, iLabel, iControlType)
{
m_strData = strData;
m_bAllowEmpty = bAllowEmpty;
m_iHeadingString = iHeadingString;
}
void CSettingString::FromString(const CStdString &strValue)
{
m_strData = strValue;
}
CStdString CSettingString::ToString() const
{
return m_strData;
}
CSettingPath::CSettingPath(int iOrder, const char *strSetting, int iLabel, const char *strData, int iControlType, bool bAllowEmpty, int iHeadingString)
: CSettingString(iOrder, strSetting, iLabel, strData, iControlType, bAllowEmpty, iHeadingString)
{
}
CSettingAddon::CSettingAddon(int iOrder, const char *strSetting, int iLabel, const char *strData, const TYPE type)
: CSettingString(iOrder, strSetting, iLabel, strData, BUTTON_CONTROL_STANDARD, false, -1)
, m_type(type)
{
}
void CSettingsGroup::GetCategories(vecSettingsCategory &vecCategories)
{
vecCategories.clear();
for (unsigned int i = 0; i < m_vecCategories.size(); i++)
{
vecSettings settings;
// check whether we actually have these settings available.
g_guiSettings.GetSettingsGroup(m_vecCategories[i], settings);
if (settings.size())
vecCategories.push_back(m_vecCategories[i]);
}
}
// Settings are case sensitive
CGUISettings::CGUISettings(void)
{
}
void CGUISettings::Initialize()
{
ZeroMemory(&m_replayGain, sizeof(ReplayGainSettings));
// Pictures settings
AddGroup(0, 1);
CSettingsCategory* pic = AddCategory(0, "pictures", 14081);
AddBool(pic, "pictures.usetags", 14082, true);
AddBool(pic,"pictures.generatethumbs",13360,true);
AddBool(pic, "pictures.useexifrotation", 20184, true);
AddBool(pic, "pictures.showvideos", 22022, true);
// FIXME: hide this setting until it is properly respected. In the meanwhile, default to AUTO.
AddInt(NULL, "pictures.displayresolution", 169, (int)RES_AUTORES, (int)RES_AUTORES, 1, (int)RES_AUTORES, SPIN_CONTROL_TEXT);
CSettingsCategory* cat = AddCategory(0, "slideshow", 108);
AddInt(cat, "slideshow.staytime", 12378, 5, 1, 1, 100, SPIN_CONTROL_INT_PLUS, MASK_SECS);
AddBool(cat, "slideshow.displayeffects", 12379, true);
AddBool(NULL, "slideshow.shuffle", 13319, false);
// Programs settings
// AddGroup(1, 0);
// My Weather settings
AddGroup(2, 8);
CSettingsCategory* wea = AddCategory(2, "weather", 16000);
AddInt(NULL, "weather.currentlocation", 0, 1, 1, 1, 3, SPIN_CONTROL_INT_PLUS);
AddDefaultAddon(wea, "weather.addon", 24027, "weather.wunderground", ADDON_SCRIPT_WEATHER);
AddString(wea, "weather.addonsettings", 21417, "", BUTTON_CONTROL_STANDARD, true);
// My Music Settings
AddGroup(3, 2);
CSettingsCategory* ml = AddCategory(3,"musiclibrary",14022);
AddBool(NULL, "musiclibrary.enabled", 418, true);
AddBool(ml, "musiclibrary.showcompilationartists", 13414, true);
AddSeparator(ml,"musiclibrary.sep1");
AddBool(ml,"musiclibrary.downloadinfo", 20192, false);
AddDefaultAddon(ml, "musiclibrary.albumsscraper", 20193, "metadata.album.universal", ADDON_SCRAPER_ALBUMS);
AddDefaultAddon(ml, "musiclibrary.artistsscraper", 20194, "metadata.artists.universal", ADDON_SCRAPER_ARTISTS);
AddBool(ml, "musiclibrary.updateonstartup", 22000, false);
AddBool(ml, "musiclibrary.backgroundupdate", 22001, false);
AddSeparator(ml,"musiclibrary.sep2");
AddString(ml, "musiclibrary.cleanup", 334, "", BUTTON_CONTROL_STANDARD);
AddString(ml, "musiclibrary.export", 20196, "", BUTTON_CONTROL_STANDARD);
AddString(ml, "musiclibrary.import", 20197, "", BUTTON_CONTROL_STANDARD);
CSettingsCategory* mp = AddCategory(3, "musicplayer", 14086);
AddBool(mp, "musicplayer.autoplaynextitem", 489, true);
AddBool(mp, "musicplayer.queuebydefault", 14084, false);
AddSeparator(mp, "musicplayer.sep1");
map<int,int> gain;
gain.insert(make_pair(351,REPLAY_GAIN_NONE));
gain.insert(make_pair(639,REPLAY_GAIN_TRACK));
gain.insert(make_pair(640,REPLAY_GAIN_ALBUM));
AddInt(mp, "musicplayer.replaygaintype", 638, REPLAY_GAIN_ALBUM, gain, SPIN_CONTROL_TEXT);
AddInt(mp, "musicplayer.replaygainpreamp", 641, 89, 77, 1, 101, SPIN_CONTROL_INT_PLUS, MASK_DB);
AddInt(mp, "musicplayer.replaygainnogainpreamp", 642, 89, 77, 1, 101, SPIN_CONTROL_INT_PLUS, MASK_DB);
AddBool(mp, "musicplayer.replaygainavoidclipping", 643, false);
AddSeparator(mp, "musicplayer.sep2");
AddInt(mp, "musicplayer.crossfade", 13314, 0, 0, 1, 15, SPIN_CONTROL_INT_PLUS, MASK_SECS, TEXT_OFF);
AddBool(mp, "musicplayer.crossfadealbumtracks", 13400, true);
AddSeparator(mp, "musicplayer.sep3");
AddDefaultAddon(mp, "musicplayer.visualisation", 250, DEFAULT_VISUALISATION, ADDON_VIZ);
CSettingsCategory* mf = AddCategory(3, "musicfiles", 14081);
AddBool(mf, "musicfiles.usetags", 258, true);
AddString(mf, "musicfiles.trackformat", 13307, "[%N. ]%A - %T", EDIT_CONTROL_INPUT, false, 16016);
AddString(mf, "musicfiles.trackformatright", 13387, "%D", EDIT_CONTROL_INPUT, false, 16016);
// advanced per-view trackformats.
AddString(NULL, "musicfiles.nowplayingtrackformat", 13307, "", EDIT_CONTROL_INPUT, false, 16016);
AddString(NULL, "musicfiles.nowplayingtrackformatright", 13387, "", EDIT_CONTROL_INPUT, false, 16016);
AddString(NULL, "musicfiles.librarytrackformat", 13307, "", EDIT_CONTROL_INPUT, false, 16016);
AddString(NULL, "musicfiles.librarytrackformatright", 13387, "", EDIT_CONTROL_INPUT, false, 16016);
AddBool(mf, "musicfiles.findremotethumbs", 14059, true);
CSettingsCategory* scr = AddCategory(3, "scrobbler", 15221);
AddBool(scr, "scrobbler.lastfmsubmit", 15201, false);
AddBool(scr, "scrobbler.lastfmsubmitradio", 15250, false);
AddString(scr,"scrobbler.lastfmusername", 15202, "", EDIT_CONTROL_INPUT, false, 15202);
AddString(scr,"scrobbler.lastfmpass", 15203, "", EDIT_CONTROL_MD5_INPUT, false, 15203);
AddSeparator(scr, "scrobbler.sep1");
AddBool(scr, "scrobbler.librefmsubmit", 15217, false);
AddString(scr, "scrobbler.librefmusername", 15218, "", EDIT_CONTROL_INPUT, false, 15218);
AddString(scr, "scrobbler.librefmpass", 15219, "", EDIT_CONTROL_MD5_INPUT, false, 15219);
CSettingsCategory* acd = AddCategory(3, "audiocds", 620);
map<int,int> autocd;
autocd.insert(make_pair(16018, AUTOCD_NONE));
autocd.insert(make_pair(14098, AUTOCD_PLAY));
#ifdef HAS_CDDA_RIPPER
autocd.insert(make_pair(14096, AUTOCD_RIP));
#endif
AddInt(acd,"audiocds.autoaction",14097,AUTOCD_NONE, autocd, SPIN_CONTROL_TEXT);
AddBool(acd, "audiocds.usecddb", 227, true);
AddSeparator(acd, "audiocds.sep1");
AddPath(acd,"audiocds.recordingpath",20000,"select writable folder",BUTTON_CONTROL_PATH_INPUT,false,657);
AddString(acd, "audiocds.trackpathformat", 13307, "%A - %B/[%N. ][%A - ]%T", EDIT_CONTROL_INPUT, false, 16016);
map<int,int> encoders;
#ifdef HAVE_LIBMP3LAME
encoders.insert(make_pair(34000,CDDARIP_ENCODER_LAME));
#endif
#ifdef HAVE_LIBVORBISENC
encoders.insert(make_pair(34001,CDDARIP_ENCODER_VORBIS));
#endif
encoders.insert(make_pair(34002,CDDARIP_ENCODER_WAV));
encoders.insert(make_pair(34005,CDDARIP_ENCODER_FLAC));
AddInt(acd, "audiocds.encoder", 621, CDDARIP_ENCODER_FLAC, encoders, SPIN_CONTROL_TEXT);
map<int,int> qualities;
qualities.insert(make_pair(604,CDDARIP_QUALITY_CBR));
qualities.insert(make_pair(601,CDDARIP_QUALITY_MEDIUM));
qualities.insert(make_pair(602,CDDARIP_QUALITY_STANDARD));
qualities.insert(make_pair(603,CDDARIP_QUALITY_EXTREME));
AddInt(acd, "audiocds.quality", 622, CDDARIP_QUALITY_CBR, qualities, SPIN_CONTROL_TEXT);
AddInt(acd, "audiocds.bitrate", 623, 192, 128, 32, 320, SPIN_CONTROL_INT_PLUS, MASK_KBPS);
AddInt(acd, "audiocds.compressionlevel", 665, 5, 0, 1, 8, SPIN_CONTROL_INT_PLUS);
AddBool(acd, "audiocds.ejectonrip", 14099, true);
#ifdef HAS_KARAOKE
CSettingsCategory* kar = AddCategory(3, "karaoke", 13327);
AddBool(kar, "karaoke.enabled", 13323, false);
// auto-popup the song selector dialog when the karaoke song was just finished and playlist is empty.
AddBool(kar, "karaoke.autopopupselector", 22037, false);
AddSeparator(kar, "karaoke.sep1");
AddString(kar, "karaoke.font", 22030, "arial.ttf", SPIN_CONTROL_TEXT);
AddInt(kar, "karaoke.fontheight", 22031, 36, 16, 2, 74, SPIN_CONTROL_TEXT); // use text as there is a disk based lookup needed
map<int,int> colors;
for (int i = KARAOKE_COLOR_START; i <= KARAOKE_COLOR_END; i++)
colors.insert(make_pair(22040 + i, i));
AddInt(kar, "karaoke.fontcolors", 22032, KARAOKE_COLOR_START, colors, SPIN_CONTROL_TEXT);
AddString(kar, "karaoke.charset", 22033, "DEFAULT", SPIN_CONTROL_TEXT);
AddSeparator(kar,"karaoke.sep2");
AddString(kar, "karaoke.export", 22038, "", BUTTON_CONTROL_STANDARD);
AddString(kar, "karaoke.importcsv", 22036, "", BUTTON_CONTROL_STANDARD);
#endif
// System settings
AddGroup(4, 13000);
CSettingsCategory* vs = AddCategory(4, "videoscreen", 21373);
// this setting would ideally not be saved, as its value is systematically derived from videoscreen.screenmode.
// contains a DISPLAYMODE
#if !defined(TARGET_DARWIN_IOS_ATV2)
AddInt(vs, "videoscreen.screen", 240, 0, -1, 1, 32, SPIN_CONTROL_TEXT);
#endif
// this setting would ideally not be saved, as its value is systematically derived from videoscreen.screenmode.
// contains an index to the g_settings.m_ResInfo array. the only meaningful fields are iScreen, iWidth, iHeight.
#if defined(TARGET_DARWIN)
#if !defined(TARGET_DARWIN_IOS_ATV2)
AddInt(vs, "videoscreen.resolution", 131, -1, 0, 1, INT_MAX, SPIN_CONTROL_TEXT);
#endif
#else
AddInt(vs, "videoscreen.resolution", 169, -1, 0, 1, INT_MAX, SPIN_CONTROL_TEXT);
#endif
AddString(g_application.IsStandAlone() ? vs : NULL, "videoscreen.screenmode", 243, "DESKTOP", SPIN_CONTROL_TEXT);
#if defined(_WIN32) || defined(TARGET_DARWIN)
// We prefer a fake fullscreen mode (window covering the screen rather than dedicated fullscreen)
// as it works nicer with switching to other applications. However on some systems vsync is broken
// when we do this (eg non-Aero on ATI in particular) and on others (AppleTV) we can't get XBMC to
// the front
bool fakeFullScreen = true;
bool showSetting = true;
if (g_sysinfo.IsAeroDisabled())
fakeFullScreen = false;
#if defined(_WIN32) && defined(HAS_GL)
fakeFullScreen = true;
showSetting = false;
#endif
#if defined(TARGET_DARWIN)
showSetting = false;
#endif
AddBool(showSetting ? vs : NULL, "videoscreen.fakefullscreen", 14083, fakeFullScreen);
#ifdef TARGET_DARWIN_IOS
AddBool(NULL, "videoscreen.blankdisplays", 13130, false);
#else
AddBool(vs, "videoscreen.blankdisplays", 13130, false);
#endif
AddSeparator(vs, "videoscreen.sep1");
#endif
map<int,int> vsync;
#if defined(_LINUX) && !defined(TARGET_DARWIN)
vsync.insert(make_pair(13101,VSYNC_DRIVER));
#endif
vsync.insert(make_pair(13106,VSYNC_DISABLED));
vsync.insert(make_pair(13107,VSYNC_VIDEO));
vsync.insert(make_pair(13108,VSYNC_ALWAYS));
AddInt(vs, "videoscreen.vsync", 13105, DEFAULT_VSYNC, vsync, SPIN_CONTROL_TEXT);
AddString(vs, "videoscreen.guicalibration",214,"", BUTTON_CONTROL_STANDARD);
#ifndef HAS_DX
// Todo: Implement test pattern for DX
AddString(vs, "videoscreen.testpattern",226,"", BUTTON_CONTROL_STANDARD);
#endif
#if defined(HAS_LCD)
AddBool(vs, "videoscreen.haslcd", 4501, false);
#endif
CSettingsCategory* ao = AddCategory(4, "audiooutput", 772);
map<int,int> audiomode;
audiomode.insert(make_pair(338,AUDIO_ANALOG));
audiomode.insert(make_pair(339,AUDIO_IEC958));
audiomode.insert(make_pair(420,AUDIO_HDMI ));
AddInt(ao, "audiooutput.mode", 337, AUDIO_ANALOG, audiomode, SPIN_CONTROL_TEXT);
map<int,int> channelLayout;
for(int layout = AE_CH_LAYOUT_2_0; layout < AE_CH_LAYOUT_MAX; ++layout)
channelLayout.insert(make_pair(34100+layout, layout));
AddInt(ao, "audiooutput.channellayout", 34100, AE_CH_LAYOUT_2_0, channelLayout, SPIN_CONTROL_TEXT);
AddBool(ao, "audiooutput.normalizelevels", 346, false);
AddBool(ao, "audiooutput.stereoupmix", 252, false);
#if defined(TARGET_DARWIN_IOS)
CSettingsCategory* aocat = g_sysinfo.IsAppleTV2() ? ao : NULL;
#else
CSettingsCategory* aocat = ao;
#endif
AddBool(aocat, "audiooutput.ac3passthrough" , 364, true);
AddBool(aocat, "audiooutput.dtspassthrough" , 254, true);
#if !defined(TARGET_DARWIN)
AddBool(aocat, "audiooutput.passthroughaac" , 299, false);
#endif
#if !defined(TARGET_DARWIN_IOS)
AddBool(aocat, "audiooutput.multichannellpcm" , 348, true );
#endif
#if !defined(TARGET_DARWIN)
AddBool(aocat, "audiooutput.truehdpassthrough", 349, true );
AddBool(aocat, "audiooutput.dtshdpassthrough" , 347, true );
#endif
#if defined(TARGET_DARWIN)
#if defined(TARGET_DARWIN_IOS)
CStdString defaultDeviceName = "Default";
#else
CStdString defaultDeviceName;
CCoreAudioHardware::GetOutputDeviceName(defaultDeviceName);
#endif
AddString(ao, "audiooutput.audiodevice", 545, defaultDeviceName.c_str(), SPIN_CONTROL_TEXT);
AddString(NULL, "audiooutput.passthroughdevice", 546, defaultDeviceName.c_str(), SPIN_CONTROL_TEXT);
#else
AddSeparator(ao, "audiooutput.sep1");
AddString (ao, "audiooutput.audiodevice" , 545, CStdString(CAEFactory::GetDefaultDevice(false)), SPIN_CONTROL_TEXT);
AddString (ao, "audiooutput.passthroughdevice", 546, CStdString(CAEFactory::GetDefaultDevice(true )), SPIN_CONTROL_TEXT);
AddSeparator(ao, "audiooutput.sep2");
#endif
map<int,int> guimode;
guimode.insert(make_pair(34121, AE_SOUND_IDLE ));
guimode.insert(make_pair(34122, AE_SOUND_ALWAYS));
guimode.insert(make_pair(34123, AE_SOUND_OFF ));
AddInt(ao, "audiooutput.guisoundmode", 34120, AE_SOUND_IDLE, guimode, SPIN_CONTROL_TEXT);
CSettingsCategory* in = AddCategory(4, "input", 14094);
AddString(in, "input.peripherals", 35000, "", BUTTON_CONTROL_STANDARD);
#if defined(TARGET_DARWIN)
map<int,int> remotemode;
remotemode.insert(make_pair(13610,APPLE_REMOTE_DISABLED));
remotemode.insert(make_pair(13611,APPLE_REMOTE_STANDARD));
remotemode.insert(make_pair(13612,APPLE_REMOTE_UNIVERSAL));
remotemode.insert(make_pair(13613,APPLE_REMOTE_MULTIREMOTE));
AddInt(in, "input.appleremotemode", 13600, APPLE_REMOTE_STANDARD, remotemode, SPIN_CONTROL_TEXT);
#if defined(TARGET_DARWIN_OSX)
AddBool(in, "input.appleremotealwayson", 13602, false);
#else
AddBool(NULL, "input.appleremotealwayson", 13602, false);
#endif
AddInt(NULL, "input.appleremotesequencetime", 13603, 500, 50, 50, 1000, SPIN_CONTROL_INT_PLUS, MASK_MS, TEXT_OFF);
AddSeparator(in, "input.sep1");
#endif
AddBool(in, "input.remoteaskeyboard", 21449, false);
#if defined(TARGET_DARWIN_IOS)
AddBool(NULL, "input.enablemouse", 21369, true);
#else
AddBool(in, "input.enablemouse", 21369, true);
#endif
#if defined(HAS_SDL_JOYSTICK)
AddBool(in, "input.enablejoystick", 35100, true);
#endif
CSettingsCategory* net = AddCategory(4, "network", 798);
if (g_application.IsStandAlone())
{
#if !defined(TARGET_DARWIN)
AddString(NULL, "network.interface",775,"", SPIN_CONTROL_TEXT);
map<int, int> networkAssignments;
networkAssignments.insert(make_pair(716, NETWORK_DHCP));
networkAssignments.insert(make_pair(717, NETWORK_STATIC));
networkAssignments.insert(make_pair(787, NETWORK_DISABLED));
AddInt(NULL, "network.assignment", 715, NETWORK_DHCP, networkAssignments, SPIN_CONTROL_TEXT);
AddString(NULL, "network.ipaddress", 719, "0.0.0.0", EDIT_CONTROL_IP_INPUT);
AddString(NULL, "network.subnet", 720, "255.255.255.0", EDIT_CONTROL_IP_INPUT);
AddString(NULL, "network.gateway", 721, "0.0.0.0", EDIT_CONTROL_IP_INPUT);
AddString(NULL, "network.dns", 722, "0.0.0.0", EDIT_CONTROL_IP_INPUT);
AddString(NULL, "network.dnssuffix", 22002, "", EDIT_CONTROL_INPUT, true);
AddString(NULL, "network.essid", 776, "0.0.0.0", BUTTON_CONTROL_STANDARD);
map<int, int> networkEncapsulations;
networkEncapsulations.insert(make_pair(780, ENC_NONE));
networkEncapsulations.insert(make_pair(781, ENC_WEP));
networkEncapsulations.insert(make_pair(782, ENC_WPA));
networkEncapsulations.insert(make_pair(783, ENC_WPA2));
AddInt(NULL, "network.enc", 778, ENC_NONE, networkEncapsulations, SPIN_CONTROL_TEXT);
AddString(NULL, "network.key", 777, "0.0.0.0", EDIT_CONTROL_INPUT);
#ifndef _WIN32
AddString(NULL, "network.save", 779, "", BUTTON_CONTROL_STANDARD);
#endif
AddSeparator(NULL, "network.sep1");
#endif
}
AddBool(net, "network.usehttpproxy", 708, false);
AddString(net, "network.httpproxyserver", 706, "", EDIT_CONTROL_INPUT);
AddString(net, "network.httpproxyport", 730, "8080", EDIT_CONTROL_NUMBER_INPUT, false, 707);
AddString(net, "network.httpproxyusername", 1048, "", EDIT_CONTROL_INPUT);
AddString(net, "network.httpproxypassword", 733, "", EDIT_CONTROL_HIDDEN_INPUT,true,733);
AddInt(net, "network.bandwidth", 14041, 0, 0, 512, 100*1024, SPIN_CONTROL_INT_PLUS, MASK_KBPS, TEXT_OFF);
CSettingsCategory* pwm = AddCategory(4, "powermanagement", 14095);
// Note: Application.cpp might hide powersaving settings if not supported.
AddInt(pwm, "powermanagement.displaysoff", 1450, 0, 0, 5, 120, SPIN_CONTROL_INT_PLUS, MASK_MINS, TEXT_OFF);
AddInt(pwm, "powermanagement.shutdowntime", 357, 0, 0, 5, 120, SPIN_CONTROL_INT_PLUS, MASK_MINS, TEXT_OFF);
map<int,int> shutdown;
if (g_powerManager.CanPowerdown())
shutdown.insert(make_pair(13005,POWERSTATE_SHUTDOWN));
if (g_powerManager.CanHibernate())
shutdown.insert(make_pair(13010,POWERSTATE_HIBERNATE));
if (g_powerManager.CanSuspend())
shutdown.insert(make_pair(13011,POWERSTATE_SUSPEND));
// In standalone mode we default to another.
if (g_application.IsStandAlone())
AddInt(pwm, "powermanagement.shutdownstate", 13008, POWERSTATE_SHUTDOWN, shutdown, SPIN_CONTROL_TEXT);
else
{
shutdown.insert(make_pair(13009,POWERSTATE_QUIT));
shutdown.insert(make_pair(13014,POWERSTATE_MINIMIZE));
AddInt(pwm, "powermanagement.shutdownstate", 13008, POWERSTATE_QUIT, shutdown, SPIN_CONTROL_TEXT);
}
CSettingsCategory* dbg = AddCategory(4, "debug", 14092);
AddBool(dbg, "debug.showloginfo", 20191, false);
AddPath(dbg, "debug.screenshotpath",20004,"select writable folder",BUTTON_CONTROL_PATH_INPUT,false,657);
CSettingsCategory* mst = AddCategory(4, "masterlock", 12360);
AddString(mst, "masterlock.lockcode" , 20100, "-", BUTTON_CONTROL_STANDARD);
AddBool(mst, "masterlock.startuplock" , 20076,false);
// hidden masterlock settings
AddInt(NULL,"masterlock.maxretries", 12364, 3, 3, 1, 100, SPIN_CONTROL_TEXT);
AddCategory(4, "cache", 439);
AddInt(NULL, "cache.harddisk", 14025, 256, 0, 256, 4096, SPIN_CONTROL_INT_PLUS, MASK_KB, TEXT_OFF);
AddSeparator(NULL, "cache.sep1");
AddInt(NULL, "cachevideo.dvdrom", 14026, 2048, 0, 256, 16384, SPIN_CONTROL_INT_PLUS, MASK_KB, TEXT_OFF);
AddInt(NULL, "cachevideo.lan", 14027, 2048, 0, 256, 16384, SPIN_CONTROL_INT_PLUS, MASK_KB, TEXT_OFF);
AddInt(NULL, "cachevideo.internet", 14028, 4096, 0, 256, 16384, SPIN_CONTROL_INT_PLUS, MASK_KB, TEXT_OFF);
AddSeparator(NULL, "cache.sep2");
AddInt(NULL, "cacheaudio.dvdrom", 14030, 256, 0, 256, 4096, SPIN_CONTROL_INT_PLUS, MASK_KB, TEXT_OFF);
AddInt(NULL, "cacheaudio.lan", 14031, 256, 0, 256, 4096, SPIN_CONTROL_INT_PLUS, MASK_KB, TEXT_OFF);
AddInt(NULL, "cacheaudio.internet", 14032, 256, 0, 256, 4096, SPIN_CONTROL_INT_PLUS, MASK_KB, TEXT_OFF);
AddSeparator(NULL, "cache.sep3");
AddInt(NULL, "cachedvd.dvdrom", 14034, 2048, 0, 256, 16384, SPIN_CONTROL_INT_PLUS, MASK_KB, TEXT_OFF);
AddInt(NULL, "cachedvd.lan", 14035, 2048, 0, 256, 16384, SPIN_CONTROL_INT_PLUS, MASK_KB, TEXT_OFF);
AddSeparator(NULL, "cache.sep4");
AddInt(NULL, "cacheunknown.internet", 14060, 4096, 0, 256, 16384, SPIN_CONTROL_INT_PLUS, MASK_KB, TEXT_OFF);
// video settings
AddGroup(5, 3);
CSettingsCategory* vdl = AddCategory(5, "videolibrary", 14022);
AddBool(NULL, "videolibrary.enabled", 418, true);
AddBool(vdl, "videolibrary.showunwatchedplots", 20369, true);
AddBool(NULL, "videolibrary.seasonthumbs", 20382, true);
AddBool(vdl, "videolibrary.actorthumbs", 20402, true);
map<int, int> flattenTVShowOptions;
flattenTVShowOptions.insert(make_pair(20420, 0));
flattenTVShowOptions.insert(make_pair(20421, 1));
flattenTVShowOptions.insert(make_pair(20422, 2));
AddInt(vdl, "videolibrary.flattentvshows", 20412, 1, flattenTVShowOptions, SPIN_CONTROL_TEXT);
AddBool(vdl, "videolibrary.groupmoviesets", 20458, false);
AddBool(vdl, "videolibrary.updateonstartup", 22000, false);
AddBool(vdl, "videolibrary.backgroundupdate", 22001, false);
AddSeparator(vdl, "videolibrary.sep3");
AddString(vdl, "videolibrary.cleanup", 334, "", BUTTON_CONTROL_STANDARD);
AddString(vdl, "videolibrary.export", 647, "", BUTTON_CONTROL_STANDARD);
AddString(vdl, "videolibrary.import", 648, "", BUTTON_CONTROL_STANDARD);
CSettingsCategory* vp = AddCategory(5, "videoplayer", 14086);
map<int, int> renderers;
renderers.insert(make_pair(13416, RENDER_METHOD_AUTO));
#ifdef HAS_DX
if (g_sysinfo.IsVistaOrHigher())
renderers.insert(make_pair(16319, RENDER_METHOD_DXVA));
renderers.insert(make_pair(13431, RENDER_METHOD_D3D_PS));
renderers.insert(make_pair(13419, RENDER_METHOD_SOFTWARE));
#endif
#ifdef HAS_GL
renderers.insert(make_pair(13417, RENDER_METHOD_ARB));
renderers.insert(make_pair(13418, RENDER_METHOD_GLSL));
renderers.insert(make_pair(13419, RENDER_METHOD_SOFTWARE));
#endif
AddInt(vp, "videoplayer.rendermethod", 13415, RENDER_METHOD_AUTO, renderers, SPIN_CONTROL_TEXT);
#ifdef HAVE_LIBVDPAU
AddBool(vp, "videoplayer.usevdpau", 13425, true);
#endif
#ifdef HAVE_LIBVA
AddBool(vp, "videoplayer.usevaapi", 13426, true);
#endif
#ifdef HAS_DX
AddBool(g_sysinfo.IsVistaOrHigher() ? vp: NULL, "videoplayer.usedxva2", 13427, g_sysinfo.IsVistaOrHigher() ? true : false);
#endif
#ifdef HAVE_LIBCRYSTALHD
AddBool(CCrystalHD::GetInstance()->DevicePresent() ? vp: NULL, "videoplayer.usechd", 13428, true);
#endif
#ifdef HAVE_LIBVDADECODER
AddBool(g_sysinfo.HasVDADecoder() ? vp: NULL, "videoplayer.usevda", 13429, true);
#endif
#ifdef HAVE_LIBOPENMAX
AddBool(vp, "videoplayer.useomx", 13430, true);
#endif
#ifdef HAVE_VIDEOTOOLBOXDECODER
AddBool(g_sysinfo.HasVideoToolBoxDecoder() ? vp: NULL, "videoplayer.usevideotoolbox", 13432, true);
#endif
#ifdef HAS_GL
AddBool(NULL, "videoplayer.usepbo", 13424, true);
#endif
// FIXME: hide this setting until it is properly respected. In the meanwhile, default to AUTO.
//AddInt(5, "videoplayer.displayresolution", 169, (int)RES_AUTORES, (int)RES_AUTORES, 1, (int)CUSTOM+MAX_RESOLUTIONS, SPIN_CONTROL_TEXT);
AddInt(NULL, "videoplayer.displayresolution", 169, (int)RES_AUTORES, (int)RES_AUTORES, 1, (int)RES_AUTORES, SPIN_CONTROL_TEXT);
#if !defined(TARGET_DARWIN_IOS)
AddBool(vp, "videoplayer.adjustrefreshrate", 170, false);
AddInt(vp, "videoplayer.pauseafterrefreshchange", 13550, 0, 0, 1, MAXREFRESHCHANGEDELAY, SPIN_CONTROL_TEXT);
#else
AddBool(NULL, "videoplayer.adjustrefreshrate", 170, false);
AddInt(NULL, "videoplayer.pauseafterrefreshchange", 13550, 0, 0, 1, MAXREFRESHCHANGEDELAY, SPIN_CONTROL_TEXT);
#endif
//sync settings not available on windows gl build
#if defined(_WIN32) && defined(HAS_GL)
#define SYNCSETTINGS 0
#else
#define SYNCSETTINGS 1
#endif
AddBool(SYNCSETTINGS ? vp : NULL, "videoplayer.usedisplayasclock", 13510, false);
map<int, int> syncTypes;
syncTypes.insert(make_pair(13501, SYNC_DISCON));
syncTypes.insert(make_pair(13502, SYNC_SKIPDUP));
syncTypes.insert(make_pair(13503, SYNC_RESAMPLE));
AddInt(SYNCSETTINGS ? vp : NULL, "videoplayer.synctype", 13500, SYNC_RESAMPLE, syncTypes, SPIN_CONTROL_TEXT);
AddFloat(NULL, "videoplayer.maxspeedadjust", 13504, 5.0f, 0.0f, 0.1f, 10.0f);
map<int, int> resampleQualities;
resampleQualities.insert(make_pair(13506, RESAMPLE_LOW));
resampleQualities.insert(make_pair(13507, RESAMPLE_MID));
resampleQualities.insert(make_pair(13508, RESAMPLE_HIGH));
resampleQualities.insert(make_pair(13509, RESAMPLE_REALLYHIGH));
AddInt(NULL, "videoplayer.resamplequality", 13505, RESAMPLE_MID, resampleQualities, SPIN_CONTROL_TEXT);
AddInt(vp, "videoplayer.errorinaspect", 22021, 0, 0, 1, 20, SPIN_CONTROL_INT_PLUS, MASK_PERCENT, TEXT_NONE);
map<int,int> stretch;
stretch.insert(make_pair(630,VIEW_MODE_NORMAL));
stretch.insert(make_pair(633,VIEW_MODE_WIDE_ZOOM));
stretch.insert(make_pair(634,VIEW_MODE_STRETCH_16x9));
stretch.insert(make_pair(631,VIEW_MODE_ZOOM));
AddInt(vp, "videoplayer.stretch43", 173, VIEW_MODE_NORMAL, stretch, SPIN_CONTROL_TEXT);
#ifdef HAVE_LIBVDPAU
AddBool(NULL, "videoplayer.vdpau_allow_xrandr", 13122, false);
#endif
#if defined(HAS_GL) || HAS_GLES == 2 // May need changing for GLES
AddSeparator(vp, "videoplayer.sep1.5");
#ifdef HAVE_LIBVDPAU
AddBool(NULL, "videoplayer.vdpauUpscalingLevel", 13121, false);
AddBool(vp, "videoplayer.vdpaustudiolevel", 13122, false);
#endif
#endif
AddSeparator(vp, "videoplayer.sep5");
AddBool(vp, "videoplayer.teletextenabled", 23050, true);
CSettingsCategory* vid = AddCategory(5, "myvideos", 14081);
map<int, int> myVideosSelectActions;
myVideosSelectActions.insert(make_pair(22080, SELECT_ACTION_CHOOSE));
myVideosSelectActions.insert(make_pair(208, SELECT_ACTION_PLAY_OR_RESUME));
myVideosSelectActions.insert(make_pair(13404, SELECT_ACTION_RESUME));
myVideosSelectActions.insert(make_pair(22081, SELECT_ACTION_INFO));
AddInt(vid, "myvideos.selectaction", 22079, SELECT_ACTION_PLAY_OR_RESUME, myVideosSelectActions, SPIN_CONTROL_TEXT);
AddBool(vid, "myvideos.extractflags",20433, true);
AddBool(vid, "myvideos.replacelabels", 20419, true);
AddBool(NULL, "myvideos.extractthumb",20433, true);
CSettingsCategory* sub = AddCategory(5, "subtitles", 287);
AddString(sub, "subtitles.font", 14089, "arial.ttf", SPIN_CONTROL_TEXT);
AddInt(sub, "subtitles.height", 289, 28, 16, 2, 74, SPIN_CONTROL_TEXT); // use text as there is a disk based lookup needed
map<int, int> fontStyles;
fontStyles.insert(make_pair(738, FONT_STYLE_NORMAL));
fontStyles.insert(make_pair(739, FONT_STYLE_BOLD));
fontStyles.insert(make_pair(740, FONT_STYLE_ITALICS));
fontStyles.insert(make_pair(741, FONT_STYLE_BOLD | FONT_STYLE_ITALICS));
AddInt(sub, "subtitles.style", 736, FONT_STYLE_BOLD, fontStyles, SPIN_CONTROL_TEXT);
AddInt(sub, "subtitles.color", 737, SUBTITLE_COLOR_START + 1, SUBTITLE_COLOR_START, 1, SUBTITLE_COLOR_END, SPIN_CONTROL_TEXT);
AddString(sub, "subtitles.charset", 735, "DEFAULT", SPIN_CONTROL_TEXT);
AddBool(sub,"subtitles.overrideassfonts", 21368, false);
AddSeparator(sub, "subtitles.sep1");
AddPath(sub, "subtitles.custompath", 21366, "", BUTTON_CONTROL_PATH_INPUT, false, 657);
map<int, int> subtitleAlignments;
subtitleAlignments.insert(make_pair(21461, SUBTITLE_ALIGN_MANUAL));
subtitleAlignments.insert(make_pair(21462, SUBTITLE_ALIGN_BOTTOM_INSIDE));
subtitleAlignments.insert(make_pair(21463, SUBTITLE_ALIGN_BOTTOM_OUTSIDE));
subtitleAlignments.insert(make_pair(21464, SUBTITLE_ALIGN_TOP_INSIDE));
subtitleAlignments.insert(make_pair(21465, SUBTITLE_ALIGN_TOP_OUTSIDE));
AddInt(sub, "subtitles.align", 21460, SUBTITLE_ALIGN_MANUAL, subtitleAlignments, SPIN_CONTROL_TEXT);
CSettingsCategory* dvd = AddCategory(5, "dvds", 14087);
AddBool(dvd, "dvds.autorun", 14088, false);
AddInt(dvd, "dvds.playerregion", 21372, 0, 0, 1, 8, SPIN_CONTROL_INT_PLUS, -1, TEXT_OFF);
AddBool(dvd, "dvds.automenu", 21882, false);
AddDefaultAddon(NULL, "scrapers.moviesdefault", 21413, "metadata.themoviedb.org", ADDON_SCRAPER_MOVIES);
AddDefaultAddon(NULL, "scrapers.tvshowsdefault", 21414, "metadata.tvdb.com", ADDON_SCRAPER_TVSHOWS);
AddDefaultAddon(NULL, "scrapers.musicvideosdefault", 21415, "metadata.musicvideos.last.fm", ADDON_SCRAPER_MUSICVIDEOS);
// service settings
AddGroup(6, 14036);
CSettingsCategory* srvGeneral = AddCategory(6, "general", 16000);
AddString(srvGeneral,"services.devicename", 1271, "XBMC", EDIT_CONTROL_INPUT);
CSettingsCategory* srvUpnp = AddCategory(6, "upnp", 20187);
AddBool(srvUpnp, "services.upnpserver", 21360, false);
AddBool(srvUpnp, "services.upnprenderer", 21881, false);
#ifdef HAS_WEB_SERVER
CSettingsCategory* srvWeb = AddCategory(6, "webserver", 33101);
AddBool(srvWeb, "services.webserver", 263, false);
AddString(srvWeb,"services.webserverport", 730, CUtil::CanBindPrivileged()?"80":"8080", EDIT_CONTROL_NUMBER_INPUT, false, 730);
AddString(srvWeb,"services.webserverusername",1048, "xbmc", EDIT_CONTROL_INPUT);
AddString(srvWeb,"services.webserverpassword",733, "", EDIT_CONTROL_HIDDEN_INPUT, true, 733);
AddDefaultAddon(srvWeb, "services.webskin",199, DEFAULT_WEB_INTERFACE, ADDON_WEB_INTERFACE);
#endif
#ifdef HAS_EVENT_SERVER
CSettingsCategory* srvEvent = AddCategory(6, "remotecontrol", 790);
AddBool(srvEvent, "services.esenabled", 791, true);
AddString(NULL,"services.esport", 792, "9777", EDIT_CONTROL_NUMBER_INPUT, false, 792);
AddInt(NULL, "services.esportrange", 793, 10, 1, 1, 100, SPIN_CONTROL_INT);
AddInt(NULL, "services.esmaxclients", 797, 20, 1, 1, 100, SPIN_CONTROL_INT);
AddBool(srvEvent, "services.esallinterfaces", 794, false);
AddInt(NULL, "services.esinitialdelay", 795, 750, 5, 5, 10000, SPIN_CONTROL_INT);
AddInt(NULL, "services.escontinuousdelay", 796, 25, 5, 5, 10000, SPIN_CONTROL_INT);
#endif
#ifdef HAS_ZEROCONF
CSettingsCategory* srvZeroconf = AddCategory(6, "zeroconf", 1259);
#ifdef TARGET_WINDOWS
AddBool(srvZeroconf, "services.zeroconf", 1260, false);
#else
AddBool(srvZeroconf, "services.zeroconf", 1260, true);
#endif
#endif
#ifdef HAS_AIRPLAY
CSettingsCategory* srvAirplay = AddCategory(6, "airplay", 1273);
AddBool(srvAirplay, "services.airplay", 1270, false);
AddBool(srvAirplay, "services.useairplaypassword", 1272, false);
AddString(srvAirplay, "services.airplaypassword", 733, "", EDIT_CONTROL_HIDDEN_INPUT, false, 733);
#endif
#ifndef _WIN32
CSettingsCategory* srvSmb = AddCategory(6, "smb", 1200);
AddString(srvSmb, "smb.winsserver", 1207, "", EDIT_CONTROL_IP_INPUT);
AddString(srvSmb, "smb.workgroup", 1202, "WORKGROUP", EDIT_CONTROL_INPUT, false, 1202);
#endif
// appearance settings
AddGroup(7, 480);
CSettingsCategory* laf = AddCategory(7,"lookandfeel", 166);
AddDefaultAddon(laf, "lookandfeel.skin",166,DEFAULT_SKIN, ADDON_SKIN);
AddString(laf, "lookandfeel.skintheme",15111,"SKINDEFAULT", SPIN_CONTROL_TEXT);
AddString(laf, "lookandfeel.skincolors",14078, "SKINDEFAULT", SPIN_CONTROL_TEXT);
AddString(laf, "lookandfeel.font",13303,"Default", SPIN_CONTROL_TEXT);
AddInt(laf, "lookandfeel.skinzoom",20109, 0, -20, 2, 20, SPIN_CONTROL_INT, MASK_PERCENT);
AddInt(laf, "lookandfeel.startupwindow",512,1, WINDOW_HOME, 1, WINDOW_PYTHON_END, SPIN_CONTROL_TEXT);
AddString(laf, "lookandfeel.soundskin",15108,"SKINDEFAULT", SPIN_CONTROL_TEXT);
AddSeparator(laf, "lookandfeel.sep2");
AddBool(laf, "lookandfeel.enablerssfeeds",13305, true);
AddString(laf, "lookandfeel.rssedit", 21450, "", BUTTON_CONTROL_STANDARD);
CSettingsCategory* loc = AddCategory(7, "locale", 14090);
AddString(loc, "locale.language",248,"english", SPIN_CONTROL_TEXT);
AddString(loc, "locale.country", 20026, "USA", SPIN_CONTROL_TEXT);
AddString(loc, "locale.charset", 14091, "DEFAULT", SPIN_CONTROL_TEXT); // charset is set by the language file
bool use_timezone = false;
#if defined(_LINUX)
#if defined(TARGET_DARWIN)
if (g_sysinfo.IsAppleTV2() && GetIOSVersion() < 4.3)
#endif
use_timezone = true;
if (use_timezone)
{
AddSeparator(loc, "locale.sep1");
AddString(loc, "locale.timezonecountry", 14079, g_timezone.GetCountryByTimezone(g_timezone.GetOSConfiguredTimezone()), SPIN_CONTROL_TEXT);
AddString(loc, "locale.timezone", 14080, g_timezone.GetOSConfiguredTimezone(), SPIN_CONTROL_TEXT);
}
#endif
#ifdef HAS_TIME_SERVER
AddSeparator(loc, "locale.sep2");
AddBool(loc, "locale.timeserver", 168, false);
AddString(loc, "locale.timeserveraddress", 731, "pool.ntp.org", EDIT_CONTROL_INPUT);
#endif
AddSeparator(loc, "locale.sep3");
AddString(loc, "locale.audiolanguage", 285, "original", SPIN_CONTROL_TEXT);
AddString(loc, "locale.subtitlelanguage", 286, "original", SPIN_CONTROL_TEXT);
CSettingsCategory* fl = AddCategory(7, "filelists", 14081);
AddBool(fl, "filelists.showparentdiritems", 13306, true);
AddBool(fl, "filelists.showextensions", 497, true);
AddBool(fl, "filelists.ignorethewhensorting", 13399, true);
AddBool(fl, "filelists.allowfiledeletion", 14071, false);
AddBool(fl, "filelists.showaddsourcebuttons", 21382, true);
AddBool(fl, "filelists.showhidden", 21330, false);
CSettingsCategory* ss = AddCategory(7, "screensaver", 360);
AddInt(ss, "screensaver.time", 355, 3, 1, 1, 60, SPIN_CONTROL_INT_PLUS, MASK_MINS);
AddDefaultAddon(ss, "screensaver.mode", 356, "screensaver.xbmc.builtin.dim", ADDON_SCREENSAVER);
AddString(ss, "screensaver.settings", 21417, "", BUTTON_CONTROL_STANDARD);
AddString(ss, "screensaver.preview", 1000, "", BUTTON_CONTROL_STANDARD);
AddSeparator(ss, "screensaver.sep1");
AddBool(ss, "screensaver.usemusicvisinstead", 13392, true);
AddBool(ss, "screensaver.usedimonpause", 22014, true);
AddCategory(7, "window", 0);
AddInt(NULL, "window.width", 0, 720, 10, 1, INT_MAX, SPIN_CONTROL_INT);
AddInt(NULL, "window.height", 0, 480, 10, 1, INT_MAX, SPIN_CONTROL_INT);
AddPath(NULL,"system.playlistspath",20006,"set default",BUTTON_CONTROL_PATH_INPUT,false);
// PVR-related setting typically used by skins that are aimed at PVR and non-PVR builds
AddBool(NULL, "pvrmanager.enabled", 449, false);
}
CGUISettings::~CGUISettings(void)
{
Clear();
}
void CGUISettings::AddGroup(int groupID, int labelID)
{
CSettingsGroup *pGroup = new CSettingsGroup(groupID, labelID);
if (pGroup)
settingsGroups.push_back(pGroup);
}
CSettingsCategory* CGUISettings::AddCategory(int groupID, const char *strSetting, int labelID)
{
for (unsigned int i = 0; i < settingsGroups.size(); i++)
{
if (settingsGroups[i]->GetGroupID() == groupID)
return settingsGroups[i]->AddCategory(CStdString(strSetting).ToLower(), labelID);
}
return NULL;
}
CSettingsGroup *CGUISettings::GetGroup(int groupID)
{
for (unsigned int i = 0; i < settingsGroups.size(); i++)
{
if (settingsGroups[i]->GetGroupID() == groupID)
return settingsGroups[i];
}
CLog::Log(LOGDEBUG, "Error: Requested setting group (%i) was not found. "
"It must be case-sensitive",
groupID);
return NULL;
}
void CGUISettings::AddSetting(CSettingsCategory* cat, CSetting* setting)
{
if (!setting)
return;
if (cat)
cat->m_settings.push_back(setting);
settingsMap.insert(pair<CStdString, CSetting*>(CStdString(setting->GetSetting()).ToLower(), setting));
}
void CGUISettings::AddSeparator(CSettingsCategory* cat, const char *strSetting)
{
int iOrder = cat ? cat->m_settings.size() : 0;
CSettingSeparator *pSetting = new CSettingSeparator(iOrder, CStdString(strSetting).ToLower());
if (!pSetting) return;
AddSetting(cat, pSetting);
}
void CGUISettings::AddBool(CSettingsCategory* cat, const char *strSetting, int iLabel, bool bData, int iControlType)
{
int iOrder = cat ? cat->m_settings.size() : 0;
CSettingBool* pSetting = new CSettingBool(iOrder, CStdString(strSetting).ToLower(), iLabel, bData, iControlType);
if (!pSetting) return ;
AddSetting(cat, pSetting);
}
bool CGUISettings::GetBool(const char *strSetting) const
{
ASSERT(settingsMap.size());
CStdString lower(strSetting);
lower.ToLower();
constMapIter it = settingsMap.find(lower);
if (it != settingsMap.end())
{ // old category
return ((CSettingBool*)(*it).second)->GetData();
}
// Backward compatibility (skins use this setting)
if (lower == "lookandfeel.enablemouse")
return GetBool("input.enablemouse");
// Assert here and write debug output
CLog::Log(LOGDEBUG,"Error: Requested setting (%s) was not found. It must be case-sensitive", strSetting);
return false;
}
void CGUISettings::SetBool(const char *strSetting, bool bSetting)
{
ASSERT(settingsMap.size());
mapIter it = settingsMap.find(CStdString(strSetting).ToLower());
if (it != settingsMap.end())
{ // old category
((CSettingBool*)(*it).second)->SetData(bSetting);
return ;
}
// Assert here and write debug output
CLog::Log(LOGDEBUG,"Error: Requested setting (%s) was not found. It must be case-sensitive", strSetting);
}
void CGUISettings::ToggleBool(const char *strSetting)
{
ASSERT(settingsMap.size());
mapIter it = settingsMap.find(CStdString(strSetting).ToLower());
if (it != settingsMap.end())
{ // old category
((CSettingBool*)(*it).second)->SetData(!((CSettingBool *)(*it).second)->GetData());
return ;
}
// Assert here and write debug output
CLog::Log(LOGDEBUG,"Error: Requested setting (%s) was not found. It must be case-sensitive", strSetting);
}
void CGUISettings::AddFloat(CSettingsCategory* cat, const char *strSetting, int iLabel, float fData, float fMin, float fStep, float fMax, int iControlType)
{
int iOrder = cat ? cat->m_settings.size() : 0;
CSettingFloat* pSetting = new CSettingFloat(iOrder, CStdString(strSetting).ToLower(), iLabel, fData, fMin, fStep, fMax, iControlType);
if (!pSetting) return ;
AddSetting(cat, pSetting);
}
float CGUISettings::GetFloat(const char *strSetting) const
{
ASSERT(settingsMap.size());
constMapIter it = settingsMap.find(CStdString(strSetting).ToLower());
if (it != settingsMap.end())
{
return ((CSettingFloat *)(*it).second)->GetData();
}
// Assert here and write debug output
//ASSERT(false);
CLog::Log(LOGDEBUG,"Error: Requested setting (%s) was not found. It must be case-sensitive", strSetting);
return 0.0f;
}
void CGUISettings::SetFloat(const char *strSetting, float fSetting)
{
ASSERT(settingsMap.size());
mapIter it = settingsMap.find(CStdString(strSetting).ToLower());
if (it != settingsMap.end())
{
((CSettingFloat *)(*it).second)->SetData(fSetting);
return ;
}
// Assert here and write debug output
ASSERT(false);
CLog::Log(LOGDEBUG,"Error: Requested setting (%s) was not found. It must be case-sensitive", strSetting);
}
void CGUISettings::LoadMasterLock(TiXmlElement *pRootElement)
{
std::map<CStdString,CSetting*>::iterator it = settingsMap.find("masterlock.maxretries");
if (it != settingsMap.end())
LoadFromXML(pRootElement, it);
it = settingsMap.find("masterlock.startuplock");
if (it != settingsMap.end())
LoadFromXML(pRootElement, it);
}
void CGUISettings::AddInt(CSettingsCategory* cat, const char *strSetting, int iLabel, int iData, int iMin, int iStep, int iMax, int iControlType, const char *strFormat)
{
int iOrder = cat ? cat->m_settings.size() : 0;
CSettingInt* pSetting = new CSettingInt(iOrder, CStdString(strSetting).ToLower(), iLabel, iData, iMin, iStep, iMax, iControlType, strFormat);
if (!pSetting) return ;
AddSetting(cat, pSetting);
}
void CGUISettings::AddInt(CSettingsCategory* cat, const char *strSetting, int iLabel, int iData, int iMin, int iStep, int iMax, int iControlType, int iFormat, int iLabelMin/*=-1*/)
{
int iOrder = cat ? cat->m_settings.size() : 0;
CSettingInt* pSetting = new CSettingInt(iOrder, CStdString(strSetting).ToLower(), iLabel, iData, iMin, iStep, iMax, iControlType, iFormat, iLabelMin);
if (!pSetting) return ;
AddSetting(cat, pSetting);
}
void CGUISettings::AddInt(CSettingsCategory* cat, const char *strSetting, int iLabel, int iData, const map<int,int>& entries, int iControlType)
{
int iOrder = cat ? cat->m_settings.size() : 0;
CSettingInt* pSetting = new CSettingInt(iOrder, CStdString(strSetting).ToLower(), iLabel, iData, entries, iControlType);
if (!pSetting) return ;
AddSetting(cat, pSetting);
}
void CGUISettings::AddHex(CSettingsCategory* cat, const char *strSetting, int iLabel, int iData, int iMin, int iStep, int iMax, int iControlType, const char *strFormat)
{
int iOrder = cat ? cat->m_settings.size() : 0;
CSettingHex* pSetting = new CSettingHex(iOrder, CStdString(strSetting).ToLower(), iLabel, iData, iMin, iStep, iMax, iControlType, strFormat);
if (!pSetting) return ;
AddSetting(cat, pSetting);
}
int CGUISettings::GetInt(const char *strSetting) const
{
ASSERT(settingsMap.size());
constMapIter it = settingsMap.find(CStdString(strSetting).ToLower());
if (it != settingsMap.end())
{
return ((CSettingInt *)(*it).second)->GetData();
}
// Assert here and write debug output
CLog::Log(LOGERROR,"Error: Requested setting (%s) was not found. It must be case-sensitive", strSetting);
//ASSERT(false);
return 0;
}
void CGUISettings::SetInt(const char *strSetting, int iSetting)
{
ASSERT(settingsMap.size());
mapIter it = settingsMap.find(CStdString(strSetting).ToLower());
if (it != settingsMap.end())
{
((CSettingInt *)(*it).second)->SetData(iSetting);
return ;
}
// Assert here and write debug output
ASSERT(false);
}
void CGUISettings::AddString(CSettingsCategory* cat, const char *strSetting, int iLabel, const char *strData, int iControlType, bool bAllowEmpty, int iHeadingString)
{
int iOrder = cat ? cat->m_settings.size() : 0;
CSettingString* pSetting = new CSettingString(iOrder, CStdString(strSetting).ToLower(), iLabel, strData, iControlType, bAllowEmpty, iHeadingString);
if (!pSetting) return ;
AddSetting(cat, pSetting);
}
void CGUISettings::AddPath(CSettingsCategory* cat, const char *strSetting, int iLabel, const char *strData, int iControlType, bool bAllowEmpty, int iHeadingString)
{
int iOrder = cat ? cat->m_settings.size() : 0;
CSettingPath* pSetting = new CSettingPath(iOrder, CStdString(strSetting).ToLower(), iLabel, strData, iControlType, bAllowEmpty, iHeadingString);
if (!pSetting) return ;
AddSetting(cat, pSetting);
}
void CGUISettings::AddDefaultAddon(CSettingsCategory* cat, const char *strSetting, int iLabel, const char *strData, const TYPE type)
{
int iOrder = cat ? cat->m_settings.size() : 0;
CSettingAddon* pSetting = new CSettingAddon(iOrder, CStdString(strSetting).ToLower(), iLabel, strData, type);
if (!pSetting) return ;
AddSetting(cat, pSetting);
}
const CStdString &CGUISettings::GetString(const char *strSetting, bool bPrompt /* = true */) const
{
ASSERT(settingsMap.size());
constMapIter it = settingsMap.find(CStdString(strSetting).ToLower());
if (it != settingsMap.end())
{
CSettingString* result = ((CSettingString *)(*it).second);
if (result->GetData() == "select folder" || result->GetData() == "select writable folder")
{
CStdString strData = "";
if (bPrompt)
{
VECSOURCES shares;
g_mediaManager.GetLocalDrives(shares);
if (CGUIDialogFileBrowser::ShowAndGetDirectory(shares,g_localizeStrings.Get(result->GetLabel()),strData,result->GetData() == "select writable folder"))
{
result->SetData(strData);
g_settings.Save();
}
else
return StringUtils::EmptyString;
}
else
return StringUtils::EmptyString;
}
return result->GetData();
}
// Assert here and write debug output
CLog::Log(LOGDEBUG,"Error: Requested setting (%s) was not found. It must be case-sensitive", strSetting);
//ASSERT(false);
// hardcoded return value so that compiler is happy
return StringUtils::EmptyString;
}
void CGUISettings::SetString(const char *strSetting, const char *strData)
{
ASSERT(settingsMap.size());
mapIter it = settingsMap.find(CStdString(strSetting).ToLower());
if (it != settingsMap.end())
{
((CSettingString *)(*it).second)->SetData(strData);
return ;
}
// Assert here and write debug output
ASSERT(false);
CLog::Log(LOGDEBUG,"Error: Requested setting (%s) was not found. It must be case-sensitive", strSetting);
}
CSetting *CGUISettings::GetSetting(const char *strSetting)
{
ASSERT(settingsMap.size());
mapIter it = settingsMap.find(CStdString(strSetting).ToLower());
if (it != settingsMap.end())
return (*it).second;
else
return NULL;
}
// get all the settings beginning with the term "strGroup"
void CGUISettings::GetSettingsGroup(CSettingsCategory* cat, vecSettings &settings)
{
if (!cat || cat->m_settings.size() <= 0)
return;
vecSettings unorderedSettings;
for (unsigned int index = 0; index < cat->m_settings.size(); index++)
{
if (!cat->m_settings.at(index)->IsAdvanced())
unorderedSettings.push_back(cat->m_settings.at(index));
}
// now order them...
sort(unorderedSettings.begin(), unorderedSettings.end(), sortsettings());
// remove any instances of 2 separators in a row
bool lastWasSeparator(false);
for (vecSettings::iterator it = unorderedSettings.begin(); it != unorderedSettings.end(); it++)
{
CSetting *setting = *it;
// only add separators if we don't have 2 in a row
if (setting->GetType() == SETTINGS_TYPE_SEPARATOR)
{
if (!lastWasSeparator)
settings.push_back(setting);
lastWasSeparator = true;
}
else
{
lastWasSeparator = false;
settings.push_back(setting);
}
}
}
void CGUISettings::LoadXML(TiXmlElement *pRootElement, bool hideSettings /* = false */)
{ // load our stuff...
for (mapIter it = settingsMap.begin(); it != settingsMap.end(); it++)
{
LoadFromXML(pRootElement, it, hideSettings);
}
// Get hardware based stuff...
CLog::Log(LOGNOTICE, "Getting hardware information now...");
// FIXME: Check if the hardware supports it (if possible ;)
//SetBool("audiooutput.ac3passthrough", g_audioConfig.GetAC3Enabled());
//SetBool("audiooutput.dtspassthrough", g_audioConfig.GetDTSEnabled());
CLog::Log(LOGINFO, "Using %s output", GetInt("audiooutput.mode") == AUDIO_ANALOG ? "analog" : "digital");
CLog::Log(LOGINFO, "AC3 pass through is %s", GetBool("audiooutput.ac3passthrough") ? "enabled" : "disabled");
CLog::Log(LOGINFO, "DTS pass through is %s", GetBool("audiooutput.dtspassthrough") ? "enabled" : "disabled");
CLog::Log(LOGINFO, "AAC pass through is %s", GetBool("audiooutput.passthroughaac") ? "enabled" : "disabled");
#if defined(TARGET_DARWIN)
// trap any previous vsync by driver setting, does not exist on OSX
if (GetInt("videoscreen.vsync") == VSYNC_DRIVER)
{
SetInt("videoscreen.vsync", VSYNC_ALWAYS);
}
#endif
// DXMERGE: This might have been useful?
// g_videoConfig.SetVSyncMode((VSYNC)GetInt("videoscreen.vsync"));
// Move replaygain settings into our struct
m_replayGain.iPreAmp = GetInt("musicplayer.replaygainpreamp");
m_replayGain.iNoGainPreAmp = GetInt("musicplayer.replaygainnogainpreamp");
m_replayGain.iType = GetInt("musicplayer.replaygaintype");
m_replayGain.bAvoidClipping = GetBool("musicplayer.replaygainavoidclipping");
bool use_timezone = false;
#if defined(_LINUX)
#if defined(TARGET_DARWIN)
if (g_sysinfo.IsAppleTV2() && GetIOSVersion() < 4.3)
#endif
use_timezone = true;
if (use_timezone)
{
CStdString timezone = GetString("locale.timezone");
if(timezone == "0" || timezone.IsEmpty())
{
timezone = g_timezone.GetOSConfiguredTimezone();
SetString("locale.timezone", timezone);
}
g_timezone.SetTimezone(timezone);
}
#endif
CStdString streamLanguage = GetString("locale.audiolanguage");
if (!streamLanguage.Equals("original") && !streamLanguage.Equals("default"))
g_langInfo.SetAudioLanguage(streamLanguage);
else
g_langInfo.SetAudioLanguage("");
streamLanguage = GetString("locale.subtitlelanguage");
if (!streamLanguage.Equals("original") && !streamLanguage.Equals("default"))
g_langInfo.SetSubtitleLanguage(streamLanguage);
else
g_langInfo.SetSubtitleLanguage("");
}
void CGUISettings::LoadFromXML(TiXmlElement *pRootElement, mapIter &it, bool advanced /* = false */)
{
CStdStringArray strSplit;
StringUtils::SplitString((*it).first, ".", strSplit);
if (strSplit.size() > 1)
{
const TiXmlNode *pChild = pRootElement->FirstChild(strSplit[0].c_str());
if (pChild)
{
const TiXmlElement *pGrandChild = pChild->FirstChildElement(strSplit[1].c_str());
if (pGrandChild)
{
CStdString strValue = pGrandChild->FirstChild() ? pGrandChild->FirstChild()->Value() : "";
if (strValue != "-")
{ // update our item
(*it).second->FromString(strValue);
if (advanced)
(*it).second->SetAdvanced();
}
}
}
}
}
void CGUISettings::SaveXML(TiXmlNode *pRootNode)
{
for (mapIter it = settingsMap.begin(); it != settingsMap.end(); it++)
{
// don't save advanced settings
CStdString first = (*it).first;
if ((*it).second->IsAdvanced() || (*it).second->GetType() == SETTINGS_TYPE_SEPARATOR)
continue;
CStdStringArray strSplit;
StringUtils::SplitString((*it).first, ".", strSplit);
if (strSplit.size() > 1)
{
TiXmlNode *pChild = pRootNode->FirstChild(strSplit[0].c_str());
if (!pChild)
{ // add our group tag
TiXmlElement newElement(strSplit[0].c_str());
pChild = pRootNode->InsertEndChild(newElement);
}
if (pChild)
{ // successfully added (or found) our group
TiXmlElement newElement(strSplit[1]);
if ((*it).second->GetType() == SETTINGS_TYPE_PATH)
newElement.SetAttribute("pathversion", XMLUtils::path_version);
TiXmlNode *pNewNode = pChild->InsertEndChild(newElement);
if (pNewNode)
{
TiXmlText value((*it).second->ToString());
pNewNode->InsertEndChild(value);
}
}
}
}
}
void CGUISettings::Clear()
{
for (mapIter it = settingsMap.begin(); it != settingsMap.end(); it++)
delete (*it).second;
settingsMap.clear();
for (unsigned int i = 0; i < settingsGroups.size(); i++)
delete settingsGroups[i];
settingsGroups.clear();
}
float square_error(float x, float y)
{
float yonx = (x > 0) ? y / x : 0;
float xony = (y > 0) ? x / y : 0;
return std::max(yonx, xony);
}
RESOLUTION CGUISettings::GetResolution() const
{
return GetResFromString(GetString("videoscreen.screenmode"));
}
RESOLUTION CGUISettings::GetResFromString(const CStdString &res)
{
if (res == "DESKTOP")
return RES_DESKTOP;
else if (res == "WINDOW")
return RES_WINDOW;
else if (res.GetLength()==20)
{
// format: SWWWWWHHHHHRRR.RRRRR, where S = screen, W = width, H = height, R = refresh
int screen = atol(res.Mid(0,1).c_str());
int width = atol(res.Mid(1,5).c_str());
int height = atol(res.Mid(6,5).c_str());
float refresh = (float)atof(res.Mid(11).c_str());
// find the closest match to these in our res vector. If we have the screen, we score the res
RESOLUTION bestRes = RES_DESKTOP;
float bestScore = FLT_MAX;
for (unsigned int i = RES_DESKTOP; i < g_settings.m_ResInfo.size(); ++i)
{
const RESOLUTION_INFO &info = g_settings.m_ResInfo[i];
if (info.iScreen != screen)
continue;
float score = 10*(square_error((float)info.iWidth, (float)width) + square_error((float)info.iHeight, (float)height)) + square_error(info.fRefreshRate, refresh);
if (score < bestScore)
{
bestScore = score;
bestRes = (RESOLUTION)i;
}
}
return bestRes;
}
return RES_DESKTOP;
}
void CGUISettings::SetResolution(RESOLUTION res)
{
CStdString mode;
if (res == RES_DESKTOP)
mode = "DESKTOP";
else if (res == RES_WINDOW)
mode = "WINDOW";
else if (res >= RES_CUSTOM && res < (RESOLUTION)g_settings.m_ResInfo.size())
{
const RESOLUTION_INFO &info = g_settings.m_ResInfo[res];
mode.Format("%1i%05i%05i%09.5f", info.iScreen, info.iWidth, info.iHeight, info.fRefreshRate);
}
else
{
CLog::Log(LOGWARNING, "%s, setting invalid resolution %i", __FUNCTION__, res);
mode = "DESKTOP";
}
SetString("videoscreen.screenmode", mode);
m_LookAndFeelResolution = res;
}
bool CGUISettings::SetLanguage(const CStdString &strLanguage)
{
CStdString strPreviousLanguage = GetString("locale.language");
CStdString strNewLanguage = strLanguage;
if (strNewLanguage != strPreviousLanguage)
{
CStdString strLangInfoPath;
strLangInfoPath.Format("special://xbmc/language/%s/langinfo.xml", strNewLanguage.c_str());
if (!g_langInfo.Load(strLangInfoPath))
return false;
if (g_langInfo.ForceUnicodeFont() && !g_fontManager.IsFontSetUnicode())
{
CLog::Log(LOGINFO, "Language needs a ttf font, loading first ttf font available");
CStdString strFontSet;
if (g_fontManager.GetFirstFontSetUnicode(strFontSet))
strNewLanguage = strFontSet;
else
CLog::Log(LOGERROR, "No ttf font found but needed: %s", strFontSet.c_str());
}
SetString("locale.language", strNewLanguage);
g_charsetConverter.reset();
if (!g_localizeStrings.Load("special://xbmc/language/", strNewLanguage))
return false;
// also tell our weather and skin to reload as these are localized
g_weatherManager.Refresh();
g_application.ReloadSkin();
}
return true;
}
Jump to Line
Something went wrong with that request. Please try again.