Compare commits
No commits in common. "56fb1aeb3d115f7776b3753ea9c687553f6d4998" and "bdf7b0979d9111882d43cca9729b4d169aeaa4f4" have entirely different histories.
56fb1aeb3d
...
bdf7b0979d
@ -448,17 +448,17 @@ class PlaylistRows(Base):
|
|||||||
f"note={self.note} row_number={self.row_number}>"
|
f"note={self.note} row_number={self.row_number}>"
|
||||||
)
|
)
|
||||||
|
|
||||||
def __init__(
|
# def __init__(
|
||||||
self, session: Session, playlist_id: int, track_id: int,
|
# self, session: Session, playlist_id: int, track_id: int,
|
||||||
row_number: int) -> None:
|
# row: int) -> None:
|
||||||
"""Create PlaylistRows object"""
|
# log.debug(f"xPlaylistTracks.__init__({playlist_id=}, {track_id=}, {row=})")
|
||||||
|
#
|
||||||
self.playlist_id = playlist_id
|
# self.playlist_id = playlist_id
|
||||||
self.track_id = track_id
|
# self.track_id = track_id
|
||||||
self.row_number = row_number
|
# self.row = row
|
||||||
session.add(self)
|
# session.add(self)
|
||||||
session.flush()
|
# session.flush()
|
||||||
|
#
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def delete_higher_rows(session: Session, playlist_id: int, row: int) \
|
def delete_higher_rows(session: Session, playlist_id: int, row: int) \
|
||||||
-> None:
|
-> None:
|
||||||
@ -806,33 +806,23 @@ class Tracks(Base):
|
|||||||
# session.flush()
|
# session.flush()
|
||||||
# except IntegrityError as exception:
|
# except IntegrityError as exception:
|
||||||
# log.error(f"Can't remove track with {path=} ({exception=})")
|
# log.error(f"Can't remove track with {path=} ({exception=})")
|
||||||
|
#
|
||||||
@classmethod
|
# @classmethod
|
||||||
def search_artists(cls, session: Session, text: str) -> List["Tracks"]:
|
# def search_artists(cls, session: Session, text: str) -> List["Tracks"]:
|
||||||
"""Search case-insenstively for artists containing str"""
|
#
|
||||||
|
# return (
|
||||||
return (
|
# session.query(cls)
|
||||||
session.execute(
|
# .filter(cls.artist.ilike(f"%{text}%"))
|
||||||
select(cls)
|
# .order_by(cls.title)
|
||||||
.where(cls.artist.ilike(f"%{text}%"))
|
# ).all()
|
||||||
.order_by(cls.title)
|
#
|
||||||
)
|
# @classmethod
|
||||||
.scalars()
|
# def search_titles(cls, session: Session, text: str) -> List["Tracks"]:
|
||||||
.all()
|
# return (
|
||||||
)
|
# session.query(cls)
|
||||||
|
# .filter(cls.title.ilike(f"%{text}%"))
|
||||||
@classmethod
|
# .order_by(cls.title)
|
||||||
def search_titles(cls, session: Session, text: str) -> List["Tracks"]:
|
# ).all()
|
||||||
"""Search case-insenstively for titles containing str"""
|
|
||||||
return (
|
|
||||||
session.execute(
|
|
||||||
select(cls)
|
|
||||||
.where(cls.title.ilike(f"%{text}%"))
|
|
||||||
.order_by(cls.title)
|
|
||||||
)
|
|
||||||
.scalars()
|
|
||||||
.all()
|
|
||||||
)
|
|
||||||
#
|
#
|
||||||
# @staticmethod
|
# @staticmethod
|
||||||
# def update_lastplayed(session: Session, track_id: int) -> None:
|
# def update_lastplayed(session: Session, track_id: int) -> None:
|
||||||
|
|||||||
@ -36,7 +36,7 @@ from models import (
|
|||||||
)
|
)
|
||||||
from playlists import PlaylistTab
|
from playlists import PlaylistTab
|
||||||
from sqlalchemy.orm.exc import DetachedInstanceError
|
from sqlalchemy.orm.exc import DetachedInstanceError
|
||||||
from ui.dlg_search_database_ui import Ui_Dialog # type: ignore
|
# from ui.dlg_search_database_ui import Ui_Dialog
|
||||||
from ui.dlg_SelectPlaylist_ui import Ui_dlgSelectPlaylist # type: ignore
|
from ui.dlg_SelectPlaylist_ui import Ui_dlgSelectPlaylist # type: ignore
|
||||||
from ui.downloadcsv_ui import Ui_DateSelect # type: ignore
|
from ui.downloadcsv_ui import Ui_DateSelect # type: ignore
|
||||||
from config import Config
|
from config import Config
|
||||||
@ -148,7 +148,7 @@ class Window(QMainWindow, Ui_MainWindow):
|
|||||||
event.accept()
|
event.accept()
|
||||||
|
|
||||||
def connect_signals_slots(self) -> None:
|
def connect_signals_slots(self) -> None:
|
||||||
self.actionInsertSectionHeader.triggered.connect(self.insert_header)
|
# self.actionAdd_note.triggered.connect(self.create_note)
|
||||||
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)
|
||||||
self.actionDownload_CSV_of_played_tracks.triggered.connect(
|
self.actionDownload_CSV_of_played_tracks.triggered.connect(
|
||||||
@ -163,7 +163,7 @@ class Window(QMainWindow, Ui_MainWindow):
|
|||||||
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.actionSearch_database.triggered.connect(self.search_database)
|
||||||
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)
|
||||||
self.actionSelect_previous_track.triggered.connect(
|
self.actionSelect_previous_track.triggered.connect(
|
||||||
@ -213,25 +213,15 @@ class Window(QMainWindow, Ui_MainWindow):
|
|||||||
# Close playlist and remove tab
|
# Close playlist and remove tab
|
||||||
self.tabPlaylist.widget(tab_index).close()
|
self.tabPlaylist.widget(tab_index).close()
|
||||||
self.tabPlaylist.removeTab(tab_index)
|
self.tabPlaylist.removeTab(tab_index)
|
||||||
|
#
|
||||||
def insert_header(self) -> None:
|
# def create_note(self) -> None:
|
||||||
"""Show dialog box to enter header text and add to playlist"""
|
# """Call playlist to create note"""
|
||||||
|
#
|
||||||
try:
|
# try:
|
||||||
playlist_tab = self.visible_playlist_tab()
|
# self.visible_playlist_tab().create_note()
|
||||||
except AttributeError:
|
# except AttributeError:
|
||||||
# Just return if there's no visible playlist tab
|
# # Just return if there's no visible playlist tab
|
||||||
return
|
# return
|
||||||
|
|
||||||
# Get header text
|
|
||||||
dlg: QInputDialog = QInputDialog(self)
|
|
||||||
dlg.setInputMode(QInputDialog.TextInput)
|
|
||||||
dlg.setLabelText("Header text:")
|
|
||||||
dlg.resize(500, 100)
|
|
||||||
ok = dlg.exec()
|
|
||||||
if ok:
|
|
||||||
with Session() as session:
|
|
||||||
playlist_tab.insert_header(session, dlg.textValue())
|
|
||||||
|
|
||||||
def create_playlist(self) -> None:
|
def create_playlist(self) -> None:
|
||||||
"""Create new playlist"""
|
"""Create new playlist"""
|
||||||
@ -617,12 +607,12 @@ class Window(QMainWindow, Ui_MainWindow):
|
|||||||
self.label_end_time.setText(
|
self.label_end_time.setText(
|
||||||
end_at.strftime(Config.TRACK_TIME_FORMAT))
|
end_at.strftime(Config.TRACK_TIME_FORMAT))
|
||||||
|
|
||||||
def insert_track(self) -> None:
|
# def search_database(self) -> None:
|
||||||
"""Show dialog box to select and add track from database"""
|
# """Show dialog box to select and cue track from database"""
|
||||||
|
#
|
||||||
with Session() as session:
|
# with Session() as session:
|
||||||
dlg = DbDialog(self, session)
|
# dlg = DbDialog(self, session)
|
||||||
dlg.exec()
|
# dlg.exec()
|
||||||
#
|
#
|
||||||
# def search_playlist(self):
|
# def search_playlist(self):
|
||||||
# """Show text box to search playlist"""
|
# """Show text box to search playlist"""
|
||||||
@ -891,121 +881,104 @@ class Window(QMainWindow, Ui_MainWindow):
|
|||||||
)
|
)
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
self.hdrNextTrack.setText("")
|
self.hdrNextTrack.setText("")
|
||||||
|
#
|
||||||
|
#
|
||||||
class DbDialog(QDialog):
|
# class DbDialog(QDialog):
|
||||||
"""Select track from database"""
|
# """Select track from database"""
|
||||||
|
#
|
||||||
def __init__(self, parent: QMainWindow, session: Session) -> None:
|
# def __init__(self, parent, session): # review
|
||||||
"""Subclassed QDialog to manage track selection"""
|
# super().__init__(parent)
|
||||||
|
# self.session = session
|
||||||
super().__init__(parent)
|
# self.ui = Ui_Dialog()
|
||||||
self.session = session
|
# self.ui.setupUi(self)
|
||||||
self.ui = Ui_Dialog()
|
# self.ui.btnAdd.clicked.connect(self.add_selected)
|
||||||
self.ui.setupUi(self)
|
# self.ui.btnAddClose.clicked.connect(self.add_selected_and_close)
|
||||||
self.ui.btnAdd.clicked.connect(self.add_selected)
|
# self.ui.btnClose.clicked.connect(self.close)
|
||||||
self.ui.btnAddClose.clicked.connect(self.add_selected_and_close)
|
# self.ui.matchList.itemDoubleClicked.connect(self.double_click)
|
||||||
self.ui.btnClose.clicked.connect(self.close)
|
# self.ui.matchList.itemSelectionChanged.connect(self.selection_changed)
|
||||||
self.ui.matchList.itemDoubleClicked.connect(self.double_click)
|
# self.ui.radioTitle.toggled.connect(self.title_artist_toggle)
|
||||||
self.ui.matchList.itemSelectionChanged.connect(self.selection_changed)
|
# self.ui.searchString.textEdited.connect(self.chars_typed)
|
||||||
self.ui.radioTitle.toggled.connect(self.title_artist_toggle)
|
#
|
||||||
self.ui.searchString.textEdited.connect(self.chars_typed)
|
# record = Settings.get_int_settings(self.session, "dbdialog_width")
|
||||||
|
# width = record.f_int or 800
|
||||||
record = Settings.get_int_settings(self.session, "dbdialog_width")
|
# record = Settings.get_int_settings(self.session, "dbdialog_height")
|
||||||
width = record.f_int or 800
|
# height = record.f_int or 600
|
||||||
record = Settings.get_int_settings(self.session, "dbdialog_height")
|
# self.resize(width, height)
|
||||||
height = record.f_int or 600
|
#
|
||||||
self.resize(width, height)
|
# def __del__(self): # review
|
||||||
|
# record = Settings.get_int_settings(self.session, "dbdialog_height")
|
||||||
def __del__(self) -> None:
|
# if record.f_int != self.height():
|
||||||
"""Save dialog size and position"""
|
# record.update(self.session, {'f_int': self.height()})
|
||||||
|
#
|
||||||
record = Settings.get_int_settings(self.session, "dbdialog_height")
|
# record = Settings.get_int_settings(self.session, "dbdialog_width")
|
||||||
if record.f_int != self.height():
|
# if record.f_int != self.width():
|
||||||
record.update(self.session, {'f_int': self.height()})
|
# record.update(self.session, {'f_int': self.width()})
|
||||||
|
#
|
||||||
record = Settings.get_int_settings(self.session, "dbdialog_width")
|
# def add_selected(self): # review
|
||||||
if record.f_int != self.width():
|
# if not self.ui.matchList.selectedItems():
|
||||||
record.update(self.session, {'f_int': self.width()})
|
# return
|
||||||
|
#
|
||||||
def add_selected(self) -> None:
|
# item = self.ui.matchList.currentItem()
|
||||||
"""Handle Add button"""
|
# track = item.data(Qt.UserRole)
|
||||||
|
# self.add_track(track)
|
||||||
if not self.ui.matchList.selectedItems():
|
#
|
||||||
return
|
# def add_selected_and_close(self): # review
|
||||||
|
# self.add_selected()
|
||||||
item = self.ui.matchList.currentItem()
|
# self.close()
|
||||||
track = item.data(Qt.UserRole)
|
#
|
||||||
self.add_track(track)
|
# def title_artist_toggle(self): # review
|
||||||
|
# """
|
||||||
def add_selected_and_close(self) -> None:
|
# Handle switching between searching for artists and searching for
|
||||||
"""Handle Add and Close button"""
|
# titles
|
||||||
|
# """
|
||||||
self.add_selected()
|
#
|
||||||
self.close()
|
# # Logic is handled already in chars_typed(), so just call that.
|
||||||
|
# self.chars_typed(self.ui.searchString.text())
|
||||||
def add_track(self, track: Tracks) -> None:
|
#
|
||||||
"""Add passed track to playlist on screen"""
|
# def chars_typed(self, s): # review
|
||||||
|
# if len(s) > 0:
|
||||||
self.parent().visible_playlist_tab().insert_track(self.session, track)
|
# if self.ui.radioTitle.isChecked():
|
||||||
# Commit session to get correct row numbers if more tracks added
|
# matches = Tracks.search_titles(self.session, s)
|
||||||
self.session.commit()
|
# else:
|
||||||
# Select search text to make it easier for next search
|
# matches = Tracks.search_artists(self.session, s)
|
||||||
self.select_searchtext()
|
# self.ui.matchList.clear()
|
||||||
|
# if matches:
|
||||||
def chars_typed(self, s: str) -> None:
|
# for track in matches:
|
||||||
"""Handle text typed in search box"""
|
# t = QListWidgetItem()
|
||||||
|
# t.setText(
|
||||||
self.ui.matchList.clear()
|
# f"{track.title} - {track.artist} "
|
||||||
if len(s) > 1:
|
# f"[{helpers.ms_to_mmss(track.duration)}] "
|
||||||
if self.ui.radioTitle.isChecked():
|
# f"({helpers.get_relative_date(track.lastplayed)})"
|
||||||
matches = Tracks.search_titles(self.session, s)
|
# )
|
||||||
else:
|
# t.setData(Qt.UserRole, track)
|
||||||
matches = Tracks.search_artists(self.session, s)
|
# self.ui.matchList.addItem(t)
|
||||||
if matches:
|
#
|
||||||
for track in matches:
|
# def double_click(self, entry): # review
|
||||||
last_played = Playdates.last_played(self.session, track.id)
|
# track = entry.data(Qt.UserRole)
|
||||||
t = QListWidgetItem()
|
# self.add_track(track)
|
||||||
t.setText(
|
# # Select search text to make it easier for next search
|
||||||
f"{track.title} - {track.artist} "
|
# self.select_searchtext()
|
||||||
f"[{helpers.ms_to_mmss(track.duration)}] "
|
#
|
||||||
f"({helpers.get_relative_date(last_played)})"
|
# def add_track(self, track): # review
|
||||||
)
|
# # Add to playlist on screen
|
||||||
t.setData(Qt.UserRole, track)
|
# self.parent().visible_playlist_tab().insert_track(
|
||||||
self.ui.matchList.addItem(t)
|
# self.session, track)
|
||||||
|
# # Commit session to get correct row numbers if more tracks added
|
||||||
def double_click(self, entry: QListWidgetItem) -> None:
|
# self.session.commit()
|
||||||
"""Add items that are double-clicked"""
|
# # Select search text to make it easier for next search
|
||||||
|
# self.select_searchtext()
|
||||||
track = entry.data(Qt.UserRole)
|
#
|
||||||
self.add_track(track)
|
# def select_searchtext(self): # review
|
||||||
# Select search text to make it easier for next search
|
# self.ui.searchString.selectAll()
|
||||||
self.select_searchtext()
|
# self.ui.searchString.setFocus()
|
||||||
|
#
|
||||||
def select_searchtext(self) -> None:
|
# def selection_changed(self): # review
|
||||||
"""Select the searchbox"""
|
# if not self.ui.matchList.selectedItems():
|
||||||
|
# return
|
||||||
self.ui.searchString.selectAll()
|
#
|
||||||
self.ui.searchString.setFocus()
|
# item = self.ui.matchList.currentItem()
|
||||||
|
# track = item.data(Qt.UserRole)
|
||||||
def selection_changed(self) -> None:
|
# self.ui.dbPath.setText(track.path)
|
||||||
"""Display selected track path in dialog box"""
|
|
||||||
|
|
||||||
if not self.ui.matchList.selectedItems():
|
|
||||||
return
|
|
||||||
|
|
||||||
item = self.ui.matchList.currentItem()
|
|
||||||
track = item.data(Qt.UserRole)
|
|
||||||
self.ui.dbPath.setText(track.path)
|
|
||||||
|
|
||||||
def title_artist_toggle(self) -> None:
|
|
||||||
"""
|
|
||||||
Handle switching between searching for artists and searching for
|
|
||||||
titles
|
|
||||||
"""
|
|
||||||
|
|
||||||
# Logic is handled already in chars_typed(), so just call that.
|
|
||||||
self.chars_typed(self.ui.searchString.text())
|
|
||||||
|
|
||||||
|
|
||||||
class DownloadCSV(QDialog):
|
class DownloadCSV(QDialog):
|
||||||
|
|||||||
152
app/playlists.py
152
app/playlists.py
@ -17,6 +17,7 @@ from PyQt5.QtWidgets import (
|
|||||||
QAbstractItemDelegate,
|
QAbstractItemDelegate,
|
||||||
QAbstractItemView,
|
QAbstractItemView,
|
||||||
QApplication,
|
QApplication,
|
||||||
|
# QInputDialog,
|
||||||
QLineEdit,
|
QLineEdit,
|
||||||
QMainWindow,
|
QMainWindow,
|
||||||
QMenu,
|
QMenu,
|
||||||
@ -336,6 +337,15 @@ class PlaylistTab(QTableWidget):
|
|||||||
# closeEditor()
|
# closeEditor()
|
||||||
# _cell_edit_ended()
|
# _cell_edit_ended()
|
||||||
|
|
||||||
|
|
||||||
|
# def _edit_note_cell(self, row: int, column: int): # review
|
||||||
|
# """Called when table is single-clicked"""
|
||||||
|
|
||||||
|
# print(f"_edit_note_cell({row=}, {column=}")
|
||||||
|
# # if column in [FIXUP.COL_ROW_NOTES]:
|
||||||
|
# # item = self.item(row, column)
|
||||||
|
# # self.editItem(item)
|
||||||
|
|
||||||
def _cell_changed(self, row: int, column: int) -> None:
|
def _cell_changed(self, row: int, column: int) -> None:
|
||||||
"""Called when cell content has changed"""
|
"""Called when cell content has changed"""
|
||||||
|
|
||||||
@ -477,28 +487,30 @@ class PlaylistTab(QTableWidget):
|
|||||||
|
|
||||||
return [self._get_playlistrow_id(a) for a in self._selected_rows()]
|
return [self._get_playlistrow_id(a) for a in self._selected_rows()]
|
||||||
|
|
||||||
def insert_header(self, session: Session, note: str,
|
#
|
||||||
repaint: bool = True) -> None:
|
# def create_note(self) -> None:
|
||||||
"""
|
# """
|
||||||
Insert section header into playlist tab.
|
# Create note
|
||||||
|
#
|
||||||
If a row is selected, add header above. Otherwise, add to end of
|
# If a row is selected, set note row to be row above. Otherwise,
|
||||||
playlist.
|
# set note row to be end of playlist.
|
||||||
|
# """
|
||||||
We simply build a PlaylistRows object and pass it to insert_row()
|
#
|
||||||
to do the heavy lifing.
|
# row: Optional[int] = self._get_selected_row()
|
||||||
"""
|
# if not row:
|
||||||
|
# row = self.rowCount()
|
||||||
# PlaylistRows object requires a row number, but that number
|
#
|
||||||
# can be reset by calling PlaylistRows.fixup_rownumbers() later,
|
# # Get note text
|
||||||
# so just fudge a row number for now.
|
# dlg: QInputDialog = QInputDialog(self)
|
||||||
row_number = 0
|
# dlg.setInputMode(QInputDialog.TextInput)
|
||||||
plr = PlaylistRows(session, self.playlist_id, None, row_number)
|
# dlg.setLabelText("Note:")
|
||||||
plr.note = note
|
# dlg.resize(500, 100)
|
||||||
self.insert_row(session, plr)
|
# ok: int = dlg.exec()
|
||||||
PlaylistRows.fixup_rownumbers(session, self.playlist_id)
|
# if ok:
|
||||||
if repaint:
|
# with Session() as session:
|
||||||
self.update_display(session)
|
# note: Notes = Notes(
|
||||||
|
# session, self.playlist_id, row, dlg.textValue())
|
||||||
|
# self._insert_note(session, note, row, True) # checked
|
||||||
#
|
#
|
||||||
# def _get_selected_rows(self) -> List[int]:
|
# def _get_selected_rows(self) -> List[int]:
|
||||||
# """Return a sorted list of selected row numbers"""
|
# """Return a sorted list of selected row numbers"""
|
||||||
@ -595,28 +607,80 @@ class PlaylistTab(QTableWidget):
|
|||||||
if repaint:
|
if repaint:
|
||||||
self.save_playlist(session)
|
self.save_playlist(session)
|
||||||
self.update_display(session, clear_selection=False)
|
self.update_display(session, clear_selection=False)
|
||||||
|
#
|
||||||
def insert_track(self, session: Session, track: Tracks,
|
# def insert_track(self, session: Session, track: Tracks,
|
||||||
repaint: bool = True) -> None:
|
# repaint: bool = True) -> None:
|
||||||
"""
|
# """
|
||||||
Insert track into playlist tab.
|
# Insert track into playlist tab.
|
||||||
|
#
|
||||||
If a row is selected, add track above. Otherwise, add to end of
|
# If a row is selected, add track above. Otherwise, add to end of
|
||||||
playlist.
|
# playlist.
|
||||||
|
# """
|
||||||
We simply build a PlaylistRows object and pass it to insert_row()
|
#
|
||||||
to do the heavy lifing.
|
# if self.selectionModel().hasSelection():
|
||||||
"""
|
# row = self.currentRow()
|
||||||
|
# else:
|
||||||
# PlaylistRows object requires a row number, but that number
|
# row = self.rowCount()
|
||||||
# can be reset by calling PlaylistRows.fixup_rownumbers() later,
|
# log.debug(
|
||||||
# so just fudge a row number for now.
|
# f"playlists.insert_track({session=}, {track=}, {repaint=}), "
|
||||||
row_number = 0
|
# f"{row=}"
|
||||||
plr = PlaylistRows(session, self.playlist_id, track.id, row_number)
|
# )
|
||||||
self.insert_row(session, plr)
|
#
|
||||||
PlaylistRows.fixup_rownumbers(session, self.playlist_id)
|
# self.insertRow(row)
|
||||||
if repaint:
|
#
|
||||||
self.update_display(session)
|
# # Put an item in COL_USERDATA for later
|
||||||
|
# item: QTableWidgetItem = QTableWidgetItem()
|
||||||
|
# # Add row metadata
|
||||||
|
# item.setData(self.ROW_FLAGS, 0)
|
||||||
|
# self.setItem(row, FIXUP.COL_USERDATA, item)
|
||||||
|
#
|
||||||
|
# # Add track details to columns
|
||||||
|
# mss_item: QTableWidgetItem = QTableWidgetItem(str(track.start_gap))
|
||||||
|
# if track.start_gap and track.start_gap >= 500:
|
||||||
|
# mss_item.setBackground(QColor(Config.COLOUR_LONG_START))
|
||||||
|
# self.setItem(row, FIXUP.COL_MSS, mss_item)
|
||||||
|
#
|
||||||
|
# title_item: QTableWidgetItem = QTableWidgetItem(track.title)
|
||||||
|
# self.setItem(row, FIXUP.COL_TITLE, title_item)
|
||||||
|
#
|
||||||
|
# artist_item: QTableWidgetItem = QTableWidgetItem(track.artist)
|
||||||
|
# self.setItem(row, FIXUP.COL_ARTIST, artist_item)
|
||||||
|
#
|
||||||
|
# duration_item: QTableWidgetItem = QTableWidgetItem(
|
||||||
|
# ms_to_mmss(track.duration)
|
||||||
|
# )
|
||||||
|
# self._set_row_duration(row, track.duration)
|
||||||
|
# self.setItem(row, FIXUP.COL_DURATION, duration_item)
|
||||||
|
#
|
||||||
|
# last_playtime: Optional[datetime] = Playdates.last_played(
|
||||||
|
# session, track.id)
|
||||||
|
# last_played_str: str = get_relative_date(last_playtime)
|
||||||
|
# last_played_item: QTableWidgetItem = QTableWidgetItem(last_played_str)
|
||||||
|
# self.setItem(row, FIXUP.COL_LAST_PLAYED, last_played_item)
|
||||||
|
#
|
||||||
|
# row_note: Optional[str] = "Play text"
|
||||||
|
# row_note_item: QTableWidgetItem = QTableWidgetItem(row_note)
|
||||||
|
# self.setItem(row, FIXUP.COL_ROW_NOTES, row_note_item)
|
||||||
|
#
|
||||||
|
# # Add empty start and stop time because background
|
||||||
|
# # colour won't be set for columns without items
|
||||||
|
# start_item: QTableWidgetItem = QTableWidgetItem()
|
||||||
|
# self.setItem(row, FIXUP.COL_START_TIME, start_item)
|
||||||
|
# stop_item: QTableWidgetItem = QTableWidgetItem()
|
||||||
|
# self.setItem(row, FIXUP.COL_END_TIME, stop_item)
|
||||||
|
#
|
||||||
|
# # Attach track.id object to row
|
||||||
|
# self._set_row_content(row, track.id)
|
||||||
|
#
|
||||||
|
# # Mark track if file is unreadable
|
||||||
|
# if not file_is_readable(track.path):
|
||||||
|
# self._set_unreadable_row(row)
|
||||||
|
# # Scroll to new row
|
||||||
|
# self.scrollToItem(title_item, QAbstractItemView.PositionAtCenter)
|
||||||
|
#
|
||||||
|
# if repaint:
|
||||||
|
# self.save_playlist(session)
|
||||||
|
# self.update_display(session, clear_selection=False)
|
||||||
#
|
#
|
||||||
# def move_selected_to_playlist(self, session: Session, playlist_id: int) \
|
# def move_selected_to_playlist(self, session: Session, playlist_id: int) \
|
||||||
# -> None:
|
# -> None:
|
||||||
|
|||||||
@ -780,12 +780,12 @@ border: 1px solid rgb(85, 87, 83);</string>
|
|||||||
<addaction name="separator"/>
|
<addaction name="separator"/>
|
||||||
<addaction name="actionSkipToNext"/>
|
<addaction name="actionSkipToNext"/>
|
||||||
<addaction name="separator"/>
|
<addaction name="separator"/>
|
||||||
<addaction name="actionInsertSectionHeader"/>
|
<addaction name="actionInsert"/>
|
||||||
<addaction name="actionInsertTrack"/>
|
|
||||||
<addaction name="actionRemove"/>
|
<addaction name="actionRemove"/>
|
||||||
<addaction name="actionImport"/>
|
<addaction name="actionImport"/>
|
||||||
<addaction name="actionSetNext"/>
|
<addaction name="actionSetNext"/>
|
||||||
<addaction name="action_Clear_selection"/>
|
<addaction name="action_Clear_selection"/>
|
||||||
|
<addaction name="actionInsert_section_header"/>
|
||||||
<addaction name="separator"/>
|
<addaction name="separator"/>
|
||||||
<addaction name="actionSearch"/>
|
<addaction name="actionSearch"/>
|
||||||
<addaction name="actionSelect_next_track"/>
|
<addaction name="actionSelect_next_track"/>
|
||||||
@ -828,7 +828,7 @@ border: 1px solid rgb(85, 87, 83);</string>
|
|||||||
<string>Ctrl+Alt+Return</string>
|
<string>Ctrl+Alt+Return</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
<action name="actionInsertTrack">
|
<action name="actionInsert">
|
||||||
<property name="icon">
|
<property name="icon">
|
||||||
<iconset>
|
<iconset>
|
||||||
<normaloff>../../../../.designer/backup/icon_search_database.png</normaloff>../../../../.designer/backup/icon_search_database.png</iconset>
|
<normaloff>../../../../.designer/backup/icon_search_database.png</normaloff>../../../../.designer/backup/icon_search_database.png</iconset>
|
||||||
@ -837,7 +837,7 @@ border: 1px solid rgb(85, 87, 83);</string>
|
|||||||
<string>Insert &track...</string>
|
<string>Insert &track...</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="shortcut">
|
<property name="shortcut">
|
||||||
<string>Ctrl+T</string>
|
<string>Ctrl+D</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
<action name="actionAdd_file">
|
<action name="actionAdd_file">
|
||||||
@ -1030,13 +1030,10 @@ border: 1px solid rgb(85, 87, 83);</string>
|
|||||||
<string>/</string>
|
<string>/</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
<action name="actionInsertSectionHeader">
|
<action name="actionInsert_section_header">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Insert &section header...</string>
|
<string>Insert &section header...</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="shortcut">
|
|
||||||
<string>Ctrl+H</string>
|
|
||||||
</property>
|
|
||||||
</action>
|
</action>
|
||||||
<action name="actionRemove">
|
<action name="actionRemove">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
|
|||||||
@ -366,11 +366,11 @@ class Ui_MainWindow(object):
|
|||||||
icon4.addPixmap(QtGui.QPixmap(":/icons/next"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
icon4.addPixmap(QtGui.QPixmap(":/icons/next"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||||
self.actionSkipToNext.setIcon(icon4)
|
self.actionSkipToNext.setIcon(icon4)
|
||||||
self.actionSkipToNext.setObjectName("actionSkipToNext")
|
self.actionSkipToNext.setObjectName("actionSkipToNext")
|
||||||
self.actionInsertTrack = QtWidgets.QAction(MainWindow)
|
self.actionInsert = QtWidgets.QAction(MainWindow)
|
||||||
icon5 = QtGui.QIcon()
|
icon5 = QtGui.QIcon()
|
||||||
icon5.addPixmap(QtGui.QPixmap("app/ui/../../../../.designer/backup/icon_search_database.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
icon5.addPixmap(QtGui.QPixmap("app/ui/../../../../.designer/backup/icon_search_database.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||||
self.actionInsertTrack.setIcon(icon5)
|
self.actionInsert.setIcon(icon5)
|
||||||
self.actionInsertTrack.setObjectName("actionInsertTrack")
|
self.actionInsert.setObjectName("actionInsert")
|
||||||
self.actionAdd_file = QtWidgets.QAction(MainWindow)
|
self.actionAdd_file = QtWidgets.QAction(MainWindow)
|
||||||
icon6 = QtGui.QIcon()
|
icon6 = QtGui.QIcon()
|
||||||
icon6.addPixmap(QtGui.QPixmap("app/ui/../../../../.designer/backup/icon_open_file.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
icon6.addPixmap(QtGui.QPixmap("app/ui/../../../../.designer/backup/icon_open_file.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||||
@ -440,8 +440,8 @@ class Ui_MainWindow(object):
|
|||||||
self.actionDownload_CSV_of_played_tracks.setObjectName("actionDownload_CSV_of_played_tracks")
|
self.actionDownload_CSV_of_played_tracks.setObjectName("actionDownload_CSV_of_played_tracks")
|
||||||
self.actionSearch = QtWidgets.QAction(MainWindow)
|
self.actionSearch = QtWidgets.QAction(MainWindow)
|
||||||
self.actionSearch.setObjectName("actionSearch")
|
self.actionSearch.setObjectName("actionSearch")
|
||||||
self.actionInsertSectionHeader = QtWidgets.QAction(MainWindow)
|
self.actionInsert_section_header = QtWidgets.QAction(MainWindow)
|
||||||
self.actionInsertSectionHeader.setObjectName("actionInsertSectionHeader")
|
self.actionInsert_section_header.setObjectName("actionInsert_section_header")
|
||||||
self.actionRemove = QtWidgets.QAction(MainWindow)
|
self.actionRemove = QtWidgets.QAction(MainWindow)
|
||||||
self.actionRemove.setObjectName("actionRemove")
|
self.actionRemove.setObjectName("actionRemove")
|
||||||
self.menuFile.addAction(self.actionNewPlaylist)
|
self.menuFile.addAction(self.actionNewPlaylist)
|
||||||
@ -464,12 +464,12 @@ class Ui_MainWindow(object):
|
|||||||
self.menuPlaylist.addSeparator()
|
self.menuPlaylist.addSeparator()
|
||||||
self.menuPlaylist.addAction(self.actionSkipToNext)
|
self.menuPlaylist.addAction(self.actionSkipToNext)
|
||||||
self.menuPlaylist.addSeparator()
|
self.menuPlaylist.addSeparator()
|
||||||
self.menuPlaylist.addAction(self.actionInsertSectionHeader)
|
self.menuPlaylist.addAction(self.actionInsert)
|
||||||
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.addAction(self.actionSetNext)
|
self.menuPlaylist.addAction(self.actionSetNext)
|
||||||
self.menuPlaylist.addAction(self.action_Clear_selection)
|
self.menuPlaylist.addAction(self.action_Clear_selection)
|
||||||
|
self.menuPlaylist.addAction(self.actionInsert_section_header)
|
||||||
self.menuPlaylist.addSeparator()
|
self.menuPlaylist.addSeparator()
|
||||||
self.menuPlaylist.addAction(self.actionSearch)
|
self.menuPlaylist.addAction(self.actionSearch)
|
||||||
self.menuPlaylist.addAction(self.actionSelect_next_track)
|
self.menuPlaylist.addAction(self.actionSelect_next_track)
|
||||||
@ -518,8 +518,8 @@ class Ui_MainWindow(object):
|
|||||||
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"))
|
||||||
self.actionSkipToNext.setShortcut(_translate("MainWindow", "Ctrl+Alt+Return"))
|
self.actionSkipToNext.setShortcut(_translate("MainWindow", "Ctrl+Alt+Return"))
|
||||||
self.actionInsertTrack.setText(_translate("MainWindow", "Insert &track..."))
|
self.actionInsert.setText(_translate("MainWindow", "Insert &track..."))
|
||||||
self.actionInsertTrack.setShortcut(_translate("MainWindow", "Ctrl+T"))
|
self.actionInsert.setShortcut(_translate("MainWindow", "Ctrl+D"))
|
||||||
self.actionAdd_file.setText(_translate("MainWindow", "Add &file"))
|
self.actionAdd_file.setText(_translate("MainWindow", "Add &file"))
|
||||||
self.actionAdd_file.setShortcut(_translate("MainWindow", "Ctrl+F"))
|
self.actionAdd_file.setShortcut(_translate("MainWindow", "Ctrl+F"))
|
||||||
self.actionFade.setText(_translate("MainWindow", "F&ade"))
|
self.actionFade.setText(_translate("MainWindow", "F&ade"))
|
||||||
@ -557,8 +557,7 @@ class Ui_MainWindow(object):
|
|||||||
self.actionDownload_CSV_of_played_tracks.setText(_translate("MainWindow", "Download CSV of played tracks..."))
|
self.actionDownload_CSV_of_played_tracks.setText(_translate("MainWindow", "Download CSV of played tracks..."))
|
||||||
self.actionSearch.setText(_translate("MainWindow", "Search..."))
|
self.actionSearch.setText(_translate("MainWindow", "Search..."))
|
||||||
self.actionSearch.setShortcut(_translate("MainWindow", "/"))
|
self.actionSearch.setShortcut(_translate("MainWindow", "/"))
|
||||||
self.actionInsertSectionHeader.setText(_translate("MainWindow", "Insert §ion header..."))
|
self.actionInsert_section_header.setText(_translate("MainWindow", "Insert §ion header..."))
|
||||||
self.actionInsertSectionHeader.setShortcut(_translate("MainWindow", "Ctrl+H"))
|
|
||||||
self.actionRemove.setText(_translate("MainWindow", "&Remove track"))
|
self.actionRemove.setText(_translate("MainWindow", "&Remove track"))
|
||||||
from infotabs import InfoTabs
|
from infotabs import InfoTabs
|
||||||
import icons_rc
|
import icons_rc
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user