# Kodi Addon Settings System – Kompletní výzkum

**Datum**: 2026-04-06
**Dotazy**: Kodi settings.xml format, visibility conditions eq(), setting types, Python API, v1 vs v2, slider/select/action format

## Shrnutí

Kodi addon settings jsou definovány v `resources/settings.xml`. Existují dva formáty: **v1 (legacy)** – jednoduchý flat XML, a **v2 (Kodi 19+)** – strukturovaný s groups/dependencies. Plugin plugin.video.milionar používá v1 formát, který je stále plně podporován. Klíčový objev: v `eq(-N, value)` se počítají VŠECHNY `<setting>` elementy včetně `sep`, `lsep` a `text` – nikoliv jen ty s `id`. Podmínky fungují pouze v rámci jedné `<category>`.

## Detailní zjištění

### V1 formát (legacy) – používáme

#### Struktura
```xml
<?xml version="1.0" encoding="UTF-8"?>
<settings>
    <category label="32001">
        <setting id="..." type="..." label="..." default="..." />
    </category>
</settings>
```

#### Všechny typy settings

| Typ | Popis | Uložená hodnota | Klíčové atributy |
|-----|-------|-----------------|-------------------|
| `text` | Textový vstup | string | `option="hidden"` pro hesla |
| `ipaddress` | IP adresa | string | – |
| `number` | Celé číslo (up/down) | string čísla | – |
| `bool` | Přepínač true/false | `"true"/"false"` | – |
| `select` | Dialog výběru | index (0,1,2...) jako string | `values=`, `lvalues=` |
| `enum` | Spinner (inline) | index jako string | `values=`, `lvalues=` |
| `labelenum` | Spinner (labeled) | text hodnoty | `values=`, `lvalues=` |
| `slider` | Posuvník | hodnota jako string | `range=`, `option=`, nebo `min/max/step` |
| `file` | Výběr souboru | cesta | `mask=` |
| `folder` | Výběr složky | cesta | `option="writeable"` |
| `audio` | Výběr audio souboru | cesta | – |
| `video` | Výběr video souboru | cesta | – |
| `image` | Výběr obrázku | cesta | – |
| `executable` | Výběr spustitelného | cesta | – |
| `addon` | Výběr addonu | addon ID | `addontype=` |
| `action` | Tlačítko s akcí | – (nemaže se) | `action=` |
| `sep` | Horizontální čára | – | – |
| `lsep` | Nadpis sekce | – | `label=` |

#### Atributy settings

| Atribut | Popis | Příklad |
|---------|-------|---------|
| `id` | Unikátní identifikátor | `id="my_setting"` |
| `type` | Typ prvku | `type="bool"` |
| `label` | Popis (string ID nebo text) | `label="32001"` nebo `label="Název"` |
| `default` | Výchozí hodnota | `default="true"` |
| `values` | Seznam hodnot (pipe-separated) | `values="A\|B\|C"` |
| `lvalues` | Seznam string ID (lokalizované) | `lvalues="32001\|32002"` |
| `visible` | Podmínka viditelnosti | `visible="eq(-1,true)"` |
| `enable` | Podmínka aktivnosti | `enable="eq(-1,true)"` |
| `subsetting` | Vizuální odsazení | `subsetting="true"` |
| `option` | Modifikátor typu | `option="hidden"`, `option="float"` |
| `source` | Zdroj pro file/folder | `source="auto"` |
| `range` | Rozsah pro slider | `range="0.0,0.1,1.0"` |
| `min/max/step` | Alternativa k range | `min="1" max="100" step="5"` |
| `action` | Kodi příkaz pro action typ | `action="RunPlugin(...)"` |
| `mask` | Filter souborů | `mask=".xml\|.txt"` |
| `addontype` | Typ addonu pro addon typ | `addontype="xbmc.python.script"` |

#### select vs enum vs labelenum

- **`select`** s `values=` → otevře dialog, uloží **index** (0,1,2...)
- **`select`** s `lvalues=` → otevře dialog, uloží **index** (0,1,2...), zobrazí lokalizovaný text
- **`enum`** → inline spinner, uloží **index**
- **`labelenum`** → inline spinner, uloží **samotnou hodnotu** (text)

#### Slider formáty

Dva způsoby definice rozsahu:
```xml
<!-- Způsob 1: range atribut (starší) -->
<setting type="slider" range="0.0,0.1,1.0" option="float" />

<!-- Způsob 2: min/max/step atributy (novější, čitelnější) -->
<setting type="slider" min="1" max="100" step="5" />
```

`option` pro slider: `"int"`, `"float"`, `"percent"`

#### Visibility a Enable podmínky

**Syntax**: `visible="CONDITION"` / `enable="CONDITION"`

**Komparátory**:
- `eq(-N, value)` – setting N pozic zpět se rovná value
- `gt(-N, value)` – greater than
- `lt(-N, value)` – less than
- `!eq(-N, value)` – NOT equal

**Logické operátory**:
- `+` = AND
- `|` = OR (nelze v atributu, jen v Kodi interně)
- `!` = NOT

**Kombinace**: `visible="!eq(-3,false) + !eq(-1,false)"`

### ⚠️ KRITICKÉ: Jak funguje počítání eq(-N)

**VŠECHNY `<setting>` elementy se počítají**, včetně:
- `<setting type="sep"/>` – čára
- `<setting type="lsep" label="..."/>` – nadpis sekce
- `<setting type="text" label="..." enable="false"/>` – popisný text

**Příklad počítání:**
```xml
<setting type="sep"/>                     <!-- pozice: -8 -->
<setting type="lsep" label="Sekce"/>      <!-- pozice: -7 -->
<setting type="text" label="Popis"/>       <!-- pozice: -6 -->
<setting id="switch" type="bool"/>         <!-- pozice: -5 -->
<setting type="sep"/>                     <!-- pozice: -4 -->
<setting type="lsep" label="Další"/>       <!-- pozice: -3 -->
<setting type="text" label="Info"/>        <!-- pozice: -2 -->
<setting id="child" type="bool"/>          <!-- pozice: -1 -->
<setting id="target" visible="eq(-5,true)"/> <!-- TADY: -5 = switch -->
```

**Pravidla**:
- Počítá se od aktuálního elementu SMĚREM NAHORU
- Scope je POUZE v rámci jedné `<category>`
- Nelze odkazovat mezi kategoriemi

#### Action settings

```xml
<!-- RunPlugin – spustí plugin s parametry -->
<setting id="btn" type="action" label="Tlačítko" 
         action="RunPlugin(plugin://plugin.video.milionar/?action=my_action)" />

<!-- RunScript – spustí Python skript -->
<setting type="action" label="Spustit" 
         action="RunScript(script.addon.id, param1, param2)" />
```

⚠️ Action se spustí IHNED po kliknutí. Settings dialog zůstává otevřený. Dosud neuložené hodnoty v dialogu NEJSOU viditelné pro skript (musí se nejdřív potvrdit OK).

#### Skryté settings

```xml
<!-- Interní settings – v UI neviditelné -->
<setting id="internal_token" type="text" visible="false" default="" />
```

Používá se pro uložení tokenů, migračních flagů, interního stavu.

### Python API pro settings

#### V1 API (všechny verze Kodi)
```python
import xbmcaddon
addon = xbmcaddon.Addon()

# Čtení – VŽDY vrací string!
value = addon.getSetting('id')            # "true", "false", "0", "text"

# Zápis – VŽDY string!
addon.setSetting('id', 'new_value')

# Otevření dialogu
addon.openSettings()
```

#### V2 API (Kodi 20+)
```python
settings = addon.getSettings()

# Typované gettery
enabled = settings.getBool('enabled')      # bool
count = settings.getInt('count')           # int  
name = settings.getString('name')          # str

# Typované settery
settings.setBool('enabled', True)
settings.setInt('count', 42)
settings.setString('name', 'test')
```

#### ⚠️ Gotchas
- `getSetting('bool_id')` vrací `"true"` nebo `"false"` (STRING, ne bool!)
- `"false"` je v Pythonu truthy → `if addon.getSetting('enabled')` je VŽDY True!
- Správně: `addon.getSetting('enabled') == 'true'` nebo `getSettingBool()`
- `setSetting()` při otevřeném settings dialogu se NEPROJEVÍ v UI
- Settings se ukládají do: `~/.kodi/userdata/addon_data/<addon-id>/settings.xml`

### V2 formát (Kodi 19+ Matrix)

Strukturovanější, s explicitními dependencies místo relativního eq():

```xml
<settings version="2">
    <section id="main">
        <category id="general" label="32001">
            <group id="grp1" label="32010">
                <setting id="enabled" type="boolean" label="32011">
                    <level>0</level>
                    <default>true</default>
                    <control type="toggle"/>
                </setting>
                <setting id="interval" type="integer" label="32012">
                    <level>0</level>
                    <default>15</default>
                    <constraints>
                        <minimum>5</minimum>
                        <maximum>60</maximum>
                        <step>5</step>
                    </constraints>
                    <dependencies>
                        <dependency type="visible" setting="enabled">true</dependency>
                    </dependencies>
                    <control type="slider" format="integer"/>
                </setting>
            </group>
        </category>
    </section>
</settings>
```

**Výhody v2**: Odkazování přes ID (ne relativní), groups, levels, constraints.
**Nevýhody**: Výrazně více XML, méně přehledný pro jednoduché addony.

## Zdroje
- Kodi Wiki – Add-on Settings (403, info z cache)
- Kodi Wiki – Add-on Settings Conversion
- Kodi Forum – diskuse o eq() counting
- Kodi GitHub – settings parser source

## Závěr a doporučení

1. Plugin plugin.video.milionar používá **v1 formát** – je plně funkční a jednodušší
2. Pro podmíněné zobrazení: přesuň referenční setting NAHORU, pak použij `eq(-N, value)` s přesným počítáním VŠECH elementů
3. Při práci se settings VŽDY čti hodnoty jako string a konvertuj explicitně
4. Pro skryté interní data použij `visible="false"`
5. Action settings nespoléhej na neuložené hodnoty v dialogu
