diff options
Diffstat (limited to 'xbmc/GUIInfoManager.cpp')
-rw-r--r-- | xbmc/GUIInfoManager.cpp | 11456 |
1 files changed, 11456 insertions, 0 deletions
diff --git a/xbmc/GUIInfoManager.cpp b/xbmc/GUIInfoManager.cpp new file mode 100644 index 0000000..dc4b7a8 --- /dev/null +++ b/xbmc/GUIInfoManager.cpp @@ -0,0 +1,11456 @@ +/* + * Copyright (C) 2005-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 "GUIInfoManager.h" + +#include "FileItem.h" +#include "ServiceBroker.h" +#include "URL.h" +#include "Util.h" +#include "application/ApplicationComponents.h" +#include "application/ApplicationPlayer.h" +#include "cores/DataCacheCore.h" +#include "filesystem/File.h" +#include "games/tags/GameInfoTag.h" +#include "guilib/guiinfo/GUIInfo.h" +#include "guilib/guiinfo/GUIInfoHelper.h" +#include "guilib/guiinfo/GUIInfoLabels.h" +#include "input/WindowTranslator.h" +#include "interfaces/AnnouncementManager.h" +#include "interfaces/info/InfoExpression.h" +#include "messaging/ApplicationMessenger.h" +#include "playlists/PlayListTypes.h" +#include "settings/SkinSettings.h" +#include "utils/CharsetConverter.h" +#include "utils/FileUtils.h" +#include "utils/StringUtils.h" +#include "utils/URIUtils.h" +#include "utils/log.h" + +#include <algorithm> +#include <array> +#include <charconv> +#include <cmath> +#include <functional> +#include <iterator> +#include <memory> +#include <mutex> + +using namespace KODI::GUILIB; +using namespace KODI::GUILIB::GUIINFO; +using namespace INFO; + +bool InfoBoolComparator(const InfoPtr &right, const InfoPtr &left) +{ + return *right < *left; +} + +CGUIInfoManager::CGUIInfoManager(void) +: m_currentFile(new CFileItem), + m_bools(&InfoBoolComparator) +{ +} + +CGUIInfoManager::~CGUIInfoManager(void) +{ + delete m_currentFile; +} + +void CGUIInfoManager::Initialize() +{ + CServiceBroker::GetAppMessenger()->RegisterReceiver(this); +} + +/// \brief Translates a string as given by the skin into an int that we use for more +/// efficient retrieval of data. Can handle combined strings on the form +/// Player.Caching + VideoPlayer.IsFullscreen (Logical and) +/// Player.HasVideo | Player.HasAudio (Logical or) +int CGUIInfoManager::TranslateString(const std::string &condition) +{ + // translate $LOCALIZE as required + std::string strCondition(CGUIInfoLabel::ReplaceLocalize(condition)); + return TranslateSingleString(strCondition); +} + +typedef struct +{ + const char *str; + int val; +} infomap; + +/// \page modules__infolabels_boolean_conditions Infolabels and Boolean conditions +/// \tableofcontents +/// +/// \section modules__infolabels_boolean_conditions_Description Description +/// Skins can use boolean conditions with the <b>\<visible\></b> tag or with condition +/// attributes. Scripts can read boolean conditions with +/// <b>xbmc.getCondVisibility(condition)</b>. +/// +/// Skins can use infolabels with <b>$INFO[infolabel]</b> or the <b>\<info\></b> tag. Scripts +/// can read infolabels with <b>xbmc.getInfoLabel('infolabel')</b>. +/// +/// @todo [docs] Improve the description and create links for functions +/// @todo [docs] Separate boolean conditions from infolabels +/// @todo [docs] Order items alphabetically within subsections for a better search experience +/// @todo [docs] Order subsections alphabetically +/// @todo [docs] Use links instead of bold values for infolabels/bools +/// so we can use a link to point users when providing help +/// + + +/// \page modules__infolabels_boolean_conditions +/// \section modules_list_infolabels_booleans List of Infolabels and Boolean conditions +/// \subsection modules__infolabels_boolean_conditions_GlobalBools Global +/// \table_start +/// \table_h3{ Labels, Type, Description } +/// \table_row3{ <b>`true`</b>, +/// \anchor Global_True +/// _boolean_, +/// @return Always evaluates to **true**. +/// <p> +/// } +/// \table_row3{ <b>`false`</b>, +/// \anchor Global_False +/// _boolean_, +/// @return Always evaluates to **false**. +/// <p> +/// } +/// \table_row3{ <b>`yes`</b>, +/// \anchor Global_Yes +/// _boolean_, +/// @return same as \link Global_True `true` \endlink. +/// <p> +/// } +/// \table_row3{ <b>`no`</b>, +/// \anchor Global_No +/// _boolean_, +/// @return same as \link Global_False `false` \endlink. +/// <p> +/// } +/// \table_end +/// +/// ----------------------------------------------------------------------------- + +/// \page modules__infolabels_boolean_conditions +/// \subsection modules__infolabels_boolean_conditions_Addon Addon +/// \table_start +/// \table_h3{ Labels, Type, Description } +/// \table_row3{ <b>`Addon.SettingStr(addon_id\,setting_id)`</b>, +/// \anchor Addon_SettingString +/// _string_, +/// @return The string value of the setting `setting_id` belonging to the addon with the id `addon_id`. +/// @param addon_id - the id of the addon +/// @param setting_id - the addon setting +/// <p><hr> +/// @skinning_v20 **[New Infolabel]** \link Addon_SettingString `Addon.SettingStr(addon_id\,setting_id)`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Addon.SettingBool(addon_id\,setting_id)`</b>, +/// \anchor Addon_SettingBool +/// _boolean_, +/// @return **True** if the setting `setting_id` belonging to the addon with the id `addon_id` is **True**\, **False** otherwise. +/// @note The provided setting with `setting_id` must be a boolean setting type. Otherwise it will return the boolean info +/// default value (which is **False**). +/// @param addon_id - the id of the addon +/// @param setting_id - the addon setting +/// <p><hr> +/// @skinning_v20 **[New Boolean Condition]** \link Addon_SettingBool `Addon.SettingBool(addon_id\,setting_id)`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Addon.SettingInt(addon_id\,setting_id)`</b>, +/// \anchor Addon_SettingInt +/// _integer_, +/// @return The integer value of the setting `setting_id` belong to the addon with the id `addon_id`. +/// @note The provided setting with `setting_id` must be an integer setting type. Otherwise it will return the integer info +/// default value (which is 0). +/// @param addon_id - the id of the addon +/// @param setting_id - the addon setting +/// <p><hr> +/// @skinning_v20 **[New Integer Info]** \link Addon_SettingInt `Addon.SettingInt(addon_id\,setting_id)`\endlink +/// <p> +/// } +/// \table_end +/// +/// ----------------------------------------------------------------------------- +const infomap addons[] = { + {"settingstr", ADDON_SETTING_STRING}, + {"settingbool", ADDON_SETTING_BOOL}, + {"settingint", ADDON_SETTING_INT}, +}; + +/// \page modules__infolabels_boolean_conditions +/// \subsection modules__infolabels_boolean_conditions_String String +/// \table_start +/// \table_h3{ Labels, Type, Description } +/// \table_row3{ <b>`String.IsEmpty(info)`</b>, +/// \anchor String_IsEmpty +/// _boolean_, +/// @return **True** if the info is empty. +/// @param info - infolabel +/// @note **Example of info:** \link ListItem_Title `ListItem.Title` \endlink \, +/// \link ListItem_Genre `ListItem.Genre` \endlink. +/// Please note that string can also be a `$LOCALIZE[]`. +/// Also note that in a panelview or similar this only works on the focused item +/// <p><hr> +/// @skinning_v17 **[New Boolean Condition]** \link String_IsEmpty `String.IsEmpty(info)`\endlink +/// <p> +/// } +/// \table_row3{ <b>`String.IsEqual(info\,string)`</b>, +/// \anchor String_IsEqual +/// _boolean_, +/// @return **True** if the info is equal to the given string. +/// @param info - infolabel +/// @param string - comparison string +/// @note **Example of info:** \link ListItem_Title `ListItem.Title` \endlink \, +/// \link ListItem_Genre `ListItem.Genre` \endlink. +/// Please note that string can also be a `$LOCALIZE[]`. +/// Also note that in a panelview or similar this only works on the focused item +/// <p><hr> +/// @skinning_v17 **[New Boolean Condition]** \link String_IsEqual `String.IsEqual(info\,string)`\endlink +/// <p> +/// } +/// \table_row3{ <b>`String.StartsWith(info\,substring)`</b>, +/// \anchor String_StartsWith +/// _boolean_, +/// @return **True** if the info starts with the given substring. +/// @param info - infolabel +/// @param substring - substring to check +/// @note **Example of info:** \link ListItem_Title `ListItem.Title` \endlink \, +/// \link ListItem_Genre `ListItem.Genre` \endlink. +/// Please note that string can also be a `$LOCALIZE[]`. +/// Also note that in a panelview or similar this only works on the focused item +/// <p><hr> +/// @skinning_v17 **[New Boolean Condition]** \link String_StartsWith `String.StartsWith(info\,substring)`\endlink +/// <p> +/// } +/// \table_row3{ <b>`String.EndsWith(info\,substring)`</b>, +/// \anchor String_EndsWith +/// _boolean_, +/// @return **True** if the info ends with the given substring. +/// @param info - infolabel +/// @param substring - substring to check +/// @note **Example of info:** \link ListItem_Title `ListItem.Title` \endlink \, +/// \link ListItem_Genre `ListItem.Genre` \endlink. +/// Please note that string can also be a `$LOCALIZE[]`. +/// Also note that in a panelview or similar this only works on the focused item +/// <p><hr> +/// @skinning_v17 **[New Boolean Condition]** \link String_EndsWith `String.EndsWith(info\,substring)`\endlink +/// <p> +/// } +/// \table_row3{ <b>`String.Contains(info\,substring)`</b>, +/// \anchor String_Contains +/// _boolean_, +/// @return **True** if the info contains the given substring. +/// @param info - infolabel +/// @param substring - substring to check +/// @note **Example of info:** \link ListItem_Title `ListItem.Title` \endlink \, +/// \link ListItem_Genre `ListItem.Genre` \endlink. +/// Please note that string can also be a `$LOCALIZE[]`. +/// Also note that in a panelview or similar this only works on the focused item +/// <p><hr> +/// @skinning_v17 **[New Boolean Condition]** \link String_Contains `String.Contains(info\,substring)`\endlink +/// <p> +/// } +/// \table_end +/// +/// ----------------------------------------------------------------------------- + + +const infomap string_bools[] = {{ "isempty", STRING_IS_EMPTY }, + { "isequal", STRING_IS_EQUAL }, + { "startswith", STRING_STARTS_WITH }, + { "endswith", STRING_ENDS_WITH }, + { "contains", STRING_CONTAINS }}; + +/// \page modules__infolabels_boolean_conditions +/// \subsection modules__infolabels_boolean_conditions_Integer Integer +/// \table_start +/// \table_h3{ Labels, Type, Description } +/// \table_row3{ <b>`Integer.ValueOf(number)`</b>, +/// \anchor Integer_ValueOf +/// _integer_, +/// @return An integer info label that represents the provided number +/// @param number - the number to compute +/// @note **Example:** `Integer.ValueOf(4)` will be evaluated to 4. +/// @note Will return -1 if not able to convert the provided value to an integer. **Example**: `Integer.ValueOf(some string)` will evaluate to -1 +/// as the provided argument is not an integer. +/// <p><hr> +/// @skinning_v20 **[New InfoLabel]** \link Integer_ValueOf `Integer.ValueOf(number)`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Integer.IsEqual(info\,number)`</b>, +/// \anchor Integer_IsEqual +/// _boolean_, +/// @return **True** if the value of the infolabel is equal to the supplied number. +/// @param info - infolabel +/// @param number - number or integer infolabel to compare +/// @note **Example:** `Integer.IsEqual(ListItem.Year\,2000)` +/// <p><hr> +/// @skinning_v17 **[New Boolean Condition]** \link Integer_IsEqual `Integer.IsEqual(info\,number)`\endlink +/// @skinning_v20 \link Integer_IsEqual `Integer.IsEqual(info\,number)`\endlink now supports comparisons against other integer infos +/// and not just fixed number values. +/// <p> +/// } +/// \table_row3{ <b>`Integer.IsGreater(info\,number)`</b>, +/// \anchor Integer_IsGreater +/// _boolean_, +/// @return **True** if the value of the infolabel is greater than to the supplied number. +/// @param info - infolabel +/// @param number - number or integer infolabel to compare +/// @note **Example:** `Integer.IsGreater(ListItem.Year\,2000)` +/// <p><hr> +/// @skinning_v17 **[New Boolean Condition]** \link Integer_IsGreater `Integer.IsGreater(info\,number)`\endlink +/// @skinning_v20 \link Integer_IsGreater `Integer.IsGreater(info\,number)`\endlink now supports comparisons against other integer infos +/// and not just fixed number values. +/// <p> +/// } +/// \table_row3{ <b>`Integer.IsGreaterOrEqual(info\,number)`</b>, +/// \anchor Integer_IsGreaterOrEqual +/// _boolean_, +/// @return **True** if the value of the infolabel is greater or equal to the supplied number. +/// @param info - infolabel +/// @param number - number or integer infolabel to compare +/// @note **Example:** `Integer.IsGreaterOrEqual(ListItem.Year\,2000)` +/// @note **Example2:** `Integer.IsGreaterOrEqual(Container(x).ListItem(1).Year\,Container(x).ListItem(2).Year)` +/// <p><hr> +/// @skinning_v17 **[New Boolean Condition]** \link Integer_IsGreaterOrEqual `Integer.IsGreaterOrEqual(info\,number)`\endlink +/// @skinning_v20 \link Integer_IsGreaterOrEqual `Integer.IsGreaterOrEqual(info\,number)`\endlink now supports comparisons against other integer infos +/// and not just fixed number values. +/// <p> +/// } +/// \table_row3{ <b>`Integer.IsLess(info\,number)`</b>, +/// \anchor Integer_IsLess +/// _boolean_, +/// @return **True** if the value of the infolabel is less than the supplied number. +/// @param info - infolabel +/// @param number - number or integer infolabel to compare +/// @note **Example:** `Integer.IsLess(ListItem.Year\,2000)` +/// <p><hr> +/// @skinning_v17 **[New Boolean Condition]** \link Integer_IsLess `Integer.IsLess(info\,number)`\endlink +/// @skinning_v20 \link Integer_IsLess `Integer.IsLess(info\,number)`\endlink now supports comparisons against other integer infos +/// and not just fixed number values. +/// <p> +/// } +/// \table_row3{ <b>`Integer.IsLessOrEqual(info\,number)`</b>, +/// \anchor Integer_IsLessOrEqual +/// _boolean_, +/// @return **True** if the value of the infolabel is less or equal to the supplied number. +/// @param info - infolabel +/// @param number - number or integer infolabel to compare +/// @note **Example:** `Integer.IsLessOrEqual(ListItem.Year\,2000)` +/// <p><hr> +/// @skinning_v17 **[New Boolean Condition]** \link Integer_IsLessOrEqual `Integer.IsLessOrEqual(info\,number)`\endlink +/// @skinning_v20 \link Integer_IsLessOrEqual `Integer.IsLessOrEqual(info\,number)`\endlink now supports comparisons against other integer infos +/// and not just fixed number values. +/// <p> +/// } +/// \table_row3{ <b>`Integer.IsEven(info)`</b>, +/// \anchor Integer_IsEven +/// _boolean_, +/// @return **True** if the value of the infolabel is odd +/// @param info - infolabel +/// @note **Example:** `Integer.IsEven(ListItem.CurrentItem)` +/// <p><hr> +/// @skinning_v19 **[New Boolean Condition]** \link Integer_IsEven `Integer.IsEven(info)`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Integer.IsOdd(info)`</b>, +/// \anchor Integer_IsOdd +/// _boolean_, +/// @return **True** if the value of the infolabel is odd +/// @param info - infolabel +/// @note **Example:** `Integer.IsOdd(ListItem.CurrentItem)` +/// <p><hr> +/// @skinning_v19 **[New Boolean Condition]** \link Integer_IsOdd `Integer.IsOdd(info)`\endlink +/// <p> +/// } +/// \table_end +/// +/// ----------------------------------------------------------------------------- + +const infomap integer_bools[] = {{ "isequal", INTEGER_IS_EQUAL }, + { "isgreater", INTEGER_GREATER_THAN }, + { "isgreaterorequal", INTEGER_GREATER_OR_EQUAL }, + { "isless", INTEGER_LESS_THAN }, + { "islessorequal", INTEGER_LESS_OR_EQUAL }, + { "iseven", INTEGER_EVEN }, + { "isodd", INTEGER_ODD }}; + + +/// \page modules__infolabels_boolean_conditions +/// \subsection modules__infolabels_boolean_conditions_Player Player +/// \table_start +/// \table_h3{ Labels, Type, Description } +/// \table_row3{ <b>`Player.HasAudio`</b>, +/// \anchor Player_HasAudio +/// _boolean_, +/// @return **True** if the player has an audio file. +/// <p> +/// } +/// \table_row3{ <b>`Player.HasGame`</b>, +/// \anchor Player_HasGame +/// _boolean_, +/// @return **True** if the player has a game file (RETROPLAYER). +/// <p><hr> +/// @skinning_v18 **[New Boolean Condition]** \link Player_HasGame `Player.HasGame`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Player.HasMedia`</b>, +/// \anchor Player_HasMedia +/// _boolean_, +/// @return **True** if the player has an audio or video file. +/// <p> +/// } +/// \table_row3{ <b>`Player.HasVideo`</b>, +/// \anchor Player_HasVideo +/// _boolean_, +/// @return **True** if the player has a video file. +/// <p> +/// } +/// \table_row3{ <b>`Player.Paused`</b>, +/// \anchor Player_Paused +/// _boolean_, +/// @return **True** if the player is paused. +/// <p> +/// } +/// \table_row3{ <b>`Player.Playing`</b>, +/// \anchor Player_Playing +/// _boolean_, +/// @return **True** if the player is currently playing (i.e. not ffwding\, +/// rewinding or paused.) +/// <p> +/// } +/// \table_row3{ <b>`Player.Rewinding`</b>, +/// \anchor Player_Rewinding +/// _boolean_, +/// @return **True** if the player is rewinding. +/// <p> +/// } +/// \table_row3{ <b>`Player.Rewinding2x`</b>, +/// \anchor Player_Rewinding2x +/// _boolean_, +/// @return **True** if the player is rewinding at 2x. +/// <p> +/// } +/// \table_row3{ <b>`Player.Rewinding4x`</b>, +/// \anchor Player_Rewinding4x +/// _boolean_, +/// @return **True** if the player is rewinding at 4x. +/// <p> +/// } +/// \table_row3{ <b>`Player.Rewinding8x`</b>, +/// \anchor Player_Rewinding8x +/// _boolean_, +/// @return **True** if the player is rewinding at 8x. +/// <p> +/// } +/// \table_row3{ <b>`Player.Rewinding16x`</b>, +/// \anchor Player_Rewinding16x +/// _boolean_, +/// @return **True** if the player is rewinding at 16x. +/// <p> +/// } +/// \table_row3{ <b>`Player.Rewinding32x`</b>, +/// \anchor Player_Rewinding32x +/// _boolean_, +/// @return **True** if the player is rewinding at 32x. +/// <p> +/// } +/// \table_row3{ <b>`Player.Forwarding`</b>, +/// \anchor Player_Forwarding +/// _boolean_, +/// @return **True** if the player is fast forwarding. +/// <p> +/// } +/// \table_row3{ <b>`Player.Forwarding2x`</b>, +/// \anchor Player_Forwarding2x +/// _boolean_, +/// @return **True** if the player is fast forwarding at 2x. +/// <p> +/// } +/// \table_row3{ <b>`Player.Forwarding4x`</b>, +/// \anchor Player_Forwarding4x +/// _boolean_, +/// @return **True** if the player is fast forwarding at 4x. +/// <p> +/// } +/// \table_row3{ <b>`Player.Forwarding8x`</b>, +/// \anchor Player_Forwarding8x +/// _boolean_, +/// @return **True** if the player is fast forwarding at 8x. +/// <p> +/// } +/// \table_row3{ <b>`Player.Forwarding16x`</b>, +/// \anchor Player_Forwarding16x +/// _boolean_, +/// @return **True** if the player is fast forwarding at 16x. +/// <p> +/// } +/// \table_row3{ <b>`Player.Forwarding32x`</b>, +/// \anchor Player_Forwarding32x +/// _boolean_, +/// @return **True** if the player is fast forwarding at 32x. +/// <p> +/// } +/// \table_row3{ <b>`Player.Caching`</b>, +/// \anchor Player_Caching +/// _boolean_, +/// @return **True** if the player is current re-caching data (internet based +/// video playback). +/// <p> +/// } +/// \table_row3{ <b>`Player.DisplayAfterSeek`</b>, +/// \anchor Player_DisplayAfterSeek +/// _boolean_, +/// @return **True** for the first 2.5 seconds after a seek. +/// <p> +/// } +/// \table_row3{ <b>`Player.Seekbar`</b>, +/// \anchor Player_Seekbar +/// _integer_, +/// @return The percentage of one seek to other position. +/// <p> +/// } +/// \table_row3{ <b>`Player.Seeking`</b>, +/// \anchor Player_Seeking +/// _boolean_, +/// @return **True** if a seek is in progress. +/// <p> +/// } +/// \table_row3{ <b>`Player.ShowTime`</b>, +/// \anchor Player_ShowTime +/// _boolean_, +/// @return **True** if the user has requested the time to show (occurs in video +/// fullscreen). +/// <p> +/// } +/// \table_row3{ <b>`Player.ShowInfo`</b>, +/// \anchor Player_ShowInfo +/// _boolean_, +/// @return **True** if the user has requested the song info to show (occurs in +/// visualisation fullscreen and slideshow). +/// <p> +/// } +/// \table_row3{ <b>`Player.Title`</b>, +/// \anchor Player_Title +/// _string_, +/// @return The Musicplayer title for audio and the Videoplayer title for +/// video. +/// <p> +/// } +/// \table_row3{ <b>`Player.offset(number).Title`</b>, +/// \anchor Player_Offset_Title +/// _string_, +/// @return The title of audio or video which has an offset `number` with respect to the currently playing item. +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link Player_Offset_Title `Player.offset(number).Title`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Player.position(number).Title`</b>, +/// \anchor Player_Position_Title +/// _string_, +/// @return The title of the audio or video which has an offset `number` with respect to the start of the playlist. +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link Player_Position_Title `Player.position(number).Title`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Player.Muted`</b>, +/// \anchor Player_Muted +/// _boolean_, +/// @return **True** if the volume is muted. +/// <p> +/// } +/// \table_row3{ <b>`Player.HasDuration`</b>, +/// \anchor Player_HasDuration +/// _boolean_, +/// @return **True** if Media is not a true stream. +/// <p> +/// } +/// \table_row3{ <b>`Player.Passthrough`</b>, +/// \anchor Player_Passthrough +/// _boolean_, +/// @return **True** if the player is using audio passthrough. +/// <p> +/// } +/// \table_row3{ <b>`Player.CacheLevel`</b>, +/// \anchor Player_CacheLevel +/// _string_, +/// @return The used cache level as a string with an integer number. +/// <p> +/// } +/// \table_row3{ <b>`Player.Progress`</b>, +/// \anchor Player_Progress +/// _integer_ / _string_, +/// @return The progress position as percentage. +/// <p><hr> +/// @skinning_v19 \link Player_Progress `Player.Progress`\endlink infolabel +/// also exposed as a string. +/// <p> +/// } +/// \table_row3{ <b>`Player.ProgressCache`</b>, +/// \anchor Player_ProgressCache +/// _integer_ / _string_, +/// @return How much of the file is cached above current play percentage +/// <p><hr> +/// @skinning_v19 \link Player_ProgressCache `Player.ProgressCache`\endlink +/// infolabel also exposed as a string. +/// <p> +/// } +/// \table_row3{ <b>`Player.Volume`</b>, +/// \anchor Player_Volume +/// _string_, +/// @return The current player volume with the format `%2.1f` dB +/// <p> +/// } +/// \table_row3{ <b>`Player.SubtitleDelay`</b>, +/// \anchor Player_SubtitleDelay +/// _string_, +/// @return The used subtitle delay with the format `%2.3f` s +/// <p> +/// } +/// \table_row3{ <b>`Player.AudioDelay`</b>, +/// \anchor Player_AudioDelay +/// _string_, +/// @return The used audio delay with the format `%2.3f` s +/// <p> +/// } +/// \table_row3{ <b>`Player.Chapter`</b>, +/// \anchor Player_Chapter +/// _integer_, +/// @return The current chapter of current playing media. +/// <p> +/// } +/// \table_row3{ <b>`Player.ChapterCount`</b>, +/// \anchor Player_ChapterCount +/// _integer_, +/// @return The total number of chapters of current playing media. +/// <p> +/// } +/// \table_row3{ <b>`Player.ChapterName`</b>, +/// \anchor Player_ChapterName +/// _string_, +/// @return The name of currently used chapter if available. +/// <p> +/// } +/// \table_row3{ <b>`Player.Folderpath`</b>, +/// \anchor Player_Folderpath +/// _string_, +/// @return The full path of the currently playing song or movie +/// <p> +/// } +/// \table_row3{ <b>`Player.offset(number).Folderpath`</b>, +/// \anchor Player_Offset_Folderpath +/// _string_, +/// @return The full path of the audio or video file which has an offset `number` with respect to the currently playing item. +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link Player_Offset_Folderpath `Player.offset(number).Folderpath`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Player.position(number).Folderpath`</b>, +/// \anchor Player_Position_Folderpath +/// _string_, +/// @return The full path of the audio or video file which has an offset `number` with respect to the start of the playlist. +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link Player_Position_Folderpath `Player.position(number).Folderpath`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Player.FilenameAndPath`</b>, +/// \anchor Player_FilenameAndPath +/// _string_, +/// @return The full path with filename of the currently +/// playing song or movie +/// <p> +/// } +/// \table_row3{ <b>`Player.offset(number).FilenameAndPath`</b>, +/// \anchor Player_Offset_FilenameAndPath +/// _string_, +/// @return The full path with filename of audio or video file which has an offset `number` with respect to the currently playing item. +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link Player_Offset_FilenameAndPath `Player.offset(number).FilenameAndPath`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Player.position(number).FilenameAndPath`</b>, +/// \anchor Player_Position_FilenameAndPath +/// _string_, +/// @return The full path with filename of the audio or video file which has an offset `number` with respect to the start of the playlist. +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link Player_Position_FilenameAndPath `Player.position(number).FilenameAndPath`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Player.Filename`</b>, +/// \anchor Player_Filename +/// _string_, +/// @return The filename of the currently playing media. +/// <p><hr> +/// @skinning_v13 **[New Infolabel]** \link Player_Filename `Player.Filename`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Player.offset(number).Filename`</b>, +/// \anchor Player_Offset_Filename +/// _string_, +/// @return The filename of audio or video file which has an offset `number` with respect to the currently playing item. +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link Player_Offset_Filename `Player.offset(number).Filename`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Player.position(number).Filename`</b>, +/// \anchor Player_Position_Filename +/// _string_, +/// @return The filename of the audio or video file which has an offset `number` with respect to the start of the playlist. +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link Player_Position_Filename `Player.position(number).Filename`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Player.IsInternetStream`</b>, +/// \anchor Player_IsInternetStream +/// _boolean_, +/// @return **True** if the player is playing an internet stream. +/// <p> +/// } +/// \table_row3{ <b>`Player.PauseEnabled`</b>, +/// \anchor Player_PauseEnabled +/// _boolean_, +/// @return **True** if played stream is paused. +/// <p> +/// } +/// \table_row3{ <b>`Player.SeekEnabled`</b>, +/// \anchor Player_SeekEnabled +/// _boolean_, +/// @return **True** if seek on playing is enabled. +/// <p> +/// } +/// \table_row3{ <b>`Player.ChannelPreviewActive`</b>, +/// \anchor Player_ChannelPreviewActive +/// _boolean_, +/// @return **True** if PVR channel preview is active (used +/// channel tag different from played tag) +/// <p> +/// } +/// \table_row3{ <b>`Player.TempoEnabled`</b>, +/// \anchor Player_TempoEnabled +/// _boolean_, +/// @return **True** if player supports tempo (i.e. speed up/down normal +/// playback speed) +/// <p><hr> +/// @skinning_v17 **[New Boolean Condition]** \link Player_TempoEnabled `Player.TempoEnabled`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Player.IsTempo`</b>, +/// \anchor Player_IsTempo +/// _boolean_, +/// @return **True** if player has tempo (i.e. is playing with a playback speed higher or +/// lower than normal playback speed) +/// <p><hr> +/// @skinning_v17 **[New Boolean Condition]** \link Player_IsTempo `Player.IsTempo`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Player.PlaySpeed`</b>, +/// \anchor Player_PlaySpeed +/// _string_, +/// @return The player playback speed with the format `%1.2f` (1.00 means normal +/// playback speed). +/// @note For Tempo\, the default range is 0.80 - 1.50 (it can be changed +/// in advanced settings). If \ref Player_PlaySpeed "Player.PlaySpeed" returns a value different from 1.00 +/// and \ref Player_IsTempo "Player.IsTempo" is false it means the player is in ff/rw mode. +/// <p> +/// } +/// \table_row3{ <b>`Player.HasResolutions`</b>, +/// \anchor Player_HasResolutions +/// _boolean_, +/// @return **True** if the player is allowed to switch resolution and refresh rate +/// (i.e. if whitelist modes are configured in Kodi's System/Display settings) +/// <p><hr> +/// @skinning_v18 **[New Boolean Condition]** \link Player_HasResolutions `Player.HasResolutions`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Player.HasPrograms`</b>, +/// \anchor Player_HasPrograms +/// _boolean_, +/// @return **True** if the media file being played has programs\, i.e. groups of streams. +/// @note Ex: if a media file has multiple streams (quality\, channels\, etc) a program represents +/// a particular stream combo. +/// <p> +/// } +/// \table_row3{ <b>`Player.FrameAdvance`</b>, +/// \anchor Player_FrameAdvance +/// _boolean_, +/// @return **True** if player is in frame advance mode. +/// @note Skins should hide seek bar in this mode +/// <p><hr> +/// @skinning_v18 **[New Boolean Condition]** \link Player_FrameAdvance `Player.FrameAdvance`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Player.Icon`</b>, +/// \anchor Player_Icon +/// _string_, +/// @return The thumbnail of the currently playing item. If no thumbnail image exists\, +/// the icon will be returned\, if available. +/// <p><hr> +/// @skinning_v18 **[New Infolabel]** \link Player_Icon `Player.Icon`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Player.Cutlist`</b>, +/// \anchor Player_Cutlist +/// _string_, +/// @return The cutlist of the currently playing item as csv in the format start1\,end1\,start2\,end2\,... +/// Tokens must have values in the range from 0.0 to 100.0. end token must be less or equal than start token. +/// <p> +/// @deprecated \link Player_Cutlist `Player.Cutlist`\endlink is deprecated and will be removed in the next version. +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link Player_Cutlist `Player.Cutlist`\endlink +/// @skinning_v20 \link Player_Cutlist `Player.Cutlist`\endlink is deprecated\, use \link Player_Editlist `Player.Editlist`\endlink instead +/// <p> +/// } +/// \table_row3{ <b>`Player.Editlist`</b>, +/// \anchor Player_Editlist +/// _string_, +/// @return The editlist of the currently playing item as csv in the format start1\,end1\,start2\,end2\,... +/// Tokens must have values in the range from 0.0 to 100.0. end token must be less or equal than start token. +/// @note This infolabel does not contain EDL cuts. Edits start and end times are ajusted according to cuts +/// defined for the media item. +/// <p><hr> +/// @skinning_v20 **[New Infolabel]** \link Player_Editlist `Player.Editlist`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Player.Cuts`</b>, +/// \anchor Player_Cuts +/// _string_, +/// @return The EDL cut markers of the currently playing item as csv in the format start1\,end1\,start2\,end2\,... +/// Tokens must have values in the range from 0.0 to 100.0. end token must be less or equal than start token. +/// <p><hr> +/// @skinning_v20 **[New Infolabel]** \link Player_Cuts `Player.Cuts`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Player.SceneMarkers`</b>, +/// \anchor Player_SceneMarkers +/// _string_, +/// @return The EDL scene markers of the currently playing item as csv in the format start1\,end1\,start2\,end2\,... +/// Tokens must have values in the range from 0.0 to 100.0. end token must be less or equal than start token. +/// <p><hr> +/// @skinning_v20 **[New Infolabel]** \link Player_SceneMarkers `Player.SceneMarkers`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Player.HasSceneMarkers`</b>, +/// \anchor Player_HasSceneMarkers +/// _boolean_, +/// @return **True** if the item being played has scene markers\, **False** otherwise +/// <p><hr> +/// @skinning_v20 **[New Infolabel]** \link Player_HasSceneMarkers `Player.HasSceneMarkers`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Player.Chapters`</b>, +/// \anchor Player_Chapters +/// _string_, +/// @return The chapters of the currently playing item as csv in the format start1\,end1\,start2\,end2\,... +/// Tokens must have values in the range from 0.0 to 100.0. end token must be less or equal than start token. +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link Player_Chapters `Player.Chapters`\endlink +/// <p> +/// } +const infomap player_labels[] = {{"hasmedia", PLAYER_HAS_MEDIA}, + {"hasaudio", PLAYER_HAS_AUDIO}, + {"hasvideo", PLAYER_HAS_VIDEO}, + {"hasgame", PLAYER_HAS_GAME}, + {"playing", PLAYER_PLAYING}, + {"paused", PLAYER_PAUSED}, + {"rewinding", PLAYER_REWINDING}, + {"forwarding", PLAYER_FORWARDING}, + {"rewinding2x", PLAYER_REWINDING_2x}, + {"rewinding4x", PLAYER_REWINDING_4x}, + {"rewinding8x", PLAYER_REWINDING_8x}, + {"rewinding16x", PLAYER_REWINDING_16x}, + {"rewinding32x", PLAYER_REWINDING_32x}, + {"forwarding2x", PLAYER_FORWARDING_2x}, + {"forwarding4x", PLAYER_FORWARDING_4x}, + {"forwarding8x", PLAYER_FORWARDING_8x}, + {"forwarding16x", PLAYER_FORWARDING_16x}, + {"forwarding32x", PLAYER_FORWARDING_32x}, + {"caching", PLAYER_CACHING}, + {"seekbar", PLAYER_SEEKBAR}, + {"seeking", PLAYER_SEEKING}, + {"showtime", PLAYER_SHOWTIME}, + {"showinfo", PLAYER_SHOWINFO}, + {"muted", PLAYER_MUTED}, + {"hasduration", PLAYER_HASDURATION}, + {"passthrough", PLAYER_PASSTHROUGH}, + {"cachelevel", PLAYER_CACHELEVEL}, + {"title", PLAYER_TITLE}, + {"progress", PLAYER_PROGRESS}, + {"progresscache", PLAYER_PROGRESS_CACHE}, + {"volume", PLAYER_VOLUME}, + {"subtitledelay", PLAYER_SUBTITLE_DELAY}, + {"audiodelay", PLAYER_AUDIO_DELAY}, + {"chapter", PLAYER_CHAPTER}, + {"chaptercount", PLAYER_CHAPTERCOUNT}, + {"chaptername", PLAYER_CHAPTERNAME}, + {"folderpath", PLAYER_PATH}, + {"filenameandpath", PLAYER_FILEPATH}, + {"filename", PLAYER_FILENAME}, + {"isinternetstream", PLAYER_ISINTERNETSTREAM}, + {"pauseenabled", PLAYER_CAN_PAUSE}, + {"seekenabled", PLAYER_CAN_SEEK}, + {"channelpreviewactive", PLAYER_IS_CHANNEL_PREVIEW_ACTIVE}, + {"tempoenabled", PLAYER_SUPPORTS_TEMPO}, + {"istempo", PLAYER_IS_TEMPO}, + {"playspeed", PLAYER_PLAYSPEED}, + {"hasprograms", PLAYER_HAS_PROGRAMS}, + {"hasresolutions", PLAYER_HAS_RESOLUTIONS}, + {"frameadvance", PLAYER_FRAMEADVANCE}, + {"icon", PLAYER_ICON}, + {"cutlist", PLAYER_CUTLIST}, + {"editlist", PLAYER_EDITLIST}, + {"cuts", PLAYER_CUTS}, + {"scenemarkers", PLAYER_SCENE_MARKERS}, + {"hasscenemarkers", PLAYER_HAS_SCENE_MARKERS}, + {"chapters", PLAYER_CHAPTERS}}; + +/// \page modules__infolabels_boolean_conditions +/// \table_row3{ <b>`Player.Art(type)`</b>, +/// \anchor Player_Art_type +/// _string_, +/// @return The Image for the defined art type for the current playing ListItem. +/// @param type - The art type. The type is defined by scripts and scrappers and can have any value. +/// Common example values for type are: +/// - fanart +/// - thumb +/// - poster +/// - banner +/// - clearlogo +/// - tvshow.poster +/// - tvshow.banner +/// - etc +/// @todo get a way of centralize all random art strings used in core so we can point users to them +/// while still making it clear they can have any value. +/// <p> +/// } +/// \table_row3{ <b>`Player.HasPerformedSeek(interval)`</b>, +/// \anchor Player_HasPerformedSeek +/// _boolean_, +/// @return **True** if the Player has performed a seek operation in the last provided second `interval`\, **False** otherwise. +/// @param interval - the time interval (in seconds) +/// <p><hr> +/// @skinning_v20 **[New Boolean Condition]** \link Player_HasPerformedSeek `Player.HasPerformedSeek(interval)`\endlink +/// <p> +/// } + +const infomap player_param[] = {{"art", PLAYER_ITEM_ART}, + {"hasperformedseek", PLAYER_HASPERFORMEDSEEK}}; + +/// \page modules__infolabels_boolean_conditions +/// \table_row3{ <b>`Player.SeekTime`</b>, +/// \anchor Player_SeekTime +/// _string_, +/// @return The time to which the user is seeking. +/// <p> +/// } +/// \table_row3{ <b>`Player.SeekOffset([format])`</b>, +/// \anchor Player_SeekOffset_format +/// _string_, +/// @return The seek offset after a seek press in a given format. +/// @param format [opt] The format of the return time value. +/// See \ref TIME_FORMAT for the list of possible values. +/// <p> +/// @note **Example:** user presses BigStepForward\, player.seekoffset returns +10:00 +/// <p> +/// } +/// \table_row3{ <b>`Player.SeekStepSize`</b>, +/// \anchor Player_SeekStepSize +/// _string_, +/// @return The seek step size. +/// <p> +/// <hr> +/// @skinning_v15 **[New Infolabel]** \link Player_SeekStepSize `Player.SeekStepSize`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Player.TimeRemaining([format])`</b>, +/// \anchor Player_TimeRemaining_format +/// _string_, +/// @return The remaining time of current playing media in a given format. +/// @param format [opt] The format of the return time value. +/// See \ref TIME_FORMAT for the list of possible values. +/// <p> +/// } +/// \table_row3{ <b>`Player.TimeSpeed`</b>, +/// \anchor Player_TimeSpeed +/// _string_, +/// @return The time and the playspeed formatted: "1:23 (2x)". +/// <p> +/// } +/// \table_row3{ <b>`Player.Time([format])`</b>, +/// \anchor Player_Time_format +/// _string_, +/// @return The elapsed time of current playing media in a given format. +/// @param format [opt] The format of the return time value. +/// See \ref TIME_FORMAT for the list of possible values. +/// <p> +/// } +/// \table_row3{ <b>`Player.Duration([format])`</b>, +/// \anchor Player_Duration_format +/// _string_, +/// @return The total duration of the current playing media in a given format. +/// @param format [opt] The format of the return time value. +/// See \ref TIME_FORMAT for the list of possible values. +/// <p> +/// } +/// \table_row3{ <b>`Player.FinishTime([format])`</b>, +/// \anchor Player_FinishTime_format +/// _string_, +/// @return The time at which the playing media will end (in a specified format). +/// @param format [opt] The format of the return time value. +/// See \ref TIME_FORMAT for the list of possible values. +/// <p> +/// } +/// \table_row3{ <b>`Player.StartTime([format])`</b>, +/// \anchor Player_StartTime_format +/// _string_, +/// @return The time at which the playing media began (in a specified format). +/// @param format [opt] The format of the return time value. +/// See \ref TIME_FORMAT for the list of possible values. +/// <p> +/// } +/// \table_row3{ <b>`Player.SeekNumeric([format])`</b>, +/// \anchor Player_SeekNumeric_format +/// _string_, +/// @return The time at which the playing media began (in a specified format). +/// @param format [opt] The format of the return time value. +/// See \ref TIME_FORMAT for the list of possible values. +/// <p> +/// } +const infomap player_times[] = {{ "seektime", PLAYER_SEEKTIME }, + { "seekoffset", PLAYER_SEEKOFFSET }, + { "seekstepsize", PLAYER_SEEKSTEPSIZE }, + { "timeremaining", PLAYER_TIME_REMAINING }, + { "timespeed", PLAYER_TIME_SPEED }, + { "time", PLAYER_TIME }, + { "duration", PLAYER_DURATION }, + { "finishtime", PLAYER_FINISH_TIME }, + { "starttime", PLAYER_START_TIME }, + { "seeknumeric", PLAYER_SEEKNUMERIC } }; + + +/// \page modules__infolabels_boolean_conditions +/// \table_row3{ <b>`Player.Process(videohwdecoder)`</b>, +/// \anchor Player_Process_videohwdecoder +/// _boolean_, +/// @return **True** if the currently playing video is decoded in hardware. +/// <p><hr> +/// @skinning_v17 **[New Boolean Condition]** \link Player_Process_videohwdecoder `Player.Process(videohwdecoder)`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Player.Process(videodecoder)`</b>, +/// \anchor Player_Process_videodecoder +/// _string_, +/// @return The videodecoder name of the currently playing video. +/// <p><hr> +/// @skinning_v17 **[New Infolabel]** \link Player_Process_videodecoder `Player.Process(videodecoder)`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Player.Process(deintmethod)`</b>, +/// \anchor Player_Process_deintmethod +/// _string_, +/// @return The deinterlace method of the currently playing video. +/// <p><hr> +/// @skinning_v17 **[New Infolabel]** \link Player_Process_deintmethod `Player.Process(deintmethod)`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Player.Process(pixformat)`</b>, +/// \anchor Player_Process_pixformat +/// _string_, +/// @return The pixel format of the currently playing video. +/// <p><hr> +/// @skinning_v17 **[New Infolabel]** \link Player_Process_pixformat `Player.Process(pixformat)`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Player.Process(videowidth)`</b>, +/// \anchor Player_Process_videowidth +/// _string_, +/// @return The width of the currently playing video. +/// <p><hr> +/// @skinning_v17 **[New Infolabel]** \link Player_Process_videowidth `Player.Process(videowidth)`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Player.Process(videoheight)`</b>, +/// \anchor Player_Process_videoheight +/// _string_, +/// @return The width of the currently playing video. +/// <p><hr> +/// @skinning_v17 **[New Infolabel]** \link Player_Process_videoheight `Player.Process(videoheight)`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Player.Process(videoscantype)`</b>, +/// \anchor Player_Process_videoscantype +/// _string_, +/// @return The scan type identifier of the currently playing video **p** (for progressive) or **i** (for interlaced). +/// <p><hr> +/// @skinning_v20 **[New Infolabel]** \link Player_Process_videoscantype `Player.Process(videoscantype)`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Player.Process(videofps)`</b>, +/// \anchor Player_Process_videofps +/// _string_, +/// @return The video framerate of the currently playing video. +/// <p><hr> +/// @skinning_v17 **[New Infolabel]** \link Player_Process_videofps `Player.Process(videofps)`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Player.Process(videodar)`</b>, +/// \anchor Player_Process_videodar +/// _string_, +/// @return The display aspect ratio of the currently playing video. +/// <p><hr> +/// @skinning_v17 **[New Infolabel]** \link Player_Process_videodar `Player.Process(videodar)`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Player.Process(audiodecoder)`</b>, +/// \anchor Player_Process_audiodecoder +/// _string_, +/// @return The audiodecoder name of the currently playing item. +/// <p><hr> +/// @skinning_v17 **[New Infolabel]** \link Player_Process_videodar `Player.Process(audiodecoder)`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Player.Process(audiochannels)`</b>, +/// \anchor Player_Process_audiochannels +/// _string_, +/// @return The audiodecoder name of the currently playing item. +/// <p><hr> +/// @skinning_v17 **[New Infolabel]** \link Player_Process_audiochannels `Player.Process(audiochannels)`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Player.Process(audiosamplerate)`</b>, +/// \anchor Player_Process_audiosamplerate +/// _string_, +/// @return The samplerate of the currently playing item. +/// <p><hr> +/// @skinning_v17 **[New Infolabel]** \link Player_Process_audiosamplerate `Player.Process(audiosamplerate)`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Player.Process(audiobitspersample)`</b>, +/// \anchor Player_Process_audiobitspersample +/// _string_, +/// @return The bits per sample of the currently playing item. +/// <p><hr> +/// @skinning_v17 **[New Infolabel]** \link Player_Process_audiobitspersample `Player.Process(audiobitspersample)`\endlink +/// <p> +/// } +/// \table_end +/// +/// ----------------------------------------------------------------------------- + +const infomap player_process[] = {{"videodecoder", PLAYER_PROCESS_VIDEODECODER}, + {"deintmethod", PLAYER_PROCESS_DEINTMETHOD}, + {"pixformat", PLAYER_PROCESS_PIXELFORMAT}, + {"videowidth", PLAYER_PROCESS_VIDEOWIDTH}, + {"videoheight", PLAYER_PROCESS_VIDEOHEIGHT}, + {"videofps", PLAYER_PROCESS_VIDEOFPS}, + {"videodar", PLAYER_PROCESS_VIDEODAR}, + {"videohwdecoder", PLAYER_PROCESS_VIDEOHWDECODER}, + {"audiodecoder", PLAYER_PROCESS_AUDIODECODER}, + {"audiochannels", PLAYER_PROCESS_AUDIOCHANNELS}, + {"audiosamplerate", PLAYER_PROCESS_AUDIOSAMPLERATE}, + {"audiobitspersample", PLAYER_PROCESS_AUDIOBITSPERSAMPLE}, + {"videoscantype", PLAYER_PROCESS_VIDEOSCANTYPE}}; + +/// \page modules__infolabels_boolean_conditions +/// \subsection modules__infolabels_boolean_conditions_Weather Weather +/// \table_start +/// \table_h3{ Labels, Type, Description } +/// \table_row3{ <b>`Weather.IsFetched`</b>, +/// \anchor Weather_IsFetched +/// _boolean_, +/// @return **True** if the weather data has been downloaded. +/// <p> +/// } +/// \table_row3{ <b>`Weather.Conditions`</b>, +/// \anchor Weather_Conditions +/// _string_, +/// @return The current weather conditions as textual description. +/// @note This is looked up in a background process. +/// <p> +/// } +/// \table_row3{ <b>`Weather.ConditionsIcon`</b>, +/// \anchor Weather_ConditionsIcon +/// _string_, +/// @return The current weather conditions as an icon. +/// @note This is looked up in a background process. +/// <p> +/// } +/// \table_row3{ <b>`Weather.Temperature`</b>, +/// \anchor Weather_Temperature +/// _string_, +/// @return The current weather temperature. +/// <p> +/// } +/// \table_row3{ <b>`Weather.Location`</b>, +/// \anchor Weather_Location +/// _string_, +/// @return The city/town which the above two items are for. +/// <p> +/// } +/// \table_row3{ <b>`Weather.Fanartcode`</b>, +/// \anchor Weather_fanartcode +/// _string_, +/// @return The current weather fanartcode. +/// <p> +/// } +/// \table_row3{ <b>`Weather.Plugin`</b>, +/// \anchor Weather_plugin +/// _string_, +/// @return The current weather plugin. +/// <p> +/// } +/// \table_end +/// +/// ----------------------------------------------------------------------------- +const infomap weather[] = {{ "isfetched", WEATHER_IS_FETCHED }, + { "conditions", WEATHER_CONDITIONS_TEXT }, // labels from here + { "temperature", WEATHER_TEMPERATURE }, + { "location", WEATHER_LOCATION }, + { "fanartcode", WEATHER_FANART_CODE }, + { "plugin", WEATHER_PLUGIN }, + { "conditionsicon", WEATHER_CONDITIONS_ICON }}; + +/// \page modules__infolabels_boolean_conditions +/// \subsection modules__infolabels_boolean_conditions_System System +/// @todo some values are hardcoded in the middle of the code - refactor to make it easier to track +/// \table_start +/// \table_h3{ Labels, Type, Description } +/// \table_row3{ <b>`System.AlarmLessOrEqual(alarmname\,seconds)`</b>, +/// \anchor System_AlarmLessOrEqual +/// _boolean_, +/// @return **True** if the alarm with `alarmname` has less or equal to `seconds` left. +/// @param alarmname - The name of the alarm. It can be one of the following: +/// - shutdowntimer +/// @param seconds - Time in seconds to compare with the alarm trigger event +/// @note **Example:** `System.Alarmlessorequal(shutdowntimer\,119)`\, +/// will return true when the shutdowntimer has less then 2 minutes +/// left. +/// <p> +/// } +/// \table_row3{ <b>`System.HasNetwork`</b>, +/// \anchor System_HasNetwork +/// _boolean_, +/// @return **True** if the Kodi host has a network available. +/// <p> +/// } +/// \table_row3{ <b>`System.HasMediadvd`</b>, +/// \anchor System_HasMediadvd +/// _boolean_, +/// @return **True** if there is a CD or DVD in the DVD-ROM drive. +/// <p> +/// } +/// \table_row3{ <b>`System.HasMediaAudioCD`</b>, +/// \anchor System_HasMediaAudioCD +/// _boolean_, +/// @return **True** if there is an audio CD in the optical drive. **False** if no drive +/// available\, empty drive or other medium. +/// <p><hr> +/// @skinning_v18 **[New Boolean Condition]** \link System_HasMediaAudioCD +/// `System.HasMediaAudioCD` \endlink <p> +/// } +/// \table_row3{ <b>`System.DVDReady`</b>, +/// \anchor System_DVDReady +/// _boolean_, +/// @return **True** if the disc is ready to use. +/// <p> +/// } +/// \table_row3{ <b>`System.TrayOpen`</b>, +/// \anchor System_TrayOpen +/// _boolean_, +/// @return **True** if the disc tray is open. +/// <p> +/// } +/// \table_row3{ <b>`System.HasLocks`</b>, +/// \anchor System_HasLocks +/// _boolean_, +/// @return **True** if the system has an active lock mode. +/// <p> +/// } +/// \table_row3{ <b>`System.IsMaster`</b>, +/// \anchor System_IsMaster +/// _boolean_, +/// @return **True** if the system is in master mode. +/// <p> +/// } +/// \table_row3{ <b>`System.ShowExitButton`</b>, +/// \anchor System_ShowExitButton +/// _boolean_, +/// @return **True** if the exit button should be shown (configurable via advanced settings). +/// <p> +/// } +/// \table_row3{ <b>`System.DPMSActive`</b>, +/// \anchor System_DPMSActive +/// _boolean_, +/// @return **True** if DPMS (VESA Display Power Management Signaling) mode is active. +/// <p> +/// } +/// \table_row3{ <b>`System.IsStandalone`</b>, +/// \anchor System_IsStandalone +/// _boolean_, +/// @return **True** if Kodi is running in standalone mode. +/// <p> +/// } +/// \table_row3{ <b>`System.IsFullscreen`</b>, +/// \anchor System_IsFullscreen +/// _boolean_, +/// @return **True** if Kodi is running fullscreen. +/// <p> +/// } +/// \table_row3{ <b>`System.LoggedOn`</b>, +/// \anchor System_LoggedOn +/// _boolean_, +/// @return **True** if a user is currently logged on under a profile. +/// <p> +/// } +/// \table_row3{ <b>`System.HasLoginScreen`</b>, +/// \anchor System_HasLoginScreen +/// _boolean_, +/// @return **True** if the profile login screen is enabled. +/// <p> +/// } +/// \table_row3{ <b>`System.HasPVR`</b>, +/// \anchor System_HasPVR +/// _boolean_, +/// @return **True** if PVR is supported from Kodi. +/// @note normally always true +/// +/// } +/// \table_row3{ <b>`System.HasPVRAddon`</b>, +/// \anchor System_HasPVRAddon +/// _boolean_, +/// @return **True** if at least one pvr client addon is installed and enabled. +/// @param id - addon id of the PVR addon +/// <p><hr> +/// @skinning_v17 **[New Boolean Condition]** \link System_HasPVRAddon +/// `System.HasPVRAddon`\endlink <p> +/// } +/// \table_row3{ <b>`System.HasCMS`</b>, +/// \anchor System_HasCMS +/// _boolean_, +/// @return **True** if colour management is supported from Kodi. +/// @note currently only supported for OpenGL +/// <p><hr> +/// @skinning_v17 **[New Boolean Condition]** \link System_HasCMS `System.HasCMS`\endlink +/// <p> +/// } +/// \table_row3{ <b>`System.HasActiveModalDialog`</b>, +/// \anchor System_HasActiveModalDialog +/// _boolean_, +/// @return **True** if a modal dialog is active. +/// <p><hr> +/// @skinning_v18 **[New Boolean Condition]** \link System_HasActiveModalDialog +/// `System.HasActiveModalDialog`\endlink <p> +/// } +/// \table_row3{ <b>`System.HasVisibleModalDialog`</b>, +/// \anchor System_HasVisibleModalDialog +/// _boolean_, +/// @return **True** if a modal dialog is visible. +/// <p><hr> +/// @skinning_v18 **[New Boolean Condition]** \link System_HasVisibleModalDialog +/// `System.HasVisibleModalDialog`\endlink <p> +/// } +/// \table_row3{ <b>`System.Platform.Linux`</b>, +/// \anchor System_PlatformLinux +/// _boolean_, +/// @return **True** if Kodi is running on a linux/unix based computer. +/// <p> +/// } +/// \table_row3{ <b>`System.Platform.Windows`</b>, +/// \anchor System_PlatformWindows +/// _boolean_, +/// @return **True** if Kodi is running on a windows based computer. +/// <p> +/// } +/// \table_row3{ <b>`System.Platform.UWP`</b>, +/// \anchor System_PlatformUWP +/// _boolean_, +/// @return **True** if Kodi is running on Universal Windows Platform (UWP). +/// <p><hr> +/// @skinning_v18 **[New Boolean Condition]** \link System_PlatformUWP +/// `System.Platform.UWP`\endlink <p> +/// } +/// \table_row3{ <b>`System.Platform.OSX`</b>, +/// \anchor System_PlatformOSX +/// _boolean_, +/// @return **True** if Kodi is running on an OSX based computer. +/// <p> +/// } +/// \table_row3{ <b>`System.Platform.IOS`</b>, +/// \anchor System_PlatformIOS +/// _boolean_, +/// @return **True** if Kodi is running on an IOS device. +/// <p> +/// } +/// \table_row3{ <b>`System.Platform.TVOS`</b>, +/// \anchor System_PlatformTVOS +/// _boolean_, +/// @return **True** if Kodi is running on a tvOS device. +/// <p><hr> +/// @skinning_v19 **[New Boolean Condition]** \link System_PlatformTVOS +/// `System.Platform.TVOS`\endlink <p> +/// } +/// \table_row3{ <b>`System.Platform.Darwin`</b>, +/// \anchor System_PlatformDarwin +/// _boolean_, +/// @return **True** if Kodi is running on an OSX or IOS system. +/// <p> +/// } +/// \table_row3{ <b>`System.Platform.Android`</b>, +/// \anchor System_PlatformAndroid +/// _boolean_, +/// @return **True** if Kodi is running on an android device. +/// <p> +/// } +/// \table_row3{ <b>`System.CanPowerDown`</b>, +/// \anchor System_CanPowerDown +/// _boolean_, +/// @return **True** if Kodi can powerdown the system. +/// <p> +/// } +/// \table_row3{ <b>`System.CanSuspend`</b>, +/// \anchor System_CanSuspend +/// _boolean_, +/// @return **True** if Kodi can suspend the system. +/// <p> +/// } +/// \table_row3{ <b>`System.CanHibernate`</b>, +/// \anchor System_CanHibernate +/// _boolean_, +/// @return **True** if Kodi can hibernate the system. +/// <p> +/// } +/// \table_row3{ <b>`System.HasHiddenInput`</b>, +/// \anchor System_HasHiddenInput +/// _boolean_, +/// @return **True** when to osd keyboard/numeric dialog requests a +/// password/pincode. +/// <p><hr> +/// @skinning_v16 **[New Boolean Condition]** \link System_HasHiddenInput +/// `System.HasHiddenInput`\endlink <p> +/// } +/// \table_row3{ <b>`System.CanReboot`</b>, +/// \anchor System_CanReboot +/// _boolean_, +/// @return **True** if Kodi can reboot the system. +/// <p> +/// } +/// \table_row3{ <b>`System.ScreenSaverActive`</b>, +/// \anchor System_ScreenSaverActive +/// _boolean_, +/// @return **True** if ScreenSaver is active. +/// <p> +/// } +/// \table_row3{ <b>`System.IdleShutdownInhibited`</b>, +/// \anchor System_IdleShutdownInhibited +/// _boolean_, +/// @return **True** when shutdown on idle is disabled. +/// <p> +/// } +/// \table_row3{ <b>`System.HasShutdown`</b>, +/// \anchor System_HasShutdown +/// _boolean_, +/// @return **True** if Kodi can shutdown the system. +/// <p> +/// } +/// \table_row3{ <b>`System.Time`</b>, +/// \anchor System_Time +/// _string_, +/// @return The current time. +/// <p> +/// } +/// \table_row3{ <b>`System.Time(format)`</b>, +/// \anchor System_Time_format +/// _string_, +/// @return The current time in a specified format. +/// @param format [opt] The format of the return time value. +/// See \ref TIME_FORMAT for the list of possible values. +/// <p> +/// } +/// \table_row3{ <b>`System.Time(startTime[\,endTime])`</b>, +/// \anchor System_Time +/// _boolean_, +/// @return **True** if the current system time is >= `startTime` and < `endTime` (if defined). +/// @param startTime - Start time +/// @param endTime - [opt] End time +/// <p> +/// @note Time must be specified in the format HH:mm\, using +/// a 24 hour clock. +/// <p> +/// } +/// \table_row3{ <b>`System.Date`</b>, +/// \anchor System_Date +/// _string_, +/// @return The current date. +/// <p><hr> +/// @skinning_v16 **[Infolabel Updated]** \link System_Date `System.Date`\endlink +/// will now return the full day and month names. old: sat\, jul 18 2015 +/// new: saturday\, july 18 2015 +/// <p> +/// } +/// \table_row3{ <b>`System.Date(format)`</b>, +/// \anchor System_Date_format +/// _string_, +/// @return The current date using a specified format. +/// @param format - the format for the date. It can be one of the following +/// values: +/// - **d** - day of month (1-31) +/// - **dd** - day of month (01-31) +/// - **ddd** - short day of the week Mon-Sun +/// - **DDD** - long day of the week Monday-Sunday +/// - **m** - month (1-12) +/// - **mm** - month (01-12) +/// - **mmm** - short month name Jan-Dec +/// - **MMM** - long month name January-December +/// - **yy** - 2-digit year +/// - **yyyy** - 4-digit year +/// <p> +/// } +/// \table_row3{ <b>`System.Date(startDate[\,endDate])`</b>, +/// \anchor System_Date +/// _boolean_, +/// @return **True** if the current system date is >= `startDate` and < `endDate` (if defined). +/// @param startDate - The start date +/// @param endDate - [opt] The end date +/// @note Date must be specified in the format MM-DD or YY-MM-DD. +/// <p> +/// } +/// \table_row3{ <b>`System.AlarmPos`</b>, +/// \anchor System_AlarmPos +/// _string_, +/// @return The shutdown Timer position. +/// <p> +/// } +/// \table_row3{ <b>`System.BatteryLevel`</b>, +/// \anchor System_BatteryLevel +/// _string_, +/// @return The remaining battery level in range 0-100. +/// <p> +/// } +/// \table_row3{ <b>`System.FreeSpace`</b>, +/// \anchor System_FreeSpace +/// _string_, +/// @return The total Freespace on the drive. +/// <p> +/// } +/// \table_row3{ <b>`System.UsedSpace`</b>, +/// \anchor System_UsedSpace +/// _string_, +/// @return The total Usedspace on the drive. +/// <p> +/// } +/// \table_row3{ <b>`System.TotalSpace`</b>, +/// \anchor System_TotalSpace +/// _string_, +/// @return The total space on the drive. +/// <p> +/// } +/// \table_row3{ <b>`System.UsedSpacePercent`</b>, +/// \anchor System_UsedSpacePercent +/// _string_, +/// @return The total Usedspace Percent on the drive. +/// <p> +/// } +/// \table_row3{ <b>`System.FreeSpacePercent`</b>, +/// \anchor System_FreeSpacePercent +/// _string_, +/// @return The total Freespace Percent on the drive. +/// <p> +/// } +/// \table_row3{ <b>`System.CPUTemperature`</b>, +/// \anchor System_CPUTemperature +/// _string_, +/// @return The current CPU temperature. +/// <p> +/// } +/// \table_row3{ <b>`System.CpuUsage`</b>, +/// \anchor System_CpuUsage +/// _string_, +/// @return The the cpu usage for each individual cpu core. +/// <p> +/// } +/// \table_row3{ <b>`System.GPUTemperature`</b>, +/// \anchor System_GPUTemperature +/// _string_, +/// @return The current GPU temperature. +/// <p> +/// } +/// \table_row3{ <b>`System.FanSpeed`</b>, +/// \anchor System_FanSpeed +/// _string_, +/// @return The current fan speed. +/// <p> +/// } +/// \table_row3{ <b>`System.BuildVersion`</b>, +/// \anchor System_BuildVersion +/// _string_, +/// @return The version of build. +/// <p> +/// } +/// \table_row3{ <b>`System.BuildVersionShort`</b>, +/// \anchor System_BuildVersionShort +/// _string_, +/// @return The shorter string with version of build. +/// <p> +/// } +/// \table_row3{ <b>`System.BuildDate`</b>, +/// \anchor System_BuildDate +/// _string_, +/// @return The date of build. +/// <p> +/// } +/// \table_row3{ <b>`System.BuildVersionCode`</b>, +/// \anchor System_BuildVersionCode +/// _string_, +/// @return The version code of build. +/// <p> +/// } +/// \table_row3{ <b>`System.BuildVersionGit`</b>, +/// \anchor System_BuildVersionGit +/// _string_, +/// @return The git version of build. +/// <p> +/// } +/// \table_row3{ <b>`System.FriendlyName`</b>, +/// \anchor System_FriendlyName +/// _string_, +/// @return The Kodi instance name. +/// @note It will auto append (%hostname%) in case +/// the device name was not changed. eg. "Kodi (htpc)" +/// <p> +/// } +/// \table_row3{ <b>`System.FPS`</b>, +/// \anchor System_FPS +/// _string_, +/// @return The current rendering speed (frames per second). +/// <p> +/// } +/// \table_row3{ <b>`System.FreeMemory`</b>, +/// \anchor System_FreeMemory +/// _string_, +/// @return The amount of free memory in Mb. +/// <p> +/// } +/// \table_row3{ <b>`System.ScreenMode`</b>, +/// \anchor System_ScreenMode +/// _string_, +/// @return The screenmode (eg windowed / fullscreen). +/// <p> +/// } +/// \table_row3{ <b>`System.ScreenWidth`</b>, +/// \anchor System_ScreenWidth +/// _string_, +/// @return The width of screen in pixels. +/// <p> +/// } +/// \table_row3{ <b>`System.ScreenHeight`</b>, +/// \anchor System_ScreenHeight +/// _string_, +/// @return The height of screen in pixels. +/// <p> +/// } +/// \table_row3{ <b>`System.StartupWindow`</b>, +/// \anchor System_StartupWindow +/// _string_, +/// @return The Window Kodi will load on startup. +/// <p><hr> +/// @skinning_v13 **[New Infolabel]** \link System_StartupWindow `System.StartupWindow`\endlink +/// <p> +/// } +/// \table_row3{ <b>`System.CurrentWindow`</b>, +/// \anchor System_CurrentWindow +/// _string_, +/// @return The current Window in use. +/// <p> +/// } +/// \table_row3{ <b>`System.CurrentControl`</b>, +/// \anchor System_CurrentControl +/// _string_, +/// @return The current focused control +/// <p> +/// } +/// \table_row3{ <b>`System.CurrentControlId`</b>, +/// \anchor System_CurrentControlId +/// _string_, +/// @return The ID of the currently focused control. +/// <p> +/// } +/// \table_row3{ <b>`System.DVDLabel`</b>, +/// \anchor System_DVDLabel +/// _string_, +/// @return the label of the disk in the DVD-ROM drive. +/// <p> +/// } +/// \table_row3{ <b>`System.KernelVersion`</b>, +/// \anchor System_KernelVersion +/// _string_, +/// @return The System kernel version. +/// <p> +/// } +/// \table_row3{ <b>`System.OSVersionInfo`</b>, +/// \anchor System_OSVersionInfo +/// _string_, +/// @return The system name + kernel version. +/// <p> +/// } +/// \table_row3{ <b>`System.Uptime`</b>, +/// \anchor System_Uptime +/// _string_, +/// @return The system current uptime. +/// <p> +/// } +/// \table_row3{ <b>`System.TotalUptime`</b>, +/// \anchor System_TotalUptime +/// _string_, +/// @return The system total uptime. +/// <p> +/// } +/// \table_row3{ <b>`System.CpuFrequency`</b>, +/// \anchor System_CpuFrequency +/// _string_, +/// @return The system cpu frequency. +/// <p> +/// } +/// \table_row3{ <b>`System.ScreenResolution`</b>, +/// \anchor System_ScreenResolution +/// _string_, +/// @return The screen resolution. +/// <p> +/// } +/// \table_row3{ <b>`System.VideoEncoderInfo`</b>, +/// \anchor System_VideoEncoderInfo +/// _string_, +/// @return The video encoder info. +/// <p> +/// } +/// \table_row3{ <b>`System.InternetState`</b>, +/// \anchor System_InternetState +/// _string_, +/// @return The internet state: connected or not connected. +/// @warning Do not use to check status in a pythonscript since it is threaded. +/// <p> +/// } +/// \table_row3{ <b>`System.Language`</b>, +/// \anchor System_Language +/// _string_, +/// @return the current language. +/// <p> +/// } +/// \table_row3{ <b>`System.ProfileName`</b>, +/// \anchor System_ProfileName +/// _string_, +/// @return The user name of the currently logged in Kodi user +/// <p> +/// } +/// \table_row3{ <b>`System.ProfileThumb`</b>, +/// \anchor System_ProfileThumb +/// _string_, +/// @return The thumbnail image of the currently logged in Kodi user +/// <p> +/// } +/// \table_row3{ <b>`System.ProfileCount`</b>, +/// \anchor System_ProfileCount +/// _string_, +/// @return The number of defined profiles. +/// <p> +/// } +/// \table_row3{ <b>`System.ProfileAutoLogin`</b>, +/// \anchor System_ProfileAutoLogin +/// _string_, +/// @return The profile Kodi will auto login to. +/// <p><hr> +/// @skinning_v13 **[New Infolabel]** \link System_ProfileAutoLogin +/// `System.ProfileAutoLogin`\endlink <p> +/// } +/// \table_row3{ <b>`System.StereoscopicMode`</b>, +/// \anchor System_StereoscopicMode +/// _string_, +/// @return The preferred stereoscopic mode. +/// @note Configured in settings > video > playback). +/// <p><hr> +/// @skinning_v13 **[New Infolabel]** \link System_StereoscopicMode +/// `System.StereoscopicMode`\endlink <p> +/// } +/// \table_row3{ <b>`System.TemperatureUnits`</b>, +/// \anchor System_TemperatureUnits +/// _string_, +/// @return the Celsius or the Fahrenheit symbol. +/// <p> +/// } +/// \table_row3{ <b>`System.Progressbar`</b>, +/// \anchor System_Progressbar +/// _string_, +/// @return The percentage of the currently active progress. +/// <p> +/// } +/// \table_row3{ <b>`System.GetBool(boolean)`</b>, +/// \anchor System_GetBool +/// _string_, +/// @return The value of any standard system boolean setting. +/// @note Will not work with settings in advancedsettings.xml +/// <p> +/// } +/// \table_row3{ <b>`System.Memory(type)`</b>, +/// \anchor System_Memory +/// _string_, +/// @return The memory value depending on the requested type. +/// @param type - Can be one of the following: +/// - <b>free</b> +/// - <b>free.percent</b> +/// - <b>used</b> +/// - <b>used.percent</b> +/// - <b>total</b> +/// <p> +/// } +/// \table_row3{ <b>`System.AddonTitle(id)`</b>, +/// \anchor System_AddonTitle +/// _string_, +/// @return The title of the addon with the given id +/// @param id - the addon id +/// <p> +/// } +/// \table_row3{ <b>`System.AddonVersion(id)`</b>, +/// \anchor System_AddonVersion +/// _string_, +/// @return The version of the addon with the given id. +/// @param id - the addon id +/// <p><hr> +/// @skinning_v13 **[New Infolabel]** \link System_AddonVersion +/// `System.AddonVersion(id)`\endlink <p> +/// } +/// \table_row3{ <b>`System.AddonIcon(id)`</b>, +/// \anchor System_AddonVersion +/// _string_, +/// @return The icon of the addon with the given id. +/// @param id - the addon id +/// <p> +/// } +/// \table_row3{ <b>`System.AddonUpdateCount`</b>, +/// \anchor System_AddonUpdateCount +/// _string_, +/// @return The number of available addon updates. +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link System_AddonUpdateCount ` +/// System.AddonUpdateCount`\endlink <p> +/// } +/// \table_row3{ <b>`System.IdleTime(time)`</b>, +/// \anchor System_IdleTime +/// _boolean_, +/// @return **True** if Kodi has had no input for `time` amount of seconds. +/// @param time - elapsed seconds to check for idle activity. +/// <p> +/// } +/// \table_row3{ <b>`System.PrivacyPolicy`</b>, +/// \anchor System_PrivacyPolicy +/// _string_, +/// @return The official Kodi privacy policy. +/// <p><hr> +/// @skinning_v17 **[New Infolabel]** \link System_PrivacyPolicy `System.PrivacyPolicy`\endlink +/// <p> +/// } +/// \table_row3{ <b>`System.SupportsCPUUsage`</b>, +/// \anchor System_SupportsCPUUsage +/// _boolean_, +/// @return **True** if the system can provide CPU usage information. +/// <p><hr> +/// @skinning_v19 **[New Boolean Condition]** \link System_SupportsCPUUsage ` +/// System.SupportsCPUUsage`\endlink <p> +/// } +/// \table_row3{ <b>`System.SupportedHDRTypes`</b>, +/// \anchor System_SupportedHDRTypes +/// _string_, +/// @return The display's supported HDR types. +/// <p><hr> +/// @skinning_v20 **[New Infolabel]** \link System_SupportedHDRTypes `System.SupportedHDRTypes`\endlink +/// <p> +/// } +/// \table_row3{ <b>`System.IsScreensaverInhibited`</b>, +/// \anchor System_IsScreensaverInhibited +/// _boolean_, +/// @return **True** when screensaver on idle is disabled. +/// <p> +/// } +const infomap system_labels[] = { + {"hasnetwork", SYSTEM_ETHERNET_LINK_ACTIVE}, + {"hasmediadvd", SYSTEM_MEDIA_DVD}, + {"hasmediaaudiocd", SYSTEM_MEDIA_AUDIO_CD}, + {"dvdready", SYSTEM_DVDREADY}, + {"trayopen", SYSTEM_TRAYOPEN}, + {"haslocks", SYSTEM_HASLOCKS}, + {"hashiddeninput", SYSTEM_HAS_INPUT_HIDDEN}, + {"hasloginscreen", SYSTEM_HAS_LOGINSCREEN}, + {"hasactivemodaldialog", SYSTEM_HAS_ACTIVE_MODAL_DIALOG}, + {"hasvisiblemodaldialog", SYSTEM_HAS_VISIBLE_MODAL_DIALOG}, + {"ismaster", SYSTEM_ISMASTER}, + {"isfullscreen", SYSTEM_ISFULLSCREEN}, + {"isstandalone", SYSTEM_ISSTANDALONE}, + {"loggedon", SYSTEM_LOGGEDON}, + {"showexitbutton", SYSTEM_SHOW_EXIT_BUTTON}, + {"canpowerdown", SYSTEM_CAN_POWERDOWN}, + {"cansuspend", SYSTEM_CAN_SUSPEND}, + {"canhibernate", SYSTEM_CAN_HIBERNATE}, + {"canreboot", SYSTEM_CAN_REBOOT}, + {"screensaveractive", SYSTEM_SCREENSAVER_ACTIVE}, + {"dpmsactive", SYSTEM_DPMS_ACTIVE}, + {"cputemperature", SYSTEM_CPU_TEMPERATURE}, // labels from here + {"cpuusage", SYSTEM_CPU_USAGE}, + {"gputemperature", SYSTEM_GPU_TEMPERATURE}, + {"fanspeed", SYSTEM_FAN_SPEED}, + {"freespace", SYSTEM_FREE_SPACE}, + {"usedspace", SYSTEM_USED_SPACE}, + {"totalspace", SYSTEM_TOTAL_SPACE}, + {"usedspacepercent", SYSTEM_USED_SPACE_PERCENT}, + {"freespacepercent", SYSTEM_FREE_SPACE_PERCENT}, + {"buildversion", SYSTEM_BUILD_VERSION}, + {"buildversionshort", SYSTEM_BUILD_VERSION_SHORT}, + {"buildversioncode", SYSTEM_BUILD_VERSION_CODE}, + {"buildversiongit", SYSTEM_BUILD_VERSION_GIT}, + {"builddate", SYSTEM_BUILD_DATE}, + {"fps", SYSTEM_FPS}, + {"freememory", SYSTEM_FREE_MEMORY}, + {"language", SYSTEM_LANGUAGE}, + {"temperatureunits", SYSTEM_TEMPERATURE_UNITS}, + {"screenmode", SYSTEM_SCREEN_MODE}, + {"screenwidth", SYSTEM_SCREEN_WIDTH}, + {"screenheight", SYSTEM_SCREEN_HEIGHT}, + {"currentwindow", SYSTEM_CURRENT_WINDOW}, + {"currentcontrol", SYSTEM_CURRENT_CONTROL}, + {"currentcontrolid", SYSTEM_CURRENT_CONTROL_ID}, + {"dvdlabel", SYSTEM_DVD_LABEL}, + {"internetstate", SYSTEM_INTERNET_STATE}, + {"osversioninfo", SYSTEM_OS_VERSION_INFO}, + {"kernelversion", SYSTEM_OS_VERSION_INFO}, // old, not correct name + {"uptime", SYSTEM_UPTIME}, + {"totaluptime", SYSTEM_TOTALUPTIME}, + {"cpufrequency", SYSTEM_CPUFREQUENCY}, + {"screenresolution", SYSTEM_SCREEN_RESOLUTION}, + {"videoencoderinfo", SYSTEM_VIDEO_ENCODER_INFO}, + {"profilename", SYSTEM_PROFILENAME}, + {"profilethumb", SYSTEM_PROFILETHUMB}, + {"profilecount", SYSTEM_PROFILECOUNT}, + {"profileautologin", SYSTEM_PROFILEAUTOLOGIN}, + {"progressbar", SYSTEM_PROGRESS_BAR}, + {"batterylevel", SYSTEM_BATTERY_LEVEL}, + {"friendlyname", SYSTEM_FRIENDLY_NAME}, + {"alarmpos", SYSTEM_ALARM_POS}, + {"isinhibit", + SYSTEM_IDLE_SHUTDOWN_INHIBITED}, // Deprecated, replaced by "idleshutdowninhibited" + {"idleshutdowninhibited", SYSTEM_IDLE_SHUTDOWN_INHIBITED}, + {"hasshutdown", SYSTEM_HAS_SHUTDOWN}, + {"haspvr", SYSTEM_HAS_PVR}, + {"startupwindow", SYSTEM_STARTUP_WINDOW}, + {"stereoscopicmode", SYSTEM_STEREOSCOPIC_MODE}, + {"hascms", SYSTEM_HAS_CMS}, + {"privacypolicy", SYSTEM_PRIVACY_POLICY}, + {"haspvraddon", SYSTEM_HAS_PVR_ADDON}, + {"addonupdatecount", SYSTEM_ADDON_UPDATE_COUNT}, + {"supportscpuusage", SYSTEM_SUPPORTS_CPU_USAGE}, + {"supportedhdrtypes", SYSTEM_SUPPORTED_HDR_TYPES}, + {"isscreensaverinhibited", SYSTEM_IS_SCREENSAVER_INHIBITED}}; + +/// \page modules__infolabels_boolean_conditions +/// \table_row3{ <b>`System.HasAddon(id)`</b>, +/// \anchor System_HasAddon +/// _boolean_, +/// @return **True** if the specified addon is installed on the system. +/// @param id - the addon id +/// @skinning_v19 **[Boolean Condition Updated]** \link System_HasAddon `System.HasAddon(id)`\endlink +/// <p> +/// } +/// \table_row3{ <b>`System.AddonIsEnabled(id)`</b>, +/// \anchor System_AddonIsEnabled +/// _boolean_, +/// @return **True** if the specified addon is enabled on the system. +/// @param id - The addon Id +/// <p><hr> +/// @skinning_v19 **[New Boolean Condition]** \link System_AddonIsEnabled `System.AddonIsEnabled(id)`\endlink +/// <p> +/// } +/// \table_row3{ <b>`System.HasCoreId(id)`</b>, +/// \anchor System_HasCoreId +/// _boolean_, +/// @return **True** if the CPU core with the given 'id' exists. +/// @param id - the id of the CPU core +/// <p> +/// } +/// \table_row3{ <b>`System.HasAlarm(alarm)`</b>, +/// \anchor System_HasAlarm +/// _boolean_, +/// @return **True** if the system has the `alarm` alarm set. +/// @param alarm - the name of the alarm +/// <p> +/// } +/// \table_row3{ <b>`System.CoreUsage(id)`</b>, +/// \anchor System_CoreUsage +/// _string_, +/// @return the usage of the CPU core with the given 'id' +/// @param id - the id of the CPU core +/// <p> +/// } +/// \table_row3{ <b>`System.Setting(hidewatched)`</b>, +/// \anchor System_Setting +/// _boolean_, +/// @return **True** if 'hide watched items' is selected. +/// <p> +/// } +/// \table_row3{ <b>`System.Setting(hideunwatchedepisodethumbs)`</b>, +/// \anchor System_Setting_HideUnwatchedEpisodeThumbs +/// _boolean_, +/// @return **True** if 'hide unwatched episode setting is enabled'\, **False** otherwise. +/// <p><hr> +/// @skinning_v20 **[New Boolean Condition]** \link System_Setting_HideUnwatchedEpisodeThumbs `System.Setting(hideunwatchedepisodethumbs)`\endlink +/// <p> +/// } +/// \table_end +/// +/// ----------------------------------------------------------------------------- +const infomap system_param[] = {{ "hasalarm", SYSTEM_HAS_ALARM }, + { "hascoreid", SYSTEM_HAS_CORE_ID }, + { "setting", SYSTEM_SETTING }, + { "hasaddon", SYSTEM_HAS_ADDON }, + { "addonisenabled", SYSTEM_ADDON_IS_ENABLED }, + { "coreusage", SYSTEM_GET_CORE_USAGE }}; + +/// \page modules__infolabels_boolean_conditions +/// \subsection modules__infolabels_boolean_conditions_Network Network +/// \table_start +/// \table_h3{ Labels, Type, Description } +/// \table_row3{ <b>`Network.IsDHCP`</b>, +/// \anchor Network_IsDHCP +/// _boolean_, +/// @return **True** if the network type is DHCP. +/// @note Network type can be either DHCP or FIXED +/// <p> +/// } +/// \table_row3{ <b>`Network.IPAddress`</b>, +/// \anchor Network_IPAddress +/// _string_, +/// @return The system's IP Address. e.g. 192.168.1.15 +/// <p> +/// } +/// \table_row3{ <b>`Network.LinkState`</b>, +/// \anchor Network_LinkState +/// _string_, +/// @return The network linkstate e.g. 10mbit/100mbit etc. +/// <p> +/// } +/// \table_row3{ <b>`Network.MacAddress`</b>, +/// \anchor Network_MacAddress +/// _string_, +/// @return The system's MAC address. +/// <p> +/// } +/// \table_row3{ <b>`Network.SubnetMask`</b>, +/// \anchor Network_SubnetMask +/// _string_, +/// @return The network subnet mask. +/// <p> +/// } +/// \table_row3{ <b>`Network.GatewayAddress`</b>, +/// \anchor Network_GatewayAddress +/// _string_, +/// @return The network gateway address. +/// <p> +/// } +/// \table_row3{ <b>`Network.DNS1Address`</b>, +/// \anchor Network_DNS1Address +/// _string_, +/// @return The network DNS 1 address. +/// <p> +/// } +/// \table_row3{ <b>`Network.DNS2Address`</b>, +/// \anchor Network_DNS2Address +/// _string_, +/// @return The network DNS 2 address. +/// <p> +/// } +/// \table_row3{ <b>`Network.DHCPAddress`</b>, +/// \anchor Network_DHCPAddress +/// _string_, +/// @return The DHCP IP address. +/// <p> +/// } +/// \table_end +/// +/// ----------------------------------------------------------------------------- +const infomap network_labels[] = {{ "isdhcp", NETWORK_IS_DHCP }, + { "ipaddress", NETWORK_IP_ADDRESS }, //labels from here + { "linkstate", NETWORK_LINK_STATE }, + { "macaddress", NETWORK_MAC_ADDRESS }, + { "subnetmask", NETWORK_SUBNET_MASK }, + { "gatewayaddress", NETWORK_GATEWAY_ADDRESS }, + { "dns1address", NETWORK_DNS1_ADDRESS }, + { "dns2address", NETWORK_DNS2_ADDRESS }, + { "dhcpaddress", NETWORK_DHCP_ADDRESS }}; + +/// \page modules__infolabels_boolean_conditions +/// \subsection modules__infolabels_boolean_conditions_musicpartymode Music party mode +/// \table_start +/// \table_h3{ Labels, Type, Description } +/// \table_row3{ <b>`MusicPartyMode.Enabled`</b>, +/// \anchor MusicPartyMode_Enabled +/// _boolean_, +/// @return **True** if Party Mode is enabled. +/// <p> +/// } +/// \table_row3{ <b>`MusicPartyMode.SongsPlayed`</b>, +/// \anchor MusicPartyMode_SongsPlayed +/// _string_, +/// @return The number of songs played during Party Mode. +/// <p> +/// } +/// \table_row3{ <b>`MusicPartyMode.MatchingSongs`</b>, +/// \anchor MusicPartyMode_MatchingSongs +/// _string_, +/// @return The number of songs available to Party Mode. +/// <p> +/// } +/// \table_row3{ <b>`MusicPartyMode.MatchingSongsPicked`</b>, +/// \anchor MusicPartyMode_MatchingSongsPicked +/// _string_, +/// @return The number of songs picked already for Party Mode. +/// <p> +/// } +/// \table_row3{ <b>`MusicPartyMode.MatchingSongsLeft`</b>, +/// \anchor MusicPartyMode_MatchingSongsLeft +/// _string_, +/// @return The number of songs left to be picked from for Party Mode. +/// <p> +/// } +/// \table_row3{ <b>`MusicPartyMode.RelaxedSongsPicked`</b>, +/// \anchor MusicPartyMode_RelaxedSongsPicked +/// _string_, +/// @todo Not currently used +/// <p> +/// } +/// \table_row3{ <b>`MusicPartyMode.RandomSongsPicked`</b>, +/// \anchor MusicPartyMode_RandomSongsPicked +/// _string_, +/// @return The number of unique random songs picked during Party Mode. +/// <p> +/// } +/// \table_end +/// +/// ----------------------------------------------------------------------------- +const infomap musicpartymode[] = {{ "enabled", MUSICPM_ENABLED }, + { "songsplayed", MUSICPM_SONGSPLAYED }, + { "matchingsongs", MUSICPM_MATCHINGSONGS }, + { "matchingsongspicked", MUSICPM_MATCHINGSONGSPICKED }, + { "matchingsongsleft", MUSICPM_MATCHINGSONGSLEFT }, + { "relaxedsongspicked", MUSICPM_RELAXEDSONGSPICKED }, + { "randomsongspicked", MUSICPM_RANDOMSONGSPICKED }}; + +/// \page modules__infolabels_boolean_conditions +/// \subsection modules__infolabels_boolean_conditions_MusicPlayer Music player +/// \table_start +/// \table_h3{ Labels, Type, Description } +/// \table_row3{ <b>`MusicPlayer.Offset(number).Exists`</b>, +/// \anchor MusicPlayer_Offset +/// _boolean_, +/// @return **True** if the music players playlist has a song queued in +/// position (number). +/// @param number - song position +/// <p> +/// } +/// \table_row3{ <b>`MusicPlayer.Title`</b>, +/// \anchor MusicPlayer_Title +/// _string_, +/// @return The title of the currently playing song. +/// <p> +/// } +/// \table_row3{ <b>`MusicPlayer.offset(number).Title`</b>, +/// \anchor MusicPlayer_Offset_Title +/// _string_, +/// @return The title of the song which has an offset `number` with respect to the +/// current playing song. +/// @param number - the offset number with respect to the current playing song +/// <p> +/// } +/// \table_row3{ <b>`MusicPlayer.Position(number).Title`</b>, +/// \anchor MusicPlayer_Position_Title +/// _string_, +/// @return The title of the song which as an offset `number` with respect to the +/// start of the playlist. +/// @param number - the offset number with respect to the start of the playlist +/// <p> +/// } +/// \table_row3{ <b>`MusicPlayer.Album`</b>, +/// \anchor MusicPlayer_Album +/// _string_, +/// @return The album from which the current song is from. +/// <p> +/// } +/// \table_row3{ <b>`MusicPlayer.offset(number).Album`</b>, +/// \anchor MusicPlayer_OffSet_Album +/// _string_, +/// @return The album from which the song with offset `number` with respect to +/// the current song is from. +/// @param number - the offset number with respect to the current playing song +/// <p> +/// } +/// \table_row3{ <b>`MusicPlayer.Position(number).Album`</b>, +/// \anchor MusicPlayer_Position_Album +/// _string_, +/// @return The album from which the song with offset `number` with respect to +/// the start of the playlist is from. +/// @param number - the offset number with respect to the start of the playlist +/// <p> +/// } +/// \table_row3{ <b>`MusicPlayer.Property(Album_Mood)`</b>, +/// \anchor MusicPlayer_Property_Album_Mood +/// _string_, +/// @return The moods of the currently playing Album +/// <p> +/// } +/// \table_row3{ <b>`MusicPlayer.Property(Role.Composer)`</b>, +/// \anchor MusicPlayer_Property_Role_Composer +/// _string_, +/// @return The name of the person who composed the selected song. +/// <p><hr> +/// @skinning_v17 **[New Infolabel]** \link MusicPlayer_Property_Role_Composer `MusicPlayer.Property(Role.Composer)`\endlink +/// <p> +/// } +/// \table_row3{ <b>`MusicPlayer.Property(Role.Conductor)`</b>, +/// \anchor MusicPlayer_Property_Role_Conductor +/// _string_, +/// @return The name of the person who conducted the selected song. +/// <p><hr> +/// @skinning_v17 **[New Infolabel]** \link MusicPlayer_Property_Role_Conductor `MusicPlayer.Property(Role.Conductor)`\endlink +/// <p> +/// } +/// \table_row3{ <b>`MusicPlayer.Property(Role.Orchestra)`</b>, +/// \anchor MusicPlayer_Property_Role_Orchestra +/// _string_, +/// @return The name of the orchestra performing the selected song. +/// <p><hr> +/// @skinning_v17 **[New Infolabel]** \link MusicPlayer_Property_Role_Orchestra `MusicPlayer.Property(Role.Orchestra)`\endlink +/// <p> +/// } +/// \table_row3{ <b>`MusicPlayer.Property(Role.Lyricist)`</b>, +/// \anchor MusicPlayer_Property_Role_Lyricist +/// _string_, +/// @return The name of the person who wrote the lyrics of the selected song. +/// <p><hr> +/// @skinning_v17 **[New Infolabel]** \link MusicPlayer_Property_Role_Lyricist `MusicPlayer.Property(Role.Lyricist)`\endlink +/// <p> +/// } +/// \table_row3{ <b>`MusicPlayer.Property(Role.Remixer)`</b>, +/// \anchor MusicPlayer_Property_Role_Remixer +/// _string_, +/// @return The name of the person who remixed the selected song. +/// <p><hr> +/// @skinning_v17 **[New Infolabel]** \link MusicPlayer_Property_Role_Remixer `MusicPlayer.Property(Role.Remixer)`\endlink +/// <p> +/// } +/// \table_row3{ <b>`MusicPlayer.Property(Role.Arranger)`</b>, +/// \anchor MusicPlayer_Property_Role_Arranger +/// _string_, +/// @return The name of the person who arranged the selected song. +/// <p><hr> +/// @skinning_v17 **[New Infolabel]** \link MusicPlayer_Property_Role_Arranger `MusicPlayer.Property(Role.Arranger)`\endlink +/// <p> +/// } +/// \table_row3{ <b>`MusicPlayer.Property(Role.Engineer)`</b>, +/// \anchor MusicPlayer_Property_Role_Engineer +/// _string_, +/// @return The name of the person who was the engineer of the selected song. +/// <p><hr> +/// @skinning_v17 **[New Infolabel]** \link MusicPlayer_Property_Role_Engineer `MusicPlayer.Property(Role.Engineer)`\endlink +/// <p> +/// } +/// \table_row3{ <b>`MusicPlayer.Property(Role.Producer)`</b>, +/// \anchor MusicPlayer_Property_Role_Producer +/// _string_, +/// @return The name of the person who produced the selected song. +/// <p><hr> +/// @skinning_v17 **[New Infolabel]** \link MusicPlayer_Property_Role_Producer `MusicPlayer.Property(Role.Producer)`\endlink +/// <p> +/// } +/// \table_row3{ <b>`MusicPlayer.Property(Role.DJMixer)`</b>, +/// \anchor MusicPlayer_Property_Role_DJMixer +/// _string_, +/// @return The name of the dj who remixed the selected song. +/// <p><hr> +/// @skinning_v17 **[New Infolabel]** \link MusicPlayer_Property_Role_DJMixer `MusicPlayer.Property(Role.DJMixer)`\endlink +/// <p> +/// } +/// \table_row3{ <b>`MusicPlayer.Property(Role.Mixer)`</b>, +/// \anchor MusicPlayer_Property_Role_Mixer +/// _string_, +/// @return The name of the dj who remixed the selected song. +/// @todo So maybe rather than a row each have one entry for Role.XXXXX with composer\, arranger etc. as listed values +/// @note MusicPlayer.Property(Role.any_custom_role) also works\, +/// where any_custom_role could be an instrument violin or some other production activity e.g. sound engineer. +/// The roles listed (composer\, arranger etc.) are standard ones but there are many possible. +/// Music file tagging allows for the musicians and all other people involved in the recording to be added\, Kodi +/// will gathers and stores that data\, and it is available to GUI. +/// <p><hr> +/// @skinning_v17 **[New Infolabel]** \link MusicPlayer_Property_Role_Mixer `MusicPlayer.Property(Role.Mixer)`\endlink +/// <p> +/// } +/// \table_row3{ <b>`MusicPlayer.Property(Album_Mood)`</b>, +/// \anchor MusicPlayer_Property_Album_Mood +/// _string_, +/// @return the moods of the currently playing Album +/// <p> +/// } +/// \table_row3{ <b>`MusicPlayer.Property(Album_Style)`</b>, +/// \anchor MusicPlayer_Property_Album_Style +/// _string_, +/// @return the styles of the currently playing Album. +/// <p> +/// } +/// \table_row3{ <b>`MusicPlayer.Property(Album_Theme)`</b>, +/// \anchor MusicPlayer_Property_Album_Theme +/// _string_, +/// @return The themes of the currently playing Album +/// <p> +/// } +/// \table_row3{ <b>`MusicPlayer.Property(Album_Type)`</b>, +/// \anchor MusicPlayer_Property_Album_Type +/// _string_, +/// @return The album type (e.g. compilation\, enhanced\, explicit lyrics) of the +/// currently playing album. +/// <p> +/// } +/// \table_row3{ <b>`MusicPlayer.Property(Album_Label)`</b>, +/// \anchor MusicPlayer_Property_Album_Label +/// _string_, +/// @return The record label of the currently playing album. +/// <p> +/// } +/// \table_row3{ <b>`MusicPlayer.Property(Album_Description)`</b>, +/// \anchor MusicPlayer_Property_Album_Description +/// _string_, +/// @return A review of the currently playing album +/// <p> +/// } +/// \table_row3{ <b>`MusicPlayer.Artist`</b>, +/// \anchor MusicPlayer_Artist +/// _string_, +/// @return Artist(s) of current song. +/// <p> +/// } +/// \table_row3{ <b>`MusicPlayer.offset(number).Artist`</b>, +/// \anchor MusicPlayer_Offset_Artist +/// _string_, +/// @return Artist(s) of the song which has an offset `number` with respect +/// to the current playing song. +/// @param number - the offset of the song with respect to the current +/// playing song +/// <p> +/// } +/// \table_row3{ <b>`MusicPlayer.Position(number).Artist`</b>, +/// \anchor MusicPlayer_Position_Artist +/// _string_, +/// @return Artist(s) of the song which has an offset `number` with respect +/// to the start of the playlist. +/// @param number - the offset of the song with respect to +/// the start of the playlist +/// <p> +/// } +/// \table_row3{ <b>`MusicPlayer.AlbumArtist`</b>, +/// \anchor MusicPlayer_AlbumArtist +/// _string_, +/// @return The album artist of the currently playing song. +/// <p> +/// } +/// \table_row3{ <b>`MusicPlayer.Cover`</b>, +/// \anchor MusicPlayer_Cover +/// _string_, +/// @return The album cover of currently playing song. +/// <p> +/// } +/// \table_row3{ <b>`MusicPlayer.Property(Artist_Sortname)`</b>, +/// \anchor MusicPlayer_Property_Artist_Sortname +/// _string_, +/// @return The sortname of the currently playing Artist. +/// <p><hr> +/// @skinning_v18 **[New Infolabel]** \link MusicPlayer_Property_Artist_Sortname `MusicPlayer.Property(Artist_Sortname)`\endlink +/// <p> +/// } +/// \table_row3{ <b>`MusicPlayer.Property(Artist_Type)`</b>, +/// \anchor MusicPlayer_Property_Artist_Type +/// _string_, +/// @return The type of the currently playing Artist - person\, +/// group\, orchestra\, choir etc. +/// <p><hr> +/// @skinning_v18 **[New Infolabel]** \link MusicPlayer_Property_Artist_Type `MusicPlayer.Property(Artist_Type)`\endlink +/// <p> +/// } +/// \table_row3{ <b>`MusicPlayer.Property(Artist_Gender)`</b>, +/// \anchor MusicPlayer_Property_Artist_Gender +/// _string_, +/// @return The gender of the currently playing Artist - male\, +/// female\, other. +/// <p><hr> +/// @skinning_v18 **[New Infolabel]** \link MusicPlayer_Property_Artist_Gender `MusicPlayer.Property(Artist_Gender)`\endlink +/// <p> +/// } +/// \table_row3{ <b>`MusicPlayer.Property(Artist_Disambiguation)`</b>, +/// \anchor MusicPlayer_Property_Artist_Disambiguation +/// _string_, +/// @return A brief description of the currently playing Artist that differentiates them +/// from others with the same name. +/// <p><hr> +/// @skinning_v18 **[New Infolabel]** \link MusicPlayer_Property_Artist_Disambiguation `MusicPlayer.Property(Artist_Disambiguation)`\endlink +/// <p> +/// } +/// \table_row3{ <b>`MusicPlayer.Property(Artist_Born)`</b>, +/// \anchor MusicPlayer_Property_Artist_Born +/// _string_, +/// @return The date of Birth of the currently playing Artist. +/// <p> +/// } +/// \table_row3{ <b>`MusicPlayer.Property(Artist_Died)`</b>, +/// \anchor MusicPlayer_Property_Artist_Died +/// _string_, +/// @return The date of Death of the currently playing Artist. +/// <p> +/// } +/// \table_row3{ <b>`MusicPlayer.Property(Artist_Formed)`</b>, +/// \anchor MusicPlayer_Property_Artist_Formed +/// _string_, +/// @return The Formation date of the currently playing Artist/Band. +/// <p> +/// } +/// \table_row3{ <b>`MusicPlayer.Property(Artist_Disbanded)`</b>, +/// \anchor MusicPlayer_Property_Artist_Disbanded +/// _string_, +/// @return The disbanding date of the currently playing Artist/Band. +/// <p> +/// } +/// \table_row3{ <b>`MusicPlayer.Property(Artist_YearsActive)`</b>, +/// \anchor MusicPlayer_Property_Artist_YearsActive +/// _string_, +/// @return The years the currently Playing artist has been active. +/// <p> +/// } +/// \table_row3{ <b>`MusicPlayer.Property(Artist_Instrument)`</b>, +/// \anchor MusicPlayer_Property_Artist_Instrument +/// _string_, +/// @return The instruments played by the currently playing artist. +/// <p> +/// } +/// \table_row3{ <b>`MusicPlayer.Property(Artist_Description)`</b>, +/// \anchor MusicPlayer_Property_Artist_Description +/// _string_, +/// @return A biography of the currently playing artist. +/// <p> +/// } +/// \table_row3{ <b>`MusicPlayer.Property(Artist_Mood)`</b>, +/// \anchor MusicPlayer_Property_Artist_Mood +/// _string_, +/// @return The moods of the currently playing artist. +/// <p> +/// } +/// \table_row3{ <b>`MusicPlayer.Property(Artist_Style)`</b>, +/// \anchor MusicPlayer_Property_Artist_Style +/// _string_, +/// @return The styles of the currently playing artist. +/// <p> +/// } +/// \table_row3{ <b>`MusicPlayer.Property(Artist_Genre)`</b>, +/// \anchor MusicPlayer_Property_Artist_Genre +/// _string_, +/// @return The genre of the currently playing artist. +/// <p> +/// } +/// \table_row3{ <b>`MusicPlayer.Genre`</b>, +/// \anchor MusicPlayer_Genre +/// _string_, +/// @return The genre(s) of current song. +/// <p> +/// } +/// \table_row3{ <b>`MusicPlayer.offset(number).Genre`</b>, +/// \anchor MusicPlayer_OffSet_Genre +/// _string_, +/// @return The genre(s) of the song with an offset `number` with respect +/// to the current playing song. +/// @param number - the offset song number with respect to the current playing +/// song. +/// <p> +/// } +/// \table_row3{ <b>`MusicPlayer.Position(number).Genre`</b>, +/// \anchor MusicPlayer_Position_Genre +/// _string_, +/// @return The genre(s) of the song with an offset `number` with respect +/// to the start of the playlist. +/// @param number - the offset song number with respect to the start of the +/// playlist +/// song. +/// <p> +/// } +/// \table_row3{ <b>`MusicPlayer.Lyrics`</b>, +/// \anchor MusicPlayer_Lyrics +/// _string_, +/// @return The lyrics of current song stored in ID tag info. +/// <p> +/// } +/// \table_row3{ <b>`MusicPlayer.Year`</b>, +/// \anchor MusicPlayer_Year +/// _string_, +/// @return The year of release of current song. +/// <p> +/// } +/// \table_row3{ <b>`MusicPlayer.offset(number).Year`</b>, +/// \anchor MusicPlayer_Offset_Year +/// _string_, +/// @return The year of release of the song with an offset `number` with +/// respect to the current playing song. +/// @param number - the offset number with respect to the current song. +/// <p> +/// } +/// \table_row3{ <b>`MusicPlayer.Position(number).Year`</b>, +/// \anchor MusicPlayer_Position_Year +/// _string_, +/// @return The year of release of the song with an offset `number` with +/// respect to the start of the playlist. +/// @param number - the offset number with respect to the start of the +/// playlist. +/// <p> +/// } +/// \table_row3{ <b>`MusicPlayer.Rating`</b>, +/// \anchor MusicPlayer_Rating +/// _string_, +/// @return The numeric Rating of current song (1-10). +/// <p> +/// } +/// \table_row3{ <b>`MusicPlayer.offset(number).Rating`</b>, +/// \anchor MusicPlayer_OffSet_Rating +/// _string_, +/// @return The numeric Rating of song with an offset `number` with +/// respect to the current playing song. +/// @param number - the offset with respect to the current playing song +/// <p> +/// } +/// \table_row3{ <b>`MusicPlayer.Position(number).Rating`</b>, +/// \anchor MusicPlayer_Position_Rating +/// _string_, +/// @return The numeric Rating of song with an offset `number` with +/// respect to the start of the playlist. +/// @param number - the offset with respect to the start of the playlist +/// <p> +/// } +/// \table_row3{ <b>`MusicPlayer.RatingAndVotes`</b>, +/// \anchor MusicPlayer_RatingAndVotes +/// _string_, +/// @return The scraped rating and votes of currently playing song\, if it's in the database. +/// <p> +/// } +/// \table_row3{ <b>`MusicPlayer.UserRating`</b>, +/// \anchor MusicPlayer_UserRating +/// _string_, +/// @return The scraped rating of the currently playing song (1-10). +/// <p><hr> +/// @skinning_v17 **[New Infolabel]** \link MusicPlayer_UserRating `MusicPlayer.UserRating`\endlink +/// <p> +/// } +/// \table_row3{ <b>`MusicPlayer.Votes`</b>, +/// \anchor MusicPlayer_Votes +/// _string_, +/// @return The scraped votes of currently playing song\, if it's in the database. +/// <p> +/// } +/// \table_row3{ <b>`MusicPlayer.DiscNumber`</b>, +/// \anchor MusicPlayer_DiscNumber +/// _string_, +/// @return The Disc Number of current song stored in ID tag info. +/// <p> +/// } +/// \table_row3{ <b>`MusicPlayer.offset(number).DiscNumber`</b>, +/// \anchor MusicPlayer_Offset_DiscNumber +/// _string_, +/// @return The Disc Number of current song stored in ID tag info for the +/// song with an offset `number` with respect to the playing song. +/// @param number - The offset value for the song with respect to the +/// playing song. +/// <p> +/// } +/// \table_row3{ <b>`MusicPlayer.Position(number).DiscNumber`</b>, +/// \anchor MusicPlayer_Position_DiscNumber +/// _string_, +/// @return The Disc Number of current song stored in ID tag info for the +/// song with an offset `number` with respect to the start of the playlist. +/// @param number - The offset value for the song with respect to the +/// start of the playlist. +/// <p> +/// } +/// \table_row3{ <b>`MusicPlayer.Comment`</b>, +/// \anchor MusicPlayer_Comment +/// _string_, +/// @return The Comment of current song stored in ID tag info. +/// <p> +/// } +/// \table_row3{ <b>`MusicPlayer.offset(number).Comment`</b>, +/// \anchor MusicPlayer_Offset_Comment +/// _string_, +/// @return The Comment of current song stored in ID tag info for the +/// song with an offset `number` with respect to the playing song. +/// @param number - The offset value for the song with respect to the +/// playing song. +/// <p> +/// } +/// \table_row3{ <b>`MusicPlayer.Position(number).Comment`</b>, +/// \anchor MusicPlayer_Position_Comment +/// _string_, +/// @return The Comment of current song stored in ID tag info for the +/// song with an offset `number` with respect to the start of the playlist. +/// @param number - The offset value for the song with respect to the +/// start of the playlist. +/// <p> +/// } +/// \table_row3{ <b>`MusicPlayer.Contributors`</b>, +/// \anchor MusicPlayer_Contributors +/// _string_, +/// @return The list of all people who've contributed to the currently playing song +/// <p><hr> +/// @skinning_v17 **[New Infolabel]** \link MusicPlayer_Contributors `MusicPlayer.Contributors`\endlink +/// <p> +/// } +/// \table_row3{ <b>`MusicPlayer.ContributorAndRole`</b>, +/// \anchor MusicPlayer_ContributorAndRole +/// _string_, +/// @return The list of all people and their role who've contributed to the currently playing song. +/// <p><hr> +/// @skinning_v17 **[New Infolabel]** \link MusicPlayer_ContributorAndRole `MusicPlayer.ContributorAndRole`\endlink +/// <p> +/// } +/// \table_row3{ <b>`MusicPlayer.Mood`</b>, +/// \anchor MusicPlayer_Mood +/// _string_, +/// @return The mood of the currently playing song. +/// <p><hr> +/// @skinning_v17 **[New Infolabel]** \link MusicPlayer_Mood `MusicPlayer.Mood`\endlink +/// <p> +/// } +/// \table_row3{ <b>`MusicPlayer.PlaylistPlaying`</b>, +/// \anchor MusicPlayer_PlaylistPlaying +/// _boolean_, +/// @return **True** if a playlist is currently playing. +/// <p> +/// } +/// \table_row3{ <b>`MusicPlayer.Exists(relative\,position)`</b>, +/// \anchor MusicPlayer_Exists +/// _boolean_, +/// @return **True** if the currently playing playlist has a song queued at the given position. +/// @param relative - bool - If the position is relative +/// @param position - int - The position of the song +/// @note It is possible to define whether the position is relative or not\, default is false. +/// <p> +/// } +/// \table_row3{ <b>`MusicPlayer.HasPrevious`</b>, +/// \anchor MusicPlayer_HasPrevious +/// _boolean_, +/// @return **True** if the music player has a a Previous Song in the Playlist. +/// <p> +/// } +/// \table_row3{ <b>`MusicPlayer.HasNext`</b>, +/// \anchor MusicPlayer_HasNext +/// _boolean_, +/// @return **True** if the music player has a next song queued in the Playlist. +/// <p> +/// } +/// \table_row3{ <b>`MusicPlayer.PlayCount`</b>, +/// \anchor MusicPlayer_PlayCount +/// _integer_, +/// @return The play count of currently playing song\, if it's in the database. +/// <p> +/// } +/// \table_row3{ <b>`MusicPlayer.LastPlayed`</b>, +/// \anchor MusicPlayer_LastPlayed +/// _string_, +/// @return The last play date of currently playing song\, if it's in the database. +/// <p> +/// } +/// \table_row3{ <b>`MusicPlayer.TrackNumber`</b>, +/// \anchor MusicPlayer_TrackNumber +/// _string_, +/// @return The track number of current song. +/// <p> +/// } +/// \table_row3{ <b>`MusicPlayer.offset(number).TrackNumber`</b>, +/// \anchor MusicPlayer_Offset_TrackNumber +/// _string_, +/// @return The track number of the song with an offset `number` +/// with respect to the current playing song. +/// @param number - The offset number of the song with respect to the +/// playing song +/// <p> +/// } +/// \table_row3{ <b>`MusicPlayer.Position(number).TrackNumber`</b>, +/// \anchor MusicPlayer_Position_TrackNumber +/// _string_, +/// @return The track number of the song with an offset `number` +/// with respect to start of the playlist. +/// @param number - The offset number of the song with respect +/// to start of the playlist +/// <p> +/// } +/// \table_row3{ <b>`MusicPlayer.Duration`</b>, +/// \anchor MusicPlayer_Duration +/// _string_, +/// @return The duration of the current song. +/// <p> +/// } +/// \table_row3{ <b>`MusicPlayer.offset(number).Duration`</b>, +/// \anchor MusicPlayer_Offset_Duration +/// _string_, +/// @return The duration of the song with an offset `number` +/// with respect to the current playing song. +/// @param number - the offset number of the song with respect +/// to the current playing song +/// <p> +/// } +/// \table_row3{ <b>`MusicPlayer.Position(number).Duration`</b>, +/// \anchor MusicPlayer_Position_Duration +/// _string_, +/// @return The duration of the song with an offset `number` +/// with respect to the start of the playlist. +/// @param number - the offset number of the song with respect +/// to the start of the playlist +/// <p> +/// } +/// \table_row3{ <b>`MusicPlayer.BitRate`</b>, +/// \anchor MusicPlayer_BitRate +/// _string_, +/// @return The bitrate of current song. +/// <p> +/// } +/// \table_row3{ <b>`MusicPlayer.Channels`</b>, +/// \anchor MusicPlayer_Channels +/// _string_, +/// @return The number of channels of current song. +/// <p> +/// } +/// \table_row3{ <b>`MusicPlayer.BitsPerSample`</b>, +/// \anchor MusicPlayer_BitsPerSample +/// _string_, +/// @return The number of bits per sample of current song. +/// <p> +/// } +/// \table_row3{ <b>`MusicPlayer.SampleRate`</b>, +/// \anchor MusicPlayer_SampleRate +/// _string_, +/// @return The samplerate of current playing song. +/// <p> +/// } +/// \table_row3{ <b>`MusicPlayer.Codec`</b>, +/// \anchor MusicPlayer_Codec +/// _string_, +/// @return The codec of current playing song. +/// <p> +/// } +/// \table_row3{ <b>`MusicPlayer.PlaylistPosition`</b>, +/// \anchor MusicPlayer_PlaylistPosition +/// _string_, +/// @return The position of the current song in the current music playlist. +/// <p> +/// } +/// \table_row3{ <b>`MusicPlayer.PlaylistLength`</b>, +/// \anchor MusicPlayer_PlaylistLength +/// _string_, +/// @return The total size of the current music playlist. +/// <p> +/// } +/// \table_row3{ <b>`MusicPlayer.ChannelName`</b>, +/// \anchor MusicPlayer_ChannelName +/// _string_, +/// @return The channel name of the radio programme that's currently playing (PVR). +/// <p> +/// } +/// \table_row3{ <b>`MusicPlayer.ChannelNumberLabel`</b>, +/// \anchor MusicPlayer_ChannelNumberLabel +/// _string_, +/// @return The channel and subchannel number of the radio channel that's currently +/// playing (PVR). +/// <p><hr> +/// @skinning_v14 **[New Infolabel]** \link MusicPlayer_ChannelNumberLabel `MusicPlayer.ChannelNumberLabel`\endlink +/// <p> +/// } +/// \table_row3{ <b>`MusicPlayer.ChannelGroup`</b>, +/// \anchor MusicPlayer_ChannelGroup +/// _string_, +/// @return The channel group of the radio programme that's currently playing (PVR). +/// <p> +/// } +/// \table_row3{ <b>`MusicPlayer.Property(propname)`</b>, +/// \anchor MusicPlayer_Property_Propname +/// _string_, +/// @return The requested property value of the currently playing item. +/// @param propname - The requested property +/// <p> +/// } +/// \table_row3{ <b>`MusicPlayer.DBID`</b>, +/// \anchor MusicPlayer_DBID +/// _string_, +/// @return The database id of the currently playing song. +/// <p><hr> +/// @skinning_v17 **[New Infolabel]** \link MusicPlayer_DBID `MusicPlayer.DBID`\endlink +/// <p> +/// } +/// \table_row3{ <b>`MusicPlayer.DiscTitle`</b>, +/// \anchor MusicPlayer_DiscTitle +/// _string_, +/// @return The title of the disc currently playing. +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link MusicPlayer_DiscTitle `MusicPlayer.DiscTitle`\endlink +/// <p> +/// } +/// \table_row3{ <b>`MusicPlayer.ReleaseDate`</b>, +/// \anchor MusicPlayer_ReleaseDate +/// _string_, +/// @return The release date of the song currently playing. +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link MusicPlayer_ReleaseDate `MusicPlayer.ReleaseDate`\endlink +/// <p> +/// } +/// \table_row3{ <b>`MusicPlayer.OriginalDate`</b>, +/// \anchor MusicPlayer_OriginalDate +/// _string_, +/// @return The original release date of the song currently playing. +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link MusicPlayer_OriginalDate `MusicPlayer.OriginalDate`\endlink +/// <p> +/// } +/// \table_row3{ <b>`MusicPlayer.BPM`</b>, +/// \anchor MusicPlayer_BPM +/// _string_, +/// @return The bpm of the track currently playing. +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link MusicPlayer_BPM `MusicPlayer.BPM`\endlink +/// <p> +/// } +/// \table_row3{ <b>`MusicPlayer.IsMultiDisc`</b>, +/// \anchor MusicPlayer_IsMultiDisc +/// _boolean_, +/// @return Returns **true** if the album currently playing has more than one disc. +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link MusicPlayer_IsMultiDisc `MusicPlayer.IsMultiDisc`\endlink +/// <p> +/// } +/// \table_row3{ <b>`MusicPlayer.TotalDiscs`</b>, +/// \anchor MusicPlayer_TotalDiscs +/// _string_, +/// @return The number of discs associated with the currently playing album. +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link MusicPlayer_TotalDiscs `MusicPlayer.TotalDiscs`\endlink +/// <p> +/// } +/// \table_row3{ <b>`MusicPlayer.Station`</b>, +/// \anchor MusicPlayer_Station +/// _string_, +/// @return The name of the radio station currently playing (if available). +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link MusicPlayer_Station `MusicPlayer.Station`\endlink +/// <p> +/// } +/// \table_end +/// +/// ----------------------------------------------------------------------------- +const infomap musicplayer[] = {{ "title", MUSICPLAYER_TITLE }, + { "album", MUSICPLAYER_ALBUM }, + { "artist", MUSICPLAYER_ARTIST }, + { "albumartist", MUSICPLAYER_ALBUM_ARTIST }, + { "year", MUSICPLAYER_YEAR }, + { "genre", MUSICPLAYER_GENRE }, + { "duration", MUSICPLAYER_DURATION }, + { "tracknumber", MUSICPLAYER_TRACK_NUMBER }, + { "cover", MUSICPLAYER_COVER }, + { "bitrate", MUSICPLAYER_BITRATE }, + { "playlistlength", MUSICPLAYER_PLAYLISTLEN }, + { "playlistposition", MUSICPLAYER_PLAYLISTPOS }, + { "channels", MUSICPLAYER_CHANNELS }, + { "bitspersample", MUSICPLAYER_BITSPERSAMPLE }, + { "samplerate", MUSICPLAYER_SAMPLERATE }, + { "codec", MUSICPLAYER_CODEC }, + { "discnumber", MUSICPLAYER_DISC_NUMBER }, + { "disctitle", MUSICPLAYER_DISC_TITLE }, + { "rating", MUSICPLAYER_RATING }, + { "ratingandvotes", MUSICPLAYER_RATING_AND_VOTES }, + { "userrating", MUSICPLAYER_USER_RATING }, + { "votes", MUSICPLAYER_VOTES }, + { "comment", MUSICPLAYER_COMMENT }, + { "mood", MUSICPLAYER_MOOD }, + { "contributors", MUSICPLAYER_CONTRIBUTORS }, + { "contributorandrole", MUSICPLAYER_CONTRIBUTOR_AND_ROLE }, + { "lyrics", MUSICPLAYER_LYRICS }, + { "playlistplaying", MUSICPLAYER_PLAYLISTPLAYING }, + { "exists", MUSICPLAYER_EXISTS }, + { "hasprevious", MUSICPLAYER_HASPREVIOUS }, + { "hasnext", MUSICPLAYER_HASNEXT }, + { "playcount", MUSICPLAYER_PLAYCOUNT }, + { "lastplayed", MUSICPLAYER_LASTPLAYED }, + { "channelname", MUSICPLAYER_CHANNEL_NAME }, + { "channelnumberlabel", MUSICPLAYER_CHANNEL_NUMBER }, + { "channelgroup", MUSICPLAYER_CHANNEL_GROUP }, + { "dbid", MUSICPLAYER_DBID }, + { "property", MUSICPLAYER_PROPERTY }, + { "releasedate", MUSICPLAYER_RELEASEDATE }, + { "originaldate", MUSICPLAYER_ORIGINALDATE }, + { "bpm", MUSICPLAYER_BPM }, + { "ismultidisc", MUSICPLAYER_ISMULTIDISC }, + { "totaldiscs", MUSICPLAYER_TOTALDISCS }, + { "station", MUSICPLAYER_STATIONNAME } +}; + +/// \page modules__infolabels_boolean_conditions +/// \subsection modules__infolabels_boolean_conditions_Videoplayer Video player +/// \table_start +/// \table_h3{ Labels, Type, Description } +/// \table_row3{ <b>`VideoPlayer.UsingOverlays`</b>, +/// \anchor VideoPlayer_UsingOverlays +/// _boolean_, +/// @return **True** if the video player is using the hardware overlays render +/// method. +/// @note This is useful\, as with hardware overlays you have no alpha blending to +/// the video image\, so shadows etc. need redoing\, or disabling. +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.IsFullscreen`</b>, +/// \anchor VideoPlayer_IsFullscreen +/// _boolean_, +/// @return **True** if the video player is in fullscreen mode. +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.HasMenu`</b>, +/// \anchor VideoPlayer_HasMenu +/// _boolean_, +/// @return **True** if the video player has a menu (ie is playing a DVD). +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.HasInfo`</b>, +/// \anchor VideoPlayer_HasInfo +/// _boolean_, +/// @return **True** if the current playing video has information from the +/// library or from a plugin (eg director/plot etc.) +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.Content(parameter)`</b>, +/// \anchor VideoPlayer_Content +/// _boolean_, +/// @return **True** if the current Video you are playing is contained in +/// corresponding Video Library sections. The following values are accepted: +/// - <b>files</b> +/// - <b>movies</b> +/// - <b>episodes</b> +/// - <b>musicvideos</b> +/// - <b>livetv</b> +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.HasSubtitles`</b>, +/// \anchor VideoPlayer_HasSubtitles +/// _boolean_, +/// @return **True** if there are subtitles available for video. +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.HasTeletext`</b>, +/// \anchor VideoPlayer_HasTeletext +/// _boolean_, +/// @return **True** if teletext is usable on played TV channel. +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.IsStereoscopic`</b>, +/// \anchor VideoPlayer_IsStereoscopic +/// _boolean_, +/// @return **True** when the currently playing video is a 3D (stereoscopic) +/// video. +/// <p><hr> +/// @skinning_v13 **[New Boolean Condition]** \link VideoPlayer_IsStereoscopic `VideoPlayer.IsStereoscopic`\endlink +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.SubtitlesEnabled`</b>, +/// \anchor VideoPlayer_SubtitlesEnabled +/// _boolean_, +/// @return **True** if subtitles are turned on for video. +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.HasEpg`</b>, +/// \anchor VideoPlayer_HasEpg +/// _boolean_, +/// @return **True** if epg information is available for the currently playing +/// programme (PVR). +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.CanResumeLiveTV`</b>, +/// \anchor VideoPlayer_CanResumeLiveTV +/// _boolean_, +/// @return **True** if a in-progress PVR recording is playing an the respective +/// live TV channel is available. +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.Title`</b>, +/// \anchor VideoPlayer_Title +/// _string_, +/// @return The title of currently playing video. +/// @note If it's in the database it will return the database title\, else the filename. +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.offset(number).Title`</b>, +/// \anchor VideoPlayer_Offset_Title +/// _string_, +/// @return The title of video which has an offset `number` with respect to the currently playing video. +/// @note If it's in the database it will return the database title\, else the filename. +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Offset_Title `VideoPlayer.offset(number).Title`\endlink +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.position(number).Title`</b>, +/// \anchor VideoPlayer_Position_Title +/// _string_, +/// @return The title of the video which has an offset `number` with respect to the start of the playlist. +/// @note If it's in the database it will return the database title\, else the filename. +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Position_Title `VideoPlayer.position(number).Title`\endlink +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.OriginalTitle`</b>, +/// \anchor VideoPlayer_OriginalTitle +/// _string_, +/// @return The original title of currently playing video. If it's in the database. +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.offset(number).OriginalTitle`</b>, +/// \anchor VideoPlayer_Offset_OriginalTitle +/// _string_, +/// @return The original title of the video which has an offset `number` with respect to the currently playing video. +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Offset_OriginalTitle `VideoPlayer.offset(number).OriginalTitle`\endlink +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.position(number).OriginalTitle`</b>, +/// \anchor VideoPlayer_Position_OriginalTitle +/// _string_, +/// @return The original title of the video which has an offset `number` with respect to the start of the playlist. +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Position_OriginalTitle `VideoPlayer.position(number).OriginalTitle`\endlink +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.TVShowTitle`</b>, +/// \anchor VideoPlayer_TVShowTitle +/// _string_, +/// @return The title of currently playing episode's tvshow name. +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.offset(number).TVShowTitle`</b>, +/// \anchor VideoPlayer_Offset_TVShowTitle +/// _string_, +/// @return The title of the episode's tvshow name which has an offset `number` with respect to the currently playing video. +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Offset_TVShowTitle `VideoPlayer.offset(number).TVShowTitle`\endlink +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.position(number).TVShowTitle`</b>, +/// \anchor VideoPlayer_Position_TVShowTitle +/// _string_, +/// @return The title of the episode's tvshow name which has an offset `number` with respect to the start of the playlist. +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Position_TVShowTitle `VideoPlayer.position(number).TVShowTitle`\endlink +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.Season`</b>, +/// \anchor VideoPlayer_Season +/// _string_, +/// @return The season number of the currently playing episode\, if it's in the database. +/// <p><hr> +/// @skinning_v15 **[Infolabel Updated]** \link VideoPlayer_Season `VideoPlayer.Season`\endlink +/// also supports EPG. +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.offset(number).Season`</b>, +/// \anchor VideoPlayer_Offset_Season +/// _string_, +/// @return The season number of the episode which has an offset `number` with respect to the currently playing video. +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Offset_Season `VideoPlayer.offset(number).Season`\endlink +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.position(number).Season`</b>, +/// \anchor VideoPlayer_Position_Season +/// _string_, +/// @return The season number of the episode which has an offset `number` with respect to the start of the playlist. +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Position_Season `VideoPlayer.position(number).Season`\endlink +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.Episode`</b>, +/// \anchor VideoPlayer_Episode +/// _string_, +/// @return The episode number of the currently playing episode. +/// <p><hr> +/// @skinning_v15 **[Infolabel Updated]** \link VideoPlayer_Episode `VideoPlayer.Episode`\endlink +/// also supports EPG. +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.offset(number).Episode`</b>, +/// \anchor VideoPlayer_Offset_Episode +/// _string_, +/// @return The episode number of the episode which has an offset `number` with respect to the currently playing video. +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Offset_Episode `VideoPlayer.offset(number).Episode`\endlink +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.position(number).Episode`</b>, +/// \anchor VideoPlayer_Position_Episode +/// _string_, +/// @return The episode number of the episode which has an offset `number` with respect to the start of the playlist. +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Position_Episode `VideoPlayer.position(number).Episode`\endlink +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.Genre`</b>, +/// \anchor VideoPlayer_Genre +/// _string_, +/// @return The genre(s) of current movie\, if it's in the database. +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.offset(number).Genre`</b>, +/// \anchor VideoPlayer_Offset_Genre +/// _string_, +/// @return The genre(s) of the video which has an offset `number` with respect to the currently playing video. +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Offset_Genre `VideoPlayer.offset(number).Genre`\endlink +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.position(number).Genre`</b>, +/// \anchor VideoPlayer_Position_Genre +/// _string_, +/// @return The genre(s) of the video which has an offset `number` with respect to the start of the playlist. +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Position_Genre `VideoPlayer.position(number).Genre`\endlink +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.Director`</b>, +/// \anchor VideoPlayer_Director +/// _string_, +/// @return The director of current movie\, if it's in the database. +/// <p><hr> +/// @skinning_v15 **[Infolabel Updated]** \link VideoPlayer_Director `VideoPlayer.Director`\endlink +/// also supports EPG. +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.offset(number).Director`</b>, +/// \anchor VideoPlayer_Offset_Director +/// _string_, +/// @return The director of the video which has an offset `number` with respect to the currently playing video. +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Offset_Director `VideoPlayer.offset(number).VideoPlayer_Offset_Director`\endlink +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.position(number).Director`</b>, +/// \anchor VideoPlayer_Position_Director +/// _string_, +/// @return The director of the video which has an offset `number` with respect to the start of the playlist. +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Position_Director `VideoPlayer.position(number).Director`\endlink +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.Country`</b>, +/// \anchor VideoPlayer_Country +/// _string_, +/// @return The production country of current movie\, if it's in the database. +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.offset(number).Country`</b>, +/// \anchor VideoPlayer_Offset_Country +/// _string_, +/// @return The production country of the video which has an offset `number` with respect to the currently playing video. +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Offset_Country `VideoPlayer.offset(number).Country`\endlink +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.position(number).Country`</b>, +/// \anchor VideoPlayer_Position_Country +/// _string_, +/// @return The production country of the video which has an offset `number` with respect to the start of the playlist. +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Position_Country `VideoPlayer.position(number).Country`\endlink +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.Year`</b>, +/// \anchor VideoPlayer_Year +/// _string_, +/// @return The year of release of current movie\, if it's in the database. +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.offset(number).Year`</b>, +/// \anchor VideoPlayer_Offset_Year +/// _string_, +/// @return The year of release of the video which has an offset `number` with respect to the currently playing video. +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Offset_Year `VideoPlayer.offset(number).Year`\endlink +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.position(number).Year`</b>, +/// \anchor VideoPlayer_Position_Year +/// _string_, +/// @return The year of release of the video which has an offset `number` with respect to the start of the playlist. +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Position_Year `VideoPlayer.position(number).Year`\endlink +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.Cover`</b>, +/// \anchor VideoPlayer_Cover +/// _string_, +/// @return The cover of currently playing movie. +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.offset(number).Cover`</b>, +/// \anchor VideoPlayer_Offset_Cover +/// _string_, +/// @return The cover of the video which has an offset `number` with respect to the currently playing video. +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Offset_Cover `VideoPlayer.offset(number).Cover`\endlink +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.position(number).Cover`</b>, +/// \anchor VideoPlayer_Position_Cover +/// _string_, +/// @return The cover of the video which has an offset `number` with respect to the start of the playlist. +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Position_Cover `VideoPlayer.position(number).Cover`\endlink +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.Rating`</b>, +/// \anchor VideoPlayer_Rating +/// _string_, +/// @return The scraped rating of current movie\, if it's in the database. +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.offset(number).Rating`</b>, +/// \anchor VideoPlayer_Offset_Rating +/// _string_, +/// @return The scraped rating of the video which has an offset `number` with respect to the currently playing video. +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Offset_Rating `VideoPlayer.offset(number).Rating`\endlink +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.position(number).Rating`</b>, +/// \anchor VideoPlayer_Position_Rating +/// _string_, +/// @return The scraped rating of the video which has an offset `number` with respect to the start of the playlist. +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Position_Rating `VideoPlayer.position(number).Rating`\endlink +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.UserRating`</b>, +/// \anchor VideoPlayer_UserRating +/// _string_, +/// @return The user rating of the currently playing item. +/// <p><hr> +/// @skinning_v16 **[New Infolabel]** \link VideoPlayer_UserRating `VideoPlayer.UserRating`\endlink +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.offset(number).UserRating`</b>, +/// \anchor VideoPlayer_Offset_UserRating +/// _string_, +/// @return The user rating of the video which has an offset `number` with respect to the currently playing video. +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Offset_UserRating `VideoPlayer.offset(number).UserRating`\endlink +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.position(number).UserRating`</b>, +/// \anchor VideoPlayer_Position_UserRating +/// _string_, +/// @return The user rating of the video which has an offset `number` with respect to the start of the playlist. +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Position_UserRating `VideoPlayer.position(number).UserRating`\endlink +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.Votes`</b>, +/// \anchor VideoPlayer_Votes +/// _string_, +/// @return The scraped votes of current movie\, if it's in the database. +/// <p><hr> +/// @skinning_v13 **[New Infolabel]** \link VideoPlayer_Votes `VideoPlayer.Votes`\endlink +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.offset(number).Votes`</b>, +/// \anchor VideoPlayer_Offset_Votes +/// _string_, +/// @return The scraped votes of the video which has an offset `number` with respect to the currently playing video. +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Offset_Votes `VideoPlayer.offset(number).Votes`\endlink +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.position(number).Votes`</b>, +/// \anchor VideoPlayer_Position_Votes +/// _string_, +/// @return The scraped votes of the video which has an offset `number` with respect to the start of the playlist. +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Position_Votes `VideoPlayer.position(number).Votes`\endlink +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.RatingAndVotes`</b>, +/// \anchor VideoPlayer_RatingAndVotes +/// _string_, +/// @return The scraped rating and votes of current movie\, if it's in the database +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.offset(number).RatingAndVotes`</b>, +/// \anchor VideoPlayer_Offset_RatingAndVotes +/// _string_, +/// @return The scraped rating and votes of the video which has an offset `number` with respect to the currently playing video. +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Offset_RatingAndVotes `VideoPlayer.offset(number).RatingAndVotes`\endlink +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.position(number).RatingAndVotes`</b>, +/// \anchor VideoPlayer_Position_RatingAndVotes +/// _string_, +/// @return The scraped rating and votes of the video which has an offset `number` with respect to the start of the playlist. +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Position_RatingAndVotes `VideoPlayer.position(number).RatingAndVotes`\endlink +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.mpaa`</b>, +/// \anchor VideoPlayer_mpaa +/// _string_, +/// @return The MPAA rating of current movie\, if it's in the database. +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.offset(number).mpaa`</b>, +/// \anchor VideoPlayer_Offset_mpaa +/// _string_, +/// @return The MPAA rating of the video which has an offset `number` with respect to the currently playing video. +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Offset_mpaa `VideoPlayer.offset(number).mpaa`\endlink +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.position(number).mpaa`</b>, +/// \anchor VideoPlayer_Position_mpaa +/// _string_, +/// @return The MPAA rating of the video which has an offset `number` with respect to the start of the playlist. +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Position_mpaa `VideoPlayer.position(number).mpaa`\endlink +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.Art(type)`</b>, +/// \anchor VideoPlayer_art +/// _string_, +/// @return The art path for the requested arttype and for the currently playing video. +/// @param type - can virtually be anything\, refers to the art type keyword in the art map (poster\, fanart\, banner\, thumb\, etc) +/// <p><hr> +/// @skinning_v20 **[New Infolabel]** \link VideoPlayer_art `VideoPlayer.Art(type)`\endlink +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.offset(number).Art(type)`</b>, +/// \anchor VideoPlayer_Offset_art +/// _string_, +/// @return The art path for the requested arttype and for the video which has an offset `number` with respect to the currently playing video. +/// @param number - the offset with respect to the start of the playlist +/// @param type - can virtually be anything\, refers to the art type keyword in the art map (poster\, fanart\, banner\, thumb\, etc) +/// <p><hr> +/// @skinning_v20 **[New Infolabel]** \link VideoPlayer_Offset_mpaa `VideoPlayer.offset(number).Art(type)`\endlink +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.position(number).Art(type)`</b>, +/// \anchor VideoPlayer_position_art +/// _string_, +/// @return The art path for the requested arttype and for the video which has an offset `number` with respect to the start of the playlist. +/// @param number - the offset with respect to the start of the playlist +/// @param type - can virtually be anything\, refers to the art type keyword in the art map (poster\, fanart\, banner\, thumb\, etc) +/// <p><hr> +/// @skinning_v20 **[New Infolabel]** \link VideoPlayer_position_art `VideoPlayer.position(number).Art(type)`\endlink +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.IMDBNumber`</b>, +/// \anchor VideoPlayer_IMDBNumber +/// _string_, +/// @return The IMDb ID of the current movie\, if it's in the database. +/// <p><hr> +/// @skinning_v15 **[New Infolabel]** \link VideoPlayer_IMDBNumber `VideoPlayer.IMDBNumber`\endlink +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.offset(number).IMDBNumber`</b>, +/// \anchor VideoPlayer_Offset_IMDBNumber +/// _string_, +/// @return The IMDb ID of the the video which has an offset `number` with respect to the currently playing video. +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Offset_IMDBNumber `VideoPlayer.offset(number).IMDBNumber`\endlink +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.position(number).IMDBNumber`</b>, +/// \anchor VideoPlayer_Position_IMDBNumber +/// _string_, +/// @return The IMDb ID of the video which has an offset `number` with respect to the start of the playlist. +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Position_IMDBNumber `VideoPlayer.position(number).IMDBNumber`\endlink +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.Top250`</b>, +/// \anchor VideoPlayer_Top250 +/// _string_, +/// @return The IMDb Top250 position of the currently playing movie\, if it's in the database. +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.offset(number).Top250`</b>, +/// \anchor VideoPlayer_Offset_Top250 +/// _string_, +/// @return The IMDb Top250 position of the video which has an offset `number` with respect to the currently playing video. +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Offset_Top250 `VideoPlayer.offset(number).Top250`\endlink +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.position(number).Top250`</b>, +/// \anchor VideoPlayer_Position_Top250 +/// _string_, +/// @return The IMDb Top250 position of the video which has an offset `number` with respect to the start of the playlist. +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Position_Top250 `VideoPlayer.position(number).Top250`\endlink +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.EpisodeName`</b>, +/// \anchor VideoPlayer_EpisodeName +/// _string_, +/// @return The name of the episode if the playing video is a TV Show\, +/// if it's in the database (PVR). +/// <p><hr> +/// @skinning_v15 **[New Infolabel]** \link VideoPlayer_EpisodeName `VideoPlayer.EpisodeName`\endlink +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.PlaylistPosition`</b>, +/// \anchor VideoPlayer_PlaylistPosition +/// _string_, +/// @return The position of the current song in the current video playlist. +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.PlaylistLength`</b>, +/// \anchor VideoPlayer_PlaylistLength +/// _string_, +/// @return The total size of the current video playlist. +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.Cast`</b>, +/// \anchor VideoPlayer_Cast +/// _string_, +/// @return A concatenated string of cast members of the current movie\, if it's in +/// the database. +/// <p><hr> +/// @skinning_v15 **[Infolabel Updated]** \link VideoPlayer_Cast `VideoPlayer.Cast`\endlink +/// also supports EPG. +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.CastAndRole`</b>, +/// \anchor VideoPlayer_CastAndRole +/// _string_, +/// @return A concatenated string of cast members and roles of the current movie\, +/// if it's in the database. +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.Album`</b>, +/// \anchor VideoPlayer_Album +/// _string_, +/// @return The album from which the current Music Video is from\, if it's in the database. +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.offset(number).Album`</b>, +/// \anchor VideoPlayer_Offset_Album +/// _string_, +/// @return The album from which the video which has an offset `number` with respect to the currently playing video. +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Offset_Album `VideoPlayer.offset(number).Album`\endlink +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.position(number).Album`</b>, +/// \anchor VideoPlayer_Position_Album +/// _string_, +/// @return The album from which the music video which has an offset `number` with respect to the start of the playlist. +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Position_Album `VideoPlayer.position(number).Album`\endlink +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.Artist`</b>, +/// \anchor VideoPlayer_Artist +/// _string_, +/// @return The artist(s) of current Music Video\, if it's in the database. +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.offset(number).Artist`</b>, +/// \anchor VideoPlayer_Offset_Artist +/// _string_, +/// @return The artist(s) of the video which has an offset `number` with respect to the currently playing video. +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Offset_Artist `VideoPlayer.offset(number).Artist`\endlink +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.position(number).Artist`</b>, +/// \anchor VideoPlayer_Position_Artist +/// _string_, +/// @return The artist(s) of the music video which has an offset `number` with respect to the start of the playlist. +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Position_Artist `VideoPlayer.position(number).Artist`\endlink +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.Studio`</b>, +/// \anchor VideoPlayer_Studio +/// _string_, +/// @return The studio of current Music Video\, if it's in the database. +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.offset(number).Studio`</b>, +/// \anchor VideoPlayer_Offset_Studio +/// _string_, +/// @return The studio of the video which has an offset `number` with respect to the currently playing video. +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Offset_Studio `VideoPlayer.offset(number).Studio`\endlink +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.position(number).Studio`</b>, +/// \anchor VideoPlayer_Position_Studio +/// _string_, +/// @return The studio of the video which has an offset `number` with respect to the start of the playlist. +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Position_Studio `VideoPlayer.position(number).Studio`\endlink +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.Writer`</b>, +/// \anchor VideoPlayer_Writer +/// _string_, +/// @return The name of Writer of current playing Video\, if it's in the database. +/// <p><hr> +/// @skinning_v15 **[Infolabel Updated]** \link VideoPlayer_Writer `VideoPlayer.Writer`\endlink +/// also supports EPG. +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.offset(number).Writer`</b>, +/// \anchor VideoPlayer_Offset_Writer +/// _string_, +/// @return The name of Writer of the video which has an offset `number` with respect to the currently playing video. +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Offset_Writer `VideoPlayer.offset(number).Writer`\endlink +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.position(number).Writer`</b>, +/// \anchor VideoPlayer_Position_Writer +/// _string_, +/// @return The name of Writer of the video which has an offset `number` with respect to the start of the playlist. +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Position_Writer `VideoPlayer.position(number).Writer`\endlink +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.Tagline`</b>, +/// \anchor VideoPlayer_Tagline +/// _string_, +/// @return The small Summary of current playing Video\, if it's in the database. +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.offset(number).Tagline`</b>, +/// \anchor VideoPlayer_Offset_Tagline +/// _string_, +/// @return The small Summary of the video which has an offset `number` with respect to the currently playing video. +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Offset_Tagline `VideoPlayer.offset(number).Tagline`\endlink +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.position(number).Tagline`</b>, +/// \anchor VideoPlayer_Position_Tagline +/// _string_, +/// @return The small Summary of the video which has an offset `number` with respect to the start of the playlist. +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Position_Tagline `VideoPlayer.position(number).Tagline`\endlink +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.PlotOutline`</b>, +/// \anchor VideoPlayer_PlotOutline +/// _string_, +/// @return The small Summary of current playing Video\, if it's in the database. +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.offset(number).PlotOutline`</b>, +/// \anchor VideoPlayer_Offset_PlotOutline +/// _string_, +/// @return The small Summary of the video which has an offset `number` with respect to the currently playing video. +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Offset_PlotOutline `VideoPlayer.offset(number).PlotOutline`\endlink +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.position(number).PlotOutline`</b>, +/// \anchor VideoPlayer_Position_PlotOutline +/// _string_, +/// @return The small Summary of the video which has an offset `number` with respect to the start of the playlist. +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Position_PlotOutline `VideoPlayer.position(number).PlotOutline`\endlink +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.Plot`</b>, +/// \anchor VideoPlayer_Plot +/// _string_, +/// @return The complete Text Summary of current playing Video\, if it's in the database. +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.offset(number).Plot`</b>, +/// \anchor VideoPlayer_Offset_Plot +/// _string_, +/// @return The complete Text Summary of the video which has an offset `number` with respect to the currently playing video. +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Offset_Plot `VideoPlayer.offset(number).Plot`\endlink +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.position(number).Plot`</b>, +/// \anchor VideoPlayer_Position_Plot +/// _string_, +/// @return The complete Text Summary of the video which has an offset `number` with respect to the start of the playlist. +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Position_Plot `VideoPlayer.position(number).Plot`\endlink +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.Premiered`</b>, +/// \anchor VideoPlayer_Premiered +/// _string_, +/// @return The release or aired date of the currently playing episode\, show\, movie or EPG item\, +/// if it's in the database. +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.offset(number).Premiered`</b>, +/// \anchor VideoPlayer_Offset_Premiered +/// _string_, +/// @return The release or aired date of the video which has an offset `number` with respect to the currently playing video. +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Offset_Premiered `VideoPlayer.offset(number).Premiered`\endlink +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.position(number).Premiered`</b>, +/// \anchor VideoPlayer_Position_Premiered +/// _string_, +/// @return The release or aired date of the video which has an offset `number` with respect to the start of the playlist. +/// if it's in the database. +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Position_Premiered `VideoPlayer.position(number).Premiered`\endlink +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.Trailer`</b>, +/// \anchor VideoPlayer_Trailer +/// _string_, +/// @return The path to the trailer of the currently playing movie\, if it's in the database. +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.offset(number).Trailer`</b>, +/// \anchor VideoPlayer_Offset_Trailer +/// _string_, +/// @return The path to the trailer of the video which has an offset `number` with respect to the currently playing video. +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Offset_Trailer `VideoPlayer.offset(number).Title`\endlink +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.position(number).Trailer`</b>, +/// \anchor VideoPlayer_Position_Trailer +/// _string_, +/// @return The path to the trailer of the video which has an offset `number` with respect to the start of the playlist. +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Position_Trailer `VideoPlayer.position(number).Trailer`\endlink +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.LastPlayed`</b>, +/// \anchor VideoPlayer_LastPlayed +/// _string_, +/// @return The last play date of current playing Video\, if it's in the database. +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.offset(number).LastPlayed`</b>, +/// \anchor VideoPlayer_Offset_LastPlayed +/// _string_, +/// @return The last play date of the video which has an offset `number` with respect to the currently playing video. +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Offset_LastPlayed `VideoPlayer.offset(number).LastPlayed`\endlink +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.position(number).LastPlayed`</b>, +/// \anchor VideoPlayer_Position_LastPlayed +/// _string_, +/// @return The last play date of the video which has an offset `number` with respect to the start of the playlist. +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Position_LastPlayed `VideoPlayer.position(number).LastPlayed`\endlink +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.PlayCount`</b>, +/// \anchor VideoPlayer_PlayCount +/// _string_, +/// @return The playcount of current playing Video\, if it's in the database. +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.offset(number).PlayCount`</b>, +/// \anchor VideoPlayer_Offset_PlayCount +/// _string_, +/// @return The playcount of the video which has an offset `number` with respect to the currently playing video. +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Offset_PlayCount `VideoPlayer.offset(number).PlayCount`\endlink +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.position(number).PlayCount`</b>, +/// \anchor VideoPlayer_Position_PlayCount +/// _string_, +/// @return The playcount of the video which has an offset `number` with respect to the start of the playlist. +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Position_PlayCount `VideoPlayer.position(number).PlayCount`\endlink +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.VideoCodec`</b>, +/// \anchor VideoPlayer_VideoCodec +/// _string_, +/// @return The video codec of the currently playing video (common values: see +/// \ref ListItem_VideoCodec "ListItem.VideoCodec"). +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.VideoResolution`</b>, +/// \anchor VideoPlayer_VideoResolution +/// _string_, +/// @return The video resolution of the currently playing video (possible +/// values: see \ref ListItem_VideoResolution "ListItem.VideoResolution"). +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.VideoAspect`</b>, +/// \anchor VideoPlayer_VideoAspect +/// _string_, +/// @return The aspect ratio of the currently playing video (possible values: +/// see \ref ListItem_VideoAspect "ListItem.VideoAspect"). +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.AudioCodec`</b>, +/// \anchor VideoPlayer_AudioCodec +/// _string_, +/// @return The audio codec of the currently playing video\, optionally 'n' +/// defines the number of the audiostream (common values: see +/// \ref ListItem_AudioCodec "ListItem.AudioCodec"). +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.AudioChannels`</b>, +/// \anchor VideoPlayer_AudioChannels +/// _string_, +/// @return The number of audio channels of the currently playing video +/// (possible values: see \ref ListItem_AudioChannels "ListItem.AudioChannels"). +/// <p><hr> +/// @skinning_v16 **[Infolabel Updated]** \link VideoPlayer_AudioChannels `VideoPlayer.AudioChannels`\endlink +/// if a video contains no audio\, these infolabels will now return empty. +/// (they used to return 0) +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.AudioLanguage`</b>, +/// \anchor VideoPlayer_AudioLanguage +/// _string_, +/// @return The language of the audio of the currently playing video(possible +/// values: see \ref ListItem_AudioLanguage "ListItem.AudioLanguage"). +/// <p><hr> +/// @skinning_v13 **[New Infolabel]** \link VideoPlayer_AudioLanguage `VideoPlayer.AudioLanguage`\endlink +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.SubtitlesLanguage`</b>, +/// \anchor VideoPlayer_SubtitlesLanguage +/// _string_, +/// @return The language of the subtitle of the currently playing video +/// (possible values: see \ref ListItem_SubtitleLanguage "ListItem.SubtitleLanguage"). +/// @note `VideoPlayer.SubtitlesLanguage` holds the language of the next available +/// subtitle stream if subtitles are disabled in the player +/// <p><hr> +/// @skinning_v13 **[New Infolabel]** \link VideoPlayer_SubtitlesLanguage `VideoPlayer.SubtitlesLanguage`\endlink +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.StereoscopicMode`</b>, +/// \anchor VideoPlayer_StereoscopicMode +/// _string_, +/// @return The stereoscopic mode of the currently playing video (possible +/// values: see \ref ListItem_StereoscopicMode "ListItem.StereoscopicMode"). +/// <p><hr> +/// @skinning_v13 **[New Infolabel]** \link VideoPlayer_StereoscopicMode `VideoPlayer.StereoscopicMode`\endlink +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.StartTime`</b>, +/// \anchor VideoPlayer_StartTime +/// _string_, +/// @return The start date and time of the currently playing epg event or recording (PVR). +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.EndTime`</b>, +/// \anchor VideoPlayer_EndTime +/// _string_, +/// @return The end date and time of the currently playing epg event or recording (PVR). +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.NextTitle`</b>, +/// \anchor VideoPlayer_NextTitle +/// _string_, +/// @return The title of the programme that will be played next (PVR). +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.NextGenre`</b>, +/// \anchor VideoPlayer_NextGenre +/// _string_, +/// @return The genre of the programme that will be played next (PVR). +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.NextPlot`</b>, +/// \anchor VideoPlayer_NextPlot +/// _string_, +/// @return The plot of the programme that will be played next (PVR). +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.NextPlotOutline`</b>, +/// \anchor VideoPlayer_NextPlotOutline +/// _string_, +/// @return The plot outline of the programme that will be played next (PVR). +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.NextStartTime`</b>, +/// \anchor VideoPlayer_NextStartTime +/// _string_, +/// @return The start time of the programme that will be played next (PVR). +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.NextEndTime`</b>, +/// \anchor VideoPlayer_NextEndTime +/// _string_, +/// @return The end time of the programme that will be played next (PVR). +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.NextDuration`</b>, +/// \anchor VideoPlayer_NextDuration +/// _string_, +/// @return The duration of the programme that will be played next (PVR). +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.ChannelName`</b>, +/// \anchor VideoPlayer_ChannelName +/// _string_, +/// @return The name of the currently tuned channel (PVR). +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.ChannelNumberLabel`</b>, +/// \anchor VideoPlayer_ChannelNumberLabel +/// _string_, +/// @return The channel and subchannel number of the tv channel that's currently playing (PVR). +/// <p><hr> +/// @skinning_v14 **[New Infolabel]** \link VideoPlayer_ChannelNumberLabel `VideoPlayer.ChannelNumberLabel`\endlink +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.ChannelGroup`</b>, +/// \anchor VideoPlayer_ChannelGroup +/// _string_, +/// @return The group of the currently tuned channel (PVR). +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.ParentalRating`</b>, +/// \anchor VideoPlayer_ParentalRating +/// _string_, +/// @return The parental rating of the currently playing programme (PVR). +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.DBID`</b>, +/// \anchor VideoPlayer_DBID +/// _string_, +/// @return The database id of the currently playing video +/// <p><hr> +/// @skinning_v17 **[New Infolabel]** \link VideoPlayer_DBID `VideoPlayer.DBID`\endlink +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.offset(number).DBID`</b>, +/// \anchor VideoPlayer_Offset_DBID +/// _string_, +/// @return The database id of the video which has an offset `number` with respect to the currently playing video. +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Offset_DBID `VideoPlayer.offset(number).DBID`\endlink +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.position(number).DBID`</b>, +/// \anchor VideoPlayer_Position_DBID +/// _string_, +/// @return The database id of the video which has an offset `number` with respect to the start of the playlist. +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Position_DBID `VideoPlayer.position(number).DBID`\endlink +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.UniqueID(name)`</b>, +/// \anchor VideoPlayer_UniqueID +/// _string_, +/// @return The scraped metadata id of current movie\, if it's in the database. +/// @param name - the name of the metadata provider. +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_UniqueID `VideoPlayer.UniqueID(name)`\endlink +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.TvShowDBID`</b>, +/// \anchor VideoPlayer_TvShowDBID +/// _string_, +/// @return The database id of the TvShow for the currently playing Episode +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_TvShowDBID `VideoPlayer.TvShowDBID`\endlink +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.AudioStreamCount`</b>, +/// \anchor VideoPlayer_AudioStreamCount +/// _integer_, +/// @return The number of audio streams of the currently playing video. +/// @note If the video contains no audio streams it returns 0. +/// <p><hr> +/// @skinning_v20 **[New Infolabel]** \link VideoPlayer_AudioStreamCount `VideoPlayer.AudioStreamCount`\endlink +/// <p> +/// } +/// \table_row3{ <b>`VideoPlayer.HdrType`</b>, +/// \anchor VideoPlayer_HdrType +/// _string_, +/// @return String containing the name of the detected HDR type or empty if not HDR. See \ref StreamHdrType for the list of possible values. +/// <p><hr> +/// @skinning_v20 **[New Infolabel]** \link VideoPlayer_HdrType `VideoPlayer.HdrType`\endlink +/// <p> +/// } +/// \table_end +/// +/// ----------------------------------------------------------------------------- +// clang-format off +const infomap videoplayer[] = {{ "title", VIDEOPLAYER_TITLE }, + { "genre", VIDEOPLAYER_GENRE }, + { "country", VIDEOPLAYER_COUNTRY }, + { "originaltitle", VIDEOPLAYER_ORIGINALTITLE }, + { "director", VIDEOPLAYER_DIRECTOR }, + { "year", VIDEOPLAYER_YEAR }, + { "cover", VIDEOPLAYER_COVER }, + { "usingoverlays", VIDEOPLAYER_USING_OVERLAYS }, + { "isfullscreen", VIDEOPLAYER_ISFULLSCREEN }, + { "hasmenu", VIDEOPLAYER_HASMENU }, + { "playlistlength", VIDEOPLAYER_PLAYLISTLEN }, + { "playlistposition", VIDEOPLAYER_PLAYLISTPOS }, + { "plot", VIDEOPLAYER_PLOT }, + { "plotoutline", VIDEOPLAYER_PLOT_OUTLINE }, + { "episode", VIDEOPLAYER_EPISODE }, + { "season", VIDEOPLAYER_SEASON }, + { "rating", VIDEOPLAYER_RATING }, + { "ratingandvotes", VIDEOPLAYER_RATING_AND_VOTES }, + { "userrating", VIDEOPLAYER_USER_RATING }, + { "votes", VIDEOPLAYER_VOTES }, + { "tvshowtitle", VIDEOPLAYER_TVSHOW }, + { "premiered", VIDEOPLAYER_PREMIERED }, + { "studio", VIDEOPLAYER_STUDIO }, + { "mpaa", VIDEOPLAYER_MPAA }, + { "top250", VIDEOPLAYER_TOP250 }, + { "cast", VIDEOPLAYER_CAST }, + { "castandrole", VIDEOPLAYER_CAST_AND_ROLE }, + { "artist", VIDEOPLAYER_ARTIST }, + { "album", VIDEOPLAYER_ALBUM }, + { "writer", VIDEOPLAYER_WRITER }, + { "tagline", VIDEOPLAYER_TAGLINE }, + { "hasinfo", VIDEOPLAYER_HAS_INFO }, + { "trailer", VIDEOPLAYER_TRAILER }, + { "videocodec", VIDEOPLAYER_VIDEO_CODEC }, + { "videoresolution", VIDEOPLAYER_VIDEO_RESOLUTION }, + { "videoaspect", VIDEOPLAYER_VIDEO_ASPECT }, + { "videobitrate", VIDEOPLAYER_VIDEO_BITRATE }, + { "audiocodec", VIDEOPLAYER_AUDIO_CODEC }, + { "audiochannels", VIDEOPLAYER_AUDIO_CHANNELS }, + { "audiobitrate", VIDEOPLAYER_AUDIO_BITRATE }, + { "audiolanguage", VIDEOPLAYER_AUDIO_LANG }, + { "hasteletext", VIDEOPLAYER_HASTELETEXT }, + { "lastplayed", VIDEOPLAYER_LASTPLAYED }, + { "playcount", VIDEOPLAYER_PLAYCOUNT }, + { "hassubtitles", VIDEOPLAYER_HASSUBTITLES }, + { "subtitlesenabled", VIDEOPLAYER_SUBTITLESENABLED }, + { "subtitleslanguage",VIDEOPLAYER_SUBTITLES_LANG }, + { "starttime", VIDEOPLAYER_STARTTIME }, + { "endtime", VIDEOPLAYER_ENDTIME }, + { "nexttitle", VIDEOPLAYER_NEXT_TITLE }, + { "nextgenre", VIDEOPLAYER_NEXT_GENRE }, + { "nextplot", VIDEOPLAYER_NEXT_PLOT }, + { "nextplotoutline", VIDEOPLAYER_NEXT_PLOT_OUTLINE }, + { "nextstarttime", VIDEOPLAYER_NEXT_STARTTIME }, + { "nextendtime", VIDEOPLAYER_NEXT_ENDTIME }, + { "nextduration", VIDEOPLAYER_NEXT_DURATION }, + { "channelname", VIDEOPLAYER_CHANNEL_NAME }, + { "channelnumberlabel", VIDEOPLAYER_CHANNEL_NUMBER }, + { "channelgroup", VIDEOPLAYER_CHANNEL_GROUP }, + { "hasepg", VIDEOPLAYER_HAS_EPG }, + { "parentalrating", VIDEOPLAYER_PARENTAL_RATING }, + { "isstereoscopic", VIDEOPLAYER_IS_STEREOSCOPIC }, + { "stereoscopicmode", VIDEOPLAYER_STEREOSCOPIC_MODE }, + { "canresumelivetv", VIDEOPLAYER_CAN_RESUME_LIVE_TV }, + { "imdbnumber", VIDEOPLAYER_IMDBNUMBER }, + { "episodename", VIDEOPLAYER_EPISODENAME }, + { "dbid", VIDEOPLAYER_DBID }, + { "uniqueid", VIDEOPLAYER_UNIQUEID }, + { "tvshowdbid", VIDEOPLAYER_TVSHOWDBID }, + { "audiostreamcount", VIDEOPLAYER_AUDIOSTREAMCOUNT }, + { "hdrtype", VIDEOPLAYER_HDR_TYPE }, + { "art", VIDEOPLAYER_ART}, +}; +// clang-format on + +/// \page modules__infolabels_boolean_conditions +/// \subsection modules__infolabels_boolean_conditions_RetroPlayer RetroPlayer +/// \table_start +/// \table_h3{ Labels, Type, Description } +/// \table_row3{ <b>`RetroPlayer.VideoFilter`</b>, +/// \anchor RetroPlayer_VideoFilter +/// _string_, +/// @return The video filter of the currently-playing game. +/// The following values are possible: +/// - nearest (Nearest neighbor\, i.e. pixelate) +/// - linear (Bilinear filtering\, i.e. smooth blur) +/// <p><hr> +/// @skinning_v18 **[New Infolabel]** \link RetroPlayer_VideoFilter `RetroPlayer.VideoFilter`\endlink +/// <p> +/// } +/// \table_row3{ <b>`RetroPlayer.StretchMode`</b>, +/// \anchor RetroPlayer_StretchMode +/// _string_, +/// @return The stretch mode of the currently-playing game. +/// The following values are possible: +/// - normal (Show the game normally) +/// - 4:3 (Stretch to a 4:3 aspect ratio) +/// - fullscreen (Stretch to the full viewing area) +/// - original (Shrink to the original resolution) +/// <p><hr> +/// @skinning_v18 **[New Infolabel]** \link RetroPlayer_StretchMode `RetroPlayer.StretchMode`\endlink +/// <p> +/// } +/// \table_row3{ <b>`RetroPlayer.VideoRotation`</b>, +/// \anchor RetroPlayer_VideoRotation +/// _integer_, +/// @return The video rotation of the currently-playing game +/// in degrees counter-clockwise. +/// The following values are possible: +/// - 0 +/// - 90 (Shown in the GUI as 270 degrees) +/// - 180 +/// - 270 (Shown in the GUI as 90 degrees) +/// <p><hr> +/// @skinning_v18 **[New Infolabel]** \link RetroPlayer_VideoRotation `RetroPlayer.VideoRotation`\endlink +/// <p> +/// } +/// \table_end +/// +/// ----------------------------------------------------------------------------- +const infomap retroplayer[] = +{ + { "videofilter", RETROPLAYER_VIDEO_FILTER}, + { "stretchmode", RETROPLAYER_STRETCH_MODE}, + { "videorotation", RETROPLAYER_VIDEO_ROTATION}, +}; + +/// \page modules__infolabels_boolean_conditions +/// \subsection modules__infolabels_boolean_conditions_Container Container +/// \table_start +/// \table_h3{ Labels, Type, Description } +/// \table_row3{ <b>`Container.HasFiles`</b>, +/// \anchor Container_HasFiles +/// _boolean_, +/// @return **True** if the container contains files. +/// <p> +/// } +/// \table_row3{ <b>`Container.HasFolders`</b>, +/// \anchor Container_HasFolders +/// _boolean_, +/// @return **True** if the container contains folders. +/// <p> +/// } +/// \table_row3{ <b>`Container.IsStacked`</b>, +/// \anchor Container_IsStacked +/// _boolean_, +/// @return **True** if the container is currently in stacked mode. +/// <p> +/// } +/// \table_row3{ <b>`Container.FolderPath`</b>, +/// \anchor Container_FolderPath +/// _string_, +/// @return The complete path of currently displayed folder. +/// <p> +/// } +/// \table_row3{ <b>`Container.FolderName`</b>, +/// \anchor Container_FolderName +/// _string_, +/// @return The top most folder in currently displayed folder. +/// <p> +/// } +/// \table_row3{ <b>`Container.PluginName`</b>, +/// \anchor Container_PluginName +/// _string_, +/// @return The current plugins base folder name. +/// <p> +/// } +/// \table_row3{ <b>`Container.PluginCategory`</b>, +/// \anchor Container_PluginCategory +/// _string_, +/// @return The current plugins category (set by the scripter). +/// <p><hr> +/// @skinning_v17 **[New Infolabel]** \link Container_PluginCategory `Container.PluginCategory`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Container.Viewmode`</b>, +/// \anchor Container_Viewmode +/// _string_, +/// @return The current viewmode (list\, icons etc). +/// <p> +/// } +/// \table_row3{ <b>`Container.ViewCount`</b>, +/// \anchor Container_ViewCount +/// _integer_, +/// @return The number of available skin view modes for the current container listing. +/// <p><hr> +/// @skinning_v17 **[New Infolabel]** \link Container_ViewCount `Container.ViewCount`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Container.Totaltime`</b>, +/// \anchor Container_Totaltime +/// _string_, +/// @return The total time of all items in the current container. +/// <p> +/// } +/// \table_row3{ <b>`Container.TotalWatched`</b>, +/// \anchor Container_TotalWatched +/// _string_, +/// @return The number of watched items in the container. +/// @param id - [opt] if not supplied the current container will be used. +/// <p><hr> +/// @skinning_v16 **[New Infolabel]** \link Container_TotalWatched `Container(id).TotalWatched`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Container.TotalUnWatched`</b>, +/// \anchor Container_TotalUnWatched +/// _string_, +/// @return The number of unwatched items in the container. +/// @param id - [opt] if not supplied the current container will be used. +/// <p><hr> +/// @skinning_v16 **[New Infolabel]** \link Container_TotalUnWatched `Container(id).TotalUnWatched`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Container.HasThumb`</b>, +/// \anchor Container_HasThumb +/// _boolean_, +/// @return **True** if the current container you are in has a thumb assigned +/// to it. +/// <p> +/// } +/// \table_row3{ <b>`Container.SortOrder`</b>, +/// \anchor Container_SortOrder +/// _string_, +/// @return The current sort order (Ascending/Descending). +/// <p><hr> +/// @skinning_v16 **[New Infolabel]** \link Container_SortOrder `Container.SortOrder`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Container.CanFilter`</b>, +/// \anchor Container_CanFilter +/// _boolean_, +/// @return **True** when the current container can be filtered. +/// <p> +/// } +/// \table_row3{ <b>`Container.CanFilterAdvanced`</b>, +/// \anchor Container_CanFilterAdvanced +/// _boolean_, +/// @return **True** when advanced filtering can be applied to the current container. +/// <p> +/// } +/// \table_row3{ <b>`Container.Filtered`</b>, +/// \anchor Container_Filtered +/// _boolean_, +/// @return **True** when a mediafilter is applied to the current container. +/// <p> +/// } +/// \table_row3{ <b>`Container.ShowPlot`</b>, +/// \anchor Container_ShowPlot +/// _string_, +/// @return The TV Show plot of the current container and can be used at +/// season and episode level. +/// <p> +/// } +/// \table_row3{ <b>`Container.ShowTitle`</b>, +/// \anchor Container_ShowTitle +/// _string_, +/// @return The TV Show title of the current container and can be used at +/// season and episode level. +/// <p><hr> +/// @skinning_v17 **[New Infolabel]** \link Container_ShowTitle `Container.ShowTitle`\endlink +/// <p> +/// } +const infomap mediacontainer[] = {{ "hasfiles", CONTAINER_HASFILES }, + { "hasfolders", CONTAINER_HASFOLDERS }, + { "isstacked", CONTAINER_STACKED }, + { "folderpath", CONTAINER_FOLDERPATH }, + { "foldername", CONTAINER_FOLDERNAME }, + { "pluginname", CONTAINER_PLUGINNAME }, + { "plugincategory", CONTAINER_PLUGINCATEGORY }, + { "viewmode", CONTAINER_VIEWMODE }, + { "viewcount", CONTAINER_VIEWCOUNT }, + { "totaltime", CONTAINER_TOTALTIME }, + { "totalwatched", CONTAINER_TOTALWATCHED }, + { "totalunwatched", CONTAINER_TOTALUNWATCHED }, + { "hasthumb", CONTAINER_HAS_THUMB }, + { "sortorder", CONTAINER_SORT_ORDER }, + { "canfilter", CONTAINER_CAN_FILTER }, + { "canfilteradvanced",CONTAINER_CAN_FILTERADVANCED }, + { "filtered", CONTAINER_FILTERED }, + { "showplot", CONTAINER_SHOWPLOT }, + { "showtitle", CONTAINER_SHOWTITLE }}; + +/// \page modules__infolabels_boolean_conditions +/// \table_row3{ <b>`Container(id).OnNext`</b>, +/// \anchor Container_OnNext +/// _boolean_, +/// @return **True** if the container with id (or current container if id is +/// omitted) is moving to the next item. Allows views to be +/// custom-designed (such as 3D coverviews etc.) +/// <p> +/// } +/// \table_row3{ <b>`Container(id).OnScrollNext`</b>, +/// \anchor Container_OnScrollNext +/// _boolean_, +/// @return **True** if the container with id (or current container if id is +/// omitted) is scrolling to the next item. Differs from \ref Container_OnNext "OnNext" in that +/// \ref Container_OnNext "OnNext" triggers on movement even if there is no scroll involved. +/// <p> +/// } +/// \table_row3{ <b>`Container(id).OnPrevious`</b>, +/// \anchor Container_OnPrevious +/// _boolean_, +/// @return **True** if the container with id (or current container if id is +/// omitted) is moving to the previous item. Allows views to be +/// custom-designed (such as 3D coverviews etc). +/// <p> +/// } +/// \table_row3{ <b>`Container(id).OnScrollPrevious`</b>, +/// \anchor Container_OnScrollPrevious +/// _boolean_, +/// @return **True** if the container with id (or current container if id is +/// omitted) is scrolling to the previous item. Differs from \ref Container_OnPrevious "OnPrevious" in +/// that \ref Container_OnPrevious "OnPrevious" triggers on movement even if there is no scroll involved. +/// <p> +/// } +/// \table_row3{ <b>`Container(id).NumPages`</b>, +/// \anchor Container_NumPages +/// _integer_, +/// @return The number of pages in the container with given id. If no id is specified it +/// grabs the current container. +/// <p> +/// } +/// \table_row3{ <b>`Container(id).NumItems`</b>, +/// \anchor Container_NumItems +/// _integer_, +/// @return The number of items in the container or grouplist with given id excluding parent folder item. +/// @note If no id is specified it grabs the current container. +/// <p> +/// } +/// \table_row3{ <b>`Container(id).NumAllItems`</b>, +/// \anchor Container_NumAllItems +/// _integer_, +/// @return The number of all items in the container or grouplist with given id including parent folder item. +/// @note If no id is specified it grabs the current container. +/// <p><hr> +/// @skinning_v18 **[New Infolabel]** \link Container_NumAllItems `Container(id).NumAllItems`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Container(id).NumNonFolderItems`</b>, +/// \anchor Container_NumNonFolderItems +/// _integer_, +/// @return The Number of items in the container or grouplist with given id excluding all folder items. +/// @note **Example:** pvr recordings folders\, parent ".." folder). +/// If no id is specified it grabs the current container. +/// <p><hr> +/// @skinning_v18 **[New Infolabel]** \link Container_NumNonFolderItems `Container(id).NumNonFolderItems`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Container(id).CurrentPage`</b>, +/// \anchor Container_CurrentPage +/// _string_, +/// @return THe current page in the container with given id. +/// @note If no id is specified it grabs the current container. +/// <p> +/// } +/// \table_row3{ <b>`Container(id).CurrentItem`</b>, +/// \anchor Container_CurrentItem +/// _integer_, +/// @return The current item in the container or grouplist with given id. +/// @note If no id is specified it grabs the current container. +/// <p><hr> +/// @skinning_v15 **[New Infolabel]** \link Container_CurrentItem `Container(id).CurrentItem`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Container(id).Scrolling`</b>, +/// \anchor Container_Scrolling +/// _boolean_, +/// @return **True** if the user is currently scrolling through the container +/// with id (or current container if id is omitted). +/// @note This is slightly delayed from the actual scroll start. Use +/// \ref Container_OnScrollNext "Container(id).OnScrollNext" or +/// \ref Container_OnScrollPrevious "Container(id).OnScrollPrevious" to trigger animations +/// immediately on scroll. +/// <p> +/// } +/// \table_row3{ <b>`Container(id).HasNext`</b>, +/// \anchor Container_HasNext +/// _boolean_, +/// @return **True** if the container or textbox with id (id) has a next page. +/// <p> +/// } +/// \table_row3{ <b>`Container(id).HasParent`</b>, +/// \anchor Container_HasParent +/// _boolean_, +/// @return **True** when the container with given id contains a parent ('..') item. +/// @note If no id is specified it grabs the current container. +/// <p><hr> +/// @skinning_v16 **[New Boolean Condition]** \link Container_HasParent `Container.HasParent`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Container(id).HasPrevious`</b>, +/// \anchor Container_HasPrevious +/// _boolean_, +/// @return **True** if the container or textbox with id (id) has a previous page. +/// <p> +/// } +/// \table_row3{ <b>`Container(id).IsUpdating`</b>, +/// \anchor Container_IsUpdating +/// _boolean_, +/// @return **True** if the container with dynamic list content is currently updating. +/// } +const infomap container_bools[] ={{ "onnext", CONTAINER_MOVE_NEXT }, + { "onprevious", CONTAINER_MOVE_PREVIOUS }, + { "onscrollnext", CONTAINER_SCROLL_NEXT }, + { "onscrollprevious", CONTAINER_SCROLL_PREVIOUS }, + { "numpages", CONTAINER_NUM_PAGES }, + { "numitems", CONTAINER_NUM_ITEMS }, + { "numnonfolderitems", CONTAINER_NUM_NONFOLDER_ITEMS }, + { "numallitems", CONTAINER_NUM_ALL_ITEMS }, + { "currentpage", CONTAINER_CURRENT_PAGE }, + { "currentitem", CONTAINER_CURRENT_ITEM }, + { "scrolling", CONTAINER_SCROLLING }, + { "hasnext", CONTAINER_HAS_NEXT }, + { "hasparent", CONTAINER_HAS_PARENT_ITEM }, + { "hasprevious", CONTAINER_HAS_PREVIOUS }, + { "isupdating", CONTAINER_ISUPDATING }}; + +/// \page modules__infolabels_boolean_conditions +/// \table_row3{ <b>`Container(id).Row`</b>, +/// \anchor Container_Row +/// _integer_, +/// @return The row number of the focused position in a panel container. +/// <p><hr> +/// @skinning_v16 **[New Infolabel]** \link Container_Row `Container(id).Row`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Container(id).Row(parameter)`</b>, +/// \anchor Container_Row_parameter +/// _boolean_, +/// @return **True** if the row number of the focused position matches the specified parameter. +/// <p> +/// } +/// \table_row3{ <b>`Container(id).Column`</b>, +/// \anchor Container_Column +/// _integer_, +/// @return The column number of the focused position in a panel container. +/// <p><hr> +/// @skinning_v16 **[New Infolabel]** \link Container_Column `Container(id).Column`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Container(id).Column(parameter)`</b>, +/// \anchor Container_Column_parameter +/// _boolean_, +/// @return **True** if the column number of the focused position matches the specified parameter. +/// <p> +/// } +/// \table_row3{ <b>`Container(id).Position`</b>, +/// \anchor Container_Position +/// _integer_, +/// @return The current focused position of container / grouplist (id) as a +/// numeric label. +/// <p><hr> +/// @skinning_v16 **[Infolabel Updated]** \link Container_Position `Container(id).Position`\endlink +/// now also returns the position for items inside a grouplist. +/// <p> +/// } +/// \table_row3{ <b>`Container(id).Position(parameter)`</b>, +/// \anchor Container_Position_parameter +/// _boolean_, +/// @return **True** if the container with id (or current container if id is omitted) is focused on the specified position. +/// <p> +/// } +/// \table_row3{ <b>`Container(id).SubItem(item_number)`</b>, +/// \anchor Container_SubItem +/// _boolean_, +/// @return **True** if the container with id (or current container if id is omitted) is focused on the specified subitem. +/// @note If no id is specified it grabs the current container. +/// <p> +/// } +/// \table_row3{ <b>`Container(id).HasFocus(item_number)`</b>, +/// \anchor Container_HasFocus +/// _boolean_, +/// @return **True** if the container with id (or current container if id is +/// omitted) has static content and is focused on the item with id +/// item_number. +/// <p> +/// } +/// \table_row3{ <b>`Container.SortMethod`</b>, +/// \anchor Container_SortMethod +/// _string_, +/// @return The current sort method (returns a localized value). +/// <p> +/// } +/// \table_row3{ <b>`Container.SortMethod(sortid)`</b>, +/// \anchor Container_SortMethod_sortid +/// _boolean_, +/// @return **True** if the current sort method matches the specified SortID (see \ref List_of_sort_methods "SortUtils"). +/// <p> +/// } +const infomap container_ints[] = {{ "row", CONTAINER_ROW }, + { "column", CONTAINER_COLUMN }, + { "position", CONTAINER_POSITION }, + { "subitem", CONTAINER_SUBITEM }, + { "hasfocus", CONTAINER_HAS_FOCUS }, + { "sortmethod", CONTAINER_SORT_METHOD }, +}; + +/// \page modules__infolabels_boolean_conditions +/// \table_row3{ <b>`Container.Property(addoncategory)`</b>, +/// \anchor Container_Property_addoncategory +/// _string_, +/// @return The current add-on category. +/// <p> +/// } +/// \table_row3{ <b>`Container.Property(reponame)`</b>, +/// \anchor Container_Property_reponame +/// _string_, +/// @return The current add-on repository name. +/// <p> +/// } +/// \table_row3{ <b>`Container.Content`</b>, +/// \anchor Container_Content +/// _string_, +/// @return The content of the current container. +/// <p><hr> +/// @skinning_v16 **[New Infolabel]** \link Container_Content `Container.Content`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Container(id).ListItem(offset).Property`</b>, +/// \anchor Container_ListItem_property +/// _string_, +/// @return the property of the ListItem with a given offset. +/// @param offset - The offset for the listitem. +/// @note `Property` has to be replaced with `Label`\, `Label2`\, `Icon` etc. +/// @note **Example:** `Container(50).Listitem(2).Label ` +/// <p> +/// } +/// \table_row3{ <b>`Container(id).ListItemNoWrap(offset).Property`</b>, +/// \anchor Container_ListItemNoWrap +/// _string_, +/// @return the same as \link Container_ListItem_property `Container(id).ListItem(offset).Property` \endlink +/// but it won't wrap. +/// @param offset - The offset for the listitem. +/// @note That means if the last item of a list is focused\, `ListItemNoWrap(1)` +/// will be empty while `ListItem(1)` will return the first item of the list. +/// `Property` has to be replaced with `Label`\, `Label2`\, `Icon` etc. +/// @note **Example:** `Container(50).ListitemNoWrap(1).Plot` +/// <p> +/// } +/// \table_row3{ <b>`Container(id).ListItemPosition(x).[infolabel]`</b>, +/// \anchor Container_ListItemPosition +/// _string_, +/// @return The infolabel for an item in a Container. +/// @param x - the position in the container relative to the cursor position. +/// @note **Example:** `Container(50).ListItemPosition(4).Genre` +/// <p> +/// } +/// \table_row3{ <b>`Container(id).ListItemAbsolute(x).[infolabel]`</b>, +/// \anchor Container_ListItemAbsolute +/// _string_, +/// @return The infolabel for an item in a Container. +/// @param x - the absolute position in the container. +/// @note **Example:** `Container(50).ListItemAbsolute(4).Genre` +/// <p><hr> +/// @skinning_v16 **[New Infolabel]** \link Container_ListItemAbsolute `Container(id).ListItemAbsolute(x).[infolabel]`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Container.Content(parameter)`</b>, +/// \anchor Container_Content_parameter +/// _string_, +/// @return **True** if the current container you are in contains the following: +/// - <b>files</b> +/// - <b>songs</b> +/// - <b>artists</b> +/// - <b>albums</b> +/// - <b>movies</b> +/// - <b>tvshows</b> +/// - <b>seasons</b> +/// - <b>episodes</b> +/// - <b>musicvideos</b> +/// - <b>genres</b> +/// - <b>years</b> +/// - <b>actors</b> +/// - <b>playlists</b> +/// - <b>plugins</b> +/// - <b>studios</b> +/// - <b>directors</b> +/// - <b>sets</b> +/// - <b>tags</b> +/// @note These currently only work in the Video and Music +/// Library or unless a Plugin has set the value) also available are +/// Addons true when a list of add-ons is shown LiveTV true when a +/// htsp (tvheadend) directory is shown +/// <p> +/// } +/// \table_row3{ <b>`Container.Art(type)`</b>, +/// \anchor Container_Art +/// _string_, +/// @return The path to the art image file for the given type of the current container. +/// @param type - the art type to request. +/// @todo List of all art types +/// <p><hr> +/// @skinning_v16 **[Infolabel Updated]** \link Container_Art `Container.Art(type)`\endlink +/// <b>set.fanart</b> as possible type value. +/// @skinning_v15 **[New Infolabel]** \link Container_Art `Container.Art(type)`\endlink +/// <p> +/// } +/// +const infomap container_str[] = {{ "property", CONTAINER_PROPERTY }, + { "content", CONTAINER_CONTENT }, + { "art", CONTAINER_ART }}; + +/// \page modules__infolabels_boolean_conditions +/// \table_row3{ <b>`Container.SortDirection(direction)`</b>, +/// \anchor Container_SortDirection +/// _boolean_, +/// @return **True** if the sort direction of a container equals direction. +/// @param direction - The direction to check. It can be: +/// - <b>ascending</b> +/// - <b>descending</b> +/// <p> +/// } +/// \table_end +/// +/// ----------------------------------------------------------------------------- + +/// \page modules__infolabels_boolean_conditions +/// \subsection modules__infolabels_boolean_conditions_ListItem ListItem +/// \table_start +/// \table_h3{ Labels, Type, Description } +/// \table_row3{ <b>`ListItem.Thumb`</b>, +/// \anchor ListItem_Thumb +/// _string_, +/// @return The thumbnail (if it exists) of the currently selected item +/// in a list or thumb control. +/// @deprecated but still available\, returns +/// the same as \ref ListItem_Art_Type "ListItem.Art(thumb)" +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Icon`</b>, +/// \anchor ListItem_Icon +/// _string_, +/// @return The thumbnail (if it exists) of the currently selected item in a list or thumb control. +/// @note If no thumbnail image exists\, it will show the icon. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.ActualIcon`</b>, +/// \anchor ListItem_ActualIcon +/// _string_, +/// @return The icon of the currently selected item in a list or thumb control. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Overlay`</b>, +/// \anchor ListItem_Overlay +/// _string_, +/// @return The overlay icon status of the currently selected item in a list or thumb control. +/// - compressed file -- OverlayRAR.png +/// - watched -- OverlayWatched.png +/// - unwatched -- OverlayUnwatched.png +/// - locked -- OverlayLocked.png +/// <p> +/// } +/// \table_row3{ <b>`ListItem.IsFolder`</b>, +/// \anchor ListItem_IsFolder +/// _boolean_, +/// @return **True** if the current ListItem is a folder. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.IsPlaying`</b>, +/// \anchor ListItem_IsPlaying +/// _boolean_, +/// @return **True** if the current ListItem.* info labels and images are +/// currently Playing media. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.IsResumable`</b>, +/// \anchor ListItem_IsResumable +/// _boolean_, +/// @return **True** when the current ListItem has been partially played. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.IsCollection`</b>, +/// \anchor ListItem_IsCollection +/// _boolean_, +/// @return **True** when the current ListItem is a movie set. +/// <p><hr> +/// @skinning_v15 **[New Boolean Condition]** \link ListItem_IsCollection `ListItem.IsCollection`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.IsSelected`</b>, +/// \anchor ListItem_IsSelected +/// _boolean_, +/// @return **True** if the current ListItem is selected (f.e. currently playing +/// in playlist window). +/// <p> +/// } +/// \table_row3{ <b>`ListItem.HasEpg`</b>, +/// \anchor ListItem_HasEpg +/// _boolean_, +/// @return **True** when the selected programme has epg info (PVR). +/// <p> +/// } +/// \table_row3{ <b>`ListItem.HasTimer`</b>, +/// \anchor ListItem_HasTimer +/// _boolean_, +/// @return **True** when a recording timer has been set for the selected +/// programme (PVR). +/// <p> +/// } +/// \table_row3{ <b>`ListItem.IsRecording`</b>, +/// \anchor ListItem_IsRecording +/// _boolean_, +/// @return **True** when the selected programme is being recorded (PVR). +/// <p> +/// } +/// \table_row3{ <b>`ListItem.IsPlayable`</b>, +/// \anchor ListItem_IsPlayable +/// _boolean_, +/// @return **True** when the selected programme can be played (PVR) +/// <p><hr> +/// @skinning_v19 **[New Boolean Condition]** \link ListItem_IsPlayable `ListItem.IsPlayable`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.HasArchive`</b>, +/// \anchor ListItem_HasArchive +/// _boolean_, +/// @return **True** when the selected channel has a server-side back buffer (PVR) +/// <p><hr> +/// @skinning_v19 **[New Boolean Condition]** \link ListItem_HasArchive `ListItem.HasArchive`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.IsEncrypted`</b>, +/// \anchor ListItem_IsEncrypted +/// _boolean_, +/// @return **True** when the selected programme is encrypted (PVR). +/// <p> +/// } +/// \table_row3{ <b>`ListItem.IsStereoscopic`</b>, +/// \anchor ListItem_IsStereoscopic +/// _boolean_, +/// @return **True** when the selected video is a 3D (stereoscopic) video. +/// <p><hr> +/// @skinning_v13 **[New Boolean Condition]** \link ListItem_IsStereoscopic `ListItem.IsStereoscopic`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Property(IsSpecial)`</b>, +/// \anchor ListItem_Property_IsSpecial +/// _boolean_, +/// @return **True** if the current Season/Episode is a Special. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Property(DateLabel)`</b>, +/// \anchor ListItem_Property_DateLabel +/// _boolean_, +/// @return **True** if the item is a date label\, returns false if the item is a time label. +/// @note Can be used in the rulerlayout of the epggrid control. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Property(Addon.IsEnabled)`</b>, +/// \anchor ListItem_Property_AddonIsEnabled +/// _boolean_, +/// @return **True** when the selected addon is enabled (for use in the addon +/// info dialog only). +/// <p><hr> +/// @skinning_v17 **[Boolean Condition Updated]** \link ListItem_Property_AddonIsEnabled `ListItem.Property(Addon.IsEnabled)`\endlink +/// replaces `ListItem.Property(Addon.Enabled)`. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Property(Addon.IsInstalled)`</b>, +/// \anchor ListItem_Property_AddonIsInstalled +/// _boolean_, +/// @return **True** when the selected addon is installed (for use in the addon +/// info dialog only). +/// <p><hr> +/// @skinning_v17 **[Boolean Condition Updated]** \link ListItem_Property_AddonIsInstalled `ListItem.Property(Addon.IsInstalled)`\endlink +/// replaces `ListItem.Property(Addon.Installed)`. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Property(Addon.HasUpdate)`</b>, +/// \anchor ListItem_Property_AddonHasUpdate +/// _boolean_, +/// @return **True** when there's an update available for the selected addon. +/// <p><hr> +/// @skinning_v17 **[Boolean Condition Updated]** \link ListItem_Property_AddonHasUpdate `ListItem.Property(Addon.HasUpdate)`\endlink +/// replaces `ListItem.Property(Addon.UpdateAvail)`. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.IsAutoUpdateable`</b>, +/// \anchor ListItem_IsAutoUpdateable +/// _boolean_, +/// @return **True** if this add-on can be updated automatically. +/// <p><hr> +/// @skinning_v19 **[New Boolean Condition]** \link ListItem_IsAutoUpdateable `ListItem.IsAutoUpdateable`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Property(Addon.IsFromOfficialRepo)`</b>, +/// \anchor ListItem_Property_AddonIsFromOfficialRepo +/// _boolean_, +/// @return **True** if this add-on is from an official repository. +/// <p><hr> +/// @skinning_v19 **[New Boolean Condition]** \link ListItem_Property_AddonIsFromOfficialRepo `ListItem.Property(Addon.IsFromOfficialRepo)`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Property(Addon.IsBinary)`</b>, +/// \anchor ListItem_Property_AddonIsBinary +/// _boolean_, +/// @return **True** if this add-on is a binary addon. +/// <p><hr> +/// @skinning_v19 **[New Boolean Condition]** \link ListItem_Property_AddonIsBinary `ListItem.Property(Addon.IsBinary)`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Property(Addon.IsUpdate)`</b>, +/// \anchor ListItem_Property_AddonIsUpdate +/// _boolean_, +/// @return **True** if this add-on is a valid update of an installed outdated add-on. +/// <p><hr> +/// @skinning_v19 **[New Boolean Condition]** \link ListItem_Property_AddonIsUpdate `ListItem.Property(Addon.IsUpdate)`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Property(Addon.ValidUpdateOrigin)`</b>, +/// \anchor ListItem_Property_ValidUpdateOrigin +/// _string_, +/// @return The origin string of a valid update for the addon. Empty string if there is no valid update available. +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link ListItem_Property_ValidUpdateOrigin `ListItem.Property(Addon.ValidUpdateOrigin)`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Property(Addon.ValidUpdateVersion)`</b>, +/// \anchor ListItem_Property_ValidUpdateVersion +/// _string_, +/// @return The version string of a valid update for the addon. Empty string if there is no valid update available. +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link ListItem_Property_ValidUpdateVersion `ListItem.Property(Addon.ValidUpdateVersion)`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Label`</b>, +/// \anchor ListItem_Label +/// _string_, +/// @return The left label of the currently selected item in a container. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Label2`</b>, +/// \anchor ListItem_Label2 +/// _string_, +/// @return The right label of the currently selected item in a container. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Title`</b>, +/// \anchor ListItem_Title +/// _string_, +/// @return The title of the currently selected song\, movie\, game in a container. +/// <p><hr> +/// @skinning_v18 **[Infolabel Updated]** \link ListItem_Title `ListItem.Title`\endlink extended +/// to support games +/// <p> +/// } +/// \table_row3{ <b>`ListItem.OriginalTitle`</b>, +/// \anchor ListItem_OriginalTitle +/// _string_, +/// @return The original title of the currently selected movie in a container. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.SortLetter`</b>, +/// \anchor ListItem_SortLetter +/// _string_, +/// @return The first letter of the current file in a container. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.TrackNumber`</b>, +/// \anchor ListItem_TrackNumber +/// _string_, +/// @return The track number of the currently selected song in a container. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Artist`</b>, +/// \anchor ListItem_Artist +/// _string_, +/// @return The artist of the currently selected song in a container. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.AlbumArtist`</b>, +/// \anchor ListItem_AlbumArtist +/// _string_, +/// @return The artist of the currently selected album in a list. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Property(Artist_Sortname)`</b>, +/// \anchor ListItem_Property_Artist_Sortname +/// _string_, +/// @return The sortname of the currently selected Artist. +/// <p><hr> +/// @skinning_v18 **[New Infolabel]** \link ListItem_Property_Artist_Sortname `ListItem.Property(Artist_Sortname)`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Property(Artist_Type)`</b>, +/// \anchor ListItem_Property_Artist_Type +/// _string_, +/// @return The type of the currently selected Artist - person\, group\, orchestra\, choir etc. +/// <p><hr> +/// @skinning_v18 **[New Infolabel]** \link ListItem_Property_Artist_Type `ListItem.Property(Artist_Type)`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Property(Artist_Gender)`</b>, +/// \anchor ListItem_Property_Artist_Gender +/// _string_, +/// @return The Gender of the currently selected Artist - male\, female\, other. +/// <p><hr> +/// @skinning_v18 **[New Infolabel]** \link ListItem_Property_Artist_Gender `ListItem.Property(Artist_Gender)`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Property(Artist_Disambiguation)`</b>, +/// \anchor ListItem_Property_Artist_Disambiguation +/// _string_, +/// @return A Brief description of the currently selected Artist that differentiates them +/// from others with the same name. +/// <p><hr> +/// @skinning_v18 **[New Infolabel]** \link ListItem_Property_Artist_Disambiguation `ListItem.Property(Artist_Disambiguation)`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Property(Artist_Born)`</b>, +/// \anchor ListItem_Property_Artist_Born +/// _string_, +/// @return The date of Birth of the currently selected Artist. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Property(Artist_Died)`</b>, +/// \anchor ListItem_Property_Artist_Died +/// _string_, +/// @return The date of Death of the currently selected Artist. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Property(Artist_Formed)`</b>, +/// \anchor ListItem_Property_Artist_Formed +/// _string_, +/// @return The formation date of the currently selected Band. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Property(Artist_Disbanded)`</b>, +/// \anchor ListItem_Property_Artist_Disbanded +/// _string_, +/// @return The disbanding date of the currently selected Band. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Property(Artist_YearsActive)`</b>, +/// \anchor ListItem_Property_Artist_YearsActive +/// _string_, +/// @return The years the currently selected artist has been active. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Property(Artist_Instrument)`</b>, +/// \anchor ListItem_Property_Artist_Instrument +/// _string_, +/// @return The instruments played by the currently selected artist. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Property(Artist_Description)`</b>, +/// \anchor ListItem_Property_Artist_Description +/// _string_, +/// @return A biography of the currently selected artist. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Property(Artist_Mood)`</b>, +/// \anchor ListItem_Property_Artist_Mood +/// _string_, +/// @return The moods of the currently selected artist. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Property(Artist_Style)`</b>, +/// \anchor ListItem_Property_Artist_Style +/// _string_, +/// @return The styles of the currently selected artist. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Property(Artist_Genre)`</b>, +/// \anchor ListItem_Property_Artist_Genre +/// _string_, +/// @return The genre of the currently selected artist. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Album`</b>, +/// \anchor ListItem_Album +/// _string_, +/// @return The album of the currently selected song in a container. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Property(Album_Mood)`</b>, +/// \anchor ListItem_Property_Album_Mood +/// _string_, +/// @return The moods of the currently selected Album. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Property(Album_Style)`</b>, +/// \anchor ListItem_Property_Album_Style +/// _string_, +/// @return The styles of the currently selected Album. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Property(Album_Theme)`</b>, +/// \anchor ListItem_Property_Album_Theme +/// _string_, +/// @return The themes of the currently selected Album. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Property(Album_Type)`</b>, +/// \anchor ListItem_Property_Album_Type +/// _string_, +/// @return The Album Type (e.g. compilation\, enhanced\, explicit lyrics) of +/// the currently selected Album. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Property(Album_Label)`</b>, +/// \anchor ListItem_Property_Album_Label +/// _string_, +/// @return The record label of the currently selected Album. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Property(Album_Description)`</b>, +/// \anchor ListItem_Property_Album_Description +/// _string_, +/// @return A review of the currently selected Album. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Property(Album_Totaldiscs)`</b>, +/// \anchor ListItem_Property_Album_Totaldiscs +/// _string_, +/// @return The total number of discs belonging to an album. +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link ListItem.Property(Album_Totaldiscs) `ListItem.Property(Album_Totaldiscs)`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Property(Album_Isboxset)`</b>, +/// \anchor ListItem_Property_Album_Isboxset +/// _string_, +/// @return **True** if the album is a boxset. +/// <p><hr> +/// @skinning_v19 **[New Infobool]** \link ListItem.Property(Album_Isboxset) `ListItem.Property(Album_Isboxset)`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Property(Album_Duration)`</b>, +/// \anchor ListItem_Property_Album_Duration +/// _string_, +/// @return The duration of the album in HH:MM:SS. +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link ListItem_Property_Album_Duration `ListItem.Property(Album_Duration)`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.DiscNumber`</b>, +/// \anchor ListItem_DiscNumber +/// _string_, +/// @return The disc number of the currently selected song in a container. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Year`</b>, +/// \anchor ListItem_Year +/// _string_, +/// @return The year of the currently selected song\, album\, movie\, game in a +/// container. +/// <p><hr> +/// @skinning_v18 **[Infolabel Updated]** \link ListItem_Title `ListItem.Title`\endlink extended +/// to support games +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Premiered`</b>, +/// \anchor ListItem_Premiered +/// _string_, +/// @return The release/aired date of the currently selected episode\, show\, +/// movie or EPG item in a container. +/// <p><hr> +/// @skinning_v15 **[Infolabel Updated]** \link ListItem_Premiered `ListItem.Premiered`\endlink +/// now also available for EPG items. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Genre`</b>, +/// \anchor ListItem_Genre +/// _string_, +/// @return The genre of the currently selected song\, album or movie in a +/// container. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Contributors`</b>, +/// \anchor ListItem_Contributors +/// _string_, +/// @return The list of all people who've contributed to the selected song. +/// <p><hr> +/// @skinning_v17 **[New Infolabel]** \link ListItem_Contributors `ListItem.Contributors`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.ContributorAndRole`</b>, +/// \anchor ListItem_ContributorAndRole +/// _string_, +/// @return The list of all people and their role who've contributed to the selected song. +/// <p><hr> +/// @skinning_v17 **[New Infolabel]** \link ListItem_ContributorAndRole `ListItem.ContributorAndRole`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Director`</b>, +/// \anchor ListItem_Director +/// _string_, +/// @return The director of the currently selected movie in a container. +/// <p><hr> +/// @skinning_v15 **[Infolabel Updated]** \link ListItem_Director `ListItem.Director`\endlink +/// also supports EPG. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Country`</b>, +/// \anchor ListItem_Country +/// _string_, +/// @return The production country of the currently selected movie in a +/// container. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Episode`</b>, +/// \anchor ListItem_Episode +/// _string_, +/// @return The episode number value for the currently selected episode. It +/// also returns the number of total\, watched or unwatched episodes for the +/// currently selected tvshow or season\, based on the the current watched +/// filter. +/// <p><hr> +/// @skinning_v15 **[Infolabel Updated]** \link ListItem_Episode `ListItem.Episode`\endlink +/// also supports EPG. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Season`</b>, +/// \anchor ListItem_Season +/// _string_, +/// @return The season value for the currently selected tvshow. +/// <p><hr> +/// @skinning_v15 **[Infolabel Updated]** \link ListItem_Season `ListItem.Season`\endlink +/// also supports EPG. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.TVShowTitle`</b>, +/// \anchor ListItem_TVShowTitle +/// _string_, +/// @return The name value for the currently selected tvshow in the season and +/// episode depth of the video library. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Property(TotalSeasons)`</b>, +/// \anchor ListItem_Property_TotalSeasons +/// _string_, +/// @return The total number of seasons for the currently selected tvshow. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Property(TotalEpisodes)`</b>, +/// \anchor ListItem_Property_TotalEpisodes +/// _string_, +/// @return the total number of episodes for the currently selected tvshow or +/// season. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Property(WatchedEpisodes)`</b>, +/// \anchor ListItem_Property_WatchedEpisodes +/// _string_, +/// @return The number of watched episodes for the currently selected tvshow +/// or season. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Property(UnWatchedEpisodes)`</b>, +/// \anchor ListItem_Property_UnWatchedEpisodes +/// _string_, +/// @return The number of unwatched episodes for the currently selected tvshow +/// or season. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Property(NumEpisodes)`</b>, +/// \anchor ListItem_Property_NumEpisodes +/// _string_, +/// @return The number of total\, watched or unwatched episodes for the +/// currently selected tvshow or season\, based on the the current watched filter. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Property(WatchedEpisodePercent)`</b>, +/// \anchor ListItem_Property_WatchedEpisodePercent +/// _string_, +/// @return The percentage of watched episodes in the tvshow (watched/total*100) or season. +/// <p><hr> +/// @skinning_v20 **[New Infolabel]** \link ListItem_Property_WatchedEpisodePercent `ListItem.Property(WatchedEpisodePercent)`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.PictureAperture`</b>, +/// \anchor ListItem_PictureAperture +/// _string_, +/// @return The F-stop used to take the selected picture. +/// @note This is the value of the EXIF FNumber tag (hex code 0x829D). +/// <p> +/// } +/// \table_row3{ <b>`ListItem.PictureAuthor`</b>, +/// \anchor ListItem_PictureAuthor +/// _string_, +/// @return The name of the person involved in writing about the selected picture. +/// @note This is the value of the IPTC Writer tag (hex code 0x7A). +/// <p><hr> +/// @skinning_v13 **[New Infolabel]** \link ListItem_PictureAuthor `ListItem.PictureAuthor`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.PictureByline`</b>, +/// \anchor ListItem_PictureByline +/// _string_, +/// @return The name of the person who created the selected picture. +/// @note This is the value of the IPTC Byline tag (hex code 0x50). +/// <p><hr> +/// @skinning_v13 **[New Infolabel]** \link ListItem_PictureByline `ListItem.PictureByline`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.PictureBylineTitle`</b>, +/// \anchor ListItem_PictureBylineTitle +/// _string_, +/// @return The title of the person who created the selected picture. +/// @note This is the value of the IPTC BylineTitle tag (hex code 0x55). +/// <p><hr> +/// @skinning_v13 **[New Infolabel]** \link ListItem_PictureBylineTitle `ListItem.PictureBylineTitle`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.PictureCamMake`</b>, +/// \anchor ListItem_PictureCamMake +/// _string_, +/// @return The manufacturer of the camera used to take the selected picture. +/// @note This is the value of the EXIF Make tag (hex code 0x010F). +/// <p> +/// } +/// \table_row3{ <b>`ListItem.PictureCamModel`</b>, +/// \anchor ListItem_PictureCamModel +/// _string_, +/// @return The manufacturer's model name or number of the camera used to take +/// the selected picture. +/// @note This is the value of the EXIF Model tag (hex code 0x0110). +/// <p> +/// } +/// \table_row3{ <b>`ListItem.PictureCaption`</b>, +/// \anchor ListItem_PictureCaption +/// _string_, +/// @return A description of the selected picture. +/// @note This is the value of the IPTC Caption tag (hex code 0x78). +/// <p> +/// } +/// \table_row3{ <b>`ListItem.PictureCategory`</b>, +/// \anchor ListItem_PictureCategory +/// _string_, +/// @return The subject of the selected picture as a category code. +/// @note This is the value of the IPTC Category tag (hex code 0x0F). +/// <p><hr> +/// @skinning_v13 **[New Infolabel]** \link ListItem_PictureCategory `ListItem.PictureCategory`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.PictureCCDWidth`</b>, +/// \anchor ListItem_PictureCCDWidth +/// _string_, +/// @return The width of the CCD in the camera used to take the selected +/// picture. +/// @note This is calculated from three EXIF tags (0xA002 * 0xA210 / 0xA20e). +/// <p><hr> +/// @skinning_v13 **[New Infolabel]** \link ListItem_PictureCCDWidth `ListItem.PictureCCDWidth`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.PictureCity`</b>, +/// \anchor ListItem_PictureCity +/// _string_, +/// @return The city where the selected picture was taken. +/// @note This is the value of the IPTC City tag (hex code 0x5A). +/// <p><hr> +/// @skinning_v13 **[New Infolabel]** \link ListItem_PictureCity `ListItem.PictureCity`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.PictureColour`</b>, +/// \anchor ListItem_PictureColour +/// _string_, +/// @return Whether the selected picture is "Colour" or "Black and White". +/// <p><hr> +/// @skinning_v13 **[New Infolabel]** \link ListItem_PictureColour `ListItem.PictureColour`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.PictureComment`</b>, +/// \anchor ListItem_PictureComment +/// _string_, +/// @return A description of the selected picture. +/// @note This is the value of the +/// EXIF User Comment tag (hex code 0x9286). This is the same value as +/// \ref Slideshow_SlideComment "Slideshow.SlideComment". +/// <p> +/// } +/// \table_row3{ <b>`ListItem.PictureCopyrightNotice`</b>, +/// \anchor ListItem_PictureCopyrightNotice +/// _string_, +/// @return The copyright notice of the selected picture. +/// @note This is the value of the IPTC Copyright tag (hex code 0x74). +/// <p><hr> +/// @skinning_v13 **[New Infolabel]** \link ListItem_PictureCopyrightNotice `ListItem.PictureCopyrightNotice`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.PictureCountry`</b>, +/// \anchor ListItem_PictureCountry +/// _string_, +/// @return The full name of the country where the selected picture was taken. +/// @note This is the value of the IPTC CountryName tag (hex code 0x65). +/// <p><hr> +/// @skinning_v13 **[New Infolabel]** \link ListItem_PictureCountry `ListItem.PictureCountry`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.PictureCountryCode`</b>, +/// \anchor ListItem_PictureCountryCode +/// _string_, +/// @return The country code of the country where the selected picture was +/// taken. +/// @note This is the value of the IPTC CountryCode tag (hex code 0x64). +/// <p><hr> +/// @skinning_v13 **[New Infolabel]** \link ListItem_PictureCountryCode `ListItem.PictureCountryCode`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.PictureCredit`</b>, +/// \anchor ListItem_PictureCredit +/// _string_, +/// @return Who provided the selected picture. +/// @note This is the value of the IPTC Credit tag (hex code 0x6E). +/// <p><hr> +/// @skinning_v13 **[New Infolabel]** \link ListItem_PictureCredit `ListItem.PictureCredit`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.PictureDate`</b>, +/// \anchor ListItem_PictureDate +/// _string_, +/// @return The localized date of the selected picture. The short form of the +/// date is used. +/// @note The value of the EXIF DateTimeOriginal tag (hex code 0x9003) +/// is preferred. If the DateTimeOriginal tag is not found\, the value of +/// DateTimeDigitized (hex code 0x9004) or of DateTime (hex code 0x0132) might +/// be used. +/// <p><hr> +/// @skinning_v13 **[New Infolabel]** \link ListItem_PictureDate `ListItem.PictureDate`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.PictureDatetime`</b>, +/// \anchor ListItem_PictureDatetime +/// _string_, +/// @return The date/timestamp of the selected picture. The localized short form +/// of the date and time is used. +/// @note The value of the EXIF DateTimeOriginal tag (hex code 0x9003) is preferred. +/// If the DateTimeOriginal tag is not found\, the value of DateTimeDigitized +/// (hex code 0x9004) or of DateTime (hex code 0x0132) might be used. +/// <p><hr> +/// @skinning_v13 **[New Infolabel]** \link ListItem_PictureDatetime `ListItem.PictureDatetime`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.PictureDesc`</b>, +/// \anchor ListItem_PictureDesc +/// _string_, +/// @return A short description of the selected picture. The SlideComment\, +/// EXIFComment\, or Caption values might contain a longer description. +/// @note This is the value of the EXIF ImageDescription tag (hex code 0x010E). +/// <p> +/// } +/// \table_row3{ <b>`ListItem.PictureDigitalZoom`</b>, +/// \anchor ListItem_PictureDigitalZoom +/// _string_, +/// @return The digital zoom ratio when the selected picture was taken. +/// @note This is the value of the EXIF DigitalZoomRatio tag (hex code 0xA404). +/// <p><hr> +/// @skinning_v13 **[New Infolabel]** \link ListItem_PictureDigitalZoom `ListItem.PictureDigitalZoom`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.PictureExpMode`</b>, +/// \anchor ListItem_PictureExpMode +/// _string_, +/// @return The exposure mode of the selected picture. +/// The possible values are: +/// - <b>"Automatic"</b> +/// - <b>"Manual"</b> +/// - <b>"Auto bracketing"</b> +/// @note This is the value of the EXIF ExposureMode tag (hex code 0xA402). +/// <p> +/// } +/// \table_row3{ <b>`ListItem.PictureExposure`</b>, +/// \anchor ListItem_PictureExposure +/// _string_, +/// @return The class of the program used by the camera to set exposure when +/// the selected picture was taken. Values include: +/// - <b>"Manual"</b> +/// - <b>"Program (Auto)"</b> +/// - <b>"Aperture priority (Semi-Auto)"</b> +/// - <b>"Shutter priority (semi-auto)"</b> +/// - etc +/// @note This is the value of the EXIF ExposureProgram tag (hex code 0x8822). +/// <p><hr> +/// @skinning_v13 **[New Infolabel]** \link ListItem_PictureExposure `ListItem.PictureExposure`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.PictureExposureBias`</b>, +/// \anchor ListItem_PictureExposureBias +/// _string_, +/// @return The exposure bias of the selected picture. +/// Typically this is a number between -99.99 and 99.99. +/// @note This is the value of the EXIF ExposureBiasValue tag (hex code 0x9204). +/// <p><hr> +/// @skinning_v13 **[New Infolabel]** \link ListItem_PictureExposureBias `ListItem.PictureExposureBias`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.PictureExpTime`</b>, +/// \anchor ListItem_PictureExpTime +/// _string_, +/// @return The exposure time of the selected picture\, in seconds. +/// @note This is the value of the EXIF ExposureTime tag (hex code 0x829A). +/// If the ExposureTime tag is not found\, the ShutterSpeedValue tag (hex code 0x9201) +/// might be used. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.PictureFlashUsed`</b>, +/// \anchor ListItem_PictureFlashUsed +/// _string_, +/// @return The status of flash when the selected picture was taken. The value +/// will be either "Yes" or "No"\, and might include additional information. +/// @note This is the value of the EXIF Flash tag (hex code 0x9209). +/// <p><hr> +/// @skinning_v13 **[New Infolabel]** \link ListItem_PictureFlashUsed `ListItem.PictureFlashUsed`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.PictureFocalLen`</b>, +/// \anchor ListItem_PictureFocalLen +/// _string_, +/// @return The lens focal length of the selected picture. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.PictureFocusDist`</b>, +/// \anchor ListItem_PictureFocusDist +/// _string_, +/// @return The focal length of the lens\, in mm. +/// @note This is the value of the EXIF FocalLength tag (hex code 0x920A). +/// } +/// \table_row3{ <b>`ListItem.PictureGPSLat`</b>, +/// \anchor ListItem_PictureGPSLat +/// _string_, +/// @return The latitude where the selected picture was taken (degrees\, +/// minutes\, seconds North or South). +/// @note This is the value of the EXIF GPSInfo.GPSLatitude and GPSInfo.GPSLatitudeRef tags. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.PictureGPSLon`</b>, +/// \anchor ListItem_PictureGPSLon +/// _string_, +/// @return The longitude where the selected picture was taken (degrees\, +/// minutes\, seconds East or West). +/// @note This is the value of the EXIF GPSInfo.GPSLongitude and GPSInfo.GPSLongitudeRef tags. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.PictureGPSAlt`</b>, +/// \anchor ListItem_PictureGPSAlt +/// _string_, +/// @return The altitude in meters where the selected picture was taken. +/// @note This is the value of the EXIF GPSInfo.GPSAltitude tag. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.PictureHeadline`</b>, +/// \anchor ListItem_PictureHeadline +/// _string_, +/// @return A synopsis of the contents of the selected picture. +/// @note This is the value of the IPTC Headline tag (hex code 0x69). +/// <p><hr> +/// @skinning_v13 **[New Infolabel]** \link ListItem_PictureHeadline `ListItem.PictureHeadline`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.PictureImageType`</b>, +/// \anchor ListItem_PictureImageType +/// _string_, +/// @return The color components of the selected picture. +/// @note This is the value of the IPTC ImageType tag (hex code 0x82). +/// <p><hr> +/// @skinning_v13 **[New Infolabel]** \link ListItem_PictureImageType `ListItem.PictureImageType`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.PictureIPTCDate`</b>, +/// \anchor ListItem_PictureIPTCDate +/// _string_, +/// @return The date when the intellectual content of the selected picture was +/// created\, rather than when the picture was created. +/// @note This is the value of the IPTC DateCreated tag (hex code 0x37). +/// <p><hr> +/// @skinning_v13 **[New Infolabel]** \link ListItem_PictureIPTCDate `ListItem.PictureIPTCDate`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.PictureIPTCTime`</b>, +/// \anchor ListItem_PictureIPTCTime +/// _string_, +/// @return The time when the intellectual content of the selected picture was +/// created\, rather than when the picture was created. +/// @note This is the value of the IPTC TimeCreated tag (hex code 0x3C). +/// <p><hr> +/// @skinning_v13 **[New Infolabel]** \link ListItem_PictureIPTCTime `ListItem.PictureIPTCTime`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.PictureISO`</b>, +/// \anchor ListItem_PictureISO +/// _string_, +/// @return The ISO speed of the camera when the selected picture was taken. +/// @note This is the value of the EXIF ISOSpeedRatings tag (hex code 0x8827). +/// <p> +/// } +/// \table_row3{ <b>`ListItem.PictureKeywords`</b>, +/// \anchor ListItem_PictureKeywords +/// _string_, +/// @return The keywords assigned to the selected picture. +/// @note This is the value of the IPTC Keywords tag (hex code 0x19). +/// <p> +/// } +/// \table_row3{ <b>`ListItem.PictureLightSource`</b>, +/// \anchor ListItem_PictureLightSource +/// _string_, +/// @return The kind of light source when the picture was taken. Possible +/// values include: +/// - <b>"Daylight"</b> +/// - <b>"Fluorescent"</b> +/// - <b>"Incandescent"</b> +/// - etc +/// @note This is the value of the EXIF LightSource tag (hex code 0x9208). +/// <p><hr> +/// @skinning_v13 **[New Infolabel]** \link ListItem_PictureLightSource `ListItem.PictureLightSource`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.PictureLongDate`</b>, +/// \anchor ListItem_PictureLongDate +/// _string_, +/// @return Only the localized date of the selected picture. The long form of +/// the date is used. +/// @note The value of the EXIF DateTimeOriginal tag (hex code +/// 0x9003) is preferred. If the DateTimeOriginal tag is not found\, the +/// value of DateTimeDigitized (hex code 0x9004) or of DateTime (hex code +/// 0x0132) might be used. +/// <p><hr> +/// @skinning_v13 **[New Infolabel]** \link ListItem_PictureLongDate `ListItem.PictureLongDate`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.PictureLongDatetime`</b>, +/// \anchor ListItem_PictureLongDatetime +/// _string_, +/// @return The date/timestamp of the selected picture. The localized long +/// form of the date and time is used. +/// @note The value of the EXIF DateTimeOriginal +/// tag (hex code 0x9003) is preferred. if the DateTimeOriginal tag is not +/// found\, the value of DateTimeDigitized (hex code 0x9004) or of DateTime +/// (hex code 0x0132) might be used. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.PictureMeteringMode`</b>, +/// \anchor ListItem_PictureMeteringMode +/// _string_, +/// @return The metering mode used when the selected picture was taken. The +/// possible values are: +/// - <b>"Center weight"</b> +/// - <b>"Spot"</b> +/// - <b>"Matrix"</b> +/// @note This is the value of the EXIF MeteringMode tag (hex code 0x9207). +/// <p><hr> +/// @skinning_v13 **[New Infolabel]** \link ListItem_PictureMeteringMode `ListItem.PictureMeteringMode`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.PictureObjectName`</b>, +/// \anchor ListItem_PictureObjectName +/// _string_, +/// @return A shorthand reference for the selected picture. +/// @note This is the value of the IPTC ObjectName tag (hex code 0x05). +/// <p><hr> +/// @skinning_v13 **[New Infolabel]** \link ListItem_PictureObjectName `ListItem.PictureObjectName`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.PictureOrientation`</b>, +/// \anchor ListItem_PictureOrientation +/// _string_, +/// @return The orientation of the selected picture. Possible values are: +/// - <b>"Top Left"</b> +/// - <b>"Top Right"</b> +/// - <b>"Left Top"</b> +/// - <b>"Right Bottom"</b> +/// - etc +/// @note This is the value of the EXIF Orientation tag (hex code 0x0112). +/// <p><hr> +/// @skinning_v13 **[New Infolabel]** \link ListItem_PictureOrientation `ListItem.PictureOrientation`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.PicturePath`</b>, +/// \anchor ListItem_PicturePath +/// _string_, +/// @return The filename and path of the selected picture. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.PictureProcess`</b>, +/// \anchor ListItem_PictureProcess +/// _string_, +/// @return The process used to compress the selected picture. +/// <p><hr> +/// @skinning_v13 **[New Infolabel]** \link ListItem_PictureProcess `ListItem.PictureProcess`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.PictureReferenceService`</b>, +/// \anchor ListItem_PictureReferenceService +/// _string_, +/// @return The Service Identifier of a prior envelope to which the selected +/// picture refers. +/// @note This is the value of the IPTC ReferenceService tag (hex code 0x2D). +/// <p><hr> +/// @skinning_v13 **[New Infolabel]** \link ListItem_PictureReferenceService `ListItem.PictureReferenceService`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.PictureResolution`</b>, +/// \anchor ListItem_PictureResolution +/// _string_, +/// @return The dimensions of the selected picture. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.PictureSource`</b>, +/// \anchor ListItem_PictureSource +/// _string_, +/// @return The original owner of the selected picture. +/// @note This is the value of the IPTC Source tag (hex code 0x73). +/// <p><hr> +/// @skinning_v13 **[New Infolabel]** \link ListItem_PictureSource `ListItem.PictureSource`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.PictureSpecialInstructions`</b>, +/// \anchor ListItem_PictureSpecialInstructions +/// _string_, +/// @return Other editorial instructions concerning the use of the selected +/// picture. +/// @note This is the value of the IPTC SpecialInstructions tag (hex code 0x28). +/// <p><hr> +/// @skinning_v13 **[New Infolabel]** \link ListItem_PictureSpecialInstructions `ListItem.PictureSpecialInstructions`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.PictureState`</b>, +/// \anchor ListItem_PictureState +/// _string_, +/// @return The State/Province where the selected picture was taken. +/// @note This is the value of the IPTC ProvinceState tag (hex code 0x5F). +/// <p><hr> +/// @skinning_v13 **[New Infolabel]** \link ListItem_PictureState `ListItem.PictureState`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.PictureSublocation`</b>, +/// \anchor ListItem_PictureSublocation +/// _string_, +/// @return The location within a city where the selected picture was taken - +/// might indicate the nearest landmark. +/// @note This is the value of the IPTC SubLocation tag (hex code 0x5C). +/// <p><hr> +/// @skinning_v13 **[New Infolabel]** \link ListItem_PictureSublocation `ListItem.PictureSublocation`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.PictureSupplementalCategories`</b>, +/// \anchor ListItem_PictureSupplementalCategories +/// _string_, +/// @return A supplemental category codes to further refine the subject of the +/// selected picture. +/// @note This is the value of the IPTC SuppCategory tag (hex code 0x14). +/// <p><hr> +/// @skinning_v13 **[New Infolabel]** \link ListItem_PictureSupplementalCategories `ListItem.PictureSupplementalCategories`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.PictureTransmissionReference`</b>, +/// \anchor ListItem_PictureTransmissionReference +/// _string_, +/// @return A code representing the location of original transmission of the +/// selected picture. +/// @note This is the value of the IPTC TransmissionReference tag (hex code 0x67). +/// <p><hr> +/// @skinning_v13 **[New Infolabel]** \link ListItem_PictureTransmissionReference `ListItem.PictureTransmissionReference`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.PictureUrgency`</b>, +/// \anchor ListItem_PictureUrgency +/// _string_, +/// @return The urgency of the selected picture. Values are 1-9. +/// @note The "1" is most urgent. Some image management programs use urgency to indicate +/// picture rating\, where urgency "1" is 5 stars and urgency "5" is 1 star. +/// Urgencies 6-9 are not used for rating. This is the value of the IPTC +/// Urgency tag (hex code 0x0A). +/// <p><hr> +/// @skinning_v13 **[New Infolabel]** \link ListItem_PictureUrgency `ListItem.PictureUrgency`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.PictureWhiteBalance`</b>, +/// \anchor ListItem_PictureWhiteBalance +/// _string_, +/// @return The white balance mode set when the selected picture was taken. +/// The possible values are: +/// - <b>"Manual"</b> +/// - <b>"Auto"</b> +/// @note This is the value of the EXIF WhiteBalance tag (hex code 0xA403). +/// <p><hr> +/// @skinning_v13 **[New Infolabel]** \link ListItem_PictureWhiteBalance `ListItem.PictureWhiteBalance`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.FileName`</b>, +/// \anchor ListItem_FileName +/// _string_, +/// @return The filename of the currently selected song or movie in a container. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Path`</b>, +/// \anchor ListItem_Path +/// _string_, +/// @return The complete path of the currently selected song or movie in a +/// container. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.FolderName`</b>, +/// \anchor ListItem_FolderName +/// _string_, +/// @return The top most folder of the path of the currently selected song or +/// movie in a container. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.FolderPath`</b>, +/// \anchor ListItem_FolderPath +/// _string_, +/// @return The complete path of the currently selected song or movie in a +/// container (without user details). +/// <p> +/// } +/// \table_row3{ <b>`ListItem.FileNameAndPath`</b>, +/// \anchor ListItem_FileNameAndPath +/// _string_, +/// @return The full path with filename of the currently selected song or +/// movie in a container. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.FileExtension`</b>, +/// \anchor ListItem_FileExtension +/// _string_, +/// @return The file extension (without leading dot) of the currently selected +/// item in a container. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.FileNameNoExtension`</b>, +/// \anchor ListItem_FileName_No_Extension +/// _string_, +/// @return The filename without extension of the currently selected +/// item in a container. +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link ListItem_FileName_No_Extension `ListItem.FileNameNoExtension`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Date`</b>, +/// \anchor ListItem_Date +/// _string_, +/// @return The file date of the currently selected song or movie in a +/// container / Aired date of an episode / Day\, start time and end time of +/// current selected TV programme (PVR). +/// <p> +/// } +/// \table_row3{ <b>`ListItem.DateTime`</b>, +/// \anchor ListItem_DateTime +/// _string_, +/// @return The date and time a certain event happened (event log). +/// <p><hr> +/// @skinning_v16 **[New Infolabel]** \link ListItem_DateTime `ListItem.DateTime`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.DateAdded`</b>, +/// \anchor ListItem_DateAdded +/// _string_, +/// @return The date the currently selected item was added to the +/// library / Date and time of an event in the EventLog window. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Size`</b>, +/// \anchor ListItem_Size +/// _string_, +/// @return The file size of the currently selected song or movie in a +/// container. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Rating([name])`</b>, +/// \anchor ListItem_Rating +/// _string_, +/// @return The scraped rating of the currently selected item in a container (1-10). +/// @param name - [opt] you can specify the name of the scraper to retrieve a specific rating\, +/// for use in dialogvideoinfo.xml. +/// <p><hr> +/// @skinning_v18 **[Infolabel Updated]** \link ListItem_Rating `ListItem.Rating([name])`\endlink replaces +/// the old `ListItem.Ratings([name])` infolabel. +/// @skinning_v17 **[New Infolabel]** \link ListItem_Rating `ListItem.Ratings([name])`\endlink +/// @skinning_v17 **[Infolabel Updated]** \link ListItem_Rating `ListItem.Ratings`\endlink +/// for songs it's now the scraped rating. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Set`</b>, +/// \anchor ListItem_Set +/// _string_, +/// @return The name of the set the movie is part of. +/// <p><hr> +/// @skinning_v17 **[New Infolabel]** \link ListItem_Set `ListItem.Set`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.SetId`</b>, +/// \anchor ListItem_SetId +/// _string_, +/// @return The id of the set the movie is part of. +/// <p><hr> +/// @skinning_v17 **[New Infolabel]** \link ListItem_SetId `ListItem.SetId`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Status`</b>, +/// \anchor ListItem_Status +/// _string_, +/// @return One of the following status: +/// - <b>"returning series"</b> +/// - <b>"in production"</b> +/// - <b>"planned"</b> +/// - <b>"cancelled"</b> +/// - <b>"ended"</b> +/// <p> +/// @note For use with tv shows. +/// <p><hr> +/// @skinning_v17 **[New Infolabel]** \link ListItem_Status `ListItem.Status`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.EndTimeResume`</b>, +/// \anchor ListItem_EndTimeResume +/// _string_, +/// @return Returns the time a video will end if you resume it\, instead of playing it from the beginning. +/// <p><hr> +/// @skinning_v17 **[New Infolabel]** \link ListItem_EndTimeResume `ListItem.EndTimeResume`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.UserRating`</b>, +/// \anchor ListItem_UserRating +/// _string_, +/// @return The user rating of the currently selected item in a container (1-10). +/// <p><hr> +/// @skinning_v17 **[Infolabel Updated]** \link ListItem_UserRating `ListItem.UserRating`\endlink +/// now available for albums/songs. +/// @skinning_v16 **[New Infolabel]** \link ListItem_UserRating `ListItem.UserRating`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Votes([name])`</b>, +/// \anchor ListItem_Votes +/// _string_, +/// @return The scraped votes of the currently selected movie in a container. +/// @param name - [opt] you can specify the name of the scraper to retrieve specific votes\, +/// for use in `dialogvideoinfo.xml`. +/// <p><hr> +/// @skinning_v17 **[Infolabel Updated]** \link ListItem_Votes `ListItem.Votes([name])`\endlink +/// add optional param <b>name</b> to specify the scrapper. +/// @skinning_v13 **[New Infolabel]** \link ListItem_Votes `ListItem.Votes`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.RatingAndVotes([name])`</b>, +/// \anchor ListItem_RatingAndVotes +/// _string_, +/// @return The scraped rating and votes of the currently selected movie in a +/// container (1-10). +/// @param name - [opt] you can specify the name of the scraper to retrieve specific votes\, +/// for use in `dialogvideoinfo.xml`. +/// <p><hr> +/// @skinning_v17 **[New Infolabel]** \link ListItem_RatingAndVotes `ListItem.RatingAndVotes([name])`\endlink +/// @skinning_v17 **[Infolabel Updated]** \link ListItem_RatingAndVotes `ListItem.RatingAndVotes`\endlink +/// now available for albums/songs. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Mood`</b>, +/// \anchor ListItem_Mood +/// _string_, +/// @return The mood of the selected song. +/// <p><hr> +/// @skinning_v17 **[New Infolabel]** \link ListItem_Mood `ListItem.Mood`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Mpaa`</b>, +/// \anchor ListItem_Mpaa +/// _string_, +/// @return The MPAA rating of the currently selected movie in a container. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.ProgramCount`</b>, +/// \anchor ListItem_ProgramCount +/// _string_, +/// @return The number of times an xbe has been run from "my programs". +/// @todo description might be outdated +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Duration`</b>, +/// \anchor ListItem_Duration +/// _string_, +/// @return The duration of the currently selected item in a container +/// in the format <b>hh:mm:ss</b>. +/// @note <b>hh:</b> will be omitted if hours value is zero. +/// <p><hr> +/// @skinning_v18 **[Infolabel Updated]** \link ListItem_Duration `ListItem.Duration`\endlink will +/// return <b>hh:mm:ss</b> instead of the duration in minutes. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Duration(format)`</b>, +/// \anchor ListItem_Duration_format +/// _string_, +/// @return The duration of the currently selected item in a container in +/// different formats. +/// @param format [opt] The format of the return time value. +/// See \ref TIME_FORMAT for the list of possible values. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.DBTYPE`</b>, +/// \anchor ListItem_DBTYPE +/// _string_, +/// @return The database type of the \ref ListItem_DBID "ListItem.DBID" for videos (movie\, set\, +/// genre\, actor\, tvshow\, season\, episode). It does not return any value +/// for the music library. +/// @note Beware with season\, the "*all seasons" entry does +/// give a DBTYPE "season" and a DBID\, but you can't get the details of that +/// entry since it's a virtual entry in the Video Library. +/// <p><hr> +/// @skinning_v17 **[Infolabel Updated]** \link ListItem_DBTYPE `ListItem.DBTYPE`\endlink +/// now available in the music library. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.DBID`</b>, +/// \anchor ListItem_DBID +/// _string_, +/// @return The database id of the currently selected listitem in a container. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Appearances`</b>, +/// \anchor ListItem_Appearances +/// _string_, +/// @return The number of movies featuring the selected actor / directed by the selected director. +/// <p><hr> +/// @skinning_v17 **[New Infolabel]** \link ListItem_Appearances `ListItem.Appearances`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Cast`</b>, +/// \anchor ListItem_Cast +/// _string_, +/// @return A concatenated string of cast members of the currently selected +/// movie\, for use in dialogvideoinfo.xml. +/// <p><hr> +/// @skinning_v15 **[Infolabel Updated]** \link ListItem_Cast `ListItem.Cast`\endlink +/// also supports EPG. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.CastAndRole`</b>, +/// \anchor ListItem_CastAndRole +/// _string_, +/// @return A concatenated string of cast members and roles of the currently +/// selected movie\, for use in dialogvideoinfo.xml. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Studio`</b>, +/// \anchor ListItem_Studio +/// _string_, +/// @return The studio of current selected Music Video in a container. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Top250`</b>, +/// \anchor ListItem_Top250 +/// _string_, +/// @return The IMDb top250 position of the currently selected listitem in a +/// container. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Trailer`</b>, +/// \anchor ListItem_Trailer +/// _string_, +/// @return The full trailer path with filename of the currently selected +/// movie in a container. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Writer`</b>, +/// \anchor ListItem_Writer +/// _string_, +/// @return The name of Writer of current Video in a container. +/// <p><hr> +/// @skinning_v15 **[Infolabel Updated]** \link ListItem_Writer `ListItem.Writer`\endlink +/// also supports EPG. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Tag`</b>, +/// \anchor ListItem_Tag +/// _string_, +/// @return The summary of current Video in a container. +/// <p><hr> +/// @skinning_v17 **[New Infolabel]** \link ListItem_Tag `ListItem.Tag`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Tagline`</b>, +/// \anchor ListItem_Tagline +/// _string_, +/// @return A Small Summary of current Video in a container. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.PlotOutline`</b>, +/// \anchor ListItem_PlotOutline +/// _string_, +/// @return A small Summary of current Video in a container. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Plot`</b>, +/// \anchor ListItem_Plot +/// _string_, +/// @return The complete Text Summary of Video in a container. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.IMDBNumber`</b>, +/// \anchor ListItem_IMDBNumber +/// _string_, +/// @return The IMDb ID of the selected Video in a container. +/// <p><hr> +/// @skinning_v15 **[New Infolabel]** \link ListItem_IMDBNumber `ListItem.IMDBNumber`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.EpisodeName`</b>, +/// \anchor ListItem_EpisodeName +/// _string_, +/// @return The name of the episode if the selected EPG item is a TV Show (PVR). +/// <p><hr> +/// @skinning_v15 **[New Infolabel]** \link ListItem_EpisodeName `ListItem.EpisodeName`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.PercentPlayed`</b>, +/// \anchor ListItem_PercentPlayed +/// _string_, +/// @return The percentage value [0-100] of how far the selected video has been +/// played. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.LastPlayed`</b>, +/// \anchor ListItem_LastPlayed +/// _string_, +/// @return The last play date of Video in a container. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.PlayCount`</b>, +/// \anchor ListItem_PlayCount +/// _string_, +/// @return The playcount of Video in a container. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.ChannelName`</b>, +/// \anchor ListItem_ChannelName +/// _string_, +/// @return The name of current selected TV channel in a container. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.VideoCodec`</b>, +/// \anchor ListItem_VideoCodec +/// _string_, +/// @return The video codec of the currently selected video. Common values: +/// - <b>3iv2</b> +/// - <b>av1</b> +/// - <b>avc1</b> +/// - <b>div2</b> +/// - <b>div3</b> +/// - <b>divx</b> +/// - <b>divx 4</b> +/// - <b>dx50</b> +/// - <b>flv</b> +/// - <b>h264</b> +/// - <b>microsoft</b> +/// - <b>mp42</b> +/// - <b>mp43</b> +/// - <b>mp4v</b> +/// - <b>mpeg1video</b> +/// - <b>mpeg2video</b> +/// - <b>mpg4</b> +/// - <b>rv40</b> +/// - <b>svq1</b> +/// - <b>svq3</b> +/// - <b>theora</b> +/// - <b>vp6f</b> +/// - <b>wmv2</b> +/// - <b>wmv3</b> +/// - <b>wvc1</b> +/// - <b>xvid</b> +/// - etc +/// <p> +/// } +/// \table_row3{ <b>`ListItem.VideoResolution`</b>, +/// \anchor ListItem_VideoResolution +/// _string_, +/// @return The resolution of the currently selected video. Possible values: +/// - <b>480</b> +/// - <b>576</b> +/// - <b>540</b> +/// - <b>720</b> +/// - <b>1080</b> +/// - <b>4K</b> +/// - <b>8K</b> +/// @note 540 usually means a widescreen +/// format (around 960x540) while 576 means PAL resolutions (normally +/// 720x576)\, therefore 540 is actually better resolution than 576. +/// <p><hr> +/// @skinning_v18 **[Updated Infolabel]** \link ListItem_VideoResolution ListItem.VideoResolution\endlink +/// added <b>8K</b> as a possible value. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.VideoAspect`</b>, +/// \anchor ListItem_VideoAspect +/// _string_, +/// @return The aspect ratio of the currently selected video. Possible values: +/// - <b>1.00</b> +/// - <b>1.19</b> +/// - <b>1.33</b> +/// - <b>1.37</b> +/// - <b>1.66</b> +/// - <b>1.78</b> +/// - <b>1.85</b> +/// - <b>2.00</b> +/// - <b>2.20</b> +/// - <b>2.35</b> +/// - <b>2.40</b> +/// - <b>2.55</b> +/// - <b>2.76</b> +/// <p> +/// } +/// \table_row3{ <b>`ListItem.AudioCodec`</b>, +/// \anchor ListItem_AudioCodec +/// _string_, +/// @return The audio codec of the currently selected video. Common values: +/// - <b>aac</b> +/// - <b>ac3</b> +/// - <b>cook</b> +/// - <b>dca</b> +/// - <b>dtshd_hra</b> +/// - <b>dtshd_ma</b> +/// - <b>eac3</b> +/// - <b>mp1</b> +/// - <b>mp2</b> +/// - <b>mp3</b> +/// - <b>pcm_s16be</b> +/// - <b>pcm_s16le</b> +/// - <b>pcm_u8</b> +/// - <b>truehd</b> +/// - <b>vorbis</b> +/// - <b>wmapro</b> +/// - <b>wmav2</b> +/// <p> +/// } +/// \table_row3{ <b>`ListItem.AudioChannels`</b>, +/// \anchor ListItem_AudioChannels +/// _string_, +/// @return The number of audio channels of the currently selected video. Possible values: +/// - <b>1</b> +/// - <b>2</b> +/// - <b>4</b> +/// - <b>5</b> +/// - <b>6</b> +/// - <b>8</b> +/// - <b>10</b> +/// <p><hr> +/// @skinning_v16 **[Infolabel Updated]** \link ListItem_AudioChannels `ListItem.AudioChannels`\endlink +/// if a video contains no audio\, these infolabels will now return empty. +/// (they used to return 0) +/// <p> +/// } +/// \table_row3{ <b>`ListItem.AudioLanguage`</b>, +/// \anchor ListItem_AudioLanguage +/// _string_, +/// @return The audio language of the currently selected video (an +/// ISO 639-2 three character code: e.g. eng\, epo\, deu) +/// <p> +/// } +/// \table_row3{ <b>`ListItem.SubtitleLanguage`</b>, +/// \anchor ListItem_SubtitleLanguage +/// _string_, +/// @return The subtitle language of the currently selected video (an +/// ISO 639-2 three character code: e.g. eng\, epo\, deu) +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Property(AudioCodec.[n])`</b>, +/// \anchor ListItem_Property_AudioCodec +/// _string_, +/// @return The audio codec of the currently selected video +/// @param n - the number of the audiostream (values: see \ref ListItem_AudioCodec "ListItem.AudioCodec") +/// <p><hr> +/// @skinning_v16 **[New Infolabel]** \link ListItem_Property_AudioCodec `ListItem.Property(AudioCodec.[n])`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Property(AudioChannels.[n])`</b>, +/// \anchor ListItem_Property_AudioChannels +/// _string_, +/// @return The number of audio channels of the currently selected video +/// @param n - the number of the audiostream (values: see +/// \ref ListItem_AudioChannels "ListItem.AudioChannels") +/// <p><hr> +/// @skinning_v16 **[New Infolabel]** \link ListItem_Property_AudioChannels `ListItem.Property(AudioChannels.[n])`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Property(AudioLanguage.[n])`</b>, +/// \anchor ListItem_Property_AudioLanguage +/// _string_, +/// @return The audio language of the currently selected video +/// @param n - the number of the audiostream (values: see \ref ListItem_AudioLanguage "ListItem.AudioLanguage") +/// <p><hr> +/// @skinning_v16 **[New Infolabel]** \link ListItem_Property_AudioLanguage `ListItem.Property(AudioLanguage.[n])`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Property(SubtitleLanguage.[n])`</b>, +/// \anchor ListItem_Property_SubtitleLanguage +/// _string_, +/// @return The subtitle language of the currently selected video +/// @param n - the number of the subtitle (values: see \ref ListItem_SubtitleLanguage "ListItem.SubtitleLanguage") +/// <p><hr> +/// @skinning_v16 **[New Infolabel]** \link ListItem_Property_SubtitleLanguage `ListItem.Property(SubtitleLanguage.[n])`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Property(Addon.Disclaimer)`</b>, +/// \anchor ListItem_Property_AddonDisclaimer +/// _string_, +/// @return The disclaimer of the currently selected addon. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Property(Addon.Changelog)`</b>, +/// \anchor ListItem_Property_AddonChangelog +/// _string_, +/// @return The changelog of the currently selected addon. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Property(Addon.ID)`</b>, +/// \anchor ListItem_Property_AddonID +/// _string_, +/// @return The identifier of the currently selected addon. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Property(Addon.Status)`</b>, +/// \anchor ListItem_Property_AddonStatus +/// _string_, +/// @return The status of the currently selected addon. +/// @todo missing reference in GuiInfoManager.cpp making it hard to track. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Property(Addon.Orphaned)`</b>, +/// \anchor ListItem_Property_AddonOrphaned +/// _boolean_, +/// @return **True** if the Addon is orphanad. +/// @todo missing reference in GuiInfoManager.cpp making it hard to track. +/// <p><hr> +/// @skinning_v17 **[New Boolean Condition]** \link ListItem_Property_AddonOrphaned `ListItem.Property(Addon.Orphaned)`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Property(Addon.Path)`</b>, +/// \anchor ListItem_Property_AddonPath +/// _string_, +/// @return The path of the currently selected addon. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.StartTime`</b>, +/// \anchor ListItem_StartTime +/// _string_, +/// @return The start time of current selected TV programme in a container. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.EndTime`</b>, +/// \anchor ListItem_EndTime +/// _string_, +/// @return The end time of current selected TV programme in a container. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.StartDate`</b>, +/// \anchor ListItem_StartDate +/// _string_, +/// @return The start date of current selected TV programme in a container. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.EndDate`</b>, +/// \anchor ListItem_EndDate +/// _string_, +/// @return The end date of current selected TV programme in a container. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.NextTitle`</b>, +/// \anchor ListItem_NextTitle +/// _string_, +/// @return The title of the next item (PVR). +/// <p> +/// } +/// \table_row3{ <b>`ListItem.NextGenre`</b>, +/// \anchor ListItem_NextGenre +/// _string_, +/// @return The genre of the next item (PVR). +/// <p> +/// } +/// \table_row3{ <b>`ListItem.NextPlot`</b>, +/// \anchor ListItem_NextPlot +/// _string_, +/// @return The plot of the next item (PVR). +/// <p> +/// } +/// \table_row3{ <b>`ListItem.NextPlotOutline`</b>, +/// \anchor ListItem_NextPlotOutline +/// _string_, +/// @return The plot outline of the next item (PVR). +/// <p> +/// } +/// \table_row3{ <b>`ListItem.NextStartTime`</b>, +/// \anchor ListItem_NextStartTime +/// _string_, +/// @return The start time of the next item (PVR). +/// <p> +/// } +/// \table_row3{ <b>`ListItem.NextEndTime`</b>, +/// \anchor ListItem_NextEndTime +/// _string_, +/// @return The end of the next item (PVR). +/// <p> +/// } +/// \table_row3{ <b>`ListItem.NextStartDate`</b>, +/// \anchor ListItem_NextStartDate +/// _string_, +/// @return The start date of the next item (PVR). +/// <p> +/// } +/// \table_row3{ <b>`ListItem.NextEndDate`</b>, +/// \anchor ListItem_NextEndDate +/// _string_, +/// @return The end date of the next item (PVR). +/// <p> +/// } +/// \table_row3{ <b>`ListItem.NextDuration`</b>, +/// \anchor ListItem_NextDuration +/// _string_, +/// @return The duration of the next item (PVR) in the format <b>hh:mm:ss</b>. +/// @note <b>hh:</b> will be omitted if hours value is zero. +/// <p><hr> +/// @skinning_v18 **[New Infolabel]** \link ListItem_NextDuration `ListItem.NextDuration`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.NextDuration(format)`</b>, +/// \anchor ListItem_NextDuration_format +/// _string_, +/// @return The duration of the next item (PVR) in different formats. +/// @param format [opt] The format of the return time value. +/// See \ref TIME_FORMAT for the list of possible values. +/// <p><hr> +/// @skinning_v18 **[New Infolabel]** \link ListItem_NextDuration_format `ListItem.NextDuration(format)`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.ChannelGroup`</b>, +/// \anchor ListItem_ChannelGroup +/// _string_, +/// @return The channel group of the selected item (PVR). +/// <p> +/// } +/// \table_row3{ <b>`ListItem.ChannelNumberLabel`</b>, +/// \anchor ListItem_ChannelNumberLabel +/// _string_, +/// @return The channel and subchannel number of the currently selected channel that's +/// currently playing (PVR). +/// <p><hr> +/// @skinning_v14 **[New Infolabel]** \link ListItem_ChannelNumberLabel `ListItem.ChannelNumberLabel`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Progress`</b>, +/// \anchor ListItem_Progress +/// _string_, +/// @return The part of the programme that's been played (PVR). +/// <p> +/// } +/// \table_row3{ <b>`ListItem.StereoscopicMode`</b>, +/// \anchor ListItem_StereoscopicMode +/// _string_, +/// @return The stereomode of the selected video: +/// - <b>mono</b> +/// - <b>split_vertical</b> +/// - <b>split_horizontal</b> +/// - <b>row_interleaved</b> +/// - <b>anaglyph_cyan_red</b> +/// - <b>anaglyph_green_magenta</b> +/// <p><hr> +/// @skinning_v13 **[New Infolabel]** \link ListItem_StereoscopicMode `ListItem.StereoscopicMode`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.HasTimerSchedule`</b>, +/// \anchor ListItem_HasTimerSchedule +/// _boolean_, +/// @return **True** if the item was scheduled by a timer rule (PVR). +/// <p><hr> +/// @skinning_v16 **[New Boolean Condition]** \ref ListItem_HasTimerSchedule "ListItem.HasTimerSchedule" +/// <p> +/// } +/// \table_row3{ <b>`ListItem.HasReminder`</b>, +/// \anchor ListItem_HasReminder +/// _boolean_, +/// @return **True** if the item has a reminder set (PVR). +/// <p><hr> +/// @skinning_v19 **[New Boolean Condition]** \ref ListItem_HasReminder "ListItem.HasReminder" +/// <p> +/// } +/// \table_row3{ <b>`ListItem.HasReminderRule`</b>, +/// \anchor ListItem_ListItem.HasReminderRule +/// _boolean_, +/// @return **True** if the item was scheduled by a reminder timer rule (PVR). +/// <p><hr> +/// @skinning_v19 **[New Boolean Condition]** \ref ListItem_HasReminderRule "ListItem.HasReminderRule" +/// <p> +/// } +/// \table_row3{ <b>`ListItem.HasRecording`</b>, +/// \anchor ListItem_HasRecording +/// _boolean_, +/// @return **True** if a given epg tag item currently gets recorded or has been recorded. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.TimerHasError`</b>, +/// \anchor ListItem_TimerHasError +/// _boolean_, +/// @return **True** if the item has a timer and it won't be recorded because of an error (PVR). +/// <p><hr> +/// @skinning_v17 **[New Boolean Condition]** \ref ListItem_TimerHasError "ListItem.TimerHasError" +/// <p> +/// } +/// \table_row3{ <b>`ListItem.TimerHasConflict`</b>, +/// \anchor ListItem_TimerHasConflict +/// _boolean_, +/// @return **True** if the item has a timer and it won't be recorded because of a conflict (PVR). +/// <p><hr> +/// @skinning_v17 **[New Boolean Condition]** \ref ListItem_TimerHasConflict "ListItem.TimerHasConflict" +/// <p> +/// } +/// \table_row3{ <b>`ListItem.TimerIsActive`</b>, +/// \anchor ListItem_TimerIsActive +/// _boolean_, +/// @return **True** if the item has a timer that will be recorded\, i.e. the timer is enabled (PVR). +/// <p><hr> +/// @skinning_v17 **[New Boolean Condition]** \ref ListItem_TimerIsActive "ListItem.TimerIsActive" +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Comment`</b>, +/// \anchor ListItem_Comment +/// _string_, +/// @return The comment assigned to the item (PVR/MUSIC). +/// <p> +/// } +/// \table_row3{ <b>`ListItem.TimerType`</b>, +/// \anchor ListItem_TimerType +/// _string_, +/// @return The type of the PVR timer / timer rule item as a human readable string. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.EpgEventTitle`</b>, +/// \anchor ListItem_EpgEventTitle +/// _string_, +/// @return The title of the epg event associated with the item\, if any. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.EpgEventIcon`</b>, +/// \anchor ListItem_EpgEventIcon +/// _string_, +/// @return The thumbnail for the EPG event associated with the item (if it exists). +/// <p><hr> +/// @skinning_v18 **[New Infolabel]** \link ListItem_EpgEventIcon `ListItem.EpgEventIcon`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.InProgress`</b>, +/// \anchor ListItem_InProgress +/// _boolean_, +/// @return **True** if the EPG event item is currently active (time-wise). +/// <p> +/// } +/// \table_row3{ <b>`ListItem.IsParentFolder`</b>, +/// \anchor ListItem_IsParentFolder +/// _boolean_, +/// @return **True** if the current list item is the goto parent folder '..'. +/// <p><hr> +/// @skinning_v17 **[New Boolean Condition]** \link ListItem_IsParentFolder `ListItem.IsParentFolder`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.AddonName`</b>, +/// \anchor ListItem_AddonName +/// _string_, +/// @return The name of the currently selected addon. +/// <p><hr> +/// @skinning_v17 **[Infolabel Updated]** \link ListItem_AddonName `ListItem.AddonName`\endlink +/// replaces `ListItem.Property(Addon.Name)`. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.AddonVersion`</b>, +/// \anchor ListItem_AddonVersion +/// _string_, +/// @return The version of the currently selected addon. +/// <p><hr> +/// @skinning_v17 **[Infolabel Updated]** \link ListItem_AddonVersion `ListItem.AddonVersion`\endlink +/// replaces `ListItem.Property(Addon.Version)`. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.AddonCreator`</b>, +/// \anchor ListItem_AddonCreator +/// _string_, +/// @return The name of the author the currently selected addon. +/// <p><hr> +/// @skinning_v17 **[Infolabel Updated]** \link ListItem_AddonCreator `ListItem.AddonCreator`\endlink +/// replaces `ListItem.Property(Addon.Creator)`. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.AddonSummary`</b>, +/// \anchor ListItem_AddonSummary +/// _string_, +/// @return A short description of the currently selected addon. +/// <p><hr> +/// @skinning_v17 **[Infolabel Updated]** \link ListItem_AddonSummary `ListItem.AddonSummary`\endlink +/// replaces `ListItem.Property(Addon.Summary)`. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.AddonDescription`</b>, +/// \anchor ListItem_AddonDescription +/// _string_, +/// @return The full description of the currently selected addon. +/// <p><hr> +/// @skinning_v17 **[Infolabel Updated]** \link ListItem_AddonDescription `ListItem.AddonDescription`\endlink +/// replaces `ListItem.Property(Addon.Description)`. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.AddonDisclaimer`</b>, +/// \anchor ListItem_AddonDisclaimer +/// _string_, +/// @return The disclaimer of the currently selected addon. +/// <p><hr> +/// @skinning_v17 **[Infolabel Updated]** \link ListItem_AddonDisclaimer `ListItem.AddonDisclaimer`\endlink +/// replaces `ListItem.Property(Addon.Disclaimer)`. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.AddonBroken`</b>, +/// \anchor ListItem_AddonBroken +/// _string_, +/// @return A message when the addon is marked as broken in the repo. +/// @deprecated but still available\, use \ref ListItem_AddonLifecycleDesc "ListItem.AddonLifecycleDesc" +/// instead +/// <p><hr> +/// @skinning_v17 **[Infolabel Updated]** \link ListItem_AddonBroken `ListItem.AddonBroken`\endlink +/// replaces `ListItem.Property(Addon.Broken)`. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.AddonLifecycleType`</b>, +/// \anchor ListItem_AddonLifecycleType +/// _string_, +/// @return String name when the addon is marked as special condition in the repo. +/// - <b>Label: 24169 (Normal)</b> - Used if an add-on has no special lifecycle state which is the default state +/// - <b>Label: 24170 (Deprecated)</b> - The add-on should be marked as deprecated but is still usable +/// - <b>Label: 24171 (Broken)</b> - The add-on should marked as broken in the repository +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link ListItem_AddonLifecycleType `ListItem.AddonLifecycleType`\endlink +/// replaces `ListItem.AddonBroken`. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.AddonLifecycleDesc`</b>, +/// \anchor ListItem_AddonLifecycleDesc +/// _string_, +/// @return From addon defined message text when it is marked as special condition inside repository. +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link ListItem_AddonLifecycleDesc `ListItem.AddonLifecycleDesc``\endlink +/// replaces `ListItem.AddonBroken`. +/// <p> +/// } + +/// \table_row3{ <b>`ListItem.AddonType`</b>, +/// \anchor ListItem_AddonType +/// _string_, +/// @return The type (screensaver\, script\, skin\, etc...) of the currently selected addon. +/// <p><hr> +/// @skinning_v17 **[Infolabel Updated]** \link ListItem_AddonType `ListItem.AddonType`\endlink +/// replaces `ListItem.Property(Addon.Type)`. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.AddonInstallDate`</b>, +/// \anchor ListItem_AddonInstallDate +/// _string_, +/// @return The date the addon was installed. +/// <p><hr> +/// @skinning_v17 **[New Infolabel]** \link ListItem_AddonInstallDate `ListItem.AddonInstallDate`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.AddonLastUpdated`</b>, +/// \anchor ListItem_AddonLastUpdated +/// _string_, +/// @return The date the addon was last updated. +/// <p><hr> +/// @skinning_v17 **[New Infolabel]** \link ListItem_AddonLastUpdated `ListItem.AddonLastUpdated`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.AddonLastUsed`</b>, +/// \anchor ListItem_AddonLastUsed +/// _string_, +/// @return The date the addon was used last. +/// <p><hr> +/// @skinning_v17 **[New Infolabel]** \link ListItem_AddonLastUsed `ListItem.AddonLastUsed`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.AddonNews`</b>, +/// \anchor ListItem_AddonNews +/// _string_, +/// @return A brief changelog\, taken from the addons' `addon.xml` file. +/// <p><hr> +/// @skinning_v17 **[New Infolabel]** \link ListItem_AddonNews `ListItem.AddonNews`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.AddonSize`</b>, +/// \anchor ListItem_AddonSize +/// _string_, +/// @return The filesize of the addon. +/// <p><hr> +/// @skinning_v17 **[New Infolabel]** \link ListItem_AddonSize `ListItem.AddonSize`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.AddonOrigin`</b>, +/// \anchor ListItem_AddonOrigin +/// _string_, +/// @return The name of the repository the add-on originates from. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.ExpirationDate`</b>, +/// \anchor ListItem_ExpirationDate +/// _string_, +/// @return The expiration date of the selected item in a container\, empty string if not supported. +/// <p> +/// } +/// \table_row3{ <b>`ListItem.ExpirationTime`</b>, +/// \anchor ListItem_ExpirationTime +/// _string_, +/// @return The expiration time of the selected item in a container\, empty string if not supported +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Art(type)`</b>, +/// \anchor ListItem_Art_Type +/// _string_, +/// @return A particular art type for an item. +/// @param type - the art type. It can be any value (set by scripts and scrappers). Common values: +/// - <b>clearart</b> - the clearart (if it exists) of the currently selected movie or tv show. +/// - <b>clearlogo</b> - the clearlogo (if it exists) of the currently selected movie or tv show. +/// - <b>landscape</b> - the 16:9 landscape (if it exists) of the currently selected item. +/// - <b>thumb</b> - the thumbnail of the currently selected item. +/// - <b>poster</b> - the poster of the currently selected movie or tv show. +/// - <b>banner</b> - the banner of the currently selected tv show. +/// - <b>fanart</b> - the fanart image of the currently selected item. +/// - <b>set.fanart</b> - the fanart image of the currently selected movieset. +/// - <b>tvshow.poster</b> - the tv show poster of the parent container. +/// - <b>tvshow.banner</b> - the tv show banner of the parent container. +/// - <b>tvshow.clearlogo</b> - the tv show clearlogo (if it exists) of the parent container. +/// - <b>tvshow.landscape</b> - the tv show landscape (if it exists) of the parent container. +/// - <b>tvshow.clearart</b> - the tv show clearart (if it exists) of the parent container. +/// - <b>season.poster</b> - the season poster of the currently selected season. (Only available in DialogVideoInfo.xml). +/// - <b>season.banner</b> - the season banner of the currently selected season. (Only available in DialogVideoInfo.xml). +/// - <b>season.fanart</b> - the fanart image of the currently selected season. (Only available in DialogVideoInfo.xml) +/// - <b>artist.thumb</b> - the artist thumb of an album or song item. +/// - <b>artist.fanart</b> - the artist fanart of an album or song item. +/// - <b>album.thumb</b> - the album thumb (cover) of a song item. +/// - <b>artist[n].*</b> - in case a song has multiple artists\, a digit is added to the art type for the 2nd artist onwards +/// e.g `Listitem.Art(artist1.thumb)` gives the thumb of the 2nd artist of a song. +/// - <b>albumartist[n].*</b> - n case a song has multiple album artists\, a digit is added to the art type for the 2nd artist +/// onwards e.g `Listitem.Art(artist1.thumb)` gives the thumb of the 2nd artist of a song. +/// <p> +/// @todo Find a better way of finding the art types instead of manually defining them here. +/// <p><hr> +/// @skinning_v18 **[Infolabel Updated]** \link ListItem_Art_Type `ListItem.Art(type)`\endlink add <b>artist[n].*</b> and +/// <b>albumartist[n].*</b> as possible targets for <b>type</b> +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Platform`</b>, +/// \anchor ListItem_Platform +/// _string_, +/// @return The game platform (e.g. "Atari 2600") (RETROPLAYER). +/// <p><hr> +/// @skinning_v18 **[New Infolabel]** \link ListItem_Platform `ListItem.Platform`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Genres`</b>, +/// \anchor ListItem_Genres +/// _string_, +/// @return The game genres (e.g. "["Action"\,"Strategy"]") (RETROPLAYER). +/// <p><hr> +/// @skinning_v18 **[New Infolabel]** \link ListItem_Genres `ListItem.Genres`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Publisher`</b>, +/// \anchor ListItem_Publisher +/// _string_, +/// @return The game publisher (e.g. "Nintendo") (RETROPLAYER). +/// <p><hr> +/// @skinning_v18 **[New Infolabel]** \link ListItem_Publisher `ListItem.Publisher`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Developer`</b>, +/// \anchor ListItem_Developer +/// _string_, +/// @return The game developer (e.g. "Square") (RETROPLAYER). +/// <p><hr> +/// @skinning_v18 **[New Infolabel]** \link ListItem_Developer `ListItem.Developer`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Overview`</b>, +/// \anchor ListItem_Overview +/// _string_, +/// @return The game overview/summary (RETROPLAYER). +/// <p><hr> +/// @skinning_v18 **[New Infolabel]** \link ListItem_Overview `ListItem.Overview`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.GameClient`</b>, +/// \anchor ListItem_GameClient +/// _string_, +/// @return The add-on ID of the game client (a.k.a. emulator) to use for playing the game +/// (e.g. game.libretro.fceumm) (RETROPLAYER). +/// <p><hr> +/// @skinning_v18 **[New Infolabel]** \link ListItem_GameClient `ListItem.GameClient`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Property(propname)`</b>, +/// \anchor ListItem_Property_Propname +/// _string_, +/// @return The requested property of a ListItem. +/// @param propname - the property requested +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Property(Role.Composer)`</b>, +/// \anchor ListItem_Property_Role_Composer +/// _string_, +/// @return The name of the person who composed the selected song. +/// <p><hr> +/// @skinning_v17 **[New Infolabel]** \link ListItem_Property_Role_Composer `ListItem.Property(Role.Composer)`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Property(Role.Conductor)`</b>, +/// \anchor ListItem_Property_Role_Conductor +/// _string_, +/// @return The name of the person who conducted the selected song. +/// <p><hr> +/// @skinning_v17 **[New Infolabel]** \link ListItem_Property_Role_Conductor `ListItem.Property(Role.Conductor)`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Property(Role.Orchestra)`</b>, +/// \anchor ListItem_Property_Role_Orchestra +/// _string_, +/// @return The name of the orchestra performing the selected song. +/// <p><hr> +/// @skinning_v17 **[New Infolabel]** \link ListItem_Property_Role_Orchestra `ListItem.Property(Role.Orchestra)`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Property(Role.Lyricist)`</b>, +/// \anchor ListItem_Property_Role_Lyricist +/// _string_, +/// @return The name of the person who wrote the lyrics of the selected song. +/// <p><hr> +/// @skinning_v17 **[New Infolabel]** \link ListItem_Property_Role_Lyricist `ListItem.Property(Role.Lyricist)`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Property(Role.Remixer)`</b>, +/// \anchor ListItem_Property_Role_Remixer +/// _string_, +/// @return The name of the person who remixed the selected song. +/// <p><hr> +/// @skinning_v17 **[New Infolabel]** \link ListItem_Property_Role_Remixer `ListItem.Property(Role.Remixer)`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Property(Role.Arranger)`</b>, +/// \anchor ListItem_Property_Role_Arranger +/// _string_, +/// @return The name of the person who arranged the selected song. +/// <p><hr> +/// @skinning_v17 **[New Infolabel]** \link ListItem_Property_Role_Arranger `ListItem.Property(Role.Arranger)`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Property(Role.Engineer)`</b>, +/// \anchor ListItem_Property_Role_Engineer +/// _string_, +/// @return The name of the person who was the engineer of the selected song. +/// <p><hr> +/// @skinning_v17 **[New Infolabel]** \link ListItem_Property_Role_Engineer `ListItem.Property(Role.Engineer)`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Property(Role.Producer)`</b>, +/// \anchor ListItem_Property_Role_Producer +/// _string_, +/// @return The name of the person who produced the selected song. +/// <p><hr> +/// @skinning_v17 **[New Infolabel]** \link ListItem_Property_Role_Producer `ListItem.Property(Role.Producer)`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Property(Role.DJMixer)`</b>, +/// \anchor ListItem_Property_Role_DJMixer +/// _string_, +/// @return The name of the dj who remixed the selected song. +/// <p><hr> +/// @skinning_v17 **[New Infolabel]** \link ListItem_Property_Role_DJMixer `ListItem.Property(Role.DJMixer)`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Property(Role.Mixer)`</b>, +/// \anchor ListItem_Property_Role_Mixer +/// _string_, +/// @return The name of the person who mixed the selected song. +/// <p><hr> +/// @skinning_v17 **[New Infolabel]** \link ListItem_Property_Role_DJMixer `ListItem.Property(Role.DJMixer)`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Property(Game.VideoFilter)`</b>, +/// \anchor ListItem_Property_Game_VideoFilter +/// _string_, +/// @return The video filter of the list item representing a +/// gamewindow control (RETROPLAYER). +/// See \link RetroPlayer_VideoFilter RetroPlayer.VideoFilter \endlink +/// for the possible values. +/// <p><hr> +/// @skinning_v18 **[New Infolabel]** \link ListItem_Property_Game_VideoFilter `ListItem.Property(Game.VideoFilter)`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Property(Game.StretchMode)`</b>, +/// \anchor ListItem_Property_Game_StretchMode +/// _string_, +/// @return The stretch mode of the list item representing a +/// gamewindow control (RETROPLAYER). +/// See \link RetroPlayer_StretchMode RetroPlayer.StretchMode \endlink +/// for the possible values. +/// <p><hr> +/// @skinning_v18 **[New Infolabel]** \link ListItem_Property_Game_StretchMode `ListItem.Property(Game.StretchMode)`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.Property(Game.VideoRotation)`</b>, +/// \anchor ListItem_Property_Game_VideoRotation +/// _integer_, +/// @return The video rotation of the list item representing a +/// gamewindow control (RETROPLAYER). +/// See \link RetroPlayer_VideoRotation RetroPlayer.VideoRotation \endlink +/// for the possible values. +/// <p><hr> +/// @skinning_v18 **[New Infolabel]** \link ListItem_Property_Game_VideoRotation `ListItem.Property(Game.VideoRotation)`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.ParentalRating`</b>, +/// \anchor ListItem_ParentalRating +/// _string_, +/// @return The parental rating of the list item (PVR). +/// <p> +/// } +/// \table_row3{ <b>`ListItem.CurrentItem`</b>, +/// \anchor ListItem_CurrentItem +/// _string_, +/// @return The current index of the item in a container starting at 1. +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link ListItem_CurrentItem `ListItem.CurrentItem`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.IsNew`</b>, +/// \anchor ListItem_IsNew +/// _boolean_, +/// @return **True** if the item is new (for example\, a Live TV show that will be first aired). +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link ListItem_IsNew `ListItem.IsNew`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.IsPremiere`</b>, +/// \anchor ListItem_IsPremiere +/// _boolean_, +/// @return **True** if the item is a premiere (for example\, a Movie first showing or season first on Live TV). +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link ListItem_IsPremiere `ListItem.IsPremiere`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.IsFinale`</b>, +/// \anchor ListItem_IsFinale +/// _boolean_, +/// @return **True** if the item is a finale (for example\, a season finale showing on Live TV). +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link ListItem_IsFinale `ListItem.IsFinale`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.IsLive`</b>, +/// \anchor ListItem_IsLive +/// _boolean_, +/// @return **True** if the item is live (for example\, a Live TV sports event). +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link ListItem_IsLive `ListItem.IsLive`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.DiscTitle`</b>, +/// \anchor ListItem_DiscTitle +/// _string_, +/// @return The disc title of the currently selected album or song. +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link ListItem_DiscTitle `ListItem.DiscTitle`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.IsBoxset`</b>, +/// \anchor ListItem_IsBoxset +/// _boolean_, +/// @return **True** if the item is part of a boxset album. +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link ListItem_IsBoxset `ListItem.IsBoxset`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.TotalDiscs`</b>, +/// \anchor ListItem_TotalDiscs +/// _boolean_, +/// @return The total number of discs belonging to an album. +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link ListItem_TotalDiscs `ListItem.TotalDiscs`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.ReleaseDate`</b>, +/// \anchor ListItem_ReleaseDate +/// _string_, +/// @return The release date of the item. +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link ListItem_ReleaseDate `ListItem.ReleaseDate`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.OriginalDate`</b>, +/// \anchor ListItem_OriginalDate +/// _string_, +/// @return The original release date of the item. Can be full or partial date. +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link ListItem_OriginalDate `ListItem.OriginalDate`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.BPM`</b>, +/// \anchor ListItem_BPM +/// _string_, +/// @return The BPM of a song. +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link ListItem_BPM `ListItem.BPM`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.UniqueID(name)`</b>, +/// \anchor ListItem_UniqueID +/// _string_, +/// @return The scraped metadata id of the currently selected item in a container\, +/// for use in dialogvideoinfo.xml. +/// @param name - the name of the metadata provider. +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link ListItem_UniqueID `ListItem.UniqueID(name)`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.BitRate`</b>, +/// \anchor ListItem_BitRate +/// _string_, +/// @return The bitrate of a song. Actual rate for CBR\, average rate for VBR. +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link ListItem_BitRate `ListItem.BitRate`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.SampleRate`</b>, +/// \anchor ListItem_SampleRate +/// _string_, +/// @return The sample rate of a song / 1000.0 eg 44.1\, 48\, 96 etc. +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link ListItem_SampleRate `ListItem.SampleRate`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.MusicChannels`</b>, +/// \anchor ListItem_MusicChannels +/// _string_, +/// @return The number of audio channels of a song. +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link ListItem_No_Of_Channels `ListItem.NoOfChannels`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.TvShowDBID`</b>, +/// \anchor ListItem_TvShowDBID +/// _string_, +/// @return The database id of the TvShow for the currently selected Season or Episode. +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link ListItem_TvShowDBID `ListItem.TvShowDBID`\endlink +/// <p> +/// } +/// \table_row3{ <b>`ListItem.AlbumStatus`</b>, +/// \anchor ListItem_AlbumStatus +/// _string_, +/// @return The Musicbrainz release status of the album (official, bootleg, promotion etc) +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link ListItem_AlbumStatus `ListItem.AlbumStatus`\endlink +/// } +/// \table_row3{ <b>`ListItem.HdrType`</b>, +/// \anchor ListItem_HdrType +/// _string_, +/// @return String containing the name of the detected HDR type or empty if not HDR. See \ref StreamHdrType for the list of possible values. +/// <p><hr> +/// @skinning_v20 **[New Infolabel]** \link ListItem_HdrType `ListItem.HdrType`\endlink +/// } +/// \table_end +/// +/// ----------------------------------------------------------------------------- +const infomap listitem_labels[]= {{ "thumb", LISTITEM_THUMB }, + { "icon", LISTITEM_ICON }, + { "actualicon", LISTITEM_ACTUAL_ICON }, + { "overlay", LISTITEM_OVERLAY }, + { "label", LISTITEM_LABEL }, + { "label2", LISTITEM_LABEL2 }, + { "title", LISTITEM_TITLE }, + { "tracknumber", LISTITEM_TRACKNUMBER }, + { "artist", LISTITEM_ARTIST }, + { "album", LISTITEM_ALBUM }, + { "albumartist", LISTITEM_ALBUM_ARTIST }, + { "year", LISTITEM_YEAR }, + { "genre", LISTITEM_GENRE }, + { "contributors", LISTITEM_CONTRIBUTORS }, + { "contributorandrole", LISTITEM_CONTRIBUTOR_AND_ROLE }, + { "director", LISTITEM_DIRECTOR }, + { "disctitle", LISTITEM_DISC_TITLE }, + { "filename", LISTITEM_FILENAME }, + { "filenameandpath", LISTITEM_FILENAME_AND_PATH }, + { "fileextension", LISTITEM_FILE_EXTENSION }, + { "filenamenoextension", LISTITEM_FILENAME_NO_EXTENSION }, + { "date", LISTITEM_DATE }, + { "datetime", LISTITEM_DATETIME }, + { "size", LISTITEM_SIZE }, + { "rating", LISTITEM_RATING }, + { "ratingandvotes", LISTITEM_RATING_AND_VOTES }, + { "userrating", LISTITEM_USER_RATING }, + { "votes", LISTITEM_VOTES }, + { "mood", LISTITEM_MOOD }, + { "programcount", LISTITEM_PROGRAM_COUNT }, + { "duration", LISTITEM_DURATION }, + { "isselected", LISTITEM_ISSELECTED }, + { "isplaying", LISTITEM_ISPLAYING }, + { "plot", LISTITEM_PLOT }, + { "plotoutline", LISTITEM_PLOT_OUTLINE }, + { "episode", LISTITEM_EPISODE }, + { "season", LISTITEM_SEASON }, + { "tvshowtitle", LISTITEM_TVSHOW }, + { "premiered", LISTITEM_PREMIERED }, + { "comment", LISTITEM_COMMENT }, + { "path", LISTITEM_PATH }, + { "foldername", LISTITEM_FOLDERNAME }, + { "folderpath", LISTITEM_FOLDERPATH }, + { "picturepath", LISTITEM_PICTURE_PATH }, + { "pictureresolution",LISTITEM_PICTURE_RESOLUTION }, + { "picturedatetime", LISTITEM_PICTURE_DATETIME }, + { "picturedate", LISTITEM_PICTURE_DATE }, + { "picturelongdatetime",LISTITEM_PICTURE_LONGDATETIME }, + { "picturelongdate", LISTITEM_PICTURE_LONGDATE }, + { "picturecomment", LISTITEM_PICTURE_COMMENT }, + { "picturecaption", LISTITEM_PICTURE_CAPTION }, + { "picturedesc", LISTITEM_PICTURE_DESC }, + { "picturekeywords", LISTITEM_PICTURE_KEYWORDS }, + { "picturecammake", LISTITEM_PICTURE_CAM_MAKE }, + { "picturecammodel", LISTITEM_PICTURE_CAM_MODEL }, + { "pictureaperture", LISTITEM_PICTURE_APERTURE }, + { "picturefocallen", LISTITEM_PICTURE_FOCAL_LEN }, + { "picturefocusdist", LISTITEM_PICTURE_FOCUS_DIST }, + { "pictureexpmode", LISTITEM_PICTURE_EXP_MODE }, + { "pictureexptime", LISTITEM_PICTURE_EXP_TIME }, + { "pictureiso", LISTITEM_PICTURE_ISO }, + { "pictureauthor", LISTITEM_PICTURE_AUTHOR }, + { "picturebyline", LISTITEM_PICTURE_BYLINE }, + { "picturebylinetitle", LISTITEM_PICTURE_BYLINE_TITLE }, + { "picturecategory", LISTITEM_PICTURE_CATEGORY }, + { "pictureccdwidth", LISTITEM_PICTURE_CCD_WIDTH }, + { "picturecity", LISTITEM_PICTURE_CITY }, + { "pictureurgency", LISTITEM_PICTURE_URGENCY }, + { "picturecopyrightnotice", LISTITEM_PICTURE_COPYRIGHT_NOTICE }, + { "picturecountry", LISTITEM_PICTURE_COUNTRY }, + { "picturecountrycode", LISTITEM_PICTURE_COUNTRY_CODE }, + { "picturecredit", LISTITEM_PICTURE_CREDIT }, + { "pictureiptcdate", LISTITEM_PICTURE_IPTCDATE }, + { "picturedigitalzoom", LISTITEM_PICTURE_DIGITAL_ZOOM }, + { "pictureexposure", LISTITEM_PICTURE_EXPOSURE }, + { "pictureexposurebias", LISTITEM_PICTURE_EXPOSURE_BIAS }, + { "pictureflashused", LISTITEM_PICTURE_FLASH_USED }, + { "pictureheadline", LISTITEM_PICTURE_HEADLINE }, + { "picturecolour", LISTITEM_PICTURE_COLOUR }, + { "picturelightsource", LISTITEM_PICTURE_LIGHT_SOURCE }, + { "picturemeteringmode", LISTITEM_PICTURE_METERING_MODE }, + { "pictureobjectname", LISTITEM_PICTURE_OBJECT_NAME }, + { "pictureorientation", LISTITEM_PICTURE_ORIENTATION }, + { "pictureprocess", LISTITEM_PICTURE_PROCESS }, + { "picturereferenceservice", LISTITEM_PICTURE_REF_SERVICE }, + { "picturesource", LISTITEM_PICTURE_SOURCE }, + { "picturespecialinstructions", LISTITEM_PICTURE_SPEC_INSTR }, + { "picturestate", LISTITEM_PICTURE_STATE }, + { "picturesupplementalcategories", LISTITEM_PICTURE_SUP_CATEGORIES }, + { "picturetransmissionreference", LISTITEM_PICTURE_TX_REFERENCE }, + { "picturewhitebalance", LISTITEM_PICTURE_WHITE_BALANCE }, + { "pictureimagetype", LISTITEM_PICTURE_IMAGETYPE }, + { "picturesublocation", LISTITEM_PICTURE_SUBLOCATION }, + { "pictureiptctime", LISTITEM_PICTURE_TIMECREATED }, + { "picturegpslat", LISTITEM_PICTURE_GPS_LAT }, + { "picturegpslon", LISTITEM_PICTURE_GPS_LON }, + { "picturegpsalt", LISTITEM_PICTURE_GPS_ALT }, + { "studio", LISTITEM_STUDIO }, + { "country", LISTITEM_COUNTRY }, + { "mpaa", LISTITEM_MPAA }, + { "cast", LISTITEM_CAST }, + { "castandrole", LISTITEM_CAST_AND_ROLE }, + { "writer", LISTITEM_WRITER }, + { "tagline", LISTITEM_TAGLINE }, + { "status", LISTITEM_STATUS }, + { "top250", LISTITEM_TOP250 }, + { "trailer", LISTITEM_TRAILER }, + { "sortletter", LISTITEM_SORT_LETTER }, + { "tag", LISTITEM_TAG }, + { "set", LISTITEM_SET }, + { "setid", LISTITEM_SETID }, + { "videocodec", LISTITEM_VIDEO_CODEC }, + { "videoresolution", LISTITEM_VIDEO_RESOLUTION }, + { "videoaspect", LISTITEM_VIDEO_ASPECT }, + { "audiocodec", LISTITEM_AUDIO_CODEC }, + { "audiochannels", LISTITEM_AUDIO_CHANNELS }, + { "audiolanguage", LISTITEM_AUDIO_LANGUAGE }, + { "subtitlelanguage", LISTITEM_SUBTITLE_LANGUAGE }, + { "isresumable", LISTITEM_IS_RESUMABLE}, + { "percentplayed", LISTITEM_PERCENT_PLAYED}, + { "isfolder", LISTITEM_IS_FOLDER }, + { "isparentfolder", LISTITEM_IS_PARENTFOLDER }, + { "iscollection", LISTITEM_IS_COLLECTION }, + { "originaltitle", LISTITEM_ORIGINALTITLE }, + { "lastplayed", LISTITEM_LASTPLAYED }, + { "playcount", LISTITEM_PLAYCOUNT }, + { "discnumber", LISTITEM_DISC_NUMBER }, + { "starttime", LISTITEM_STARTTIME }, + { "endtime", LISTITEM_ENDTIME }, + { "endtimeresume", LISTITEM_ENDTIME_RESUME }, + { "startdate", LISTITEM_STARTDATE }, + { "enddate", LISTITEM_ENDDATE }, + { "nexttitle", LISTITEM_NEXT_TITLE }, + { "nextgenre", LISTITEM_NEXT_GENRE }, + { "nextplot", LISTITEM_NEXT_PLOT }, + { "nextplotoutline", LISTITEM_NEXT_PLOT_OUTLINE }, + { "nextstarttime", LISTITEM_NEXT_STARTTIME }, + { "nextendtime", LISTITEM_NEXT_ENDTIME }, + { "nextstartdate", LISTITEM_NEXT_STARTDATE }, + { "nextenddate", LISTITEM_NEXT_ENDDATE }, + { "nextduration", LISTITEM_NEXT_DURATION }, + { "channelname", LISTITEM_CHANNEL_NAME }, + { "channelnumberlabel", LISTITEM_CHANNEL_NUMBER }, + { "channelgroup", LISTITEM_CHANNEL_GROUP }, + { "hasepg", LISTITEM_HAS_EPG }, + { "hastimer", LISTITEM_HASTIMER }, + { "hastimerschedule", LISTITEM_HASTIMERSCHEDULE }, + { "hasreminder", LISTITEM_HASREMINDER }, + { "hasreminderrule", LISTITEM_HASREMINDERRULE }, + { "hasrecording", LISTITEM_HASRECORDING }, + { "isrecording", LISTITEM_ISRECORDING }, + { "isplayable", LISTITEM_ISPLAYABLE }, + { "hasarchive", LISTITEM_HASARCHIVE }, + { "inprogress", LISTITEM_INPROGRESS }, + { "isencrypted", LISTITEM_ISENCRYPTED }, + { "progress", LISTITEM_PROGRESS }, + { "dateadded", LISTITEM_DATE_ADDED }, + { "dbtype", LISTITEM_DBTYPE }, + { "dbid", LISTITEM_DBID }, + { "appearances", LISTITEM_APPEARANCES }, + { "stereoscopicmode", LISTITEM_STEREOSCOPIC_MODE }, + { "isstereoscopic", LISTITEM_IS_STEREOSCOPIC }, + { "imdbnumber", LISTITEM_IMDBNUMBER }, + { "episodename", LISTITEM_EPISODENAME }, + { "timertype", LISTITEM_TIMERTYPE }, + { "epgeventtitle", LISTITEM_EPG_EVENT_TITLE }, + { "epgeventicon", LISTITEM_EPG_EVENT_ICON }, + { "timerisactive", LISTITEM_TIMERISACTIVE }, + { "timerhaserror", LISTITEM_TIMERHASERROR }, + { "timerhasconflict", LISTITEM_TIMERHASCONFLICT }, + { "addonname", LISTITEM_ADDON_NAME }, + { "addonversion", LISTITEM_ADDON_VERSION }, + { "addoncreator", LISTITEM_ADDON_CREATOR }, + { "addonsummary", LISTITEM_ADDON_SUMMARY }, + { "addondescription", LISTITEM_ADDON_DESCRIPTION }, + { "addondisclaimer", LISTITEM_ADDON_DISCLAIMER }, + { "addonnews", LISTITEM_ADDON_NEWS }, + { "addonbroken", LISTITEM_ADDON_BROKEN }, + { "addonlifecycletype", LISTITEM_ADDON_LIFECYCLE_TYPE }, + { "addonlifecycledesc", LISTITEM_ADDON_LIFECYCLE_DESC }, + { "addontype", LISTITEM_ADDON_TYPE }, + { "addoninstalldate", LISTITEM_ADDON_INSTALL_DATE }, + { "addonlastupdated", LISTITEM_ADDON_LAST_UPDATED }, + { "addonlastused", LISTITEM_ADDON_LAST_USED }, + { "addonorigin", LISTITEM_ADDON_ORIGIN }, + { "addonsize", LISTITEM_ADDON_SIZE }, + { "expirationdate", LISTITEM_EXPIRATION_DATE }, + { "expirationtime", LISTITEM_EXPIRATION_TIME }, + { "art", LISTITEM_ART }, + { "property", LISTITEM_PROPERTY }, + { "parentalrating", LISTITEM_PARENTAL_RATING }, + { "currentitem", LISTITEM_CURRENTITEM }, + { "isnew", LISTITEM_IS_NEW }, + { "isboxset", LISTITEM_IS_BOXSET }, + { "totaldiscs", LISTITEM_TOTALDISCS }, + { "releasedate", LISTITEM_RELEASEDATE }, + { "originaldate", LISTITEM_ORIGINALDATE }, + { "bpm", LISTITEM_BPM }, + { "uniqueid", LISTITEM_UNIQUEID }, + { "bitrate", LISTITEM_BITRATE }, + { "samplerate", LISTITEM_SAMPLERATE }, + { "musicchannels", LISTITEM_MUSICCHANNELS }, + { "ispremiere", LISTITEM_IS_PREMIERE }, + { "isfinale", LISTITEM_IS_FINALE }, + { "islive", LISTITEM_IS_LIVE }, + { "tvshowdbid", LISTITEM_TVSHOWDBID }, + { "albumstatus", LISTITEM_ALBUMSTATUS }, + { "isautoupdateable", LISTITEM_ISAUTOUPDATEABLE }, + { "hdrtype", LISTITEM_VIDEO_HDR_TYPE }, +}; + +/// \page modules__infolabels_boolean_conditions +/// \subsection modules__infolabels_boolean_conditions_Visualisation Visualisation +/// \table_start +/// \table_h3{ Labels, Type, Description } +/// \table_row3{ <b>`Visualisation.Enabled`</b>, +/// \anchor Visualisation_Enabled +/// _boolean_, +/// @return **True** if any visualisation has been set in settings (so not None). +/// <p> +/// } +/// \table_row3{ <b>`Visualisation.HasPresets`</b>, +/// \anchor Visualisation_HasPresets +/// _boolean_, +/// @return **True** if the visualisation has built in presets. +/// <p><hr> +/// @skinning_v16 **[New Boolean Condition]** \link Visualisation_HasPresets `Visualisation.HasPresets`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Visualisation.Locked`</b>, +/// \anchor Visualisation_Locked +/// _boolean_, +/// @return **True** if the current visualisation preset is locked (e.g. in Milkdrop). +/// <p> +/// } +/// \table_row3{ <b>`Visualisation.Preset`</b>, +/// \anchor Visualisation_Preset +/// _string_, +/// @return The current preset of the visualisation. +/// <p> +/// } +/// \table_row3{ <b>`Visualisation.Name`</b>, +/// \anchor Visualisation_Name +/// _string_, +/// @return the name of the visualisation. +/// <p> +/// } +/// \table_end +/// +/// ----------------------------------------------------------------------------- +const infomap visualisation[] = {{ "locked", VISUALISATION_LOCKED }, + { "preset", VISUALISATION_PRESET }, + { "haspresets", VISUALISATION_HAS_PRESETS }, + { "name", VISUALISATION_NAME }, + { "enabled", VISUALISATION_ENABLED }}; + +/// \page modules__infolabels_boolean_conditions +/// \subsection modules__infolabels_boolean_conditions_Fanart Fanart +/// \table_start +/// \table_h3{ Labels, Type, Description } +/// \table_row3{ <b>`Fanart.Color1`</b>, +/// \anchor Fanart_Color1 +/// _string_, +/// @return The first of three colors included in the currently selected +/// Fanart theme for the parent TV Show. +/// @note Colors are arranged Lightest to Darkest. +/// <p> +/// } +/// \table_row3{ <b>`Fanart.Color2`</b>, +/// \anchor Fanart_Color2 +/// _string_, +/// @return The second of three colors included in the currently selected +/// Fanart theme for the parent TV Show. +/// @note Colors are arranged Lightest to Darkest. +/// <p> +/// } +/// \table_row3{ <b>`Fanart.Color3`</b>, +/// \anchor Fanart_Color3 +/// _string_, +/// @return The third of three colors included in the currently selected +/// Fanart theme for the parent TV Show. +/// @note Colors are arranged Lightest to Darkest. +/// <p> +/// } +/// \table_row3{ <b>`Fanart.Image`</b>, +/// \anchor Fanart_Image +/// _string_, +/// @return The fanart image\, if any +/// <p> +/// } +/// \table_end +/// +/// ----------------------------------------------------------------------------- +const infomap fanart_labels[] = {{ "color1", FANART_COLOR1 }, + { "color2", FANART_COLOR2 }, + { "color3", FANART_COLOR3 }, + { "image", FANART_IMAGE }}; + +/// \page modules__infolabels_boolean_conditions +/// \subsection modules__infolabels_boolean_conditions_Skin Skin +/// \table_start +/// \table_h3{ Labels, Type, Description } +/// \table_row3{ <b>`Skin.HasSetting(setting)`</b>, +/// \anchor Skin_HasSetting +/// _boolean_, +/// @param setting - the requested skin setting +/// @return **True** if the requested skin setting is true\, false otherwise. +/// @sa \link Skin_SetBool `Skin.SetBool(setting[\,value])` +/// <p> +/// } +/// \table_row3{ <b>`Skin.String(setting)`</b>, +/// \anchor Skin_StringValue +/// _string_, +/// @param setting - the requested skin setting +/// @return The value of the requested string setting (as a string) +/// @sa \link Skin_SetString `Skin.SetString(setting[\,value])`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Skin.String(setting[\,value])`</b>, +/// \anchor Skin_StringCompare +/// _boolean_, +/// @param setting - the requested skin setting +/// @param value [opt] - the string value to compare the requested setting to +/// @return **True** if the setting value equals the provided value\, false otherwise. +/// @sa \link Skin_SetString `Skin.SetString(setting[\,value])`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Skin.HasTheme(theme)`</b>, +/// \anchor Skin_HasTheme +/// _boolean_, +/// @param theme - the requested skin theme +/// @return **True** if the requested theme is enabled\, false otherwise. +/// @sa \link Skin_CycleTheme `Skin.Theme()`\endlink and \link Skin_CurrentTheme `Skin.CurrentTheme`\endlink. +/// <p> +/// } +/// \table_row3{ <b>`Skin.CurrentTheme`</b>, +/// \anchor Skin_CurrentTheme +/// _string_, +/// @return The current selected skin theme. +/// <p> +/// } +/// \table_row3{ <b>`Skin.CurrentColourTheme`</b>, +/// \anchor Skin_CurrentColourTheme +/// _string_, +/// @return the current selected colour theme of the skin. +/// <p> +/// } +/// \table_row3{ <b>`Skin.AspectRatio`</b>, +/// \anchor Skin_AspectRatio +/// _string_, +/// @return The closest aspect ratio match using the resolution info from the skin's `addon.xml` file. +/// <p> +/// } +/// \table_row3{ <b>`Skin.Font`</b>, +/// \anchor Skin_Font +/// _string_, +/// @return the current fontset from `Font.xml`. +/// <p><hr> +/// @skinning_v18 **[New Infolabel]** \link Skin_Font `Skin.Font`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Skin.Numeric(settingid)`</b>, +/// \anchor Skin_Numeric +/// _integer_, +/// @return return the setting value as an integer/numeric value. +/// @sa \link Skin_SetNumeric `Skin.SetNumeric(settingid)`\endlink +/// <p><hr> +/// @skinning_v20 **[New Infolabel]** \link Skin_Numeric `Skin.Numeric(settingid)`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Skin.TimerElapsedSecs(timer)`</b>, +/// \anchor Skin_TimerElapsedSecs +/// _integer_ \, _string_, +/// @return The elapsed time in seconds for the provided `timer`. +/// @param timer - the timer name +/// <p><hr> +/// @skinning_v20 **[New Infolabel]** \link Skin_TimerElapsedSecs `Skin.TimerElapsedSecs(timer)`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Skin.TimerIsRunning(timer)`</b>, +/// \anchor Skin_TimerIsRunning +/// _boolean_, +/// @return **True** if the given `timer` is active\, false otherwise. +/// @param timer - the timer name +/// <p><hr> +/// @skinning_v20 **[New Infolabel]** \link Skin_TimerIsRunning `Skin.TimerIsRunning(timer)`\endlink +/// <p> +/// } +/// \table_end +/// +/// ----------------------------------------------------------------------------- +const infomap skin_labels[] = {{ "currenttheme", SKIN_THEME }, + { "currentcolourtheme",SKIN_COLOUR_THEME }, + { "aspectratio", SKIN_ASPECT_RATIO}, + { "font", SKIN_FONT}}; + +/// \page modules__infolabels_boolean_conditions +/// \subsection modules__infolabels_boolean_conditions_Window Window +/// \table_start +/// \table_h3{ Labels, Type, Description } +/// \table_row3{ <b>`Window.IsMedia`</b>, +/// \anchor Window_IsMedia +/// _boolean_, +/// @return **True** if this window is a media window (programs\, music\, video\, +/// scripts\, pictures) +/// <p> +/// } +/// \table_row3{ <b>`Window.Is(window)`</b>, +/// \anchor Window_Is +/// _boolean_, +/// @return **True** if the window with the given name is the window which is currently rendered. +/// @param window - the name of the window +/// @note Useful in xml files that are shared between multiple windows or dialogs. +/// <p><hr> +/// @skinning_v17 **[New Boolean Condition]** \ref Window_Is "Window.Is(window)" +/// <p> +/// } +/// \table_row3{ <b>`Window.IsActive(window)`</b>, +/// \anchor Window_IsActive +/// _boolean_, +/// @return **True** if the window with id or title _window_ is active +/// @param window - the id or name of the window +/// @note Excludes fade out time on dialogs +/// <p> +/// } +/// \table_row3{ <b>`Window.IsVisible(window)`</b>, +/// \anchor Window_IsVisible +/// _boolean_, +/// @return **True** if the window is visible +/// @note Includes fade out time on dialogs +/// <p> +/// } +/// \table_row3{ <b>`Window.IsTopmost(window)`</b>, +/// \anchor Window_IsTopmost +/// _boolean_, +/// @return **True** if the window with id or title _window_ is on top of the +/// window stack. +/// @param window - the id or name of the window +/// @note Excludes fade out time on dialogs +/// @deprecated use \ref Window_IsDialogTopmost "Window.IsDialogTopmost(dialog)" instead +/// <p> +/// } +/// \table_row3{ <b>`Window.IsDialogTopmost(dialog)`</b>, +/// \anchor Window_IsDialogTopmost +/// _boolean_, +/// @return **True** if the dialog with id or title _dialog_ is on top of the +/// dialog stack. +/// @param window - the id or name of the window +/// @note Excludes fade out time on dialogs +/// <p> +/// } +/// \table_row3{ <b>`Window.IsModalDialogTopmost(dialog)`</b>, +/// \anchor Window_IsModalDialogTopmost +/// _boolean_, +/// @return **True** if the dialog with id or title _dialog_ is on top of the +/// modal dialog stack +/// @note Excludes fade out time on dialogs +/// <p> +/// } +/// \table_row3{ <b>`Window.Previous(window)`</b>, +/// \anchor Window_Previous +/// _boolean_, +/// @return **True** if the window with id or title _window_ is being moved from. +/// @param window - the window id or title +/// @note Only valid while windows are changing. +/// <p> +/// } +/// \table_row3{ <b>`Window.Next(window)`</b>, +/// \anchor Window_Next +/// _boolean_, +/// @return **True** if the window with id or title _window_ is being moved to. +/// @param window - the window id or title +/// @note Only valid while windows are changing. +/// <p> +/// } +/// \table_row3{ <b>`Window.Property(Addon.ID)`</b>, +/// \anchor Window_Property_AddonId +/// _string_, +/// @return The id of the selected addon\, in `DialogAddonSettings.xml`. +/// <p><hr> +/// @skinning_v17 **[New Infolabel]** \link Window_Property_AddonId `Window.Property(Addon.ID)`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Window.Property(IsRadio)`</b>, +/// \anchor Window_Property_IsRadio +/// _string_, +/// @return "true" if the window is a radio window\, empty string otherwise (for use in the PVR windows). +/// <p> +/// } +/// \table_row3{ <b>`Window([window]).Property(key)`</b>, +/// \anchor Window_Window_Property_key +/// _string_, +/// @return A window property. +/// @param window - [opt] window id or name. +/// @param key - any value. +/// <p> +/// } +/// \table_row3{ <b>`Window(AddonBrowser).Property(Updated)`</b>, +/// \anchor Window_Addonbrowser_Property_Updated +/// _string_, +/// @return The date and time the addon repo was last checked for updates. +/// @todo move to a future window document. +/// <p><hr> +/// @skinning_v15 **[New Infolabel]** \link Window_Addonbrowser_Property_Updated `Window(AddonBrowser).Property(Updated)`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Window(Weather).Property(property)`</b>, +/// \anchor Window_Weather_Property +/// _string_, +/// @return The property for the weather window. +/// @param property - The requested property. The following are available: +/// - Current.ConditionIcon +/// - Day[0-6].OutlookIcon +/// - Current.FanartCode +/// - Day[0-6].FanartCode +/// - WeatherProviderLogo +/// - Daily.%i.OutlookIcon +/// - 36Hour.%i.OutlookIcon +/// - Weekend.%i.OutlookIcon +/// - Hourly.%i.OutlookIcon +/// @todo move to a future window document. +/// <p><hr> +/// @skinning_v16 **[Updated infolabel]** \link Window_Weather_Property `Window(Weather).Property(property)`\endlink +/// For skins that support extended weather info\, the following infolabels have been changed: +/// - Daily.%i.OutlookIcon +/// - 36Hour.%i.OutlookIcon +/// - Weekend.%i.OutlookIcon +/// - Hourly.%i.OutlookIcon +/// +/// previously the openweathermap addon would provide the full\, hardcoded path to the icon +/// ie. `resource://resource.images.weathericons.default/28.png` +/// to make it easier for skins to work with custom icon sets\, it now will return the filename only +/// i.e. 28.png +/// @skinning_v13 **[Infolabel Updated]** \link Window_Weather_Property `Window(Weather).Property(property)`\endlink +/// added `WeatherProviderLogo` property - weather provider logo (for weather addons that support it). +/// <p> +/// } +/// \table_end +/// +/// ----------------------------------------------------------------------------- +const infomap window_bools[] = {{ "ismedia", WINDOW_IS_MEDIA }, + { "is", WINDOW_IS }, + { "isactive", WINDOW_IS_ACTIVE }, + { "isvisible", WINDOW_IS_VISIBLE }, + { "istopmost", WINDOW_IS_DIALOG_TOPMOST }, //! @deprecated, remove in v19 + { "isdialogtopmost", WINDOW_IS_DIALOG_TOPMOST }, + { "ismodaldialogtopmost", WINDOW_IS_MODAL_DIALOG_TOPMOST }, + { "previous", WINDOW_PREVIOUS }, + { "next", WINDOW_NEXT }}; + +/// \page modules__infolabels_boolean_conditions +/// \subsection modules__infolabels_boolean_conditions_Control Control +/// \table_start +/// \table_h3{ Labels, Type, Description } +/// \table_row3{ <b>`Control.HasFocus(id)`</b>, +/// \anchor Control_HasFocus +/// _boolean_, +/// @return **True** if the currently focused control has id "id". +/// @param id - The id of the control +/// <p> +/// } +/// \table_row3{ <b>`Control.IsVisible(id)`</b>, +/// \anchor Control_IsVisible +/// _boolean_, +/// @return **True** if the control with id "id" is visible. +/// @param id - The id of the control +/// <p> +/// } +/// \table_row3{ <b>`Control.IsEnabled(id)`</b>, +/// \anchor Control_IsEnabled +/// _boolean_, +/// @return **True** if the control with id "id" is enabled. +/// @param id - The id of the control +/// <p> +/// } +/// \table_row3{ <b>`Control.GetLabel(id)[.index()]`</b>, +/// \anchor Control_GetLabel +/// _string_, +/// @return The label value or texture name of the control with the given id. +/// @param id - The id of the control +/// @param index - [opt] Optionally you can specify index(1) to retrieve label2 from an Edit +/// control. +/// <p><hr> +/// @skinning_v15 **[Infolabel Updated]** \link Control_GetLabel `Control.GetLabel(id)`\endlink +/// added index parameter - allows skinner to retrieve label2 of a control. Only edit controls are supported. +/// ** Example** : `Control.GetLabel(999).index(1)` where: +/// - index(0) = label +/// - index(1) = label2 +/// <p> +/// } +/// \table_end +/// +/// ----------------------------------------------------------------------------- +const infomap control_labels[] = {{ "hasfocus", CONTROL_HAS_FOCUS }, + { "isvisible", CONTROL_IS_VISIBLE }, + { "isenabled", CONTROL_IS_ENABLED }, + { "getlabel", CONTROL_GET_LABEL }}; + +/// \page modules__infolabels_boolean_conditions +/// \subsection modules__infolabels_boolean_conditions_Playlist Playlist +/// \table_start +/// \table_h3{ Labels, Type, Description } +/// \table_row3{ <b>`Playlist.Length(media)`</b>, +/// \anchor Playlist_Length +/// _integer_, +/// @return The total size of the current playlist. +/// @param media - [opt] mediatype with is either +/// video or music. +/// <p> +/// } +/// \table_row3{ <b>`Playlist.Position(media)`</b>, +/// \anchor Playlist_Position +/// _integer_, +/// @return The position of the current item in the current playlist. +/// @param media - [opt] mediatype with is either +/// video or music. +/// <p> +/// } +/// \table_row3{ <b>`Playlist.Random`</b>, +/// \anchor Playlist_Random +/// _integer_, +/// @return String ID for the random mode: +/// - **16041** (On) +/// - **591** (Off) +/// <p><hr> +/// @skinning_v18 **[Infolabel Updated]** \link Playlist_Random `Playlist.Random`\endlink will +/// now return **On/Off** +/// <p> +/// } +/// \table_row3{ <b>`Playlist.Repeat`</b>, +/// \anchor Playlist_Repeat +/// _integer_, +/// @return The String Id for the repeat mode. It can be one of the following +/// values: +/// - **592** (Repeat One) +/// - **593** (Repeat All) +/// - **594** (Repeat Off) +/// <p> +/// } +/// \table_row3{ <b>`Playlist.IsRandom`</b>, +/// \anchor Playlist_IsRandom +/// _boolean_, +/// @return **True** if the player is in random mode. +/// <p> +/// } +/// \table_row3{ <b>`Playlist.IsRepeat`</b>, +/// \anchor Playlist_IsRepeat +/// _boolean_, +/// @return **True** if the player is in repeat all mode. +/// <p> +/// } +/// \table_row3{ <b>`Playlist.IsRepeatOne`</b>, +/// \anchor Playlist_IsRepeatOne +/// _boolean_, +/// @return **True** if the player is in repeat one mode. +/// <p> +/// } +/// \table_end +/// +/// ----------------------------------------------------------------------------- +const infomap playlist[] = {{ "length", PLAYLIST_LENGTH }, + { "position", PLAYLIST_POSITION }, + { "random", PLAYLIST_RANDOM }, + { "repeat", PLAYLIST_REPEAT }, + { "israndom", PLAYLIST_ISRANDOM }, + { "isrepeat", PLAYLIST_ISREPEAT }, + { "isrepeatone", PLAYLIST_ISREPEATONE }}; + +/// \page modules__infolabels_boolean_conditions +/// \subsection modules__infolabels_boolean_conditions_Pvr Pvr +/// \table_start +/// \table_h3{ Labels, Type, Description } +/// \table_row3{ <b>`PVR.IsRecording`</b>, +/// \anchor PVR_IsRecording +/// _boolean_, +/// @return **True** when the system is recording a tv or radio programme. +/// <p> +/// } +/// \table_row3{ <b>`PVR.HasTimer`</b>, +/// \anchor PVR_HasTimer +/// _boolean_, +/// @return **True** when a recording timer is active. +/// <p> +/// } +/// \table_row3{ <b>`PVR.HasTVChannels`</b>, +/// \anchor PVR_HasTVChannels +/// _boolean_, +/// @return **True** if there are TV channels available. +/// <p> +/// } +/// \table_row3{ <b>`PVR.HasRadioChannels`</b>, +/// \anchor PVR_HasRadioChannels +/// _boolean_, +/// @return **True** if there are radio channels available. +/// <p> +/// } +/// \table_row3{ <b>`PVR.HasNonRecordingTimer`</b>, +/// \anchor PVR_HasNonRecordingTimer +/// _boolean_, +/// @return **True** if there are timers present who currently not do recording. +/// <p> +/// } +/// \table_row3{ <b>`PVR.BackendName`</b>, +/// \anchor PVR_BackendName +/// _string_, +/// @return The name of the backend being used. +/// <p> +/// } +/// \table_row3{ <b>`PVR.BackendVersion`</b>, +/// \anchor PVR_BackendVersion +/// _string_, +/// @return The version of the backend that's being used. +/// <p> +/// } +/// \table_row3{ <b>`PVR.BackendHost`</b>, +/// \anchor PVR_BackendHost +/// _string_, +/// @return The backend hostname. +/// <p> +/// } +/// \table_row3{ <b>`PVR.BackendDiskSpace`</b>, +/// \anchor PVR_BackendDiskSpace +/// _string_, +/// @return The available diskspace on the backend as string with size. +/// <p> +/// } +/// \table_row3{ <b>`PVR.BackendDiskSpaceProgr`</b>, +/// \anchor PVR_BackendDiskSpaceProgr +/// _integer_, +/// @return The available diskspace on the backend as percent value. +/// <p><hr> +/// @skinning_v14 **[New Infolabel]** \link PVR_BackendDiskSpaceProgr `PVR.BackendDiskSpaceProgr`\endlink +/// <p> +/// } +/// \table_row3{ <b>`PVR.BackendChannels`</b>, +/// \anchor PVR_BackendChannels +/// _string (integer)_, +/// @return The number of available channels the backend provides. +/// <p> +/// } +/// \table_row3{ <b>`PVR.BackendTimers`</b>, +/// \anchor PVR_BackendTimers +/// _string (integer)_, +/// @return The number of timers set for the backend. +/// <p> +/// } +/// \table_row3{ <b>`PVR.BackendRecordings`</b>, +/// \anchor PVR_BackendRecordings +/// _string (integer)_, +/// @return The number of recordings available on the backend. +/// <p> +/// } +/// \table_row3{ <b>`PVR.BackendDeletedRecordings`</b>, +/// \anchor PVR_BackendDeletedRecordings +/// _string (integer)_, +/// @return The number of deleted recordings present on the backend. +/// <p> +/// } +/// \table_row3{ <b>`PVR.BackendNumber`</b>, +/// \anchor PVR_BackendNumber +/// _string_, +/// @return The backend number. +/// <p> +/// } +/// \table_row3{ <b>`PVR.TotalDiscSpace`</b>, +/// \anchor PVR_TotalDiscSpace +/// _string_, +/// @return The total diskspace available for recordings. +/// <p> +/// } +/// \table_row3{ <b>`PVR.NextTimer`</b>, +/// \anchor PVR_NextTimer +/// _boolean_, +/// @return The next timer date. +/// <p> +/// } +/// \table_row3{ <b>`PVR.IsPlayingTV`</b>, +/// \anchor PVR_IsPlayingTV +/// _boolean_, +/// @return **True** when live tv is being watched. +/// <p> +/// } +/// \table_row3{ <b>`PVR.IsPlayingRadio`</b>, +/// \anchor PVR_IsPlayingRadio +/// _boolean_, +/// @return **True** when live radio is being listened to. +/// <p> +/// } +/// \table_row3{ <b>`PVR.IsPlayingRecording`</b>, +/// \anchor PVR_IsPlayingRecording +/// _boolean_, +/// @return **True** when a recording is being watched. +/// <p> +/// } +/// \table_row3{ <b>`PVR.IsPlayingEpgTag`</b>, +/// \anchor PVR_IsPlayingEpgTag +/// _boolean_, +/// @return **True** when an epg tag is being watched. +/// <p> +/// } +/// \table_row3{ <b>`PVR.EpgEventProgress`</b>, +/// \anchor PVR_EpgEventProgress +/// _integer_, +/// @return The percentage complete of the currently playing epg event. +/// <p><hr> +/// @skinning_v18 **[Infolabel Updated]** \link PVR_EpgEventProgress `PVR.EpgEventProgress`\endlink replaces +/// the old `PVR.Progress` infolabel. +/// <p> +/// } +/// \table_row3{ <b>`PVR.ActStreamClient`</b>, +/// \anchor PVR_ActStreamClient +/// _string_, +/// @return The stream client name. +/// <p> +/// } +/// \table_row3{ <b>`PVR.ActStreamDevice`</b>, +/// \anchor PVR_ActStreamDevice +/// _string_, +/// @return The stream device name. +/// <p> +/// } +/// \table_row3{ <b>`PVR.ActStreamStatus`</b>, +/// \anchor PVR_ActStreamStatus +/// _string_, +/// @return The status of the stream. +/// <p> +/// } +/// \table_row3{ <b>`PVR.ActStreamSignal`</b>, +/// \anchor PVR_ActStreamSignal +/// _string_, +/// @return The signal quality of the stream. +/// <p> +/// } +/// \table_row3{ <b>`PVR.ActStreamSnr`</b>, +/// \anchor PVR_ActStreamSnr +/// _string_, +/// @return The signal to noise ratio of the stream. +/// <p> +/// } +/// \table_row3{ <b>`PVR.ActStreamBer`</b>, +/// \anchor PVR_ActStreamBer +/// _string_, +/// @return The bit error rate of the stream. +/// <p> +/// } +/// \table_row3{ <b>`PVR.ActStreamUnc`</b>, +/// \anchor PVR_ActStreamUnc +/// _string_, +/// @return The UNC value of the stream. +/// <p> +/// } +/// \table_row3{ <b>`PVR.ActStreamProgrSignal`</b>, +/// \anchor PVR_ActStreamProgrSignal +/// _integer_, +/// @return The signal quality of the programme. +/// <p> +/// } +/// \table_row3{ <b>`PVR.ActStreamProgrSnr`</b>, +/// \anchor PVR_ActStreamProgrSnr +/// _integer_, +/// @return The signal to noise ratio of the programme. +/// <p> +/// } +/// \table_row3{ <b>`PVR.ActStreamIsEncrypted`</b>, +/// \anchor PVR_ActStreamIsEncrypted +/// _boolean_, +/// @return **True** when channel is encrypted on source. +/// <p> +/// } +/// \table_row3{ <b>`PVR.ActStreamEncryptionName`</b>, +/// \anchor PVR_ActStreamEncryptionName +/// _string_, +/// @return The encryption used on the stream. +/// <p> +/// } +/// \table_row3{ <b>`PVR.ActStreamServiceName`</b>, +/// \anchor PVR_ActStreamServiceName +/// _string_, +/// @return The service name of played channel if available. +/// <p> +/// } +/// \table_row3{ <b>`PVR.ActStreamMux`</b>, +/// \anchor PVR_ActStreamMux +/// _string_, +/// @return The multiplex type of played channel if available. +/// <p> +/// } +/// \table_row3{ <b>`PVR.ActStreamProviderName`</b>, +/// \anchor PVR_ActStreamProviderName +/// _string_, +/// @return The provider name of the played channel if available. +/// <p> +/// } +/// \table_row3{ <b>`PVR.IsTimeShift`</b>, +/// \anchor PVR_IsTimeShift +/// _boolean_, +/// @return **True** when for channel is timeshift available. +/// <p> +/// } +/// \table_row3{ <b>`PVR.TimeShiftProgress`</b>, +/// \anchor PVR_TimeShiftProgress +/// _integer_, +/// @return The position of currently timeshifted title on TV as integer. +/// <p> +/// } +/// \table_row3{ <b>`PVR.TimeShiftSeekbar`</b>, +/// \anchor PVR_TimeShiftSeekbar +/// _integer_, +/// @return The percentage we are seeking to in a timeshifted title. +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link PVR_TimeShiftSeekbar `PVR.TimeShiftSeekbar`\endlink +/// <p> +/// } +/// \table_row3{ <b>`PVR.NowRecordingTitle`</b>, +/// \anchor PVR_NowRecordingTitle +/// _string_, +/// @return The title of the programme being recorded. +/// <p> +/// } +/// \table_row3{ <b>`PVR.NowRecordingDateTime`</b>, +/// \anchor PVR_NowRecordingDateTime +/// _Date/Time string_, +/// @return The start date and time of the current recording. +/// <p> +/// } +/// \table_row3{ <b>`PVR.NowRecordingChannel`</b>, +/// \anchor PVR_NowRecordingChannel +/// _string_, +/// @return The channel name of the current recording. +/// <p> +/// } +/// \table_row3{ <b>`PVR.NowRecordingChannelIcon`</b>, +/// \anchor PVR_NowRecordingChannelIcon +/// _string_, +/// @return The icon of the current recording channel. +/// <p> +/// } +/// \table_row3{ <b>`PVR.NextRecordingTitle`</b>, +/// \anchor PVR_NextRecordingTitle +/// _string_, +/// @return The title of the next programme that will be recorded. +/// <p> +/// } +/// \table_row3{ <b>`PVR.NextRecordingDateTime`</b>, +/// \anchor PVR_NextRecordingDateTime +/// _Date/Time string_, +/// @return The start date and time of the next recording. +/// <p> +/// } +/// \table_row3{ <b>`PVR.NextRecordingChannel`</b>, +/// \anchor PVR_NextRecordingChannel +/// _string_, +/// @return The channel name of the next recording. +/// <p> +/// } +/// \table_row3{ <b>`PVR.NextRecordingChannelIcon`</b>, +/// \anchor PVR_NextRecordingChannelIcon +/// _string_, +/// @return The icon of the next recording channel. +/// <p> +/// } +/// \table_row3{ <b>`PVR.TVNowRecordingTitle`</b>, +/// \anchor PVR_TVNowRecordingTitle +/// _string_, +/// @return The title of the tv programme being recorded. +/// <p><hr> +/// @skinning_v17 **[New Infolabel]** \link PVR_TVNowRecordingTitle `PVR.TVNowRecordingTitle`\endlink +/// <p> +/// } +/// \table_row3{ <b>`PVR.TVNowRecordingDateTime`</b>, +/// \anchor PVR_TVNowRecordingDateTime +/// _Date/Time string_, +/// @return The start date and time of the current tv recording. +/// <p><hr> +/// @skinning_v17 **[New Infolabel]** \link PVR_TVNowRecordingDateTime `PVR.TVNowRecordingDateTime`\endlink +/// <p> +/// } +/// \table_row3{ <b>`PVR.TVNowRecordingChannel`</b>, +/// \anchor PVR_TVNowRecordingChannel +/// _string_, +/// @return The channel name of the current tv recording. +/// <p><hr> +/// @skinning_v17 **[New Infolabel]** \link PVR_TVNowRecordingChannel `PVR.TVNowRecordingChannel`\endlink +/// <p> +/// } +/// \table_row3{ <b>`PVR.TVNowRecordingChannelIcon`</b>, +/// \anchor PVR_TVNowRecordingChannelIcon +/// _string_, +/// @return The icon of the current recording TV channel. +/// <p><hr> +/// @skinning_v17 **[New Infolabel]** \link PVR_TVNowRecordingChannelIcon `PVR.TVNowRecordingChannelIcon`\endlink +/// <p> +/// } +/// \table_row3{ <b>`PVR.TVNextRecordingTitle`</b>, +/// \anchor PVR_TVNextRecordingTitle +/// _string_, +/// @return The title of the next tv programme that will be recorded. +/// <p><hr> +/// @skinning_v17 **[New Infolabel]** \link PVR_TVNextRecordingTitle `PVR.TVNextRecordingTitle`\endlink +/// <p> +/// } +/// \table_row3{ <b>`PVR.TVNextRecordingDateTime`</b>, +/// \anchor PVR_TVNextRecordingDateTime +/// _Date/Time string_, +/// @return The start date and time of the next tv recording. +/// <p><hr> +/// @skinning_v17 **[New Infolabel]** \link PVR_TVNextRecordingDateTime `PVR.TVNextRecordingDateTime`\endlink +/// <p> +/// } +/// \table_row3{ <b>`PVR.TVNextRecordingChannel`</b>, +/// \anchor PVR_TVNextRecordingChannel +/// _string_, +/// @return The channel name of the next tv recording. +/// <p><hr> +/// @skinning_v17 **[New Infolabel]** \link PVR_TVNextRecordingChannel `PVR.TVNextRecordingChannel`\endlink +/// <p> +/// } +/// \table_row3{ <b>`PVR.TVNextRecordingChannelIcon`</b>, +/// \anchor PVR_TVNextRecordingChannelIcon +/// _string_, +/// @return The icon of the next recording tv channel. +/// <p><hr> +/// @skinning_v17 **[New Infolabel]** \link PVR_TVNextRecordingChannelIcon `PVR.TVNextRecordingChannelIcon`\endlink +/// <p> +/// } +/// \table_row3{ <b>`PVR.RadioNowRecordingTitle`</b>, +/// \anchor PVR_RadioNowRecordingTitle +/// _string_, +/// @return The title of the radio programme being recorded. +/// <p><hr> +/// @skinning_v17 **[New Infolabel]** \link PVR_RadioNowRecordingTitle `PVR.RadioNowRecordingTitle`\endlink +/// <p> +/// } +/// \table_row3{ <b>`PVR.RadioNowRecordingDateTime`</b>, +/// \anchor PVR_RadioNowRecordingDateTime +/// _Date/Time string_, +/// @return The start date and time of the current radio recording. +/// <p><hr> +/// @skinning_v17 **[New Infolabel]** \link PVR_RadioNowRecordingDateTime `PVR.RadioNowRecordingDateTime`\endlink +/// <p> +/// } +/// \table_row3{ <b>`PVR.RadioNowRecordingChannel`</b>, +/// \anchor PVR_RadioNowRecordingChannel +/// _string_, +/// @return The channel name of the current radio recording. +/// <p><hr> +/// @skinning_v17 **[New Infolabel]** \link PVR_RadioNowRecordingChannel `PVR.RadioNowRecordingChannel`\endlink +/// <p> +/// } +/// \table_row3{ <b>`PVR.RadioNowRecordingChannelIcon`</b>, +/// \anchor PVR_RadioNowRecordingChannelIcon +/// _string_, +/// @return The icon of the current recording radio channel. +/// <p><hr> +/// @skinning_v17 **[New Infolabel]** \link PVR_RadioNowRecordingChannelIcon `PVR.RadioNowRecordingChannelIcon`\endlink +/// <p> +/// } +/// \table_row3{ <b>`PVR.RadioNextRecordingTitle`</b>, +/// \anchor PVR_RadioNextRecordingTitle +/// _string_, +/// @return The title of the next radio programme that will be recorded. +/// <p><hr> +/// @skinning_v17 **[New Infolabel]** \link PVR_RadioNextRecordingTitle `PVR.RadioNextRecordingTitle`\endlink +/// <p> +/// } +/// \table_row3{ <b>`PVR.RadioNextRecordingDateTime`</b>, +/// \anchor PVR_RadioNextRecordingDateTime +/// _Date/Time string_, +/// @return The start date and time of the next radio recording. +/// <p><hr> +/// @skinning_v17 **[New Infolabel]** \link PVR_RadioNextRecordingDateTime `PVR.RadioNextRecordingDateTime`\endlink +/// <p> +/// } +/// \table_row3{ <b>`PVR.RadioNextRecordingChannel`</b>, +/// \anchor PVR_RadioNextRecordingChannel +/// _string_, +/// @return The channel name of the next radio recording. +/// <p><hr> +/// @skinning_v17 **[New Infolabel]** \link PVR_RadioNextRecordingChannel `PVR.RadioNextRecordingChannel`\endlink +/// <p> +/// } +/// \table_row3{ <b>`PVR.RadioNextRecordingChannelIcon`</b>, +/// \anchor PVR_RadioNextRecordingChannelIcon +/// _string_, +/// @return The icon of the next recording radio channel. +/// <p><hr> +/// @skinning_v17 **[New Infolabel]** \link PVR_RadioNextRecordingChannelIcon `PVR.RadioNextRecordingChannelIcon`\endlink +/// <p> +/// } +/// \table_row3{ <b>`PVR.IsRecordingTV`</b>, +/// \anchor PVR_IsRecordingTV +/// _boolean_, +/// @return **True** when the system is recording a tv programme. +/// <p><hr> +/// @skinning_v17 **[New Boolean Condition]** \link PVR_IsRecordingTV `PVR.IsRecordingTV`\endlink +/// <p> +/// } +/// \table_row3{ <b>`PVR.HasTVTimer`</b>, +/// \anchor PVR_HasTVTimer +/// _boolean_, +/// @return **True** if at least one tv timer is active. +/// <p><hr> +/// @skinning_v17 **[New Boolean Condition]** \link PVR_HasTVTimer `PVR.HasTVTimer`\endlink +/// <p> +/// } +/// \table_row3{ <b>`PVR.HasNonRecordingTVTimer`</b>, +/// \anchor PVR_HasNonRecordingTVTimer +/// _boolean_, +/// @return **True** if there are tv timers present who currently not do recording. +/// <p><hr> +/// @skinning_v17 **[New Boolean Condition]** \link PVR_HasNonRecordingTVTimer `PVR.HasNonRecordingTVTimer`\endlink +/// <p> +/// } +/// \table_row3{ <b>`PVR.IsRecordingRadio`</b>, +/// \anchor PVR_IsRecordingRadio +/// _boolean_, +/// @return **True** when the system is recording a radio programme. +/// <p><hr> +/// @skinning_v17 **[New Boolean Condition]** \link PVR_IsRecordingRadio `PVR.IsRecordingRadio`\endlink +/// <p> +/// } +/// \table_row3{ <b>`PVR.HasRadioTimer`</b>, +/// \anchor PVR_HasRadioTimer +/// _boolean_, +/// @return **True** if at least one radio timer is active. +/// <p><hr> +/// @skinning_v17 **[New Boolean Condition]** \link PVR_HasRadioTimer `PVR.HasRadioTimer`\endlink +/// <p> +/// } +/// \table_row3{ <b>`PVR.HasNonRecordingRadioTimer`</b>, +/// \anchor PVR_HasNonRecordingRadioTimer +/// _boolean_, +/// @return **True** if there are radio timers present who currently not do recording. +/// <p><hr> +/// @skinning_v17 **[New Boolean Condition]** \link PVR_HasNonRecordingRadioTimer `PVR.HasRadioTimer`\endlink +/// <p> +/// } +/// \table_row3{ <b>`PVR.ChannelNumberInput`</b>, +/// \anchor PVR_ChannelNumberInput +/// _string_, +/// @return The currently entered channel number while in numeric channel input mode\, an empty string otherwise. +/// <p><hr> +/// @skinning_v18 **[New Infolabel]** \link PVR_ChannelNumberInput `PVR.ChannelNumberInput`\endlink +/// <p> +/// } +/// \table_row3{ <b>`PVR.CanRecordPlayingChannel`</b>, +/// \anchor PVR_CanRecordPlayingChannel +/// _boolean_, +/// @return **True** if PVR is currently playing a channel and if this channel can be recorded. +/// <p><hr> +/// @skinning_v18 **[Infolabel Updated]** \link PVR_CanRecordPlayingChannel `PVR.CanRecordPlayingChannel`\endlink replaces +/// the old `Player.CanRecord` infolabel. +/// <p> +/// } +/// \table_row3{ <b>`PVR.IsRecordingPlayingChannel`</b>, +/// \anchor PVR_IsRecordingPlayingChannel +/// _boolean_, +/// @return **True** if PVR is currently playing a channel and if this channel is currently recorded. +/// <p><hr> +/// @skinning_v18 **[Infolabel Updated]** \link PVR_IsRecordingPlayingChannel `PVR.IsRecordingPlayingChannel`\endlink replaces +/// the old `Player.Recording` infolabel. +/// <p> +/// } +/// \table_row3{ <b>`PVR.IsPlayingActiveRecording`</b>, +/// \anchor PVR_IsPlayingActiveRecording +/// _boolean_, +/// @return **True** if PVR is currently playing an in progress recording. +/// <p><hr> +/// @skinning_v19 **[New Infolabel]** \link PVR_IsPlayingActiveRecording `PVR.IsPlayingActiveRecording`\endlink +/// <p> +/// } +/// \table_row3{ <b>`PVR.TimeshiftProgressPlayPos`</b>, +/// \anchor PVR_TimeshiftProgressPlayPos +/// _integer_, +/// @return The percentage of the current play position within the PVR timeshift progress. +/// <p><hr> +/// @skinning_v18 **[New Infolabel]** \link PVR_TimeshiftProgressPlayPos `PVR.TimeshiftProgressPlayPos`\endlink +/// <p> +/// } +/// \table_row3{ <b>`PVR.TimeshiftProgressEpgStart`</b>, +/// \anchor PVR_TimeshiftProgressEpgStart +/// _integer_, +/// @return The percentage of the start of the currently playing epg event within the PVR timeshift progress. +/// <p><hr> +/// @skinning_v18 **[New Infolabel]** \link PVR_TimeshiftProgressEpgStart `PVR.TimeshiftProgressEpgStart`\endlink +/// <p> +/// } +/// \table_row3{ <b>`PVR.TimeshiftProgressEpgEnd`</b>, +/// \anchor PVR_TimeshiftProgressEpgEnd +/// _integer_, +/// @return The percentage of the end of the currently playing epg event within the PVR timeshift progress. +/// <p><hr> +/// @skinning_v18 **[New Infolabel]** \link PVR_TimeshiftProgressEpgEnd `PVR.TimeshiftProgressEpgEnd`\endlink +/// <p> +/// } +/// \table_row3{ <b>`PVR.TimeshiftProgressBufferStart`</b>, +/// \anchor PVR_TimeshiftProgressBufferStart +/// _integer_, +/// @return The percentage of the start of the timeshift buffer within the PVR timeshift progress. +/// <p><hr> +/// @skinning_v18 **[New Infolabel]** \link PVR_TimeshiftProgressBufferStart `PVR.TimeshiftProgressBufferStart`\endlink +/// <p> +/// } +/// \table_row3{ <b>`PVR.TimeshiftProgressBufferEnd`</b>, +/// \anchor PVR_TimeshiftProgressBufferEnd +/// _integer_, +/// @return The percentage of the end of the timeshift buffer within the PVR timeshift progress. +/// <p><hr> +/// @skinning_v18 **[New Infolabel]** \link PVR_TimeshiftProgressBufferEnd `PVR.TimeshiftProgressBufferEnd`\endlink +/// <p> +/// } +/// \table_row3{ <b>`PVR.EpgEventIcon`</b>, +/// \anchor PVR_EpgEventIcon +/// _string_, +/// @return The icon of the currently playing epg event\, if any. +/// <p><hr> +/// @skinning_v18 **[New Infolabel]** \link PVR_EpgEventIcon `PVR_EpgEventIcon`\endlink +/// <p> +/// } +/// +const infomap pvr[] = {{ "isrecording", PVR_IS_RECORDING }, + { "hastimer", PVR_HAS_TIMER }, + { "hastvchannels", PVR_HAS_TV_CHANNELS }, + { "hasradiochannels", PVR_HAS_RADIO_CHANNELS }, + { "hasnonrecordingtimer", PVR_HAS_NONRECORDING_TIMER }, + { "backendname", PVR_BACKEND_NAME }, + { "backendversion", PVR_BACKEND_VERSION }, + { "backendhost", PVR_BACKEND_HOST }, + { "backenddiskspace", PVR_BACKEND_DISKSPACE }, + { "backenddiskspaceprogr", PVR_BACKEND_DISKSPACE_PROGR }, + { "backendchannels", PVR_BACKEND_CHANNELS }, + { "backendtimers", PVR_BACKEND_TIMERS }, + { "backendrecordings", PVR_BACKEND_RECORDINGS }, + { "backenddeletedrecordings", PVR_BACKEND_DELETED_RECORDINGS }, + { "backendnumber", PVR_BACKEND_NUMBER }, + { "totaldiscspace", PVR_TOTAL_DISKSPACE }, + { "nexttimer", PVR_NEXT_TIMER }, + { "isplayingtv", PVR_IS_PLAYING_TV }, + { "isplayingradio", PVR_IS_PLAYING_RADIO }, + { "isplayingrecording", PVR_IS_PLAYING_RECORDING }, + { "isplayingepgtag", PVR_IS_PLAYING_EPGTAG }, + { "epgeventprogress", PVR_EPG_EVENT_PROGRESS }, + { "actstreamclient", PVR_ACTUAL_STREAM_CLIENT }, + { "actstreamdevice", PVR_ACTUAL_STREAM_DEVICE }, + { "actstreamstatus", PVR_ACTUAL_STREAM_STATUS }, + { "actstreamsignal", PVR_ACTUAL_STREAM_SIG }, + { "actstreamsnr", PVR_ACTUAL_STREAM_SNR }, + { "actstreamber", PVR_ACTUAL_STREAM_BER }, + { "actstreamunc", PVR_ACTUAL_STREAM_UNC }, + { "actstreamprogrsignal", PVR_ACTUAL_STREAM_SIG_PROGR }, + { "actstreamprogrsnr", PVR_ACTUAL_STREAM_SNR_PROGR }, + { "actstreamisencrypted", PVR_ACTUAL_STREAM_ENCRYPTED }, + { "actstreamencryptionname", PVR_ACTUAL_STREAM_CRYPTION }, + { "actstreamservicename", PVR_ACTUAL_STREAM_SERVICE }, + { "actstreammux", PVR_ACTUAL_STREAM_MUX }, + { "actstreamprovidername", PVR_ACTUAL_STREAM_PROVIDER }, + { "istimeshift", PVR_IS_TIMESHIFTING }, + { "timeshiftprogress", PVR_TIMESHIFT_PROGRESS }, + { "timeshiftseekbar", PVR_TIMESHIFT_SEEKBAR }, + { "nowrecordingtitle", PVR_NOW_RECORDING_TITLE }, + { "nowrecordingdatetime", PVR_NOW_RECORDING_DATETIME }, + { "nowrecordingchannel", PVR_NOW_RECORDING_CHANNEL }, + { "nowrecordingchannelicon", PVR_NOW_RECORDING_CHAN_ICO }, + { "nextrecordingtitle", PVR_NEXT_RECORDING_TITLE }, + { "nextrecordingdatetime", PVR_NEXT_RECORDING_DATETIME }, + { "nextrecordingchannel", PVR_NEXT_RECORDING_CHANNEL }, + { "nextrecordingchannelicon", PVR_NEXT_RECORDING_CHAN_ICO }, + { "tvnowrecordingtitle", PVR_TV_NOW_RECORDING_TITLE }, + { "tvnowrecordingdatetime", PVR_TV_NOW_RECORDING_DATETIME }, + { "tvnowrecordingchannel", PVR_TV_NOW_RECORDING_CHANNEL }, + { "tvnowrecordingchannelicon", PVR_TV_NOW_RECORDING_CHAN_ICO }, + { "tvnextrecordingtitle", PVR_TV_NEXT_RECORDING_TITLE }, + { "tvnextrecordingdatetime", PVR_TV_NEXT_RECORDING_DATETIME }, + { "tvnextrecordingchannel", PVR_TV_NEXT_RECORDING_CHANNEL }, + { "tvnextrecordingchannelicon", PVR_TV_NEXT_RECORDING_CHAN_ICO }, + { "radionowrecordingtitle", PVR_RADIO_NOW_RECORDING_TITLE }, + { "radionowrecordingdatetime", PVR_RADIO_NOW_RECORDING_DATETIME }, + { "radionowrecordingchannel", PVR_RADIO_NOW_RECORDING_CHANNEL }, + { "radionowrecordingchannelicon", PVR_RADIO_NOW_RECORDING_CHAN_ICO }, + { "radionextrecordingtitle", PVR_RADIO_NEXT_RECORDING_TITLE }, + { "radionextrecordingdatetime", PVR_RADIO_NEXT_RECORDING_DATETIME }, + { "radionextrecordingchannel", PVR_RADIO_NEXT_RECORDING_CHANNEL }, + { "radionextrecordingchannelicon", PVR_RADIO_NEXT_RECORDING_CHAN_ICO }, + { "isrecordingtv", PVR_IS_RECORDING_TV }, + { "hastvtimer", PVR_HAS_TV_TIMER }, + { "hasnonrecordingtvtimer", PVR_HAS_NONRECORDING_TV_TIMER }, + { "isrecordingradio", PVR_IS_RECORDING_RADIO }, + { "hasradiotimer", PVR_HAS_RADIO_TIMER }, + { "hasnonrecordingradiotimer", PVR_HAS_NONRECORDING_RADIO_TIMER }, + { "channelnumberinput", PVR_CHANNEL_NUMBER_INPUT }, + { "canrecordplayingchannel", PVR_CAN_RECORD_PLAYING_CHANNEL }, + { "isrecordingplayingchannel", PVR_IS_RECORDING_PLAYING_CHANNEL }, + { "isplayingactiverecording", PVR_IS_PLAYING_ACTIVE_RECORDING }, + { "timeshiftprogressplaypos", PVR_TIMESHIFT_PROGRESS_PLAY_POS }, + { "timeshiftprogressepgstart", PVR_TIMESHIFT_PROGRESS_EPG_START }, + { "timeshiftprogressepgend", PVR_TIMESHIFT_PROGRESS_EPG_END }, + { "timeshiftprogressbufferstart", PVR_TIMESHIFT_PROGRESS_BUFFER_START }, + { "timeshiftprogressbufferend", PVR_TIMESHIFT_PROGRESS_BUFFER_END }, + { "epgeventicon", PVR_EPG_EVENT_ICON }}; + +/// \page modules__infolabels_boolean_conditions +/// \table_row3{ <b>`PVR.EpgEventDuration`</b>, +/// \anchor PVR_EpgEventDuration +/// _string_, +/// @return The duration of the currently playing epg event in the +/// format <b>hh:mm:ss</b>. +/// @note <b>hh:</b> will be omitted if hours value is zero. +/// <p><hr> +/// @skinning_v18 **[Infolabel Updated]** \link PVR_EpgEventDuration `PVR.EpgEventDuration`\endlink replaces +/// the old `PVR.Duration` infolabel. +/// <p> +/// } +/// \table_row3{ <b>`PVR.EpgEventDuration(format)`</b>, +/// \anchor PVR_EpgEventDuration_format +/// _string_, +/// @return The duration of the currently playing EPG event in different formats. +/// @param format [opt] The format of the return time value. +/// See \ref TIME_FORMAT for the list of possible values. +/// <p> +/// } +/// \table_row3{ <b>`PVR.EpgEventElapsedTime`</b>, +/// \anchor PVR_EpgEventElapsedTime +/// _string_, +/// @return the time of the current position of the currently playing epg event in the +/// format <b>hh:mm:ss</b>. +/// @note <b>hh:</b> will be omitted if hours value is zero. +/// <p><hr> +/// @skinning_v18 **[Infolabel Updated]** \link PVR_EpgEventElapsedTime `PVR.EpgEventElapsedTime`\endlink replaces +/// the old `PVR.Time` infolabel. +/// <p> +/// } +/// \table_row3{ <b>`PVR.EpgEventElapsedTime(format)`</b>, +/// \anchor PVR_EpgEventElapsedTime_format +/// _string_, +/// @return The time of the current position of the currently playing epg event in different formats. +/// @param format [opt] The format of the return time value. +/// See \ref TIME_FORMAT for the list of possible values. +/// <p> +/// } +/// \table_row3{ <b>`PVR.EpgEventRemainingTime`</b>, +/// \anchor PVR_EpgEventRemainingTime +/// _string_, +/// @return The remaining time for currently playing epg event in the +/// format <b>hh:mm:ss</b>. +/// @note <b>hh:</b> will be omitted if hours value is zero. +/// <p><hr> +/// @skinning_v18 **[New Infolabel]** \link PVR_EpgEventRemainingTime `PVR.EpgEventRemainingTime`\endlink +/// <p> +/// } +/// \table_row3{ <b>`PVR.EpgEventRemainingTime(format)`</b>, +/// \anchor PVR_EpgEventRemainingTime_format +/// _string_, +/// @return The remaining time for currently playing epg event in different formats. +/// @param format [opt] The format of the return time value. +/// See \ref TIME_FORMAT for the list of possible values. +/// <p> +/// } +/// \table_row3{ <b>`PVR.EpgEventSeekTime`</b>, +/// \anchor PVR_EpgEventSeekTime +/// _string_, +/// @return The time the user is seeking within the currently playing epg event in the +/// format <b>hh:mm:ss</b>. +/// @note <b>hh:</b> will be omitted if hours value is zero. +/// <p><hr> +/// @skinning_v18 **[New Infolabel]** \link PVR_EpgEventSeekTime `PVR.EpgEventSeekTime`\endlink +/// <p> +/// } +/// \table_row3{ <b>`PVR.EpgEventSeekTime(format)`</b>, +/// \anchor PVR_EpgEventSeekTime_format +/// _string_, +/// @return The time the user is seeking within the currently playing epg event in different formats. +/// @param format [opt] The format of the return time value. +/// See \ref TIME_FORMAT for the list of possible values. +/// <p> +/// } +/// \table_row3{ <b>`PVR.EpgEventFinishTime`</b>, +/// \anchor PVR_EpgEventFinishTime +/// _string_, +/// @return The time the currently playing epg event will end in the +/// format <b>hh:mm:ss</b>. +/// @note <b>hh:</b> will be omitted if hours value is zero. +/// <p><hr> +/// @skinning_v18 **[New Infolabel]** \link PVR_EpgEventFinishTime `PVR.EpgEventFinishTime`\endlink +/// <p> +/// } +/// \table_row3{ <b>`PVR.EpgEventFinishTime(format)`</b>, +/// \anchor PVR_EpgEventFinishTime_format +/// _string_, +/// Returns the time the currently playing epg event will end in different formats. +/// @param format [opt] The format of the return time value. +/// See \ref TIME_FORMAT for the list of possible values. +/// <p> +/// } +/// \table_row3{ <b>`PVR.TimeShiftStart`</b>, +/// \anchor PVR_TimeShiftStart +/// _string_, +/// @return The start time of the timeshift buffer in the +/// format <b>hh:mm:ss</b>. +/// @note <b>hh:</b> will be omitted if hours value is zero. +/// <p> +/// } +/// \table_row3{ <b>`PVR.TimeShiftStart(format)`</b>, +/// \anchor PVR_TimeShiftStart_format +/// _string_, +/// Returns the start time of the timeshift buffer in different formats. +/// @param format [opt] The format of the return time value. +/// See \ref TIME_FORMAT for the list of possible values. +/// <p> +/// } +/// \table_row3{ <b>`PVR.TimeShiftEnd`</b>, +/// \anchor PVR_TimeShiftEnd +/// _string_, +/// @return The end time of the timeshift buffer in the +/// format <b>hh:mm:ss</b>. +/// @note <b>hh:</b> will be omitted if hours value is zero. +/// <p> +/// } +/// \table_row3{ <b>`PVR.TimeShiftEnd(format)`</b>, +/// \anchor PVR_TimeShiftEnd_format +/// _string_, +/// @return The end time of the timeshift buffer in different formats. +/// @param format [opt] The format of the return time value. +/// See \ref TIME_FORMAT for the list of possible values. +/// <p> +/// } +/// \table_row3{ <b>`PVR.TimeShiftCur`</b>, +/// \anchor PVR_TimeShiftCur +/// _string_, +/// @return The current playback time within the timeshift buffer in the +/// format <b>hh:mm:ss</b>. +/// @note <b>hh:</b> will be omitted if hours value is zero. +/// <p> +/// } +/// \table_row3{ <b>`PVR.TimeShiftCur(format)`</b>, +/// \anchor PVR_TimeShiftCur_format +/// _string_, +/// Returns the current playback time within the timeshift buffer in different formats. +/// @param format [opt] The format of the return time value. +/// See \ref TIME_FORMAT for the list of possible values. +/// <p> +/// } +/// \table_row3{ <b>`PVR.TimeShiftOffset`</b>, +/// \anchor PVR_TimeShiftOffset +/// _string_, +/// @return The delta of timeshifted time to actual time in the +/// format <b>hh:mm:ss</b>. +/// @note <b>hh:</b> will be omitted if hours value is zero. +/// <p> +/// } +/// \table_row3{ <b>`PVR.TimeShiftOffset(format)`</b>, +/// \anchor PVR_TimeShiftOffset_format +/// _string_, +/// Returns the delta of timeshifted time to actual time in different formats. +/// @param format [opt] The format of the return time value. +/// See \ref TIME_FORMAT for the list of possible values. +/// <p> +/// } +/// \table_row3{ <b>`PVR.TimeshiftProgressDuration`</b>, +/// \anchor PVR_TimeshiftProgressDuration +/// _string_, +/// @return the duration of the PVR timeshift progress in the +/// format <b>hh:mm:ss</b>. +/// @note <b>hh:</b> will be omitted if hours value is zero. +/// <p><hr> +/// @skinning_v18 **[New Infolabel]** \link PVR_TimeshiftProgressDuration `PVR.TimeshiftProgressDuration`\endlink +/// <p> +/// } +/// \table_row3{ <b>`PVR.TimeshiftProgressDuration(format)`</b>, +/// \anchor PVR_TimeshiftProgressDuration_format +/// _string_, +/// @return The duration of the PVR timeshift progress in different formats. +/// @param format [opt] The format of the return time value. +/// See \ref TIME_FORMAT for the list of possible values. +/// <p> +/// } +/// \table_row3{ <b>`PVR.TimeshiftProgressStartTime`</b>, +/// \anchor PVR_TimeshiftProgressStartTime +/// _string_, +/// @return The start time of the PVR timeshift progress in the +/// format <b>hh:mm:ss</b>. +/// @note <b>hh:</b> will be omitted if hours value is zero. +/// <p><hr> +/// @skinning_v18 **[New Infolabel]** \link PVR_TimeshiftProgressStartTime `PVR.TimeshiftProgressStartTime`\endlink +/// <p> +/// } +/// \table_row3{ <b>`PVR.TimeshiftProgressStartTime(format)`</b>, +/// \anchor PVR_TimeshiftProgressStartTime_format +/// _string_, +/// @return The start time of the PVR timeshift progress in different formats. +/// @param format [opt] The format of the return time value. +/// See \ref TIME_FORMAT for the list of possible values. +/// <p> +/// } +/// \table_row3{ <b>`PVR.TimeshiftProgressEndTime`</b>, +/// \anchor PVR_TimeshiftProgressEndTime +/// _string_, +/// @return The end time of the PVR timeshift progress in the +/// format <b>hh:mm:ss</b>. +/// @note hh: will be omitted if hours value is zero. +/// <p><hr> +/// @skinning_v18 **[New Infolabel]** \link PVR_TimeshiftProgressEndTime `PVR.TimeshiftProgressEndTime`\endlink +/// <p> +/// } +/// \table_row3{ <b>`PVR.TimeshiftProgressEndTime(format)`</b>, +/// \anchor PVR_TimeshiftProgressEndTime_format +/// _string_, +/// @return The end time of the PVR timeshift progress in different formats. +/// @param format [opt] The format of the return time value. +/// See \ref TIME_FORMAT for the list of possible values. +/// <p> +/// } +/// \table_end +/// +/// ----------------------------------------------------------------------------- +const infomap pvr_times[] = {{ "epgeventduration", PVR_EPG_EVENT_DURATION }, + { "epgeventelapsedtime", PVR_EPG_EVENT_ELAPSED_TIME }, + { "epgeventremainingtime", PVR_EPG_EVENT_REMAINING_TIME }, + { "epgeventfinishtime", PVR_EPG_EVENT_FINISH_TIME }, + { "epgeventseektime", PVR_EPG_EVENT_SEEK_TIME }, + { "timeshiftstart", PVR_TIMESHIFT_START_TIME }, + { "timeshiftend", PVR_TIMESHIFT_END_TIME }, + { "timeshiftcur", PVR_TIMESHIFT_PLAY_TIME }, + { "timeshiftoffset", PVR_TIMESHIFT_OFFSET }, + { "timeshiftprogressduration", PVR_TIMESHIFT_PROGRESS_DURATION }, + { "timeshiftprogressstarttime", PVR_TIMESHIFT_PROGRESS_START_TIME }, + { "timeshiftprogressendtime", PVR_TIMESHIFT_PROGRESS_END_TIME }}; + +/// \page modules__infolabels_boolean_conditions +/// \subsection modules__infolabels_boolean_conditions_RDS RDS +/// @note Only supported if both the PVR backend and the Kodi client support RDS. +/// +/// \table_start +/// \table_h3{ Labels, Type, Description } +/// \table_row3{ <b>`RDS.HasRds`</b>, +/// \anchor RDS_HasRds +/// _boolean_, +/// @return **True** if RDS is present. +/// <p><hr> +/// @skinning_v16 **[New Boolean Condition]** \link RDS_HasRds `RDS.HasRds`\endlink +/// <p> +/// } +/// \table_row3{ <b>`RDS.HasRadioText`</b>, +/// \anchor RDS_HasRadioText +/// _boolean_, +/// @return **True** if RDS contains also RadioText. +/// <p><hr> +/// @skinning_v16 **[New Boolean Condition]** \link RDS_HasRadioText `RDS.HasRadioText`\endlink +/// <p> +/// } +/// \table_row3{ <b>`RDS.HasRadioTextPlus`</b>, +/// \anchor RDS_HasRadioTextPlus +/// _boolean_, +/// @return **True** if RDS with RadioText contains also the plus information. +/// <p><hr> +/// @skinning_v16 **[New Boolean Condition]** \link RDS_HasRadioTextPlus `RDS.HasRadioTextPlus`\endlink +/// <p> +/// } +/// \table_row3{ <b>`RDS.HasHotline`</b>, +/// \anchor RDS_HasHotline +/// _boolean_, +/// @return **True** if a hotline phone number is present. +/// @note Only available on RadioText Plus +/// <p><hr> +/// @skinning_v16 **[New Boolean Condition]** \link RDS_HasHotline `RDS.HasHotline`\endlink +/// <p> +/// } +/// \table_row3{ <b>`RDS.HasStudio`</b>, +/// \anchor RDS_HasStudio +/// _boolean_, +/// @return **True** if a studio name is present. +/// @note Only available on RadioText Plus +/// <p><hr> +/// @skinning_v16 **[New Boolean Condition]** \link RDS_HasStudio `RDS.HasStudio`\endlink +/// <p> +/// } +/// \table_row3{ <b>`RDS.AudioLanguage`</b>, +/// \anchor RDS_AudioLanguage +/// _string_, +/// @return The RDS reported audio language of the channel. +/// <p><hr> +/// @skinning_v16 **[New Infolabel]** \link RDS_AudioLanguage `RDS.AudioLanguage`\endlink +/// <p> +/// } +/// \table_row3{ <b>`RDS.ChannelCountry`</b>, +/// \anchor RDS_ChannelCountry +/// _string_, +/// @return The country where the radio channel is broadcasted. +/// <p><hr> +/// @skinning_v16 **[New Infolabel]** \link RDS_ChannelCountry `RDS.ChannelCountry`\endlink +/// <p> +/// } +/// \table_row3{ <b>`RDS.GetLine(number)`</b>, +/// \anchor RDS_GetLine +/// _string_, +/// @return The last sent RDS text messages on given number. +/// @param number - given number for RDS\, 0 is the +/// last and 4 rows are supported (0-3) +/// <p><hr> +/// @skinning_v16 **[New Infolabel]** \link RDS_GetLine `RDS.GetLine(number)`\endlink +/// <p> +/// } +/// \table_row3{ <b>`RDS.Title`</b>, +/// \anchor RDS_Title +/// _string_, +/// @return The title of item; e.g. track title of an album. +/// @note Only available on RadioText Plus +/// <p><hr> +/// @skinning_v16 **[New Infolabel]** \link RDS_Title `RDS.Title`\endlink +/// <p> +/// } +/// \table_row3{ <b>`RDS.Artist`</b>, +/// \anchor RDS_Artist +/// _string_, +/// @return A person or band/collective generally considered responsible for the work. +/// @note Only available on RadioText Plus +/// <p><hr> +/// @skinning_v16 **[New Infolabel]** \link RDS_Artist `RDS.Artist`\endlink +/// <p> +/// } +/// \table_row3{ <b>`RDS.Band`</b>, +/// \anchor RDS_Band +/// _string_, +/// @return The band/orchestra/musician. +/// @note Only available on RadioText Plus +/// <p><hr> +/// @skinning_v16 **[New Infolabel]** \link RDS_Band `RDS.Band`\endlink +/// <p> +/// } +/// \table_row3{ <b>`RDS.Composer`</b>, +/// \anchor RDS_Composer +/// _string_, +/// @return The name of the original composer/author. +/// @note Only available on RadioText Plus +/// <p><hr> +/// @skinning_v16 **[New Infolabel]** \link RDS_Composer `RDS.Composer`\endlink +/// <p> +/// } +/// \table_row3{ <b>`RDS.Conductor`</b>, +/// \anchor RDS_Conductor +/// _string_, +/// @return The artist(s) who performed the work. In classical music this would be +/// the conductor. +/// @note Only available on RadioText Plus +/// <p><hr> +/// @skinning_v16 **[New Infolabel]** \link RDS_Conductor `RDS.Conductor`\endlink +/// <p> +/// } +/// \table_row3{ <b>`RDS.Album`</b>, +/// \anchor RDS_Album +/// _string_, +/// @return The album of the song. +/// @note Only available on RadioText Plus +/// <p><hr> +/// @skinning_v16 **[New Infolabel]** \link RDS_Album `RDS.Album`\endlink +/// <p> +/// } +/// \table_row3{ <b>`RDS.TrackNumber`</b>, +/// \anchor RDS_TrackNumber +/// _string_, +/// @return The track number of the item on the album on which it was originally +/// released. +/// @note Only be available on RadioText Plus +/// <p><hr> +/// @skinning_v16 **[New Infolabel]** \link RDS_TrackNumber `RDS.TrackNumber`\endlink +/// <p> +/// } +/// \table_row3{ <b>`RDS.RadioStyle`</b>, +/// \anchor RDS_RadioStyle +/// _string_, +/// @return The style of current played radio channel\, it is always +/// updated once the style changes\, e.g "popmusic" to "news" or "weather"... +/// | RDS | RBDS | +/// |:------------------------|:------------------------| +/// | none | none | +/// | news | news | +/// | currentaffairs | information | +/// | information | sport | +/// | sport | talk | +/// | education | rockmusic | +/// | drama | classicrockmusic | +/// | cultures | adulthits | +/// | science | softrock | +/// | variedspeech | top40 | +/// | popmusic | countrymusic | +/// | rockmusic | oldiesmusic | +/// | easylistening | softmusic | +/// | lightclassics | nostalgia | +/// | seriousclassics | jazzmusic | +/// | othermusic | classical | +/// | weather | randb | +/// | finance | softrandb | +/// | childrensprogs | language | +/// | socialaffairs | religiousmusic | +/// | religion | religioustalk | +/// | phonein | personality | +/// | travelandtouring | public | +/// | leisureandhobby | college | +/// | jazzmusic | spanishtalk | +/// | countrymusic | spanishmusic | +/// | nationalmusic | hiphop | +/// | oldiesmusic | | +/// | folkmusic | | +/// | documentary | weather | +/// | alarmtest | alarmtest | +/// | alarm-alarm | alarm-alarm | +/// @note "alarm-alarm" is normally not used from radio stations\, is thought +/// to inform about horrible messages who are needed asap to all people. +/// <p><hr> +/// @skinning_v16 **[New Infolabel]** \link RDS_RadioStyle `RDS.RadioStyle`\endlink +/// <p> +/// } +/// \table_row3{ <b>`RDS.Comment`</b>, +/// \anchor RDS_Comment +/// _string_, +/// @return The radio station comment string if available. +/// @note Only available on RadioText Plus +/// <p><hr> +/// @skinning_v16 **[New Infolabel]** \link RDS_Comment `RDS.Comment`\endlink +/// <p> +/// } +/// \table_row3{ <b>`RDS.InfoNews`</b>, +/// \anchor RDS_InfoNews +/// _string_, +/// @return The message / headline (if available). +/// @note Only available on RadioText Plus +/// <p><hr> +/// @skinning_v16 **[New Infolabel]** \link RDS_InfoNews `RDS.InfoNews`\endlink +/// <p> +/// } +/// \table_row3{ <b>`RDS.InfoNewsLocal`</b>, +/// \anchor RDS_InfoNewsLocal +/// _string_, +/// @return The local information news sended from radio channel (if available). +/// @note Only available on RadioText Plus +/// <p><hr> +/// @skinning_v16 **[New Infolabel]** \link RDS_InfoNewsLocal `RDS.InfoNewsLocal`\endlink +/// <p> +/// } +/// \table_row3{ <b>`RDS.InfoStock`</b>, +/// \anchor RDS_InfoStock +/// _string_, +/// @return The stock information; either as one part or as several distinct parts: +/// "name 99latest value 99change 99high 99low 99volume" (if available). +/// @note Only available on RadioText Plus +/// <p><hr> +/// @skinning_v16 **[New Infolabel]** \link RDS_InfoStock `RDS.InfoStock`\endlink +/// <p> +/// } +/// \table_row3{ <b>`RDS.InfoStockSize`</b>, +/// \anchor RDS_InfoStockSize +/// _string_, +/// @return The number of rows present in stock information. +/// @note Only available on RadioText Plus +/// <p><hr> +/// @skinning_v16 **[New Infolabel]** \link RDS_InfoStockSize `RDS.InfoStockSize`\endlink +/// <p> +/// } +/// \table_row3{ <b>`RDS.InfoSport`</b>, +/// \anchor RDS_InfoSport +/// _string_, +/// @return The result of a match; either as one part or as several distinct parts: +/// "match 99result"\, e.g. "Bayern München : Borussia 995:5" (if available). +/// @note Only available on RadioText Plus +/// <p><hr> +/// @skinning_v16 **[New Infolabel]** \link RDS_InfoSport `RDS.InfoSport`\endlink +/// <p> +/// } +/// \table_row3{ <b>`RDS.InfoSportSize`</b>, +/// \anchor RDS_InfoSportSize +/// _string_, +/// @return The number of rows present in sport information. +/// @note Only available on RadioText Plus +/// <p><hr> +/// @skinning_v16 **[New Infolabel]** \link RDS_InfoSportSize `RDS.InfoSportSize`\endlink +/// <p> +/// } +/// \table_row3{ <b>`RDS.InfoLottery`</b>, +/// \anchor RDS_InfoLottery +/// _string_, +/// @return The raffle / lottery: "key word 99values" (if available). +/// @note Only available on RadioText Plus +/// <p><hr> +/// @skinning_v16 **[New Infolabel]** \link RDS_InfoLottery `RDS.InfoLottery`\endlink +/// <p> +/// } +/// \table_row3{ <b>`RDS.InfoLotterySize`</b>, +/// \anchor RDS_InfoLotterySize +/// _string_, +/// @return The number of rows present in lottery information. +/// @note Only available on RadioText Plus +/// <p><hr> +/// @skinning_v16 **[New Infolabel]** \link RDS_InfoLotterySize `RDS.InfoLotterySize`\endlink +/// <p> +/// } +/// \table_row3{ <b>`RDS.InfoWeather`</b>, +/// \anchor RDS_InfoWeather +/// _string_, +/// @return The weather information (if available). +/// @note Only available on RadioText Plus +/// <p><hr> +/// @skinning_v16 **[New Infolabel]** \link RDS_InfoWeather `RDS.InfoWeather`\endlink +/// <p> +/// } +/// \table_row3{ <b>`RDS.InfoWeatherSize`</b>, +/// \anchor RDS_InfoWeatherSize +/// _string_, +/// @return The number of rows present in weather information. +/// @note Only available on RadioText Plus +/// <p><hr> +/// @skinning_v16 **[New Infolabel]** \link RDS_InfoWeatherSize `RDS.InfoWeatherSize`\endlink +/// <p> +/// } +/// \table_row3{ <b>`RDS.InfoCinema`</b>, +/// \anchor RDS_InfoCinema +/// _string_, +/// @return The information about movies in cinema (if available). +/// @note Only available on RadioText Plus +/// <p><hr> +/// @skinning_v16 **[New Infolabel]** \link RDS_InfoCinema `RDS.InfoCinema`\endlink +/// <p> +/// } +/// \table_row3{ <b>`RDS.InfoCinemaSize`</b>, +/// \anchor RDS_InfoCinemaSize +/// _string_, +/// @return The number of rows present in cinema information. +/// @note Only available on RadioText Plus +/// <p><hr> +/// @skinning_v16 **[New Infolabel]** \link RDS_InfoCinemaSize `RDS.InfoCinemaSize`\endlink +/// <p> +/// } +/// \table_row3{ <b>`RDS.InfoHoroscope`</b>, +/// \anchor RDS_InfoHoroscope +/// _string_, +/// @return The horoscope; either as one part or as two distinct parts: +/// "key word 99text"\, e.g. "sign of the zodiac 99blablabla" (if available). +/// @note Only available on RadioText Plus +/// <p><hr> +/// @skinning_v16 **[New Infolabel]** \link RDS_InfoHoroscope `RDS.InfoHoroscope`\endlink +/// <p> +/// } +/// \table_row3{ <b>`RDS.InfoHoroscopeSize`</b>, +/// \anchor RDS_InfoHoroscopeSize +/// _string_, +/// @return The Number of rows present in horoscope information. +/// @note Only available on RadioText Plus +/// <p><hr> +/// @skinning_v16 **[New Infolabel]** \link RDS_InfoHoroscopeSize `RDS.InfoHoroscopeSize`\endlink +/// <p> +/// } +/// \table_row3{ <b>`RDS.InfoOther`</b>, +/// \anchor RDS_InfoOther +/// _string_, +/// @return Other information\, not especially specified: "key word 99info" (if available). +/// @note Only available on RadioText Plus +/// <p><hr> +/// @skinning_v16 **[New Infolabel]** \link RDS_InfoOther `RDS.InfoOther`\endlink +/// <p> +/// } +/// \table_row3{ <b>`RDS.InfoOtherSize`</b>, +/// \anchor RDS_InfoOtherSize +/// _string_, +/// @return The number of rows present with other information. +/// @note Only available on RadioText Plus +/// <p><hr> +/// @skinning_v16 **[New Infolabel]** \link RDS_InfoOtherSize `RDS.InfoOtherSize`\endlink +/// <p> +/// } +/// \table_row3{ <b>`RDS.ProgStation`</b>, +/// \anchor RDS_ProgStation +/// _string_, +/// @return The name of the radio channel. +/// @note becomes also set from epg if it is not available from RDS +/// <p><hr> +/// @skinning_v16 **[New Infolabel]** \link RDS_ProgStation `RDS.ProgStation`\endlink +/// <p> +/// } +/// \table_row3{ <b>`RDS.ProgNow`</b>, +/// \anchor RDS_ProgNow +/// _string_, +/// @return The now playing program name. +/// @note becomes also be set from epg if from RDS not available +/// <p><hr> +/// @skinning_v16 **[New Infolabel]** \link RDS_ProgNow `RDS.ProgNow`\endlink +/// <p> +/// } +/// \table_row3{ <b>`RDS.ProgNext`</b>, +/// \anchor RDS_ProgNext +/// _string_, +/// @return The next played program name (if available). +/// @note becomes also be set from epg if from RDS not available +/// <p><hr> +/// @skinning_v16 **[New Infolabel]** \link RDS_ProgNext `RDS.ProgNext`\endlink +/// <p> +/// } +/// \table_row3{ <b>`RDS.ProgHost`</b>, +/// \anchor RDS_ProgHost +/// _string_, +/// @return The name of the host of the radio show. +/// <p><hr> +/// @skinning_v16 **[New Infolabel]** \link RDS_ProgHost `RDS.ProgHost`\endlink +/// <p> +/// } +/// \table_row3{ <b>`RDS.ProgEditStaff`</b>, +/// \anchor RDS_ProgEditStaff +/// _string_, +/// @return The name of the editorial staff; e.g. name of editorial journalist. +/// @note Only available on RadioText Plus +/// <p><hr> +/// @skinning_v16 **[New Infolabel]** \link RDS_ProgEditStaff `RDS.ProgEditStaff`\endlink +/// <p> +/// } +/// \table_row3{ <b>`RDS.ProgHomepage`</b>, +/// \anchor RDS_ProgHomepage +/// _string_, +/// @return The Link to radio station homepage +/// @note Only available on RadioText Plus +/// <p><hr> +/// @skinning_v16 **[New Infolabel]** \link RDS_ProgHomepage `RDS.ProgHomepage`\endlink +/// <p> +/// } +/// \table_row3{ <b>`RDS.ProgStyle`</b>, +/// \anchor RDS_ProgStyle +/// _string_, +/// @return A human readable string about radiostyle defined from RDS or RBDS. +/// <p><hr> +/// @skinning_v16 **[New Infolabel]** \link RDS_ProgStyle `RDS.ProgStyle`\endlink +/// <p> +/// } +/// \table_row3{ <b>`RDS.PhoneHotline`</b>, +/// \anchor RDS_PhoneHotline +/// _string_, +/// @return The telephone number of the radio station's hotline. +/// @note Only available on RadioText Plus +/// <p><hr> +/// @skinning_v16 **[New Infolabel]** \link RDS_PhoneHotline `RDS.PhoneHotline`\endlink +/// <p> +/// } +/// \table_row3{ <b>`RDS.PhoneStudio`</b>, +/// \anchor RDS_PhoneStudio +/// _string_, +/// @return The telephone number of the radio station's studio. +/// @note Only available on RadioText Plus +/// <p><hr> +/// @skinning_v16 **[New Infolabel]** \link RDS_PhoneStudio `RDS.PhoneStudio`\endlink +/// <p> +/// } +/// \table_row3{ <b>`RDS.SmsStudio`</b>, +/// \anchor RDS_SmsStudio +/// _string_, +/// @return The sms number of the radio stations studio (to send directly a sms to +/// the studio) (if available). +/// @note Only available on RadioText Plus +/// <p><hr> +/// @skinning_v16 **[New Infolabel]** \link RDS_SmsStudio `RDS.SmsStudio`\endlink +/// <p> +/// } +/// \table_row3{ <b>`RDS.EmailHotline`</b>, +/// \anchor RDS_EmailHotline +/// _string_, +/// @return The email address of the radio stations hotline (if available). +/// @note Only available on RadioText Plus +/// <p><hr> +/// @skinning_v16 **[New Infolabel]** \link RDS_EmailHotline `RDS.EmailHotline`\endlink +/// <p> +/// } +/// \table_row3{ <b>`RDS.EmailStudio`</b>, +/// \anchor RDS_EmailStudio +/// _string_, +/// @return The email address of the radio station's studio (if available). +/// @note Only available on RadioText Plus +/// <p><hr> +/// @skinning_v16 **[New Infolabel]** \link RDS_EmailStudio `RDS.EmailStudio`\endlink +/// <p> +/// } +/// \table_end +/// +/// ----------------------------------------------------------------------------- +const infomap rds[] = {{ "hasrds", RDS_HAS_RDS }, + { "hasradiotext", RDS_HAS_RADIOTEXT }, + { "hasradiotextplus", RDS_HAS_RADIOTEXT_PLUS }, + { "audiolanguage", RDS_AUDIO_LANG }, + { "channelcountry", RDS_CHANNEL_COUNTRY }, + { "title", RDS_TITLE }, + { "getline", RDS_GET_RADIOTEXT_LINE }, + { "artist", RDS_ARTIST }, + { "band", RDS_BAND }, + { "composer", RDS_COMPOSER }, + { "conductor", RDS_CONDUCTOR }, + { "album", RDS_ALBUM }, + { "tracknumber", RDS_ALBUM_TRACKNUMBER }, + { "radiostyle", RDS_GET_RADIO_STYLE }, + { "comment", RDS_COMMENT }, + { "infonews", RDS_INFO_NEWS }, + { "infonewslocal", RDS_INFO_NEWS_LOCAL }, + { "infostock", RDS_INFO_STOCK }, + { "infostocksize", RDS_INFO_STOCK_SIZE }, + { "infosport", RDS_INFO_SPORT }, + { "infosportsize", RDS_INFO_SPORT_SIZE }, + { "infolottery", RDS_INFO_LOTTERY }, + { "infolotterysize", RDS_INFO_LOTTERY_SIZE }, + { "infoweather", RDS_INFO_WEATHER }, + { "infoweathersize", RDS_INFO_WEATHER_SIZE }, + { "infocinema", RDS_INFO_CINEMA }, + { "infocinemasize", RDS_INFO_CINEMA_SIZE }, + { "infohoroscope", RDS_INFO_HOROSCOPE }, + { "infohoroscopesize", RDS_INFO_HOROSCOPE_SIZE }, + { "infoother", RDS_INFO_OTHER }, + { "infoothersize", RDS_INFO_OTHER_SIZE }, + { "progstation", RDS_PROG_STATION }, + { "prognow", RDS_PROG_NOW }, + { "prognext", RDS_PROG_NEXT }, + { "proghost", RDS_PROG_HOST }, + { "progeditstaff", RDS_PROG_EDIT_STAFF }, + { "proghomepage", RDS_PROG_HOMEPAGE }, + { "progstyle", RDS_PROG_STYLE }, + { "phonehotline", RDS_PHONE_HOTLINE }, + { "phonestudio", RDS_PHONE_STUDIO }, + { "smsstudio", RDS_SMS_STUDIO }, + { "emailhotline", RDS_EMAIL_HOTLINE }, + { "emailstudio", RDS_EMAIL_STUDIO }, + { "hashotline", RDS_HAS_HOTLINE_DATA }, + { "hasstudio", RDS_HAS_STUDIO_DATA }}; + +/// \page modules__infolabels_boolean_conditions +/// \subsection modules__infolabels_boolean_conditions_slideshow Slideshow +/// \table_start +/// \table_h3{ Labels, Type, Description } +/// \table_row3{ <b>`Slideshow.IsActive`</b>, +/// \anchor Slideshow_IsActive +/// _boolean_, +/// @return **True** if the picture slideshow is running. +/// <p> +/// } +/// \table_row3{ <b>`Slideshow.IsPaused`</b>, +/// \anchor Slideshow_IsPaused +/// _boolean_, +/// @return **True** if the picture slideshow is paused. +/// <p> +/// } +/// \table_row3{ <b>`Slideshow.IsRandom`</b>, +/// \anchor Slideshow_IsRandom +/// _boolean_, +/// @return **True** if the picture slideshow is in random mode. +/// <p> +/// } +/// \table_row3{ <b>`Slideshow.IsVideo`</b>, +/// \anchor Slideshow_IsVideo +/// _boolean_, +/// @return **True** if the picture slideshow is playing a video. +/// <p><hr> +/// @skinning_v13 **[New Boolean Condition]** \link Slideshow_IsVideo `Slideshow.IsVideo`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Slideshow.Altitude`</b>, +/// \anchor Slideshow_Altitude +/// _string_, +/// @return The altitude in meters where the current picture was taken. +/// @note This is the value of the EXIF GPSInfo.GPSAltitude tag. +/// <p> +/// } +/// \table_row3{ <b>`Slideshow.Aperture`</b>, +/// \anchor Slideshow_Aperture +/// _string_, +/// @return The F-stop used to take the current picture. +/// @note This is the value of the EXIF FNumber tag (hex code 0x829D). +/// <p> +/// } +/// \table_row3{ <b>`Slideshow.Author`</b>, +/// \anchor Slideshow_Author +/// _string_, +/// @return The name of the person involved in writing about the current +/// picture. +/// @note This is the value of the IPTC Writer tag (hex code 0x7A). +/// <p><hr> +/// @skinning_v13 **[New Infolabel]** \link Slideshow_Author `Slideshow.Author`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Slideshow.Byline`</b>, +/// \anchor Slideshow_Byline +/// _string_, +/// @return The name of the person who created the current picture. +/// @note This is the value of the IPTC Byline tag (hex code 0x50). +/// <p><hr> +/// @skinning_v13 **[New Infolabel]** \link Slideshow_Byline `Slideshow.Byline`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Slideshow.BylineTitle`</b>, +/// \anchor Slideshow_BylineTitle +/// _string_, +/// @return The title of the person who created the current picture. +/// @note This is the value of the IPTC BylineTitle tag (hex code 0x55). +/// <p><hr> +/// @skinning_v13 **[New Infolabel]** \link Slideshow_BylineTitle `Slideshow.BylineTitle`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Slideshow.CameraMake`</b>, +/// \anchor Slideshow_CameraMake +/// _string_, +/// @return The manufacturer of the camera used to take the current picture. +/// @note This is the value of the EXIF Make tag (hex code 0x010F). +/// <p> +/// } +/// \table_row3{ <b>`Slideshow.CameraModel`</b>, +/// \anchor Slideshow_CameraModel +/// _string_, +/// @return The manufacturer's model name or number of the camera used to take +/// the current picture. +/// @note This is the value of the EXIF Model tag (hex code 0x0110). +/// <p> +/// } +/// \table_row3{ <b>`Slideshow.Caption`</b>, +/// \anchor Slideshow_Caption +/// _string_, +/// @return A description of the current picture. +/// @note This is the value of the IPTC Caption tag (hex code 0x78). +/// <p> +/// } +/// \table_row3{ <b>`Slideshow.Category`</b>, +/// \anchor Slideshow_Category +/// _string_, +/// @return The subject of the current picture as a category code. +/// @note This is the value of the IPTC Category tag (hex code 0x0F). +/// <p><hr> +/// @skinning_v13 **[New Infolabel]** \link Slideshow_Category `Slideshow.Category`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Slideshow.CCDWidth`</b>, +/// \anchor Slideshow_CCDWidth +/// _string_, +/// @return The width of the CCD in the camera used to take the current +/// picture. +/// @note This is calculated from three EXIF tags (0xA002 * 0xA210 / 0xA20e). +/// <p><hr> +/// @skinning_v13 **[New Infolabel]** \link Slideshow_CCDWidth `Slideshow.CCDWidth`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Slideshow.City`</b>, +/// \anchor Slideshow_City +/// _string_, +/// @return The city where the current picture was taken. +/// @note This is the value of the IPTC City tag (hex code 0x5A). +/// <p><hr> +/// @skinning_v13 **[New Infolabel]** \link Slideshow_City `Slideshow.City`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Slideshow.Colour`</b>, +/// \anchor Slideshow_Colour +/// _string_, +/// @return the colour of the picture. It can have one of the following values: +/// - <b>"Colour"</b> +/// - <b>"Black and White"</b> +/// <p><hr> +/// @skinning_v13 **[New Infolabel]** \link Slideshow_Colour `Slideshow.Colour`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Slideshow.CopyrightNotice`</b>, +/// \anchor Slideshow_CopyrightNotice +/// _string_, +/// @return The copyright notice of the current picture. +/// @note This is the value of the IPTC Copyright tag (hex code 0x74). +/// <p><hr> +/// @skinning_v13 **[New Infolabel]** \link Slideshow_CopyrightNotice `Slideshow.CopyrightNotice`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Slideshow.Country`</b>, +/// \anchor Slideshow_Country +/// _string_, +/// @return The full name of the country where the current picture was taken. +/// @note This is the value of the IPTC CountryName tag (hex code 0x65). +/// <p><hr> +/// @skinning_v13 **[New Infolabel]** \link Slideshow_Country `Slideshow.Country`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Slideshow.CountryCode`</b>, +/// \anchor Slideshow_CountryCode +/// _string_, +/// @return The country code of the country where the current picture was +/// taken. +/// @note This is the value of the IPTC CountryCode tag (hex code 0x64). +/// <p><hr> +/// @skinning_v13 **[New Infolabel]** \link Slideshow_CountryCode `Slideshow.CountryCode`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Slideshow.Credit`</b>, +/// \anchor Slideshow_Credit +/// _string_, +/// @return Who provided the current picture. +/// @note This is the value of the IPTC Credit tag (hex code 0x6E). +/// <p><hr> +/// @skinning_v13 **[New Infolabel]** \link Slideshow_Credit `Slideshow.Credit`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Slideshow.DigitalZoom`</b>, +/// \anchor Slideshow_DigitalZoom +/// _string_, +/// @return The digital zoom ratio when the current picture was taken. +/// @note This is the value of the EXIF .DigitalZoomRatio tag (hex code 0xA404). +/// <p><hr> +/// @skinning_v13 **[New Infolabel]** \link Slideshow_DigitalZoom `Slideshow.DigitalZoom`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Slideshow.EXIFComment`</b>, +/// \anchor Slideshow_EXIFComment +/// _string_, +/// @return A description of the current picture. +/// @note This is the value of the EXIF User Comment tag (hex code 0x9286). +/// This is the same value as \ref Slideshow_SlideComment "Slideshow.SlideComment". +/// <p> +/// } +/// \table_row3{ <b>`Slideshow.EXIFDate`</b>, +/// \anchor Slideshow_EXIFDate +/// _string_, +/// @return The localized date of the current picture. The short form of the +/// date is used. +/// @note The value of the EXIF DateTimeOriginal tag (hex code +/// 0x9003) is preferred. If the DateTimeOriginal tag is not found\, the +/// value of DateTimeDigitized (hex code 0x9004) or of DateTime (hex code +/// 0x0132) might be used. +/// <p><hr> +/// @skinning_v13 **[New Infolabel]** \link Slideshow_EXIFDate `Slideshow.EXIFDate`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Slideshow.EXIFDescription`</b>, +/// \anchor Slideshow_EXIFDescription +/// _string_, +/// @return A short description of the current picture. The SlideComment\, +/// EXIFComment or Caption values might contain a longer description. +/// @note This is the value of the EXIF ImageDescription tag (hex code 0x010E). +/// <p> +/// } +/// \table_row3{ <b>`Slideshow.EXIFSoftware`</b>, +/// \anchor Slideshow_EXIFSoftware +/// _string_, +/// @return The name and version of the firmware used by the camera that took +/// the current picture. +/// @note This is the value of the EXIF Software tag (hex code 0x0131). +/// <p> +/// } +/// \table_row3{ <b>`Slideshow.EXIFTime`</b>, +/// \anchor Slideshow_EXIFTime +/// _string_, +/// @return The date/timestamp of the current picture. The localized short +/// form of the date and time is used. +/// @note The value of the EXIF DateTimeOriginal tag (hex code 0x9003) is +/// preferred. If the DateTimeOriginal tag is not found\, the value of +/// DateTimeDigitized (hex code 0x9004) or of DateTime (hex code 0x0132) +/// might be used. +/// <p> +/// } +/// \table_row3{ <b>`Slideshow.Exposure`</b>, +/// \anchor Slideshow_Exposure +/// _string_, +/// @return The class of the program used by the camera to set exposure when +/// the current picture was taken. Values include: +/// - <b>"Manual"</b> +/// - <b>"Program (Auto)"</b> +/// - <b>"Aperture priority (Semi-Auto)"</b> +/// - <b>"Shutter priority (semi-auto)"</b> +/// - etc... +/// @note This is the value of the EXIF ExposureProgram tag +/// (hex code 0x8822). +/// <p><hr> +/// @skinning_v13 **[New Infolabel]** \link Slideshow_Exposure `Slideshow.Exposure`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Slideshow.ExposureBias`</b>, +/// \anchor Slideshow_ExposureBias +/// _string_, +/// @return The exposure bias of the current picture. Typically this is a +/// number between -99.99 and 99.99. +/// @note This is the value of the EXIF ExposureBiasValue tag (hex code 0x9204). +/// <p><hr> +/// @skinning_v13 **[New Infolabel]** \link Slideshow_ExposureBias `Slideshow.ExposureBias`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Slideshow.ExposureMode`</b>, +/// \anchor Slideshow_ExposureMode +/// _string_, +/// @return The exposure mode of the current picture. The possible values are: +/// - <b>"Automatic"</b> +/// - <b>"Manual"</b> +/// - <b>"Auto bracketing"</b> +/// @note This is the value of the EXIF ExposureMode tag (hex code 0xA402). +/// <p> +/// } +/// \table_row3{ <b>`Slideshow.ExposureTime`</b>, +/// \anchor Slideshow_ExposureTime +/// _string_, +/// @return The exposure time of the current picture\, in seconds. +/// @note This is the value of the EXIF ExposureTime tag (hex code 0x829A). +/// If the ExposureTime tag is not found\, the ShutterSpeedValue tag (hex code +/// 0x9201) might be used. +/// <p> +/// } +/// \table_row3{ <b>`Slideshow.Filedate`</b>, +/// \anchor Slideshow_Filedate +/// _string_, +/// @return The file date of the current picture. +/// <p> +/// } +/// \table_row3{ <b>`Slideshow.Filename`</b>, +/// \anchor Slideshow_Filename +/// _string_, +/// @return The file name of the current picture. +/// <p> +/// } +/// \table_row3{ <b>`Slideshow.Filesize`</b>, +/// \anchor Slideshow_Filesize +/// _string_, +/// @return The file size of the current picture. +/// <p> +/// } +/// \table_row3{ <b>`Slideshow.FlashUsed`</b>, +/// \anchor Slideshow_FlashUsed +/// _string_, +/// @return The status of flash when the current picture was taken. The value +/// will be either <b>"Yes"</b> or <b>"No"</b>\, and might include additional information. +/// @note This is the value of the EXIF Flash tag (hex code 0x9209). +/// <p><hr> +/// @skinning_v13 **[New Infolabel]** \link Slideshow_FlashUsed `Slideshow.FlashUsed`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Slideshow.FocalLength`</b>, +/// \anchor Slideshow_FocalLength +/// _string_, +/// @return The focal length of the lens\, in mm. +/// @note This is the value of the EXIF FocalLength tag (hex code 0x920A). +/// <p> +/// } +/// \table_row3{ <b>`Slideshow.FocusDistance`</b>, +/// \anchor Slideshow_FocusDistance +/// _string_, +/// @return The distance to the subject\, in meters. +/// @note This is the value of the EXIF SubjectDistance tag (hex code 0x9206). +/// <p> +/// } +/// \table_row3{ <b>`Slideshow.Headline`</b>, +/// \anchor Slideshow_Headline +/// _string_, +/// @return A synopsis of the contents of the current picture. +/// @note This is the value of the IPTC Headline tag (hex code 0x69). +/// <p><hr> +/// @skinning_v13 **[New Infolabel]** \link Slideshow_Headline `Slideshow.Headline`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Slideshow.ImageType`</b>, +/// \anchor Slideshow_ImageType +/// _string_, +/// @return The color components of the current picture. +/// @note This is the value of the IPTC ImageType tag (hex code 0x82). +/// <p><hr> +/// @skinning_v13 **[New Infolabel]** \link Slideshow_ImageType `Slideshow.ImageType`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Slideshow.IPTCDate`</b>, +/// \anchor Slideshow_IPTCDate +/// _string_, +/// @return The date when the intellectual content of the current picture was +/// created\, rather than when the picture was created. +/// @note This is the value of the IPTC DateCreated tag (hex code 0x37). +/// <p> +/// } +/// \table_row3{ <b>`Slideshow.ISOEquivalence`</b>, +/// \anchor Slideshow_ISOEquivalence +/// _string_, +/// @return The ISO speed of the camera when the current picture was taken. +/// @note This is the value of the EXIF ISOSpeedRatings tag (hex code 0x8827). +/// <p> +/// } +/// \table_row3{ <b>`Slideshow.Keywords`</b>, +/// \anchor Slideshow_Keywords +/// _string_, +/// @return The keywords assigned to the current picture. +/// @note This is the value of the IPTC Keywords tag (hex code 0x19). +/// <p> +/// } +/// \table_row3{ <b>`Slideshow.Latitude`</b>, +/// \anchor Slideshow_Latitude +/// _string_, +/// @return The latitude where the current picture was taken (degrees\, +/// minutes\, seconds North or South). +/// @note This is the value of the EXIF GPSInfo.GPSLatitude and +/// GPSInfo.GPSLatitudeRef tags. +/// <p> +/// } +/// \table_row3{ <b>`Slideshow.LightSource`</b>, +/// \anchor Slideshow_LightSource +/// _string_, +/// @return The kind of light source when the picture was taken. Possible +/// values include: +/// - <b>"Daylight"</b> +/// - <b>"Fluorescent"</b> +/// - <b>"Incandescent"</b> +/// - etc... +/// @note This is the value of the EXIF LightSource tag (hex code 0x9208). +/// <p><hr> +/// @skinning_v13 **[New Infolabel]** \link Slideshow_LightSource `Slideshow.LightSource`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Slideshow.LongEXIFDate`</b>, +/// \anchor Slideshow_LongEXIFDate +/// _string_, +/// @return Only the localized date of the current picture. The long form of +/// the date is used. +/// @note The value of the EXIF DateTimeOriginal tag (hex code +/// 0x9003) is preferred. If the DateTimeOriginal tag is not found\, the +/// value of DateTimeDigitized (hex code 0x9004) or of DateTime (hex code +/// 0x0132) might be used. +/// <p><hr> +/// @skinning_v13 **[New Infolabel]** \link Slideshow_LongEXIFDate `Slideshow.LongEXIFDate`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Slideshow.LongEXIFTime`</b>, +/// \anchor Slideshow_LongEXIFTime +/// _string_, +/// @return The date/timestamp of the current picture. The localized long form +/// of the date and time is used. +/// @note The value of the EXIF DateTimeOriginal tag +/// (hex code 0x9003) is preferred. if the DateTimeOriginal tag is not found\, +/// the value of DateTimeDigitized (hex code 0x9004) or of DateTime (hex +/// code 0x0132) might be used. +/// <p><hr> +/// @skinning_v13 **[New Infolabel]** \link Slideshow_LongEXIFTime `Slideshow.LongEXIFTime`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Slideshow.Longitude`</b>, +/// \anchor Slideshow_Longitude +/// _string_, +/// @return The longitude where the current picture was taken (degrees\, +/// minutes\, seconds East or West). +/// @note This is the value of the EXIF GPSInfo.GPSLongitude and +/// GPSInfo.GPSLongitudeRef tags. +/// <p> +/// } +/// \table_row3{ <b>`Slideshow.MeteringMode`</b>, +/// \anchor Slideshow_MeteringMode +/// _string_, +/// @return The metering mode used when the current picture was taken. The +/// possible values are: +/// - <b>"Center weight"</b> +/// - <b>"Spot"</b> +/// - <b>"Matrix"</b> +/// @note This is the value of the EXIF MeteringMode tag (hex code 0x9207). +/// <p><hr> +/// @skinning_v13 **[New Infolabel]** \link Slideshow_MeteringMode `Slideshow.MeteringMode`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Slideshow.ObjectName`</b>, +/// \anchor Slideshow_ObjectName +/// _string_, +/// @return a shorthand reference for the current picture. +/// @note This is the value of the IPTC ObjectName tag (hex code 0x05). +/// <p><hr> +/// @skinning_v13 **[New Infolabel]** \link Slideshow_ObjectName `Slideshow.ObjectName`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Slideshow.Orientation`</b>, +/// \anchor Slideshow_Orientation +/// _string_, +/// @return The orientation of the current picture. Possible values are: +/// - <b>"Top Left"</b> +/// - <b>"Top Right"</b> +/// - <b>"Left Top"</b> +/// - <b>"Right Bottom"</b> +/// - etc... +/// @note This is the value of the EXIF Orientation tag (hex code 0x0112). +/// <p><hr> +/// @skinning_v13 **[New Infolabel]** \link Slideshow_Orientation `Slideshow.Orientation`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Slideshow.Path`</b>, +/// \anchor Slideshow_Path +/// _string_, +/// @return The file path of the current picture. +/// <p> +/// } +/// \table_row3{ <b>`Slideshow.Process`</b>, +/// \anchor Slideshow_Process +/// _string_, +/// @return The process used to compress the current picture. +/// <p><hr> +/// @skinning_v13 **[New Infolabel]** \link Slideshow_Process `Slideshow.Process`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Slideshow.ReferenceService`</b>, +/// \anchor Slideshow_ReferenceService +/// _string_, +/// @return The Service Identifier of a prior envelope to which the current +/// picture refers. +/// @note This is the value of the IPTC ReferenceService tag (hex code 0x2D). +/// <p><hr> +/// @skinning_v13 **[New Infolabel]** \link Slideshow_ReferenceService `Slideshow.ReferenceService`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Slideshow.Resolution`</b>, +/// \anchor Slideshow_Resolution +/// _string_, +/// @return The dimensions of the current picture (Width x Height) +/// <p> +/// } +/// \table_row3{ <b>`Slideshow.SlideComment`</b>, +/// \anchor Slideshow_SlideComment +/// _string_, +/// @return A description of the current picture. +/// @note This is the value of the EXIF User Comment tag (hex code 0x9286). +/// This is the same value as \ref Slideshow_EXIFComment "Slideshow.EXIFComment". +/// <p> +/// } +/// \table_row3{ <b>`Slideshow.SlideIndex`</b>, +/// \anchor Slideshow_SlideIndex +/// _string_, +/// @return The slide index of the current picture. +/// <p> +/// } +/// \table_row3{ <b>`Slideshow.Source`</b>, +/// \anchor Slideshow_Source +/// _string_, +/// @return The original owner of the current picture. +/// @note This is the value of the IPTC Source tag (hex code 0x73). +/// <p><hr> +/// @skinning_v13 **[New Infolabel]** \link Slideshow_Source `Slideshow.Source`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Slideshow.SpecialInstructions`</b>, +/// \anchor Slideshow_SpecialInstructions +/// _string_, +/// @return Other editorial instructions concerning the use of the current +/// picture. +/// @note This is the value of the IPTC SpecialInstructions tag (hex code 0x28). +/// <p><hr> +/// @skinning_v13 **[New Infolabel]** \link Slideshow_SpecialInstructions `Slideshow.SpecialInstructions`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Slideshow.State`</b>, +/// \anchor Slideshow_State +/// _string_, +/// @return The State/Province where the current picture was taken. +/// @note This is the value of the IPTC ProvinceState tag (hex code 0x5F). +/// <p><hr> +/// @skinning_v13 **[New Infolabel]** \link Slideshow_State `Slideshow.State`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Slideshow.Sublocation`</b>, +/// \anchor Slideshow_Sublocation +/// _string_, +/// @return The location within a city where the current picture was taken - +/// might indicate the nearest landmark. +/// @note This is the value of the IPTC SubLocation tag (hex code 0x5C). +/// <p><hr> +/// @skinning_v13 **[New Infolabel]** \link Slideshow_Sublocation `Slideshow.Sublocation`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Slideshow.SupplementalCategories`</b>, +/// \anchor Slideshow_SupplementalCategories +/// _string_, +/// @return The supplemental category codes to further refine the subject of the +/// current picture. +/// @note This is the value of the IPTC SuppCategory tag (hex +/// code 0x14). +/// <p><hr> +/// @skinning_v13 **[New Infolabel]** \link Slideshow_SupplementalCategories `Slideshow.SupplementalCategories`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Slideshow.TimeCreated`</b>, +/// \anchor Slideshow_TimeCreated +/// _string_, +/// @return The time when the intellectual content of the current picture was +/// created\, rather than when the picture was created. +/// @note This is the value of the IPTC TimeCreated tag (hex code 0x3C). +/// <p><hr> +/// @skinning_v13 **[New Infolabel]** \link Slideshow_TimeCreated `Slideshow.TimeCreated`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Slideshow.TransmissionReference`</b>, +/// \anchor Slideshow_TransmissionReference +/// _string_, +/// @return A code representing the location of original transmission of the +/// current picture. +/// @note This is the value of the IPTC TransmissionReference tag +/// (hex code 0x67). +/// <p><hr> +/// @skinning_v13 **[New Infolabel]** \link Slideshow_TransmissionReference `Slideshow.TransmissionReference`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Slideshow.Urgency`</b>, +/// \anchor Slideshow_Urgency +/// _string_, +/// @return The urgency of the current picture. Values are 1-9. The 1 is most +/// urgent. +/// @note Some image management programs use urgency to indicate picture +/// rating\, where urgency 1 is 5 stars and urgency 5 is 1 star. Urgencies +/// 6-9 are not used for rating. This is the value of the IPTC Urgency tag +/// (hex code 0x0A). +/// <p><hr> +/// @skinning_v13 **[New Infolabel]** \link Slideshow_Urgency `Slideshow.Urgency`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Slideshow.WhiteBalance`</b>, +/// \anchor Slideshow_WhiteBalance +/// _string_, +/// @return The white balance mode set when the current picture was taken. +/// The possible values are: +/// - <b>"Manual"</b> +/// - <b>"Auto"</b> +/// <p> +/// @note This is the value of the EXIF WhiteBalance tag (hex code 0xA403). +/// <p><hr> +/// @skinning_v13 **[New Infolabel]** \link Slideshow_WhiteBalance `Slideshow.WhiteBalance`\endlink +/// <p> +/// } +/// \table_end +/// +/// ----------------------------------------------------------------------------- +const infomap slideshow[] = {{ "ispaused", SLIDESHOW_ISPAUSED }, + { "isactive", SLIDESHOW_ISACTIVE }, + { "isvideo", SLIDESHOW_ISVIDEO }, + { "israndom", SLIDESHOW_ISRANDOM }, + { "filename", SLIDESHOW_FILE_NAME }, + { "path", SLIDESHOW_FILE_PATH }, + { "filesize", SLIDESHOW_FILE_SIZE }, + { "filedate", SLIDESHOW_FILE_DATE }, + { "slideindex", SLIDESHOW_INDEX }, + { "resolution", SLIDESHOW_RESOLUTION }, + { "slidecomment", SLIDESHOW_COMMENT }, + { "colour", SLIDESHOW_COLOUR }, + { "process", SLIDESHOW_PROCESS }, + { "exiftime", SLIDESHOW_EXIF_DATE_TIME }, + { "exifdate", SLIDESHOW_EXIF_DATE }, + { "longexiftime", SLIDESHOW_EXIF_LONG_DATE_TIME }, + { "longexifdate", SLIDESHOW_EXIF_LONG_DATE }, + { "exifdescription", SLIDESHOW_EXIF_DESCRIPTION }, + { "cameramake", SLIDESHOW_EXIF_CAMERA_MAKE }, + { "cameramodel", SLIDESHOW_EXIF_CAMERA_MODEL }, + { "exifcomment", SLIDESHOW_EXIF_COMMENT }, + { "exifsoftware", SLIDESHOW_EXIF_SOFTWARE }, + { "aperture", SLIDESHOW_EXIF_APERTURE }, + { "focallength", SLIDESHOW_EXIF_FOCAL_LENGTH }, + { "focusdistance", SLIDESHOW_EXIF_FOCUS_DIST }, + { "exposure", SLIDESHOW_EXIF_EXPOSURE }, + { "exposuretime", SLIDESHOW_EXIF_EXPOSURE_TIME }, + { "exposurebias", SLIDESHOW_EXIF_EXPOSURE_BIAS }, + { "exposuremode", SLIDESHOW_EXIF_EXPOSURE_MODE }, + { "flashused", SLIDESHOW_EXIF_FLASH_USED }, + { "whitebalance", SLIDESHOW_EXIF_WHITE_BALANCE }, + { "lightsource", SLIDESHOW_EXIF_LIGHT_SOURCE }, + { "meteringmode", SLIDESHOW_EXIF_METERING_MODE }, + { "isoequivalence", SLIDESHOW_EXIF_ISO_EQUIV }, + { "digitalzoom", SLIDESHOW_EXIF_DIGITAL_ZOOM }, + { "ccdwidth", SLIDESHOW_EXIF_CCD_WIDTH }, + { "orientation", SLIDESHOW_EXIF_ORIENTATION }, + { "supplementalcategories", SLIDESHOW_IPTC_SUP_CATEGORIES }, + { "keywords", SLIDESHOW_IPTC_KEYWORDS }, + { "caption", SLIDESHOW_IPTC_CAPTION }, + { "author", SLIDESHOW_IPTC_AUTHOR }, + { "headline", SLIDESHOW_IPTC_HEADLINE }, + { "specialinstructions", SLIDESHOW_IPTC_SPEC_INSTR }, + { "category", SLIDESHOW_IPTC_CATEGORY }, + { "byline", SLIDESHOW_IPTC_BYLINE }, + { "bylinetitle", SLIDESHOW_IPTC_BYLINE_TITLE }, + { "credit", SLIDESHOW_IPTC_CREDIT }, + { "source", SLIDESHOW_IPTC_SOURCE }, + { "copyrightnotice", SLIDESHOW_IPTC_COPYRIGHT_NOTICE }, + { "objectname", SLIDESHOW_IPTC_OBJECT_NAME }, + { "city", SLIDESHOW_IPTC_CITY }, + { "state", SLIDESHOW_IPTC_STATE }, + { "country", SLIDESHOW_IPTC_COUNTRY }, + { "transmissionreference", SLIDESHOW_IPTC_TX_REFERENCE }, + { "iptcdate", SLIDESHOW_IPTC_DATE }, + { "urgency", SLIDESHOW_IPTC_URGENCY }, + { "countrycode", SLIDESHOW_IPTC_COUNTRY_CODE }, + { "referenceservice", SLIDESHOW_IPTC_REF_SERVICE }, + { "latitude", SLIDESHOW_EXIF_GPS_LATITUDE }, + { "longitude", SLIDESHOW_EXIF_GPS_LONGITUDE }, + { "altitude", SLIDESHOW_EXIF_GPS_ALTITUDE }, + { "timecreated", SLIDESHOW_IPTC_TIMECREATED }, + { "sublocation", SLIDESHOW_IPTC_SUBLOCATION }, + { "imagetype", SLIDESHOW_IPTC_IMAGETYPE }, +}; + +/// \page modules__infolabels_boolean_conditions +/// \subsection modules__infolabels_boolean_conditions_Library Library +/// @todo Make this annotate an array of infobools/labels to make it easier to track +/// \table_start +/// \table_h3{ Labels, Type, Description } +/// \table_row3{ <b>`Library.IsScanning`</b>, +/// \anchor Library_IsScanning +/// _boolean_, +/// @return **True** if the library is being scanned. +/// <p> +/// } +/// \table_row3{ <b>`Library.IsScanningVideo`</b>, +/// \anchor Library_IsScanningVideo +/// _boolean_, +/// @return **True** if the video library is being scanned. +/// <p> +/// } +/// \table_row3{ <b>`Library.IsScanningMusic`</b>, +/// \anchor Library_IsScanningMusic +/// _boolean_, +/// @return **True** if the music library is being scanned. +/// <p> +/// } +/// \table_row3{ <b>`Library.HasContent(music)`</b>, +/// \anchor Library_HasContent_Music +/// _boolean_, +/// @return **True** if the library has music content. +/// <p> +/// } +/// \table_row3{ <b>`Library.HasContent(video)`</b>, +/// \anchor Library_HasContent_Video +/// _boolean_, +/// @return **True** if the library has video content. +/// <p> +/// } +/// \table_row3{ <b>`Library.HasContent(movies)`</b>, +/// \anchor Library_HasContent_Movies +/// _boolean_, +/// @return **True** if the library has movies. +/// <p> +/// } +/// \table_row3{ <b>`Library.HasContent(tvshows)`</b>, +/// \anchor Library_HasContent_TVShows +/// _boolean_, +/// @return **True** if the library has tvshows. +/// <p> +/// } +/// \table_row3{ <b>`Library.HasContent(musicvideos)`</b>, +/// \anchor Library_HasContent_MusicVideos +/// _boolean_, +/// @return **True** if the library has music videos. +/// <p> +/// } +/// \table_row3{ <b>`Library.HasContent(moviesets)`</b>, +/// \anchor Library_HasContent_MovieSets +/// _boolean_, +/// @return **True** if the library has movie sets. +/// <p> +/// } +/// \table_row3{ <b>`Library.HasContent(singles)`</b>, +/// \anchor Library_HasContent_Singles +/// _boolean_, +/// @return **True** if the library has singles. +/// <p> +/// } +/// \table_row3{ <b>`Library.HasContent(compilations)`</b>, +/// \anchor Library_HasContent_Compilations +/// _boolean_, +/// @return **True** if the library has compilations. +/// <p> +/// } +/// \table_row3{ <b>`Library.HasContent(Role.Composer)`</b>, +/// \anchor Library_HasContent_Role_Composer +/// _boolean_, +/// @return **True** if there are songs in the library which have composers. +/// <p><hr> +/// @skinning_v17 **[New Boolean Condition]** \link Library_HasContent_Role_Composer `Library.HasContent(Role.Composer)`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Library.HasContent(Role.Conductor)`</b>, +/// \anchor Library_HasContent_Role_Conductor +/// _boolean_, +/// @return **True** if there are songs in the library which have a conductor. +/// <p><hr> +/// @skinning_v17 **[New Boolean Condition]** \link Library_HasContent_Role_Conductor `Library.HasContent(Role.Conductor)`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Library.HasContent(Role.Orchestra)`</b>, +/// \anchor Library_HasContent_Role_Orchestra +/// _boolean_, +/// @return **True** if there are songs in the library which have an orchestra. +/// <p><hr> +/// @skinning_v17 **[New Boolean Condition]** \link Library_HasContent_Role_Orchestra `Library.HasContent(Role.Orchestra)`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Library.HasContent(Role.Lyricist)`</b>, +/// \anchor Library_HasContent_Role_Lyricist +/// _boolean_, +/// @return **True** if there are songs in the library which have a lyricist. +/// <p><hr> +/// @skinning_v17 **[New Boolean Condition]** \link Library_HasContent_Role_Lyricist `Library.HasContent(Role.Lyricist)`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Library.HasContent(Role.Remixer)`</b>, +/// \anchor Library_HasContent_Role_Remixer +/// _boolean_, +/// @return **True** if there are songs in the library which have a remixer. +/// <p><hr> +/// @skinning_v17 **[New Boolean Condition]** \link Library_HasContent_Role_Remixer `Library.HasContent(Role.Remixer)`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Library.HasContent(Role.Arranger)`</b>, +/// \anchor Library_HasContent_Role_Remixer +/// _boolean_, +/// @return **True** if there are songs in the library which have an arranger. +/// <p><hr> +/// @skinning_v17 **[New Boolean Condition]** \link Library_HasContent_Role_Remixer `Library.HasContent(Role.Arranger)`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Library.HasContent(Role.Engineer)`</b>, +/// \anchor Library_HasContent_Role_Engineer +/// _boolean_, +/// @return **True** if there are songs in the library which have an engineer. +/// <p><hr> +/// @skinning_v17 **[New Boolean Condition]** \link Library_HasContent_Role_Engineer `Library.HasContent(Role.Engineer)`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Library.HasContent(Role.Producer)`</b>, +/// \anchor Library_HasContent_Role_Producer +/// _boolean_, +/// @return **True** if there are songs in the library which have an producer. +/// <p><hr> +/// @skinning_v17 **[New Boolean Condition]** \link Library_HasContent_Role_Producer `Library.HasContent(Role.Producer)`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Library.HasContent(Role.DJMixer)`</b>, +/// \anchor Library_HasContent_Role_DJMixer +/// _boolean_, +/// @return **True** if there are songs in the library which have a DJMixer. +/// <p><hr> +/// @skinning_v17 **[New Boolean Condition]** \link Library_HasContent_Role_DJMixer `Library.HasContent(Role.DJMixer)`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Library.HasContent(Role.Mixer)`</b>, +/// \anchor Library_HasContent_Role_Mixer +/// _boolean_, +/// @return **True** if there are songs in the library which have a mixer. +/// <p><hr> +/// @skinning_v17 **[New Boolean Condition]** \link Library_HasContent_Role_Mixer `Library.HasContent(Role.Mixer)`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Library.HasContent(boxsets)`</b>, +/// \anchor Library_HasContent_Boxsets +/// _boolean_, +/// @return **True** if there are albums in the library which are boxsets. +/// <p><hr> +/// @skinning_v19 **[New Boolean Condition]** \link Library_HasContent_Boxsets `Library.HasContent(boxsets)`\endlink +/// <p> +/// } +/// \table_row3{ <b>`Library.HasNode(path)`</b>, +/// \anchor Library_HasNode +/// _boolean_, +/// @return **True** if there the node is present in the library. +/// <p><hr> +/// @skinning_v19 **[New Boolean Condition]** \link Library_HasNode `Library.HasNode(path)`\endlink +/// <p> +/// } +/// \table_end +/// +/// ----------------------------------------------------------------------------- + +/// \page modules__infolabels_boolean_conditions +/// \section modules_rm_infolabels_booleans Additional revision history for Infolabels and Boolean Conditions +/// <hr> +/// \subsection modules_rm_infolabels_booleans_v20 Kodi v20 (Nexus) +/// @skinning_v20 **[Removed Boolean conditions]** The following boolean conditions have been removed: +/// - `Player.DisplayAfterSeek` - use \link Player_HasPerformedSeek `Player.HasPerformedSeek(interval)`\endlink instead +/// +/// <hr> +/// \subsection modules_rm_infolabels_booleans_v19 Kodi v19 (Matrix) +/// @skinning_v19 **[Removed Infolabels]** The following infolabels have been removed: +/// - `System.Platform.Linux.RaspberryPi` - use \link System_Platform_Linux `System.Platform.Linux`\endlink instead +/// +/// <hr> +/// \subsection modules_rm_infolabels_booleans_v18 Kodi v18 (Leia) +/// +/// @skinning_v18 **[Removed Infolabels]** The following infolabels have been removed: +/// - `Listitem.Property(artistthumbs)`, `Listitem.Property(artistthumb)` - use +/// \link ListItem_Art_Type `ListItem.Art(type)`\endlink with <b>albumartist[n].*</b> or <b>artist[n].*</b> as <b>type</b> +/// - `ADSP.ActiveStreamType` +/// - `ADSP.DetectedStreamType` +/// - `ADSP.MasterName` +/// - `ADSP.MasterInfo` +/// - `ADSP.MasterOwnIcon` +/// - `ADSP.MasterOverrideIcon` +/// - `ListItem.ChannelNumber`, `ListItem.SubChannelNumber`, `MusicPlayer.ChannelNumber`, +/// `MusicPlayer.SubChannelNumber`, `VideoPlayer.ChannelNumber`, +/// `VideoPlayer.SubChannelNumber`. Please use the following alternatives +/// \link ListItem_ChannelNumberLabel `ListItem.ChannelNumberLabel` \endlink, +/// \link MusicPlayer_ChannelNumberLabel `MusicPlayer.ChannelNumberLabel` \endlink +/// \link VideoPlayer_ChannelNumberLabel `VideoPlayer.ChannelNumberLabel` \endlink from now on. +/// +/// @skinning_v18 **[Removed Boolean Conditions]** The following infobools have been removed: +/// - `System.HasModalDialog` - use \link System_HasActiveModalDialog `System.HasActiveModalDialog` \endlink and +/// \link System_HasVisibleModalDialog `System.HasVisibleModalDialog`\endlink instead +/// - `StringCompare()` - use \link String_IsEqual `String.IsEqual(info,string)`\endlink instead +/// - `SubString()` - use \link String_Contains `String.Contains(info,substring)`\endlink instead +/// - `IntegerGreaterThan()` - use \link Integer_IsGreater `Integer.IsGreater(info,number)`\endlink instead +/// - `IsEmpty()` - use \link String_IsEmpty `String.IsEmpty(info)`\endlink instead +/// - `System.HasADSP` +/// - `ADSP.IsActive` +/// - `ADSP.HasInputResample` +/// - `ADSP.HasPreProcess` +/// - `ADSP.HasMasterProcess` +/// - `ADSP.HasPostProcess` +/// - `ADSP.HasOutputResample` +/// - `ADSP.MasterActive` +/// <hr> +/// \subsection modules_rm_infolabels_booleans_v17 Kodi v17 (Krypton) +/// @skinning_v17 **[Removed Infolabels]** The following infolabels have been removed: +/// - `ListItem.StarRating` - use the other ratings instead. +/// +/// @skinning_v17 **[Removed Boolean Conditions]** The following infobools have been removed: +/// - `on` - use `true` instead +/// - `off` - use `false` instead +/// - `Player.ShowCodec` +/// - `System.GetBool(pvrmanager.enabled)` +/// <hr> +/// \subsection modules_rm_infolabels_booleans_v16 Kodi v16 (Jarvis) +/// @skinning_v16 **[New Boolean Conditions]** The following infobools were added: +/// - `System.HasADSP` +/// - `ADSP.IsActive` +/// - `ADSP.HasInputResample` +/// - `ADSP.HasPreProcess` +/// - `ADSP.HasMasterProcess` +/// - `ADSP.HasPostProcess` +/// - `ADSP.HasOutputResample` +/// - `ADSP.MasterActive` +/// - `System.HasModalDialog` +/// +/// @skinning_v16 **[New Infolabels]** The following infolabels were added: +/// - `ADSP.ActiveStreamType` +/// - `ADSP.DetectedStreamType` +/// - `ADSP.MasterName` +/// - `ADSP.MasterInfo` +/// - `ADSP.MasterOwnIcon` +/// - `ADSP.MasterOverrideIcon` +/// +/// @skinning_v16 **[Removed Boolean Conditions]** The following infobols were removed: +/// - `System.Platform.ATV2` + +/// <hr> +/// \subsection modules_rm_infolabels_booleans_v15 Kodi v15 (Isengard) +/// <hr> +/// \subsection modules_rm_infolabels_booleans_v14 Kodi v14 (Helix) +/// @skinning_v14 **[New Infolabels]** The following infolabels were added: +/// - `ListItem.SubChannelNumber` +/// - `MusicPlayer.SubChannelNumber` +/// - `VideoPlayer.SubChannelNumber` +/// +/// <hr> +/// \subsection modules_rm_infolabels_booleans_v13 XBMC v13 (Gotham) +/// @skinning_v13 **[Removed Infolabels]** The following infolabels were removed: +/// - `Network.SubnetAddress` +/// +/// <hr> +// Crazy part, to use tableofcontents must it be on end +/// \page modules__infolabels_boolean_conditions +/// \tableofcontents + +CGUIInfoManager::Property::Property(const std::string &property, const std::string ¶meters) +: name(property) +{ + CUtil::SplitParams(parameters, params); +} + +const std::string &CGUIInfoManager::Property::param(unsigned int n /* = 0 */) const +{ + if (n < params.size()) + return params[n]; + return StringUtils::Empty; +} + +unsigned int CGUIInfoManager::Property::num_params() const +{ + return params.size(); +} + +void CGUIInfoManager::SplitInfoString(const std::string &infoString, std::vector<Property> &info) +{ + // our string is of the form: + // category[(params)][.info(params).info2(params)] ... + // so we need to split on . while taking into account of () pairs + unsigned int parentheses = 0; + std::string property; + std::string param; + for (size_t i = 0; i < infoString.size(); ++i) + { + if (infoString[i] == '(') + { + if (!parentheses++) + continue; + } + else if (infoString[i] == ')') + { + if (!parentheses) + CLog::Log(LOGERROR, "unmatched parentheses in {}", infoString); + else if (!--parentheses) + continue; + } + else if (infoString[i] == '.' && !parentheses) + { + if (!property.empty()) // add our property and parameters + { + StringUtils::ToLower(property); + info.emplace_back(Property(property, param)); + } + property.clear(); + param.clear(); + continue; + } + if (parentheses) + param += infoString[i]; + else + property += infoString[i]; + } + + if (parentheses) + CLog::Log(LOGERROR, "unmatched parentheses in {}", infoString); + + if (!property.empty()) + { + StringUtils::ToLower(property); + info.emplace_back(Property(property, param)); + } +} + +/// \brief Translates a string as given by the skin into an int that we use for more +/// efficient retrieval of data. +int CGUIInfoManager::TranslateSingleString(const std::string &strCondition) +{ + bool listItemDependent; + return TranslateSingleString(strCondition, listItemDependent); +} + +int CGUIInfoManager::TranslateSingleString(const std::string &strCondition, bool &listItemDependent) +{ + /* We need to disable caching in INFO::InfoBool::Get if either of the following are true: + * 1. if condition is between LISTITEM_START and LISTITEM_END + * 2. if condition is string or integer the corresponding label is between LISTITEM_START and LISTITEM_END + * This is achieved by setting the bool pointed at by listItemDependent, either here or in a recursive call + */ + // trim whitespaces + std::string strTest = strCondition; + StringUtils::Trim(strTest); + + std::vector< Property> info; + SplitInfoString(strTest, info); + + if (info.empty()) + return 0; + + const Property &cat = info[0]; + if (info.size() == 1) + { // single category + if (cat.name == "false" || cat.name == "no") + return SYSTEM_ALWAYS_FALSE; + else if (cat.name == "true" || cat.name == "yes") + return SYSTEM_ALWAYS_TRUE; + } + else if (info.size() == 2) + { + const Property &prop = info[1]; + if (cat.name == "string") + { + if (prop.name == "isempty") + { + return AddMultiInfo(CGUIInfo(STRING_IS_EMPTY, TranslateSingleString(prop.param(), listItemDependent))); + } + else if (prop.num_params() == 2) + { + for (const infomap& string_bool : string_bools) + { + if (prop.name == string_bool.str) + { + int data1 = TranslateSingleString(prop.param(0), listItemDependent); + // pipe our original string through the localize parsing then make it lowercase (picks up $LBRACKET etc.) + std::string label = CGUIInfoLabel::GetLabel(prop.param(1), INFO::DEFAULT_CONTEXT); + StringUtils::ToLower(label); + // 'true', 'false', 'yes', 'no' are valid strings, do not resolve them to SYSTEM_ALWAYS_TRUE or SYSTEM_ALWAYS_FALSE + if (label != "true" && label != "false" && label != "yes" && label != "no") + { + int data2 = TranslateSingleString(prop.param(1), listItemDependent); + if (data2 > 0) + return AddMultiInfo(CGUIInfo(string_bool.val, data1, -data2)); + } + return AddMultiInfo(CGUIInfo(string_bool.val, data1, label)); + } + } + } + } + if (cat.name == "integer") + { + if (prop.name == "valueof") + { + int value = -1; + std::from_chars(prop.param(0).data(), prop.param(0).data() + prop.param(0).size(), value); + return AddMultiInfo(CGUIInfo(INTEGER_VALUEOF, value)); + } + + for (const infomap& integer_bool : integer_bools) + { + if (prop.name == integer_bool.str) + { + std::array<int, 2> data = {-1, -1}; + for (size_t i = 0; i < data.size(); i++) + { + std::from_chars_result result = std::from_chars( + prop.param(i).data(), prop.param(i).data() + prop.param(i).size(), data.at(i)); + if (result.ec == std::errc::invalid_argument) + { + // could not translate provided value to int, translate the info string + data.at(i) = TranslateSingleString(prop.param(i), listItemDependent); + } + else + { + // conversion succeeded, integer value provided - translate it to an Integer.ValueOf() info. + data.at(i) = AddMultiInfo(CGUIInfo(INTEGER_VALUEOF, data.at(i))); + } + } + return AddMultiInfo(CGUIInfo(integer_bool.val, data.at(0), data.at(1))); + } + } + } + else if (cat.name == "player") + { + for (const infomap& player_label : player_labels) + { + if (prop.name == player_label.str) + return player_label.val; + } + for (const infomap& player_time : player_times) + { + if (prop.name == player_time.str) + return AddMultiInfo(CGUIInfo(player_time.val, TranslateTimeFormat(prop.param()))); + } + if (prop.name == "process" && prop.num_params()) + { + for (const infomap& player_proces : player_process) + { + if (StringUtils::EqualsNoCase(prop.param(), player_proces.str)) + return player_proces.val; + } + } + if (prop.num_params() == 1) + { + for (const infomap& i : player_param) + { + if (prop.name == i.str) + return AddMultiInfo(CGUIInfo(i.val, prop.param())); + } + } + } + else if (cat.name == "addon") + { + for (const infomap& i : addons) + { + if (prop.name == i.str && prop.num_params() == 2) + return AddMultiInfo(CGUIInfo(i.val, prop.param(0), prop.param(1))); + } + } + else if (cat.name == "weather") + { + for (const infomap& i : weather) + { + if (prop.name == i.str) + return i.val; + } + } + else if (cat.name == "network") + { + for (const infomap& network_label : network_labels) + { + if (prop.name == network_label.str) + return network_label.val; + } + } + else if (cat.name == "musicpartymode") + { + for (const infomap& i : musicpartymode) + { + if (prop.name == i.str) + return i.val; + } + } + else if (cat.name == "system") + { + for (const infomap& system_label : system_labels) + { + if (prop.name == system_label.str) + return system_label.val; + } + if (prop.num_params() == 1) + { + const std::string ¶m = prop.param(); + if (prop.name == "getbool") + { + std::string paramCopy = param; + StringUtils::ToLower(paramCopy); + return AddMultiInfo(CGUIInfo(SYSTEM_GET_BOOL, paramCopy)); + } + for (const infomap& i : system_param) + { + if (prop.name == i.str) + return AddMultiInfo(CGUIInfo(i.val, param)); + } + if (prop.name == "memory") + { + if (param == "free") + return SYSTEM_FREE_MEMORY; + else if (param == "free.percent") + return SYSTEM_FREE_MEMORY_PERCENT; + else if (param == "used") + return SYSTEM_USED_MEMORY; + else if (param == "used.percent") + return SYSTEM_USED_MEMORY_PERCENT; + else if (param == "total") + return SYSTEM_TOTAL_MEMORY; + } + else if (prop.name == "addontitle") + { + // Example: System.AddonTitle(Skin.String(HomeVideosButton1)) => skin string HomeVideosButton1 holds an addon identifier string + int infoLabel = TranslateSingleString(param, listItemDependent); + if (infoLabel > 0) + return AddMultiInfo(CGUIInfo(SYSTEM_ADDON_TITLE, infoLabel, 0)); + std::string label = CGUIInfoLabel::GetLabel(param, INFO::DEFAULT_CONTEXT); + StringUtils::ToLower(label); + return AddMultiInfo(CGUIInfo(SYSTEM_ADDON_TITLE, label, 1)); + } + else if (prop.name == "addonicon") + { + int infoLabel = TranslateSingleString(param, listItemDependent); + if (infoLabel > 0) + return AddMultiInfo(CGUIInfo(SYSTEM_ADDON_ICON, infoLabel, 0)); + std::string label = CGUIInfoLabel::GetLabel(param, INFO::DEFAULT_CONTEXT); + StringUtils::ToLower(label); + return AddMultiInfo(CGUIInfo(SYSTEM_ADDON_ICON, label, 1)); + } + else if (prop.name == "addonversion") + { + int infoLabel = TranslateSingleString(param, listItemDependent); + if (infoLabel > 0) + return AddMultiInfo(CGUIInfo(SYSTEM_ADDON_VERSION, infoLabel, 0)); + std::string label = CGUIInfoLabel::GetLabel(param, INFO::DEFAULT_CONTEXT); + StringUtils::ToLower(label); + return AddMultiInfo(CGUIInfo(SYSTEM_ADDON_VERSION, label, 1)); + } + else if (prop.name == "idletime") + return AddMultiInfo(CGUIInfo(SYSTEM_IDLE_TIME, atoi(param.c_str()))); + } + if (prop.name == "alarmlessorequal" && prop.num_params() == 2) + return AddMultiInfo(CGUIInfo(SYSTEM_ALARM_LESS_OR_EQUAL, prop.param(0), atoi(prop.param(1).c_str()))); + else if (prop.name == "date") + { + if (prop.num_params() == 2) + return AddMultiInfo(CGUIInfo(SYSTEM_DATE, StringUtils::DateStringToYYYYMMDD(prop.param(0)) % 10000, StringUtils::DateStringToYYYYMMDD(prop.param(1)) % 10000)); + else if (prop.num_params() == 1) + { + int dateformat = StringUtils::DateStringToYYYYMMDD(prop.param(0)); + if (dateformat <= 0) // not concrete date + return AddMultiInfo(CGUIInfo(SYSTEM_DATE, prop.param(0), -1)); + else + return AddMultiInfo(CGUIInfo(SYSTEM_DATE, dateformat % 10000)); + } + return SYSTEM_DATE; + } + else if (prop.name == "time") + { + if (prop.num_params() == 0) + return AddMultiInfo(CGUIInfo(SYSTEM_TIME, TIME_FORMAT_GUESS)); + if (prop.num_params() == 1) + { + TIME_FORMAT timeFormat = TranslateTimeFormat(prop.param(0)); + if (timeFormat == TIME_FORMAT_GUESS) + return AddMultiInfo(CGUIInfo(SYSTEM_TIME, StringUtils::TimeStringToSeconds(prop.param(0)))); + return AddMultiInfo(CGUIInfo(SYSTEM_TIME, timeFormat)); + } + else + return AddMultiInfo(CGUIInfo(SYSTEM_TIME, StringUtils::TimeStringToSeconds(prop.param(0)), StringUtils::TimeStringToSeconds(prop.param(1)))); + } + } + else if (cat.name == "library") + { + if (prop.name == "isscanning") + return LIBRARY_IS_SCANNING; + else if (prop.name == "isscanningvideo") + return LIBRARY_IS_SCANNING_VIDEO; //! @todo change to IsScanning(Video) + else if (prop.name == "isscanningmusic") + return LIBRARY_IS_SCANNING_MUSIC; + else if (prop.name == "hascontent" && prop.num_params()) + { + std::string cat = prop.param(0); + StringUtils::ToLower(cat); + if (cat == "music") + return LIBRARY_HAS_MUSIC; + else if (cat == "video") + return LIBRARY_HAS_VIDEO; + else if (cat == "movies") + return LIBRARY_HAS_MOVIES; + else if (cat == "tvshows") + return LIBRARY_HAS_TVSHOWS; + else if (cat == "musicvideos") + return LIBRARY_HAS_MUSICVIDEOS; + else if (cat == "moviesets") + return LIBRARY_HAS_MOVIE_SETS; + else if (cat == "singles") + return LIBRARY_HAS_SINGLES; + else if (cat == "compilations") + return LIBRARY_HAS_COMPILATIONS; + else if (cat == "boxsets") + return LIBRARY_HAS_BOXSETS; + else if (cat == "role" && prop.num_params() > 1) + return AddMultiInfo(CGUIInfo(LIBRARY_HAS_ROLE, prop.param(1), 0)); + } + else if (prop.name == "hasnode" && prop.num_params()) + { + std::string node = prop.param(0); + StringUtils::ToLower(node); + return AddMultiInfo(CGUIInfo(LIBRARY_HAS_NODE, prop.param(), 0)); + } + } + else if (cat.name == "musicplayer") + { + for (const infomap& player_time : player_times) //! @todo remove these, they're repeats + { + if (prop.name == player_time.str) + return AddMultiInfo(CGUIInfo(player_time.val, TranslateTimeFormat(prop.param()))); + } + if (prop.name == "content" && prop.num_params()) + return AddMultiInfo(CGUIInfo(MUSICPLAYER_CONTENT, prop.param(), 0)); + else if (prop.name == "property") + { + if (StringUtils::EqualsNoCase(prop.param(), "fanart_image")) + return AddMultiInfo(CGUIInfo(PLAYER_ITEM_ART, "fanart")); + + return AddMultiInfo(CGUIInfo(MUSICPLAYER_PROPERTY, prop.param())); + } + return TranslateMusicPlayerString(prop.name); + } + else if (cat.name == "videoplayer") + { + if (prop.name != "starttime") // player.starttime is semantically different from videoplayer.starttime which has its own implementation! + { + for (const infomap& player_time : player_times) //! @todo remove these, they're repeats + { + if (prop.name == player_time.str) + return AddMultiInfo(CGUIInfo(player_time.val, TranslateTimeFormat(prop.param()))); + } + } + if (prop.name == "content" && prop.num_params()) + { + return AddMultiInfo(CGUIInfo(VIDEOPLAYER_CONTENT, prop.param(), 0)); + } + if (prop.name == "uniqueid" && prop.num_params()) + { + return AddMultiInfo(CGUIInfo(VIDEOPLAYER_UNIQUEID, prop.param(), 0)); + } + if (prop.name == "art" && prop.num_params() > 0) + { + return AddMultiInfo(CGUIInfo(VIDEOPLAYER_ART, prop.param(), 0)); + } + return TranslateVideoPlayerString(prop.name); + } + else if (cat.name == "retroplayer") + { + for (const infomap& i : retroplayer) + { + if (prop.name == i.str) + return i.val; + } + } + else if (cat.name == "slideshow") + { + for (const infomap& i : slideshow) + { + if (prop.name == i.str) + return i.val; + } + } + else if (cat.name == "container") + { + for (const infomap& i : mediacontainer) // these ones don't have or need an id + { + if (prop.name == i.str) + return i.val; + } + int id = atoi(cat.param().c_str()); + for (const infomap& container_bool : container_bools) // these ones can have an id (but don't need to?) + { + if (prop.name == container_bool.str) + return id ? AddMultiInfo(CGUIInfo(container_bool.val, id)) : container_bool.val; + } + for (const infomap& container_int : container_ints) // these ones can have an int param on the property + { + if (prop.name == container_int.str) + return AddMultiInfo(CGUIInfo(container_int.val, id, atoi(prop.param().c_str()))); + } + for (const infomap& i : container_str) // these ones have a string param on the property + { + if (prop.name == i.str) + return AddMultiInfo(CGUIInfo(i.val, id, prop.param())); + } + if (prop.name == "sortdirection") + { + SortOrder order = SortOrderNone; + if (StringUtils::EqualsNoCase(prop.param(), "ascending")) + order = SortOrderAscending; + else if (StringUtils::EqualsNoCase(prop.param(), "descending")) + order = SortOrderDescending; + return AddMultiInfo(CGUIInfo(CONTAINER_SORT_DIRECTION, order)); + } + } + else if (cat.name == "listitem" || + cat.name == "listitemposition" || + cat.name == "listitemnowrap" || + cat.name == "listitemabsolute") + { + int ret = TranslateListItem(cat, prop, 0, false); + if (ret) + listItemDependent = true; + return ret; + } + else if (cat.name == "visualisation") + { + for (const infomap& i : visualisation) + { + if (prop.name == i.str) + return i.val; + } + } + else if (cat.name == "fanart") + { + for (const infomap& fanart_label : fanart_labels) + { + if (prop.name == fanart_label.str) + return fanart_label.val; + } + } + else if (cat.name == "skin") + { + for (const infomap& skin_label : skin_labels) + { + if (prop.name == skin_label.str) + return skin_label.val; + } + if (prop.num_params()) + { + if (prop.name == "string") + { + if (prop.num_params() == 2) + return AddMultiInfo(CGUIInfo(SKIN_STRING_IS_EQUAL, CSkinSettings::GetInstance().TranslateString(prop.param(0)), prop.param(1))); + else + return AddMultiInfo(CGUIInfo(SKIN_STRING, CSkinSettings::GetInstance().TranslateString(prop.param(0)))); + } + else if (prop.name == "numeric") + { + return AddMultiInfo( + CGUIInfo(SKIN_INTEGER, CSkinSettings::GetInstance().TranslateString(prop.param(0)))); + } + else if (prop.name == "hassetting") + return AddMultiInfo(CGUIInfo(SKIN_BOOL, CSkinSettings::GetInstance().TranslateBool(prop.param(0)))); + else if (prop.name == "hastheme") + return AddMultiInfo(CGUIInfo(SKIN_HAS_THEME, prop.param(0))); + else if (prop.name == "timerisrunning") + return AddMultiInfo(CGUIInfo(SKIN_TIMER_IS_RUNNING, prop.param(0))); + else if (prop.name == "timerelapsedsecs") + return AddMultiInfo(CGUIInfo(SKIN_TIMER_ELAPSEDSECS, prop.param(0))); + } + } + else if (cat.name == "window") + { + if (prop.name == "property" && prop.num_params() == 1) + { //! @todo this doesn't support foo.xml + int winID = cat.param().empty() ? 0 : CWindowTranslator::TranslateWindow(cat.param()); + if (winID != WINDOW_INVALID) + return AddMultiInfo(CGUIInfo(WINDOW_PROPERTY, winID, prop.param())); + } + for (const infomap& window_bool : window_bools) + { + if (prop.name == window_bool.str) + { //! @todo The parameter for these should really be on the first not the second property + if (prop.param().find("xml") != std::string::npos) + return AddMultiInfo(CGUIInfo(window_bool.val, 0, prop.param())); + int winID = prop.param().empty() ? WINDOW_INVALID : CWindowTranslator::TranslateWindow(prop.param()); + return AddMultiInfo(CGUIInfo(window_bool.val, winID, 0)); + } + } + } + else if (cat.name == "control") + { + for (const infomap& control_label : control_labels) + { + if (prop.name == control_label.str) + { //! @todo The parameter for these should really be on the first not the second property + int controlID = atoi(prop.param().c_str()); + if (controlID) + return AddMultiInfo(CGUIInfo(control_label.val, controlID, 0)); + return 0; + } + } + } + else if (cat.name == "controlgroup" && prop.name == "hasfocus") + { + int groupID = atoi(cat.param().c_str()); + if (groupID) + return AddMultiInfo(CGUIInfo(CONTROL_GROUP_HAS_FOCUS, groupID, atoi(prop.param(0).c_str()))); + } + else if (cat.name == "playlist") + { + int ret = -1; + for (const infomap& i : playlist) + { + if (prop.name == i.str) + { + ret = i.val; + break; + } + } + if (ret >= 0) + { + if (prop.num_params() <= 0) + return ret; + else + { + PLAYLIST::Id playlistid = PLAYLIST::TYPE_NONE; + if (StringUtils::EqualsNoCase(prop.param(), "video")) + playlistid = PLAYLIST::TYPE_VIDEO; + else if (StringUtils::EqualsNoCase(prop.param(), "music")) + playlistid = PLAYLIST::TYPE_MUSIC; + + if (playlistid != PLAYLIST::TYPE_NONE) + return AddMultiInfo(CGUIInfo(ret, playlistid, 1)); + } + } + } + else if (cat.name == "pvr") + { + for (const infomap& i : pvr) + { + if (prop.name == i.str) + return i.val; + } + for (const infomap& pvr_time : pvr_times) + { + if (prop.name == pvr_time.str) + return AddMultiInfo(CGUIInfo(pvr_time.val, TranslateTimeFormat(prop.param()))); + } + } + else if (cat.name == "rds") + { + if (prop.name == "getline") + return AddMultiInfo(CGUIInfo(RDS_GET_RADIOTEXT_LINE, atoi(prop.param(0).c_str()))); + + for (const infomap& rd : rds) + { + if (prop.name == rd.str) + return rd.val; + } + } + } + else if (info.size() == 3 || info.size() == 4) + { + if (info[0].name == "system" && info[1].name == "platform") + { //! @todo replace with a single system.platform + std::string platform = info[2].name; + if (platform == "linux") + return SYSTEM_PLATFORM_LINUX; + else if (platform == "windows") + return SYSTEM_PLATFORM_WINDOWS; + else if (platform == "uwp") + return SYSTEM_PLATFORM_UWP; + else if (platform == "darwin") + return SYSTEM_PLATFORM_DARWIN; + else if (platform == "osx") + return SYSTEM_PLATFORM_DARWIN_OSX; + else if (platform == "ios") + return SYSTEM_PLATFORM_DARWIN_IOS; + else if (platform == "tvos") + return SYSTEM_PLATFORM_DARWIN_TVOS; + else if (platform == "android") + return SYSTEM_PLATFORM_ANDROID; + } + if (info[0].name == "musicplayer") + { //! @todo these two don't allow duration(foo) and also don't allow more than this number of levels... + if (info[1].name == "position") + { + int position = atoi(info[1].param().c_str()); + int value = TranslateMusicPlayerString(info[2].name); // musicplayer.position(foo).bar + return AddMultiInfo(CGUIInfo(value, 2, position)); // 2 => absolute (0 used for not set) + } + else if (info[1].name == "offset") + { + int position = atoi(info[1].param().c_str()); + int value = TranslateMusicPlayerString(info[2].name); // musicplayer.offset(foo).bar + return AddMultiInfo(CGUIInfo(value, 1, position)); // 1 => relative + } + } + else if (info[0].name == "videoplayer") + { //! @todo these two don't allow duration(foo) and also don't allow more than this number of levels... + if (info[1].name == "position") + { + int position = atoi(info[1].param().c_str()); + int value = TranslateVideoPlayerString(info[2].name); // videoplayer.position(foo).bar + // additional param for the requested infolabel, e.g. VideoPlayer.Position(1).Art(poster): art is the value, poster is the param + const std::string& param = info[2].param(); + return AddMultiInfo( + CGUIInfo(value, 2, position, param)); // 2 => absolute (0 used for not set) + } + else if (info[1].name == "offset") + { + int position = atoi(info[1].param().c_str()); + int value = TranslateVideoPlayerString(info[2].name); // videoplayer.offset(foo).bar + // additional param for the requested infolabel, e.g. VideoPlayer.Offset(1).Art(poster): art is the value, poster is the param + const std::string& param = info[2].param(); + return AddMultiInfo(CGUIInfo(value, 1, position, param)); // 1 => relative + } + } + else if (info[0].name == "player") + { //! @todo these two don't allow duration(foo) and also don't allow more than this number of levels... + if (info[1].name == "position") + { + int position = atoi(info[1].param().c_str()); + int value = TranslatePlayerString(info[2].name); // player.position(foo).bar + return AddMultiInfo(CGUIInfo(value, 2, position)); // 2 => absolute (0 used for not set) + } + else if (info[1].name == "offset") + { + int position = atoi(info[1].param().c_str()); + int value = TranslatePlayerString(info[2].name); // player.offset(foo).bar + return AddMultiInfo(CGUIInfo(value, 1, position)); // 1 => relative + } + } + else if (info[0].name == "container") + { + if (info[1].name == "listitem" || + info[1].name == "listitemposition" || + info[1].name == "listitemabsolute" || + info[1].name == "listitemnowrap") + { + int id = atoi(info[0].param().c_str()); + int ret = TranslateListItem(info[1], info[2], id, true); + if (ret) + listItemDependent = true; + return ret; + } + } + else if (info[0].name == "control") + { + const Property &prop = info[1]; + for (const infomap& control_label : control_labels) + { + if (prop.name == control_label.str) + { //! @todo The parameter for these should really be on the first not the second property + int controlID = atoi(prop.param().c_str()); + if (controlID) + return AddMultiInfo(CGUIInfo(control_label.val, controlID, atoi(info[2].param(0).c_str()))); + return 0; + } + } + } + } + + return 0; +} + +int CGUIInfoManager::TranslateListItem(const Property& cat, const Property& prop, int id, bool container) +{ + int ret = 0; + std::string data3; + int data4 = 0; + if (prop.num_params() == 1) + { + // special case: map 'property(fanart_image)' to 'art(fanart)' + if (prop.name == "property" && StringUtils::EqualsNoCase(prop.param(), "fanart_image")) + { + ret = LISTITEM_ART; + data3 = "fanart"; + } + else if (prop.name == "property" || + prop.name == "art" || + prop.name == "rating" || + prop.name == "votes" || + prop.name == "ratingandvotes" || + prop.name == "uniqueid") + { + data3 = prop.param(); + } + else if (prop.name == "duration" || prop.name == "nextduration") + { + data4 = TranslateTimeFormat(prop.param()); + } + } + + if (ret == 0) + { + for (const infomap& listitem_label : listitem_labels) // these ones don't have or need an id + { + if (prop.name == listitem_label.str) + { + ret = listitem_label.val; + break; + } + } + } + + if (ret) + { + int offset = std::atoi(cat.param().c_str()); + + int flags = 0; + if (cat.name == "listitem") + flags = INFOFLAG_LISTITEM_WRAP; + else if (cat.name == "listitemposition") + flags = INFOFLAG_LISTITEM_POSITION; + else if (cat.name == "listitemabsolute") + flags = INFOFLAG_LISTITEM_ABSOLUTE; + else if (cat.name == "listitemnowrap") + flags = INFOFLAG_LISTITEM_NOWRAP; + + if (container) + flags |= INFOFLAG_LISTITEM_CONTAINER; + + return AddMultiInfo(CGUIInfo(ret, id, offset, flags, data3, data4)); + } + + return 0; +} + +int CGUIInfoManager::TranslateMusicPlayerString(const std::string &info) const +{ + for (const infomap& i : musicplayer) + { + if (info == i.str) + return i.val; + } + return 0; +} + +int CGUIInfoManager::TranslateVideoPlayerString(const std::string& info) const +{ + for (const infomap& i : videoplayer) + { + if (info == i.str) + return i.val; + } + return 0; +} + +int CGUIInfoManager::TranslatePlayerString(const std::string& info) const +{ + for (const infomap& i : player_labels) + { + if (info == i.str) + return i.val; + } + return 0; +} + +TIME_FORMAT CGUIInfoManager::TranslateTimeFormat(const std::string &format) +{ + if (format.empty()) + return TIME_FORMAT_GUESS; + else if (StringUtils::EqualsNoCase(format, "hh")) + return TIME_FORMAT_HH; + else if (StringUtils::EqualsNoCase(format, "mm")) + return TIME_FORMAT_MM; + else if (StringUtils::EqualsNoCase(format, "ss")) + return TIME_FORMAT_SS; + else if (StringUtils::EqualsNoCase(format, "hh:mm")) + return TIME_FORMAT_HH_MM; + else if (StringUtils::EqualsNoCase(format, "mm:ss")) + return TIME_FORMAT_MM_SS; + else if (StringUtils::EqualsNoCase(format, "hh:mm:ss")) + return TIME_FORMAT_HH_MM_SS; + else if (StringUtils::EqualsNoCase(format, "hh:mm:ss xx")) + return TIME_FORMAT_HH_MM_SS_XX; + else if (StringUtils::EqualsNoCase(format, "h")) + return TIME_FORMAT_H; + else if (StringUtils::EqualsNoCase(format, "m")) + return TIME_FORMAT_M; + else if (StringUtils::EqualsNoCase(format, "h:mm:ss")) + return TIME_FORMAT_H_MM_SS; + else if (StringUtils::EqualsNoCase(format, "h:mm:ss xx")) + return TIME_FORMAT_H_MM_SS_XX; + else if (StringUtils::EqualsNoCase(format, "xx")) + return TIME_FORMAT_XX; + else if (StringUtils::EqualsNoCase(format, "secs")) + return TIME_FORMAT_SECS; + else if (StringUtils::EqualsNoCase(format, "mins")) + return TIME_FORMAT_MINS; + else if (StringUtils::EqualsNoCase(format, "hours")) + return TIME_FORMAT_HOURS; + return TIME_FORMAT_GUESS; +} + +std::string CGUIInfoManager::GetLabel(int info, int contextWindow, std::string *fallback) const +{ + if (info >= CONDITIONAL_LABEL_START && info <= CONDITIONAL_LABEL_END) + { + return GetSkinVariableString(info, contextWindow, false); + } + else if (info >= MULTI_INFO_START && info <= MULTI_INFO_END) + { + return GetMultiInfoLabel(m_multiInfo[info - MULTI_INFO_START], contextWindow); + } + else if (info >= LISTITEM_START && info <= LISTITEM_END) + { + const CGUIListItemPtr item = GUIINFO::GetCurrentListItem(contextWindow); + if (item && item->IsFileItem()) + return GetItemLabel(static_cast<CFileItem*>(item.get()), contextWindow, info, fallback); + } + + std::string strLabel; + m_infoProviders.GetLabel(strLabel, m_currentFile, contextWindow, CGUIInfo(info), fallback); + return strLabel; +} + +bool CGUIInfoManager::GetInt(int &value, int info, int contextWindow, const CGUIListItem *item /* = nullptr */) const +{ + if (info >= MULTI_INFO_START && info <= MULTI_INFO_END) + { + return GetMultiInfoInt(value, m_multiInfo[info - MULTI_INFO_START], contextWindow, item); + } + else if (info >= LISTITEM_START && info <= LISTITEM_END) + { + CGUIListItemPtr itemPtr; + if (!item) + { + itemPtr = GUIINFO::GetCurrentListItem(contextWindow); + item = itemPtr.get(); + } + return GetItemInt(value, item, contextWindow, info); + } + + value = 0; + return m_infoProviders.GetInt(value, m_currentFile, contextWindow, CGUIInfo(info)); +} + +INFO::InfoPtr CGUIInfoManager::Register(const std::string &expression, int context) +{ + std::string condition(CGUIInfoLabel::ReplaceLocalize(expression)); + StringUtils::Trim(condition); + + if (condition.empty()) + return INFO::InfoPtr(); + + std::unique_lock<CCriticalSection> lock(m_critInfo); + std::pair<INFOBOOLTYPE::iterator, bool> res; + + if (condition.find_first_of("|+[]!") != condition.npos) + res = m_bools.insert(std::make_shared<InfoExpression>(condition, context, m_refreshCounter)); + else + res = m_bools.insert(std::make_shared<InfoSingle>(condition, context, m_refreshCounter)); + + if (res.second) + res.first->get()->Initialize(); + + return *(res.first); +} + +void CGUIInfoManager::UnRegister(const INFO::InfoPtr& expression) +{ + std::unique_lock<CCriticalSection> lock(m_critInfo); + m_bools.erase(expression); +} + +bool CGUIInfoManager::EvaluateBool(const std::string &expression, int contextWindow /* = 0 */, const CGUIListItemPtr &item /* = nullptr */) +{ + INFO::InfoPtr info = Register(expression, contextWindow); + if (info) + return info->Get(contextWindow, item.get()); + return false; +} + +bool CGUIInfoManager::GetBool(int condition1, int contextWindow, const CGUIListItem *item) +{ + bool bReturn = false; + int condition = std::abs(condition1); + + if (condition >= LISTITEM_START && condition < LISTITEM_END) + { + CGUIListItemPtr itemPtr; + if (!item) + { + itemPtr = GUIINFO::GetCurrentListItem(contextWindow); + item = itemPtr.get(); + } + bReturn = GetItemBool(item, contextWindow, condition); + } + else if (condition >= MULTI_INFO_START && condition <= MULTI_INFO_END) + { + bReturn = GetMultiInfoBool(m_multiInfo[condition - MULTI_INFO_START], contextWindow, item); + } + else if (!m_infoProviders.GetBool(bReturn, m_currentFile, contextWindow, CGUIInfo(condition))) + { + // default: use integer value different from 0 as true + int val; + bReturn = GetInt(val, condition, DEFAULT_CONTEXT) && val != 0; + } + + return (condition1 < 0) ? !bReturn : bReturn; +} + +bool CGUIInfoManager::GetMultiInfoBool(const CGUIInfo &info, int contextWindow, const CGUIListItem *item) +{ + bool bReturn = false; + int condition = std::abs(info.m_info); + + if (condition >= LISTITEM_START && condition <= LISTITEM_END) + { + CGUIListItemPtr itemPtr; + if (!item) + { + itemPtr = GUIINFO::GetCurrentListItem(contextWindow, info.GetData1(), info.GetData2(), info.GetInfoFlag()); + item = itemPtr.get(); + } + if (item) + { + if (condition == LISTITEM_PROPERTY) + { + if (item->HasProperty(info.GetData3())) + bReturn = item->GetProperty(info.GetData3()).asBoolean(); + } + else + bReturn = GetItemBool(item, contextWindow, condition); + } + else + { + bReturn = false; + } + } + else if (!m_infoProviders.GetBool(bReturn, m_currentFile, contextWindow, info)) + { + switch (condition) + { + case STRING_IS_EMPTY: + // note: Get*Image() falls back to Get*Label(), so this should cover all of them + if (item && item->IsFileItem() && IsListItemInfo(info.GetData1())) + bReturn = GetItemImage(item, contextWindow, info.GetData1()).empty(); + else + bReturn = GetImage(info.GetData1(), contextWindow).empty(); + break; + case STRING_STARTS_WITH: + case STRING_ENDS_WITH: + case STRING_CONTAINS: + case STRING_IS_EQUAL: + { + std::string compare; + if (info.GetData2() < 0) // info labels are stored with negative numbers + { + int info2 = -info.GetData2(); + CGUIListItemPtr item2; + + if (IsListItemInfo(info2)) + { + int iResolvedInfo2 = ResolveMultiInfo(info2); + if (iResolvedInfo2 != 0) + { + const GUIINFO::CGUIInfo& resolvedInfo2 = m_multiInfo[iResolvedInfo2 - MULTI_INFO_START]; + if (resolvedInfo2.GetInfoFlag() & INFOFLAG_LISTITEM_CONTAINER) + item2 = GUIINFO::GetCurrentListItem(contextWindow, resolvedInfo2.GetData1()); // data1 contains the container id + } + } + + if (item2 && item2->IsFileItem()) + compare = GetItemImage(item2.get(), contextWindow, info2); + else if (item && item->IsFileItem()) + compare = GetItemImage(item, contextWindow, info2); + else + compare = GetImage(info2, contextWindow); + } + else if (!info.GetData3().empty()) + { // conditional string + compare = info.GetData3(); + } + StringUtils::ToLower(compare); + + std::string label; + if (item && item->IsFileItem() && IsListItemInfo(info.GetData1())) + label = GetItemImage(item, contextWindow, info.GetData1()); + else + label = GetImage(info.GetData1(), contextWindow); + StringUtils::ToLower(label); + + if (condition == STRING_STARTS_WITH) + bReturn = StringUtils::StartsWith(label, compare); + else if (condition == STRING_ENDS_WITH) + bReturn = StringUtils::EndsWith(label, compare); + else if (condition == STRING_CONTAINS) + bReturn = label.find(compare) != std::string::npos; + else + bReturn = StringUtils::EqualsNoCase(label, compare); + } + break; + case INTEGER_IS_EQUAL: + case INTEGER_GREATER_THAN: + case INTEGER_GREATER_OR_EQUAL: + case INTEGER_LESS_THAN: + case INTEGER_LESS_OR_EQUAL: + case INTEGER_EVEN: + case INTEGER_ODD: + { + auto getIntValue = [this, &item, &contextWindow](int infoNum) { + int intValue = 0; + if (!GetInt(intValue, infoNum, contextWindow, item)) + { + std::string value; + if (item && item->IsFileItem() && IsListItemInfo(infoNum)) + value = GetItemImage(item, contextWindow, infoNum); + else + value = GetImage(infoNum, contextWindow); + + // Handle the case when a value contains time separator (:). This makes Integer.IsGreater + // useful for Player.Time* members without adding a separate set of members returning time in seconds + if (value.find_first_of(':') != value.npos) + intValue = StringUtils::TimeStringToSeconds(value); + else + std::from_chars(value.data(), value.data() + value.size(), intValue); + } + return intValue; + }; + + int leftIntValue = getIntValue(info.GetData1()); + int rightIntValue = getIntValue(info.GetData2()); + + // compare + if (condition == INTEGER_IS_EQUAL) + bReturn = leftIntValue == rightIntValue; + else if (condition == INTEGER_GREATER_THAN) + bReturn = leftIntValue > rightIntValue; + else if (condition == INTEGER_GREATER_OR_EQUAL) + bReturn = leftIntValue >= rightIntValue; + else if (condition == INTEGER_LESS_THAN) + bReturn = leftIntValue < rightIntValue; + else if (condition == INTEGER_LESS_OR_EQUAL) + bReturn = leftIntValue <= rightIntValue; + else if (condition == INTEGER_EVEN) + bReturn = leftIntValue % 2 == 0; + else if (condition == INTEGER_ODD) + bReturn = leftIntValue % 2 != 0; + } + break; + } + } + return (info.m_info < 0) ? !bReturn : bReturn; +} + +bool CGUIInfoManager::GetMultiInfoInt(int &value, const CGUIInfo &info, int contextWindow, const CGUIListItem *item) const +{ + if (info.m_info == INTEGER_VALUEOF) + { + value = info.GetData1(); + return true; + } + else if (info.m_info >= LISTITEM_START && info.m_info <= LISTITEM_END) + { + CGUIListItemPtr itemPtr; + if (!item) + { + itemPtr = GUIINFO::GetCurrentListItem(contextWindow, info.GetData1(), info.GetData2(), info.GetInfoFlag()); + item = itemPtr.get(); + } + if (item) + { + if (info.m_info == LISTITEM_PROPERTY) + { + if (item->HasProperty(info.GetData3())) + { + value = item->GetProperty(info.GetData3()).asInteger(); + return true; + } + return false; + } + else + return GetItemInt(value, item, contextWindow, info.m_info); + } + else + { + return false; + } + } + + return m_infoProviders.GetInt(value, m_currentFile, contextWindow, info); +} + +std::string CGUIInfoManager::GetMultiInfoLabel(const CGUIInfo &constinfo, int contextWindow, std::string *fallback) const +{ + CGUIInfo info(constinfo); + + if (info.m_info >= LISTITEM_START && info.m_info <= LISTITEM_END) + { + const CGUIListItemPtr item = GUIINFO::GetCurrentListItem(contextWindow, info.GetData1(), info.GetData2(), info.GetInfoFlag()); + if (item) + { + // Image prioritizes images over labels (in the case of music item ratings for instance) + return GetMultiInfoItemImage(dynamic_cast<CFileItem*>(item.get()), contextWindow, info, fallback); + } + else + { + return std::string(); + } + } + else if (info.m_info == SYSTEM_ADDON_TITLE || + info.m_info == SYSTEM_ADDON_ICON || + info.m_info == SYSTEM_ADDON_VERSION) + { + if (info.GetData2() == 0) + { + // resolve the addon id + const std::string addonId = GetLabel(info.GetData1(), contextWindow); + info = CGUIInfo(info.m_info, addonId); + } + } + + std::string strValue; + m_infoProviders.GetLabel(strValue, m_currentFile, contextWindow, info, fallback); + return strValue; +} + +/// \brief Obtains the filename of the image to show from whichever subsystem is needed +std::string CGUIInfoManager::GetImage(int info, int contextWindow, std::string *fallback) +{ + if (info >= CONDITIONAL_LABEL_START && info <= CONDITIONAL_LABEL_END) + { + return GetSkinVariableString(info, contextWindow, true); + } + else if (info >= MULTI_INFO_START && info <= MULTI_INFO_END) + { + return GetMultiInfoLabel(m_multiInfo[info - MULTI_INFO_START], contextWindow, fallback); + } + else if (info == LISTITEM_THUMB || + info == LISTITEM_ICON || + info == LISTITEM_ACTUAL_ICON || + info == LISTITEM_OVERLAY || + info == LISTITEM_ART) + { + const CGUIListItemPtr item = GUIINFO::GetCurrentListItem(contextWindow); + if (item && item->IsFileItem()) + return GetItemImage(item.get(), contextWindow, info, fallback); + } + + return GetLabel(info, contextWindow, fallback); +} + +void CGUIInfoManager::ResetCurrentItem() +{ + m_currentFile->Reset(); + m_infoProviders.InitCurrentItem(nullptr); +} + +void CGUIInfoManager::UpdateCurrentItem(const CFileItem &item) +{ + m_currentFile->UpdateInfo(item); +} + +void CGUIInfoManager::SetCurrentItem(const CFileItem &item) +{ + *m_currentFile = item; + m_currentFile->FillInDefaultIcon(); + + m_infoProviders.InitCurrentItem(m_currentFile); + + CServiceBroker::GetAnnouncementManager()->Announce(ANNOUNCEMENT::Info, "OnChanged"); +} + +void CGUIInfoManager::SetCurrentAlbumThumb(const std::string &thumbFileName) +{ + if (CFileUtils::Exists(thumbFileName)) + m_currentFile->SetArt("thumb", thumbFileName); + else + { + m_currentFile->SetArt("thumb", ""); + m_currentFile->FillInDefaultIcon(); + } +} + +void CGUIInfoManager::Clear() +{ + std::unique_lock<CCriticalSection> lock(m_critInfo); + m_skinVariableStrings.clear(); + + /* + Erase any info bools that are unused. We do this repeatedly as each run + will remove those bools that are no longer dependencies of other bools + in the vector. + */ + INFOBOOLTYPE swapList(&InfoBoolComparator); + do + { + swapList.clear(); + for (auto &item : m_bools) + if (!item.unique()) + swapList.insert(item); + m_bools.swap(swapList); + } while (swapList.size() != m_bools.size()); + + // log which ones are used - they should all be gone by now + for (INFOBOOLTYPE::const_iterator i = m_bools.begin(); i != m_bools.end(); ++i) + CLog::Log(LOGDEBUG, "Infobool '{}' still used by {} instances", (*i)->GetExpression(), + (unsigned int)i->use_count()); +} + +void CGUIInfoManager::UpdateAVInfo() +{ + if (CServiceBroker::GetDataCacheCore().HasAVInfoChanges()) + { + VideoStreamInfo video; + AudioStreamInfo audio; + SubtitleStreamInfo subtitle; + + auto& components = CServiceBroker::GetAppComponents(); + const auto appPlayer = components.GetComponent<CApplicationPlayer>(); + appPlayer->GetVideoStreamInfo(CURRENT_STREAM, video); + appPlayer->GetAudioStreamInfo(CURRENT_STREAM, audio); + appPlayer->GetSubtitleStreamInfo(CURRENT_STREAM, subtitle); + + m_infoProviders.UpdateAVInfo(audio, video, subtitle); + } +} + +int CGUIInfoManager::AddMultiInfo(const CGUIInfo &info) +{ + // check to see if we have this info already + for (unsigned int i = 0; i < m_multiInfo.size(); ++i) + if (m_multiInfo[i] == info) + return static_cast<int>(i) + MULTI_INFO_START; + // return the new offset + m_multiInfo.emplace_back(info); + int id = static_cast<int>(m_multiInfo.size()) + MULTI_INFO_START - 1; + if (id > MULTI_INFO_END) + CLog::Log(LOGERROR, "{} - too many multiinfo bool/labels in this skin", __FUNCTION__); + return id; +} + +int CGUIInfoManager::ResolveMultiInfo(int info) const +{ + int iLastInfo = 0; + + int iResolvedInfo = info; + while (iResolvedInfo >= MULTI_INFO_START && iResolvedInfo <= MULTI_INFO_END) + { + iLastInfo = iResolvedInfo; + iResolvedInfo = m_multiInfo[iResolvedInfo - MULTI_INFO_START].m_info; + } + + return iLastInfo; +} + +bool CGUIInfoManager::IsListItemInfo(int info) const +{ + int iResolvedInfo = info; + while (iResolvedInfo >= MULTI_INFO_START && iResolvedInfo <= MULTI_INFO_END) + iResolvedInfo = m_multiInfo[iResolvedInfo - MULTI_INFO_START].m_info; + + return (iResolvedInfo >= LISTITEM_START && iResolvedInfo <= LISTITEM_END); +} + +bool CGUIInfoManager::GetItemInt(int &value, const CGUIListItem *item, int contextWindow, int info) const +{ + value = 0; + + if (!item) + return false; + + return m_infoProviders.GetInt(value, item, contextWindow, CGUIInfo(info)); +} + +std::string CGUIInfoManager::GetItemLabel(const CFileItem *item, int contextWindow, int info, std::string *fallback /* = nullptr */) const +{ + return GetMultiInfoItemLabel(item, contextWindow, CGUIInfo(info), fallback); +} + +std::string CGUIInfoManager::GetMultiInfoItemLabel(const CFileItem *item, int contextWindow, const CGUIInfo &info, std::string *fallback /* = nullptr */) const +{ + if (!item) + return std::string(); + + std::string value; + + if (info.m_info >= CONDITIONAL_LABEL_START && info.m_info <= CONDITIONAL_LABEL_END) + { + return GetSkinVariableString(info.m_info, contextWindow, false, item); + } + else if (info.m_info >= MULTI_INFO_START && info.m_info <= MULTI_INFO_END) + { + return GetMultiInfoItemLabel(item, contextWindow, m_multiInfo[info.m_info - MULTI_INFO_START], fallback); + } + else if (!m_infoProviders.GetLabel(value, item, contextWindow, info, fallback)) + { + switch (info.m_info) + { + case LISTITEM_PROPERTY: + return item->GetProperty(info.GetData3()).asString(); + case LISTITEM_LABEL: + return item->GetLabel(); + case LISTITEM_LABEL2: + return item->GetLabel2(); + case LISTITEM_FILENAME: + case LISTITEM_FILE_EXTENSION: + case LISTITEM_FILENAME_NO_EXTENSION: + { + std::string strFile = URIUtils::GetFileName(item->GetPath()); + if (info.m_info == LISTITEM_FILE_EXTENSION) + { + std::string strExtension = URIUtils::GetExtension(strFile); + return StringUtils::TrimLeft(strExtension, "."); + } + else if (info.m_info == LISTITEM_FILENAME_NO_EXTENSION) + { + URIUtils::RemoveExtension(strFile); + } + return strFile; + } + case LISTITEM_DATE: + if (item->m_dateTime.IsValid()) + return item->m_dateTime.GetAsLocalizedDate(); + break; + case LISTITEM_DATETIME: + if (item->m_dateTime.IsValid()) + return item->m_dateTime.GetAsLocalizedDateTime(); + break; + case LISTITEM_SIZE: + if (!item->m_bIsFolder || item->m_dwSize) + return StringUtils::SizeToString(item->m_dwSize); + break; + case LISTITEM_PROGRAM_COUNT: + return std::to_string(item->m_iprogramCount); + case LISTITEM_ACTUAL_ICON: + return item->GetArt("icon"); + case LISTITEM_ICON: + { + std::string strThumb = item->GetThumbHideIfUnwatched(item); + if (strThumb.empty()) + strThumb = item->GetArt("icon"); + if (fallback) + *fallback = item->GetArt("icon"); + return strThumb; + } + case LISTITEM_ART: + return item->GetArt(info.GetData3()); + case LISTITEM_OVERLAY: + return item->GetOverlayImage(); + case LISTITEM_THUMB: + return item->GetThumbHideIfUnwatched(item); + case LISTITEM_FOLDERPATH: + return CURL(item->GetPath()).GetWithoutUserDetails(); + case LISTITEM_FOLDERNAME: + case LISTITEM_PATH: + { + std::string path; + URIUtils::GetParentPath(item->GetPath(), path); + path = CURL(path).GetWithoutUserDetails(); + if (info.m_info == LISTITEM_FOLDERNAME) + { + URIUtils::RemoveSlashAtEnd(path); + path = URIUtils::GetFileName(path); + } + return path; + } + case LISTITEM_FILENAME_AND_PATH: + { + std::string path = item->GetPath(); + path = CURL(path).GetWithoutUserDetails(); + return path; + } + case LISTITEM_SORT_LETTER: + { + std::string letter; + std::wstring character(1, item->GetSortLabel()[0]); + StringUtils::ToUpper(character); + g_charsetConverter.wToUTF8(character, letter); + return letter; + } + case LISTITEM_STARTTIME: + { + if (item->m_dateTime.IsValid()) + return item->m_dateTime.GetAsLocalizedTime("", false); + break; + } + case LISTITEM_STARTDATE: + { + if (item->m_dateTime.IsValid()) + return item->m_dateTime.GetAsLocalizedDate(true); + break; + } + case LISTITEM_CURRENTITEM: + return std::to_string(item->GetCurrentItem()); + } + } + + return value; +} + +std::string CGUIInfoManager::GetItemImage(const CGUIListItem *item, int contextWindow, int info, std::string *fallback /*= nullptr*/) const +{ + if (!item || !item->IsFileItem()) + return std::string(); + + return GetMultiInfoItemImage(static_cast<const CFileItem*>(item), contextWindow, CGUIInfo(info), fallback); +} + +std::string CGUIInfoManager::GetMultiInfoItemImage(const CFileItem *item, int contextWindow, const CGUIInfo &info, std::string *fallback /*= nullptr*/) const +{ + if (info.m_info >= CONDITIONAL_LABEL_START && info.m_info <= CONDITIONAL_LABEL_END) + { + return GetSkinVariableString(info.m_info, contextWindow, true, item); + } + else if (info.m_info >= MULTI_INFO_START && info.m_info <= MULTI_INFO_END) + { + return GetMultiInfoItemImage(item, contextWindow, m_multiInfo[info.m_info - MULTI_INFO_START], fallback); + } + + return GetMultiInfoItemLabel(item, contextWindow, info, fallback); +} + +bool CGUIInfoManager::GetItemBool(const CGUIListItem *item, int contextWindow, int condition) const +{ + if (!item) + return false; + + bool value = false; + if (!m_infoProviders.GetBool(value, item, contextWindow, CGUIInfo(condition))) + { + switch (condition) + { + case LISTITEM_ISSELECTED: + return item->IsSelected(); + case LISTITEM_IS_FOLDER: + return item->m_bIsFolder; + case LISTITEM_IS_PARENTFOLDER: + { + if (item->IsFileItem()) + { + const CFileItem *pItem = static_cast<const CFileItem *>(item); + return pItem->IsParentFolder(); + } + break; + } + } + } + + return value; +} + +void CGUIInfoManager::ResetCache() +{ + // mark our infobools as dirty + std::unique_lock<CCriticalSection> lock(m_critInfo); + ++m_refreshCounter; +} + +void CGUIInfoManager::SetCurrentVideoTag(const CVideoInfoTag &tag) +{ + m_currentFile->SetFromVideoInfoTag(tag); + m_currentFile->SetStartOffset(0); +} + +void CGUIInfoManager::SetCurrentSongTag(const MUSIC_INFO::CMusicInfoTag &tag) +{ + m_currentFile->SetFromMusicInfoTag(tag); + m_currentFile->SetStartOffset(0); +} + +const MUSIC_INFO::CMusicInfoTag* CGUIInfoManager::GetCurrentSongTag() const +{ + if (m_currentFile->HasMusicInfoTag()) + return m_currentFile->GetMusicInfoTag(); + + return nullptr; +} + +const CVideoInfoTag* CGUIInfoManager::GetCurrentMovieTag() const +{ + if (m_currentFile->HasVideoInfoTag()) + return m_currentFile->GetVideoInfoTag(); + + return nullptr; +} + +const KODI::GAME::CGameInfoTag* CGUIInfoManager::GetCurrentGameTag() const +{ + if (m_currentFile->HasGameInfoTag()) + return m_currentFile->GetGameInfoTag(); + + return nullptr; +} + +int CGUIInfoManager::RegisterSkinVariableString(const CSkinVariableString* info) +{ + if (!info) + return 0; + + std::unique_lock<CCriticalSection> lock(m_critInfo); + m_skinVariableStrings.emplace_back(*info); + delete info; + return CONDITIONAL_LABEL_START + m_skinVariableStrings.size() - 1; +} + +int CGUIInfoManager::TranslateSkinVariableString(const std::string& name, int context) +{ + for (std::vector<CSkinVariableString>::const_iterator it = m_skinVariableStrings.begin(); + it != m_skinVariableStrings.end(); ++it) + { + if (StringUtils::EqualsNoCase(it->GetName(), name) && it->GetContext() == context) + return it - m_skinVariableStrings.begin() + CONDITIONAL_LABEL_START; + } + return 0; +} + +std::string CGUIInfoManager::GetSkinVariableString(int info, + int contextWindow, + bool preferImage /*= false*/, + const CGUIListItem* item /*= nullptr*/) const +{ + info -= CONDITIONAL_LABEL_START; + if (info >= 0 && info < static_cast<int>(m_skinVariableStrings.size())) + return m_skinVariableStrings[info].GetValue(contextWindow, preferImage, item); + + return ""; +} + +bool CGUIInfoManager::ConditionsChangedValues(const std::map<INFO::InfoPtr, bool>& map) +{ + for (std::map<INFO::InfoPtr, bool>::const_iterator it = map.begin() ; it != map.end() ; ++it) + { + if (it->first->Get(INFO::DEFAULT_CONTEXT) != it->second) + return true; + } + return false; +} + +int CGUIInfoManager::GetMessageMask() +{ + return TMSG_MASK_GUIINFOMANAGER; +} + +void CGUIInfoManager::OnApplicationMessage(KODI::MESSAGING::ThreadMessage* pMsg) +{ + switch (pMsg->dwMessage) + { + case TMSG_GUI_INFOLABEL: + { + if (pMsg->lpVoid) + { + auto infoLabels = static_cast<std::vector<std::string>*>(pMsg->lpVoid); + for (auto& param : pMsg->params) + infoLabels->emplace_back(GetLabel(TranslateString(param), DEFAULT_CONTEXT)); + } + } + break; + + case TMSG_GUI_INFOBOOL: + { + if (pMsg->lpVoid) + { + auto infoLabels = static_cast<std::vector<bool>*>(pMsg->lpVoid); + for (auto& param : pMsg->params) + infoLabels->push_back(EvaluateBool(param, DEFAULT_CONTEXT)); + } + } + break; + + case TMSG_UPDATE_CURRENT_ITEM: + { + CFileItem* item = static_cast<CFileItem*>(pMsg->lpVoid); + if (!item) + return; + + if (pMsg->param1 == 1 && item->HasMusicInfoTag()) // only grab music tag + SetCurrentSongTag(*item->GetMusicInfoTag()); + else if (pMsg->param1 == 2 && item->HasVideoInfoTag()) // only grab video tag + SetCurrentVideoTag(*item->GetVideoInfoTag()); + else + SetCurrentItem(*item); + + delete item; + } + break; + + default: + break; + } +} + +void CGUIInfoManager::RegisterInfoProvider(IGUIInfoProvider *provider) +{ + if (!CServiceBroker::GetWinSystem()) + return; + + std::unique_lock<CCriticalSection> lock(CServiceBroker::GetWinSystem()->GetGfxContext()); + + m_infoProviders.RegisterProvider(provider, false); +} + +void CGUIInfoManager::UnregisterInfoProvider(IGUIInfoProvider *provider) +{ + if (!CServiceBroker::GetWinSystem()) + return; + + std::unique_lock<CCriticalSection> lock(CServiceBroker::GetWinSystem()->GetGfxContext()); + + m_infoProviders.UnregisterProvider(provider); +} |