Compare commits

..

5 Commits

Author SHA1 Message Date
Keith Edmunds
af6e0f69be Speed up changing to tab with lots of tracks
Fixes: #219
2024-01-19 10:16:28 +00:00
Keith Edmunds
2ecb67629e Don't exit if Audacity not running
Handle Audacity integration better

Fixes: #215
2024-01-19 10:12:41 +00:00
Keith Edmunds
4fce750223 Refactor / simplify start/stop times
Fixes #218
2024-01-19 09:58:52 +00:00
Keith Edmunds
fcbdfc65ac Resize rows after hiding/showing played
Fixes #216
2024-01-19 09:57:25 +00:00
Keith Edmunds
c5dd913b98 Resize rows on show/hide played 2024-01-18 22:59:02 +00:00
3 changed files with 61 additions and 54 deletions

View File

@ -227,8 +227,11 @@ class Window(QMainWindow, Ui_MainWindow):
self.move_source_model: Optional[PlaylistProxyModel] = None self.move_source_model: Optional[PlaylistProxyModel] = None
self.audacity_file_path: Optional[str] = None self.audacity_file_path: Optional[str] = None
# Initialise Audacity access # Initialise Audacity access
self.audacity_client = pipeclient.PipeClient() try:
log.info(f"{hex(id(self.audacity_client))=}") self.audacity_client = pipeclient.PipeClient()
log.info(f"{hex(id(self.audacity_client))=}")
except RuntimeError as e:
log.error(f"Unable to initialise Audacity: {str(e)}")
if Config.CARTS_HIDE: if Config.CARTS_HIDE:
self.cartsWidget.hide() self.cartsWidget.hide()
@ -786,6 +789,8 @@ class Window(QMainWindow, Ui_MainWindow):
self.hide_played_tracks = True self.hide_played_tracks = True
self.active_proxy_model().hide_played_tracks(True) self.active_proxy_model().hide_played_tracks(True)
self.btnHidePlayed.setText("Show played") self.btnHidePlayed.setText("Show played")
# Reset row heights
self.active_tab().resizeRowsToContents()
def import_track(self) -> None: def import_track(self) -> None:
"""Import track file""" """Import track file"""
@ -1122,20 +1127,20 @@ class Window(QMainWindow, Ui_MainWindow):
if not track_sequence.now.path: if not track_sequence.now.path:
log.error("No path for next track") log.error("No path for next track")
return return
self.music.play(track_sequence.now.path, position)
# Notify model # Note that track is playing
self.active_proxy_model().current_track_started() track_sequence.now.start()
# Note that track is now playing
self.playing = True self.playing = True
# Disable play next controls # Disable play next controls
self.disable_play_next_controls() self.disable_play_next_controls()
# Notify model
self.active_proxy_model().current_track_started()
# Update headers # Update headers
self.update_headers() self.update_headers()
track_sequence.now.start()
self.music.play(track_sequence.now.path, position)
# Ensure 100% volume # Ensure 100% volume
# For as-yet unknown reasons. sometimes the volume gets # For as-yet unknown reasons. sometimes the volume gets
@ -1488,7 +1493,7 @@ class Window(QMainWindow, Ui_MainWindow):
tab = self.active_tab() tab = self.active_tab()
if tab: if tab:
tab.resizeRowsToContents() QTimer.singleShot(300, tab.resizeRowsToContents)
def tick_10ms(self) -> None: def tick_10ms(self) -> None:
""" """

View File

@ -81,7 +81,7 @@ import argparse
if sys.version_info[0] < 3: if sys.version_info[0] < 3:
sys.exit('PipeClient Error: Python 3.x required') raise RuntimeError('PipeClient Error: Python 3.x required')
# Platform specific constants # Platform specific constants
if sys.platform == 'win32': if sys.platform == 'win32':
@ -156,7 +156,7 @@ class PipeClient():
# Allow a little time for connection to be made. # Allow a little time for connection to be made.
time.sleep(0.1) time.sleep(0.1)
if not self._write_pipe: if not self._write_pipe:
sys.exit('PipeClientError: Write pipe cannot be opened.') raise RuntimeError('PipeClientError: Write pipe cannot be opened.')
def _write_pipe_open(self) -> None: def _write_pipe_open(self) -> None:
"""Open _write_pipe.""" """Open _write_pipe."""
@ -187,7 +187,7 @@ class PipeClient():
self._write_pipe.write(command + EOL) self._write_pipe.write(command + EOL)
# Check that read pipe is alive # Check that read pipe is alive
if PipeClient.reader_pipe_broken.is_set(): if PipeClient.reader_pipe_broken.is_set():
sys.exit('PipeClient: Read-pipe error.') raise RuntimeError('PipeClient: Read-pipe error.')
try: try:
self._write_pipe.flush() self._write_pipe.flush()
if self.timer: if self.timer:
@ -196,7 +196,7 @@ class PipeClient():
PipeClient.reply_ready.clear() PipeClient.reply_ready.clear()
except IOError as err: except IOError as err:
if err.errno == errno.EPIPE: if err.errno == errno.EPIPE:
sys.exit('PipeClient: Write-pipe error.') raise RuntimeError('PipeClient: Write-pipe error.')
else: else:
raise raise

View File

@ -68,6 +68,8 @@ class PlaylistRowData:
self.played = False self.played = False
self.start_gap: Optional[int] = None self.start_gap: Optional[int] = None
self.title: str = "" self.title: str = ""
self.start_time: Optional[datetime] = None
self.end_time: Optional[datetime] = None
self.plrid: int = plr.id self.plrid: int = plr.id
self.plr_rownum: int = plr.plr_rownum self.plr_rownum: int = plr.plr_rownum
@ -93,12 +95,6 @@ class PlaylistRowData:
) )
@dataclass
class StartEndTimes:
start_time: Optional[datetime] = None
end_time: Optional[datetime] = None
class PlaylistModel(QAbstractTableModel): class PlaylistModel(QAbstractTableModel):
""" """
The Playlist Model The Playlist Model
@ -127,7 +123,6 @@ class PlaylistModel(QAbstractTableModel):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
self.playlist_rows: dict[int, PlaylistRowData] = {} self.playlist_rows: dict[int, PlaylistRowData] = {}
self.start_end_times: dict[int, StartEndTimes] = {}
self.signals = MusicMusterSignals() self.signals = MusicMusterSignals()
self.played_tracks_hidden = False self.played_tracks_hidden = False
@ -259,6 +254,7 @@ class PlaylistModel(QAbstractTableModel):
""" """
row_number = track_sequence.now.plr_rownum row_number = track_sequence.now.plr_rownum
prd = self.playlist_rows[row_number]
# Sanity check # Sanity check
if not track_sequence.now.track_id: if not track_sequence.now.track_id:
@ -289,8 +285,8 @@ class PlaylistModel(QAbstractTableModel):
log.error(f"Can't retrieve plr, {track_sequence.now.plr_id=}") log.error(f"Can't retrieve plr, {track_sequence.now.plr_id=}")
# Update track times # Update track times
self.start_end_times[row_number].start_time = track_sequence.now.start_time prd.start_time = track_sequence.now.start_time
self.start_end_times[row_number].end_time = track_sequence.now.end_time prd.end_time = track_sequence.now.end_time
# Update colour and times for current row # Update colour and times for current row
self.invalidate_row(row_number) self.invalidate_row(row_number)
@ -408,17 +404,15 @@ class PlaylistModel(QAbstractTableModel):
return QVariant() return QVariant()
if column == Col.START_TIME.value: if column == Col.START_TIME.value:
if row in self.start_end_times: start_time = prd.start_time
start_time = self.start_end_times[row].start_time if start_time:
if start_time: return QVariant(start_time.strftime(Config.TRACK_TIME_FORMAT))
return QVariant(start_time.strftime(Config.TRACK_TIME_FORMAT))
return QVariant() return QVariant()
if column == Col.END_TIME.value: if column == Col.END_TIME.value:
if row in self.start_end_times: end_time = prd.end_time
end_time = self.start_end_times[row].end_time if end_time:
if end_time: return QVariant(end_time.strftime(Config.TRACK_TIME_FORMAT))
return QVariant(end_time.strftime(Config.TRACK_TIME_FORMAT))
return QVariant() return QVariant()
dispatch_table = { dispatch_table = {
@ -1327,15 +1321,15 @@ class PlaylistModel(QAbstractTableModel):
update_rows: List[int] = [] update_rows: List[int] = []
for row_number in range(len(self.playlist_rows)): for row_number in range(len(self.playlist_rows)):
stend = self.start_end_times[row_number] = StartEndTimes()
prd = self.playlist_rows[row_number] prd = self.playlist_rows[row_number]
# Reset start_time if this is the current row # Reset start_time if this is the current row
if row_number == track_sequence.now.plr_rownum: if row_number == track_sequence.now.plr_rownum:
stend.start_time = track_sequence.now.start_time prd.start_time = track_sequence.now.start_time
stend.end_time = track_sequence.now.end_time prd.end_time = track_sequence.now.end_time
update_rows.append(row_number)
if not next_start_time: if not next_start_time:
next_start_time = stend.end_time next_start_time = prd.end_time
continue continue
# Set start time for next row if we have a current track # Set start time for next row if we have a current track
@ -1343,9 +1337,9 @@ class PlaylistModel(QAbstractTableModel):
row_number == track_sequence.next.plr_rownum row_number == track_sequence.next.plr_rownum
and track_sequence.now.end_time and track_sequence.now.end_time
): ):
stend.start_time = track_sequence.now.end_time prd.start_time = track_sequence.now.end_time
stend.end_time = stend.start_time + timedelta(milliseconds=prd.duration) prd.end_time = prd.start_time + timedelta(milliseconds=prd.duration)
next_start_time = stend.end_time next_start_time = prd.end_time
update_rows.append(row_number) update_rows.append(row_number)
continue continue
@ -1362,31 +1356,39 @@ class PlaylistModel(QAbstractTableModel):
< row_number < row_number
< track_sequence.next.plr_rownum < track_sequence.next.plr_rownum
): ):
prd.start_time = None
prd.end_time = None
update_rows.append(row_number) update_rows.append(row_number)
continue continue
# Reset start time if timing in header or at current track # Reset start time if timing in header
if self.is_header_row(row_number): if self.is_header_row(row_number):
header_time = get_embedded_time(prd.note) header_time = get_embedded_time(prd.note)
if header_time: if header_time:
next_start_time = header_time next_start_time = header_time
else: continue
# This is an unplayed track
# Don't schedule unplayable tracks
if file_is_unreadable(prd.path):
continue
# Set start/end if we have a start time # This is an unplayed track
if next_start_time is None: # Don't schedule unplayable tracks
continue if file_is_unreadable(prd.path):
if stend.start_time != next_start_time: continue
stend.start_time = next_start_time
update_rows.append(row_number) # Set start/end if we have a start time
next_start_time += timedelta( if next_start_time is None:
milliseconds=self.playlist_rows[row_number].duration continue
)
if stend.end_time != next_start_time: # Update start time of this row if it's incorrect
stend.end_time = next_start_time if prd.start_time != next_start_time:
prd.start_time = next_start_time
update_rows.append(row_number)
# Calculate next start time
next_start_time += timedelta(milliseconds=prd.duration)
# Update end time of this row if it's incorrect
if prd.end_time != next_start_time:
prd.end_time = next_start_time
if row_number not in update_rows:
update_rows.append(row_number) update_rows.append(row_number)
# Update start/stop times of rows that have changed # Update start/stop times of rows that have changed