You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
ffx/bin/ffx/show_details_screen.py

253 lines
8.1 KiB
Python

import click
from textual import events
from textual.app import App, ComposeResult
from textual.screen import Screen
from textual.widgets import Header, Footer, Placeholder, Label, ListView, ListItem, Static, DataTable, Button, Input
from textual.containers import Grid, Horizontal
from ffx.model.show import Show
from ffx.model.pattern import Pattern
from .pattern_details_screen import PatternDetailsScreen
from .pattern_delete_screen import PatternDeleteScreen
from .show_controller import ShowController
from .pattern_controller import PatternController
# Screen[dict[int, str, int]]
class ShowDetailsScreen(Screen):
CSS = """
Grid {
grid-size: 2;
grid-rows: 2 auto;
grid-columns: 30 330;
height: 100%;
width: 100%;
padding: 1;
}
Input {
border: none;
}
Button {
border: none;
}
DataTable {
column-span: 2;
min-height: 5;
}
#toplabel {
height: 1;
}
.two {
column-span: 2;
}
.box {
height: 100%;
border: solid green;
}
"""
BINDINGS = [
#("e", "edit_show", "Edit Show"),
("a", "add_pattern", "Add Pattern"),
("r", "remove_pattern", "Remove Pattern"),
]
def __init__(self, showId = None):
super().__init__()
self.context = self.app.getContext()
self.Session = self.context['database_session'] # convenience
self.__sc = ShowController(context = self.context)
self.__pc = PatternController(context = self.context)
self.show_obj = self.__sc.getShowDesciptor(showId) if showId is not None else {}
def loadPatterns(self, show_id):
try:
s = self.Session()
q = s.query(Pattern).filter(Pattern.show_id == int(show_id))
return [{'id': int(p.id), 'pattern': p.pattern} for p in q.all()]
except Exception as ex:
click.ClickException(f"loadPatterns(): {repr(ex)}")
finally:
s.close()
def on_mount(self):
if self.show_obj:
self.query_one("#id_wdg", Static).update(str(self.show_obj['id']))
self.query_one("#name_input", Input).value = str(self.show_obj['name'])
self.query_one("#year_input", Input).value = str(self.show_obj['year'])
self.query_one("#index_season_digits_input", Input).value = str(self.show_obj['index_season_digits'])
self.query_one("#index_episode_digits_input", Input).value = str(self.show_obj['index_episode_digits'])
self.query_one("#indicator_season_digits_input", Input).value = str(self.show_obj['indicator_season_digits'])
self.query_one("#indicator_episode_digits_input", Input).value = str(self.show_obj['indicator_episode_digits'])
for pattern in self.loadPatterns(int(self.show_obj['id'])):
row = (pattern['pattern'],)
self.patternTable.add_row(*map(str, row))
else:
self.query_one("#index_season_digits_input", Input).value = "2"
self.query_one("#index_episode_digits_input", Input).value = "2"
self.query_one("#indicator_season_digits_input", Input).value = "2"
self.query_one("#indicator_episode_digits_input", Input).value = "2"
def getSelectedPattern(self):
# Fetch the currently selected row when 'Enter' is pressed
#selected_row_index = self.table.cursor_row
row_key, col_key = self.patternTable.coordinate_to_cell_key(self.patternTable.cursor_coordinate)
selectedPattern = {}
if row_key is not None:
selected_row_data = self.patternTable.get_row(row_key)
selectedPattern['pattern'] = str(selected_row_data[0])
#selectedPattern['pattern'] = selected_row_data[1]
return selectedPattern
def action_add_pattern(self):
if self.show_obj:
self.app.push_screen(PatternDetailsScreen(showId = self.show_obj['id']), self.handle_add_pattern)
def handle_add_pattern(self, screenResult):
pattern = (screenResult['pattern'],)
self.patternTable.add_row(*map(str, pattern))
def action_remove_pattern(self):
selectedPattern = self.getSelectedPattern()
if selectedPattern:
selectedPatternId = self.__pc.findPattern(self.show_obj['id'], selectedPattern['pattern'])
if selectedPatternId is None:
raise click.ClickException(f"ShowDetailsScreen.action_remove_pattern(): Pattern to remove has no id")
self.app.push_screen(PatternDeleteScreen(patternId = selectedPatternId, showId = self.show_obj['id']), self.handle_remove_pattern)
def handle_remove_pattern(self, screenResult):
row_key, col_key = self.patternTable.coordinate_to_cell_key(self.patternTable.cursor_coordinate)
self.patternTable.remove_row(row_key)
def compose(self):
# Create the DataTable widget
self.patternTable = DataTable(classes="two")
# Define the columns with headers
self.column_key_id = self.patternTable.add_column("Patterns", width=60)
#self.column_key_name = self.patternTable.add_column("Name", width=50)
#self.column_key_year = self.patternTable.add_column("Year", width=10)
self.patternTable.cursor_type = 'row'
yield Header()
with Grid():
yield Static("Show" if self.show_obj else "New Show", id="toplabel", classes="two")
yield Static("ID")
if self.show_obj:
yield Static("", id="id_wdg")
else:
yield Input(type="integer", id="id_wdg")
yield Static("Name")
yield Input(type="text", id="name_input")
yield Static("Year")
yield Input(type="integer", id="year_input")
yield Static(" ", classes="two")
yield Static("Index Season Digits")
yield Input(type="integer", id="index_season_digits_input")
yield Static("Index Episode Digits")
yield Input(type="integer", id="index_episode_digits_input")
yield Static("Indicator Season Digits")
yield Input(type="integer", id="indicator_season_digits_input")
yield Static("Indicator Edisode Digits")
yield Input(type="integer", id="indicator_episode_digits_input")
yield Static(" ", classes="two")
yield self.patternTable
yield Static(" ", classes="two")
yield Button("Save", id="save_button")
yield Button("Cancel", id="cancel_button")
yield Footer()
def getShowDescriptorFromInput(self):
showDescriptor = {}
if self.show_obj:
showDescriptor['id'] = int(self.show_obj['id'])
else:
showDescriptor['id'] = int(self.query_one("#id_wdg", Input).value)
showDescriptor['name'] = str(self.query_one("#name_input", Input).value)
showDescriptor['year'] = int(self.query_one("#year_input", Input).value)
showDescriptor['index_season_digits'] = int(self.query_one("#index_season_digits_input", Input).value)
showDescriptor['index_episode_digits'] = int(self.query_one("#index_episode_digits_input", Input).value)
showDescriptor['indicator_season_digits'] = int(self.query_one("#indicator_season_digits_input", Input).value)
showDescriptor['indicator_episode_digits'] = int(self.query_one("#indicator_episode_digits_input", Input).value)
return showDescriptor
# Event handler for button press
def on_button_pressed(self, event: Button.Pressed) -> None:
# Check if the button pressed is the one we are interested in
if event.button.id == "save_button":
showDescriptor = self.getShowDescriptorFromInput()
if self.__sc.updateShow(showDescriptor):
self.dismiss(showDescriptor)
else:
#TODO: Meldung
self.app.pop_screen()
if event.button.id == "cancel_button":
self.app.pop_screen()