from textual.app import App, ComposeResult from textual.widgets import Header, Footer, DataTable from textual.coordinate import Coordinate class HamsterToolsApp(App): """A Textual app to manage stopwatches.""" BINDINGS = [ ("q", "quit", "Quit"), ("s", "sort", "Sort"), ("r", "refresh", "Refresh"), ("d", "delete_activity", "Delete activity"), ] def __init__(self, db_cursor, db_connection): self.db_cursor = db_cursor self.db_connection = db_connection super().__init__() def _refresh(self): self.table.clear() sql = ''' SELECT categories.id AS category_id, COALESCE(categories.name, '') AS category_name, activities.id AS activity_id, activities.name AS activity_name, COALESCE(facts_count, 0) AS total_facts FROM activities LEFT JOIN categories ON activities.category_id = categories.id LEFT JOIN ( SELECT activity_id, COUNT(*) AS facts_count FROM facts GROUP BY activity_id ) AS facts_count_subquery ON activities.id = facts_count_subquery.activity_id; ''' results = self.db_cursor.execute(sql) # results = [[cell or "" for cell in row] for row in self.db_cursor.fetchall()] self.table.add_rows(results) self.table.sort(self.columns[1], self.columns[3]) def compose(self) -> ComposeResult: """Create child widgets for the app.""" yield Header() yield DataTable() yield Footer() def on_mount(self) -> None: self.table = self.query_one(DataTable) self.table.cursor_type = "row" self.columns = self.table.add_columns("category id","category","activity ID","activity","entries") self._refresh() def action_quit(self) -> None: self.exit() def action_refresh(self) -> None: self._refresh() def action_sort(self) -> None: self.table.cursor_type = "column" def action_delete_activity(self) -> None: # Get the keys for the row and column under the cursor. row_key, _ = self.table.coordinate_to_cell_key(self.table.cursor_coordinate) activity_id = self.table.get_cell_at( Coordinate(self.table.cursor_coordinate.row, 2), ) sql = 'DELETE FROM activities WHERE id = ?' print(Coordinate(2, self.table.cursor_coordinate.row),) print(activity_id) self.db_cursor.execute(sql, (activity_id,)) self.db_connection.commit() # Supply the row key to `remove_row` to delete the row. self.table.remove_row(row_key) def on_data_table_column_selected(self, event): event.data_table.sort(event.column_key) event.data_table.cursor_type = "row"