Compare commits

..

No commits in common. "ebdb0d0a82219d3c23f67a02ee35e402ea903a88" and "56fb1aeb3d115f7776b3753ea9c687553f6d4998" have entirely different histories.

4 changed files with 249 additions and 319 deletions

View File

@ -16,7 +16,7 @@ from PyQt5.QtWidgets import (
QFileDialog, QFileDialog,
QInputDialog, QInputDialog,
QLabel, QLabel,
QLineEdit, # QLineEdit,
QListWidgetItem, QListWidgetItem,
QMainWindow, QMainWindow,
# QMessageBox, # QMessageBox,
@ -77,9 +77,9 @@ class Window(QMainWindow, Ui_MainWindow):
self.set_main_window_size() self.set_main_window_size()
self.lblSumPlaytime = QLabel("") self.lblSumPlaytime = QLabel("")
self.statusbar.addPermanentWidget(self.lblSumPlaytime) self.statusbar.addPermanentWidget(self.lblSumPlaytime)
self.txtSearch = QLineEdit() # self.txtSearch = QLineEdit()
self.statusbar.addWidget(self.txtSearch) # self.statusbar.addWidget(self.txtSearch)
self.txtSearch.setHidden(True) # self.txtSearch.setHidden(True)
self.hide_played_tracks = False self.hide_played_tracks = False
self.visible_playlist_tab: Callable[[], PlaylistTab] = \ self.visible_playlist_tab: Callable[[], PlaylistTab] = \
@ -101,12 +101,8 @@ class Window(QMainWindow, Ui_MainWindow):
def clear_selection(self) -> None: def clear_selection(self) -> None:
""" Clear selected row""" """ Clear selected row"""
# Unselect any selected rows
if self.visible_playlist_tab(): if self.visible_playlist_tab():
self.visible_playlist_tab().clear_selection() self.visible_playlist_tab().clear_selection()
# Clear the search bar
self.search_playlist_clear()
def closeEvent(self, event: QEvent) -> None: def closeEvent(self, event: QEvent) -> None:
"""Handle attempt to close main window""" """Handle attempt to close main window"""
@ -152,10 +148,6 @@ class Window(QMainWindow, Ui_MainWindow):
event.accept() event.accept()
def connect_signals_slots(self) -> None: def connect_signals_slots(self) -> None:
self.actionFind_next.triggered.connect(
lambda: self.tabPlaylist.currentWidget().search_next())
self.actionFind_previous.triggered.connect(
lambda: self.tabPlaylist.currentWidget().search_previous())
self.actionInsertSectionHeader.triggered.connect(self.insert_header) self.actionInsertSectionHeader.triggered.connect(self.insert_header)
self.action_Clear_selection.triggered.connect(self.clear_selection) self.action_Clear_selection.triggered.connect(self.clear_selection)
self.actionClosePlaylist.triggered.connect(self.close_playlist_tab) self.actionClosePlaylist.triggered.connect(self.close_playlist_tab)
@ -170,7 +162,7 @@ class Window(QMainWindow, Ui_MainWindow):
self.actionNewPlaylist.triggered.connect(self.create_playlist) self.actionNewPlaylist.triggered.connect(self.create_playlist)
self.actionOpenPlaylist.triggered.connect(self.open_playlist) self.actionOpenPlaylist.triggered.connect(self.open_playlist)
self.actionPlay_next.triggered.connect(self.play_next) self.actionPlay_next.triggered.connect(self.play_next)
self.actionSearch.triggered.connect(self.search_playlist) # self.actionSearch.triggered.connect(self.search_playlist)
self.actionInsertTrack.triggered.connect(self.insert_track) self.actionInsertTrack.triggered.connect(self.insert_track)
self.actionSelect_next_track.triggered.connect(self.select_next_row) self.actionSelect_next_track.triggered.connect(self.select_next_row)
# self.actionSelect_played_tracks.triggered.connect(self.select_played) # self.actionSelect_played_tracks.triggered.connect(self.select_played)
@ -187,8 +179,9 @@ class Window(QMainWindow, Ui_MainWindow):
self.btnFade.clicked.connect(self.fade) self.btnFade.clicked.connect(self.fade)
self.btnStop.clicked.connect(self.stop) self.btnStop.clicked.connect(self.stop)
self.tabPlaylist.tabCloseRequested.connect(self.close_tab) self.tabPlaylist.tabCloseRequested.connect(self.close_tab)
self.txtSearch.returnPressed.connect(self.search_playlist_return) # self.txtSearch.returnPressed.connect(self.search_playlist_return)
# self.txtSearch.textChanged.connect(self.search_playlist_update)
#
self.timer.timeout.connect(self.tick) self.timer.timeout.connect(self.tick)
def close_playlist_tab(self) -> None: def close_playlist_tab(self) -> None:
@ -630,35 +623,26 @@ class Window(QMainWindow, Ui_MainWindow):
with Session() as session: with Session() as session:
dlg = DbDialog(self, session) dlg = DbDialog(self, session)
dlg.exec() dlg.exec()
#
def search_playlist(self) -> None: # def search_playlist(self):
"""Show text box to search playlist""" # """Show text box to search playlist"""
#
# Disable play controls so that 'return' in search box doesn't # self.disable_play_next_controls()
# play next track # self.txtSearch.setHidden(False)
self.disable_play_next_controls() # self.txtSearch.setFocus()
self.txtSearch.setHidden(False) #
self.txtSearch.setFocus() # def search_playlist_return(self):
# """Close off search box when return pressed"""
def search_playlist_clear(self) -> None: #
"""Tidy up and reset search bar""" # self.txtSearch.setText("")
# self.txtSearch.setHidden(True)
# Clear the search text # self.enable_play_next_controls()
self.visible_playlist_tab().search("") # self.visible_playlist_tab().set_filter("")
# Clean up search bar #
self.txtSearch.setText("") # def search_playlist_update(self):
self.txtSearch.setHidden(True) # """Update search when search string changes"""
#
def search_playlist_return(self) -> None: # self.visible_playlist_tab().set_filter(self.txtSearch.text())
"""Initiate search when return pressed"""
self.visible_playlist_tab().search(self.txtSearch.text())
self.enable_play_next_controls()
# def search_playlist_update(self):
# """Update search when search string changes"""
# self.visible_playlist_tab().set_filter(self.txtSearch.text())
def open_playlist(self): def open_playlist(self):
with Session() as session: with Session() as session:

View File

@ -146,7 +146,7 @@ class PlaylistTab(QTableWidget):
self.itemSelectionChanged.connect(self._select_event) self.itemSelectionChanged.connect(self._select_event)
self.search_text: str = "" self.row_filter: Optional[str] = None
self.edit_cell_type = None self.edit_cell_type = None
self.selecting_in_progress = False self.selecting_in_progress = False
# Connect signals # Connect signals
@ -360,6 +360,7 @@ class PlaylistTab(QTableWidget):
self._set_row_start_time(row, start_time) self._set_row_start_time(row, start_time)
else: else:
self._set_row_start_time(row, None) self._set_row_start_time(row, None)
else: else:
track = None track = None
if track_id: if track_id:
@ -375,6 +376,8 @@ class PlaylistTab(QTableWidget):
# which currently it isn't). # which currently it isn't).
self.musicmuster.update_headers() self.musicmuster.update_headers()
self.edit_cell_type = None
def closeEditor(self, def closeEditor(self,
editor: QWidget, editor: QWidget,
hint: QAbstractItemDelegate.EndEditHint) -> None: hint: QAbstractItemDelegate.EndEditHint) -> None:
@ -388,7 +391,6 @@ class PlaylistTab(QTableWidget):
with Session() as session: with Session() as session:
self.update_display(session) self.update_display(session)
self.edit_cell_type = None
self.musicmuster.enable_play_next_controls() self.musicmuster.enable_play_next_controls()
super(PlaylistTab, self).closeEditor(editor, hint) super(PlaylistTab, self).closeEditor(editor, hint)
@ -400,8 +402,9 @@ class PlaylistTab(QTableWidget):
Override QAbstractItemView.edit to catch when editing starts Override QAbstractItemView.edit to catch when editing starts
""" """
self.edit_cell_type = None
result = super(PlaylistTab, self).edit(index, trigger, event) result = super(PlaylistTab, self).edit(index, trigger, event)
if result: # will only be true on double-clicke if result:
row = index.row() row = index.row()
column = index.column() column = index.column()
@ -433,6 +436,9 @@ class PlaylistTab(QTableWidget):
note_column = 1 note_column = 1
self.edit_cell_type = "row_notes" self.edit_cell_type = "row_notes"
# Connect signal so we know when cell has changed.
self.cellChanged.connect(self._cell_changed)
# Disable play controls so that keyboard input doesn't # Disable play controls so that keyboard input doesn't
# disturb playing # disturb playing
self.musicmuster.disable_play_next_controls() self.musicmuster.disable_play_next_controls()
@ -448,9 +454,6 @@ class PlaylistTab(QTableWidget):
item = self.item(row, note_column) item = self.item(row, note_column)
item.setText(plr_item.note) item.setText(plr_item.note)
# Connect signal so we know when cell has changed.
self.cellChanged.connect(self._cell_changed)
return result return result
# # ########## Externally called functions ########## # # ########## Externally called functions ##########
@ -775,109 +778,78 @@ class PlaylistTab(QTableWidget):
session.commit() session.commit()
PlaylistRows.delete_higher_rows(session, self.playlist_id, row) PlaylistRows.delete_higher_rows(session, self.playlist_id, row)
def search(self, text: str) -> None: # def save_playlist(self, session) -> None:
"""Set search text and find first match""" # """
# Save playlist to database.
self.search_text = text #
if not text: # For notes: check the database entry is correct and update it if
# Search string has been reset # necessary. Playlists:Note is one:many, so each note may only appear
return # in one playlist.
self.search_next() #
# For tracks: erase the playlist tracks and recreate. This is much
def search_next(self) -> None: # simpler than trying to implement any Playlists:Tracks many:many
""" # changes.
Select next row containg self.search_string. Start from # """
top selected row if there is one, else from top. #
# playlist = Playlists.get_by_id(session, self.playlist_id)
Wrap at last row. #
""" # # Notes first
# # Create dictionaries indexed by note_id
if not self.search_text: # playlist_notes: Dict[int, Notes] = {}
return # database_notes: Dict[int, Notes] = {}
# notes_rows: List[int] = self._get_notes_rows()
selected_row = self._get_selected_row() #
if selected_row and selected_row < self.rowCount() - 1: # # PlaylistTab
starting_row = selected_row + 1 # for row in notes_rows:
else: # note: Notes = self._get_row_notes_object(row, session)
starting_row = 0 # session.add(note)
# playlist_notes[note.id] = note
wrapped = False # if row != note.row:
match_row = None # log.debug(f"Updating: {playlist.name=}, {row=}, {note.row=}")
row = starting_row # note.update(session=session, row=row)
needle = self.search_text.lower() #
while True: # # Database
# Check for match in title, artist or notes # for note in playlist.notes:
title = self._get_row_title(row) # database_notes[note.id] = note
if title and needle in title.lower(): #
match_row = row # # We don't need to check for notes to add to the database as
break # # they can't exist in the playlist without being in the database
artist = self._get_row_title(row) # # and pointing at this playlist.
if artist and needle in artist.lower(): #
match_row = row # # Notes to remove from database
break # for note_id in set(database_notes.keys()) - set(playlist_notes.keys()):
note = self._get_row_note(row) # log.debug(
if note and needle in note.lower(): # "_save_playlist(): "
match_row = row # f"Delete {note_id=} from {self=} in database"
break # )
row += 1 # database_notes[note_id].delete_note(session)
if wrapped and row >= starting_row: #
break # # Note rows to update in playlist database
if row >= self.rowCount(): # for note_id in set(playlist_notes.keys()) & set(database_notes.keys()):
row = 0 # if playlist_notes[note_id].row != database_notes[note_id].row:
wrapped = True # log.debug(
# f"_save_playlist(): Update notes row in database "
if match_row: # f"from {database_notes[note_id]=} "
self.selectRow(row) # f"to {playlist_notes[note_id]=}"
# )
def search_previous(self) -> None: # database_notes[note_id].update(
""" # session, row=playlist_notes[note_id].row)
Select previous row containg self.search_string. Start from #
top selected row if there is one, else from top. # # Tracks
# # Remove all tracks from this playlist
Wrap at last row. # playlist.remove_all_tracks(session)
""" # # Iterate on-screen playlist and add tracks back in
# for row in range(self.rowCount()):
if not self.search_text: # if row in notes_rows:
return # continue
# track_id: int = self.item(
selected_row = self._get_selected_row() # row, FIXUP.COL_USERDATA).data(self.CONTENT_OBJECT)
if selected_row and selected_row > 0: # playlist.add_track(session, track_id, row)
starting_row = selected_row - 1 # session.commit()
else:
starting_row = self.rowCount() - 1
wrapped = False
match_row = None
row = starting_row
needle = self.search_text.lower()
while True:
# Check for match in title, artist or notes
title = self._get_row_title(row)
if title and needle in title.lower():
match_row = row
break
artist = self._get_row_title(row)
if artist and needle in artist.lower():
match_row = row
break
note = self._get_row_note(row)
if note and needle in note.lower():
match_row = row
break
row -= 1
if wrapped and row <= starting_row:
break
if row < 0:
row = self.rowCount() - 1
wrapped = True
if match_row:
self.selectRow(row)
def select_next_row(self) -> None: def select_next_row(self) -> None:
""" """
Select next or first row. Don't select section headers. Select next or first row. Don't select section headers.
Wrap at last row. Wrap at last row.
""" """
@ -969,12 +941,13 @@ class PlaylistTab(QTableWidget):
# finally: # finally:
# self.selecting_in_progress = False # self.selecting_in_progress = False
# self._select_event() # self._select_event()
#
def set_searchtext(self, text: Optional[str]) -> None: # def set_filter(self, text: Optional[str]) -> None:
"""Set the search text and find first match""" # """Filter rows to only show those containing text"""
#
self.search_text = text # self.row_filter = text
self._find_next_match() # with Session() as session:
# self.update_display(session)
def set_selected_as_next(self) -> None: def set_selected_as_next(self) -> None:
"""Sets the select track as next to play""" """Sets the select track as next to play"""
@ -1010,8 +983,12 @@ class PlaylistTab(QTableWidget):
] ]
unreadable: List[int] = self._get_unreadable_track_rows() unreadable: List[int] = self._get_unreadable_track_rows()
if self.row_filter:
filter_text = self.row_filter.lower()
else:
filter_text = None
next_start_time = None next_start_time = None
section_start_plr = None section_start_row = None
section_time = 0 section_time = 0
# Start time calculations # Start time calculations
@ -1046,9 +1023,25 @@ class PlaylistTab(QTableWidget):
continue continue
# Add track time to section time if in timed section # Add track time to section time if in timed section
if section_start_plr is not None: if section_start_row is not None:
section_time += track.duration section_time += track.duration
# If filtering, only show matching tracks
if filter_text:
try:
if (track.title
and filter_text not in track.title.lower()
and track.artist
and filter_text not in track.artist.lower()):
self.hideRow(row)
continue
else:
self.showRow(row)
except TypeError:
print(f"TypeError: {track=}")
else:
self.showRow(row)
# Colour any note # Colour any note
if note_text: if note_text:
(self.item(row, columns['row_notes'].idx) (self.item(row, columns['row_notes'].idx)
@ -1129,21 +1122,27 @@ class PlaylistTab(QTableWidget):
continue continue
# No track associated, so this row is a section header # No track associated, so this row is a section header
if filter_text:
if filter_text not in note_text.lower():
self.hideRow(row)
continue
else:
self.showRow(row)
else:
self.showRow(row)
# Does the note have a start time? # Does the note have a start time?
row_time = self._get_note_text_time(note_text) row_time = self._get_note_text_time(note_text)
if row_time: if row_time:
next_start_time = row_time next_start_time = row_time
# Does it delimit a section? # Does it delimit a section?
if section_start_plr is not None: if section_start_row is not None:
if note_text.endswith("-"): if note_text.endswith("-"):
self._update_note_text( self._set_timed_section(session, section_start_row,
section_start_plr, section_time)
self._get_section_timing_string(section_time) section_start_row = None
)
section_start_plr = None
section_time = 0 section_time = 0
elif note_text.endswith("+"): elif note_text.endswith("+"):
section_start_plr = playlist_row section_start_row = row
section_time = 0 section_time = 0
self._set_row_colour( self._set_row_colour(
row, QColor(note_colour) row, QColor(note_colour)
@ -1153,11 +1152,9 @@ class PlaylistTab(QTableWidget):
continue continue
# Have we had a section start but not end? # Have we had a section start but not end?
if section_start_plr is not None: if section_start_row is not None:
self._update_note_text( self._set_timed_section(
section_start_plr, session, section_start_row, section_time, no_end=True)
self._get_section_timing_string(section_time, no_end=True)
)
# #
# # ########## Internally called functions ########## # # ########## Internally called functions ##########
@ -1266,18 +1263,11 @@ class PlaylistTab(QTableWidget):
return (index.row() + 1 if self._is_below(event.pos(), index) return (index.row() + 1 if self._is_below(event.pos(), index)
else index.row()) else index.row())
def _find_next_match(self) -> None: # def _get_notes_rows(self) -> List[int]:
""" # """Return rows marked as notes, or None"""
Find next match of search_text. Start at first highlighted row #
if there is one, else from top of playlist. # return self._meta_search(RowMeta.NOTE, one=False)
""" #
start_row = self._get_selected_row()
if start_row is None:
start_row = 0
def _find_next_track_row(self, session: Session, def _find_next_track_row(self, session: Session,
starting_row: int = None) -> Optional[int]: starting_row: int = None) -> Optional[int]:
@ -1349,16 +1339,6 @@ class PlaylistTab(QTableWidget):
return playlistrow_id return playlistrow_id
def _get_row_artist(self, row: int) -> Optional[str]:
"""Return artist on this row or None if none"""
track_id = self._get_row_track_id(row)
if not track_id:
return None
item_artist = self.item(row, columns['artist'].idx)
return item_artist.text()
def _get_row_duration(self, row: int) -> int: def _get_row_duration(self, row: int) -> int:
"""Return duration associated with this row""" """Return duration associated with this row"""
@ -1369,15 +1349,46 @@ class PlaylistTab(QTableWidget):
else: else:
return 0 return 0
def _get_row_note(self, row: int) -> Optional[str]: def _get_row_track_id(self, row: int) -> int:
"""Return note on this row or None if none""" """Return the track_id associated with this row or None"""
track_id = self._get_row_track_id(row) track_id = (self.item(row, columns['userdata'].idx)
if track_id: .data(self.ROW_TRACK_ID))
item_note = self.item(row, columns['row_notes'].idx)
else: return track_id
item_note = self.item(row, 1)
return item_note.text() #
# def _get_row_end_time(self, row) -> Optional[datetime]:
# """
# Return row end time as string
# """
#
# try:
# if self.item(row, FIXUP.COL_END_TIME):
# return datetime.strptime(self.item(
# row, FIXUP.COL_END_TIME).text(),
# Config.NOTE_TIME_FORMAT
# )
# else:
# return None
# except ValueError:
# return None
#
# def _get_row_notes_object(self, row: int, session: Session) \
# -> Optional[Notes]:
# """Return note associated with this row"""
#
# note_id = self.item(row, FIXUP.COL_USERDATA).data(self.CONTENT_OBJECT)
# note = Notes.get_by_id(session, note_id)
# return note
#
# def _get_unplayed_track_rows(self) -> Optional[List[int]]:
# """Return rows marked as unplayed, or None"""
#
# unplayed_rows: Set[int] = set(self._meta_notset(RowMeta.PLAYED))
# notes_rows: Set[int] = set(self._get_notes_rows())
#
# return list(unplayed_rows - notes_rows)
def _get_row_start_time(self, row: int) -> Optional[datetime]: def _get_row_start_time(self, row: int) -> Optional[datetime]:
try: try:
@ -1391,35 +1402,6 @@ class PlaylistTab(QTableWidget):
except ValueError: except ValueError:
return None return None
def _get_row_title(self, row: int) -> Optional[str]:
"""Return title on this row or None if none"""
track_id = self._get_row_track_id(row)
if not track_id:
return None
item_title = self.item(row, columns['title'].idx)
return item_title.text()
def _get_row_track_id(self, row: int) -> int:
"""Return the track_id associated with this row or None"""
try:
track_id = (self.item(row, columns['userdata'].idx)
.data(self.ROW_TRACK_ID))
except AttributeError:
return None
return track_id
# def _get_unplayed_track_rows(self) -> Optional[List[int]]:
# """Return rows marked as unplayed, or None"""
#
# unplayed_rows: Set[int] = set(self._meta_notset(RowMeta.PLAYED))
# notes_rows: Set[int] = set(self._get_notes_rows())
#
# return list(unplayed_rows - notes_rows)
def _get_selected_row(self) -> Optional[int]: def _get_selected_row(self) -> Optional[int]:
"""Return row number of first selected row, or None if none selected""" """Return row number of first selected row, or None if none selected"""
@ -1427,6 +1409,19 @@ class PlaylistTab(QTableWidget):
return None return None
else: else:
return self.selectionModel().selectedRows()[0].row() return self.selectionModel().selectedRows()[0].row()
#
# def _get_row_track_object(self, row: int, session: Session) \
# -> Optional[Tracks]:
# """Return track associated with this row"""
#
# track_id = self.item(row, FIXUP.COL_USERDATA).data(self.CONTENT_OBJECT)
# track = Tracks.get_by_id(session, track_id)
# return track
#
# def _get_track_rows(self) -> List[int]:
# """Return rows marked as tracks, or None"""
#
# return self._meta_notset(RowMeta.NOTE)
def _get_unreadable_track_rows(self) -> List[int]: def _get_unreadable_track_rows(self) -> List[int]:
"""Return rows marked as unreadable, or None""" """Return rows marked as unreadable, or None"""
@ -1861,52 +1856,43 @@ class PlaylistTab(QTableWidget):
"""Mark this row as unreadable""" """Mark this row as unreadable"""
self._meta_set_attribute(row, RowMeta.UNREADABLE) self._meta_set_attribute(row, RowMeta.UNREADABLE)
# #
# def _select_tracks(self, played: bool) -> None: # def _select_tracks(self, played: bool) -> None:
# """ # """
# Select all played (played=True) or unplayed (played=False) # Select all played (played=True) or unplayed (played=False)
# tracks in playlist # tracks in playlist
# """ # """
# #
# # Need to allow multiple rows to be selected # # Need to allow multiple rows to be selected
# self.setSelectionMode(QAbstractItemView.MultiSelection) # self.setSelectionMode(QAbstractItemView.MultiSelection)
# self.clear_selection() # self.clear_selection()
# #
# if played: # if played:
# rows = self._get_played_track_rows() # rows = self._get_played_track_rows()
# else: # else:
# rows = self._get_unplayed_track_rows() # rows = self._get_unplayed_track_rows()
# #
# for row in rows: # for row in rows:
# self.selectRow(row) # self.selectRow(row)
# #
# # Reset extended selection # # Reset extended selection
# self.setSelectionMode(QAbstractItemView.ExtendedSelection) # self.setSelectionMode(QAbstractItemView.ExtendedSelection)
def _get_section_timing_string(self, ms: int, #
no_end: bool = False) -> None: # def _set_timed_section(self, session, start_row, ms, no_end=False):
"""Return string describing section duration""" # """Add duration to a marked section"""
#
duration = ms_to_mmss(ms) # duration = ms_to_mmss(ms)
caveat = "" # note_object = self._get_row_notes_object(start_row, session)
if no_end: # if not note_object:
caveat = " (to end of playlist)" # log.error("Can't get note_object in playlists._set_timed_section")
return ' [' + duration + caveat + ']' # note_text = note_object.note
# caveat = ""
def _update_note_text(self, playlist_row: PlaylistRows, # if no_end:
additional_text: str) -> None: # caveat = " (to end of playlist)"
"""Append additional_text to row display""" # display_text = note_text + ' [' + duration + caveat + ']'
# item = self.item(start_row, FIXUP.COL_TITLE)
# Column to update is either 1 for a section header or the # item.setText(display_text)
# appropriate row_notes column for a track row
if playlist_row.track_id:
column = columns['row_notes'].idx
else:
column = 1
# Update text
new_text = playlist_row.note + additional_text
self.item(playlist_row.row_number, column).setText(new_text)
def _update_row(self, session, row: int, track: Tracks) -> None: def _update_row(self, session, row: int, track: Tracks) -> None:
""" """

View File

@ -784,26 +784,17 @@ border: 1px solid rgb(85, 87, 83);</string>
<addaction name="actionInsertTrack"/> <addaction name="actionInsertTrack"/>
<addaction name="actionRemove"/> <addaction name="actionRemove"/>
<addaction name="actionImport"/> <addaction name="actionImport"/>
<addaction name="separator"/>
<addaction name="actionSetNext"/> <addaction name="actionSetNext"/>
<addaction name="action_Clear_selection"/> <addaction name="action_Clear_selection"/>
<addaction name="separator"/> <addaction name="separator"/>
<addaction name="actionEnable_controls"/>
</widget>
<widget class="QMenu" name="menuSearc_h">
<property name="title">
<string>Searc&amp;h</string>
</property>
<addaction name="actionSearch"/> <addaction name="actionSearch"/>
<addaction name="actionFind_next"/>
<addaction name="actionFind_previous"/>
<addaction name="separator"/>
<addaction name="actionSelect_next_track"/> <addaction name="actionSelect_next_track"/>
<addaction name="actionSelect_previous_track"/> <addaction name="actionSelect_previous_track"/>
<addaction name="separator"/>
<addaction name="actionEnable_controls"/>
</widget> </widget>
<addaction name="menuFile"/> <addaction name="menuFile"/>
<addaction name="menuPlaylist"/> <addaction name="menuPlaylist"/>
<addaction name="menuSearc_h"/>
</widget> </widget>
<widget class="QStatusBar" name="statusbar"> <widget class="QStatusBar" name="statusbar">
<property name="enabled"> <property name="enabled">
@ -1052,22 +1043,6 @@ border: 1px solid rgb(85, 87, 83);</string>
<string>&amp;Remove track</string> <string>&amp;Remove track</string>
</property> </property>
</action> </action>
<action name="actionFind_next">
<property name="text">
<string>Find next</string>
</property>
<property name="shortcut">
<string>N</string>
</property>
</action>
<action name="actionFind_previous">
<property name="text">
<string>Find previous</string>
</property>
<property name="shortcut">
<string>P</string>
</property>
</action>
</widget> </widget>
<customwidgets> <customwidgets>
<customwidget> <customwidget>

View File

@ -350,8 +350,6 @@ class Ui_MainWindow(object):
self.menuFile.setObjectName("menuFile") self.menuFile.setObjectName("menuFile")
self.menuPlaylist = QtWidgets.QMenu(self.menubar) self.menuPlaylist = QtWidgets.QMenu(self.menubar)
self.menuPlaylist.setObjectName("menuPlaylist") self.menuPlaylist.setObjectName("menuPlaylist")
self.menuSearc_h = QtWidgets.QMenu(self.menubar)
self.menuSearc_h.setObjectName("menuSearc_h")
MainWindow.setMenuBar(self.menubar) MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow) self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setEnabled(True) self.statusbar.setEnabled(True)
@ -446,10 +444,6 @@ class Ui_MainWindow(object):
self.actionInsertSectionHeader.setObjectName("actionInsertSectionHeader") self.actionInsertSectionHeader.setObjectName("actionInsertSectionHeader")
self.actionRemove = QtWidgets.QAction(MainWindow) self.actionRemove = QtWidgets.QAction(MainWindow)
self.actionRemove.setObjectName("actionRemove") self.actionRemove.setObjectName("actionRemove")
self.actionFind_next = QtWidgets.QAction(MainWindow)
self.actionFind_next.setObjectName("actionFind_next")
self.actionFind_previous = QtWidgets.QAction(MainWindow)
self.actionFind_previous.setObjectName("actionFind_previous")
self.menuFile.addAction(self.actionNewPlaylist) self.menuFile.addAction(self.actionNewPlaylist)
self.menuFile.addAction(self.actionOpenPlaylist) self.menuFile.addAction(self.actionOpenPlaylist)
self.menuFile.addAction(self.actionClosePlaylist) self.menuFile.addAction(self.actionClosePlaylist)
@ -474,20 +468,16 @@ class Ui_MainWindow(object):
self.menuPlaylist.addAction(self.actionInsertTrack) self.menuPlaylist.addAction(self.actionInsertTrack)
self.menuPlaylist.addAction(self.actionRemove) self.menuPlaylist.addAction(self.actionRemove)
self.menuPlaylist.addAction(self.actionImport) self.menuPlaylist.addAction(self.actionImport)
self.menuPlaylist.addSeparator()
self.menuPlaylist.addAction(self.actionSetNext) self.menuPlaylist.addAction(self.actionSetNext)
self.menuPlaylist.addAction(self.action_Clear_selection) self.menuPlaylist.addAction(self.action_Clear_selection)
self.menuPlaylist.addSeparator() self.menuPlaylist.addSeparator()
self.menuPlaylist.addAction(self.actionSearch)
self.menuPlaylist.addAction(self.actionSelect_next_track)
self.menuPlaylist.addAction(self.actionSelect_previous_track)
self.menuPlaylist.addSeparator()
self.menuPlaylist.addAction(self.actionEnable_controls) self.menuPlaylist.addAction(self.actionEnable_controls)
self.menuSearc_h.addAction(self.actionSearch)
self.menuSearc_h.addAction(self.actionFind_next)
self.menuSearc_h.addAction(self.actionFind_previous)
self.menuSearc_h.addSeparator()
self.menuSearc_h.addAction(self.actionSelect_next_track)
self.menuSearc_h.addAction(self.actionSelect_previous_track)
self.menubar.addAction(self.menuFile.menuAction()) self.menubar.addAction(self.menuFile.menuAction())
self.menubar.addAction(self.menuPlaylist.menuAction()) self.menubar.addAction(self.menuPlaylist.menuAction())
self.menubar.addAction(self.menuSearc_h.menuAction())
self.retranslateUi(MainWindow) self.retranslateUi(MainWindow)
self.tabPlaylist.setCurrentIndex(-1) self.tabPlaylist.setCurrentIndex(-1)
@ -524,7 +514,6 @@ class Ui_MainWindow(object):
self.btnHidePlayed.setText(_translate("MainWindow", "Hide played")) self.btnHidePlayed.setText(_translate("MainWindow", "Hide played"))
self.menuFile.setTitle(_translate("MainWindow", "P&laylists")) self.menuFile.setTitle(_translate("MainWindow", "P&laylists"))
self.menuPlaylist.setTitle(_translate("MainWindow", "Sho&wtime")) self.menuPlaylist.setTitle(_translate("MainWindow", "Sho&wtime"))
self.menuSearc_h.setTitle(_translate("MainWindow", "Searc&h"))
self.actionPlay_next.setText(_translate("MainWindow", "&Play next")) self.actionPlay_next.setText(_translate("MainWindow", "&Play next"))
self.actionPlay_next.setShortcut(_translate("MainWindow", "Return")) self.actionPlay_next.setShortcut(_translate("MainWindow", "Return"))
self.actionSkipToNext.setText(_translate("MainWindow", "Skip to &next")) self.actionSkipToNext.setText(_translate("MainWindow", "Skip to &next"))
@ -571,9 +560,5 @@ class Ui_MainWindow(object):
self.actionInsertSectionHeader.setText(_translate("MainWindow", "Insert &section header...")) self.actionInsertSectionHeader.setText(_translate("MainWindow", "Insert &section header..."))
self.actionInsertSectionHeader.setShortcut(_translate("MainWindow", "Ctrl+H")) self.actionInsertSectionHeader.setShortcut(_translate("MainWindow", "Ctrl+H"))
self.actionRemove.setText(_translate("MainWindow", "&Remove track")) self.actionRemove.setText(_translate("MainWindow", "&Remove track"))
self.actionFind_next.setText(_translate("MainWindow", "Find next"))
self.actionFind_next.setShortcut(_translate("MainWindow", "N"))
self.actionFind_previous.setText(_translate("MainWindow", "Find previous"))
self.actionFind_previous.setShortcut(_translate("MainWindow", "P"))
from infotabs import InfoTabs from infotabs import InfoTabs
import icons_rc import icons_rc