diff --git a/src/ffx/pattern_details_screen.py b/src/ffx/pattern_details_screen.py index b5a7f07..7d4f539 100644 --- a/src/ffx/pattern_details_screen.py +++ b/src/ffx/pattern_details_screen.py @@ -9,7 +9,6 @@ from textual.containers import Grid from ffx.model.pattern import Pattern from .track_details_screen import TrackDetailsScreen -from .track_delete_screen import TrackDeleteScreen from .shifted_season_delete_screen import ShiftedSeasonDeleteScreen from .shifted_season_details_screen import ShiftedSeasonDetailsScreen @@ -483,7 +482,7 @@ class PatternDetailsScreen(Screen): yield Static(t("Streams")) yield Button(t("Add"), id="button_add_track") yield Button(t("Edit"), id="button_edit_track") - yield Button(t("Delete"), id="button_delete_track") + yield Button(t("Drop / Undrop"), id="button_toggle_track_drop") yield Static(" ") yield Button(t("Up"), id="button_track_up") @@ -665,11 +664,8 @@ class PatternDetailsScreen(Screen): ), self.handle_edit_track, ) - if event.button.id == "button_delete_track": - self.app.push_screen( - TrackDeleteScreen(trackDescriptor = selectedTrack), - self.handle_delete_track, - ) + if event.button.id == "button_toggle_track_drop": + self.toggleSelectedTrackDropped(selectedTrack) if event.button.id == "button_add_tag": @@ -753,6 +749,27 @@ class PatternDetailsScreen(Screen): self.updateTracks() + def toggleSelectedTrackDropped(self, trackDescriptor: TrackDescriptor): + if trackDescriptor is None: + return + + updatedTrack = trackDescriptor.clone(context=self.context) + updatedTrack.setDropped(not trackDescriptor.isDropped()) + + if self.__pattern is not None: + if not self.__tc.updateTrack(updatedTrack.getId(), updatedTrack): + raise click.ClickException("PatternDetailsScreen.toggleSelectedTrackDropped(): track update failed") + else: + for currentTrack in self.__draftTracks: + if ( + currentTrack.getIndex() == trackDescriptor.getIndex() + and currentTrack.getSubIndex() == trackDescriptor.getSubIndex() + ): + currentTrack.setDropped(updatedTrack.isDropped()) + break + + self.updateTracks() + def handle_delete_track(self, trackDescriptor : TrackDescriptor): if trackDescriptor is None: diff --git a/src/ffx/track_details_screen.py b/src/ffx/track_details_screen.py index ac6b18a..167f1c8 100644 --- a/src/ffx/track_details_screen.py +++ b/src/ffx/track_details_screen.py @@ -257,11 +257,7 @@ class TrackDetailsScreen(Screen): self.query_one("#audio_layout_select", Select).value = self.__audioLayout - # CB self.query_one("#drop_checkbox", Checkbox).value = self.__dropped - # self.query_one("#drop_checkbox", SelectionList).add_option( - # (t("Yes"), 0, self.__dropped) - # ) for disposition in TrackDisposition: @@ -292,9 +288,7 @@ class TrackDetailsScreen(Screen): self.query_one("#type_select", Select).disabled = True self.query_one("#audio_layout_select", Select).disabled = True - # CB self.query_one("#drop_checkbox", Checkbox).disabled = True - # self.query_one("#drop_checkbox", SelectionList).disabled = True def on_select_changed(self, event: Select.Changed) -> None: if event.select.id == "language_select": @@ -358,9 +352,7 @@ class TrackDetailsScreen(Screen): # Row 8 yield Static(t("Drop")) - # CB yield Checkbox(id="drop_checkbox", classes="four") - # yield SelectionList[int](id="drop_checkbox", classes="four") # Row 9 yield Static(" ", classes="five") @@ -479,7 +471,7 @@ class TrackDetailsScreen(Screen): kwargs[TrackDescriptor.TAGS_KEY] = trackTags kwargs[TrackDescriptor.DROPPED_KEY] = bool( - self.query_one("#drop_checkbox", SelectionList).selected + self.query_one("#drop_checkbox", Checkbox).value ) dispositionFlags = sum( diff --git a/tests/unit/test_tag_table_screen_state.py b/tests/unit/test_tag_table_screen_state.py index 4d37a61..961f746 100644 --- a/tests/unit/test_tag_table_screen_state.py +++ b/tests/unit/test_tag_table_screen_state.py @@ -190,7 +190,7 @@ class TagTableScreenStateTests(unittest.TestCase): widgets = { "#type_select": FakeValueWidget(TrackType.AUDIO), "#audio_layout_select": FakeValueWidget(AudioLayout.LAYOUT_STEREO), - "#drop_checkbox": FakeSelectionListWidget({0}), + "#drop_checkbox": FakeValueWidget(True), "#language_select": FakeValueWidget(IsoLanguage.GERMAN), "#title_input": FakeInputWidget("German Audio"), "#dispositions_selection_list": FakeSelectionListWidget({0, 6}), @@ -220,7 +220,7 @@ class TagTableScreenStateTests(unittest.TestCase): widgets = { "#type_select": FakeValueWidget(TrackType.ATTACHMENT), "#audio_layout_select": FakeValueWidget(AudioLayout.LAYOUT_UNDEFINED), - "#drop_checkbox": FakeSelectionListWidget(set()), + "#drop_checkbox": FakeValueWidget(False), "#language_select": FakeValueWidget(Select.NULL), "#title_input": FakeInputWidget(""), "#dispositions_selection_list": FakeSelectionListWidget(set()), @@ -329,7 +329,7 @@ class TagTableScreenStateTests(unittest.TestCase): "#pattern_label": FakeStaticWidget(), "#type_select": FakeValueWidget(None), "#audio_layout_select": FakeValueWidget(None), - "#drop_checkbox": FakeSelectionListWidget(set()), + "#drop_checkbox": FakeValueWidget(False), "#dispositions_selection_list": FakeSelectionListWidget(set()), "#language_select": FakeValueWidget(None), "#title_input": FakeInputWidget(""), @@ -376,6 +376,65 @@ class TagTableScreenStateTests(unittest.TestCase): self.assertIs(second_track, screen.getSelectedTrackDescriptor()) self.assertEqual("Ja", screen.tracksTable.rows["row-1"][9]) + def test_pattern_details_screen_toggles_draft_track_drop_state(self): + first_track = make_track_descriptor(0, 0, TrackType.VIDEO) + second_track = make_track_descriptor(1, 0, TrackType.SUBTITLE) + + screen = object.__new__(PatternDetailsScreen) + screen.context = {"logger": get_ffx_logger()} + screen.tracksTable = FakeTagTable() + screen._PatternDetailsScreen__draftTracks = [first_track, second_track] + screen._PatternDetailsScreen__pattern = None + screen._PatternDetailsScreen__trackRowData = {} + + screen.updateTracks() + screen.tracksTable.select_row("row-1") + + screen.toggleSelectedTrackDropped(screen.getSelectedTrackDescriptor()) + + self.assertFalse(first_track.isDropped()) + self.assertTrue(second_track.isDropped()) + self.assertEqual("Ja", list(screen.tracksTable.rows.values())[1][9]) + + def test_pattern_details_screen_toggles_persisted_track_drop_state(self): + class _FakePattern: + def getId(self): + return 5 + + class _FakeTrackController: + def __init__(self): + self.updated = [] + + def updateTrack(self, track_id, track_descriptor): + self.updated.append((track_id, track_descriptor)) + return True + + track = TrackDescriptor( + id=17, + pattern_id=5, + index=1, + source_index=1, + sub_index=0, + track_type=TrackType.SUBTITLE, + codec_name=TrackCodec.UNKNOWN, + dropped=False, + ) + track_controller = _FakeTrackController() + + screen = object.__new__(PatternDetailsScreen) + screen.context = {"logger": get_ffx_logger()} + screen._PatternDetailsScreen__pattern = _FakePattern() + screen._PatternDetailsScreen__tc = track_controller + screen.updateTracks = lambda: None + + screen.toggleSelectedTrackDropped(track) + + self.assertEqual(1, len(track_controller.updated)) + track_id, updated_track = track_controller.updated[0] + self.assertEqual(17, track_id) + self.assertFalse(track.isDropped()) + self.assertTrue(updated_track.isDropped()) + def test_pattern_details_screen_reads_selected_tag_from_raw_row_mapping(self): screen = object.__new__(PatternDetailsScreen) screen.tagsTable = FakeTagTable()