/* * 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 #include #include #include #include #include #include #include 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 \ tag or with condition /// attributes. Scripts can read boolean conditions with /// xbmc.getCondVisibility(condition). /// /// Skins can use infolabels with $INFO[infolabel] or the \ tag. Scripts /// can read infolabels with xbmc.getInfoLabel('infolabel'). /// /// @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{ `true`, /// \anchor Global_True /// _boolean_, /// @return Always evaluates to **true**. ///

/// } /// \table_row3{ `false`, /// \anchor Global_False /// _boolean_, /// @return Always evaluates to **false**. ///

/// } /// \table_row3{ `yes`, /// \anchor Global_Yes /// _boolean_, /// @return same as \link Global_True `true` \endlink. ///

/// } /// \table_row3{ `no`, /// \anchor Global_No /// _boolean_, /// @return same as \link Global_False `false` \endlink. ///

/// } /// \table_end /// /// ----------------------------------------------------------------------------- /// \page modules__infolabels_boolean_conditions /// \subsection modules__infolabels_boolean_conditions_Addon Addon /// \table_start /// \table_h3{ Labels, Type, Description } /// \table_row3{ `Addon.SettingStr(addon_id\,setting_id)`, /// \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 ///


/// @skinning_v20 **[New Infolabel]** \link Addon_SettingString `Addon.SettingStr(addon_id\,setting_id)`\endlink ///

/// } /// \table_row3{ `Addon.SettingBool(addon_id\,setting_id)`, /// \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 ///


/// @skinning_v20 **[New Boolean Condition]** \link Addon_SettingBool `Addon.SettingBool(addon_id\,setting_id)`\endlink ///

/// } /// \table_row3{ `Addon.SettingInt(addon_id\,setting_id)`, /// \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 ///


/// @skinning_v20 **[New Integer Info]** \link Addon_SettingInt `Addon.SettingInt(addon_id\,setting_id)`\endlink ///

/// } /// \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{ `String.IsEmpty(info)`, /// \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 ///


/// @skinning_v17 **[New Boolean Condition]** \link String_IsEmpty `String.IsEmpty(info)`\endlink ///

/// } /// \table_row3{ `String.IsEqual(info\,string)`, /// \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 ///


/// @skinning_v17 **[New Boolean Condition]** \link String_IsEqual `String.IsEqual(info\,string)`\endlink ///

/// } /// \table_row3{ `String.StartsWith(info\,substring)`, /// \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 ///


/// @skinning_v17 **[New Boolean Condition]** \link String_StartsWith `String.StartsWith(info\,substring)`\endlink ///

/// } /// \table_row3{ `String.EndsWith(info\,substring)`, /// \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 ///


/// @skinning_v17 **[New Boolean Condition]** \link String_EndsWith `String.EndsWith(info\,substring)`\endlink ///

/// } /// \table_row3{ `String.Contains(info\,substring)`, /// \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 ///


/// @skinning_v17 **[New Boolean Condition]** \link String_Contains `String.Contains(info\,substring)`\endlink ///

/// } /// \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{ `Integer.ValueOf(number)`, /// \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. ///


/// @skinning_v20 **[New InfoLabel]** \link Integer_ValueOf `Integer.ValueOf(number)`\endlink ///

/// } /// \table_row3{ `Integer.IsEqual(info\,number)`, /// \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)` ///


/// @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. ///

/// } /// \table_row3{ `Integer.IsGreater(info\,number)`, /// \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)` ///


/// @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. ///

/// } /// \table_row3{ `Integer.IsGreaterOrEqual(info\,number)`, /// \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)` ///


/// @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. ///

/// } /// \table_row3{ `Integer.IsLess(info\,number)`, /// \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)` ///


/// @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. ///

/// } /// \table_row3{ `Integer.IsLessOrEqual(info\,number)`, /// \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)` ///


/// @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. ///

/// } /// \table_row3{ `Integer.IsEven(info)`, /// \anchor Integer_IsEven /// _boolean_, /// @return **True** if the value of the infolabel is odd /// @param info - infolabel /// @note **Example:** `Integer.IsEven(ListItem.CurrentItem)` ///


/// @skinning_v19 **[New Boolean Condition]** \link Integer_IsEven `Integer.IsEven(info)`\endlink ///

/// } /// \table_row3{ `Integer.IsOdd(info)`, /// \anchor Integer_IsOdd /// _boolean_, /// @return **True** if the value of the infolabel is odd /// @param info - infolabel /// @note **Example:** `Integer.IsOdd(ListItem.CurrentItem)` ///


/// @skinning_v19 **[New Boolean Condition]** \link Integer_IsOdd `Integer.IsOdd(info)`\endlink ///

/// } /// \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{ `Player.HasAudio`, /// \anchor Player_HasAudio /// _boolean_, /// @return **True** if the player has an audio file. ///

/// } /// \table_row3{ `Player.HasGame`, /// \anchor Player_HasGame /// _boolean_, /// @return **True** if the player has a game file (RETROPLAYER). ///


/// @skinning_v18 **[New Boolean Condition]** \link Player_HasGame `Player.HasGame`\endlink ///

/// } /// \table_row3{ `Player.HasMedia`, /// \anchor Player_HasMedia /// _boolean_, /// @return **True** if the player has an audio or video file. ///

/// } /// \table_row3{ `Player.HasVideo`, /// \anchor Player_HasVideo /// _boolean_, /// @return **True** if the player has a video file. ///

/// } /// \table_row3{ `Player.Paused`, /// \anchor Player_Paused /// _boolean_, /// @return **True** if the player is paused. ///

/// } /// \table_row3{ `Player.Playing`, /// \anchor Player_Playing /// _boolean_, /// @return **True** if the player is currently playing (i.e. not ffwding\, /// rewinding or paused.) ///

/// } /// \table_row3{ `Player.Rewinding`, /// \anchor Player_Rewinding /// _boolean_, /// @return **True** if the player is rewinding. ///

/// } /// \table_row3{ `Player.Rewinding2x`, /// \anchor Player_Rewinding2x /// _boolean_, /// @return **True** if the player is rewinding at 2x. ///

/// } /// \table_row3{ `Player.Rewinding4x`, /// \anchor Player_Rewinding4x /// _boolean_, /// @return **True** if the player is rewinding at 4x. ///

/// } /// \table_row3{ `Player.Rewinding8x`, /// \anchor Player_Rewinding8x /// _boolean_, /// @return **True** if the player is rewinding at 8x. ///

/// } /// \table_row3{ `Player.Rewinding16x`, /// \anchor Player_Rewinding16x /// _boolean_, /// @return **True** if the player is rewinding at 16x. ///

/// } /// \table_row3{ `Player.Rewinding32x`, /// \anchor Player_Rewinding32x /// _boolean_, /// @return **True** if the player is rewinding at 32x. ///

/// } /// \table_row3{ `Player.Forwarding`, /// \anchor Player_Forwarding /// _boolean_, /// @return **True** if the player is fast forwarding. ///

/// } /// \table_row3{ `Player.Forwarding2x`, /// \anchor Player_Forwarding2x /// _boolean_, /// @return **True** if the player is fast forwarding at 2x. ///

/// } /// \table_row3{ `Player.Forwarding4x`, /// \anchor Player_Forwarding4x /// _boolean_, /// @return **True** if the player is fast forwarding at 4x. ///

/// } /// \table_row3{ `Player.Forwarding8x`, /// \anchor Player_Forwarding8x /// _boolean_, /// @return **True** if the player is fast forwarding at 8x. ///

/// } /// \table_row3{ `Player.Forwarding16x`, /// \anchor Player_Forwarding16x /// _boolean_, /// @return **True** if the player is fast forwarding at 16x. ///

/// } /// \table_row3{ `Player.Forwarding32x`, /// \anchor Player_Forwarding32x /// _boolean_, /// @return **True** if the player is fast forwarding at 32x. ///

/// } /// \table_row3{ `Player.Caching`, /// \anchor Player_Caching /// _boolean_, /// @return **True** if the player is current re-caching data (internet based /// video playback). ///

/// } /// \table_row3{ `Player.DisplayAfterSeek`, /// \anchor Player_DisplayAfterSeek /// _boolean_, /// @return **True** for the first 2.5 seconds after a seek. ///

/// } /// \table_row3{ `Player.Seekbar`, /// \anchor Player_Seekbar /// _integer_, /// @return The percentage of one seek to other position. ///

/// } /// \table_row3{ `Player.Seeking`, /// \anchor Player_Seeking /// _boolean_, /// @return **True** if a seek is in progress. ///

/// } /// \table_row3{ `Player.ShowTime`, /// \anchor Player_ShowTime /// _boolean_, /// @return **True** if the user has requested the time to show (occurs in video /// fullscreen). ///

/// } /// \table_row3{ `Player.ShowInfo`, /// \anchor Player_ShowInfo /// _boolean_, /// @return **True** if the user has requested the song info to show (occurs in /// visualisation fullscreen and slideshow). ///

/// } /// \table_row3{ `Player.Title`, /// \anchor Player_Title /// _string_, /// @return The Musicplayer title for audio and the Videoplayer title for /// video. ///

/// } /// \table_row3{ `Player.offset(number).Title`, /// \anchor Player_Offset_Title /// _string_, /// @return The title of audio or video which has an offset `number` with respect to the currently playing item. ///


/// @skinning_v19 **[New Infolabel]** \link Player_Offset_Title `Player.offset(number).Title`\endlink ///

/// } /// \table_row3{ `Player.position(number).Title`, /// \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. ///


/// @skinning_v19 **[New Infolabel]** \link Player_Position_Title `Player.position(number).Title`\endlink ///

/// } /// \table_row3{ `Player.Muted`, /// \anchor Player_Muted /// _boolean_, /// @return **True** if the volume is muted. ///

/// } /// \table_row3{ `Player.HasDuration`, /// \anchor Player_HasDuration /// _boolean_, /// @return **True** if Media is not a true stream. ///

/// } /// \table_row3{ `Player.Passthrough`, /// \anchor Player_Passthrough /// _boolean_, /// @return **True** if the player is using audio passthrough. ///

/// } /// \table_row3{ `Player.CacheLevel`, /// \anchor Player_CacheLevel /// _string_, /// @return The used cache level as a string with an integer number. ///

/// } /// \table_row3{ `Player.Progress`, /// \anchor Player_Progress /// _integer_ / _string_, /// @return The progress position as percentage. ///


/// @skinning_v19 \link Player_Progress `Player.Progress`\endlink infolabel /// also exposed as a string. ///

/// } /// \table_row3{ `Player.ProgressCache`, /// \anchor Player_ProgressCache /// _integer_ / _string_, /// @return How much of the file is cached above current play percentage ///


/// @skinning_v19 \link Player_ProgressCache `Player.ProgressCache`\endlink /// infolabel also exposed as a string. ///

/// } /// \table_row3{ `Player.Volume`, /// \anchor Player_Volume /// _string_, /// @return The current player volume with the format `%2.1f` dB ///

/// } /// \table_row3{ `Player.SubtitleDelay`, /// \anchor Player_SubtitleDelay /// _string_, /// @return The used subtitle delay with the format `%2.3f` s ///

/// } /// \table_row3{ `Player.AudioDelay`, /// \anchor Player_AudioDelay /// _string_, /// @return The used audio delay with the format `%2.3f` s ///

/// } /// \table_row3{ `Player.Chapter`, /// \anchor Player_Chapter /// _integer_, /// @return The current chapter of current playing media. ///

/// } /// \table_row3{ `Player.ChapterCount`, /// \anchor Player_ChapterCount /// _integer_, /// @return The total number of chapters of current playing media. ///

/// } /// \table_row3{ `Player.ChapterName`, /// \anchor Player_ChapterName /// _string_, /// @return The name of currently used chapter if available. ///

/// } /// \table_row3{ `Player.Folderpath`, /// \anchor Player_Folderpath /// _string_, /// @return The full path of the currently playing song or movie ///

/// } /// \table_row3{ `Player.offset(number).Folderpath`, /// \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. ///


/// @skinning_v19 **[New Infolabel]** \link Player_Offset_Folderpath `Player.offset(number).Folderpath`\endlink ///

/// } /// \table_row3{ `Player.position(number).Folderpath`, /// \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. ///


/// @skinning_v19 **[New Infolabel]** \link Player_Position_Folderpath `Player.position(number).Folderpath`\endlink ///

/// } /// \table_row3{ `Player.FilenameAndPath`, /// \anchor Player_FilenameAndPath /// _string_, /// @return The full path with filename of the currently /// playing song or movie ///

/// } /// \table_row3{ `Player.offset(number).FilenameAndPath`, /// \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. ///


/// @skinning_v19 **[New Infolabel]** \link Player_Offset_FilenameAndPath `Player.offset(number).FilenameAndPath`\endlink ///

/// } /// \table_row3{ `Player.position(number).FilenameAndPath`, /// \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. ///


/// @skinning_v19 **[New Infolabel]** \link Player_Position_FilenameAndPath `Player.position(number).FilenameAndPath`\endlink ///

/// } /// \table_row3{ `Player.Filename`, /// \anchor Player_Filename /// _string_, /// @return The filename of the currently playing media. ///


/// @skinning_v13 **[New Infolabel]** \link Player_Filename `Player.Filename`\endlink ///

/// } /// \table_row3{ `Player.offset(number).Filename`, /// \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. ///


/// @skinning_v19 **[New Infolabel]** \link Player_Offset_Filename `Player.offset(number).Filename`\endlink ///

/// } /// \table_row3{ `Player.position(number).Filename`, /// \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. ///


/// @skinning_v19 **[New Infolabel]** \link Player_Position_Filename `Player.position(number).Filename`\endlink ///

/// } /// \table_row3{ `Player.IsInternetStream`, /// \anchor Player_IsInternetStream /// _boolean_, /// @return **True** if the player is playing an internet stream. ///

/// } /// \table_row3{ `Player.PauseEnabled`, /// \anchor Player_PauseEnabled /// _boolean_, /// @return **True** if played stream is paused. ///

/// } /// \table_row3{ `Player.SeekEnabled`, /// \anchor Player_SeekEnabled /// _boolean_, /// @return **True** if seek on playing is enabled. ///

/// } /// \table_row3{ `Player.ChannelPreviewActive`, /// \anchor Player_ChannelPreviewActive /// _boolean_, /// @return **True** if PVR channel preview is active (used /// channel tag different from played tag) ///

/// } /// \table_row3{ `Player.TempoEnabled`, /// \anchor Player_TempoEnabled /// _boolean_, /// @return **True** if player supports tempo (i.e. speed up/down normal /// playback speed) ///


/// @skinning_v17 **[New Boolean Condition]** \link Player_TempoEnabled `Player.TempoEnabled`\endlink ///

/// } /// \table_row3{ `Player.IsTempo`, /// \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) ///


/// @skinning_v17 **[New Boolean Condition]** \link Player_IsTempo `Player.IsTempo`\endlink ///

/// } /// \table_row3{ `Player.PlaySpeed`, /// \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. ///

/// } /// \table_row3{ `Player.HasResolutions`, /// \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) ///


/// @skinning_v18 **[New Boolean Condition]** \link Player_HasResolutions `Player.HasResolutions`\endlink ///

/// } /// \table_row3{ `Player.HasPrograms`, /// \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. ///

/// } /// \table_row3{ `Player.FrameAdvance`, /// \anchor Player_FrameAdvance /// _boolean_, /// @return **True** if player is in frame advance mode. /// @note Skins should hide seek bar in this mode ///


/// @skinning_v18 **[New Boolean Condition]** \link Player_FrameAdvance `Player.FrameAdvance`\endlink ///

/// } /// \table_row3{ `Player.Icon`, /// \anchor Player_Icon /// _string_, /// @return The thumbnail of the currently playing item. If no thumbnail image exists\, /// the icon will be returned\, if available. ///


/// @skinning_v18 **[New Infolabel]** \link Player_Icon `Player.Icon`\endlink ///

/// } /// \table_row3{ `Player.Cutlist`, /// \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. ///

/// @deprecated \link Player_Cutlist `Player.Cutlist`\endlink is deprecated and will be removed in the next version. ///


/// @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 ///

/// } /// \table_row3{ `Player.Editlist`, /// \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. ///


/// @skinning_v20 **[New Infolabel]** \link Player_Editlist `Player.Editlist`\endlink ///

/// } /// \table_row3{ `Player.Cuts`, /// \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. ///


/// @skinning_v20 **[New Infolabel]** \link Player_Cuts `Player.Cuts`\endlink ///

/// } /// \table_row3{ `Player.SceneMarkers`, /// \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. ///


/// @skinning_v20 **[New Infolabel]** \link Player_SceneMarkers `Player.SceneMarkers`\endlink ///

/// } /// \table_row3{ `Player.HasSceneMarkers`, /// \anchor Player_HasSceneMarkers /// _boolean_, /// @return **True** if the item being played has scene markers\, **False** otherwise ///


/// @skinning_v20 **[New Infolabel]** \link Player_HasSceneMarkers `Player.HasSceneMarkers`\endlink ///

/// } /// \table_row3{ `Player.Chapters`, /// \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. ///


/// @skinning_v19 **[New Infolabel]** \link Player_Chapters `Player.Chapters`\endlink ///

/// } 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{ `Player.Art(type)`, /// \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. ///

/// } /// \table_row3{ `Player.HasPerformedSeek(interval)`, /// \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) ///


/// @skinning_v20 **[New Boolean Condition]** \link Player_HasPerformedSeek `Player.HasPerformedSeek(interval)`\endlink ///

/// } const infomap player_param[] = {{"art", PLAYER_ITEM_ART}, {"hasperformedseek", PLAYER_HASPERFORMEDSEEK}}; /// \page modules__infolabels_boolean_conditions /// \table_row3{ `Player.SeekTime`, /// \anchor Player_SeekTime /// _string_, /// @return The time to which the user is seeking. ///

/// } /// \table_row3{ `Player.SeekOffset([format])`, /// \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. ///

/// @note **Example:** user presses BigStepForward\, player.seekoffset returns +10:00 ///

/// } /// \table_row3{ `Player.SeekStepSize`, /// \anchor Player_SeekStepSize /// _string_, /// @return The seek step size. ///

///


/// @skinning_v15 **[New Infolabel]** \link Player_SeekStepSize `Player.SeekStepSize`\endlink ///

/// } /// \table_row3{ `Player.TimeRemaining([format])`, /// \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. ///

/// } /// \table_row3{ `Player.TimeSpeed`, /// \anchor Player_TimeSpeed /// _string_, /// @return The time and the playspeed formatted: "1:23 (2x)". ///

/// } /// \table_row3{ `Player.Time([format])`, /// \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. ///

/// } /// \table_row3{ `Player.Duration([format])`, /// \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. ///

/// } /// \table_row3{ `Player.FinishTime([format])`, /// \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. ///

/// } /// \table_row3{ `Player.StartTime([format])`, /// \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. ///

/// } /// \table_row3{ `Player.SeekNumeric([format])`, /// \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. ///

/// } 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{ `Player.Process(videohwdecoder)`, /// \anchor Player_Process_videohwdecoder /// _boolean_, /// @return **True** if the currently playing video is decoded in hardware. ///


/// @skinning_v17 **[New Boolean Condition]** \link Player_Process_videohwdecoder `Player.Process(videohwdecoder)`\endlink ///

/// } /// \table_row3{ `Player.Process(videodecoder)`, /// \anchor Player_Process_videodecoder /// _string_, /// @return The videodecoder name of the currently playing video. ///


/// @skinning_v17 **[New Infolabel]** \link Player_Process_videodecoder `Player.Process(videodecoder)`\endlink ///

/// } /// \table_row3{ `Player.Process(deintmethod)`, /// \anchor Player_Process_deintmethod /// _string_, /// @return The deinterlace method of the currently playing video. ///


/// @skinning_v17 **[New Infolabel]** \link Player_Process_deintmethod `Player.Process(deintmethod)`\endlink ///

/// } /// \table_row3{ `Player.Process(pixformat)`, /// \anchor Player_Process_pixformat /// _string_, /// @return The pixel format of the currently playing video. ///


/// @skinning_v17 **[New Infolabel]** \link Player_Process_pixformat `Player.Process(pixformat)`\endlink ///

/// } /// \table_row3{ `Player.Process(videowidth)`, /// \anchor Player_Process_videowidth /// _string_, /// @return The width of the currently playing video. ///


/// @skinning_v17 **[New Infolabel]** \link Player_Process_videowidth `Player.Process(videowidth)`\endlink ///

/// } /// \table_row3{ `Player.Process(videoheight)`, /// \anchor Player_Process_videoheight /// _string_, /// @return The width of the currently playing video. ///


/// @skinning_v17 **[New Infolabel]** \link Player_Process_videoheight `Player.Process(videoheight)`\endlink ///

/// } /// \table_row3{ `Player.Process(videoscantype)`, /// \anchor Player_Process_videoscantype /// _string_, /// @return The scan type identifier of the currently playing video **p** (for progressive) or **i** (for interlaced). ///


/// @skinning_v20 **[New Infolabel]** \link Player_Process_videoscantype `Player.Process(videoscantype)`\endlink ///

/// } /// \table_row3{ `Player.Process(videofps)`, /// \anchor Player_Process_videofps /// _string_, /// @return The video framerate of the currently playing video. ///


/// @skinning_v17 **[New Infolabel]** \link Player_Process_videofps `Player.Process(videofps)`\endlink ///

/// } /// \table_row3{ `Player.Process(videodar)`, /// \anchor Player_Process_videodar /// _string_, /// @return The display aspect ratio of the currently playing video. ///


/// @skinning_v17 **[New Infolabel]** \link Player_Process_videodar `Player.Process(videodar)`\endlink ///

/// } /// \table_row3{ `Player.Process(audiodecoder)`, /// \anchor Player_Process_audiodecoder /// _string_, /// @return The audiodecoder name of the currently playing item. ///


/// @skinning_v17 **[New Infolabel]** \link Player_Process_videodar `Player.Process(audiodecoder)`\endlink ///

/// } /// \table_row3{ `Player.Process(audiochannels)`, /// \anchor Player_Process_audiochannels /// _string_, /// @return The audiodecoder name of the currently playing item. ///


/// @skinning_v17 **[New Infolabel]** \link Player_Process_audiochannels `Player.Process(audiochannels)`\endlink ///

/// } /// \table_row3{ `Player.Process(audiosamplerate)`, /// \anchor Player_Process_audiosamplerate /// _string_, /// @return The samplerate of the currently playing item. ///


/// @skinning_v17 **[New Infolabel]** \link Player_Process_audiosamplerate `Player.Process(audiosamplerate)`\endlink ///

/// } /// \table_row3{ `Player.Process(audiobitspersample)`, /// \anchor Player_Process_audiobitspersample /// _string_, /// @return The bits per sample of the currently playing item. ///


/// @skinning_v17 **[New Infolabel]** \link Player_Process_audiobitspersample `Player.Process(audiobitspersample)`\endlink ///

/// } /// \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{ `Weather.IsFetched`, /// \anchor Weather_IsFetched /// _boolean_, /// @return **True** if the weather data has been downloaded. ///

/// } /// \table_row3{ `Weather.Conditions`, /// \anchor Weather_Conditions /// _string_, /// @return The current weather conditions as textual description. /// @note This is looked up in a background process. ///

/// } /// \table_row3{ `Weather.ConditionsIcon`, /// \anchor Weather_ConditionsIcon /// _string_, /// @return The current weather conditions as an icon. /// @note This is looked up in a background process. ///

/// } /// \table_row3{ `Weather.Temperature`, /// \anchor Weather_Temperature /// _string_, /// @return The current weather temperature. ///

/// } /// \table_row3{ `Weather.Location`, /// \anchor Weather_Location /// _string_, /// @return The city/town which the above two items are for. ///

/// } /// \table_row3{ `Weather.Fanartcode`, /// \anchor Weather_fanartcode /// _string_, /// @return The current weather fanartcode. ///

/// } /// \table_row3{ `Weather.Plugin`, /// \anchor Weather_plugin /// _string_, /// @return The current weather plugin. ///

/// } /// \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{ `System.AlarmLessOrEqual(alarmname\,seconds)`, /// \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. ///

/// } /// \table_row3{ `System.HasNetwork`, /// \anchor System_HasNetwork /// _boolean_, /// @return **True** if the Kodi host has a network available. ///

/// } /// \table_row3{ `System.HasMediadvd`, /// \anchor System_HasMediadvd /// _boolean_, /// @return **True** if there is a CD or DVD in the DVD-ROM drive. ///

/// } /// \table_row3{ `System.HasMediaAudioCD`, /// \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. ///


/// @skinning_v18 **[New Boolean Condition]** \link System_HasMediaAudioCD /// `System.HasMediaAudioCD` \endlink

/// } /// \table_row3{ `System.DVDReady`, /// \anchor System_DVDReady /// _boolean_, /// @return **True** if the disc is ready to use. ///

/// } /// \table_row3{ `System.TrayOpen`, /// \anchor System_TrayOpen /// _boolean_, /// @return **True** if the disc tray is open. ///

/// } /// \table_row3{ `System.HasLocks`, /// \anchor System_HasLocks /// _boolean_, /// @return **True** if the system has an active lock mode. ///

/// } /// \table_row3{ `System.IsMaster`, /// \anchor System_IsMaster /// _boolean_, /// @return **True** if the system is in master mode. ///

/// } /// \table_row3{ `System.ShowExitButton`, /// \anchor System_ShowExitButton /// _boolean_, /// @return **True** if the exit button should be shown (configurable via advanced settings). ///

/// } /// \table_row3{ `System.DPMSActive`, /// \anchor System_DPMSActive /// _boolean_, /// @return **True** if DPMS (VESA Display Power Management Signaling) mode is active. ///

/// } /// \table_row3{ `System.IsStandalone`, /// \anchor System_IsStandalone /// _boolean_, /// @return **True** if Kodi is running in standalone mode. ///

/// } /// \table_row3{ `System.IsFullscreen`, /// \anchor System_IsFullscreen /// _boolean_, /// @return **True** if Kodi is running fullscreen. ///

/// } /// \table_row3{ `System.LoggedOn`, /// \anchor System_LoggedOn /// _boolean_, /// @return **True** if a user is currently logged on under a profile. ///

/// } /// \table_row3{ `System.HasLoginScreen`, /// \anchor System_HasLoginScreen /// _boolean_, /// @return **True** if the profile login screen is enabled. ///

/// } /// \table_row3{ `System.HasPVR`, /// \anchor System_HasPVR /// _boolean_, /// @return **True** if PVR is supported from Kodi. /// @note normally always true /// /// } /// \table_row3{ `System.HasPVRAddon`, /// \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 ///


/// @skinning_v17 **[New Boolean Condition]** \link System_HasPVRAddon /// `System.HasPVRAddon`\endlink

/// } /// \table_row3{ `System.HasCMS`, /// \anchor System_HasCMS /// _boolean_, /// @return **True** if colour management is supported from Kodi. /// @note currently only supported for OpenGL ///


/// @skinning_v17 **[New Boolean Condition]** \link System_HasCMS `System.HasCMS`\endlink ///

/// } /// \table_row3{ `System.HasActiveModalDialog`, /// \anchor System_HasActiveModalDialog /// _boolean_, /// @return **True** if a modal dialog is active. ///


/// @skinning_v18 **[New Boolean Condition]** \link System_HasActiveModalDialog /// `System.HasActiveModalDialog`\endlink

/// } /// \table_row3{ `System.HasVisibleModalDialog`, /// \anchor System_HasVisibleModalDialog /// _boolean_, /// @return **True** if a modal dialog is visible. ///


/// @skinning_v18 **[New Boolean Condition]** \link System_HasVisibleModalDialog /// `System.HasVisibleModalDialog`\endlink

/// } /// \table_row3{ `System.Platform.Linux`, /// \anchor System_PlatformLinux /// _boolean_, /// @return **True** if Kodi is running on a linux/unix based computer. ///

/// } /// \table_row3{ `System.Platform.Windows`, /// \anchor System_PlatformWindows /// _boolean_, /// @return **True** if Kodi is running on a windows based computer. ///

/// } /// \table_row3{ `System.Platform.UWP`, /// \anchor System_PlatformUWP /// _boolean_, /// @return **True** if Kodi is running on Universal Windows Platform (UWP). ///


/// @skinning_v18 **[New Boolean Condition]** \link System_PlatformUWP /// `System.Platform.UWP`\endlink

/// } /// \table_row3{ `System.Platform.OSX`, /// \anchor System_PlatformOSX /// _boolean_, /// @return **True** if Kodi is running on an OSX based computer. ///

/// } /// \table_row3{ `System.Platform.IOS`, /// \anchor System_PlatformIOS /// _boolean_, /// @return **True** if Kodi is running on an IOS device. ///

/// } /// \table_row3{ `System.Platform.TVOS`, /// \anchor System_PlatformTVOS /// _boolean_, /// @return **True** if Kodi is running on a tvOS device. ///


/// @skinning_v19 **[New Boolean Condition]** \link System_PlatformTVOS /// `System.Platform.TVOS`\endlink

/// } /// \table_row3{ `System.Platform.Darwin`, /// \anchor System_PlatformDarwin /// _boolean_, /// @return **True** if Kodi is running on an OSX or IOS system. ///

/// } /// \table_row3{ `System.Platform.Android`, /// \anchor System_PlatformAndroid /// _boolean_, /// @return **True** if Kodi is running on an android device. ///

/// } /// \table_row3{ `System.CanPowerDown`, /// \anchor System_CanPowerDown /// _boolean_, /// @return **True** if Kodi can powerdown the system. ///

/// } /// \table_row3{ `System.CanSuspend`, /// \anchor System_CanSuspend /// _boolean_, /// @return **True** if Kodi can suspend the system. ///

/// } /// \table_row3{ `System.CanHibernate`, /// \anchor System_CanHibernate /// _boolean_, /// @return **True** if Kodi can hibernate the system. ///

/// } /// \table_row3{ `System.HasHiddenInput`, /// \anchor System_HasHiddenInput /// _boolean_, /// @return **True** when to osd keyboard/numeric dialog requests a /// password/pincode. ///


/// @skinning_v16 **[New Boolean Condition]** \link System_HasHiddenInput /// `System.HasHiddenInput`\endlink

/// } /// \table_row3{ `System.CanReboot`, /// \anchor System_CanReboot /// _boolean_, /// @return **True** if Kodi can reboot the system. ///

/// } /// \table_row3{ `System.ScreenSaverActive`, /// \anchor System_ScreenSaverActive /// _boolean_, /// @return **True** if ScreenSaver is active. ///

/// } /// \table_row3{ `System.IdleShutdownInhibited`, /// \anchor System_IdleShutdownInhibited /// _boolean_, /// @return **True** when shutdown on idle is disabled. ///

/// } /// \table_row3{ `System.HasShutdown`, /// \anchor System_HasShutdown /// _boolean_, /// @return **True** if Kodi can shutdown the system. ///

/// } /// \table_row3{ `System.Time`, /// \anchor System_Time /// _string_, /// @return The current time. ///

/// } /// \table_row3{ `System.Time(format)`, /// \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. ///

/// } /// \table_row3{ `System.Time(startTime[\,endTime])`, /// \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 ///

/// @note Time must be specified in the format HH:mm\, using /// a 24 hour clock. ///

/// } /// \table_row3{ `System.Date`, /// \anchor System_Date /// _string_, /// @return The current date. ///


/// @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 ///

/// } /// \table_row3{ `System.Date(format)`, /// \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 ///

/// } /// \table_row3{ `System.Date(startDate[\,endDate])`, /// \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. ///

/// } /// \table_row3{ `System.AlarmPos`, /// \anchor System_AlarmPos /// _string_, /// @return The shutdown Timer position. ///

/// } /// \table_row3{ `System.BatteryLevel`, /// \anchor System_BatteryLevel /// _string_, /// @return The remaining battery level in range 0-100. ///

/// } /// \table_row3{ `System.FreeSpace`, /// \anchor System_FreeSpace /// _string_, /// @return The total Freespace on the drive. ///

/// } /// \table_row3{ `System.UsedSpace`, /// \anchor System_UsedSpace /// _string_, /// @return The total Usedspace on the drive. ///

/// } /// \table_row3{ `System.TotalSpace`, /// \anchor System_TotalSpace /// _string_, /// @return The total space on the drive. ///

/// } /// \table_row3{ `System.UsedSpacePercent`, /// \anchor System_UsedSpacePercent /// _string_, /// @return The total Usedspace Percent on the drive. ///

/// } /// \table_row3{ `System.FreeSpacePercent`, /// \anchor System_FreeSpacePercent /// _string_, /// @return The total Freespace Percent on the drive. ///

/// } /// \table_row3{ `System.CPUTemperature`, /// \anchor System_CPUTemperature /// _string_, /// @return The current CPU temperature. ///

/// } /// \table_row3{ `System.CpuUsage`, /// \anchor System_CpuUsage /// _string_, /// @return The the cpu usage for each individual cpu core. ///

/// } /// \table_row3{ `System.GPUTemperature`, /// \anchor System_GPUTemperature /// _string_, /// @return The current GPU temperature. ///

/// } /// \table_row3{ `System.FanSpeed`, /// \anchor System_FanSpeed /// _string_, /// @return The current fan speed. ///

/// } /// \table_row3{ `System.BuildVersion`, /// \anchor System_BuildVersion /// _string_, /// @return The version of build. ///

/// } /// \table_row3{ `System.BuildVersionShort`, /// \anchor System_BuildVersionShort /// _string_, /// @return The shorter string with version of build. ///

/// } /// \table_row3{ `System.BuildDate`, /// \anchor System_BuildDate /// _string_, /// @return The date of build. ///

/// } /// \table_row3{ `System.BuildVersionCode`, /// \anchor System_BuildVersionCode /// _string_, /// @return The version code of build. ///

/// } /// \table_row3{ `System.BuildVersionGit`, /// \anchor System_BuildVersionGit /// _string_, /// @return The git version of build. ///

/// } /// \table_row3{ `System.FriendlyName`, /// \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)" ///

/// } /// \table_row3{ `System.FPS`, /// \anchor System_FPS /// _string_, /// @return The current rendering speed (frames per second). ///

/// } /// \table_row3{ `System.FreeMemory`, /// \anchor System_FreeMemory /// _string_, /// @return The amount of free memory in Mb. ///

/// } /// \table_row3{ `System.ScreenMode`, /// \anchor System_ScreenMode /// _string_, /// @return The screenmode (eg windowed / fullscreen). ///

/// } /// \table_row3{ `System.ScreenWidth`, /// \anchor System_ScreenWidth /// _string_, /// @return The width of screen in pixels. ///

/// } /// \table_row3{ `System.ScreenHeight`, /// \anchor System_ScreenHeight /// _string_, /// @return The height of screen in pixels. ///

/// } /// \table_row3{ `System.StartupWindow`, /// \anchor System_StartupWindow /// _string_, /// @return The Window Kodi will load on startup. ///


/// @skinning_v13 **[New Infolabel]** \link System_StartupWindow `System.StartupWindow`\endlink ///

/// } /// \table_row3{ `System.CurrentWindow`, /// \anchor System_CurrentWindow /// _string_, /// @return The current Window in use. ///

/// } /// \table_row3{ `System.CurrentControl`, /// \anchor System_CurrentControl /// _string_, /// @return The current focused control ///

/// } /// \table_row3{ `System.CurrentControlId`, /// \anchor System_CurrentControlId /// _string_, /// @return The ID of the currently focused control. ///

/// } /// \table_row3{ `System.DVDLabel`, /// \anchor System_DVDLabel /// _string_, /// @return the label of the disk in the DVD-ROM drive. ///

/// } /// \table_row3{ `System.KernelVersion`, /// \anchor System_KernelVersion /// _string_, /// @return The System kernel version. ///

/// } /// \table_row3{ `System.OSVersionInfo`, /// \anchor System_OSVersionInfo /// _string_, /// @return The system name + kernel version. ///

/// } /// \table_row3{ `System.Uptime`, /// \anchor System_Uptime /// _string_, /// @return The system current uptime. ///

/// } /// \table_row3{ `System.TotalUptime`, /// \anchor System_TotalUptime /// _string_, /// @return The system total uptime. ///

/// } /// \table_row3{ `System.CpuFrequency`, /// \anchor System_CpuFrequency /// _string_, /// @return The system cpu frequency. ///

/// } /// \table_row3{ `System.ScreenResolution`, /// \anchor System_ScreenResolution /// _string_, /// @return The screen resolution. ///

/// } /// \table_row3{ `System.VideoEncoderInfo`, /// \anchor System_VideoEncoderInfo /// _string_, /// @return The video encoder info. ///

/// } /// \table_row3{ `System.InternetState`, /// \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. ///

/// } /// \table_row3{ `System.Language`, /// \anchor System_Language /// _string_, /// @return the current language. ///

/// } /// \table_row3{ `System.ProfileName`, /// \anchor System_ProfileName /// _string_, /// @return The user name of the currently logged in Kodi user ///

/// } /// \table_row3{ `System.ProfileThumb`, /// \anchor System_ProfileThumb /// _string_, /// @return The thumbnail image of the currently logged in Kodi user ///

/// } /// \table_row3{ `System.ProfileCount`, /// \anchor System_ProfileCount /// _string_, /// @return The number of defined profiles. ///

/// } /// \table_row3{ `System.ProfileAutoLogin`, /// \anchor System_ProfileAutoLogin /// _string_, /// @return The profile Kodi will auto login to. ///


/// @skinning_v13 **[New Infolabel]** \link System_ProfileAutoLogin /// `System.ProfileAutoLogin`\endlink

/// } /// \table_row3{ `System.StereoscopicMode`, /// \anchor System_StereoscopicMode /// _string_, /// @return The preferred stereoscopic mode. /// @note Configured in settings > video > playback). ///


/// @skinning_v13 **[New Infolabel]** \link System_StereoscopicMode /// `System.StereoscopicMode`\endlink

/// } /// \table_row3{ `System.TemperatureUnits`, /// \anchor System_TemperatureUnits /// _string_, /// @return the Celsius or the Fahrenheit symbol. ///

/// } /// \table_row3{ `System.Progressbar`, /// \anchor System_Progressbar /// _string_, /// @return The percentage of the currently active progress. ///

/// } /// \table_row3{ `System.GetBool(boolean)`, /// \anchor System_GetBool /// _string_, /// @return The value of any standard system boolean setting. /// @note Will not work with settings in advancedsettings.xml ///

/// } /// \table_row3{ `System.Memory(type)`, /// \anchor System_Memory /// _string_, /// @return The memory value depending on the requested type. /// @param type - Can be one of the following: /// - free /// - free.percent /// - used /// - used.percent /// - total ///

/// } /// \table_row3{ `System.AddonTitle(id)`, /// \anchor System_AddonTitle /// _string_, /// @return The title of the addon with the given id /// @param id - the addon id ///

/// } /// \table_row3{ `System.AddonVersion(id)`, /// \anchor System_AddonVersion /// _string_, /// @return The version of the addon with the given id. /// @param id - the addon id ///


/// @skinning_v13 **[New Infolabel]** \link System_AddonVersion /// `System.AddonVersion(id)`\endlink

/// } /// \table_row3{ `System.AddonIcon(id)`, /// \anchor System_AddonVersion /// _string_, /// @return The icon of the addon with the given id. /// @param id - the addon id ///

/// } /// \table_row3{ `System.AddonUpdateCount`, /// \anchor System_AddonUpdateCount /// _string_, /// @return The number of available addon updates. ///


/// @skinning_v19 **[New Infolabel]** \link System_AddonUpdateCount ` /// System.AddonUpdateCount`\endlink

/// } /// \table_row3{ `System.IdleTime(time)`, /// \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. ///

/// } /// \table_row3{ `System.PrivacyPolicy`, /// \anchor System_PrivacyPolicy /// _string_, /// @return The official Kodi privacy policy. ///


/// @skinning_v17 **[New Infolabel]** \link System_PrivacyPolicy `System.PrivacyPolicy`\endlink ///

/// } /// \table_row3{ `System.SupportsCPUUsage`, /// \anchor System_SupportsCPUUsage /// _boolean_, /// @return **True** if the system can provide CPU usage information. ///


/// @skinning_v19 **[New Boolean Condition]** \link System_SupportsCPUUsage ` /// System.SupportsCPUUsage`\endlink

/// } /// \table_row3{ `System.SupportedHDRTypes`, /// \anchor System_SupportedHDRTypes /// _string_, /// @return The display's supported HDR types. ///


/// @skinning_v20 **[New Infolabel]** \link System_SupportedHDRTypes `System.SupportedHDRTypes`\endlink ///

/// } /// \table_row3{ `System.IsScreensaverInhibited`, /// \anchor System_IsScreensaverInhibited /// _boolean_, /// @return **True** when screensaver on idle is disabled. ///

/// } 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{ `System.HasAddon(id)`, /// \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 ///

/// } /// \table_row3{ `System.AddonIsEnabled(id)`, /// \anchor System_AddonIsEnabled /// _boolean_, /// @return **True** if the specified addon is enabled on the system. /// @param id - The addon Id ///


/// @skinning_v19 **[New Boolean Condition]** \link System_AddonIsEnabled `System.AddonIsEnabled(id)`\endlink ///

/// } /// \table_row3{ `System.HasCoreId(id)`, /// \anchor System_HasCoreId /// _boolean_, /// @return **True** if the CPU core with the given 'id' exists. /// @param id - the id of the CPU core ///

/// } /// \table_row3{ `System.HasAlarm(alarm)`, /// \anchor System_HasAlarm /// _boolean_, /// @return **True** if the system has the `alarm` alarm set. /// @param alarm - the name of the alarm ///

/// } /// \table_row3{ `System.CoreUsage(id)`, /// \anchor System_CoreUsage /// _string_, /// @return the usage of the CPU core with the given 'id' /// @param id - the id of the CPU core ///

/// } /// \table_row3{ `System.Setting(hidewatched)`, /// \anchor System_Setting /// _boolean_, /// @return **True** if 'hide watched items' is selected. ///

/// } /// \table_row3{ `System.Setting(hideunwatchedepisodethumbs)`, /// \anchor System_Setting_HideUnwatchedEpisodeThumbs /// _boolean_, /// @return **True** if 'hide unwatched episode setting is enabled'\, **False** otherwise. ///


/// @skinning_v20 **[New Boolean Condition]** \link System_Setting_HideUnwatchedEpisodeThumbs `System.Setting(hideunwatchedepisodethumbs)`\endlink ///

/// } /// \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{ `Network.IsDHCP`, /// \anchor Network_IsDHCP /// _boolean_, /// @return **True** if the network type is DHCP. /// @note Network type can be either DHCP or FIXED ///

/// } /// \table_row3{ `Network.IPAddress`, /// \anchor Network_IPAddress /// _string_, /// @return The system's IP Address. e.g. 192.168.1.15 ///

/// } /// \table_row3{ `Network.LinkState`, /// \anchor Network_LinkState /// _string_, /// @return The network linkstate e.g. 10mbit/100mbit etc. ///

/// } /// \table_row3{ `Network.MacAddress`, /// \anchor Network_MacAddress /// _string_, /// @return The system's MAC address. ///

/// } /// \table_row3{ `Network.SubnetMask`, /// \anchor Network_SubnetMask /// _string_, /// @return The network subnet mask. ///

/// } /// \table_row3{ `Network.GatewayAddress`, /// \anchor Network_GatewayAddress /// _string_, /// @return The network gateway address. ///

/// } /// \table_row3{ `Network.DNS1Address`, /// \anchor Network_DNS1Address /// _string_, /// @return The network DNS 1 address. ///

/// } /// \table_row3{ `Network.DNS2Address`, /// \anchor Network_DNS2Address /// _string_, /// @return The network DNS 2 address. ///

/// } /// \table_row3{ `Network.DHCPAddress`, /// \anchor Network_DHCPAddress /// _string_, /// @return The DHCP IP address. ///

/// } /// \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{ `MusicPartyMode.Enabled`, /// \anchor MusicPartyMode_Enabled /// _boolean_, /// @return **True** if Party Mode is enabled. ///

/// } /// \table_row3{ `MusicPartyMode.SongsPlayed`, /// \anchor MusicPartyMode_SongsPlayed /// _string_, /// @return The number of songs played during Party Mode. ///

/// } /// \table_row3{ `MusicPartyMode.MatchingSongs`, /// \anchor MusicPartyMode_MatchingSongs /// _string_, /// @return The number of songs available to Party Mode. ///

/// } /// \table_row3{ `MusicPartyMode.MatchingSongsPicked`, /// \anchor MusicPartyMode_MatchingSongsPicked /// _string_, /// @return The number of songs picked already for Party Mode. ///

/// } /// \table_row3{ `MusicPartyMode.MatchingSongsLeft`, /// \anchor MusicPartyMode_MatchingSongsLeft /// _string_, /// @return The number of songs left to be picked from for Party Mode. ///

/// } /// \table_row3{ `MusicPartyMode.RelaxedSongsPicked`, /// \anchor MusicPartyMode_RelaxedSongsPicked /// _string_, /// @todo Not currently used ///

/// } /// \table_row3{ `MusicPartyMode.RandomSongsPicked`, /// \anchor MusicPartyMode_RandomSongsPicked /// _string_, /// @return The number of unique random songs picked during Party Mode. ///

/// } /// \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{ `MusicPlayer.Offset(number).Exists`, /// \anchor MusicPlayer_Offset /// _boolean_, /// @return **True** if the music players playlist has a song queued in /// position (number). /// @param number - song position ///

/// } /// \table_row3{ `MusicPlayer.Title`, /// \anchor MusicPlayer_Title /// _string_, /// @return The title of the currently playing song. ///

/// } /// \table_row3{ `MusicPlayer.offset(number).Title`, /// \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 ///

/// } /// \table_row3{ `MusicPlayer.Position(number).Title`, /// \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 ///

/// } /// \table_row3{ `MusicPlayer.Album`, /// \anchor MusicPlayer_Album /// _string_, /// @return The album from which the current song is from. ///

/// } /// \table_row3{ `MusicPlayer.offset(number).Album`, /// \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 ///

/// } /// \table_row3{ `MusicPlayer.Position(number).Album`, /// \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 ///

/// } /// \table_row3{ `MusicPlayer.Property(Album_Mood)`, /// \anchor MusicPlayer_Property_Album_Mood /// _string_, /// @return The moods of the currently playing Album ///

/// } /// \table_row3{ `MusicPlayer.Property(Role.Composer)`, /// \anchor MusicPlayer_Property_Role_Composer /// _string_, /// @return The name of the person who composed the selected song. ///


/// @skinning_v17 **[New Infolabel]** \link MusicPlayer_Property_Role_Composer `MusicPlayer.Property(Role.Composer)`\endlink ///

/// } /// \table_row3{ `MusicPlayer.Property(Role.Conductor)`, /// \anchor MusicPlayer_Property_Role_Conductor /// _string_, /// @return The name of the person who conducted the selected song. ///


/// @skinning_v17 **[New Infolabel]** \link MusicPlayer_Property_Role_Conductor `MusicPlayer.Property(Role.Conductor)`\endlink ///

/// } /// \table_row3{ `MusicPlayer.Property(Role.Orchestra)`, /// \anchor MusicPlayer_Property_Role_Orchestra /// _string_, /// @return The name of the orchestra performing the selected song. ///


/// @skinning_v17 **[New Infolabel]** \link MusicPlayer_Property_Role_Orchestra `MusicPlayer.Property(Role.Orchestra)`\endlink ///

/// } /// \table_row3{ `MusicPlayer.Property(Role.Lyricist)`, /// \anchor MusicPlayer_Property_Role_Lyricist /// _string_, /// @return The name of the person who wrote the lyrics of the selected song. ///


/// @skinning_v17 **[New Infolabel]** \link MusicPlayer_Property_Role_Lyricist `MusicPlayer.Property(Role.Lyricist)`\endlink ///

/// } /// \table_row3{ `MusicPlayer.Property(Role.Remixer)`, /// \anchor MusicPlayer_Property_Role_Remixer /// _string_, /// @return The name of the person who remixed the selected song. ///


/// @skinning_v17 **[New Infolabel]** \link MusicPlayer_Property_Role_Remixer `MusicPlayer.Property(Role.Remixer)`\endlink ///

/// } /// \table_row3{ `MusicPlayer.Property(Role.Arranger)`, /// \anchor MusicPlayer_Property_Role_Arranger /// _string_, /// @return The name of the person who arranged the selected song. ///


/// @skinning_v17 **[New Infolabel]** \link MusicPlayer_Property_Role_Arranger `MusicPlayer.Property(Role.Arranger)`\endlink ///

/// } /// \table_row3{ `MusicPlayer.Property(Role.Engineer)`, /// \anchor MusicPlayer_Property_Role_Engineer /// _string_, /// @return The name of the person who was the engineer of the selected song. ///


/// @skinning_v17 **[New Infolabel]** \link MusicPlayer_Property_Role_Engineer `MusicPlayer.Property(Role.Engineer)`\endlink ///

/// } /// \table_row3{ `MusicPlayer.Property(Role.Producer)`, /// \anchor MusicPlayer_Property_Role_Producer /// _string_, /// @return The name of the person who produced the selected song. ///


/// @skinning_v17 **[New Infolabel]** \link MusicPlayer_Property_Role_Producer `MusicPlayer.Property(Role.Producer)`\endlink ///

/// } /// \table_row3{ `MusicPlayer.Property(Role.DJMixer)`, /// \anchor MusicPlayer_Property_Role_DJMixer /// _string_, /// @return The name of the dj who remixed the selected song. ///


/// @skinning_v17 **[New Infolabel]** \link MusicPlayer_Property_Role_DJMixer `MusicPlayer.Property(Role.DJMixer)`\endlink ///

/// } /// \table_row3{ `MusicPlayer.Property(Role.Mixer)`, /// \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. ///


/// @skinning_v17 **[New Infolabel]** \link MusicPlayer_Property_Role_Mixer `MusicPlayer.Property(Role.Mixer)`\endlink ///

/// } /// \table_row3{ `MusicPlayer.Property(Album_Mood)`, /// \anchor MusicPlayer_Property_Album_Mood /// _string_, /// @return the moods of the currently playing Album ///

/// } /// \table_row3{ `MusicPlayer.Property(Album_Style)`, /// \anchor MusicPlayer_Property_Album_Style /// _string_, /// @return the styles of the currently playing Album. ///

/// } /// \table_row3{ `MusicPlayer.Property(Album_Theme)`, /// \anchor MusicPlayer_Property_Album_Theme /// _string_, /// @return The themes of the currently playing Album ///

/// } /// \table_row3{ `MusicPlayer.Property(Album_Type)`, /// \anchor MusicPlayer_Property_Album_Type /// _string_, /// @return The album type (e.g. compilation\, enhanced\, explicit lyrics) of the /// currently playing album. ///

/// } /// \table_row3{ `MusicPlayer.Property(Album_Label)`, /// \anchor MusicPlayer_Property_Album_Label /// _string_, /// @return The record label of the currently playing album. ///

/// } /// \table_row3{ `MusicPlayer.Property(Album_Description)`, /// \anchor MusicPlayer_Property_Album_Description /// _string_, /// @return A review of the currently playing album ///

/// } /// \table_row3{ `MusicPlayer.Artist`, /// \anchor MusicPlayer_Artist /// _string_, /// @return Artist(s) of current song. ///

/// } /// \table_row3{ `MusicPlayer.offset(number).Artist`, /// \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 ///

/// } /// \table_row3{ `MusicPlayer.Position(number).Artist`, /// \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 ///

/// } /// \table_row3{ `MusicPlayer.AlbumArtist`, /// \anchor MusicPlayer_AlbumArtist /// _string_, /// @return The album artist of the currently playing song. ///

/// } /// \table_row3{ `MusicPlayer.Cover`, /// \anchor MusicPlayer_Cover /// _string_, /// @return The album cover of currently playing song. ///

/// } /// \table_row3{ `MusicPlayer.Property(Artist_Sortname)`, /// \anchor MusicPlayer_Property_Artist_Sortname /// _string_, /// @return The sortname of the currently playing Artist. ///


/// @skinning_v18 **[New Infolabel]** \link MusicPlayer_Property_Artist_Sortname `MusicPlayer.Property(Artist_Sortname)`\endlink ///

/// } /// \table_row3{ `MusicPlayer.Property(Artist_Type)`, /// \anchor MusicPlayer_Property_Artist_Type /// _string_, /// @return The type of the currently playing Artist - person\, /// group\, orchestra\, choir etc. ///


/// @skinning_v18 **[New Infolabel]** \link MusicPlayer_Property_Artist_Type `MusicPlayer.Property(Artist_Type)`\endlink ///

/// } /// \table_row3{ `MusicPlayer.Property(Artist_Gender)`, /// \anchor MusicPlayer_Property_Artist_Gender /// _string_, /// @return The gender of the currently playing Artist - male\, /// female\, other. ///


/// @skinning_v18 **[New Infolabel]** \link MusicPlayer_Property_Artist_Gender `MusicPlayer.Property(Artist_Gender)`\endlink ///

/// } /// \table_row3{ `MusicPlayer.Property(Artist_Disambiguation)`, /// \anchor MusicPlayer_Property_Artist_Disambiguation /// _string_, /// @return A brief description of the currently playing Artist that differentiates them /// from others with the same name. ///


/// @skinning_v18 **[New Infolabel]** \link MusicPlayer_Property_Artist_Disambiguation `MusicPlayer.Property(Artist_Disambiguation)`\endlink ///

/// } /// \table_row3{ `MusicPlayer.Property(Artist_Born)`, /// \anchor MusicPlayer_Property_Artist_Born /// _string_, /// @return The date of Birth of the currently playing Artist. ///

/// } /// \table_row3{ `MusicPlayer.Property(Artist_Died)`, /// \anchor MusicPlayer_Property_Artist_Died /// _string_, /// @return The date of Death of the currently playing Artist. ///

/// } /// \table_row3{ `MusicPlayer.Property(Artist_Formed)`, /// \anchor MusicPlayer_Property_Artist_Formed /// _string_, /// @return The Formation date of the currently playing Artist/Band. ///

/// } /// \table_row3{ `MusicPlayer.Property(Artist_Disbanded)`, /// \anchor MusicPlayer_Property_Artist_Disbanded /// _string_, /// @return The disbanding date of the currently playing Artist/Band. ///

/// } /// \table_row3{ `MusicPlayer.Property(Artist_YearsActive)`, /// \anchor MusicPlayer_Property_Artist_YearsActive /// _string_, /// @return The years the currently Playing artist has been active. ///

/// } /// \table_row3{ `MusicPlayer.Property(Artist_Instrument)`, /// \anchor MusicPlayer_Property_Artist_Instrument /// _string_, /// @return The instruments played by the currently playing artist. ///

/// } /// \table_row3{ `MusicPlayer.Property(Artist_Description)`, /// \anchor MusicPlayer_Property_Artist_Description /// _string_, /// @return A biography of the currently playing artist. ///

/// } /// \table_row3{ `MusicPlayer.Property(Artist_Mood)`, /// \anchor MusicPlayer_Property_Artist_Mood /// _string_, /// @return The moods of the currently playing artist. ///

/// } /// \table_row3{ `MusicPlayer.Property(Artist_Style)`, /// \anchor MusicPlayer_Property_Artist_Style /// _string_, /// @return The styles of the currently playing artist. ///

/// } /// \table_row3{ `MusicPlayer.Property(Artist_Genre)`, /// \anchor MusicPlayer_Property_Artist_Genre /// _string_, /// @return The genre of the currently playing artist. ///

/// } /// \table_row3{ `MusicPlayer.Genre`, /// \anchor MusicPlayer_Genre /// _string_, /// @return The genre(s) of current song. ///

/// } /// \table_row3{ `MusicPlayer.offset(number).Genre`, /// \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. ///

/// } /// \table_row3{ `MusicPlayer.Position(number).Genre`, /// \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. ///

/// } /// \table_row3{ `MusicPlayer.Lyrics`, /// \anchor MusicPlayer_Lyrics /// _string_, /// @return The lyrics of current song stored in ID tag info. ///

/// } /// \table_row3{ `MusicPlayer.Year`, /// \anchor MusicPlayer_Year /// _string_, /// @return The year of release of current song. ///

/// } /// \table_row3{ `MusicPlayer.offset(number).Year`, /// \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. ///

/// } /// \table_row3{ `MusicPlayer.Position(number).Year`, /// \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. ///

/// } /// \table_row3{ `MusicPlayer.Rating`, /// \anchor MusicPlayer_Rating /// _string_, /// @return The numeric Rating of current song (1-10). ///

/// } /// \table_row3{ `MusicPlayer.offset(number).Rating`, /// \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 ///

/// } /// \table_row3{ `MusicPlayer.Position(number).Rating`, /// \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 ///

/// } /// \table_row3{ `MusicPlayer.RatingAndVotes`, /// \anchor MusicPlayer_RatingAndVotes /// _string_, /// @return The scraped rating and votes of currently playing song\, if it's in the database. ///

/// } /// \table_row3{ `MusicPlayer.UserRating`, /// \anchor MusicPlayer_UserRating /// _string_, /// @return The scraped rating of the currently playing song (1-10). ///


/// @skinning_v17 **[New Infolabel]** \link MusicPlayer_UserRating `MusicPlayer.UserRating`\endlink ///

/// } /// \table_row3{ `MusicPlayer.Votes`, /// \anchor MusicPlayer_Votes /// _string_, /// @return The scraped votes of currently playing song\, if it's in the database. ///

/// } /// \table_row3{ `MusicPlayer.DiscNumber`, /// \anchor MusicPlayer_DiscNumber /// _string_, /// @return The Disc Number of current song stored in ID tag info. ///

/// } /// \table_row3{ `MusicPlayer.offset(number).DiscNumber`, /// \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. ///

/// } /// \table_row3{ `MusicPlayer.Position(number).DiscNumber`, /// \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. ///

/// } /// \table_row3{ `MusicPlayer.Comment`, /// \anchor MusicPlayer_Comment /// _string_, /// @return The Comment of current song stored in ID tag info. ///

/// } /// \table_row3{ `MusicPlayer.offset(number).Comment`, /// \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. ///

/// } /// \table_row3{ `MusicPlayer.Position(number).Comment`, /// \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. ///

/// } /// \table_row3{ `MusicPlayer.Contributors`, /// \anchor MusicPlayer_Contributors /// _string_, /// @return The list of all people who've contributed to the currently playing song ///


/// @skinning_v17 **[New Infolabel]** \link MusicPlayer_Contributors `MusicPlayer.Contributors`\endlink ///

/// } /// \table_row3{ `MusicPlayer.ContributorAndRole`, /// \anchor MusicPlayer_ContributorAndRole /// _string_, /// @return The list of all people and their role who've contributed to the currently playing song. ///


/// @skinning_v17 **[New Infolabel]** \link MusicPlayer_ContributorAndRole `MusicPlayer.ContributorAndRole`\endlink ///

/// } /// \table_row3{ `MusicPlayer.Mood`, /// \anchor MusicPlayer_Mood /// _string_, /// @return The mood of the currently playing song. ///


/// @skinning_v17 **[New Infolabel]** \link MusicPlayer_Mood `MusicPlayer.Mood`\endlink ///

/// } /// \table_row3{ `MusicPlayer.PlaylistPlaying`, /// \anchor MusicPlayer_PlaylistPlaying /// _boolean_, /// @return **True** if a playlist is currently playing. ///

/// } /// \table_row3{ `MusicPlayer.Exists(relative\,position)`, /// \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. ///

/// } /// \table_row3{ `MusicPlayer.HasPrevious`, /// \anchor MusicPlayer_HasPrevious /// _boolean_, /// @return **True** if the music player has a a Previous Song in the Playlist. ///

/// } /// \table_row3{ `MusicPlayer.HasNext`, /// \anchor MusicPlayer_HasNext /// _boolean_, /// @return **True** if the music player has a next song queued in the Playlist. ///

/// } /// \table_row3{ `MusicPlayer.PlayCount`, /// \anchor MusicPlayer_PlayCount /// _integer_, /// @return The play count of currently playing song\, if it's in the database. ///

/// } /// \table_row3{ `MusicPlayer.LastPlayed`, /// \anchor MusicPlayer_LastPlayed /// _string_, /// @return The last play date of currently playing song\, if it's in the database. ///

/// } /// \table_row3{ `MusicPlayer.TrackNumber`, /// \anchor MusicPlayer_TrackNumber /// _string_, /// @return The track number of current song. ///

/// } /// \table_row3{ `MusicPlayer.offset(number).TrackNumber`, /// \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 ///

/// } /// \table_row3{ `MusicPlayer.Position(number).TrackNumber`, /// \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 ///

/// } /// \table_row3{ `MusicPlayer.Duration`, /// \anchor MusicPlayer_Duration /// _string_, /// @return The duration of the current song. ///

/// } /// \table_row3{ `MusicPlayer.offset(number).Duration`, /// \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 ///

/// } /// \table_row3{ `MusicPlayer.Position(number).Duration`, /// \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 ///

/// } /// \table_row3{ `MusicPlayer.BitRate`, /// \anchor MusicPlayer_BitRate /// _string_, /// @return The bitrate of current song. ///

/// } /// \table_row3{ `MusicPlayer.Channels`, /// \anchor MusicPlayer_Channels /// _string_, /// @return The number of channels of current song. ///

/// } /// \table_row3{ `MusicPlayer.BitsPerSample`, /// \anchor MusicPlayer_BitsPerSample /// _string_, /// @return The number of bits per sample of current song. ///

/// } /// \table_row3{ `MusicPlayer.SampleRate`, /// \anchor MusicPlayer_SampleRate /// _string_, /// @return The samplerate of current playing song. ///

/// } /// \table_row3{ `MusicPlayer.Codec`, /// \anchor MusicPlayer_Codec /// _string_, /// @return The codec of current playing song. ///

/// } /// \table_row3{ `MusicPlayer.PlaylistPosition`, /// \anchor MusicPlayer_PlaylistPosition /// _string_, /// @return The position of the current song in the current music playlist. ///

/// } /// \table_row3{ `MusicPlayer.PlaylistLength`, /// \anchor MusicPlayer_PlaylistLength /// _string_, /// @return The total size of the current music playlist. ///

/// } /// \table_row3{ `MusicPlayer.ChannelName`, /// \anchor MusicPlayer_ChannelName /// _string_, /// @return The channel name of the radio programme that's currently playing (PVR). ///

/// } /// \table_row3{ `MusicPlayer.ChannelNumberLabel`, /// \anchor MusicPlayer_ChannelNumberLabel /// _string_, /// @return The channel and subchannel number of the radio channel that's currently /// playing (PVR). ///


/// @skinning_v14 **[New Infolabel]** \link MusicPlayer_ChannelNumberLabel `MusicPlayer.ChannelNumberLabel`\endlink ///

/// } /// \table_row3{ `MusicPlayer.ChannelGroup`, /// \anchor MusicPlayer_ChannelGroup /// _string_, /// @return The channel group of the radio programme that's currently playing (PVR). ///

/// } /// \table_row3{ `MusicPlayer.Property(propname)`, /// \anchor MusicPlayer_Property_Propname /// _string_, /// @return The requested property value of the currently playing item. /// @param propname - The requested property ///

/// } /// \table_row3{ `MusicPlayer.DBID`, /// \anchor MusicPlayer_DBID /// _string_, /// @return The database id of the currently playing song. ///


/// @skinning_v17 **[New Infolabel]** \link MusicPlayer_DBID `MusicPlayer.DBID`\endlink ///

/// } /// \table_row3{ `MusicPlayer.DiscTitle`, /// \anchor MusicPlayer_DiscTitle /// _string_, /// @return The title of the disc currently playing. ///


/// @skinning_v19 **[New Infolabel]** \link MusicPlayer_DiscTitle `MusicPlayer.DiscTitle`\endlink ///

/// } /// \table_row3{ `MusicPlayer.ReleaseDate`, /// \anchor MusicPlayer_ReleaseDate /// _string_, /// @return The release date of the song currently playing. ///


/// @skinning_v19 **[New Infolabel]** \link MusicPlayer_ReleaseDate `MusicPlayer.ReleaseDate`\endlink ///

/// } /// \table_row3{ `MusicPlayer.OriginalDate`, /// \anchor MusicPlayer_OriginalDate /// _string_, /// @return The original release date of the song currently playing. ///


/// @skinning_v19 **[New Infolabel]** \link MusicPlayer_OriginalDate `MusicPlayer.OriginalDate`\endlink ///

/// } /// \table_row3{ `MusicPlayer.BPM`, /// \anchor MusicPlayer_BPM /// _string_, /// @return The bpm of the track currently playing. ///


/// @skinning_v19 **[New Infolabel]** \link MusicPlayer_BPM `MusicPlayer.BPM`\endlink ///

/// } /// \table_row3{ `MusicPlayer.IsMultiDisc`, /// \anchor MusicPlayer_IsMultiDisc /// _boolean_, /// @return Returns **true** if the album currently playing has more than one disc. ///


/// @skinning_v19 **[New Infolabel]** \link MusicPlayer_IsMultiDisc `MusicPlayer.IsMultiDisc`\endlink ///

/// } /// \table_row3{ `MusicPlayer.TotalDiscs`, /// \anchor MusicPlayer_TotalDiscs /// _string_, /// @return The number of discs associated with the currently playing album. ///


/// @skinning_v19 **[New Infolabel]** \link MusicPlayer_TotalDiscs `MusicPlayer.TotalDiscs`\endlink ///

/// } /// \table_row3{ `MusicPlayer.Station`, /// \anchor MusicPlayer_Station /// _string_, /// @return The name of the radio station currently playing (if available). ///


/// @skinning_v19 **[New Infolabel]** \link MusicPlayer_Station `MusicPlayer.Station`\endlink ///

/// } /// \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{ `VideoPlayer.UsingOverlays`, /// \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. ///

/// } /// \table_row3{ `VideoPlayer.IsFullscreen`, /// \anchor VideoPlayer_IsFullscreen /// _boolean_, /// @return **True** if the video player is in fullscreen mode. ///

/// } /// \table_row3{ `VideoPlayer.HasMenu`, /// \anchor VideoPlayer_HasMenu /// _boolean_, /// @return **True** if the video player has a menu (ie is playing a DVD). ///

/// } /// \table_row3{ `VideoPlayer.HasInfo`, /// \anchor VideoPlayer_HasInfo /// _boolean_, /// @return **True** if the current playing video has information from the /// library or from a plugin (eg director/plot etc.) ///

/// } /// \table_row3{ `VideoPlayer.Content(parameter)`, /// \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: /// - files /// - movies /// - episodes /// - musicvideos /// - livetv ///

/// } /// \table_row3{ `VideoPlayer.HasSubtitles`, /// \anchor VideoPlayer_HasSubtitles /// _boolean_, /// @return **True** if there are subtitles available for video. ///

/// } /// \table_row3{ `VideoPlayer.HasTeletext`, /// \anchor VideoPlayer_HasTeletext /// _boolean_, /// @return **True** if teletext is usable on played TV channel. ///

/// } /// \table_row3{ `VideoPlayer.IsStereoscopic`, /// \anchor VideoPlayer_IsStereoscopic /// _boolean_, /// @return **True** when the currently playing video is a 3D (stereoscopic) /// video. ///


/// @skinning_v13 **[New Boolean Condition]** \link VideoPlayer_IsStereoscopic `VideoPlayer.IsStereoscopic`\endlink ///

/// } /// \table_row3{ `VideoPlayer.SubtitlesEnabled`, /// \anchor VideoPlayer_SubtitlesEnabled /// _boolean_, /// @return **True** if subtitles are turned on for video. ///

/// } /// \table_row3{ `VideoPlayer.HasEpg`, /// \anchor VideoPlayer_HasEpg /// _boolean_, /// @return **True** if epg information is available for the currently playing /// programme (PVR). ///

/// } /// \table_row3{ `VideoPlayer.CanResumeLiveTV`, /// \anchor VideoPlayer_CanResumeLiveTV /// _boolean_, /// @return **True** if a in-progress PVR recording is playing an the respective /// live TV channel is available. ///

/// } /// \table_row3{ `VideoPlayer.Title`, /// \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. ///

/// } /// \table_row3{ `VideoPlayer.offset(number).Title`, /// \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. ///


/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Offset_Title `VideoPlayer.offset(number).Title`\endlink ///

/// } /// \table_row3{ `VideoPlayer.position(number).Title`, /// \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. ///


/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Position_Title `VideoPlayer.position(number).Title`\endlink ///

/// } /// \table_row3{ `VideoPlayer.OriginalTitle`, /// \anchor VideoPlayer_OriginalTitle /// _string_, /// @return The original title of currently playing video. If it's in the database. ///

/// } /// \table_row3{ `VideoPlayer.offset(number).OriginalTitle`, /// \anchor VideoPlayer_Offset_OriginalTitle /// _string_, /// @return The original title of the video which has an offset `number` with respect to the currently playing video. ///


/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Offset_OriginalTitle `VideoPlayer.offset(number).OriginalTitle`\endlink ///

/// } /// \table_row3{ `VideoPlayer.position(number).OriginalTitle`, /// \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. ///


/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Position_OriginalTitle `VideoPlayer.position(number).OriginalTitle`\endlink ///

/// } /// \table_row3{ `VideoPlayer.TVShowTitle`, /// \anchor VideoPlayer_TVShowTitle /// _string_, /// @return The title of currently playing episode's tvshow name. ///

/// } /// \table_row3{ `VideoPlayer.offset(number).TVShowTitle`, /// \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. ///


/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Offset_TVShowTitle `VideoPlayer.offset(number).TVShowTitle`\endlink ///

/// } /// \table_row3{ `VideoPlayer.position(number).TVShowTitle`, /// \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. ///


/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Position_TVShowTitle `VideoPlayer.position(number).TVShowTitle`\endlink ///

/// } /// \table_row3{ `VideoPlayer.Season`, /// \anchor VideoPlayer_Season /// _string_, /// @return The season number of the currently playing episode\, if it's in the database. ///


/// @skinning_v15 **[Infolabel Updated]** \link VideoPlayer_Season `VideoPlayer.Season`\endlink /// also supports EPG. ///

/// } /// \table_row3{ `VideoPlayer.offset(number).Season`, /// \anchor VideoPlayer_Offset_Season /// _string_, /// @return The season number of the episode which has an offset `number` with respect to the currently playing video. ///


/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Offset_Season `VideoPlayer.offset(number).Season`\endlink ///

/// } /// \table_row3{ `VideoPlayer.position(number).Season`, /// \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. ///


/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Position_Season `VideoPlayer.position(number).Season`\endlink ///

/// } /// \table_row3{ `VideoPlayer.Episode`, /// \anchor VideoPlayer_Episode /// _string_, /// @return The episode number of the currently playing episode. ///


/// @skinning_v15 **[Infolabel Updated]** \link VideoPlayer_Episode `VideoPlayer.Episode`\endlink /// also supports EPG. ///

/// } /// \table_row3{ `VideoPlayer.offset(number).Episode`, /// \anchor VideoPlayer_Offset_Episode /// _string_, /// @return The episode number of the episode which has an offset `number` with respect to the currently playing video. ///


/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Offset_Episode `VideoPlayer.offset(number).Episode`\endlink ///

/// } /// \table_row3{ `VideoPlayer.position(number).Episode`, /// \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. ///


/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Position_Episode `VideoPlayer.position(number).Episode`\endlink ///

/// } /// \table_row3{ `VideoPlayer.Genre`, /// \anchor VideoPlayer_Genre /// _string_, /// @return The genre(s) of current movie\, if it's in the database. ///

/// } /// \table_row3{ `VideoPlayer.offset(number).Genre`, /// \anchor VideoPlayer_Offset_Genre /// _string_, /// @return The genre(s) of the video which has an offset `number` with respect to the currently playing video. ///


/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Offset_Genre `VideoPlayer.offset(number).Genre`\endlink ///

/// } /// \table_row3{ `VideoPlayer.position(number).Genre`, /// \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. ///


/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Position_Genre `VideoPlayer.position(number).Genre`\endlink ///

/// } /// \table_row3{ `VideoPlayer.Director`, /// \anchor VideoPlayer_Director /// _string_, /// @return The director of current movie\, if it's in the database. ///


/// @skinning_v15 **[Infolabel Updated]** \link VideoPlayer_Director `VideoPlayer.Director`\endlink /// also supports EPG. ///

/// } /// \table_row3{ `VideoPlayer.offset(number).Director`, /// \anchor VideoPlayer_Offset_Director /// _string_, /// @return The director of the video which has an offset `number` with respect to the currently playing video. ///


/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Offset_Director `VideoPlayer.offset(number).VideoPlayer_Offset_Director`\endlink ///

/// } /// \table_row3{ `VideoPlayer.position(number).Director`, /// \anchor VideoPlayer_Position_Director /// _string_, /// @return The director of the video which has an offset `number` with respect to the start of the playlist. ///


/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Position_Director `VideoPlayer.position(number).Director`\endlink ///

/// } /// \table_row3{ `VideoPlayer.Country`, /// \anchor VideoPlayer_Country /// _string_, /// @return The production country of current movie\, if it's in the database. ///

/// } /// \table_row3{ `VideoPlayer.offset(number).Country`, /// \anchor VideoPlayer_Offset_Country /// _string_, /// @return The production country of the video which has an offset `number` with respect to the currently playing video. ///


/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Offset_Country `VideoPlayer.offset(number).Country`\endlink ///

/// } /// \table_row3{ `VideoPlayer.position(number).Country`, /// \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. ///


/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Position_Country `VideoPlayer.position(number).Country`\endlink ///

/// } /// \table_row3{ `VideoPlayer.Year`, /// \anchor VideoPlayer_Year /// _string_, /// @return The year of release of current movie\, if it's in the database. ///

/// } /// \table_row3{ `VideoPlayer.offset(number).Year`, /// \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. ///


/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Offset_Year `VideoPlayer.offset(number).Year`\endlink ///

/// } /// \table_row3{ `VideoPlayer.position(number).Year`, /// \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. ///


/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Position_Year `VideoPlayer.position(number).Year`\endlink ///

/// } /// \table_row3{ `VideoPlayer.Cover`, /// \anchor VideoPlayer_Cover /// _string_, /// @return The cover of currently playing movie. ///

/// } /// \table_row3{ `VideoPlayer.offset(number).Cover`, /// \anchor VideoPlayer_Offset_Cover /// _string_, /// @return The cover of the video which has an offset `number` with respect to the currently playing video. ///


/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Offset_Cover `VideoPlayer.offset(number).Cover`\endlink ///

/// } /// \table_row3{ `VideoPlayer.position(number).Cover`, /// \anchor VideoPlayer_Position_Cover /// _string_, /// @return The cover of the video which has an offset `number` with respect to the start of the playlist. ///


/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Position_Cover `VideoPlayer.position(number).Cover`\endlink ///

/// } /// \table_row3{ `VideoPlayer.Rating`, /// \anchor VideoPlayer_Rating /// _string_, /// @return The scraped rating of current movie\, if it's in the database. ///

/// } /// \table_row3{ `VideoPlayer.offset(number).Rating`, /// \anchor VideoPlayer_Offset_Rating /// _string_, /// @return The scraped rating of the video which has an offset `number` with respect to the currently playing video. ///


/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Offset_Rating `VideoPlayer.offset(number).Rating`\endlink ///

/// } /// \table_row3{ `VideoPlayer.position(number).Rating`, /// \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. ///


/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Position_Rating `VideoPlayer.position(number).Rating`\endlink ///

/// } /// \table_row3{ `VideoPlayer.UserRating`, /// \anchor VideoPlayer_UserRating /// _string_, /// @return The user rating of the currently playing item. ///


/// @skinning_v16 **[New Infolabel]** \link VideoPlayer_UserRating `VideoPlayer.UserRating`\endlink ///

/// } /// \table_row3{ `VideoPlayer.offset(number).UserRating`, /// \anchor VideoPlayer_Offset_UserRating /// _string_, /// @return The user rating of the video which has an offset `number` with respect to the currently playing video. ///


/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Offset_UserRating `VideoPlayer.offset(number).UserRating`\endlink ///

/// } /// \table_row3{ `VideoPlayer.position(number).UserRating`, /// \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. ///


/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Position_UserRating `VideoPlayer.position(number).UserRating`\endlink ///

/// } /// \table_row3{ `VideoPlayer.Votes`, /// \anchor VideoPlayer_Votes /// _string_, /// @return The scraped votes of current movie\, if it's in the database. ///


/// @skinning_v13 **[New Infolabel]** \link VideoPlayer_Votes `VideoPlayer.Votes`\endlink ///

/// } /// \table_row3{ `VideoPlayer.offset(number).Votes`, /// \anchor VideoPlayer_Offset_Votes /// _string_, /// @return The scraped votes of the video which has an offset `number` with respect to the currently playing video. ///


/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Offset_Votes `VideoPlayer.offset(number).Votes`\endlink ///

/// } /// \table_row3{ `VideoPlayer.position(number).Votes`, /// \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. ///


/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Position_Votes `VideoPlayer.position(number).Votes`\endlink ///

/// } /// \table_row3{ `VideoPlayer.RatingAndVotes`, /// \anchor VideoPlayer_RatingAndVotes /// _string_, /// @return The scraped rating and votes of current movie\, if it's in the database ///

/// } /// \table_row3{ `VideoPlayer.offset(number).RatingAndVotes`, /// \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. ///


/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Offset_RatingAndVotes `VideoPlayer.offset(number).RatingAndVotes`\endlink ///

/// } /// \table_row3{ `VideoPlayer.position(number).RatingAndVotes`, /// \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. ///


/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Position_RatingAndVotes `VideoPlayer.position(number).RatingAndVotes`\endlink ///

/// } /// \table_row3{ `VideoPlayer.mpaa`, /// \anchor VideoPlayer_mpaa /// _string_, /// @return The MPAA rating of current movie\, if it's in the database. ///

/// } /// \table_row3{ `VideoPlayer.offset(number).mpaa`, /// \anchor VideoPlayer_Offset_mpaa /// _string_, /// @return The MPAA rating of the video which has an offset `number` with respect to the currently playing video. ///


/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Offset_mpaa `VideoPlayer.offset(number).mpaa`\endlink ///

/// } /// \table_row3{ `VideoPlayer.position(number).mpaa`, /// \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. ///


/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Position_mpaa `VideoPlayer.position(number).mpaa`\endlink ///

/// } /// \table_row3{ `VideoPlayer.Art(type)`, /// \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) ///


/// @skinning_v20 **[New Infolabel]** \link VideoPlayer_art `VideoPlayer.Art(type)`\endlink ///

/// } /// \table_row3{ `VideoPlayer.offset(number).Art(type)`, /// \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) ///


/// @skinning_v20 **[New Infolabel]** \link VideoPlayer_Offset_mpaa `VideoPlayer.offset(number).Art(type)`\endlink ///

/// } /// \table_row3{ `VideoPlayer.position(number).Art(type)`, /// \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) ///


/// @skinning_v20 **[New Infolabel]** \link VideoPlayer_position_art `VideoPlayer.position(number).Art(type)`\endlink ///

/// } /// \table_row3{ `VideoPlayer.IMDBNumber`, /// \anchor VideoPlayer_IMDBNumber /// _string_, /// @return The IMDb ID of the current movie\, if it's in the database. ///


/// @skinning_v15 **[New Infolabel]** \link VideoPlayer_IMDBNumber `VideoPlayer.IMDBNumber`\endlink ///

/// } /// \table_row3{ `VideoPlayer.offset(number).IMDBNumber`, /// \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. ///


/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Offset_IMDBNumber `VideoPlayer.offset(number).IMDBNumber`\endlink ///

/// } /// \table_row3{ `VideoPlayer.position(number).IMDBNumber`, /// \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. ///


/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Position_IMDBNumber `VideoPlayer.position(number).IMDBNumber`\endlink ///

/// } /// \table_row3{ `VideoPlayer.Top250`, /// \anchor VideoPlayer_Top250 /// _string_, /// @return The IMDb Top250 position of the currently playing movie\, if it's in the database. ///

/// } /// \table_row3{ `VideoPlayer.offset(number).Top250`, /// \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. ///


/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Offset_Top250 `VideoPlayer.offset(number).Top250`\endlink ///

/// } /// \table_row3{ `VideoPlayer.position(number).Top250`, /// \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. ///


/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Position_Top250 `VideoPlayer.position(number).Top250`\endlink ///

/// } /// \table_row3{ `VideoPlayer.EpisodeName`, /// \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). ///


/// @skinning_v15 **[New Infolabel]** \link VideoPlayer_EpisodeName `VideoPlayer.EpisodeName`\endlink ///

/// } /// \table_row3{ `VideoPlayer.PlaylistPosition`, /// \anchor VideoPlayer_PlaylistPosition /// _string_, /// @return The position of the current song in the current video playlist. ///

/// } /// \table_row3{ `VideoPlayer.PlaylistLength`, /// \anchor VideoPlayer_PlaylistLength /// _string_, /// @return The total size of the current video playlist. ///

/// } /// \table_row3{ `VideoPlayer.Cast`, /// \anchor VideoPlayer_Cast /// _string_, /// @return A concatenated string of cast members of the current movie\, if it's in /// the database. ///


/// @skinning_v15 **[Infolabel Updated]** \link VideoPlayer_Cast `VideoPlayer.Cast`\endlink /// also supports EPG. ///

/// } /// \table_row3{ `VideoPlayer.CastAndRole`, /// \anchor VideoPlayer_CastAndRole /// _string_, /// @return A concatenated string of cast members and roles of the current movie\, /// if it's in the database. ///

/// } /// \table_row3{ `VideoPlayer.Album`, /// \anchor VideoPlayer_Album /// _string_, /// @return The album from which the current Music Video is from\, if it's in the database. ///

/// } /// \table_row3{ `VideoPlayer.offset(number).Album`, /// \anchor VideoPlayer_Offset_Album /// _string_, /// @return The album from which the video which has an offset `number` with respect to the currently playing video. ///


/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Offset_Album `VideoPlayer.offset(number).Album`\endlink ///

/// } /// \table_row3{ `VideoPlayer.position(number).Album`, /// \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. ///


/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Position_Album `VideoPlayer.position(number).Album`\endlink ///

/// } /// \table_row3{ `VideoPlayer.Artist`, /// \anchor VideoPlayer_Artist /// _string_, /// @return The artist(s) of current Music Video\, if it's in the database. ///

/// } /// \table_row3{ `VideoPlayer.offset(number).Artist`, /// \anchor VideoPlayer_Offset_Artist /// _string_, /// @return The artist(s) of the video which has an offset `number` with respect to the currently playing video. ///


/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Offset_Artist `VideoPlayer.offset(number).Artist`\endlink ///

/// } /// \table_row3{ `VideoPlayer.position(number).Artist`, /// \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. ///


/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Position_Artist `VideoPlayer.position(number).Artist`\endlink ///

/// } /// \table_row3{ `VideoPlayer.Studio`, /// \anchor VideoPlayer_Studio /// _string_, /// @return The studio of current Music Video\, if it's in the database. ///

/// } /// \table_row3{ `VideoPlayer.offset(number).Studio`, /// \anchor VideoPlayer_Offset_Studio /// _string_, /// @return The studio of the video which has an offset `number` with respect to the currently playing video. ///


/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Offset_Studio `VideoPlayer.offset(number).Studio`\endlink ///

/// } /// \table_row3{ `VideoPlayer.position(number).Studio`, /// \anchor VideoPlayer_Position_Studio /// _string_, /// @return The studio of the video which has an offset `number` with respect to the start of the playlist. ///


/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Position_Studio `VideoPlayer.position(number).Studio`\endlink ///

/// } /// \table_row3{ `VideoPlayer.Writer`, /// \anchor VideoPlayer_Writer /// _string_, /// @return The name of Writer of current playing Video\, if it's in the database. ///


/// @skinning_v15 **[Infolabel Updated]** \link VideoPlayer_Writer `VideoPlayer.Writer`\endlink /// also supports EPG. ///

/// } /// \table_row3{ `VideoPlayer.offset(number).Writer`, /// \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. ///


/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Offset_Writer `VideoPlayer.offset(number).Writer`\endlink ///

/// } /// \table_row3{ `VideoPlayer.position(number).Writer`, /// \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. ///


/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Position_Writer `VideoPlayer.position(number).Writer`\endlink ///

/// } /// \table_row3{ `VideoPlayer.Tagline`, /// \anchor VideoPlayer_Tagline /// _string_, /// @return The small Summary of current playing Video\, if it's in the database. ///

/// } /// \table_row3{ `VideoPlayer.offset(number).Tagline`, /// \anchor VideoPlayer_Offset_Tagline /// _string_, /// @return The small Summary of the video which has an offset `number` with respect to the currently playing video. ///


/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Offset_Tagline `VideoPlayer.offset(number).Tagline`\endlink ///

/// } /// \table_row3{ `VideoPlayer.position(number).Tagline`, /// \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. ///


/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Position_Tagline `VideoPlayer.position(number).Tagline`\endlink ///

/// } /// \table_row3{ `VideoPlayer.PlotOutline`, /// \anchor VideoPlayer_PlotOutline /// _string_, /// @return The small Summary of current playing Video\, if it's in the database. ///

/// } /// \table_row3{ `VideoPlayer.offset(number).PlotOutline`, /// \anchor VideoPlayer_Offset_PlotOutline /// _string_, /// @return The small Summary of the video which has an offset `number` with respect to the currently playing video. ///


/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Offset_PlotOutline `VideoPlayer.offset(number).PlotOutline`\endlink ///

/// } /// \table_row3{ `VideoPlayer.position(number).PlotOutline`, /// \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. ///


/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Position_PlotOutline `VideoPlayer.position(number).PlotOutline`\endlink ///

/// } /// \table_row3{ `VideoPlayer.Plot`, /// \anchor VideoPlayer_Plot /// _string_, /// @return The complete Text Summary of current playing Video\, if it's in the database. ///

/// } /// \table_row3{ `VideoPlayer.offset(number).Plot`, /// \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. ///


/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Offset_Plot `VideoPlayer.offset(number).Plot`\endlink ///

/// } /// \table_row3{ `VideoPlayer.position(number).Plot`, /// \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. ///


/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Position_Plot `VideoPlayer.position(number).Plot`\endlink ///

/// } /// \table_row3{ `VideoPlayer.Premiered`, /// \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. ///

/// } /// \table_row3{ `VideoPlayer.offset(number).Premiered`, /// \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. ///


/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Offset_Premiered `VideoPlayer.offset(number).Premiered`\endlink ///

/// } /// \table_row3{ `VideoPlayer.position(number).Premiered`, /// \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. ///


/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Position_Premiered `VideoPlayer.position(number).Premiered`\endlink ///

/// } /// \table_row3{ `VideoPlayer.Trailer`, /// \anchor VideoPlayer_Trailer /// _string_, /// @return The path to the trailer of the currently playing movie\, if it's in the database. ///

/// } /// \table_row3{ `VideoPlayer.offset(number).Trailer`, /// \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. ///


/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Offset_Trailer `VideoPlayer.offset(number).Title`\endlink ///

/// } /// \table_row3{ `VideoPlayer.position(number).Trailer`, /// \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. ///


/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Position_Trailer `VideoPlayer.position(number).Trailer`\endlink ///

/// } /// \table_row3{ `VideoPlayer.LastPlayed`, /// \anchor VideoPlayer_LastPlayed /// _string_, /// @return The last play date of current playing Video\, if it's in the database. ///

/// } /// \table_row3{ `VideoPlayer.offset(number).LastPlayed`, /// \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. ///


/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Offset_LastPlayed `VideoPlayer.offset(number).LastPlayed`\endlink ///

/// } /// \table_row3{ `VideoPlayer.position(number).LastPlayed`, /// \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. ///


/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Position_LastPlayed `VideoPlayer.position(number).LastPlayed`\endlink ///

/// } /// \table_row3{ `VideoPlayer.PlayCount`, /// \anchor VideoPlayer_PlayCount /// _string_, /// @return The playcount of current playing Video\, if it's in the database. ///

/// } /// \table_row3{ `VideoPlayer.offset(number).PlayCount`, /// \anchor VideoPlayer_Offset_PlayCount /// _string_, /// @return The playcount of the video which has an offset `number` with respect to the currently playing video. ///


/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Offset_PlayCount `VideoPlayer.offset(number).PlayCount`\endlink ///

/// } /// \table_row3{ `VideoPlayer.position(number).PlayCount`, /// \anchor VideoPlayer_Position_PlayCount /// _string_, /// @return The playcount of the video which has an offset `number` with respect to the start of the playlist. ///


/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Position_PlayCount `VideoPlayer.position(number).PlayCount`\endlink ///

/// } /// \table_row3{ `VideoPlayer.VideoCodec`, /// \anchor VideoPlayer_VideoCodec /// _string_, /// @return The video codec of the currently playing video (common values: see /// \ref ListItem_VideoCodec "ListItem.VideoCodec"). ///

/// } /// \table_row3{ `VideoPlayer.VideoResolution`, /// \anchor VideoPlayer_VideoResolution /// _string_, /// @return The video resolution of the currently playing video (possible /// values: see \ref ListItem_VideoResolution "ListItem.VideoResolution"). ///

/// } /// \table_row3{ `VideoPlayer.VideoAspect`, /// \anchor VideoPlayer_VideoAspect /// _string_, /// @return The aspect ratio of the currently playing video (possible values: /// see \ref ListItem_VideoAspect "ListItem.VideoAspect"). ///

/// } /// \table_row3{ `VideoPlayer.AudioCodec`, /// \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"). ///

/// } /// \table_row3{ `VideoPlayer.AudioChannels`, /// \anchor VideoPlayer_AudioChannels /// _string_, /// @return The number of audio channels of the currently playing video /// (possible values: see \ref ListItem_AudioChannels "ListItem.AudioChannels"). ///


/// @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) ///

/// } /// \table_row3{ `VideoPlayer.AudioLanguage`, /// \anchor VideoPlayer_AudioLanguage /// _string_, /// @return The language of the audio of the currently playing video(possible /// values: see \ref ListItem_AudioLanguage "ListItem.AudioLanguage"). ///


/// @skinning_v13 **[New Infolabel]** \link VideoPlayer_AudioLanguage `VideoPlayer.AudioLanguage`\endlink ///

/// } /// \table_row3{ `VideoPlayer.SubtitlesLanguage`, /// \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 ///


/// @skinning_v13 **[New Infolabel]** \link VideoPlayer_SubtitlesLanguage `VideoPlayer.SubtitlesLanguage`\endlink ///

/// } /// \table_row3{ `VideoPlayer.StereoscopicMode`, /// \anchor VideoPlayer_StereoscopicMode /// _string_, /// @return The stereoscopic mode of the currently playing video (possible /// values: see \ref ListItem_StereoscopicMode "ListItem.StereoscopicMode"). ///


/// @skinning_v13 **[New Infolabel]** \link VideoPlayer_StereoscopicMode `VideoPlayer.StereoscopicMode`\endlink ///

/// } /// \table_row3{ `VideoPlayer.StartTime`, /// \anchor VideoPlayer_StartTime /// _string_, /// @return The start date and time of the currently playing epg event or recording (PVR). ///

/// } /// \table_row3{ `VideoPlayer.EndTime`, /// \anchor VideoPlayer_EndTime /// _string_, /// @return The end date and time of the currently playing epg event or recording (PVR). ///

/// } /// \table_row3{ `VideoPlayer.NextTitle`, /// \anchor VideoPlayer_NextTitle /// _string_, /// @return The title of the programme that will be played next (PVR). ///

/// } /// \table_row3{ `VideoPlayer.NextGenre`, /// \anchor VideoPlayer_NextGenre /// _string_, /// @return The genre of the programme that will be played next (PVR). ///

/// } /// \table_row3{ `VideoPlayer.NextPlot`, /// \anchor VideoPlayer_NextPlot /// _string_, /// @return The plot of the programme that will be played next (PVR). ///

/// } /// \table_row3{ `VideoPlayer.NextPlotOutline`, /// \anchor VideoPlayer_NextPlotOutline /// _string_, /// @return The plot outline of the programme that will be played next (PVR). ///

/// } /// \table_row3{ `VideoPlayer.NextStartTime`, /// \anchor VideoPlayer_NextStartTime /// _string_, /// @return The start time of the programme that will be played next (PVR). ///

/// } /// \table_row3{ `VideoPlayer.NextEndTime`, /// \anchor VideoPlayer_NextEndTime /// _string_, /// @return The end time of the programme that will be played next (PVR). ///

/// } /// \table_row3{ `VideoPlayer.NextDuration`, /// \anchor VideoPlayer_NextDuration /// _string_, /// @return The duration of the programme that will be played next (PVR). ///

/// } /// \table_row3{ `VideoPlayer.ChannelName`, /// \anchor VideoPlayer_ChannelName /// _string_, /// @return The name of the currently tuned channel (PVR). ///

/// } /// \table_row3{ `VideoPlayer.ChannelNumberLabel`, /// \anchor VideoPlayer_ChannelNumberLabel /// _string_, /// @return The channel and subchannel number of the tv channel that's currently playing (PVR). ///


/// @skinning_v14 **[New Infolabel]** \link VideoPlayer_ChannelNumberLabel `VideoPlayer.ChannelNumberLabel`\endlink ///

/// } /// \table_row3{ `VideoPlayer.ChannelGroup`, /// \anchor VideoPlayer_ChannelGroup /// _string_, /// @return The group of the currently tuned channel (PVR). ///

/// } /// \table_row3{ `VideoPlayer.ParentalRating`, /// \anchor VideoPlayer_ParentalRating /// _string_, /// @return The parental rating of the currently playing programme (PVR). ///

/// } /// \table_row3{ `VideoPlayer.DBID`, /// \anchor VideoPlayer_DBID /// _string_, /// @return The database id of the currently playing video ///


/// @skinning_v17 **[New Infolabel]** \link VideoPlayer_DBID `VideoPlayer.DBID`\endlink ///

/// } /// \table_row3{ `VideoPlayer.offset(number).DBID`, /// \anchor VideoPlayer_Offset_DBID /// _string_, /// @return The database id of the video which has an offset `number` with respect to the currently playing video. ///


/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Offset_DBID `VideoPlayer.offset(number).DBID`\endlink ///

/// } /// \table_row3{ `VideoPlayer.position(number).DBID`, /// \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. ///


/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_Position_DBID `VideoPlayer.position(number).DBID`\endlink ///

/// } /// \table_row3{ `VideoPlayer.UniqueID(name)`, /// \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. ///


/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_UniqueID `VideoPlayer.UniqueID(name)`\endlink ///

/// } /// \table_row3{ `VideoPlayer.TvShowDBID`, /// \anchor VideoPlayer_TvShowDBID /// _string_, /// @return The database id of the TvShow for the currently playing Episode ///


/// @skinning_v19 **[New Infolabel]** \link VideoPlayer_TvShowDBID `VideoPlayer.TvShowDBID`\endlink ///

/// } /// \table_row3{ `VideoPlayer.AudioStreamCount`, /// \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. ///


/// @skinning_v20 **[New Infolabel]** \link VideoPlayer_AudioStreamCount `VideoPlayer.AudioStreamCount`\endlink ///

/// } /// \table_row3{ `VideoPlayer.HdrType`, /// \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. ///


/// @skinning_v20 **[New Infolabel]** \link VideoPlayer_HdrType `VideoPlayer.HdrType`\endlink ///

/// } /// \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{ `RetroPlayer.VideoFilter`, /// \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) ///


/// @skinning_v18 **[New Infolabel]** \link RetroPlayer_VideoFilter `RetroPlayer.VideoFilter`\endlink ///

/// } /// \table_row3{ `RetroPlayer.StretchMode`, /// \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) ///


/// @skinning_v18 **[New Infolabel]** \link RetroPlayer_StretchMode `RetroPlayer.StretchMode`\endlink ///

/// } /// \table_row3{ `RetroPlayer.VideoRotation`, /// \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) ///


/// @skinning_v18 **[New Infolabel]** \link RetroPlayer_VideoRotation `RetroPlayer.VideoRotation`\endlink ///

/// } /// \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{ `Container.HasFiles`, /// \anchor Container_HasFiles /// _boolean_, /// @return **True** if the container contains files. ///

/// } /// \table_row3{ `Container.HasFolders`, /// \anchor Container_HasFolders /// _boolean_, /// @return **True** if the container contains folders. ///

/// } /// \table_row3{ `Container.IsStacked`, /// \anchor Container_IsStacked /// _boolean_, /// @return **True** if the container is currently in stacked mode. ///

/// } /// \table_row3{ `Container.FolderPath`, /// \anchor Container_FolderPath /// _string_, /// @return The complete path of currently displayed folder. ///

/// } /// \table_row3{ `Container.FolderName`, /// \anchor Container_FolderName /// _string_, /// @return The top most folder in currently displayed folder. ///

/// } /// \table_row3{ `Container.PluginName`, /// \anchor Container_PluginName /// _string_, /// @return The current plugins base folder name. ///

/// } /// \table_row3{ `Container.PluginCategory`, /// \anchor Container_PluginCategory /// _string_, /// @return The current plugins category (set by the scripter). ///


/// @skinning_v17 **[New Infolabel]** \link Container_PluginCategory `Container.PluginCategory`\endlink ///

/// } /// \table_row3{ `Container.Viewmode`, /// \anchor Container_Viewmode /// _string_, /// @return The current viewmode (list\, icons etc). ///

/// } /// \table_row3{ `Container.ViewCount`, /// \anchor Container_ViewCount /// _integer_, /// @return The number of available skin view modes for the current container listing. ///


/// @skinning_v17 **[New Infolabel]** \link Container_ViewCount `Container.ViewCount`\endlink ///

/// } /// \table_row3{ `Container.Totaltime`, /// \anchor Container_Totaltime /// _string_, /// @return The total time of all items in the current container. ///

/// } /// \table_row3{ `Container.TotalWatched`, /// \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. ///


/// @skinning_v16 **[New Infolabel]** \link Container_TotalWatched `Container(id).TotalWatched`\endlink ///

/// } /// \table_row3{ `Container.TotalUnWatched`, /// \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. ///


/// @skinning_v16 **[New Infolabel]** \link Container_TotalUnWatched `Container(id).TotalUnWatched`\endlink ///

/// } /// \table_row3{ `Container.HasThumb`, /// \anchor Container_HasThumb /// _boolean_, /// @return **True** if the current container you are in has a thumb assigned /// to it. ///

/// } /// \table_row3{ `Container.SortOrder`, /// \anchor Container_SortOrder /// _string_, /// @return The current sort order (Ascending/Descending). ///


/// @skinning_v16 **[New Infolabel]** \link Container_SortOrder `Container.SortOrder`\endlink ///

/// } /// \table_row3{ `Container.CanFilter`, /// \anchor Container_CanFilter /// _boolean_, /// @return **True** when the current container can be filtered. ///

/// } /// \table_row3{ `Container.CanFilterAdvanced`, /// \anchor Container_CanFilterAdvanced /// _boolean_, /// @return **True** when advanced filtering can be applied to the current container. ///

/// } /// \table_row3{ `Container.Filtered`, /// \anchor Container_Filtered /// _boolean_, /// @return **True** when a mediafilter is applied to the current container. ///

/// } /// \table_row3{ `Container.ShowPlot`, /// \anchor Container_ShowPlot /// _string_, /// @return The TV Show plot of the current container and can be used at /// season and episode level. ///

/// } /// \table_row3{ `Container.ShowTitle`, /// \anchor Container_ShowTitle /// _string_, /// @return The TV Show title of the current container and can be used at /// season and episode level. ///


/// @skinning_v17 **[New Infolabel]** \link Container_ShowTitle `Container.ShowTitle`\endlink ///

/// } 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{ `Container(id).OnNext`, /// \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.) ///

/// } /// \table_row3{ `Container(id).OnScrollNext`, /// \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. ///

/// } /// \table_row3{ `Container(id).OnPrevious`, /// \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). ///

/// } /// \table_row3{ `Container(id).OnScrollPrevious`, /// \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. ///

/// } /// \table_row3{ `Container(id).NumPages`, /// \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. ///

/// } /// \table_row3{ `Container(id).NumItems`, /// \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. ///

/// } /// \table_row3{ `Container(id).NumAllItems`, /// \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. ///


/// @skinning_v18 **[New Infolabel]** \link Container_NumAllItems `Container(id).NumAllItems`\endlink ///

/// } /// \table_row3{ `Container(id).NumNonFolderItems`, /// \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. ///


/// @skinning_v18 **[New Infolabel]** \link Container_NumNonFolderItems `Container(id).NumNonFolderItems`\endlink ///

/// } /// \table_row3{ `Container(id).CurrentPage`, /// \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. ///

/// } /// \table_row3{ `Container(id).CurrentItem`, /// \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. ///


/// @skinning_v15 **[New Infolabel]** \link Container_CurrentItem `Container(id).CurrentItem`\endlink ///

/// } /// \table_row3{ `Container(id).Scrolling`, /// \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. ///

/// } /// \table_row3{ `Container(id).HasNext`, /// \anchor Container_HasNext /// _boolean_, /// @return **True** if the container or textbox with id (id) has a next page. ///

/// } /// \table_row3{ `Container(id).HasParent`, /// \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. ///


/// @skinning_v16 **[New Boolean Condition]** \link Container_HasParent `Container.HasParent`\endlink ///

/// } /// \table_row3{ `Container(id).HasPrevious`, /// \anchor Container_HasPrevious /// _boolean_, /// @return **True** if the container or textbox with id (id) has a previous page. ///

/// } /// \table_row3{ `Container(id).IsUpdating`, /// \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{ `Container(id).Row`, /// \anchor Container_Row /// _integer_, /// @return The row number of the focused position in a panel container. ///


/// @skinning_v16 **[New Infolabel]** \link Container_Row `Container(id).Row`\endlink ///

/// } /// \table_row3{ `Container(id).Row(parameter)`, /// \anchor Container_Row_parameter /// _boolean_, /// @return **True** if the row number of the focused position matches the specified parameter. ///

/// } /// \table_row3{ `Container(id).Column`, /// \anchor Container_Column /// _integer_, /// @return The column number of the focused position in a panel container. ///


/// @skinning_v16 **[New Infolabel]** \link Container_Column `Container(id).Column`\endlink ///

/// } /// \table_row3{ `Container(id).Column(parameter)`, /// \anchor Container_Column_parameter /// _boolean_, /// @return **True** if the column number of the focused position matches the specified parameter. ///

/// } /// \table_row3{ `Container(id).Position`, /// \anchor Container_Position /// _integer_, /// @return The current focused position of container / grouplist (id) as a /// numeric label. ///


/// @skinning_v16 **[Infolabel Updated]** \link Container_Position `Container(id).Position`\endlink /// now also returns the position for items inside a grouplist. ///

/// } /// \table_row3{ `Container(id).Position(parameter)`, /// \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. ///

/// } /// \table_row3{ `Container(id).SubItem(item_number)`, /// \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. ///

/// } /// \table_row3{ `Container(id).HasFocus(item_number)`, /// \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. ///

/// } /// \table_row3{ `Container.SortMethod`, /// \anchor Container_SortMethod /// _string_, /// @return The current sort method (returns a localized value). ///

/// } /// \table_row3{ `Container.SortMethod(sortid)`, /// \anchor Container_SortMethod_sortid /// _boolean_, /// @return **True** if the current sort method matches the specified SortID (see \ref List_of_sort_methods "SortUtils"). ///

/// } 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{ `Container.Property(addoncategory)`, /// \anchor Container_Property_addoncategory /// _string_, /// @return The current add-on category. ///

/// } /// \table_row3{ `Container.Property(reponame)`, /// \anchor Container_Property_reponame /// _string_, /// @return The current add-on repository name. ///

/// } /// \table_row3{ `Container.Content`, /// \anchor Container_Content /// _string_, /// @return The content of the current container. ///


/// @skinning_v16 **[New Infolabel]** \link Container_Content `Container.Content`\endlink ///

/// } /// \table_row3{ `Container(id).ListItem(offset).Property`, /// \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 ` ///

/// } /// \table_row3{ `Container(id).ListItemNoWrap(offset).Property`, /// \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` ///

/// } /// \table_row3{ `Container(id).ListItemPosition(x).[infolabel]`, /// \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` ///

/// } /// \table_row3{ `Container(id).ListItemAbsolute(x).[infolabel]`, /// \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` ///


/// @skinning_v16 **[New Infolabel]** \link Container_ListItemAbsolute `Container(id).ListItemAbsolute(x).[infolabel]`\endlink ///

/// } /// \table_row3{ `Container.Content(parameter)`, /// \anchor Container_Content_parameter /// _string_, /// @return **True** if the current container you are in contains the following: /// - files /// - songs /// - artists /// - albums /// - movies /// - tvshows /// - seasons /// - episodes /// - musicvideos /// - genres /// - years /// - actors /// - playlists /// - plugins /// - studios /// - directors /// - sets /// - tags /// @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 ///

/// } /// \table_row3{ `Container.Art(type)`, /// \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 ///


/// @skinning_v16 **[Infolabel Updated]** \link Container_Art `Container.Art(type)`\endlink /// set.fanart as possible type value. /// @skinning_v15 **[New Infolabel]** \link Container_Art `Container.Art(type)`\endlink ///

/// } /// const infomap container_str[] = {{ "property", CONTAINER_PROPERTY }, { "content", CONTAINER_CONTENT }, { "art", CONTAINER_ART }}; /// \page modules__infolabels_boolean_conditions /// \table_row3{ `Container.SortDirection(direction)`, /// \anchor Container_SortDirection /// _boolean_, /// @return **True** if the sort direction of a container equals direction. /// @param direction - The direction to check. It can be: /// - ascending /// - descending ///

/// } /// \table_end /// /// ----------------------------------------------------------------------------- /// \page modules__infolabels_boolean_conditions /// \subsection modules__infolabels_boolean_conditions_ListItem ListItem /// \table_start /// \table_h3{ Labels, Type, Description } /// \table_row3{ `ListItem.Thumb`, /// \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)" ///

/// } /// \table_row3{ `ListItem.Icon`, /// \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. ///

/// } /// \table_row3{ `ListItem.ActualIcon`, /// \anchor ListItem_ActualIcon /// _string_, /// @return The icon of the currently selected item in a list or thumb control. ///

/// } /// \table_row3{ `ListItem.Overlay`, /// \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 ///

/// } /// \table_row3{ `ListItem.IsFolder`, /// \anchor ListItem_IsFolder /// _boolean_, /// @return **True** if the current ListItem is a folder. ///

/// } /// \table_row3{ `ListItem.IsPlaying`, /// \anchor ListItem_IsPlaying /// _boolean_, /// @return **True** if the current ListItem.* info labels and images are /// currently Playing media. ///

/// } /// \table_row3{ `ListItem.IsResumable`, /// \anchor ListItem_IsResumable /// _boolean_, /// @return **True** when the current ListItem has been partially played. ///

/// } /// \table_row3{ `ListItem.IsCollection`, /// \anchor ListItem_IsCollection /// _boolean_, /// @return **True** when the current ListItem is a movie set. ///


/// @skinning_v15 **[New Boolean Condition]** \link ListItem_IsCollection `ListItem.IsCollection`\endlink ///

/// } /// \table_row3{ `ListItem.IsSelected`, /// \anchor ListItem_IsSelected /// _boolean_, /// @return **True** if the current ListItem is selected (f.e. currently playing /// in playlist window). ///

/// } /// \table_row3{ `ListItem.HasEpg`, /// \anchor ListItem_HasEpg /// _boolean_, /// @return **True** when the selected programme has epg info (PVR). ///

/// } /// \table_row3{ `ListItem.HasTimer`, /// \anchor ListItem_HasTimer /// _boolean_, /// @return **True** when a recording timer has been set for the selected /// programme (PVR). ///

/// } /// \table_row3{ `ListItem.IsRecording`, /// \anchor ListItem_IsRecording /// _boolean_, /// @return **True** when the selected programme is being recorded (PVR). ///

/// } /// \table_row3{ `ListItem.IsPlayable`, /// \anchor ListItem_IsPlayable /// _boolean_, /// @return **True** when the selected programme can be played (PVR) ///


/// @skinning_v19 **[New Boolean Condition]** \link ListItem_IsPlayable `ListItem.IsPlayable`\endlink ///

/// } /// \table_row3{ `ListItem.HasArchive`, /// \anchor ListItem_HasArchive /// _boolean_, /// @return **True** when the selected channel has a server-side back buffer (PVR) ///


/// @skinning_v19 **[New Boolean Condition]** \link ListItem_HasArchive `ListItem.HasArchive`\endlink ///

/// } /// \table_row3{ `ListItem.IsEncrypted`, /// \anchor ListItem_IsEncrypted /// _boolean_, /// @return **True** when the selected programme is encrypted (PVR). ///

/// } /// \table_row3{ `ListItem.IsStereoscopic`, /// \anchor ListItem_IsStereoscopic /// _boolean_, /// @return **True** when the selected video is a 3D (stereoscopic) video. ///


/// @skinning_v13 **[New Boolean Condition]** \link ListItem_IsStereoscopic `ListItem.IsStereoscopic`\endlink ///

/// } /// \table_row3{ `ListItem.Property(IsSpecial)`, /// \anchor ListItem_Property_IsSpecial /// _boolean_, /// @return **True** if the current Season/Episode is a Special. ///

/// } /// \table_row3{ `ListItem.Property(DateLabel)`, /// \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. ///

/// } /// \table_row3{ `ListItem.Property(Addon.IsEnabled)`, /// \anchor ListItem_Property_AddonIsEnabled /// _boolean_, /// @return **True** when the selected addon is enabled (for use in the addon /// info dialog only). ///


/// @skinning_v17 **[Boolean Condition Updated]** \link ListItem_Property_AddonIsEnabled `ListItem.Property(Addon.IsEnabled)`\endlink /// replaces `ListItem.Property(Addon.Enabled)`. ///

/// } /// \table_row3{ `ListItem.Property(Addon.IsInstalled)`, /// \anchor ListItem_Property_AddonIsInstalled /// _boolean_, /// @return **True** when the selected addon is installed (for use in the addon /// info dialog only). ///


/// @skinning_v17 **[Boolean Condition Updated]** \link ListItem_Property_AddonIsInstalled `ListItem.Property(Addon.IsInstalled)`\endlink /// replaces `ListItem.Property(Addon.Installed)`. ///

/// } /// \table_row3{ `ListItem.Property(Addon.HasUpdate)`, /// \anchor ListItem_Property_AddonHasUpdate /// _boolean_, /// @return **True** when there's an update available for the selected addon. ///


/// @skinning_v17 **[Boolean Condition Updated]** \link ListItem_Property_AddonHasUpdate `ListItem.Property(Addon.HasUpdate)`\endlink /// replaces `ListItem.Property(Addon.UpdateAvail)`. ///

/// } /// \table_row3{ `ListItem.IsAutoUpdateable`, /// \anchor ListItem_IsAutoUpdateable /// _boolean_, /// @return **True** if this add-on can be updated automatically. ///


/// @skinning_v19 **[New Boolean Condition]** \link ListItem_IsAutoUpdateable `ListItem.IsAutoUpdateable`\endlink ///

/// } /// \table_row3{ `ListItem.Property(Addon.IsFromOfficialRepo)`, /// \anchor ListItem_Property_AddonIsFromOfficialRepo /// _boolean_, /// @return **True** if this add-on is from an official repository. ///


/// @skinning_v19 **[New Boolean Condition]** \link ListItem_Property_AddonIsFromOfficialRepo `ListItem.Property(Addon.IsFromOfficialRepo)`\endlink ///

/// } /// \table_row3{ `ListItem.Property(Addon.IsBinary)`, /// \anchor ListItem_Property_AddonIsBinary /// _boolean_, /// @return **True** if this add-on is a binary addon. ///


/// @skinning_v19 **[New Boolean Condition]** \link ListItem_Property_AddonIsBinary `ListItem.Property(Addon.IsBinary)`\endlink ///

/// } /// \table_row3{ `ListItem.Property(Addon.IsUpdate)`, /// \anchor ListItem_Property_AddonIsUpdate /// _boolean_, /// @return **True** if this add-on is a valid update of an installed outdated add-on. ///


/// @skinning_v19 **[New Boolean Condition]** \link ListItem_Property_AddonIsUpdate `ListItem.Property(Addon.IsUpdate)`\endlink ///

/// } /// \table_row3{ `ListItem.Property(Addon.ValidUpdateOrigin)`, /// \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. ///


/// @skinning_v19 **[New Infolabel]** \link ListItem_Property_ValidUpdateOrigin `ListItem.Property(Addon.ValidUpdateOrigin)`\endlink ///

/// } /// \table_row3{ `ListItem.Property(Addon.ValidUpdateVersion)`, /// \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. ///


/// @skinning_v19 **[New Infolabel]** \link ListItem_Property_ValidUpdateVersion `ListItem.Property(Addon.ValidUpdateVersion)`\endlink ///

/// } /// \table_row3{ `ListItem.Label`, /// \anchor ListItem_Label /// _string_, /// @return The left label of the currently selected item in a container. ///

/// } /// \table_row3{ `ListItem.Label2`, /// \anchor ListItem_Label2 /// _string_, /// @return The right label of the currently selected item in a container. ///

/// } /// \table_row3{ `ListItem.Title`, /// \anchor ListItem_Title /// _string_, /// @return The title of the currently selected song\, movie\, game in a container. ///


/// @skinning_v18 **[Infolabel Updated]** \link ListItem_Title `ListItem.Title`\endlink extended /// to support games ///

/// } /// \table_row3{ `ListItem.OriginalTitle`, /// \anchor ListItem_OriginalTitle /// _string_, /// @return The original title of the currently selected movie in a container. ///

/// } /// \table_row3{ `ListItem.SortLetter`, /// \anchor ListItem_SortLetter /// _string_, /// @return The first letter of the current file in a container. ///

/// } /// \table_row3{ `ListItem.TrackNumber`, /// \anchor ListItem_TrackNumber /// _string_, /// @return The track number of the currently selected song in a container. ///

/// } /// \table_row3{ `ListItem.Artist`, /// \anchor ListItem_Artist /// _string_, /// @return The artist of the currently selected song in a container. ///

/// } /// \table_row3{ `ListItem.AlbumArtist`, /// \anchor ListItem_AlbumArtist /// _string_, /// @return The artist of the currently selected album in a list. ///

/// } /// \table_row3{ `ListItem.Property(Artist_Sortname)`, /// \anchor ListItem_Property_Artist_Sortname /// _string_, /// @return The sortname of the currently selected Artist. ///


/// @skinning_v18 **[New Infolabel]** \link ListItem_Property_Artist_Sortname `ListItem.Property(Artist_Sortname)`\endlink ///

/// } /// \table_row3{ `ListItem.Property(Artist_Type)`, /// \anchor ListItem_Property_Artist_Type /// _string_, /// @return The type of the currently selected Artist - person\, group\, orchestra\, choir etc. ///


/// @skinning_v18 **[New Infolabel]** \link ListItem_Property_Artist_Type `ListItem.Property(Artist_Type)`\endlink ///

/// } /// \table_row3{ `ListItem.Property(Artist_Gender)`, /// \anchor ListItem_Property_Artist_Gender /// _string_, /// @return The Gender of the currently selected Artist - male\, female\, other. ///


/// @skinning_v18 **[New Infolabel]** \link ListItem_Property_Artist_Gender `ListItem.Property(Artist_Gender)`\endlink ///

/// } /// \table_row3{ `ListItem.Property(Artist_Disambiguation)`, /// \anchor ListItem_Property_Artist_Disambiguation /// _string_, /// @return A Brief description of the currently selected Artist that differentiates them /// from others with the same name. ///


/// @skinning_v18 **[New Infolabel]** \link ListItem_Property_Artist_Disambiguation `ListItem.Property(Artist_Disambiguation)`\endlink ///

/// } /// \table_row3{ `ListItem.Property(Artist_Born)`, /// \anchor ListItem_Property_Artist_Born /// _string_, /// @return The date of Birth of the currently selected Artist. ///

/// } /// \table_row3{ `ListItem.Property(Artist_Died)`, /// \anchor ListItem_Property_Artist_Died /// _string_, /// @return The date of Death of the currently selected Artist. ///

/// } /// \table_row3{ `ListItem.Property(Artist_Formed)`, /// \anchor ListItem_Property_Artist_Formed /// _string_, /// @return The formation date of the currently selected Band. ///

/// } /// \table_row3{ `ListItem.Property(Artist_Disbanded)`, /// \anchor ListItem_Property_Artist_Disbanded /// _string_, /// @return The disbanding date of the currently selected Band. ///

/// } /// \table_row3{ `ListItem.Property(Artist_YearsActive)`, /// \anchor ListItem_Property_Artist_YearsActive /// _string_, /// @return The years the currently selected artist has been active. ///

/// } /// \table_row3{ `ListItem.Property(Artist_Instrument)`, /// \anchor ListItem_Property_Artist_Instrument /// _string_, /// @return The instruments played by the currently selected artist. ///

/// } /// \table_row3{ `ListItem.Property(Artist_Description)`, /// \anchor ListItem_Property_Artist_Description /// _string_, /// @return A biography of the currently selected artist. ///

/// } /// \table_row3{ `ListItem.Property(Artist_Mood)`, /// \anchor ListItem_Property_Artist_Mood /// _string_, /// @return The moods of the currently selected artist. ///

/// } /// \table_row3{ `ListItem.Property(Artist_Style)`, /// \anchor ListItem_Property_Artist_Style /// _string_, /// @return The styles of the currently selected artist. ///

/// } /// \table_row3{ `ListItem.Property(Artist_Genre)`, /// \anchor ListItem_Property_Artist_Genre /// _string_, /// @return The genre of the currently selected artist. ///

/// } /// \table_row3{ `ListItem.Album`, /// \anchor ListItem_Album /// _string_, /// @return The album of the currently selected song in a container. ///

/// } /// \table_row3{ `ListItem.Property(Album_Mood)`, /// \anchor ListItem_Property_Album_Mood /// _string_, /// @return The moods of the currently selected Album. ///

/// } /// \table_row3{ `ListItem.Property(Album_Style)`, /// \anchor ListItem_Property_Album_Style /// _string_, /// @return The styles of the currently selected Album. ///

/// } /// \table_row3{ `ListItem.Property(Album_Theme)`, /// \anchor ListItem_Property_Album_Theme /// _string_, /// @return The themes of the currently selected Album. ///

/// } /// \table_row3{ `ListItem.Property(Album_Type)`, /// \anchor ListItem_Property_Album_Type /// _string_, /// @return The Album Type (e.g. compilation\, enhanced\, explicit lyrics) of /// the currently selected Album. ///

/// } /// \table_row3{ `ListItem.Property(Album_Label)`, /// \anchor ListItem_Property_Album_Label /// _string_, /// @return The record label of the currently selected Album. ///

/// } /// \table_row3{ `ListItem.Property(Album_Description)`, /// \anchor ListItem_Property_Album_Description /// _string_, /// @return A review of the currently selected Album. ///

/// } /// \table_row3{ `ListItem.Property(Album_Totaldiscs)`, /// \anchor ListItem_Property_Album_Totaldiscs /// _string_, /// @return The total number of discs belonging to an album. ///


/// @skinning_v19 **[New Infolabel]** \link ListItem.Property(Album_Totaldiscs) `ListItem.Property(Album_Totaldiscs)`\endlink ///

/// } /// \table_row3{ `ListItem.Property(Album_Isboxset)`, /// \anchor ListItem_Property_Album_Isboxset /// _string_, /// @return **True** if the album is a boxset. ///


/// @skinning_v19 **[New Infobool]** \link ListItem.Property(Album_Isboxset) `ListItem.Property(Album_Isboxset)`\endlink ///

/// } /// \table_row3{ `ListItem.Property(Album_Duration)`, /// \anchor ListItem_Property_Album_Duration /// _string_, /// @return The duration of the album in HH:MM:SS. ///


/// @skinning_v19 **[New Infolabel]** \link ListItem_Property_Album_Duration `ListItem.Property(Album_Duration)`\endlink ///

/// } /// \table_row3{ `ListItem.DiscNumber`, /// \anchor ListItem_DiscNumber /// _string_, /// @return The disc number of the currently selected song in a container. ///

/// } /// \table_row3{ `ListItem.Year`, /// \anchor ListItem_Year /// _string_, /// @return The year of the currently selected song\, album\, movie\, game in a /// container. ///


/// @skinning_v18 **[Infolabel Updated]** \link ListItem_Title `ListItem.Title`\endlink extended /// to support games ///

/// } /// \table_row3{ `ListItem.Premiered`, /// \anchor ListItem_Premiered /// _string_, /// @return The release/aired date of the currently selected episode\, show\, /// movie or EPG item in a container. ///


/// @skinning_v15 **[Infolabel Updated]** \link ListItem_Premiered `ListItem.Premiered`\endlink /// now also available for EPG items. ///

/// } /// \table_row3{ `ListItem.Genre`, /// \anchor ListItem_Genre /// _string_, /// @return The genre of the currently selected song\, album or movie in a /// container. ///

/// } /// \table_row3{ `ListItem.Contributors`, /// \anchor ListItem_Contributors /// _string_, /// @return The list of all people who've contributed to the selected song. ///


/// @skinning_v17 **[New Infolabel]** \link ListItem_Contributors `ListItem.Contributors`\endlink ///

/// } /// \table_row3{ `ListItem.ContributorAndRole`, /// \anchor ListItem_ContributorAndRole /// _string_, /// @return The list of all people and their role who've contributed to the selected song. ///


/// @skinning_v17 **[New Infolabel]** \link ListItem_ContributorAndRole `ListItem.ContributorAndRole`\endlink ///

/// } /// \table_row3{ `ListItem.Director`, /// \anchor ListItem_Director /// _string_, /// @return The director of the currently selected movie in a container. ///


/// @skinning_v15 **[Infolabel Updated]** \link ListItem_Director `ListItem.Director`\endlink /// also supports EPG. ///

/// } /// \table_row3{ `ListItem.Country`, /// \anchor ListItem_Country /// _string_, /// @return The production country of the currently selected movie in a /// container. ///

/// } /// \table_row3{ `ListItem.Episode`, /// \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. ///


/// @skinning_v15 **[Infolabel Updated]** \link ListItem_Episode `ListItem.Episode`\endlink /// also supports EPG. ///

/// } /// \table_row3{ `ListItem.Season`, /// \anchor ListItem_Season /// _string_, /// @return The season value for the currently selected tvshow. ///


/// @skinning_v15 **[Infolabel Updated]** \link ListItem_Season `ListItem.Season`\endlink /// also supports EPG. ///

/// } /// \table_row3{ `ListItem.TVShowTitle`, /// \anchor ListItem_TVShowTitle /// _string_, /// @return The name value for the currently selected tvshow in the season and /// episode depth of the video library. ///

/// } /// \table_row3{ `ListItem.Property(TotalSeasons)`, /// \anchor ListItem_Property_TotalSeasons /// _string_, /// @return The total number of seasons for the currently selected tvshow. ///

/// } /// \table_row3{ `ListItem.Property(TotalEpisodes)`, /// \anchor ListItem_Property_TotalEpisodes /// _string_, /// @return the total number of episodes for the currently selected tvshow or /// season. ///

/// } /// \table_row3{ `ListItem.Property(WatchedEpisodes)`, /// \anchor ListItem_Property_WatchedEpisodes /// _string_, /// @return The number of watched episodes for the currently selected tvshow /// or season. ///

/// } /// \table_row3{ `ListItem.Property(UnWatchedEpisodes)`, /// \anchor ListItem_Property_UnWatchedEpisodes /// _string_, /// @return The number of unwatched episodes for the currently selected tvshow /// or season. ///

/// } /// \table_row3{ `ListItem.Property(NumEpisodes)`, /// \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. ///

/// } /// \table_row3{ `ListItem.Property(WatchedEpisodePercent)`, /// \anchor ListItem_Property_WatchedEpisodePercent /// _string_, /// @return The percentage of watched episodes in the tvshow (watched/total*100) or season. ///


/// @skinning_v20 **[New Infolabel]** \link ListItem_Property_WatchedEpisodePercent `ListItem.Property(WatchedEpisodePercent)`\endlink ///

/// } /// \table_row3{ `ListItem.PictureAperture`, /// \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). ///

/// } /// \table_row3{ `ListItem.PictureAuthor`, /// \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). ///


/// @skinning_v13 **[New Infolabel]** \link ListItem_PictureAuthor `ListItem.PictureAuthor`\endlink ///

/// } /// \table_row3{ `ListItem.PictureByline`, /// \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). ///


/// @skinning_v13 **[New Infolabel]** \link ListItem_PictureByline `ListItem.PictureByline`\endlink ///

/// } /// \table_row3{ `ListItem.PictureBylineTitle`, /// \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). ///


/// @skinning_v13 **[New Infolabel]** \link ListItem_PictureBylineTitle `ListItem.PictureBylineTitle`\endlink ///

/// } /// \table_row3{ `ListItem.PictureCamMake`, /// \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). ///

/// } /// \table_row3{ `ListItem.PictureCamModel`, /// \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). ///

/// } /// \table_row3{ `ListItem.PictureCaption`, /// \anchor ListItem_PictureCaption /// _string_, /// @return A description of the selected picture. /// @note This is the value of the IPTC Caption tag (hex code 0x78). ///

/// } /// \table_row3{ `ListItem.PictureCategory`, /// \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). ///


/// @skinning_v13 **[New Infolabel]** \link ListItem_PictureCategory `ListItem.PictureCategory`\endlink ///

/// } /// \table_row3{ `ListItem.PictureCCDWidth`, /// \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). ///


/// @skinning_v13 **[New Infolabel]** \link ListItem_PictureCCDWidth `ListItem.PictureCCDWidth`\endlink ///

/// } /// \table_row3{ `ListItem.PictureCity`, /// \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). ///


/// @skinning_v13 **[New Infolabel]** \link ListItem_PictureCity `ListItem.PictureCity`\endlink ///

/// } /// \table_row3{ `ListItem.PictureColour`, /// \anchor ListItem_PictureColour /// _string_, /// @return Whether the selected picture is "Colour" or "Black and White". ///


/// @skinning_v13 **[New Infolabel]** \link ListItem_PictureColour `ListItem.PictureColour`\endlink ///

/// } /// \table_row3{ `ListItem.PictureComment`, /// \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". ///

/// } /// \table_row3{ `ListItem.PictureCopyrightNotice`, /// \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). ///


/// @skinning_v13 **[New Infolabel]** \link ListItem_PictureCopyrightNotice `ListItem.PictureCopyrightNotice`\endlink ///

/// } /// \table_row3{ `ListItem.PictureCountry`, /// \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). ///


/// @skinning_v13 **[New Infolabel]** \link ListItem_PictureCountry `ListItem.PictureCountry`\endlink ///

/// } /// \table_row3{ `ListItem.PictureCountryCode`, /// \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). ///


/// @skinning_v13 **[New Infolabel]** \link ListItem_PictureCountryCode `ListItem.PictureCountryCode`\endlink ///

/// } /// \table_row3{ `ListItem.PictureCredit`, /// \anchor ListItem_PictureCredit /// _string_, /// @return Who provided the selected picture. /// @note This is the value of the IPTC Credit tag (hex code 0x6E). ///


/// @skinning_v13 **[New Infolabel]** \link ListItem_PictureCredit `ListItem.PictureCredit`\endlink ///

/// } /// \table_row3{ `ListItem.PictureDate`, /// \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. ///


/// @skinning_v13 **[New Infolabel]** \link ListItem_PictureDate `ListItem.PictureDate`\endlink ///

/// } /// \table_row3{ `ListItem.PictureDatetime`, /// \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. ///


/// @skinning_v13 **[New Infolabel]** \link ListItem_PictureDatetime `ListItem.PictureDatetime`\endlink ///

/// } /// \table_row3{ `ListItem.PictureDesc`, /// \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). ///

/// } /// \table_row3{ `ListItem.PictureDigitalZoom`, /// \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). ///


/// @skinning_v13 **[New Infolabel]** \link ListItem_PictureDigitalZoom `ListItem.PictureDigitalZoom`\endlink ///

/// } /// \table_row3{ `ListItem.PictureExpMode`, /// \anchor ListItem_PictureExpMode /// _string_, /// @return The exposure mode of the selected picture. /// The possible values are: /// - "Automatic" /// - "Manual" /// - "Auto bracketing" /// @note This is the value of the EXIF ExposureMode tag (hex code 0xA402). ///

/// } /// \table_row3{ `ListItem.PictureExposure`, /// \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: /// - "Manual" /// - "Program (Auto)" /// - "Aperture priority (Semi-Auto)" /// - "Shutter priority (semi-auto)" /// - etc /// @note This is the value of the EXIF ExposureProgram tag (hex code 0x8822). ///


/// @skinning_v13 **[New Infolabel]** \link ListItem_PictureExposure `ListItem.PictureExposure`\endlink ///

/// } /// \table_row3{ `ListItem.PictureExposureBias`, /// \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). ///


/// @skinning_v13 **[New Infolabel]** \link ListItem_PictureExposureBias `ListItem.PictureExposureBias`\endlink ///

/// } /// \table_row3{ `ListItem.PictureExpTime`, /// \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. ///

/// } /// \table_row3{ `ListItem.PictureFlashUsed`, /// \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). ///


/// @skinning_v13 **[New Infolabel]** \link ListItem_PictureFlashUsed `ListItem.PictureFlashUsed`\endlink ///

/// } /// \table_row3{ `ListItem.PictureFocalLen`, /// \anchor ListItem_PictureFocalLen /// _string_, /// @return The lens focal length of the selected picture. ///

/// } /// \table_row3{ `ListItem.PictureFocusDist`, /// \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{ `ListItem.PictureGPSLat`, /// \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. ///

/// } /// \table_row3{ `ListItem.PictureGPSLon`, /// \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. ///

/// } /// \table_row3{ `ListItem.PictureGPSAlt`, /// \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. ///

/// } /// \table_row3{ `ListItem.PictureHeadline`, /// \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). ///


/// @skinning_v13 **[New Infolabel]** \link ListItem_PictureHeadline `ListItem.PictureHeadline`\endlink ///

/// } /// \table_row3{ `ListItem.PictureImageType`, /// \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). ///


/// @skinning_v13 **[New Infolabel]** \link ListItem_PictureImageType `ListItem.PictureImageType`\endlink ///

/// } /// \table_row3{ `ListItem.PictureIPTCDate`, /// \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). ///


/// @skinning_v13 **[New Infolabel]** \link ListItem_PictureIPTCDate `ListItem.PictureIPTCDate`\endlink ///

/// } /// \table_row3{ `ListItem.PictureIPTCTime`, /// \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). ///


/// @skinning_v13 **[New Infolabel]** \link ListItem_PictureIPTCTime `ListItem.PictureIPTCTime`\endlink ///

/// } /// \table_row3{ `ListItem.PictureISO`, /// \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). ///

/// } /// \table_row3{ `ListItem.PictureKeywords`, /// \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). ///

/// } /// \table_row3{ `ListItem.PictureLightSource`, /// \anchor ListItem_PictureLightSource /// _string_, /// @return The kind of light source when the picture was taken. Possible /// values include: /// - "Daylight" /// - "Fluorescent" /// - "Incandescent" /// - etc /// @note This is the value of the EXIF LightSource tag (hex code 0x9208). ///


/// @skinning_v13 **[New Infolabel]** \link ListItem_PictureLightSource `ListItem.PictureLightSource`\endlink ///

/// } /// \table_row3{ `ListItem.PictureLongDate`, /// \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. ///


/// @skinning_v13 **[New Infolabel]** \link ListItem_PictureLongDate `ListItem.PictureLongDate`\endlink ///

/// } /// \table_row3{ `ListItem.PictureLongDatetime`, /// \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. ///

/// } /// \table_row3{ `ListItem.PictureMeteringMode`, /// \anchor ListItem_PictureMeteringMode /// _string_, /// @return The metering mode used when the selected picture was taken. The /// possible values are: /// - "Center weight" /// - "Spot" /// - "Matrix" /// @note This is the value of the EXIF MeteringMode tag (hex code 0x9207). ///


/// @skinning_v13 **[New Infolabel]** \link ListItem_PictureMeteringMode `ListItem.PictureMeteringMode`\endlink ///

/// } /// \table_row3{ `ListItem.PictureObjectName`, /// \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). ///


/// @skinning_v13 **[New Infolabel]** \link ListItem_PictureObjectName `ListItem.PictureObjectName`\endlink ///

/// } /// \table_row3{ `ListItem.PictureOrientation`, /// \anchor ListItem_PictureOrientation /// _string_, /// @return The orientation of the selected picture. Possible values are: /// - "Top Left" /// - "Top Right" /// - "Left Top" /// - "Right Bottom" /// - etc /// @note This is the value of the EXIF Orientation tag (hex code 0x0112). ///


/// @skinning_v13 **[New Infolabel]** \link ListItem_PictureOrientation `ListItem.PictureOrientation`\endlink ///

/// } /// \table_row3{ `ListItem.PicturePath`, /// \anchor ListItem_PicturePath /// _string_, /// @return The filename and path of the selected picture. ///

/// } /// \table_row3{ `ListItem.PictureProcess`, /// \anchor ListItem_PictureProcess /// _string_, /// @return The process used to compress the selected picture. ///


/// @skinning_v13 **[New Infolabel]** \link ListItem_PictureProcess `ListItem.PictureProcess`\endlink ///

/// } /// \table_row3{ `ListItem.PictureReferenceService`, /// \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). ///


/// @skinning_v13 **[New Infolabel]** \link ListItem_PictureReferenceService `ListItem.PictureReferenceService`\endlink ///

/// } /// \table_row3{ `ListItem.PictureResolution`, /// \anchor ListItem_PictureResolution /// _string_, /// @return The dimensions of the selected picture. ///

/// } /// \table_row3{ `ListItem.PictureSource`, /// \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). ///


/// @skinning_v13 **[New Infolabel]** \link ListItem_PictureSource `ListItem.PictureSource`\endlink ///

/// } /// \table_row3{ `ListItem.PictureSpecialInstructions`, /// \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). ///


/// @skinning_v13 **[New Infolabel]** \link ListItem_PictureSpecialInstructions `ListItem.PictureSpecialInstructions`\endlink ///

/// } /// \table_row3{ `ListItem.PictureState`, /// \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). ///


/// @skinning_v13 **[New Infolabel]** \link ListItem_PictureState `ListItem.PictureState`\endlink ///

/// } /// \table_row3{ `ListItem.PictureSublocation`, /// \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). ///


/// @skinning_v13 **[New Infolabel]** \link ListItem_PictureSublocation `ListItem.PictureSublocation`\endlink ///

/// } /// \table_row3{ `ListItem.PictureSupplementalCategories`, /// \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). ///


/// @skinning_v13 **[New Infolabel]** \link ListItem_PictureSupplementalCategories `ListItem.PictureSupplementalCategories`\endlink ///

/// } /// \table_row3{ `ListItem.PictureTransmissionReference`, /// \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). ///


/// @skinning_v13 **[New Infolabel]** \link ListItem_PictureTransmissionReference `ListItem.PictureTransmissionReference`\endlink ///

/// } /// \table_row3{ `ListItem.PictureUrgency`, /// \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). ///


/// @skinning_v13 **[New Infolabel]** \link ListItem_PictureUrgency `ListItem.PictureUrgency`\endlink ///

/// } /// \table_row3{ `ListItem.PictureWhiteBalance`, /// \anchor ListItem_PictureWhiteBalance /// _string_, /// @return The white balance mode set when the selected picture was taken. /// The possible values are: /// - "Manual" /// - "Auto" /// @note This is the value of the EXIF WhiteBalance tag (hex code 0xA403). ///


/// @skinning_v13 **[New Infolabel]** \link ListItem_PictureWhiteBalance `ListItem.PictureWhiteBalance`\endlink ///

/// } /// \table_row3{ `ListItem.FileName`, /// \anchor ListItem_FileName /// _string_, /// @return The filename of the currently selected song or movie in a container. ///

/// } /// \table_row3{ `ListItem.Path`, /// \anchor ListItem_Path /// _string_, /// @return The complete path of the currently selected song or movie in a /// container. ///

/// } /// \table_row3{ `ListItem.FolderName`, /// \anchor ListItem_FolderName /// _string_, /// @return The top most folder of the path of the currently selected song or /// movie in a container. ///

/// } /// \table_row3{ `ListItem.FolderPath`, /// \anchor ListItem_FolderPath /// _string_, /// @return The complete path of the currently selected song or movie in a /// container (without user details). ///

/// } /// \table_row3{ `ListItem.FileNameAndPath`, /// \anchor ListItem_FileNameAndPath /// _string_, /// @return The full path with filename of the currently selected song or /// movie in a container. ///

/// } /// \table_row3{ `ListItem.FileExtension`, /// \anchor ListItem_FileExtension /// _string_, /// @return The file extension (without leading dot) of the currently selected /// item in a container. ///

/// } /// \table_row3{ `ListItem.FileNameNoExtension`, /// \anchor ListItem_FileName_No_Extension /// _string_, /// @return The filename without extension of the currently selected /// item in a container. ///


/// @skinning_v19 **[New Infolabel]** \link ListItem_FileName_No_Extension `ListItem.FileNameNoExtension`\endlink ///

/// } /// \table_row3{ `ListItem.Date`, /// \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). ///

/// } /// \table_row3{ `ListItem.DateTime`, /// \anchor ListItem_DateTime /// _string_, /// @return The date and time a certain event happened (event log). ///


/// @skinning_v16 **[New Infolabel]** \link ListItem_DateTime `ListItem.DateTime`\endlink ///

/// } /// \table_row3{ `ListItem.DateAdded`, /// \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. ///

/// } /// \table_row3{ `ListItem.Size`, /// \anchor ListItem_Size /// _string_, /// @return The file size of the currently selected song or movie in a /// container. ///

/// } /// \table_row3{ `ListItem.Rating([name])`, /// \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. ///


/// @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. ///

/// } /// \table_row3{ `ListItem.Set`, /// \anchor ListItem_Set /// _string_, /// @return The name of the set the movie is part of. ///


/// @skinning_v17 **[New Infolabel]** \link ListItem_Set `ListItem.Set`\endlink ///

/// } /// \table_row3{ `ListItem.SetId`, /// \anchor ListItem_SetId /// _string_, /// @return The id of the set the movie is part of. ///


/// @skinning_v17 **[New Infolabel]** \link ListItem_SetId `ListItem.SetId`\endlink ///

/// } /// \table_row3{ `ListItem.Status`, /// \anchor ListItem_Status /// _string_, /// @return One of the following status: /// - "returning series" /// - "in production" /// - "planned" /// - "cancelled" /// - "ended" ///

/// @note For use with tv shows. ///


/// @skinning_v17 **[New Infolabel]** \link ListItem_Status `ListItem.Status`\endlink ///

/// } /// \table_row3{ `ListItem.EndTimeResume`, /// \anchor ListItem_EndTimeResume /// _string_, /// @return Returns the time a video will end if you resume it\, instead of playing it from the beginning. ///


/// @skinning_v17 **[New Infolabel]** \link ListItem_EndTimeResume `ListItem.EndTimeResume`\endlink ///

/// } /// \table_row3{ `ListItem.UserRating`, /// \anchor ListItem_UserRating /// _string_, /// @return The user rating of the currently selected item in a container (1-10). ///


/// @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 ///

/// } /// \table_row3{ `ListItem.Votes([name])`, /// \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`. ///


/// @skinning_v17 **[Infolabel Updated]** \link ListItem_Votes `ListItem.Votes([name])`\endlink /// add optional param name to specify the scrapper. /// @skinning_v13 **[New Infolabel]** \link ListItem_Votes `ListItem.Votes`\endlink ///

/// } /// \table_row3{ `ListItem.RatingAndVotes([name])`, /// \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`. ///


/// @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. ///

/// } /// \table_row3{ `ListItem.Mood`, /// \anchor ListItem_Mood /// _string_, /// @return The mood of the selected song. ///


/// @skinning_v17 **[New Infolabel]** \link ListItem_Mood `ListItem.Mood`\endlink ///

/// } /// \table_row3{ `ListItem.Mpaa`, /// \anchor ListItem_Mpaa /// _string_, /// @return The MPAA rating of the currently selected movie in a container. ///

/// } /// \table_row3{ `ListItem.ProgramCount`, /// \anchor ListItem_ProgramCount /// _string_, /// @return The number of times an xbe has been run from "my programs". /// @todo description might be outdated ///

/// } /// \table_row3{ `ListItem.Duration`, /// \anchor ListItem_Duration /// _string_, /// @return The duration of the currently selected item in a container /// in the format hh:mm:ss. /// @note hh: will be omitted if hours value is zero. ///


/// @skinning_v18 **[Infolabel Updated]** \link ListItem_Duration `ListItem.Duration`\endlink will /// return hh:mm:ss instead of the duration in minutes. ///

/// } /// \table_row3{ `ListItem.Duration(format)`, /// \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. ///

/// } /// \table_row3{ `ListItem.DBTYPE`, /// \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. ///


/// @skinning_v17 **[Infolabel Updated]** \link ListItem_DBTYPE `ListItem.DBTYPE`\endlink /// now available in the music library. ///

/// } /// \table_row3{ `ListItem.DBID`, /// \anchor ListItem_DBID /// _string_, /// @return The database id of the currently selected listitem in a container. ///

/// } /// \table_row3{ `ListItem.Appearances`, /// \anchor ListItem_Appearances /// _string_, /// @return The number of movies featuring the selected actor / directed by the selected director. ///


/// @skinning_v17 **[New Infolabel]** \link ListItem_Appearances `ListItem.Appearances`\endlink ///

/// } /// \table_row3{ `ListItem.Cast`, /// \anchor ListItem_Cast /// _string_, /// @return A concatenated string of cast members of the currently selected /// movie\, for use in dialogvideoinfo.xml. ///


/// @skinning_v15 **[Infolabel Updated]** \link ListItem_Cast `ListItem.Cast`\endlink /// also supports EPG. ///

/// } /// \table_row3{ `ListItem.CastAndRole`, /// \anchor ListItem_CastAndRole /// _string_, /// @return A concatenated string of cast members and roles of the currently /// selected movie\, for use in dialogvideoinfo.xml. ///

/// } /// \table_row3{ `ListItem.Studio`, /// \anchor ListItem_Studio /// _string_, /// @return The studio of current selected Music Video in a container. ///

/// } /// \table_row3{ `ListItem.Top250`, /// \anchor ListItem_Top250 /// _string_, /// @return The IMDb top250 position of the currently selected listitem in a /// container. ///

/// } /// \table_row3{ `ListItem.Trailer`, /// \anchor ListItem_Trailer /// _string_, /// @return The full trailer path with filename of the currently selected /// movie in a container. ///

/// } /// \table_row3{ `ListItem.Writer`, /// \anchor ListItem_Writer /// _string_, /// @return The name of Writer of current Video in a container. ///


/// @skinning_v15 **[Infolabel Updated]** \link ListItem_Writer `ListItem.Writer`\endlink /// also supports EPG. ///

/// } /// \table_row3{ `ListItem.Tag`, /// \anchor ListItem_Tag /// _string_, /// @return The summary of current Video in a container. ///


/// @skinning_v17 **[New Infolabel]** \link ListItem_Tag `ListItem.Tag`\endlink ///

/// } /// \table_row3{ `ListItem.Tagline`, /// \anchor ListItem_Tagline /// _string_, /// @return A Small Summary of current Video in a container. ///

/// } /// \table_row3{ `ListItem.PlotOutline`, /// \anchor ListItem_PlotOutline /// _string_, /// @return A small Summary of current Video in a container. ///

/// } /// \table_row3{ `ListItem.Plot`, /// \anchor ListItem_Plot /// _string_, /// @return The complete Text Summary of Video in a container. ///

/// } /// \table_row3{ `ListItem.IMDBNumber`, /// \anchor ListItem_IMDBNumber /// _string_, /// @return The IMDb ID of the selected Video in a container. ///


/// @skinning_v15 **[New Infolabel]** \link ListItem_IMDBNumber `ListItem.IMDBNumber`\endlink ///

/// } /// \table_row3{ `ListItem.EpisodeName`, /// \anchor ListItem_EpisodeName /// _string_, /// @return The name of the episode if the selected EPG item is a TV Show (PVR). ///


/// @skinning_v15 **[New Infolabel]** \link ListItem_EpisodeName `ListItem.EpisodeName`\endlink ///

/// } /// \table_row3{ `ListItem.PercentPlayed`, /// \anchor ListItem_PercentPlayed /// _string_, /// @return The percentage value [0-100] of how far the selected video has been /// played. ///

/// } /// \table_row3{ `ListItem.LastPlayed`, /// \anchor ListItem_LastPlayed /// _string_, /// @return The last play date of Video in a container. ///

/// } /// \table_row3{ `ListItem.PlayCount`, /// \anchor ListItem_PlayCount /// _string_, /// @return The playcount of Video in a container. ///

/// } /// \table_row3{ `ListItem.ChannelName`, /// \anchor ListItem_ChannelName /// _string_, /// @return The name of current selected TV channel in a container. ///

/// } /// \table_row3{ `ListItem.VideoCodec`, /// \anchor ListItem_VideoCodec /// _string_, /// @return The video codec of the currently selected video. Common values: /// - 3iv2 /// - av1 /// - avc1 /// - div2 /// - div3 /// - divx /// - divx 4 /// - dx50 /// - flv /// - h264 /// - microsoft /// - mp42 /// - mp43 /// - mp4v /// - mpeg1video /// - mpeg2video /// - mpg4 /// - rv40 /// - svq1 /// - svq3 /// - theora /// - vp6f /// - wmv2 /// - wmv3 /// - wvc1 /// - xvid /// - etc ///

/// } /// \table_row3{ `ListItem.VideoResolution`, /// \anchor ListItem_VideoResolution /// _string_, /// @return The resolution of the currently selected video. Possible values: /// - 480 /// - 576 /// - 540 /// - 720 /// - 1080 /// - 4K /// - 8K /// @note 540 usually means a widescreen /// format (around 960x540) while 576 means PAL resolutions (normally /// 720x576)\, therefore 540 is actually better resolution than 576. ///


/// @skinning_v18 **[Updated Infolabel]** \link ListItem_VideoResolution ListItem.VideoResolution\endlink /// added 8K as a possible value. ///

/// } /// \table_row3{ `ListItem.VideoAspect`, /// \anchor ListItem_VideoAspect /// _string_, /// @return The aspect ratio of the currently selected video. Possible values: /// - 1.00 /// - 1.19 /// - 1.33 /// - 1.37 /// - 1.66 /// - 1.78 /// - 1.85 /// - 2.00 /// - 2.20 /// - 2.35 /// - 2.40 /// - 2.55 /// - 2.76 ///

/// } /// \table_row3{ `ListItem.AudioCodec`, /// \anchor ListItem_AudioCodec /// _string_, /// @return The audio codec of the currently selected video. Common values: /// - aac /// - ac3 /// - cook /// - dca /// - dtshd_hra /// - dtshd_ma /// - eac3 /// - mp1 /// - mp2 /// - mp3 /// - pcm_s16be /// - pcm_s16le /// - pcm_u8 /// - truehd /// - vorbis /// - wmapro /// - wmav2 ///

/// } /// \table_row3{ `ListItem.AudioChannels`, /// \anchor ListItem_AudioChannels /// _string_, /// @return The number of audio channels of the currently selected video. Possible values: /// - 1 /// - 2 /// - 4 /// - 5 /// - 6 /// - 8 /// - 10 ///


/// @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) ///

/// } /// \table_row3{ `ListItem.AudioLanguage`, /// \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) ///

/// } /// \table_row3{ `ListItem.SubtitleLanguage`, /// \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) ///

/// } /// \table_row3{ `ListItem.Property(AudioCodec.[n])`, /// \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") ///


/// @skinning_v16 **[New Infolabel]** \link ListItem_Property_AudioCodec `ListItem.Property(AudioCodec.[n])`\endlink ///

/// } /// \table_row3{ `ListItem.Property(AudioChannels.[n])`, /// \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") ///


/// @skinning_v16 **[New Infolabel]** \link ListItem_Property_AudioChannels `ListItem.Property(AudioChannels.[n])`\endlink ///

/// } /// \table_row3{ `ListItem.Property(AudioLanguage.[n])`, /// \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") ///


/// @skinning_v16 **[New Infolabel]** \link ListItem_Property_AudioLanguage `ListItem.Property(AudioLanguage.[n])`\endlink ///

/// } /// \table_row3{ `ListItem.Property(SubtitleLanguage.[n])`, /// \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") ///


/// @skinning_v16 **[New Infolabel]** \link ListItem_Property_SubtitleLanguage `ListItem.Property(SubtitleLanguage.[n])`\endlink ///

/// } /// \table_row3{ `ListItem.Property(Addon.Disclaimer)`, /// \anchor ListItem_Property_AddonDisclaimer /// _string_, /// @return The disclaimer of the currently selected addon. ///

/// } /// \table_row3{ `ListItem.Property(Addon.Changelog)`, /// \anchor ListItem_Property_AddonChangelog /// _string_, /// @return The changelog of the currently selected addon. ///

/// } /// \table_row3{ `ListItem.Property(Addon.ID)`, /// \anchor ListItem_Property_AddonID /// _string_, /// @return The identifier of the currently selected addon. ///

/// } /// \table_row3{ `ListItem.Property(Addon.Status)`, /// \anchor ListItem_Property_AddonStatus /// _string_, /// @return The status of the currently selected addon. /// @todo missing reference in GuiInfoManager.cpp making it hard to track. ///

/// } /// \table_row3{ `ListItem.Property(Addon.Orphaned)`, /// \anchor ListItem_Property_AddonOrphaned /// _boolean_, /// @return **True** if the Addon is orphanad. /// @todo missing reference in GuiInfoManager.cpp making it hard to track. ///


/// @skinning_v17 **[New Boolean Condition]** \link ListItem_Property_AddonOrphaned `ListItem.Property(Addon.Orphaned)`\endlink ///

/// } /// \table_row3{ `ListItem.Property(Addon.Path)`, /// \anchor ListItem_Property_AddonPath /// _string_, /// @return The path of the currently selected addon. ///

/// } /// \table_row3{ `ListItem.StartTime`, /// \anchor ListItem_StartTime /// _string_, /// @return The start time of current selected TV programme in a container. ///

/// } /// \table_row3{ `ListItem.EndTime`, /// \anchor ListItem_EndTime /// _string_, /// @return The end time of current selected TV programme in a container. ///

/// } /// \table_row3{ `ListItem.StartDate`, /// \anchor ListItem_StartDate /// _string_, /// @return The start date of current selected TV programme in a container. ///

/// } /// \table_row3{ `ListItem.EndDate`, /// \anchor ListItem_EndDate /// _string_, /// @return The end date of current selected TV programme in a container. ///

/// } /// \table_row3{ `ListItem.NextTitle`, /// \anchor ListItem_NextTitle /// _string_, /// @return The title of the next item (PVR). ///

/// } /// \table_row3{ `ListItem.NextGenre`, /// \anchor ListItem_NextGenre /// _string_, /// @return The genre of the next item (PVR). ///

/// } /// \table_row3{ `ListItem.NextPlot`, /// \anchor ListItem_NextPlot /// _string_, /// @return The plot of the next item (PVR). ///

/// } /// \table_row3{ `ListItem.NextPlotOutline`, /// \anchor ListItem_NextPlotOutline /// _string_, /// @return The plot outline of the next item (PVR). ///

/// } /// \table_row3{ `ListItem.NextStartTime`, /// \anchor ListItem_NextStartTime /// _string_, /// @return The start time of the next item (PVR). ///

/// } /// \table_row3{ `ListItem.NextEndTime`, /// \anchor ListItem_NextEndTime /// _string_, /// @return The end of the next item (PVR). ///

/// } /// \table_row3{ `ListItem.NextStartDate`, /// \anchor ListItem_NextStartDate /// _string_, /// @return The start date of the next item (PVR). ///

/// } /// \table_row3{ `ListItem.NextEndDate`, /// \anchor ListItem_NextEndDate /// _string_, /// @return The end date of the next item (PVR). ///

/// } /// \table_row3{ `ListItem.NextDuration`, /// \anchor ListItem_NextDuration /// _string_, /// @return The duration of the next item (PVR) in the format hh:mm:ss. /// @note hh: will be omitted if hours value is zero. ///


/// @skinning_v18 **[New Infolabel]** \link ListItem_NextDuration `ListItem.NextDuration`\endlink ///

/// } /// \table_row3{ `ListItem.NextDuration(format)`, /// \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. ///


/// @skinning_v18 **[New Infolabel]** \link ListItem_NextDuration_format `ListItem.NextDuration(format)`\endlink ///

/// } /// \table_row3{ `ListItem.ChannelGroup`, /// \anchor ListItem_ChannelGroup /// _string_, /// @return The channel group of the selected item (PVR). ///

/// } /// \table_row3{ `ListItem.ChannelNumberLabel`, /// \anchor ListItem_ChannelNumberLabel /// _string_, /// @return The channel and subchannel number of the currently selected channel that's /// currently playing (PVR). ///


/// @skinning_v14 **[New Infolabel]** \link ListItem_ChannelNumberLabel `ListItem.ChannelNumberLabel`\endlink ///

/// } /// \table_row3{ `ListItem.Progress`, /// \anchor ListItem_Progress /// _string_, /// @return The part of the programme that's been played (PVR). ///

/// } /// \table_row3{ `ListItem.StereoscopicMode`, /// \anchor ListItem_StereoscopicMode /// _string_, /// @return The stereomode of the selected video: /// - mono /// - split_vertical /// - split_horizontal /// - row_interleaved /// - anaglyph_cyan_red /// - anaglyph_green_magenta ///


/// @skinning_v13 **[New Infolabel]** \link ListItem_StereoscopicMode `ListItem.StereoscopicMode`\endlink ///

/// } /// \table_row3{ `ListItem.HasTimerSchedule`, /// \anchor ListItem_HasTimerSchedule /// _boolean_, /// @return **True** if the item was scheduled by a timer rule (PVR). ///


/// @skinning_v16 **[New Boolean Condition]** \ref ListItem_HasTimerSchedule "ListItem.HasTimerSchedule" ///

/// } /// \table_row3{ `ListItem.HasReminder`, /// \anchor ListItem_HasReminder /// _boolean_, /// @return **True** if the item has a reminder set (PVR). ///


/// @skinning_v19 **[New Boolean Condition]** \ref ListItem_HasReminder "ListItem.HasReminder" ///

/// } /// \table_row3{ `ListItem.HasReminderRule`, /// \anchor ListItem_ListItem.HasReminderRule /// _boolean_, /// @return **True** if the item was scheduled by a reminder timer rule (PVR). ///


/// @skinning_v19 **[New Boolean Condition]** \ref ListItem_HasReminderRule "ListItem.HasReminderRule" ///

/// } /// \table_row3{ `ListItem.HasRecording`, /// \anchor ListItem_HasRecording /// _boolean_, /// @return **True** if a given epg tag item currently gets recorded or has been recorded. ///

/// } /// \table_row3{ `ListItem.TimerHasError`, /// \anchor ListItem_TimerHasError /// _boolean_, /// @return **True** if the item has a timer and it won't be recorded because of an error (PVR). ///


/// @skinning_v17 **[New Boolean Condition]** \ref ListItem_TimerHasError "ListItem.TimerHasError" ///

/// } /// \table_row3{ `ListItem.TimerHasConflict`, /// \anchor ListItem_TimerHasConflict /// _boolean_, /// @return **True** if the item has a timer and it won't be recorded because of a conflict (PVR). ///


/// @skinning_v17 **[New Boolean Condition]** \ref ListItem_TimerHasConflict "ListItem.TimerHasConflict" ///

/// } /// \table_row3{ `ListItem.TimerIsActive`, /// \anchor ListItem_TimerIsActive /// _boolean_, /// @return **True** if the item has a timer that will be recorded\, i.e. the timer is enabled (PVR). ///


/// @skinning_v17 **[New Boolean Condition]** \ref ListItem_TimerIsActive "ListItem.TimerIsActive" ///

/// } /// \table_row3{ `ListItem.Comment`, /// \anchor ListItem_Comment /// _string_, /// @return The comment assigned to the item (PVR/MUSIC). ///

/// } /// \table_row3{ `ListItem.TimerType`, /// \anchor ListItem_TimerType /// _string_, /// @return The type of the PVR timer / timer rule item as a human readable string. ///

/// } /// \table_row3{ `ListItem.EpgEventTitle`, /// \anchor ListItem_EpgEventTitle /// _string_, /// @return The title of the epg event associated with the item\, if any. ///

/// } /// \table_row3{ `ListItem.EpgEventIcon`, /// \anchor ListItem_EpgEventIcon /// _string_, /// @return The thumbnail for the EPG event associated with the item (if it exists). ///


/// @skinning_v18 **[New Infolabel]** \link ListItem_EpgEventIcon `ListItem.EpgEventIcon`\endlink ///

/// } /// \table_row3{ `ListItem.InProgress`, /// \anchor ListItem_InProgress /// _boolean_, /// @return **True** if the EPG event item is currently active (time-wise). ///

/// } /// \table_row3{ `ListItem.IsParentFolder`, /// \anchor ListItem_IsParentFolder /// _boolean_, /// @return **True** if the current list item is the goto parent folder '..'. ///


/// @skinning_v17 **[New Boolean Condition]** \link ListItem_IsParentFolder `ListItem.IsParentFolder`\endlink ///

/// } /// \table_row3{ `ListItem.AddonName`, /// \anchor ListItem_AddonName /// _string_, /// @return The name of the currently selected addon. ///


/// @skinning_v17 **[Infolabel Updated]** \link ListItem_AddonName `ListItem.AddonName`\endlink /// replaces `ListItem.Property(Addon.Name)`. ///

/// } /// \table_row3{ `ListItem.AddonVersion`, /// \anchor ListItem_AddonVersion /// _string_, /// @return The version of the currently selected addon. ///


/// @skinning_v17 **[Infolabel Updated]** \link ListItem_AddonVersion `ListItem.AddonVersion`\endlink /// replaces `ListItem.Property(Addon.Version)`. ///

/// } /// \table_row3{ `ListItem.AddonCreator`, /// \anchor ListItem_AddonCreator /// _string_, /// @return The name of the author the currently selected addon. ///


/// @skinning_v17 **[Infolabel Updated]** \link ListItem_AddonCreator `ListItem.AddonCreator`\endlink /// replaces `ListItem.Property(Addon.Creator)`. ///

/// } /// \table_row3{ `ListItem.AddonSummary`, /// \anchor ListItem_AddonSummary /// _string_, /// @return A short description of the currently selected addon. ///


/// @skinning_v17 **[Infolabel Updated]** \link ListItem_AddonSummary `ListItem.AddonSummary`\endlink /// replaces `ListItem.Property(Addon.Summary)`. ///

/// } /// \table_row3{ `ListItem.AddonDescription`, /// \anchor ListItem_AddonDescription /// _string_, /// @return The full description of the currently selected addon. ///


/// @skinning_v17 **[Infolabel Updated]** \link ListItem_AddonDescription `ListItem.AddonDescription`\endlink /// replaces `ListItem.Property(Addon.Description)`. ///

/// } /// \table_row3{ `ListItem.AddonDisclaimer`, /// \anchor ListItem_AddonDisclaimer /// _string_, /// @return The disclaimer of the currently selected addon. ///


/// @skinning_v17 **[Infolabel Updated]** \link ListItem_AddonDisclaimer `ListItem.AddonDisclaimer`\endlink /// replaces `ListItem.Property(Addon.Disclaimer)`. ///

/// } /// \table_row3{ `ListItem.AddonBroken`, /// \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 ///


/// @skinning_v17 **[Infolabel Updated]** \link ListItem_AddonBroken `ListItem.AddonBroken`\endlink /// replaces `ListItem.Property(Addon.Broken)`. ///

/// } /// \table_row3{ `ListItem.AddonLifecycleType`, /// \anchor ListItem_AddonLifecycleType /// _string_, /// @return String name when the addon is marked as special condition in the repo. /// - Label: 24169 (Normal) - Used if an add-on has no special lifecycle state which is the default state /// - Label: 24170 (Deprecated) - The add-on should be marked as deprecated but is still usable /// - Label: 24171 (Broken) - The add-on should marked as broken in the repository ///


/// @skinning_v19 **[New Infolabel]** \link ListItem_AddonLifecycleType `ListItem.AddonLifecycleType`\endlink /// replaces `ListItem.AddonBroken`. ///

/// } /// \table_row3{ `ListItem.AddonLifecycleDesc`, /// \anchor ListItem_AddonLifecycleDesc /// _string_, /// @return From addon defined message text when it is marked as special condition inside repository. ///


/// @skinning_v19 **[New Infolabel]** \link ListItem_AddonLifecycleDesc `ListItem.AddonLifecycleDesc``\endlink /// replaces `ListItem.AddonBroken`. ///

/// } /// \table_row3{ `ListItem.AddonType`, /// \anchor ListItem_AddonType /// _string_, /// @return The type (screensaver\, script\, skin\, etc...) of the currently selected addon. ///


/// @skinning_v17 **[Infolabel Updated]** \link ListItem_AddonType `ListItem.AddonType`\endlink /// replaces `ListItem.Property(Addon.Type)`. ///

/// } /// \table_row3{ `ListItem.AddonInstallDate`, /// \anchor ListItem_AddonInstallDate /// _string_, /// @return The date the addon was installed. ///


/// @skinning_v17 **[New Infolabel]** \link ListItem_AddonInstallDate `ListItem.AddonInstallDate`\endlink ///

/// } /// \table_row3{ `ListItem.AddonLastUpdated`, /// \anchor ListItem_AddonLastUpdated /// _string_, /// @return The date the addon was last updated. ///


/// @skinning_v17 **[New Infolabel]** \link ListItem_AddonLastUpdated `ListItem.AddonLastUpdated`\endlink ///

/// } /// \table_row3{ `ListItem.AddonLastUsed`, /// \anchor ListItem_AddonLastUsed /// _string_, /// @return The date the addon was used last. ///


/// @skinning_v17 **[New Infolabel]** \link ListItem_AddonLastUsed `ListItem.AddonLastUsed`\endlink ///

/// } /// \table_row3{ `ListItem.AddonNews`, /// \anchor ListItem_AddonNews /// _string_, /// @return A brief changelog\, taken from the addons' `addon.xml` file. ///


/// @skinning_v17 **[New Infolabel]** \link ListItem_AddonNews `ListItem.AddonNews`\endlink ///

/// } /// \table_row3{ `ListItem.AddonSize`, /// \anchor ListItem_AddonSize /// _string_, /// @return The filesize of the addon. ///


/// @skinning_v17 **[New Infolabel]** \link ListItem_AddonSize `ListItem.AddonSize`\endlink ///

/// } /// \table_row3{ `ListItem.AddonOrigin`, /// \anchor ListItem_AddonOrigin /// _string_, /// @return The name of the repository the add-on originates from. ///

/// } /// \table_row3{ `ListItem.ExpirationDate`, /// \anchor ListItem_ExpirationDate /// _string_, /// @return The expiration date of the selected item in a container\, empty string if not supported. ///

/// } /// \table_row3{ `ListItem.ExpirationTime`, /// \anchor ListItem_ExpirationTime /// _string_, /// @return The expiration time of the selected item in a container\, empty string if not supported ///

/// } /// \table_row3{ `ListItem.Art(type)`, /// \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: /// - clearart - the clearart (if it exists) of the currently selected movie or tv show. /// - clearlogo - the clearlogo (if it exists) of the currently selected movie or tv show. /// - landscape - the 16:9 landscape (if it exists) of the currently selected item. /// - thumb - the thumbnail of the currently selected item. /// - poster - the poster of the currently selected movie or tv show. /// - banner - the banner of the currently selected tv show. /// - fanart - the fanart image of the currently selected item. /// - set.fanart - the fanart image of the currently selected movieset. /// - tvshow.poster - the tv show poster of the parent container. /// - tvshow.banner - the tv show banner of the parent container. /// - tvshow.clearlogo - the tv show clearlogo (if it exists) of the parent container. /// - tvshow.landscape - the tv show landscape (if it exists) of the parent container. /// - tvshow.clearart - the tv show clearart (if it exists) of the parent container. /// - season.poster - the season poster of the currently selected season. (Only available in DialogVideoInfo.xml). /// - season.banner - the season banner of the currently selected season. (Only available in DialogVideoInfo.xml). /// - season.fanart - the fanart image of the currently selected season. (Only available in DialogVideoInfo.xml) /// - artist.thumb - the artist thumb of an album or song item. /// - artist.fanart - the artist fanart of an album or song item. /// - album.thumb - the album thumb (cover) of a song item. /// - artist[n].* - 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. /// - albumartist[n].* - 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. ///

/// @todo Find a better way of finding the art types instead of manually defining them here. ///


/// @skinning_v18 **[Infolabel Updated]** \link ListItem_Art_Type `ListItem.Art(type)`\endlink add artist[n].* and /// albumartist[n].* as possible targets for type ///

/// } /// \table_row3{ `ListItem.Platform`, /// \anchor ListItem_Platform /// _string_, /// @return The game platform (e.g. "Atari 2600") (RETROPLAYER). ///


/// @skinning_v18 **[New Infolabel]** \link ListItem_Platform `ListItem.Platform`\endlink ///

/// } /// \table_row3{ `ListItem.Genres`, /// \anchor ListItem_Genres /// _string_, /// @return The game genres (e.g. "["Action"\,"Strategy"]") (RETROPLAYER). ///


/// @skinning_v18 **[New Infolabel]** \link ListItem_Genres `ListItem.Genres`\endlink ///

/// } /// \table_row3{ `ListItem.Publisher`, /// \anchor ListItem_Publisher /// _string_, /// @return The game publisher (e.g. "Nintendo") (RETROPLAYER). ///


/// @skinning_v18 **[New Infolabel]** \link ListItem_Publisher `ListItem.Publisher`\endlink ///

/// } /// \table_row3{ `ListItem.Developer`, /// \anchor ListItem_Developer /// _string_, /// @return The game developer (e.g. "Square") (RETROPLAYER). ///


/// @skinning_v18 **[New Infolabel]** \link ListItem_Developer `ListItem.Developer`\endlink ///

/// } /// \table_row3{ `ListItem.Overview`, /// \anchor ListItem_Overview /// _string_, /// @return The game overview/summary (RETROPLAYER). ///


/// @skinning_v18 **[New Infolabel]** \link ListItem_Overview `ListItem.Overview`\endlink ///

/// } /// \table_row3{ `ListItem.GameClient`, /// \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). ///


/// @skinning_v18 **[New Infolabel]** \link ListItem_GameClient `ListItem.GameClient`\endlink ///

/// } /// \table_row3{ `ListItem.Property(propname)`, /// \anchor ListItem_Property_Propname /// _string_, /// @return The requested property of a ListItem. /// @param propname - the property requested ///

/// } /// \table_row3{ `ListItem.Property(Role.Composer)`, /// \anchor ListItem_Property_Role_Composer /// _string_, /// @return The name of the person who composed the selected song. ///


/// @skinning_v17 **[New Infolabel]** \link ListItem_Property_Role_Composer `ListItem.Property(Role.Composer)`\endlink ///

/// } /// \table_row3{ `ListItem.Property(Role.Conductor)`, /// \anchor ListItem_Property_Role_Conductor /// _string_, /// @return The name of the person who conducted the selected song. ///


/// @skinning_v17 **[New Infolabel]** \link ListItem_Property_Role_Conductor `ListItem.Property(Role.Conductor)`\endlink ///

/// } /// \table_row3{ `ListItem.Property(Role.Orchestra)`, /// \anchor ListItem_Property_Role_Orchestra /// _string_, /// @return The name of the orchestra performing the selected song. ///


/// @skinning_v17 **[New Infolabel]** \link ListItem_Property_Role_Orchestra `ListItem.Property(Role.Orchestra)`\endlink ///

/// } /// \table_row3{ `ListItem.Property(Role.Lyricist)`, /// \anchor ListItem_Property_Role_Lyricist /// _string_, /// @return The name of the person who wrote the lyrics of the selected song. ///


/// @skinning_v17 **[New Infolabel]** \link ListItem_Property_Role_Lyricist `ListItem.Property(Role.Lyricist)`\endlink ///

/// } /// \table_row3{ `ListItem.Property(Role.Remixer)`, /// \anchor ListItem_Property_Role_Remixer /// _string_, /// @return The name of the person who remixed the selected song. ///


/// @skinning_v17 **[New Infolabel]** \link ListItem_Property_Role_Remixer `ListItem.Property(Role.Remixer)`\endlink ///

/// } /// \table_row3{ `ListItem.Property(Role.Arranger)`, /// \anchor ListItem_Property_Role_Arranger /// _string_, /// @return The name of the person who arranged the selected song. ///


/// @skinning_v17 **[New Infolabel]** \link ListItem_Property_Role_Arranger `ListItem.Property(Role.Arranger)`\endlink ///

/// } /// \table_row3{ `ListItem.Property(Role.Engineer)`, /// \anchor ListItem_Property_Role_Engineer /// _string_, /// @return The name of the person who was the engineer of the selected song. ///


/// @skinning_v17 **[New Infolabel]** \link ListItem_Property_Role_Engineer `ListItem.Property(Role.Engineer)`\endlink ///

/// } /// \table_row3{ `ListItem.Property(Role.Producer)`, /// \anchor ListItem_Property_Role_Producer /// _string_, /// @return The name of the person who produced the selected song. ///


/// @skinning_v17 **[New Infolabel]** \link ListItem_Property_Role_Producer `ListItem.Property(Role.Producer)`\endlink ///

/// } /// \table_row3{ `ListItem.Property(Role.DJMixer)`, /// \anchor ListItem_Property_Role_DJMixer /// _string_, /// @return The name of the dj who remixed the selected song. ///


/// @skinning_v17 **[New Infolabel]** \link ListItem_Property_Role_DJMixer `ListItem.Property(Role.DJMixer)`\endlink ///

/// } /// \table_row3{ `ListItem.Property(Role.Mixer)`, /// \anchor ListItem_Property_Role_Mixer /// _string_, /// @return The name of the person who mixed the selected song. ///


/// @skinning_v17 **[New Infolabel]** \link ListItem_Property_Role_DJMixer `ListItem.Property(Role.DJMixer)`\endlink ///

/// } /// \table_row3{ `ListItem.Property(Game.VideoFilter)`, /// \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. ///


/// @skinning_v18 **[New Infolabel]** \link ListItem_Property_Game_VideoFilter `ListItem.Property(Game.VideoFilter)`\endlink ///

/// } /// \table_row3{ `ListItem.Property(Game.StretchMode)`, /// \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. ///


/// @skinning_v18 **[New Infolabel]** \link ListItem_Property_Game_StretchMode `ListItem.Property(Game.StretchMode)`\endlink ///

/// } /// \table_row3{ `ListItem.Property(Game.VideoRotation)`, /// \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. ///


/// @skinning_v18 **[New Infolabel]** \link ListItem_Property_Game_VideoRotation `ListItem.Property(Game.VideoRotation)`\endlink ///

/// } /// \table_row3{ `ListItem.ParentalRating`, /// \anchor ListItem_ParentalRating /// _string_, /// @return The parental rating of the list item (PVR). ///

/// } /// \table_row3{ `ListItem.CurrentItem`, /// \anchor ListItem_CurrentItem /// _string_, /// @return The current index of the item in a container starting at 1. ///


/// @skinning_v19 **[New Infolabel]** \link ListItem_CurrentItem `ListItem.CurrentItem`\endlink ///

/// } /// \table_row3{ `ListItem.IsNew`, /// \anchor ListItem_IsNew /// _boolean_, /// @return **True** if the item is new (for example\, a Live TV show that will be first aired). ///


/// @skinning_v19 **[New Infolabel]** \link ListItem_IsNew `ListItem.IsNew`\endlink ///

/// } /// \table_row3{ `ListItem.IsPremiere`, /// \anchor ListItem_IsPremiere /// _boolean_, /// @return **True** if the item is a premiere (for example\, a Movie first showing or season first on Live TV). ///


/// @skinning_v19 **[New Infolabel]** \link ListItem_IsPremiere `ListItem.IsPremiere`\endlink ///

/// } /// \table_row3{ `ListItem.IsFinale`, /// \anchor ListItem_IsFinale /// _boolean_, /// @return **True** if the item is a finale (for example\, a season finale showing on Live TV). ///


/// @skinning_v19 **[New Infolabel]** \link ListItem_IsFinale `ListItem.IsFinale`\endlink ///

/// } /// \table_row3{ `ListItem.IsLive`, /// \anchor ListItem_IsLive /// _boolean_, /// @return **True** if the item is live (for example\, a Live TV sports event). ///


/// @skinning_v19 **[New Infolabel]** \link ListItem_IsLive `ListItem.IsLive`\endlink ///

/// } /// \table_row3{ `ListItem.DiscTitle`, /// \anchor ListItem_DiscTitle /// _string_, /// @return The disc title of the currently selected album or song. ///


/// @skinning_v19 **[New Infolabel]** \link ListItem_DiscTitle `ListItem.DiscTitle`\endlink ///

/// } /// \table_row3{ `ListItem.IsBoxset`, /// \anchor ListItem_IsBoxset /// _boolean_, /// @return **True** if the item is part of a boxset album. ///


/// @skinning_v19 **[New Infolabel]** \link ListItem_IsBoxset `ListItem.IsBoxset`\endlink ///

/// } /// \table_row3{ `ListItem.TotalDiscs`, /// \anchor ListItem_TotalDiscs /// _boolean_, /// @return The total number of discs belonging to an album. ///


/// @skinning_v19 **[New Infolabel]** \link ListItem_TotalDiscs `ListItem.TotalDiscs`\endlink ///

/// } /// \table_row3{ `ListItem.ReleaseDate`, /// \anchor ListItem_ReleaseDate /// _string_, /// @return The release date of the item. ///


/// @skinning_v19 **[New Infolabel]** \link ListItem_ReleaseDate `ListItem.ReleaseDate`\endlink ///

/// } /// \table_row3{ `ListItem.OriginalDate`, /// \anchor ListItem_OriginalDate /// _string_, /// @return The original release date of the item. Can be full or partial date. ///


/// @skinning_v19 **[New Infolabel]** \link ListItem_OriginalDate `ListItem.OriginalDate`\endlink ///

/// } /// \table_row3{ `ListItem.BPM`, /// \anchor ListItem_BPM /// _string_, /// @return The BPM of a song. ///


/// @skinning_v19 **[New Infolabel]** \link ListItem_BPM `ListItem.BPM`\endlink ///

/// } /// \table_row3{ `ListItem.UniqueID(name)`, /// \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. ///


/// @skinning_v19 **[New Infolabel]** \link ListItem_UniqueID `ListItem.UniqueID(name)`\endlink ///

/// } /// \table_row3{ `ListItem.BitRate`, /// \anchor ListItem_BitRate /// _string_, /// @return The bitrate of a song. Actual rate for CBR\, average rate for VBR. ///


/// @skinning_v19 **[New Infolabel]** \link ListItem_BitRate `ListItem.BitRate`\endlink ///

/// } /// \table_row3{ `ListItem.SampleRate`, /// \anchor ListItem_SampleRate /// _string_, /// @return The sample rate of a song / 1000.0 eg 44.1\, 48\, 96 etc. ///


/// @skinning_v19 **[New Infolabel]** \link ListItem_SampleRate `ListItem.SampleRate`\endlink ///

/// } /// \table_row3{ `ListItem.MusicChannels`, /// \anchor ListItem_MusicChannels /// _string_, /// @return The number of audio channels of a song. ///


/// @skinning_v19 **[New Infolabel]** \link ListItem_No_Of_Channels `ListItem.NoOfChannels`\endlink ///

/// } /// \table_row3{ `ListItem.TvShowDBID`, /// \anchor ListItem_TvShowDBID /// _string_, /// @return The database id of the TvShow for the currently selected Season or Episode. ///


/// @skinning_v19 **[New Infolabel]** \link ListItem_TvShowDBID `ListItem.TvShowDBID`\endlink ///

/// } /// \table_row3{ `ListItem.AlbumStatus`, /// \anchor ListItem_AlbumStatus /// _string_, /// @return The Musicbrainz release status of the album (official, bootleg, promotion etc) ///


/// @skinning_v19 **[New Infolabel]** \link ListItem_AlbumStatus `ListItem.AlbumStatus`\endlink /// } /// \table_row3{ `ListItem.HdrType`, /// \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. ///


/// @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{ `Visualisation.Enabled`, /// \anchor Visualisation_Enabled /// _boolean_, /// @return **True** if any visualisation has been set in settings (so not None). ///

/// } /// \table_row3{ `Visualisation.HasPresets`, /// \anchor Visualisation_HasPresets /// _boolean_, /// @return **True** if the visualisation has built in presets. ///


/// @skinning_v16 **[New Boolean Condition]** \link Visualisation_HasPresets `Visualisation.HasPresets`\endlink ///

/// } /// \table_row3{ `Visualisation.Locked`, /// \anchor Visualisation_Locked /// _boolean_, /// @return **True** if the current visualisation preset is locked (e.g. in Milkdrop). ///

/// } /// \table_row3{ `Visualisation.Preset`, /// \anchor Visualisation_Preset /// _string_, /// @return The current preset of the visualisation. ///

/// } /// \table_row3{ `Visualisation.Name`, /// \anchor Visualisation_Name /// _string_, /// @return the name of the visualisation. ///

/// } /// \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{ `Fanart.Color1`, /// \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. ///

/// } /// \table_row3{ `Fanart.Color2`, /// \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. ///

/// } /// \table_row3{ `Fanart.Color3`, /// \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. ///

/// } /// \table_row3{ `Fanart.Image`, /// \anchor Fanart_Image /// _string_, /// @return The fanart image\, if any ///

/// } /// \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{ `Skin.HasSetting(setting)`, /// \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])` ///

/// } /// \table_row3{ `Skin.String(setting)`, /// \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 ///

/// } /// \table_row3{ `Skin.String(setting[\,value])`, /// \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 ///

/// } /// \table_row3{ `Skin.HasTheme(theme)`, /// \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. ///

/// } /// \table_row3{ `Skin.CurrentTheme`, /// \anchor Skin_CurrentTheme /// _string_, /// @return The current selected skin theme. ///

/// } /// \table_row3{ `Skin.CurrentColourTheme`, /// \anchor Skin_CurrentColourTheme /// _string_, /// @return the current selected colour theme of the skin. ///

/// } /// \table_row3{ `Skin.AspectRatio`, /// \anchor Skin_AspectRatio /// _string_, /// @return The closest aspect ratio match using the resolution info from the skin's `addon.xml` file. ///

/// } /// \table_row3{ `Skin.Font`, /// \anchor Skin_Font /// _string_, /// @return the current fontset from `Font.xml`. ///


/// @skinning_v18 **[New Infolabel]** \link Skin_Font `Skin.Font`\endlink ///

/// } /// \table_row3{ `Skin.Numeric(settingid)`, /// \anchor Skin_Numeric /// _integer_, /// @return return the setting value as an integer/numeric value. /// @sa \link Skin_SetNumeric `Skin.SetNumeric(settingid)`\endlink ///


/// @skinning_v20 **[New Infolabel]** \link Skin_Numeric `Skin.Numeric(settingid)`\endlink ///

/// } /// \table_row3{ `Skin.TimerElapsedSecs(timer)`, /// \anchor Skin_TimerElapsedSecs /// _integer_ \, _string_, /// @return The elapsed time in seconds for the provided `timer`. /// @param timer - the timer name ///


/// @skinning_v20 **[New Infolabel]** \link Skin_TimerElapsedSecs `Skin.TimerElapsedSecs(timer)`\endlink ///

/// } /// \table_row3{ `Skin.TimerIsRunning(timer)`, /// \anchor Skin_TimerIsRunning /// _boolean_, /// @return **True** if the given `timer` is active\, false otherwise. /// @param timer - the timer name ///


/// @skinning_v20 **[New Infolabel]** \link Skin_TimerIsRunning `Skin.TimerIsRunning(timer)`\endlink ///

/// } /// \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{ `Window.IsMedia`, /// \anchor Window_IsMedia /// _boolean_, /// @return **True** if this window is a media window (programs\, music\, video\, /// scripts\, pictures) ///

/// } /// \table_row3{ `Window.Is(window)`, /// \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. ///


/// @skinning_v17 **[New Boolean Condition]** \ref Window_Is "Window.Is(window)" ///

/// } /// \table_row3{ `Window.IsActive(window)`, /// \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 ///

/// } /// \table_row3{ `Window.IsVisible(window)`, /// \anchor Window_IsVisible /// _boolean_, /// @return **True** if the window is visible /// @note Includes fade out time on dialogs ///

/// } /// \table_row3{ `Window.IsTopmost(window)`, /// \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 ///

/// } /// \table_row3{ `Window.IsDialogTopmost(dialog)`, /// \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 ///

/// } /// \table_row3{ `Window.IsModalDialogTopmost(dialog)`, /// \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 ///

/// } /// \table_row3{ `Window.Previous(window)`, /// \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. ///

/// } /// \table_row3{ `Window.Next(window)`, /// \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. ///

/// } /// \table_row3{ `Window.Property(Addon.ID)`, /// \anchor Window_Property_AddonId /// _string_, /// @return The id of the selected addon\, in `DialogAddonSettings.xml`. ///


/// @skinning_v17 **[New Infolabel]** \link Window_Property_AddonId `Window.Property(Addon.ID)`\endlink ///

/// } /// \table_row3{ `Window.Property(IsRadio)`, /// \anchor Window_Property_IsRadio /// _string_, /// @return "true" if the window is a radio window\, empty string otherwise (for use in the PVR windows). ///

/// } /// \table_row3{ `Window([window]).Property(key)`, /// \anchor Window_Window_Property_key /// _string_, /// @return A window property. /// @param window - [opt] window id or name. /// @param key - any value. ///

/// } /// \table_row3{ `Window(AddonBrowser).Property(Updated)`, /// \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. ///


/// @skinning_v15 **[New Infolabel]** \link Window_Addonbrowser_Property_Updated `Window(AddonBrowser).Property(Updated)`\endlink ///

/// } /// \table_row3{ `Window(Weather).Property(property)`, /// \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. ///


/// @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). ///

/// } /// \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{ `Control.HasFocus(id)`, /// \anchor Control_HasFocus /// _boolean_, /// @return **True** if the currently focused control has id "id". /// @param id - The id of the control ///

/// } /// \table_row3{ `Control.IsVisible(id)`, /// \anchor Control_IsVisible /// _boolean_, /// @return **True** if the control with id "id" is visible. /// @param id - The id of the control ///

/// } /// \table_row3{ `Control.IsEnabled(id)`, /// \anchor Control_IsEnabled /// _boolean_, /// @return **True** if the control with id "id" is enabled. /// @param id - The id of the control ///

/// } /// \table_row3{ `Control.GetLabel(id)[.index()]`, /// \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. ///


/// @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 ///

/// } /// \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{ `Playlist.Length(media)`, /// \anchor Playlist_Length /// _integer_, /// @return The total size of the current playlist. /// @param media - [opt] mediatype with is either /// video or music. ///

/// } /// \table_row3{ `Playlist.Position(media)`, /// \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. ///

/// } /// \table_row3{ `Playlist.Random`, /// \anchor Playlist_Random /// _integer_, /// @return String ID for the random mode: /// - **16041** (On) /// - **591** (Off) ///


/// @skinning_v18 **[Infolabel Updated]** \link Playlist_Random `Playlist.Random`\endlink will /// now return **On/Off** ///

/// } /// \table_row3{ `Playlist.Repeat`, /// \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) ///

/// } /// \table_row3{ `Playlist.IsRandom`, /// \anchor Playlist_IsRandom /// _boolean_, /// @return **True** if the player is in random mode. ///

/// } /// \table_row3{ `Playlist.IsRepeat`, /// \anchor Playlist_IsRepeat /// _boolean_, /// @return **True** if the player is in repeat all mode. ///

/// } /// \table_row3{ `Playlist.IsRepeatOne`, /// \anchor Playlist_IsRepeatOne /// _boolean_, /// @return **True** if the player is in repeat one mode. ///

/// } /// \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{ `PVR.IsRecording`, /// \anchor PVR_IsRecording /// _boolean_, /// @return **True** when the system is recording a tv or radio programme. ///

/// } /// \table_row3{ `PVR.HasTimer`, /// \anchor PVR_HasTimer /// _boolean_, /// @return **True** when a recording timer is active. ///

/// } /// \table_row3{ `PVR.HasTVChannels`, /// \anchor PVR_HasTVChannels /// _boolean_, /// @return **True** if there are TV channels available. ///

/// } /// \table_row3{ `PVR.HasRadioChannels`, /// \anchor PVR_HasRadioChannels /// _boolean_, /// @return **True** if there are radio channels available. ///

/// } /// \table_row3{ `PVR.HasNonRecordingTimer`, /// \anchor PVR_HasNonRecordingTimer /// _boolean_, /// @return **True** if there are timers present who currently not do recording. ///

/// } /// \table_row3{ `PVR.BackendName`, /// \anchor PVR_BackendName /// _string_, /// @return The name of the backend being used. ///

/// } /// \table_row3{ `PVR.BackendVersion`, /// \anchor PVR_BackendVersion /// _string_, /// @return The version of the backend that's being used. ///

/// } /// \table_row3{ `PVR.BackendHost`, /// \anchor PVR_BackendHost /// _string_, /// @return The backend hostname. ///

/// } /// \table_row3{ `PVR.BackendDiskSpace`, /// \anchor PVR_BackendDiskSpace /// _string_, /// @return The available diskspace on the backend as string with size. ///

/// } /// \table_row3{ `PVR.BackendDiskSpaceProgr`, /// \anchor PVR_BackendDiskSpaceProgr /// _integer_, /// @return The available diskspace on the backend as percent value. ///


/// @skinning_v14 **[New Infolabel]** \link PVR_BackendDiskSpaceProgr `PVR.BackendDiskSpaceProgr`\endlink ///

/// } /// \table_row3{ `PVR.BackendChannels`, /// \anchor PVR_BackendChannels /// _string (integer)_, /// @return The number of available channels the backend provides. ///

/// } /// \table_row3{ `PVR.BackendTimers`, /// \anchor PVR_BackendTimers /// _string (integer)_, /// @return The number of timers set for the backend. ///

/// } /// \table_row3{ `PVR.BackendRecordings`, /// \anchor PVR_BackendRecordings /// _string (integer)_, /// @return The number of recordings available on the backend. ///

/// } /// \table_row3{ `PVR.BackendDeletedRecordings`, /// \anchor PVR_BackendDeletedRecordings /// _string (integer)_, /// @return The number of deleted recordings present on the backend. ///

/// } /// \table_row3{ `PVR.BackendNumber`, /// \anchor PVR_BackendNumber /// _string_, /// @return The backend number. ///

/// } /// \table_row3{ `PVR.TotalDiscSpace`, /// \anchor PVR_TotalDiscSpace /// _string_, /// @return The total diskspace available for recordings. ///

/// } /// \table_row3{ `PVR.NextTimer`, /// \anchor PVR_NextTimer /// _boolean_, /// @return The next timer date. ///

/// } /// \table_row3{ `PVR.IsPlayingTV`, /// \anchor PVR_IsPlayingTV /// _boolean_, /// @return **True** when live tv is being watched. ///

/// } /// \table_row3{ `PVR.IsPlayingRadio`, /// \anchor PVR_IsPlayingRadio /// _boolean_, /// @return **True** when live radio is being listened to. ///

/// } /// \table_row3{ `PVR.IsPlayingRecording`, /// \anchor PVR_IsPlayingRecording /// _boolean_, /// @return **True** when a recording is being watched. ///

/// } /// \table_row3{ `PVR.IsPlayingEpgTag`, /// \anchor PVR_IsPlayingEpgTag /// _boolean_, /// @return **True** when an epg tag is being watched. ///

/// } /// \table_row3{ `PVR.EpgEventProgress`, /// \anchor PVR_EpgEventProgress /// _integer_, /// @return The percentage complete of the currently playing epg event. ///


/// @skinning_v18 **[Infolabel Updated]** \link PVR_EpgEventProgress `PVR.EpgEventProgress`\endlink replaces /// the old `PVR.Progress` infolabel. ///

/// } /// \table_row3{ `PVR.ActStreamClient`, /// \anchor PVR_ActStreamClient /// _string_, /// @return The stream client name. ///

/// } /// \table_row3{ `PVR.ActStreamDevice`, /// \anchor PVR_ActStreamDevice /// _string_, /// @return The stream device name. ///

/// } /// \table_row3{ `PVR.ActStreamStatus`, /// \anchor PVR_ActStreamStatus /// _string_, /// @return The status of the stream. ///

/// } /// \table_row3{ `PVR.ActStreamSignal`, /// \anchor PVR_ActStreamSignal /// _string_, /// @return The signal quality of the stream. ///

/// } /// \table_row3{ `PVR.ActStreamSnr`, /// \anchor PVR_ActStreamSnr /// _string_, /// @return The signal to noise ratio of the stream. ///

/// } /// \table_row3{ `PVR.ActStreamBer`, /// \anchor PVR_ActStreamBer /// _string_, /// @return The bit error rate of the stream. ///

/// } /// \table_row3{ `PVR.ActStreamUnc`, /// \anchor PVR_ActStreamUnc /// _string_, /// @return The UNC value of the stream. ///

/// } /// \table_row3{ `PVR.ActStreamProgrSignal`, /// \anchor PVR_ActStreamProgrSignal /// _integer_, /// @return The signal quality of the programme. ///

/// } /// \table_row3{ `PVR.ActStreamProgrSnr`, /// \anchor PVR_ActStreamProgrSnr /// _integer_, /// @return The signal to noise ratio of the programme. ///

/// } /// \table_row3{ `PVR.ActStreamIsEncrypted`, /// \anchor PVR_ActStreamIsEncrypted /// _boolean_, /// @return **True** when channel is encrypted on source. ///

/// } /// \table_row3{ `PVR.ActStreamEncryptionName`, /// \anchor PVR_ActStreamEncryptionName /// _string_, /// @return The encryption used on the stream. ///

/// } /// \table_row3{ `PVR.ActStreamServiceName`, /// \anchor PVR_ActStreamServiceName /// _string_, /// @return The service name of played channel if available. ///

/// } /// \table_row3{ `PVR.ActStreamMux`, /// \anchor PVR_ActStreamMux /// _string_, /// @return The multiplex type of played channel if available. ///

/// } /// \table_row3{ `PVR.ActStreamProviderName`, /// \anchor PVR_ActStreamProviderName /// _string_, /// @return The provider name of the played channel if available. ///

/// } /// \table_row3{ `PVR.IsTimeShift`, /// \anchor PVR_IsTimeShift /// _boolean_, /// @return **True** when for channel is timeshift available. ///

/// } /// \table_row3{ `PVR.TimeShiftProgress`, /// \anchor PVR_TimeShiftProgress /// _integer_, /// @return The position of currently timeshifted title on TV as integer. ///

/// } /// \table_row3{ `PVR.TimeShiftSeekbar`, /// \anchor PVR_TimeShiftSeekbar /// _integer_, /// @return The percentage we are seeking to in a timeshifted title. ///


/// @skinning_v19 **[New Infolabel]** \link PVR_TimeShiftSeekbar `PVR.TimeShiftSeekbar`\endlink ///

/// } /// \table_row3{ `PVR.NowRecordingTitle`, /// \anchor PVR_NowRecordingTitle /// _string_, /// @return The title of the programme being recorded. ///

/// } /// \table_row3{ `PVR.NowRecordingDateTime`, /// \anchor PVR_NowRecordingDateTime /// _Date/Time string_, /// @return The start date and time of the current recording. ///

/// } /// \table_row3{ `PVR.NowRecordingChannel`, /// \anchor PVR_NowRecordingChannel /// _string_, /// @return The channel name of the current recording. ///

/// } /// \table_row3{ `PVR.NowRecordingChannelIcon`, /// \anchor PVR_NowRecordingChannelIcon /// _string_, /// @return The icon of the current recording channel. ///

/// } /// \table_row3{ `PVR.NextRecordingTitle`, /// \anchor PVR_NextRecordingTitle /// _string_, /// @return The title of the next programme that will be recorded. ///

/// } /// \table_row3{ `PVR.NextRecordingDateTime`, /// \anchor PVR_NextRecordingDateTime /// _Date/Time string_, /// @return The start date and time of the next recording. ///

/// } /// \table_row3{ `PVR.NextRecordingChannel`, /// \anchor PVR_NextRecordingChannel /// _string_, /// @return The channel name of the next recording. ///

/// } /// \table_row3{ `PVR.NextRecordingChannelIcon`, /// \anchor PVR_NextRecordingChannelIcon /// _string_, /// @return The icon of the next recording channel. ///

/// } /// \table_row3{ `PVR.TVNowRecordingTitle`, /// \anchor PVR_TVNowRecordingTitle /// _string_, /// @return The title of the tv programme being recorded. ///


/// @skinning_v17 **[New Infolabel]** \link PVR_TVNowRecordingTitle `PVR.TVNowRecordingTitle`\endlink ///

/// } /// \table_row3{ `PVR.TVNowRecordingDateTime`, /// \anchor PVR_TVNowRecordingDateTime /// _Date/Time string_, /// @return The start date and time of the current tv recording. ///


/// @skinning_v17 **[New Infolabel]** \link PVR_TVNowRecordingDateTime `PVR.TVNowRecordingDateTime`\endlink ///

/// } /// \table_row3{ `PVR.TVNowRecordingChannel`, /// \anchor PVR_TVNowRecordingChannel /// _string_, /// @return The channel name of the current tv recording. ///


/// @skinning_v17 **[New Infolabel]** \link PVR_TVNowRecordingChannel `PVR.TVNowRecordingChannel`\endlink ///

/// } /// \table_row3{ `PVR.TVNowRecordingChannelIcon`, /// \anchor PVR_TVNowRecordingChannelIcon /// _string_, /// @return The icon of the current recording TV channel. ///


/// @skinning_v17 **[New Infolabel]** \link PVR_TVNowRecordingChannelIcon `PVR.TVNowRecordingChannelIcon`\endlink ///

/// } /// \table_row3{ `PVR.TVNextRecordingTitle`, /// \anchor PVR_TVNextRecordingTitle /// _string_, /// @return The title of the next tv programme that will be recorded. ///


/// @skinning_v17 **[New Infolabel]** \link PVR_TVNextRecordingTitle `PVR.TVNextRecordingTitle`\endlink ///

/// } /// \table_row3{ `PVR.TVNextRecordingDateTime`, /// \anchor PVR_TVNextRecordingDateTime /// _Date/Time string_, /// @return The start date and time of the next tv recording. ///


/// @skinning_v17 **[New Infolabel]** \link PVR_TVNextRecordingDateTime `PVR.TVNextRecordingDateTime`\endlink ///

/// } /// \table_row3{ `PVR.TVNextRecordingChannel`, /// \anchor PVR_TVNextRecordingChannel /// _string_, /// @return The channel name of the next tv recording. ///


/// @skinning_v17 **[New Infolabel]** \link PVR_TVNextRecordingChannel `PVR.TVNextRecordingChannel`\endlink ///

/// } /// \table_row3{ `PVR.TVNextRecordingChannelIcon`, /// \anchor PVR_TVNextRecordingChannelIcon /// _string_, /// @return The icon of the next recording tv channel. ///


/// @skinning_v17 **[New Infolabel]** \link PVR_TVNextRecordingChannelIcon `PVR.TVNextRecordingChannelIcon`\endlink ///

/// } /// \table_row3{ `PVR.RadioNowRecordingTitle`, /// \anchor PVR_RadioNowRecordingTitle /// _string_, /// @return The title of the radio programme being recorded. ///


/// @skinning_v17 **[New Infolabel]** \link PVR_RadioNowRecordingTitle `PVR.RadioNowRecordingTitle`\endlink ///

/// } /// \table_row3{ `PVR.RadioNowRecordingDateTime`, /// \anchor PVR_RadioNowRecordingDateTime /// _Date/Time string_, /// @return The start date and time of the current radio recording. ///


/// @skinning_v17 **[New Infolabel]** \link PVR_RadioNowRecordingDateTime `PVR.RadioNowRecordingDateTime`\endlink ///

/// } /// \table_row3{ `PVR.RadioNowRecordingChannel`, /// \anchor PVR_RadioNowRecordingChannel /// _string_, /// @return The channel name of the current radio recording. ///


/// @skinning_v17 **[New Infolabel]** \link PVR_RadioNowRecordingChannel `PVR.RadioNowRecordingChannel`\endlink ///

/// } /// \table_row3{ `PVR.RadioNowRecordingChannelIcon`, /// \anchor PVR_RadioNowRecordingChannelIcon /// _string_, /// @return The icon of the current recording radio channel. ///


/// @skinning_v17 **[New Infolabel]** \link PVR_RadioNowRecordingChannelIcon `PVR.RadioNowRecordingChannelIcon`\endlink ///

/// } /// \table_row3{ `PVR.RadioNextRecordingTitle`, /// \anchor PVR_RadioNextRecordingTitle /// _string_, /// @return The title of the next radio programme that will be recorded. ///


/// @skinning_v17 **[New Infolabel]** \link PVR_RadioNextRecordingTitle `PVR.RadioNextRecordingTitle`\endlink ///

/// } /// \table_row3{ `PVR.RadioNextRecordingDateTime`, /// \anchor PVR_RadioNextRecordingDateTime /// _Date/Time string_, /// @return The start date and time of the next radio recording. ///


/// @skinning_v17 **[New Infolabel]** \link PVR_RadioNextRecordingDateTime `PVR.RadioNextRecordingDateTime`\endlink ///

/// } /// \table_row3{ `PVR.RadioNextRecordingChannel`, /// \anchor PVR_RadioNextRecordingChannel /// _string_, /// @return The channel name of the next radio recording. ///


/// @skinning_v17 **[New Infolabel]** \link PVR_RadioNextRecordingChannel `PVR.RadioNextRecordingChannel`\endlink ///

/// } /// \table_row3{ `PVR.RadioNextRecordingChannelIcon`, /// \anchor PVR_RadioNextRecordingChannelIcon /// _string_, /// @return The icon of the next recording radio channel. ///


/// @skinning_v17 **[New Infolabel]** \link PVR_RadioNextRecordingChannelIcon `PVR.RadioNextRecordingChannelIcon`\endlink ///

/// } /// \table_row3{ `PVR.IsRecordingTV`, /// \anchor PVR_IsRecordingTV /// _boolean_, /// @return **True** when the system is recording a tv programme. ///


/// @skinning_v17 **[New Boolean Condition]** \link PVR_IsRecordingTV `PVR.IsRecordingTV`\endlink ///

/// } /// \table_row3{ `PVR.HasTVTimer`, /// \anchor PVR_HasTVTimer /// _boolean_, /// @return **True** if at least one tv timer is active. ///


/// @skinning_v17 **[New Boolean Condition]** \link PVR_HasTVTimer `PVR.HasTVTimer`\endlink ///

/// } /// \table_row3{ `PVR.HasNonRecordingTVTimer`, /// \anchor PVR_HasNonRecordingTVTimer /// _boolean_, /// @return **True** if there are tv timers present who currently not do recording. ///


/// @skinning_v17 **[New Boolean Condition]** \link PVR_HasNonRecordingTVTimer `PVR.HasNonRecordingTVTimer`\endlink ///

/// } /// \table_row3{ `PVR.IsRecordingRadio`, /// \anchor PVR_IsRecordingRadio /// _boolean_, /// @return **True** when the system is recording a radio programme. ///


/// @skinning_v17 **[New Boolean Condition]** \link PVR_IsRecordingRadio `PVR.IsRecordingRadio`\endlink ///

/// } /// \table_row3{ `PVR.HasRadioTimer`, /// \anchor PVR_HasRadioTimer /// _boolean_, /// @return **True** if at least one radio timer is active. ///


/// @skinning_v17 **[New Boolean Condition]** \link PVR_HasRadioTimer `PVR.HasRadioTimer`\endlink ///

/// } /// \table_row3{ `PVR.HasNonRecordingRadioTimer`, /// \anchor PVR_HasNonRecordingRadioTimer /// _boolean_, /// @return **True** if there are radio timers present who currently not do recording. ///


/// @skinning_v17 **[New Boolean Condition]** \link PVR_HasNonRecordingRadioTimer `PVR.HasRadioTimer`\endlink ///

/// } /// \table_row3{ `PVR.ChannelNumberInput`, /// \anchor PVR_ChannelNumberInput /// _string_, /// @return The currently entered channel number while in numeric channel input mode\, an empty string otherwise. ///


/// @skinning_v18 **[New Infolabel]** \link PVR_ChannelNumberInput `PVR.ChannelNumberInput`\endlink ///

/// } /// \table_row3{ `PVR.CanRecordPlayingChannel`, /// \anchor PVR_CanRecordPlayingChannel /// _boolean_, /// @return **True** if PVR is currently playing a channel and if this channel can be recorded. ///


/// @skinning_v18 **[Infolabel Updated]** \link PVR_CanRecordPlayingChannel `PVR.CanRecordPlayingChannel`\endlink replaces /// the old `Player.CanRecord` infolabel. ///

/// } /// \table_row3{ `PVR.IsRecordingPlayingChannel`, /// \anchor PVR_IsRecordingPlayingChannel /// _boolean_, /// @return **True** if PVR is currently playing a channel and if this channel is currently recorded. ///


/// @skinning_v18 **[Infolabel Updated]** \link PVR_IsRecordingPlayingChannel `PVR.IsRecordingPlayingChannel`\endlink replaces /// the old `Player.Recording` infolabel. ///

/// } /// \table_row3{ `PVR.IsPlayingActiveRecording`, /// \anchor PVR_IsPlayingActiveRecording /// _boolean_, /// @return **True** if PVR is currently playing an in progress recording. ///


/// @skinning_v19 **[New Infolabel]** \link PVR_IsPlayingActiveRecording `PVR.IsPlayingActiveRecording`\endlink ///

/// } /// \table_row3{ `PVR.TimeshiftProgressPlayPos`, /// \anchor PVR_TimeshiftProgressPlayPos /// _integer_, /// @return The percentage of the current play position within the PVR timeshift progress. ///


/// @skinning_v18 **[New Infolabel]** \link PVR_TimeshiftProgressPlayPos `PVR.TimeshiftProgressPlayPos`\endlink ///

/// } /// \table_row3{ `PVR.TimeshiftProgressEpgStart`, /// \anchor PVR_TimeshiftProgressEpgStart /// _integer_, /// @return The percentage of the start of the currently playing epg event within the PVR timeshift progress. ///


/// @skinning_v18 **[New Infolabel]** \link PVR_TimeshiftProgressEpgStart `PVR.TimeshiftProgressEpgStart`\endlink ///

/// } /// \table_row3{ `PVR.TimeshiftProgressEpgEnd`, /// \anchor PVR_TimeshiftProgressEpgEnd /// _integer_, /// @return The percentage of the end of the currently playing epg event within the PVR timeshift progress. ///


/// @skinning_v18 **[New Infolabel]** \link PVR_TimeshiftProgressEpgEnd `PVR.TimeshiftProgressEpgEnd`\endlink ///

/// } /// \table_row3{ `PVR.TimeshiftProgressBufferStart`, /// \anchor PVR_TimeshiftProgressBufferStart /// _integer_, /// @return The percentage of the start of the timeshift buffer within the PVR timeshift progress. ///


/// @skinning_v18 **[New Infolabel]** \link PVR_TimeshiftProgressBufferStart `PVR.TimeshiftProgressBufferStart`\endlink ///

/// } /// \table_row3{ `PVR.TimeshiftProgressBufferEnd`, /// \anchor PVR_TimeshiftProgressBufferEnd /// _integer_, /// @return The percentage of the end of the timeshift buffer within the PVR timeshift progress. ///


/// @skinning_v18 **[New Infolabel]** \link PVR_TimeshiftProgressBufferEnd `PVR.TimeshiftProgressBufferEnd`\endlink ///

/// } /// \table_row3{ `PVR.EpgEventIcon`, /// \anchor PVR_EpgEventIcon /// _string_, /// @return The icon of the currently playing epg event\, if any. ///


/// @skinning_v18 **[New Infolabel]** \link PVR_EpgEventIcon `PVR_EpgEventIcon`\endlink ///

/// } /// 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{ `PVR.EpgEventDuration`, /// \anchor PVR_EpgEventDuration /// _string_, /// @return The duration of the currently playing epg event in the /// format hh:mm:ss. /// @note hh: will be omitted if hours value is zero. ///


/// @skinning_v18 **[Infolabel Updated]** \link PVR_EpgEventDuration `PVR.EpgEventDuration`\endlink replaces /// the old `PVR.Duration` infolabel. ///

/// } /// \table_row3{ `PVR.EpgEventDuration(format)`, /// \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. ///

/// } /// \table_row3{ `PVR.EpgEventElapsedTime`, /// \anchor PVR_EpgEventElapsedTime /// _string_, /// @return the time of the current position of the currently playing epg event in the /// format hh:mm:ss. /// @note hh: will be omitted if hours value is zero. ///


/// @skinning_v18 **[Infolabel Updated]** \link PVR_EpgEventElapsedTime `PVR.EpgEventElapsedTime`\endlink replaces /// the old `PVR.Time` infolabel. ///

/// } /// \table_row3{ `PVR.EpgEventElapsedTime(format)`, /// \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. ///

/// } /// \table_row3{ `PVR.EpgEventRemainingTime`, /// \anchor PVR_EpgEventRemainingTime /// _string_, /// @return The remaining time for currently playing epg event in the /// format hh:mm:ss. /// @note hh: will be omitted if hours value is zero. ///


/// @skinning_v18 **[New Infolabel]** \link PVR_EpgEventRemainingTime `PVR.EpgEventRemainingTime`\endlink ///

/// } /// \table_row3{ `PVR.EpgEventRemainingTime(format)`, /// \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. ///

/// } /// \table_row3{ `PVR.EpgEventSeekTime`, /// \anchor PVR_EpgEventSeekTime /// _string_, /// @return The time the user is seeking within the currently playing epg event in the /// format hh:mm:ss. /// @note hh: will be omitted if hours value is zero. ///


/// @skinning_v18 **[New Infolabel]** \link PVR_EpgEventSeekTime `PVR.EpgEventSeekTime`\endlink ///

/// } /// \table_row3{ `PVR.EpgEventSeekTime(format)`, /// \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. ///

/// } /// \table_row3{ `PVR.EpgEventFinishTime`, /// \anchor PVR_EpgEventFinishTime /// _string_, /// @return The time the currently playing epg event will end in the /// format hh:mm:ss. /// @note hh: will be omitted if hours value is zero. ///


/// @skinning_v18 **[New Infolabel]** \link PVR_EpgEventFinishTime `PVR.EpgEventFinishTime`\endlink ///

/// } /// \table_row3{ `PVR.EpgEventFinishTime(format)`, /// \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. ///

/// } /// \table_row3{ `PVR.TimeShiftStart`, /// \anchor PVR_TimeShiftStart /// _string_, /// @return The start time of the timeshift buffer in the /// format hh:mm:ss. /// @note hh: will be omitted if hours value is zero. ///

/// } /// \table_row3{ `PVR.TimeShiftStart(format)`, /// \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. ///

/// } /// \table_row3{ `PVR.TimeShiftEnd`, /// \anchor PVR_TimeShiftEnd /// _string_, /// @return The end time of the timeshift buffer in the /// format hh:mm:ss. /// @note hh: will be omitted if hours value is zero. ///

/// } /// \table_row3{ `PVR.TimeShiftEnd(format)`, /// \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. ///

/// } /// \table_row3{ `PVR.TimeShiftCur`, /// \anchor PVR_TimeShiftCur /// _string_, /// @return The current playback time within the timeshift buffer in the /// format hh:mm:ss. /// @note hh: will be omitted if hours value is zero. ///

/// } /// \table_row3{ `PVR.TimeShiftCur(format)`, /// \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. ///

/// } /// \table_row3{ `PVR.TimeShiftOffset`, /// \anchor PVR_TimeShiftOffset /// _string_, /// @return The delta of timeshifted time to actual time in the /// format hh:mm:ss. /// @note hh: will be omitted if hours value is zero. ///

/// } /// \table_row3{ `PVR.TimeShiftOffset(format)`, /// \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. ///

/// } /// \table_row3{ `PVR.TimeshiftProgressDuration`, /// \anchor PVR_TimeshiftProgressDuration /// _string_, /// @return the duration of the PVR timeshift progress in the /// format hh:mm:ss. /// @note hh: will be omitted if hours value is zero. ///


/// @skinning_v18 **[New Infolabel]** \link PVR_TimeshiftProgressDuration `PVR.TimeshiftProgressDuration`\endlink ///

/// } /// \table_row3{ `PVR.TimeshiftProgressDuration(format)`, /// \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. ///

/// } /// \table_row3{ `PVR.TimeshiftProgressStartTime`, /// \anchor PVR_TimeshiftProgressStartTime /// _string_, /// @return The start time of the PVR timeshift progress in the /// format hh:mm:ss. /// @note hh: will be omitted if hours value is zero. ///


/// @skinning_v18 **[New Infolabel]** \link PVR_TimeshiftProgressStartTime `PVR.TimeshiftProgressStartTime`\endlink ///

/// } /// \table_row3{ `PVR.TimeshiftProgressStartTime(format)`, /// \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. ///

/// } /// \table_row3{ `PVR.TimeshiftProgressEndTime`, /// \anchor PVR_TimeshiftProgressEndTime /// _string_, /// @return The end time of the PVR timeshift progress in the /// format hh:mm:ss. /// @note hh: will be omitted if hours value is zero. ///


/// @skinning_v18 **[New Infolabel]** \link PVR_TimeshiftProgressEndTime `PVR.TimeshiftProgressEndTime`\endlink ///

/// } /// \table_row3{ `PVR.TimeshiftProgressEndTime(format)`, /// \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. ///

/// } /// \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{ `RDS.HasRds`, /// \anchor RDS_HasRds /// _boolean_, /// @return **True** if RDS is present. ///


/// @skinning_v16 **[New Boolean Condition]** \link RDS_HasRds `RDS.HasRds`\endlink ///

/// } /// \table_row3{ `RDS.HasRadioText`, /// \anchor RDS_HasRadioText /// _boolean_, /// @return **True** if RDS contains also RadioText. ///


/// @skinning_v16 **[New Boolean Condition]** \link RDS_HasRadioText `RDS.HasRadioText`\endlink ///

/// } /// \table_row3{ `RDS.HasRadioTextPlus`, /// \anchor RDS_HasRadioTextPlus /// _boolean_, /// @return **True** if RDS with RadioText contains also the plus information. ///


/// @skinning_v16 **[New Boolean Condition]** \link RDS_HasRadioTextPlus `RDS.HasRadioTextPlus`\endlink ///

/// } /// \table_row3{ `RDS.HasHotline`, /// \anchor RDS_HasHotline /// _boolean_, /// @return **True** if a hotline phone number is present. /// @note Only available on RadioText Plus ///


/// @skinning_v16 **[New Boolean Condition]** \link RDS_HasHotline `RDS.HasHotline`\endlink ///

/// } /// \table_row3{ `RDS.HasStudio`, /// \anchor RDS_HasStudio /// _boolean_, /// @return **True** if a studio name is present. /// @note Only available on RadioText Plus ///


/// @skinning_v16 **[New Boolean Condition]** \link RDS_HasStudio `RDS.HasStudio`\endlink ///

/// } /// \table_row3{ `RDS.AudioLanguage`, /// \anchor RDS_AudioLanguage /// _string_, /// @return The RDS reported audio language of the channel. ///


/// @skinning_v16 **[New Infolabel]** \link RDS_AudioLanguage `RDS.AudioLanguage`\endlink ///

/// } /// \table_row3{ `RDS.ChannelCountry`, /// \anchor RDS_ChannelCountry /// _string_, /// @return The country where the radio channel is broadcasted. ///


/// @skinning_v16 **[New Infolabel]** \link RDS_ChannelCountry `RDS.ChannelCountry`\endlink ///

/// } /// \table_row3{ `RDS.GetLine(number)`, /// \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) ///


/// @skinning_v16 **[New Infolabel]** \link RDS_GetLine `RDS.GetLine(number)`\endlink ///

/// } /// \table_row3{ `RDS.Title`, /// \anchor RDS_Title /// _string_, /// @return The title of item; e.g. track title of an album. /// @note Only available on RadioText Plus ///


/// @skinning_v16 **[New Infolabel]** \link RDS_Title `RDS.Title`\endlink ///

/// } /// \table_row3{ `RDS.Artist`, /// \anchor RDS_Artist /// _string_, /// @return A person or band/collective generally considered responsible for the work. /// @note Only available on RadioText Plus ///


/// @skinning_v16 **[New Infolabel]** \link RDS_Artist `RDS.Artist`\endlink ///

/// } /// \table_row3{ `RDS.Band`, /// \anchor RDS_Band /// _string_, /// @return The band/orchestra/musician. /// @note Only available on RadioText Plus ///


/// @skinning_v16 **[New Infolabel]** \link RDS_Band `RDS.Band`\endlink ///

/// } /// \table_row3{ `RDS.Composer`, /// \anchor RDS_Composer /// _string_, /// @return The name of the original composer/author. /// @note Only available on RadioText Plus ///


/// @skinning_v16 **[New Infolabel]** \link RDS_Composer `RDS.Composer`\endlink ///

/// } /// \table_row3{ `RDS.Conductor`, /// \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 ///


/// @skinning_v16 **[New Infolabel]** \link RDS_Conductor `RDS.Conductor`\endlink ///

/// } /// \table_row3{ `RDS.Album`, /// \anchor RDS_Album /// _string_, /// @return The album of the song. /// @note Only available on RadioText Plus ///


/// @skinning_v16 **[New Infolabel]** \link RDS_Album `RDS.Album`\endlink ///

/// } /// \table_row3{ `RDS.TrackNumber`, /// \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 ///


/// @skinning_v16 **[New Infolabel]** \link RDS_TrackNumber `RDS.TrackNumber`\endlink ///

/// } /// \table_row3{ `RDS.RadioStyle`, /// \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. ///


/// @skinning_v16 **[New Infolabel]** \link RDS_RadioStyle `RDS.RadioStyle`\endlink ///

/// } /// \table_row3{ `RDS.Comment`, /// \anchor RDS_Comment /// _string_, /// @return The radio station comment string if available. /// @note Only available on RadioText Plus ///


/// @skinning_v16 **[New Infolabel]** \link RDS_Comment `RDS.Comment`\endlink ///

/// } /// \table_row3{ `RDS.InfoNews`, /// \anchor RDS_InfoNews /// _string_, /// @return The message / headline (if available). /// @note Only available on RadioText Plus ///


/// @skinning_v16 **[New Infolabel]** \link RDS_InfoNews `RDS.InfoNews`\endlink ///

/// } /// \table_row3{ `RDS.InfoNewsLocal`, /// \anchor RDS_InfoNewsLocal /// _string_, /// @return The local information news sended from radio channel (if available). /// @note Only available on RadioText Plus ///


/// @skinning_v16 **[New Infolabel]** \link RDS_InfoNewsLocal `RDS.InfoNewsLocal`\endlink ///

/// } /// \table_row3{ `RDS.InfoStock`, /// \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 ///


/// @skinning_v16 **[New Infolabel]** \link RDS_InfoStock `RDS.InfoStock`\endlink ///

/// } /// \table_row3{ `RDS.InfoStockSize`, /// \anchor RDS_InfoStockSize /// _string_, /// @return The number of rows present in stock information. /// @note Only available on RadioText Plus ///


/// @skinning_v16 **[New Infolabel]** \link RDS_InfoStockSize `RDS.InfoStockSize`\endlink ///

/// } /// \table_row3{ `RDS.InfoSport`, /// \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 ///


/// @skinning_v16 **[New Infolabel]** \link RDS_InfoSport `RDS.InfoSport`\endlink ///

/// } /// \table_row3{ `RDS.InfoSportSize`, /// \anchor RDS_InfoSportSize /// _string_, /// @return The number of rows present in sport information. /// @note Only available on RadioText Plus ///


/// @skinning_v16 **[New Infolabel]** \link RDS_InfoSportSize `RDS.InfoSportSize`\endlink ///

/// } /// \table_row3{ `RDS.InfoLottery`, /// \anchor RDS_InfoLottery /// _string_, /// @return The raffle / lottery: "key word 99values" (if available). /// @note Only available on RadioText Plus ///


/// @skinning_v16 **[New Infolabel]** \link RDS_InfoLottery `RDS.InfoLottery`\endlink ///

/// } /// \table_row3{ `RDS.InfoLotterySize`, /// \anchor RDS_InfoLotterySize /// _string_, /// @return The number of rows present in lottery information. /// @note Only available on RadioText Plus ///


/// @skinning_v16 **[New Infolabel]** \link RDS_InfoLotterySize `RDS.InfoLotterySize`\endlink ///

/// } /// \table_row3{ `RDS.InfoWeather`, /// \anchor RDS_InfoWeather /// _string_, /// @return The weather information (if available). /// @note Only available on RadioText Plus ///


/// @skinning_v16 **[New Infolabel]** \link RDS_InfoWeather `RDS.InfoWeather`\endlink ///

/// } /// \table_row3{ `RDS.InfoWeatherSize`, /// \anchor RDS_InfoWeatherSize /// _string_, /// @return The number of rows present in weather information. /// @note Only available on RadioText Plus ///


/// @skinning_v16 **[New Infolabel]** \link RDS_InfoWeatherSize `RDS.InfoWeatherSize`\endlink ///

/// } /// \table_row3{ `RDS.InfoCinema`, /// \anchor RDS_InfoCinema /// _string_, /// @return The information about movies in cinema (if available). /// @note Only available on RadioText Plus ///


/// @skinning_v16 **[New Infolabel]** \link RDS_InfoCinema `RDS.InfoCinema`\endlink ///

/// } /// \table_row3{ `RDS.InfoCinemaSize`, /// \anchor RDS_InfoCinemaSize /// _string_, /// @return The number of rows present in cinema information. /// @note Only available on RadioText Plus ///


/// @skinning_v16 **[New Infolabel]** \link RDS_InfoCinemaSize `RDS.InfoCinemaSize`\endlink ///

/// } /// \table_row3{ `RDS.InfoHoroscope`, /// \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 ///


/// @skinning_v16 **[New Infolabel]** \link RDS_InfoHoroscope `RDS.InfoHoroscope`\endlink ///

/// } /// \table_row3{ `RDS.InfoHoroscopeSize`, /// \anchor RDS_InfoHoroscopeSize /// _string_, /// @return The Number of rows present in horoscope information. /// @note Only available on RadioText Plus ///


/// @skinning_v16 **[New Infolabel]** \link RDS_InfoHoroscopeSize `RDS.InfoHoroscopeSize`\endlink ///

/// } /// \table_row3{ `RDS.InfoOther`, /// \anchor RDS_InfoOther /// _string_, /// @return Other information\, not especially specified: "key word 99info" (if available). /// @note Only available on RadioText Plus ///


/// @skinning_v16 **[New Infolabel]** \link RDS_InfoOther `RDS.InfoOther`\endlink ///

/// } /// \table_row3{ `RDS.InfoOtherSize`, /// \anchor RDS_InfoOtherSize /// _string_, /// @return The number of rows present with other information. /// @note Only available on RadioText Plus ///


/// @skinning_v16 **[New Infolabel]** \link RDS_InfoOtherSize `RDS.InfoOtherSize`\endlink ///

/// } /// \table_row3{ `RDS.ProgStation`, /// \anchor RDS_ProgStation /// _string_, /// @return The name of the radio channel. /// @note becomes also set from epg if it is not available from RDS ///


/// @skinning_v16 **[New Infolabel]** \link RDS_ProgStation `RDS.ProgStation`\endlink ///

/// } /// \table_row3{ `RDS.ProgNow`, /// \anchor RDS_ProgNow /// _string_, /// @return The now playing program name. /// @note becomes also be set from epg if from RDS not available ///


/// @skinning_v16 **[New Infolabel]** \link RDS_ProgNow `RDS.ProgNow`\endlink ///

/// } /// \table_row3{ `RDS.ProgNext`, /// \anchor RDS_ProgNext /// _string_, /// @return The next played program name (if available). /// @note becomes also be set from epg if from RDS not available ///


/// @skinning_v16 **[New Infolabel]** \link RDS_ProgNext `RDS.ProgNext`\endlink ///

/// } /// \table_row3{ `RDS.ProgHost`, /// \anchor RDS_ProgHost /// _string_, /// @return The name of the host of the radio show. ///


/// @skinning_v16 **[New Infolabel]** \link RDS_ProgHost `RDS.ProgHost`\endlink ///

/// } /// \table_row3{ `RDS.ProgEditStaff`, /// \anchor RDS_ProgEditStaff /// _string_, /// @return The name of the editorial staff; e.g. name of editorial journalist. /// @note Only available on RadioText Plus ///


/// @skinning_v16 **[New Infolabel]** \link RDS_ProgEditStaff `RDS.ProgEditStaff`\endlink ///

/// } /// \table_row3{ `RDS.ProgHomepage`, /// \anchor RDS_ProgHomepage /// _string_, /// @return The Link to radio station homepage /// @note Only available on RadioText Plus ///


/// @skinning_v16 **[New Infolabel]** \link RDS_ProgHomepage `RDS.ProgHomepage`\endlink ///

/// } /// \table_row3{ `RDS.ProgStyle`, /// \anchor RDS_ProgStyle /// _string_, /// @return A human readable string about radiostyle defined from RDS or RBDS. ///


/// @skinning_v16 **[New Infolabel]** \link RDS_ProgStyle `RDS.ProgStyle`\endlink ///

/// } /// \table_row3{ `RDS.PhoneHotline`, /// \anchor RDS_PhoneHotline /// _string_, /// @return The telephone number of the radio station's hotline. /// @note Only available on RadioText Plus ///


/// @skinning_v16 **[New Infolabel]** \link RDS_PhoneHotline `RDS.PhoneHotline`\endlink ///

/// } /// \table_row3{ `RDS.PhoneStudio`, /// \anchor RDS_PhoneStudio /// _string_, /// @return The telephone number of the radio station's studio. /// @note Only available on RadioText Plus ///


/// @skinning_v16 **[New Infolabel]** \link RDS_PhoneStudio `RDS.PhoneStudio`\endlink ///

/// } /// \table_row3{ `RDS.SmsStudio`, /// \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 ///


/// @skinning_v16 **[New Infolabel]** \link RDS_SmsStudio `RDS.SmsStudio`\endlink ///

/// } /// \table_row3{ `RDS.EmailHotline`, /// \anchor RDS_EmailHotline /// _string_, /// @return The email address of the radio stations hotline (if available). /// @note Only available on RadioText Plus ///


/// @skinning_v16 **[New Infolabel]** \link RDS_EmailHotline `RDS.EmailHotline`\endlink ///

/// } /// \table_row3{ `RDS.EmailStudio`, /// \anchor RDS_EmailStudio /// _string_, /// @return The email address of the radio station's studio (if available). /// @note Only available on RadioText Plus ///


/// @skinning_v16 **[New Infolabel]** \link RDS_EmailStudio `RDS.EmailStudio`\endlink ///

/// } /// \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{ `Slideshow.IsActive`, /// \anchor Slideshow_IsActive /// _boolean_, /// @return **True** if the picture slideshow is running. ///

/// } /// \table_row3{ `Slideshow.IsPaused`, /// \anchor Slideshow_IsPaused /// _boolean_, /// @return **True** if the picture slideshow is paused. ///

/// } /// \table_row3{ `Slideshow.IsRandom`, /// \anchor Slideshow_IsRandom /// _boolean_, /// @return **True** if the picture slideshow is in random mode. ///

/// } /// \table_row3{ `Slideshow.IsVideo`, /// \anchor Slideshow_IsVideo /// _boolean_, /// @return **True** if the picture slideshow is playing a video. ///


/// @skinning_v13 **[New Boolean Condition]** \link Slideshow_IsVideo `Slideshow.IsVideo`\endlink ///

/// } /// \table_row3{ `Slideshow.Altitude`, /// \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. ///

/// } /// \table_row3{ `Slideshow.Aperture`, /// \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). ///

/// } /// \table_row3{ `Slideshow.Author`, /// \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). ///


/// @skinning_v13 **[New Infolabel]** \link Slideshow_Author `Slideshow.Author`\endlink ///

/// } /// \table_row3{ `Slideshow.Byline`, /// \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). ///


/// @skinning_v13 **[New Infolabel]** \link Slideshow_Byline `Slideshow.Byline`\endlink ///

/// } /// \table_row3{ `Slideshow.BylineTitle`, /// \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). ///


/// @skinning_v13 **[New Infolabel]** \link Slideshow_BylineTitle `Slideshow.BylineTitle`\endlink ///

/// } /// \table_row3{ `Slideshow.CameraMake`, /// \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). ///

/// } /// \table_row3{ `Slideshow.CameraModel`, /// \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). ///

/// } /// \table_row3{ `Slideshow.Caption`, /// \anchor Slideshow_Caption /// _string_, /// @return A description of the current picture. /// @note This is the value of the IPTC Caption tag (hex code 0x78). ///

/// } /// \table_row3{ `Slideshow.Category`, /// \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). ///


/// @skinning_v13 **[New Infolabel]** \link Slideshow_Category `Slideshow.Category`\endlink ///

/// } /// \table_row3{ `Slideshow.CCDWidth`, /// \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). ///


/// @skinning_v13 **[New Infolabel]** \link Slideshow_CCDWidth `Slideshow.CCDWidth`\endlink ///

/// } /// \table_row3{ `Slideshow.City`, /// \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). ///


/// @skinning_v13 **[New Infolabel]** \link Slideshow_City `Slideshow.City`\endlink ///

/// } /// \table_row3{ `Slideshow.Colour`, /// \anchor Slideshow_Colour /// _string_, /// @return the colour of the picture. It can have one of the following values: /// - "Colour" /// - "Black and White" ///


/// @skinning_v13 **[New Infolabel]** \link Slideshow_Colour `Slideshow.Colour`\endlink ///

/// } /// \table_row3{ `Slideshow.CopyrightNotice`, /// \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). ///


/// @skinning_v13 **[New Infolabel]** \link Slideshow_CopyrightNotice `Slideshow.CopyrightNotice`\endlink ///

/// } /// \table_row3{ `Slideshow.Country`, /// \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). ///


/// @skinning_v13 **[New Infolabel]** \link Slideshow_Country `Slideshow.Country`\endlink ///

/// } /// \table_row3{ `Slideshow.CountryCode`, /// \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). ///


/// @skinning_v13 **[New Infolabel]** \link Slideshow_CountryCode `Slideshow.CountryCode`\endlink ///

/// } /// \table_row3{ `Slideshow.Credit`, /// \anchor Slideshow_Credit /// _string_, /// @return Who provided the current picture. /// @note This is the value of the IPTC Credit tag (hex code 0x6E). ///


/// @skinning_v13 **[New Infolabel]** \link Slideshow_Credit `Slideshow.Credit`\endlink ///

/// } /// \table_row3{ `Slideshow.DigitalZoom`, /// \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). ///


/// @skinning_v13 **[New Infolabel]** \link Slideshow_DigitalZoom `Slideshow.DigitalZoom`\endlink ///

/// } /// \table_row3{ `Slideshow.EXIFComment`, /// \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". ///

/// } /// \table_row3{ `Slideshow.EXIFDate`, /// \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. ///


/// @skinning_v13 **[New Infolabel]** \link Slideshow_EXIFDate `Slideshow.EXIFDate`\endlink ///

/// } /// \table_row3{ `Slideshow.EXIFDescription`, /// \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). ///

/// } /// \table_row3{ `Slideshow.EXIFSoftware`, /// \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). ///

/// } /// \table_row3{ `Slideshow.EXIFTime`, /// \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. ///

/// } /// \table_row3{ `Slideshow.Exposure`, /// \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: /// - "Manual" /// - "Program (Auto)" /// - "Aperture priority (Semi-Auto)" /// - "Shutter priority (semi-auto)" /// - etc... /// @note This is the value of the EXIF ExposureProgram tag /// (hex code 0x8822). ///


/// @skinning_v13 **[New Infolabel]** \link Slideshow_Exposure `Slideshow.Exposure`\endlink ///

/// } /// \table_row3{ `Slideshow.ExposureBias`, /// \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). ///


/// @skinning_v13 **[New Infolabel]** \link Slideshow_ExposureBias `Slideshow.ExposureBias`\endlink ///

/// } /// \table_row3{ `Slideshow.ExposureMode`, /// \anchor Slideshow_ExposureMode /// _string_, /// @return The exposure mode of the current picture. The possible values are: /// - "Automatic" /// - "Manual" /// - "Auto bracketing" /// @note This is the value of the EXIF ExposureMode tag (hex code 0xA402). ///

/// } /// \table_row3{ `Slideshow.ExposureTime`, /// \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. ///

/// } /// \table_row3{ `Slideshow.Filedate`, /// \anchor Slideshow_Filedate /// _string_, /// @return The file date of the current picture. ///

/// } /// \table_row3{ `Slideshow.Filename`, /// \anchor Slideshow_Filename /// _string_, /// @return The file name of the current picture. ///

/// } /// \table_row3{ `Slideshow.Filesize`, /// \anchor Slideshow_Filesize /// _string_, /// @return The file size of the current picture. ///

/// } /// \table_row3{ `Slideshow.FlashUsed`, /// \anchor Slideshow_FlashUsed /// _string_, /// @return The status of flash when the current 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). ///


/// @skinning_v13 **[New Infolabel]** \link Slideshow_FlashUsed `Slideshow.FlashUsed`\endlink ///

/// } /// \table_row3{ `Slideshow.FocalLength`, /// \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). ///

/// } /// \table_row3{ `Slideshow.FocusDistance`, /// \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). ///

/// } /// \table_row3{ `Slideshow.Headline`, /// \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). ///


/// @skinning_v13 **[New Infolabel]** \link Slideshow_Headline `Slideshow.Headline`\endlink ///

/// } /// \table_row3{ `Slideshow.ImageType`, /// \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). ///


/// @skinning_v13 **[New Infolabel]** \link Slideshow_ImageType `Slideshow.ImageType`\endlink ///

/// } /// \table_row3{ `Slideshow.IPTCDate`, /// \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). ///

/// } /// \table_row3{ `Slideshow.ISOEquivalence`, /// \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). ///

/// } /// \table_row3{ `Slideshow.Keywords`, /// \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). ///

/// } /// \table_row3{ `Slideshow.Latitude`, /// \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. ///

/// } /// \table_row3{ `Slideshow.LightSource`, /// \anchor Slideshow_LightSource /// _string_, /// @return The kind of light source when the picture was taken. Possible /// values include: /// - "Daylight" /// - "Fluorescent" /// - "Incandescent" /// - etc... /// @note This is the value of the EXIF LightSource tag (hex code 0x9208). ///


/// @skinning_v13 **[New Infolabel]** \link Slideshow_LightSource `Slideshow.LightSource`\endlink ///

/// } /// \table_row3{ `Slideshow.LongEXIFDate`, /// \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. ///


/// @skinning_v13 **[New Infolabel]** \link Slideshow_LongEXIFDate `Slideshow.LongEXIFDate`\endlink ///

/// } /// \table_row3{ `Slideshow.LongEXIFTime`, /// \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. ///


/// @skinning_v13 **[New Infolabel]** \link Slideshow_LongEXIFTime `Slideshow.LongEXIFTime`\endlink ///

/// } /// \table_row3{ `Slideshow.Longitude`, /// \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. ///

/// } /// \table_row3{ `Slideshow.MeteringMode`, /// \anchor Slideshow_MeteringMode /// _string_, /// @return The metering mode used when the current picture was taken. The /// possible values are: /// - "Center weight" /// - "Spot" /// - "Matrix" /// @note This is the value of the EXIF MeteringMode tag (hex code 0x9207). ///


/// @skinning_v13 **[New Infolabel]** \link Slideshow_MeteringMode `Slideshow.MeteringMode`\endlink ///

/// } /// \table_row3{ `Slideshow.ObjectName`, /// \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). ///


/// @skinning_v13 **[New Infolabel]** \link Slideshow_ObjectName `Slideshow.ObjectName`\endlink ///

/// } /// \table_row3{ `Slideshow.Orientation`, /// \anchor Slideshow_Orientation /// _string_, /// @return The orientation of the current picture. Possible values are: /// - "Top Left" /// - "Top Right" /// - "Left Top" /// - "Right Bottom" /// - etc... /// @note This is the value of the EXIF Orientation tag (hex code 0x0112). ///


/// @skinning_v13 **[New Infolabel]** \link Slideshow_Orientation `Slideshow.Orientation`\endlink ///

/// } /// \table_row3{ `Slideshow.Path`, /// \anchor Slideshow_Path /// _string_, /// @return The file path of the current picture. ///

/// } /// \table_row3{ `Slideshow.Process`, /// \anchor Slideshow_Process /// _string_, /// @return The process used to compress the current picture. ///


/// @skinning_v13 **[New Infolabel]** \link Slideshow_Process `Slideshow.Process`\endlink ///

/// } /// \table_row3{ `Slideshow.ReferenceService`, /// \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). ///


/// @skinning_v13 **[New Infolabel]** \link Slideshow_ReferenceService `Slideshow.ReferenceService`\endlink ///

/// } /// \table_row3{ `Slideshow.Resolution`, /// \anchor Slideshow_Resolution /// _string_, /// @return The dimensions of the current picture (Width x Height) ///

/// } /// \table_row3{ `Slideshow.SlideComment`, /// \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". ///

/// } /// \table_row3{ `Slideshow.SlideIndex`, /// \anchor Slideshow_SlideIndex /// _string_, /// @return The slide index of the current picture. ///

/// } /// \table_row3{ `Slideshow.Source`, /// \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). ///


/// @skinning_v13 **[New Infolabel]** \link Slideshow_Source `Slideshow.Source`\endlink ///

/// } /// \table_row3{ `Slideshow.SpecialInstructions`, /// \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). ///


/// @skinning_v13 **[New Infolabel]** \link Slideshow_SpecialInstructions `Slideshow.SpecialInstructions`\endlink ///

/// } /// \table_row3{ `Slideshow.State`, /// \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). ///


/// @skinning_v13 **[New Infolabel]** \link Slideshow_State `Slideshow.State`\endlink ///

/// } /// \table_row3{ `Slideshow.Sublocation`, /// \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). ///


/// @skinning_v13 **[New Infolabel]** \link Slideshow_Sublocation `Slideshow.Sublocation`\endlink ///

/// } /// \table_row3{ `Slideshow.SupplementalCategories`, /// \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). ///


/// @skinning_v13 **[New Infolabel]** \link Slideshow_SupplementalCategories `Slideshow.SupplementalCategories`\endlink ///

/// } /// \table_row3{ `Slideshow.TimeCreated`, /// \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). ///


/// @skinning_v13 **[New Infolabel]** \link Slideshow_TimeCreated `Slideshow.TimeCreated`\endlink ///

/// } /// \table_row3{ `Slideshow.TransmissionReference`, /// \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). ///


/// @skinning_v13 **[New Infolabel]** \link Slideshow_TransmissionReference `Slideshow.TransmissionReference`\endlink ///

/// } /// \table_row3{ `Slideshow.Urgency`, /// \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). ///


/// @skinning_v13 **[New Infolabel]** \link Slideshow_Urgency `Slideshow.Urgency`\endlink ///

/// } /// \table_row3{ `Slideshow.WhiteBalance`, /// \anchor Slideshow_WhiteBalance /// _string_, /// @return The white balance mode set when the current picture was taken. /// The possible values are: /// - "Manual" /// - "Auto" ///

/// @note This is the value of the EXIF WhiteBalance tag (hex code 0xA403). ///


/// @skinning_v13 **[New Infolabel]** \link Slideshow_WhiteBalance `Slideshow.WhiteBalance`\endlink ///

/// } /// \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{ `Library.IsScanning`, /// \anchor Library_IsScanning /// _boolean_, /// @return **True** if the library is being scanned. ///

/// } /// \table_row3{ `Library.IsScanningVideo`, /// \anchor Library_IsScanningVideo /// _boolean_, /// @return **True** if the video library is being scanned. ///

/// } /// \table_row3{ `Library.IsScanningMusic`, /// \anchor Library_IsScanningMusic /// _boolean_, /// @return **True** if the music library is being scanned. ///

/// } /// \table_row3{ `Library.HasContent(music)`, /// \anchor Library_HasContent_Music /// _boolean_, /// @return **True** if the library has music content. ///

/// } /// \table_row3{ `Library.HasContent(video)`, /// \anchor Library_HasContent_Video /// _boolean_, /// @return **True** if the library has video content. ///

/// } /// \table_row3{ `Library.HasContent(movies)`, /// \anchor Library_HasContent_Movies /// _boolean_, /// @return **True** if the library has movies. ///

/// } /// \table_row3{ `Library.HasContent(tvshows)`, /// \anchor Library_HasContent_TVShows /// _boolean_, /// @return **True** if the library has tvshows. ///

/// } /// \table_row3{ `Library.HasContent(musicvideos)`, /// \anchor Library_HasContent_MusicVideos /// _boolean_, /// @return **True** if the library has music videos. ///

/// } /// \table_row3{ `Library.HasContent(moviesets)`, /// \anchor Library_HasContent_MovieSets /// _boolean_, /// @return **True** if the library has movie sets. ///

/// } /// \table_row3{ `Library.HasContent(singles)`, /// \anchor Library_HasContent_Singles /// _boolean_, /// @return **True** if the library has singles. ///

/// } /// \table_row3{ `Library.HasContent(compilations)`, /// \anchor Library_HasContent_Compilations /// _boolean_, /// @return **True** if the library has compilations. ///

/// } /// \table_row3{ `Library.HasContent(Role.Composer)`, /// \anchor Library_HasContent_Role_Composer /// _boolean_, /// @return **True** if there are songs in the library which have composers. ///


/// @skinning_v17 **[New Boolean Condition]** \link Library_HasContent_Role_Composer `Library.HasContent(Role.Composer)`\endlink ///

/// } /// \table_row3{ `Library.HasContent(Role.Conductor)`, /// \anchor Library_HasContent_Role_Conductor /// _boolean_, /// @return **True** if there are songs in the library which have a conductor. ///


/// @skinning_v17 **[New Boolean Condition]** \link Library_HasContent_Role_Conductor `Library.HasContent(Role.Conductor)`\endlink ///

/// } /// \table_row3{ `Library.HasContent(Role.Orchestra)`, /// \anchor Library_HasContent_Role_Orchestra /// _boolean_, /// @return **True** if there are songs in the library which have an orchestra. ///


/// @skinning_v17 **[New Boolean Condition]** \link Library_HasContent_Role_Orchestra `Library.HasContent(Role.Orchestra)`\endlink ///

/// } /// \table_row3{ `Library.HasContent(Role.Lyricist)`, /// \anchor Library_HasContent_Role_Lyricist /// _boolean_, /// @return **True** if there are songs in the library which have a lyricist. ///


/// @skinning_v17 **[New Boolean Condition]** \link Library_HasContent_Role_Lyricist `Library.HasContent(Role.Lyricist)`\endlink ///

/// } /// \table_row3{ `Library.HasContent(Role.Remixer)`, /// \anchor Library_HasContent_Role_Remixer /// _boolean_, /// @return **True** if there are songs in the library which have a remixer. ///


/// @skinning_v17 **[New Boolean Condition]** \link Library_HasContent_Role_Remixer `Library.HasContent(Role.Remixer)`\endlink ///

/// } /// \table_row3{ `Library.HasContent(Role.Arranger)`, /// \anchor Library_HasContent_Role_Remixer /// _boolean_, /// @return **True** if there are songs in the library which have an arranger. ///


/// @skinning_v17 **[New Boolean Condition]** \link Library_HasContent_Role_Remixer `Library.HasContent(Role.Arranger)`\endlink ///

/// } /// \table_row3{ `Library.HasContent(Role.Engineer)`, /// \anchor Library_HasContent_Role_Engineer /// _boolean_, /// @return **True** if there are songs in the library which have an engineer. ///


/// @skinning_v17 **[New Boolean Condition]** \link Library_HasContent_Role_Engineer `Library.HasContent(Role.Engineer)`\endlink ///

/// } /// \table_row3{ `Library.HasContent(Role.Producer)`, /// \anchor Library_HasContent_Role_Producer /// _boolean_, /// @return **True** if there are songs in the library which have an producer. ///


/// @skinning_v17 **[New Boolean Condition]** \link Library_HasContent_Role_Producer `Library.HasContent(Role.Producer)`\endlink ///

/// } /// \table_row3{ `Library.HasContent(Role.DJMixer)`, /// \anchor Library_HasContent_Role_DJMixer /// _boolean_, /// @return **True** if there are songs in the library which have a DJMixer. ///


/// @skinning_v17 **[New Boolean Condition]** \link Library_HasContent_Role_DJMixer `Library.HasContent(Role.DJMixer)`\endlink ///

/// } /// \table_row3{ `Library.HasContent(Role.Mixer)`, /// \anchor Library_HasContent_Role_Mixer /// _boolean_, /// @return **True** if there are songs in the library which have a mixer. ///


/// @skinning_v17 **[New Boolean Condition]** \link Library_HasContent_Role_Mixer `Library.HasContent(Role.Mixer)`\endlink ///

/// } /// \table_row3{ `Library.HasContent(boxsets)`, /// \anchor Library_HasContent_Boxsets /// _boolean_, /// @return **True** if there are albums in the library which are boxsets. ///


/// @skinning_v19 **[New Boolean Condition]** \link Library_HasContent_Boxsets `Library.HasContent(boxsets)`\endlink ///

/// } /// \table_row3{ `Library.HasNode(path)`, /// \anchor Library_HasNode /// _boolean_, /// @return **True** if there the node is present in the library. ///


/// @skinning_v19 **[New Boolean Condition]** \link Library_HasNode `Library.HasNode(path)`\endlink ///

/// } /// \table_end /// /// ----------------------------------------------------------------------------- /// \page modules__infolabels_boolean_conditions /// \section modules_rm_infolabels_booleans Additional revision history for Infolabels and Boolean Conditions ///


/// \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 /// ///
/// \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 /// ///
/// \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 albumartist[n].* or artist[n].* as type /// - `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` ///
/// \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)` ///
/// \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` ///
/// \subsection modules_rm_infolabels_booleans_v15 Kodi v15 (Isengard) ///
/// \subsection modules_rm_infolabels_booleans_v14 Kodi v14 (Helix) /// @skinning_v14 **[New Infolabels]** The following infolabels were added: /// - `ListItem.SubChannelNumber` /// - `MusicPlayer.SubChannelNumber` /// - `VideoPlayer.SubChannelNumber` /// ///
/// \subsection modules_rm_infolabels_booleans_v13 XBMC v13 (Gotham) /// @skinning_v13 **[Removed Infolabels]** The following infolabels were removed: /// - `Network.SubnetAddress` /// ///
// 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 &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 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(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 lock(m_critInfo); std::pair res; if (condition.find_first_of("|+[]!") != condition.npos) res = m_bools.insert(std::make_shared(condition, context, m_refreshCounter)); else res = m_bools.insert(std::make_shared(condition, context, m_refreshCounter)); if (res.second) res.first->get()->Initialize(); return *(res.first); } void CGUIInfoManager::UnRegister(const INFO::InfoPtr& expression) { std::unique_lock 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(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 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(); 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(i) + MULTI_INFO_START; // return the new offset m_multiInfo.emplace_back(info); int id = static_cast(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(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(item); return pItem->IsParentFolder(); } break; } } } return value; } void CGUIInfoManager::ResetCache() { // mark our infobools as dirty std::unique_lock 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 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::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(m_skinVariableStrings.size())) return m_skinVariableStrings[info].GetValue(contextWindow, preferImage, item); return ""; } bool CGUIInfoManager::ConditionsChangedValues(const std::map& map) { for (std::map::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*>(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*>(pMsg->lpVoid); for (auto& param : pMsg->params) infoLabels->push_back(EvaluateBool(param, DEFAULT_CONTEXT)); } } break; case TMSG_UPDATE_CURRENT_ITEM: { CFileItem* item = static_cast(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 lock(CServiceBroker::GetWinSystem()->GetGfxContext()); m_infoProviders.RegisterProvider(provider, false); } void CGUIInfoManager::UnregisterInfoProvider(IGUIInfoProvider *provider) { if (!CServiceBroker::GetWinSystem()) return; std::unique_lock lock(CServiceBroker::GetWinSystem()->GetGfxContext()); m_infoProviders.UnregisterProvider(provider); }