Add HDR column to format table and translations

Introduces an HDR (High Dynamic Range) column to the format table in both playlist and normal modes, updating column counts, widths, and item population logic accordingly. Also adds the 'hdr' translation key to all supported languages.
This commit is contained in:
Your Name
2025-10-04 14:03:29 +03:00
parent 4bc677add3
commit 79b03bd083
15 changed files with 66 additions and 12 deletions
+1
View File
@@ -40,6 +40,7 @@
"codec": "الترميز", "codec": "الترميز",
"audio": "الصوت", "audio": "الصوت",
"fps": "إطار/ث", "fps": "إطار/ث",
"hdr": "HDR",
"will_merge_audio": "سيتم دمج الصوت", "will_merge_audio": "سيتم دمج الصوت",
"has_audio": "✓ يحتوي على صوت", "has_audio": "✓ يحتوي على صوت",
"audio_only": "صوت فقط", "audio_only": "صوت فقط",
+1
View File
@@ -40,6 +40,7 @@
"codec": "Codec", "codec": "Codec",
"audio": "Audio", "audio": "Audio",
"fps": "FPS", "fps": "FPS",
"hdr": "HDR",
"will_merge_audio": "Audio wird zusammengeführt", "will_merge_audio": "Audio wird zusammengeführt",
"has_audio": "✓ Hat Audio", "has_audio": "✓ Hat Audio",
"audio_only": "Nur Audio", "audio_only": "Nur Audio",
+1
View File
@@ -40,6 +40,7 @@
"codec": "Codec", "codec": "Codec",
"audio": "Audio", "audio": "Audio",
"fps": "FPS", "fps": "FPS",
"hdr": "HDR",
"will_merge_audio": "Will merge audio", "will_merge_audio": "Will merge audio",
"has_audio": "✓ Has Audio", "has_audio": "✓ Has Audio",
"audio_only": "Audio Only", "audio_only": "Audio Only",
+1
View File
@@ -147,6 +147,7 @@
"codec": "Códec", "codec": "Códec",
"audio": "Audio", "audio": "Audio",
"fps": "FPS", "fps": "FPS",
"hdr": "HDR",
"will_merge_audio": "Se combinará audio", "will_merge_audio": "Se combinará audio",
"has_audio": "✓ Tiene Audio", "has_audio": "✓ Tiene Audio",
"audio_only": "Solo Audio", "audio_only": "Solo Audio",
+1
View File
@@ -40,6 +40,7 @@
"codec": "Codec", "codec": "Codec",
"audio": "Audio", "audio": "Audio",
"fps": "IPS", "fps": "IPS",
"hdr": "HDR",
"will_merge_audio": "L'audio sera fusionné", "will_merge_audio": "L'audio sera fusionné",
"has_audio": "✓ Contient de l'audio", "has_audio": "✓ Contient de l'audio",
"audio_only": "Audio uniquement", "audio_only": "Audio uniquement",
+1
View File
@@ -40,6 +40,7 @@
"codec": "कोडेक", "codec": "कोडेक",
"audio": "ऑडियो", "audio": "ऑडियो",
"fps": "फ्रेम दर", "fps": "फ्रेम दर",
"hdr": "HDR",
"will_merge_audio": "ऑडियो मर्ज किया जाएगा", "will_merge_audio": "ऑडियो मर्ज किया जाएगा",
"has_audio": "✓ ऑडियो है", "has_audio": "✓ ऑडियो है",
"audio_only": "केवल ऑडियो", "audio_only": "केवल ऑडियो",
+1
View File
@@ -40,6 +40,7 @@
"codec": "Codec", "codec": "Codec",
"audio": "Audio", "audio": "Audio",
"fps": "FPS", "fps": "FPS",
"hdr": "HDR",
"will_merge_audio": "Audio akan digabungkan", "will_merge_audio": "Audio akan digabungkan",
"has_audio": "✓ Memiliki audio", "has_audio": "✓ Memiliki audio",
"audio_only": "Audio saja", "audio_only": "Audio saja",
+1
View File
@@ -40,6 +40,7 @@
"codec": "Codec", "codec": "Codec",
"audio": "Audio", "audio": "Audio",
"fps": "FPS", "fps": "FPS",
"hdr": "HDR",
"will_merge_audio": "L'audio verrà unito", "will_merge_audio": "L'audio verrà unito",
"has_audio": "✓ Contiene audio", "has_audio": "✓ Contiene audio",
"audio_only": "Solo audio", "audio_only": "Solo audio",
+1
View File
@@ -40,6 +40,7 @@
"codec": "コーデック", "codec": "コーデック",
"audio": "音声", "audio": "音声",
"fps": "FPS", "fps": "FPS",
"hdr": "HDR",
"will_merge_audio": "音声が結合されます", "will_merge_audio": "音声が結合されます",
"has_audio": "✓ 音声あり", "has_audio": "✓ 音声あり",
"audio_only": "音声のみ", "audio_only": "音声のみ",
+1
View File
@@ -40,6 +40,7 @@
"codec": "Kodek", "codec": "Kodek",
"audio": "Dźwięk", "audio": "Dźwięk",
"fps": "KL/S", "fps": "KL/S",
"hdr": "HDR",
"will_merge_audio": "Dźwięk zostanie połączony", "will_merge_audio": "Dźwięk zostanie połączony",
"has_audio": "✓ Zawiera dźwięk", "has_audio": "✓ Zawiera dźwięk",
"audio_only": "Tylko dźwięk", "audio_only": "Tylko dźwięk",
+1
View File
@@ -40,6 +40,7 @@
"codec": "Codec", "codec": "Codec",
"audio": "Áudio", "audio": "Áudio",
"fps": "FPS", "fps": "FPS",
"hdr": "HDR",
"will_merge_audio": "Irá mesclar áudio", "will_merge_audio": "Irá mesclar áudio",
"has_audio": "✓ Tem Áudio", "has_audio": "✓ Tem Áudio",
"audio_only": "Apenas Áudio", "audio_only": "Apenas Áudio",
+1
View File
@@ -40,6 +40,7 @@
"codec": "Кодек", "codec": "Кодек",
"audio": "Аудио", "audio": "Аудио",
"fps": "Кадр/с", "fps": "Кадр/с",
"hdr": "HDR",
"will_merge_audio": "Объединит аудио", "will_merge_audio": "Объединит аудио",
"has_audio": "✓ Есть аудио", "has_audio": "✓ Есть аудио",
"audio_only": "Только аудио", "audio_only": "Только аудио",
+1
View File
@@ -40,6 +40,7 @@
"codec": "Codec", "codec": "Codec",
"audio": "Ses", "audio": "Ses",
"fps": "FPS", "fps": "FPS",
"hdr": "HDR",
"will_merge_audio": "Ses birleştirilecek", "will_merge_audio": "Ses birleştirilecek",
"has_audio": "✓ Ses var", "has_audio": "✓ Ses var",
"audio_only": "Sadece ses", "audio_only": "Sadece ses",
+1
View File
@@ -40,6 +40,7 @@
"codec": "编解码器", "codec": "编解码器",
"audio": "音频", "audio": "音频",
"fps": "帧率", "fps": "帧率",
"hdr": "HDR",
"will_merge_audio": "将合并音频", "will_merge_audio": "将合并音频",
"has_audio": "✓ 有音频", "has_audio": "✓ 有音频",
"audio_only": "仅音频", "audio_only": "仅音频",
+52 -12
View File
@@ -27,12 +27,13 @@ class FormatTableMixin:
self = cast("YTSageApp", self) self = cast("YTSageApp", self)
if is_playlist_mode: if is_playlist_mode:
# Playlist mode: 5 columns # Playlist mode: 6 columns
configs = [ configs = [
{"min_width": 70, "padding": 40}, # Select {"min_width": 70, "padding": 40}, # Select
{"min_width": 100, "padding": 30}, # Quality {"min_width": 100, "padding": 30}, # Quality
{"min_width": 100, "padding": 30}, # Resolution {"min_width": 100, "padding": 30}, # Resolution
{"min_width": 60, "padding": 30}, # FPS {"min_width": 60, "padding": 30}, # FPS
{"min_width": 60, "padding": 30}, # HDR
{"min_width": 100, "padding": 30}, # Audio {"min_width": 100, "padding": 30}, # Audio
] ]
@@ -41,10 +42,10 @@ class FormatTableMixin:
self.format_table.setColumnWidth(0, calculated_width) self.format_table.setColumnWidth(0, calculated_width)
# Remaining columns stretch # Remaining columns stretch
for i in range(1, 5): for i in range(1, 6):
self.format_table.horizontalHeader().setSectionResizeMode(i, QHeaderView.ResizeMode.Stretch) self.format_table.horizontalHeader().setSectionResizeMode(i, QHeaderView.ResizeMode.Stretch)
else: else:
# Normal mode: 8 columns # Normal mode: 9 columns
configs = [ configs = [
{"min_width": 70, "padding": 40}, # Select - needs space for checkbox {"min_width": 70, "padding": 40}, # Select - needs space for checkbox
{"min_width": 100, "padding": 30}, # Quality {"min_width": 100, "padding": 30}, # Quality
@@ -54,15 +55,16 @@ class FormatTableMixin:
{"min_width": 100, "padding": 30}, # Codec {"min_width": 100, "padding": 30}, # Codec
{"min_width": 100, "padding": 30}, # Audio {"min_width": 100, "padding": 30}, # Audio
{"min_width": 60, "padding": 30}, # FPS {"min_width": 60, "padding": 30}, # FPS
{"min_width": 60, "padding": 30}, # HDR
] ]
for col_index, (label, config) in enumerate(zip(header_labels, configs)): for col_index, (label, config) in enumerate(zip(header_labels, configs)):
calculated_width = self._calculate_column_width(label, config["min_width"], config["padding"]) calculated_width = self._calculate_column_width(label, config["min_width"], config["padding"])
if col_index < 7: # All columns except the last one are fixed if col_index < 8: # All columns except the last one are fixed
self.format_table.horizontalHeader().setSectionResizeMode(col_index, QHeaderView.ResizeMode.Fixed) self.format_table.horizontalHeader().setSectionResizeMode(col_index, QHeaderView.ResizeMode.Fixed)
self.format_table.setColumnWidth(col_index, calculated_width) self.format_table.setColumnWidth(col_index, calculated_width)
else: # FPS column stretches to fill remaining space else: # HDR column stretches to fill remaining space
self.format_table.horizontalHeader().setSectionResizeMode(col_index, QHeaderView.ResizeMode.Stretch) self.format_table.horizontalHeader().setSectionResizeMode(col_index, QHeaderView.ResizeMode.Stretch)
def setup_format_table(self) -> QTableWidget: def setup_format_table(self) -> QTableWidget:
@@ -71,7 +73,7 @@ class FormatTableMixin:
self.format_signals = FormatSignals() self.format_signals = FormatSignals()
# Format table with improved styling # Format table with improved styling
self.format_table = QTableWidget() self.format_table = QTableWidget()
self.format_table.setColumnCount(8) self.format_table.setColumnCount(9)
# Get translated header labels # Get translated header labels
header_labels = [ header_labels = [
@@ -83,6 +85,7 @@ class FormatTableMixin:
_("formats.codec"), _("formats.codec"),
_("formats.audio"), _("formats.audio"),
_("formats.fps"), _("formats.fps"),
_("formats.hdr"),
] ]
self.format_table.setHorizontalHeaderLabels(header_labels) self.format_table.setHorizontalHeaderLabels(header_labels)
@@ -217,20 +220,20 @@ class FormatTableMixin:
# Configure columns based on mode # Configure columns based on mode
if is_playlist_mode: if is_playlist_mode:
self.format_table.setColumnCount(5) self.format_table.setColumnCount(6)
header_labels = [_("formats.select"), _("formats.quality"), _("formats.resolution"), _("formats.fps"), _("formats.audio")] header_labels = [_("formats.select"), _("formats.quality"), _("formats.resolution"), _("formats.fps"), _("formats.hdr"), _("formats.audio")]
self.format_table.setHorizontalHeaderLabels(header_labels) self.format_table.setHorizontalHeaderLabels(header_labels)
# Configure column visibility and resizing for playlist mode # Configure column visibility and resizing for playlist mode
self.format_table.setColumnHidden(5, True)
self.format_table.setColumnHidden(6, True) self.format_table.setColumnHidden(6, True)
self.format_table.setColumnHidden(7, True) self.format_table.setColumnHidden(7, True)
self.format_table.setColumnHidden(8, True)
# Apply responsive column widths for playlist mode # Apply responsive column widths for playlist mode
self._apply_column_widths(header_labels, is_playlist_mode=True) self._apply_column_widths(header_labels, is_playlist_mode=True)
else: else:
self.format_table.setColumnCount(8) self.format_table.setColumnCount(9)
header_labels = [ header_labels = [
_("formats.select"), _("formats.select"),
_("formats.quality"), _("formats.quality"),
@@ -240,11 +243,12 @@ class FormatTableMixin:
_("formats.codec"), _("formats.codec"),
_("formats.audio"), _("formats.audio"),
_("formats.fps"), _("formats.fps"),
_("formats.hdr"),
] ]
self.format_table.setHorizontalHeaderLabels(header_labels) self.format_table.setHorizontalHeaderLabels(header_labels)
# Ensure all columns are visible # Ensure all columns are visible
for i in range(2, 8): for i in range(2, 9):
self.format_table.setColumnHidden(i, False) self.format_table.setColumnHidden(i, False)
# Apply responsive column widths for normal mode # Apply responsive column widths for normal mode
@@ -316,6 +320,24 @@ class FormatTableMixin:
else: else:
fps_item.setForeground(QColor("#888888")) # Gray for N/A fps_item.setForeground(QColor("#888888")) # Gray for N/A
self.format_table.setItem(row, 3, fps_item) self.format_table.setItem(row, 3, fps_item)
# Column 4: HDR for playlist mode
if f.get("vcodec") == "none":
# Audio-only formats don't have HDR
hdr_text = "N/A"
hdr_item = QTableWidgetItem(hdr_text)
hdr_item.setForeground(QColor("#888888")) # Gray for N/A
else:
hdr_value = f.get("dynamic_range")
if hdr_value and hdr_value != "SDR":
hdr_text = hdr_value
hdr_item = QTableWidgetItem(hdr_text)
hdr_item.setForeground(QColor("#00ffff")) # Cyan for HDR
else:
hdr_text = "SDR"
hdr_item = QTableWidgetItem(hdr_text)
hdr_item.setForeground(QColor("#888888")) # Gray for SDR
self.format_table.setItem(row, 4, hdr_item)
else: else:
# Extension for normal mode (column 2) # Extension for normal mode (column 2)
self.format_table.setItem(row, 2, QTableWidgetItem(f.get("ext", "").upper())) self.format_table.setItem(row, 2, QTableWidgetItem(f.get("ext", "").upper()))
@@ -331,7 +353,7 @@ class FormatTableMixin:
else: # Has Audio (Video+Audio) else: # Has Audio (Video+Audio)
audio_item.setForeground(QColor("#00cc00")) # Green for included audio audio_item.setForeground(QColor("#00cc00")) # Green for included audio
# Set item for correct column based on mode # Set item for correct column based on mode
audio_column_index = 4 if is_playlist_mode else 6 audio_column_index = 5 if is_playlist_mode else 6
self.format_table.setItem(row, audio_column_index, audio_item) self.format_table.setItem(row, audio_column_index, audio_item)
# --- Populate columns only shown in non-playlist mode --- # --- Populate columns only shown in non-playlist mode ---
@@ -374,6 +396,24 @@ class FormatTableMixin:
else: else:
fps_item.setForeground(QColor("#888888")) # Gray for N/A fps_item.setForeground(QColor("#888888")) # Gray for N/A
self.format_table.setItem(row, 7, fps_item) self.format_table.setItem(row, 7, fps_item)
# Column 8: HDR (Dynamic Range)
if f.get("vcodec") == "none":
# Audio-only formats don't have HDR
hdr_text = "N/A"
hdr_item = QTableWidgetItem(hdr_text)
hdr_item.setForeground(QColor("#888888")) # Gray for N/A
else:
hdr_value = f.get("dynamic_range")
if hdr_value and hdr_value != "SDR":
hdr_text = hdr_value
hdr_item = QTableWidgetItem(hdr_text)
hdr_item.setForeground(QColor("#00ffff")) # Cyan for HDR
else:
hdr_text = "SDR"
hdr_item = QTableWidgetItem(hdr_text)
hdr_item.setForeground(QColor("#888888")) # Gray for SDR
self.format_table.setItem(row, 8, hdr_item)
def handle_checkbox_click(self, clicked_checkbox) -> None: def handle_checkbox_click(self, clicked_checkbox) -> None:
self = cast("YTSageApp", self) # for autocompletion and type inference. self = cast("YTSageApp", self) # for autocompletion and type inference.