|
|
@ -12,6 +12,7 @@ from ffx.model.pattern import Pattern
|
|
|
|
|
|
|
|
|
|
|
|
from .track_controller import TrackController
|
|
|
|
from .track_controller import TrackController
|
|
|
|
from .pattern_controller import PatternController
|
|
|
|
from .pattern_controller import PatternController
|
|
|
|
|
|
|
|
from .tag_controller import TagController
|
|
|
|
# from .show_controller import ShowController
|
|
|
|
# from .show_controller import ShowController
|
|
|
|
|
|
|
|
|
|
|
|
from .track_type import TrackType
|
|
|
|
from .track_type import TrackType
|
|
|
@ -23,76 +24,11 @@ from .audio_layout import AudioLayout
|
|
|
|
from .track_descriptor import TrackDescriptor
|
|
|
|
from .track_descriptor import TrackDescriptor
|
|
|
|
|
|
|
|
|
|
|
|
from .tag_details_screen import TagDetailsScreen
|
|
|
|
from .tag_details_screen import TagDetailsScreen
|
|
|
|
|
|
|
|
from .tag_delete_screen import TagDeleteScreen
|
|
|
|
|
|
|
|
|
|
|
|
from textual.widgets._data_table import CellDoesNotExist
|
|
|
|
from textual.widgets._data_table import CellDoesNotExist
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class EditableDataTable(DataTable):
|
|
|
|
|
|
|
|
"""Custom DataTable that allows editing cells upon mouse click."""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def on_click(self, event: events.Click) -> None:
|
|
|
|
|
|
|
|
"""Handle mouse clicks on the table."""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# raise click.ClickException(f"event={event}")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#event.x und event.y sind koordinaten im Datatable
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#clicked_cell = self.coordinate_to_cell_key(self.cursor_coordinate)
|
|
|
|
|
|
|
|
#raise click.ClickException(f"x={event.x} y={event.y} clicked_cell={clicked_cell}")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#raise click.ClickException(f"cuco={self.cursor_coordinate}")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#clickCoordinates = Coordinate(row = event.y, column=event.x)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#clicked_cell = self.get_cell_at(event.x, event.y)
|
|
|
|
|
|
|
|
#row_key, col_key = self.coordinate_to_cell_key(self.cursor_coordinate)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#raise click.ClickException(f"x={event.x} y={event.y} row={row_key} col={col_key}")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#if clicked_cell:
|
|
|
|
|
|
|
|
# if row_key is not None and col_key is not None:
|
|
|
|
|
|
|
|
#row, column = clicked_cell
|
|
|
|
|
|
|
|
# Get the current cell value and activate editing.
|
|
|
|
|
|
|
|
#current_value = self.get_cell(row_key, col_key)
|
|
|
|
|
|
|
|
current_value = self.get_cell_at(self.cursor_coordinate)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
region = self._get_cell_region(self.cursor_coordinate)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
raise click.ClickException(f"region={region}")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#current_value = self.get_cell(row_key, col_key)
|
|
|
|
|
|
|
|
#self.activate_cell_edit(row_key, col_key, current_value)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
raise click.ClickException(f"val={current_value}")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def activate_cell_edit(self, row: int, column: int, value: str) -> None:
|
|
|
|
|
|
|
|
# """Method to activate cell editing."""
|
|
|
|
|
|
|
|
# # Create a new input box with the value of the cell to be edited.
|
|
|
|
|
|
|
|
input_box = Input(value=value, classes="cell-editor")
|
|
|
|
|
|
|
|
input_box.styles.width = len(value) + 2 # Adjust the width of the input box
|
|
|
|
|
|
|
|
input_box.styles.padding = (0, 1)
|
|
|
|
|
|
|
|
#
|
|
|
|
|
|
|
|
# # Position the input box over the cell to be edited.
|
|
|
|
|
|
|
|
input_box.styles.position = "absolute"
|
|
|
|
|
|
|
|
input_box.styles.left = self.get_cell_position(row, column)[0]
|
|
|
|
|
|
|
|
input_box.styles.top = self.get_cell_position(row, column)[1]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# # Add the input box to the parent widget for editing.
|
|
|
|
|
|
|
|
# self.app.mount(input_box)
|
|
|
|
|
|
|
|
# input_box.focus()
|
|
|
|
|
|
|
|
#
|
|
|
|
|
|
|
|
# # Listen to when the user completes editing.
|
|
|
|
|
|
|
|
# input_box.on_blur = lambda event: self.save_cell_value(row, column, input_box.value)
|
|
|
|
|
|
|
|
#
|
|
|
|
|
|
|
|
# def save_cell_value(self, row: int, column: int, value: str) -> None:
|
|
|
|
|
|
|
|
# """Save the new value to the table and remove the input box."""
|
|
|
|
|
|
|
|
# self.update_cell(row, column, value)
|
|
|
|
|
|
|
|
# self.app.query_one(".cell-editor").remove() # Remove the input box after saving.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Screen[dict[int, str, int]]
|
|
|
|
# Screen[dict[int, str, int]]
|
|
|
|
class TrackDetailsScreen(Screen):
|
|
|
|
class TrackDetailsScreen(Screen):
|
|
|
|
|
|
|
|
|
|
|
@ -156,18 +92,37 @@ class TrackDetailsScreen(Screen):
|
|
|
|
|
|
|
|
|
|
|
|
self.__tc = TrackController(context = self.context)
|
|
|
|
self.__tc = TrackController(context = self.context)
|
|
|
|
self.__pc = PatternController(context = self.context)
|
|
|
|
self.__pc = PatternController(context = self.context)
|
|
|
|
|
|
|
|
self.__tac = TagController(context = self.context)
|
|
|
|
|
|
|
|
|
|
|
|
self.__isNew = trackDescriptor is None
|
|
|
|
self.__isNew = trackDescriptor is None
|
|
|
|
if self.__isNew:
|
|
|
|
if self.__isNew:
|
|
|
|
self.__trackType = trackType
|
|
|
|
self.__trackType = trackType
|
|
|
|
self.__subIndex = subIndex
|
|
|
|
self.__subIndex = subIndex
|
|
|
|
self.__trackDescriptor = None
|
|
|
|
self.__trackDescriptor : TrackDescriptor = None
|
|
|
|
self.__pattern = self.__pc.getPattern(patternId) if patternId is not None else {}
|
|
|
|
self.__pattern : Pattern = self.__pc.getPattern(patternId) if patternId is not None else {}
|
|
|
|
else:
|
|
|
|
else:
|
|
|
|
self.__trackType = trackDescriptor.getType()
|
|
|
|
self.__trackType = trackDescriptor.getType()
|
|
|
|
self.__subIndex = trackDescriptor.getSubIndex()
|
|
|
|
self.__subIndex = trackDescriptor.getSubIndex()
|
|
|
|
self.__trackDescriptor = trackDescriptor
|
|
|
|
self.__trackDescriptor : TrackDescriptor = trackDescriptor
|
|
|
|
self.__pattern = self.__pc.getPattern(self.__trackDescriptor.getPatternId())
|
|
|
|
self.__pattern : Pattern = self.__pc.getPattern(self.__trackDescriptor.getPatternId())
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def updateTags(self):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
self.trackTagsTable.clear()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
trackId = self.__trackDescriptor.getId()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if trackId != -1:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
trackTags = self.__tac.findAllTrackTags(trackId)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for k,v in trackTags.items():
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if k != 'language' and k != 'title':
|
|
|
|
|
|
|
|
row = (k,v)
|
|
|
|
|
|
|
|
self.trackTagsTable.add_row(*map(str, row))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def on_mount(self):
|
|
|
|
def on_mount(self):
|
|
|
@ -175,12 +130,9 @@ class TrackDetailsScreen(Screen):
|
|
|
|
if self.__pattern is not None:
|
|
|
|
if self.__pattern is not None:
|
|
|
|
self.query_one("#patternlabel", Static).update(self.__pattern.getPattern())
|
|
|
|
self.query_one("#patternlabel", Static).update(self.__pattern.getPattern())
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if self.__subIndex is not None:
|
|
|
|
if self.__subIndex is not None:
|
|
|
|
self.query_one("#subindexlabel", Static).update(str(self.__subIndex))
|
|
|
|
self.query_one("#subindexlabel", Static).update(str(self.__subIndex))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for d in TrackDisposition:
|
|
|
|
for d in TrackDisposition:
|
|
|
|
|
|
|
|
|
|
|
|
dispositionIsSet = (self.__trackDescriptor is not None
|
|
|
|
dispositionIsSet = (self.__trackDescriptor is not None
|
|
|
@ -193,11 +145,12 @@ class TrackDetailsScreen(Screen):
|
|
|
|
|
|
|
|
|
|
|
|
self.query_one("#language_select", Select).value = self.__trackDescriptor.getLanguage().label()
|
|
|
|
self.query_one("#language_select", Select).value = self.__trackDescriptor.getLanguage().label()
|
|
|
|
self.query_one("#title_input", Input).value = self.__trackDescriptor.getTitle()
|
|
|
|
self.query_one("#title_input", Input).value = self.__trackDescriptor.getTitle()
|
|
|
|
|
|
|
|
self.updateTags()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def compose(self):
|
|
|
|
def compose(self):
|
|
|
|
|
|
|
|
|
|
|
|
self.trackTagsTable = EditableDataTable(classes="five")
|
|
|
|
self.trackTagsTable = DataTable(classes="five")
|
|
|
|
|
|
|
|
|
|
|
|
# Define the columns with headers
|
|
|
|
# Define the columns with headers
|
|
|
|
self.column_key_track_tag_key = self.trackTagsTable.add_column("Key", width=10)
|
|
|
|
self.column_key_track_tag_key = self.trackTagsTable.add_column("Key", width=10)
|
|
|
@ -297,13 +250,15 @@ class TrackDetailsScreen(Screen):
|
|
|
|
|
|
|
|
|
|
|
|
trackTags = {}
|
|
|
|
trackTags = {}
|
|
|
|
language = self.query_one("#language_select", Select).value
|
|
|
|
language = self.query_one("#language_select", Select).value
|
|
|
|
# raise click.ClickException(f"language={language}")
|
|
|
|
|
|
|
|
if language:
|
|
|
|
if language:
|
|
|
|
trackTags['language'] = IsoLanguage.find(language).threeLetter()
|
|
|
|
trackTags['language'] = IsoLanguage.find(language).threeLetter()
|
|
|
|
title = self.query_one("#title_input", Input).value
|
|
|
|
title = self.query_one("#title_input", Input).value
|
|
|
|
if title:
|
|
|
|
if title:
|
|
|
|
trackTags['title'] = title
|
|
|
|
trackTags['title'] = title
|
|
|
|
kwargs[TrackDescriptor.TAGS_KEY] = trackTags
|
|
|
|
|
|
|
|
|
|
|
|
tableTags = {row[0]:row[1] for r in self.trackTagsTable.rows if (row := self.trackTagsTable.get_row(r)) and row[0] != 'language' and row[0] != 'title'}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
kwargs[TrackDescriptor.TAGS_KEY] = trackTags | tableTags
|
|
|
|
|
|
|
|
|
|
|
|
dispositionFlags = sum([2**f for f in self.query_one("#dispositions_selection_list", SelectionList).selected])
|
|
|
|
dispositionFlags = sum([2**f for f in self.query_one("#dispositions_selection_list", SelectionList).selected])
|
|
|
|
kwargs[TrackDescriptor.DISPOSITION_SET_KEY] = TrackDisposition.toSet(dispositionFlags)
|
|
|
|
kwargs[TrackDescriptor.DISPOSITION_SET_KEY] = TrackDisposition.toSet(dispositionFlags)
|
|
|
@ -346,6 +301,8 @@ class TrackDetailsScreen(Screen):
|
|
|
|
|
|
|
|
|
|
|
|
trackDescriptor = self.getTrackDescriptorFromInput()
|
|
|
|
trackDescriptor = self.getTrackDescriptorFromInput()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# raise click.ClickException(f"td.tags={trackDescriptor.getTags()}") # language=ger, title=Deutsch
|
|
|
|
|
|
|
|
|
|
|
|
# Check for multiple default/forced disposition flags
|
|
|
|
# Check for multiple default/forced disposition flags
|
|
|
|
|
|
|
|
|
|
|
|
if self.__trackType == TrackType.AUDIO:
|
|
|
|
if self.__trackType == TrackType.AUDIO:
|
|
|
@ -376,9 +333,9 @@ class TrackDetailsScreen(Screen):
|
|
|
|
|
|
|
|
|
|
|
|
else:
|
|
|
|
else:
|
|
|
|
|
|
|
|
|
|
|
|
trackId = self.__tc.findTrack(self.__pattern.getId(), self.__trackType, self.__subIndex)
|
|
|
|
track = self.__tc.findTrack(self.__pattern.getId(), self.__trackType, self.__subIndex)
|
|
|
|
|
|
|
|
|
|
|
|
if self.__tc.updateTrack(trackId, trackDescriptor):
|
|
|
|
if self.__tc.updateTrack(track.getId(), trackDescriptor):
|
|
|
|
self.dismiss(trackDescriptor)
|
|
|
|
self.dismiss(trackDescriptor)
|
|
|
|
|
|
|
|
|
|
|
|
else:
|
|
|
|
else:
|
|
|
@ -401,17 +358,23 @@ class TrackDetailsScreen(Screen):
|
|
|
|
self.app.push_screen(TagDetailsScreen(key=tagKey, value=tagValue), self.handle_add_tag)
|
|
|
|
self.app.push_screen(TagDetailsScreen(key=tagKey, value=tagValue), self.handle_add_tag)
|
|
|
|
|
|
|
|
|
|
|
|
if event.button.id == "button_delete_stream_tag":
|
|
|
|
if event.button.id == "button_delete_stream_tag":
|
|
|
|
pass
|
|
|
|
tagKey, tagValue = self.getSelectedTag()
|
|
|
|
|
|
|
|
self.app.push_screen(TagDeleteScreen(key=tagKey, value=tagValue), self.handle_delete_tag)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def handle_add_tag(self, tag):
|
|
|
|
def handle_add_tag(self, tag):
|
|
|
|
|
|
|
|
|
|
|
|
row = (tag[0], tag[1])
|
|
|
|
trackId = self.__trackDescriptor.getId()
|
|
|
|
self.trackTagsTable.add_row(*map(str, row))
|
|
|
|
|
|
|
|
|
|
|
|
if trackId == -1:
|
|
|
|
|
|
|
|
raise click.ClickException(f"TrackDetailsScreen.handle_add_tag: trackId not set (-1) trackDescriptor={self.__trackDescriptor}")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if self.__tac.updateTrackTag(trackId, tag[0], tag[1]) is not None:
|
|
|
|
|
|
|
|
self.updateTags()
|
|
|
|
|
|
|
|
|
|
|
|
def handle_edit_tag(self, trackDescriptor : TrackDescriptor):
|
|
|
|
|
|
|
|
|
|
|
|
def handle_edit_tag(self, tag):
|
|
|
|
pass
|
|
|
|
pass
|
|
|
|
# try:
|
|
|
|
# try:
|
|
|
|
# if trackDescriptor.getType() == TrackType.AUDIO:
|
|
|
|
# if trackDescriptor.getType() == TrackType.AUDIO:
|
|
|
@ -436,15 +399,16 @@ class TrackDetailsScreen(Screen):
|
|
|
|
# pass
|
|
|
|
# pass
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def handle_delete_tag(self, trackDescriptor : TrackDescriptor):
|
|
|
|
def handle_delete_tag(self, trackTag):
|
|
|
|
pass
|
|
|
|
|
|
|
|
# try:
|
|
|
|
trackId = self.__trackDescriptor.getId()
|
|
|
|
# if trackDescriptor.getType() == TrackType.AUDIO:
|
|
|
|
|
|
|
|
# self.updateAudioTracks()
|
|
|
|
if trackId == -1:
|
|
|
|
#
|
|
|
|
raise click.ClickException(f"TrackDetailsScreen.handle_delete_tag: trackId not set (-1) trackDescriptor={self.__trackDescriptor}")
|
|
|
|
# if trackDescriptor.getType() == TrackType.SUBTITLE:
|
|
|
|
|
|
|
|
# self.updateSubtitleTracks()
|
|
|
|
tag = self.__tac.findTrackTag(trackId, trackTag[0])
|
|
|
|
#
|
|
|
|
|
|
|
|
# except CellDoesNotExist:
|
|
|
|
|
|
|
|
# pass
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if tag is not None:
|
|
|
|
|
|
|
|
if self.__tac.deleteTrackTag(tag.id):
|
|
|
|
|
|
|
|
# raise click.ClickException('deleted!')
|
|
|
|
|
|
|
|
self.updateTags()
|
|
|
|