WIP: query management
This commit is contained in:
parent
985629446a
commit
b4f5d92f5d
@ -23,27 +23,7 @@ from PyQt6.QtWidgets import (
|
||||
# App imports
|
||||
|
||||
|
||||
class Col(Enum):
|
||||
START_GAP = 0
|
||||
TITLE = auto()
|
||||
ARTIST = auto()
|
||||
INTRO = auto()
|
||||
DURATION = auto()
|
||||
START_TIME = auto()
|
||||
END_TIME = auto()
|
||||
LAST_PLAYED = auto()
|
||||
BITRATE = auto()
|
||||
NOTE = auto()
|
||||
|
||||
|
||||
class QueryCol(Enum):
|
||||
TITLE = 0
|
||||
ARTIST = auto()
|
||||
DURATION = auto()
|
||||
LAST_PLAYED = auto()
|
||||
BITRATE = auto()
|
||||
|
||||
|
||||
# Define singleton first as it's needed below
|
||||
def singleton(cls):
|
||||
"""
|
||||
Make a class a Singleton class (see
|
||||
@ -66,22 +46,6 @@ def singleton(cls):
|
||||
return wrapper_singleton
|
||||
|
||||
|
||||
class FileErrors(NamedTuple):
|
||||
path: str
|
||||
error: str
|
||||
|
||||
|
||||
@dataclass
|
||||
class Filter:
|
||||
path_type: str = "contains"
|
||||
path: Optional[str] = None
|
||||
last_played_number: Optional[int] = None
|
||||
last_played_unit: str = "years"
|
||||
duration_type: str = "longer than"
|
||||
duration_number: int = 0
|
||||
duration_unit: str = "minutes"
|
||||
|
||||
|
||||
class ApplicationError(Exception):
|
||||
"""
|
||||
Custom exception
|
||||
@ -96,6 +60,36 @@ class AudioMetadata(NamedTuple):
|
||||
fade_at: int = 0
|
||||
|
||||
|
||||
class Col(Enum):
|
||||
START_GAP = 0
|
||||
TITLE = auto()
|
||||
ARTIST = auto()
|
||||
INTRO = auto()
|
||||
DURATION = auto()
|
||||
START_TIME = auto()
|
||||
END_TIME = auto()
|
||||
LAST_PLAYED = auto()
|
||||
BITRATE = auto()
|
||||
NOTE = auto()
|
||||
|
||||
|
||||
class FileErrors(NamedTuple):
|
||||
path: str
|
||||
error: str
|
||||
|
||||
|
||||
@dataclass
|
||||
class Filter:
|
||||
path_type: str = "contains"
|
||||
path: Optional[str] = None
|
||||
last_played_number: Optional[int] = None
|
||||
last_played_type: str = "before"
|
||||
last_played_unit: str = "years"
|
||||
duration_type: str = "longer than"
|
||||
duration_number: int = 0
|
||||
duration_unit: str = "minutes"
|
||||
|
||||
|
||||
@singleton
|
||||
@dataclass
|
||||
class MusicMusterSignals(QObject):
|
||||
@ -142,6 +136,14 @@ class PlaylistStyle(QProxyStyle):
|
||||
super().drawPrimitive(element, option, painter, widget)
|
||||
|
||||
|
||||
class QueryCol(Enum):
|
||||
TITLE = 0
|
||||
ARTIST = auto()
|
||||
DURATION = auto()
|
||||
LAST_PLAYED = auto()
|
||||
BITRATE = auto()
|
||||
|
||||
|
||||
class Tags(NamedTuple):
|
||||
artist: str = ""
|
||||
title: str = ""
|
||||
|
||||
@ -6,6 +6,8 @@ menus:
|
||||
- text: "Manage Templates"
|
||||
handler: "manage_templates"
|
||||
- separator: true
|
||||
- text: "Manage Queries"
|
||||
handler: "manage_queries"
|
||||
- separator: true
|
||||
- text: "Exit"
|
||||
handler: "close"
|
||||
|
||||
@ -221,14 +221,6 @@ class Playlists(dbtables.PlaylistsTable):
|
||||
self.open = False
|
||||
session.commit()
|
||||
|
||||
def delete(self, session: Session) -> None:
|
||||
"""
|
||||
Delete playlist
|
||||
"""
|
||||
|
||||
session.execute(delete(Playlists).where(Playlists.id == self.id))
|
||||
session.commit()
|
||||
|
||||
@classmethod
|
||||
def get_all(cls, session: Session) -> Sequence["Playlists"]:
|
||||
"""Returns a list of all playlists ordered by last use"""
|
||||
@ -253,10 +245,7 @@ class Playlists(dbtables.PlaylistsTable):
|
||||
|
||||
return session.scalars(
|
||||
select(cls)
|
||||
.where(
|
||||
cls.is_template.is_(True),
|
||||
cls.favourite.is_(True)
|
||||
)
|
||||
.where(cls.is_template.is_(True), cls.favourite.is_(True))
|
||||
.order_by(cls.name)
|
||||
).all()
|
||||
|
||||
|
||||
@ -46,6 +46,7 @@ from PyQt6.QtWidgets import (
|
||||
QMenu,
|
||||
QMessageBox,
|
||||
QPushButton,
|
||||
QSpinBox,
|
||||
QTableWidget,
|
||||
QTableWidgetItem,
|
||||
QVBoxLayout,
|
||||
@ -60,6 +61,7 @@ import stackprinter # type: ignore
|
||||
# App imports
|
||||
from classes import (
|
||||
ApplicationError,
|
||||
Filter,
|
||||
MusicMusterSignals,
|
||||
TrackInfo,
|
||||
)
|
||||
@ -68,7 +70,7 @@ from dialogs import TrackSelectDialog
|
||||
from file_importer import FileImporter
|
||||
from helpers import file_is_unreadable
|
||||
from log import log
|
||||
from models import db, Playdates, PlaylistRows, Playlists, Settings, Tracks
|
||||
from models import db, Playdates, PlaylistRows, Playlists, Queries, Settings, Tracks
|
||||
from music_manager import RowAndTrack, track_sequence
|
||||
from playlistmodel import PlaylistModel, PlaylistProxyModel
|
||||
from playlists import PlaylistTab
|
||||
@ -166,6 +168,126 @@ class EditDeleteDialog(QDialog):
|
||||
self.reject()
|
||||
|
||||
|
||||
class FilterDialog(QDialog):
|
||||
def __init__(self, name: str, filter: Filter) -> None:
|
||||
super().__init__()
|
||||
self.filter = filter
|
||||
|
||||
self.setWindowTitle("Filter Settings")
|
||||
|
||||
layout = QVBoxLayout()
|
||||
|
||||
# Name row
|
||||
name_layout = QHBoxLayout()
|
||||
name_label = QLabel("Name")
|
||||
self.name_text = QLineEdit()
|
||||
self.name_text.setText(name)
|
||||
name_layout.addWidget(name_label)
|
||||
name_layout.addWidget(self.name_text)
|
||||
layout.addLayout(name_layout)
|
||||
|
||||
# Path row
|
||||
path_layout = QHBoxLayout()
|
||||
path_label = QLabel("Path")
|
||||
self.path_combo = QComboBox()
|
||||
self.path_combo.addItems(["contains", "excluding"])
|
||||
for idx in range(self.path_combo.count()):
|
||||
if self.path_combo.itemText(idx) == filter.path_type:
|
||||
self.path_combo.setCurrentIndex(idx)
|
||||
break
|
||||
self.path_text = QLineEdit()
|
||||
if filter.path:
|
||||
self.path_text.setText(filter.path)
|
||||
path_layout.addWidget(path_label)
|
||||
path_layout.addWidget(self.path_combo)
|
||||
path_layout.addWidget(self.path_text)
|
||||
layout.addLayout(path_layout)
|
||||
|
||||
# Last played row
|
||||
last_played_layout = QHBoxLayout()
|
||||
last_played_label = QLabel("Last played")
|
||||
self.last_played_combo = QComboBox()
|
||||
self.last_played_combo.addItems(["before", "never"])
|
||||
for idx in range(self.last_played_combo.count()):
|
||||
if self.last_played_combo.itemText(idx) == filter.last_played_type:
|
||||
self.last_played_combo.setCurrentIndex(idx)
|
||||
break
|
||||
|
||||
self.last_played_spinbox = QSpinBox()
|
||||
self.last_played_spinbox.setMinimum(0)
|
||||
self.last_played_spinbox.setMaximum(100)
|
||||
self.last_played_spinbox.setValue(filter.last_played_number or 0)
|
||||
|
||||
self.last_played_unit = QComboBox()
|
||||
self.last_played_unit.addItems(["years", "months", "weeks", "days"])
|
||||
for idx in range(self.last_played_unit.count()):
|
||||
if self.last_played_unit.itemText(idx) == filter.last_played_unit:
|
||||
self.last_played_unit.setCurrentIndex(idx)
|
||||
break
|
||||
|
||||
last_played_ago_label = QLabel("ago")
|
||||
|
||||
last_played_layout.addWidget(last_played_label)
|
||||
last_played_layout.addWidget(self.last_played_combo)
|
||||
last_played_layout.addWidget(self.last_played_spinbox)
|
||||
last_played_layout.addWidget(self.last_played_unit)
|
||||
last_played_layout.addWidget(last_played_ago_label)
|
||||
|
||||
layout.addLayout(last_played_layout)
|
||||
|
||||
# Duration row
|
||||
duration_layout = QHBoxLayout()
|
||||
duration_label = QLabel("Duration")
|
||||
self.duration_combo = QComboBox()
|
||||
self.duration_combo.addItems(["longer than", "shorter than"])
|
||||
for idx in range(self.duration_combo.count()):
|
||||
if self.duration_combo.itemText(idx) == filter.duration_type:
|
||||
self.duration_combo.setCurrentIndex(idx)
|
||||
break
|
||||
|
||||
self.duration_spinbox = QSpinBox()
|
||||
self.duration_spinbox.setMinimum(0)
|
||||
self.duration_spinbox.setMaximum(1000)
|
||||
self.duration_spinbox.setValue(filter.duration_number)
|
||||
|
||||
self.duration_unit = QComboBox()
|
||||
self.duration_unit.addItems(["minutes", "seconds"])
|
||||
self.duration_unit.setCurrentText("minutes")
|
||||
for idx in range(self.duration_unit.count()):
|
||||
if self.duration_unit.itemText(idx) == filter.duration_unit:
|
||||
self.duration_unit.setCurrentIndex(idx)
|
||||
break
|
||||
|
||||
duration_layout.addWidget(duration_label)
|
||||
duration_layout.addWidget(self.duration_combo)
|
||||
duration_layout.addWidget(self.duration_spinbox)
|
||||
duration_layout.addWidget(self.duration_unit)
|
||||
|
||||
layout.addLayout(duration_layout)
|
||||
|
||||
# Buttons
|
||||
button_layout = QHBoxLayout()
|
||||
self.ok_button = QPushButton("OK")
|
||||
self.cancel_button = QPushButton("Cancel")
|
||||
self.cancel_button.clicked.connect(self.reject)
|
||||
self.ok_button.clicked.connect(self.accept)
|
||||
button_layout.addWidget(self.ok_button)
|
||||
button_layout.addWidget(self.cancel_button)
|
||||
layout.addLayout(button_layout)
|
||||
|
||||
self.setLayout(layout)
|
||||
|
||||
# Connect signals
|
||||
self.last_played_combo.currentIndexChanged.connect(self.toggle_last_played_controls)
|
||||
|
||||
self.toggle_last_played_controls()
|
||||
|
||||
def toggle_last_played_controls(self):
|
||||
disabled = self.last_played_combo.currentText() == "never"
|
||||
self.last_played_spinbox.setDisabled(disabled)
|
||||
self.last_played_unit.setDisabled(disabled)
|
||||
|
||||
|
||||
@dataclass
|
||||
class ItemlistItem:
|
||||
id: int
|
||||
@ -724,6 +846,10 @@ class Window(QMainWindow):
|
||||
# Dynamically call the correct function
|
||||
items = getattr(self, f"get_{key}_items")()
|
||||
for item in items:
|
||||
# Check for separator
|
||||
if "separator" in item and item["separator"] == "separator":
|
||||
submenu.addSeparator()
|
||||
continue
|
||||
action = QAction(item["text"], self)
|
||||
|
||||
# Extract handler and arguments
|
||||
@ -751,10 +877,14 @@ class Window(QMainWindow):
|
||||
|
||||
with db.Session() as session:
|
||||
submenu_items: list[dict[str, str | tuple[Session, int]]] = [
|
||||
{"text": "Show all",
|
||||
"handler": "create_playlist_from_template",
|
||||
"args": (session, 0)
|
||||
}
|
||||
{
|
||||
"text": "Show all",
|
||||
"handler": "create_playlist_from_template",
|
||||
"args": (session, 0),
|
||||
},
|
||||
{
|
||||
"separator": "separator",
|
||||
}
|
||||
]
|
||||
templates = Playlists.get_favourite_templates(session)
|
||||
for template in templates:
|
||||
@ -835,7 +965,7 @@ class Window(QMainWindow):
|
||||
else:
|
||||
template_id = selected_template_id
|
||||
|
||||
playlist_name = self.solicit_playlist_name(session)
|
||||
playlist_name = self.solicit_name(session)
|
||||
if not playlist_name:
|
||||
return
|
||||
|
||||
@ -857,7 +987,7 @@ class Window(QMainWindow):
|
||||
f"Delete playlist '{playlist.name}': " "Are you sure?",
|
||||
):
|
||||
if self.close_playlist_tab():
|
||||
playlist.delete(session)
|
||||
session.delete(playlist)
|
||||
session.commit()
|
||||
else:
|
||||
log.error("Failed to retrieve playlist")
|
||||
@ -900,7 +1030,7 @@ class Window(QMainWindow):
|
||||
session.commit()
|
||||
helpers.show_OK("Template", "Template saved", self)
|
||||
|
||||
def solicit_playlist_name(
|
||||
def solicit_name(
|
||||
self, session: Session, default: str = "", prompt: str = "Playlist name:"
|
||||
) -> Optional[str]:
|
||||
"""Get name of new playlist from user"""
|
||||
@ -948,6 +1078,216 @@ class Window(QMainWindow):
|
||||
|
||||
return dlg.selected_id
|
||||
|
||||
# # # # # # # # # # Manage templates and queries # # # # # # # # # #
|
||||
|
||||
def manage_queries(self) -> None:
|
||||
"""
|
||||
Delete / edit queries
|
||||
"""
|
||||
|
||||
# Define callbacks to handle management options
|
||||
def delete(query_id: int) -> None:
|
||||
"""delete query"""
|
||||
|
||||
query = session.get(Queries, query_id)
|
||||
if not query:
|
||||
raise ApplicationError(
|
||||
f"manage_template.delete({query_id=}) can't load query"
|
||||
)
|
||||
if helpers.ask_yes_no(
|
||||
"Delete query",
|
||||
f"Delete query '{query.name}': " "Are you sure?",
|
||||
):
|
||||
log.info(f"manage_queries: delete {query=}")
|
||||
session.delete(query)
|
||||
session.commit()
|
||||
|
||||
def edit(query_id: int) -> None:
|
||||
"""Edit query"""
|
||||
|
||||
query = session.get(Queries, query_id)
|
||||
if not query:
|
||||
raise ApplicationError(
|
||||
f"manage_template.edit({query_id=}) can't load query"
|
||||
)
|
||||
import pdb; pdb.set_trace()
|
||||
dlg = FilterDialog(query.name, query.filter)
|
||||
dlg.show()
|
||||
|
||||
def favourite(query_id: int, favourite: bool) -> None:
|
||||
"""Mark query as (not) favourite"""
|
||||
|
||||
query = session.get(Queries, query_id)
|
||||
query.favourite = favourite
|
||||
session.commit()
|
||||
|
||||
def new_item() -> None:
|
||||
"""Create new query"""
|
||||
|
||||
# TODO: create query
|
||||
print("create query")
|
||||
|
||||
def rename(query_id: int) -> Optional[str]:
|
||||
"""rename query"""
|
||||
|
||||
query = session.get(Queries, query_id)
|
||||
if not query:
|
||||
raise ApplicationError(
|
||||
f"manage_template.delete({query_id=}) can't load query"
|
||||
)
|
||||
new_name = self.solicit_name(session, query.name, prompt="New query name")
|
||||
if new_name:
|
||||
query.rename(session, new_name)
|
||||
idx = self.tabBar.currentIndex()
|
||||
self.tabBar.setTabText(idx, new_name)
|
||||
session.commit()
|
||||
return new_name
|
||||
|
||||
return None
|
||||
|
||||
# Call listitem management dialog to manage queries
|
||||
callbacks = ItemlistManagerCallbacks(
|
||||
delete=delete,
|
||||
edit=edit,
|
||||
favourite=favourite,
|
||||
new_item=new_item,
|
||||
rename=rename,
|
||||
)
|
||||
|
||||
# Build a list of queries
|
||||
query_list: list[ItemlistItem] = []
|
||||
|
||||
with db.Session() as session:
|
||||
for query in Queries.get_all_queries(session):
|
||||
query_list.append(
|
||||
ItemlistItem(
|
||||
name=query.name, id=query.id, favourite=query.favourite
|
||||
)
|
||||
)
|
||||
# We need to retain a reference to the dialog box to stop it
|
||||
# going out of scope and being garbage-collected.
|
||||
self.dlg = ItemlistManager(query_list, callbacks)
|
||||
self.dlg.show()
|
||||
|
||||
def manage_templates(self) -> None:
|
||||
"""
|
||||
Delete / edit templates
|
||||
"""
|
||||
|
||||
# Define callbacks to handle management options
|
||||
def delete(template_id: int) -> None:
|
||||
"""delete template"""
|
||||
|
||||
template = session.get(Playlists, template_id)
|
||||
if not template:
|
||||
raise ApplicationError(
|
||||
f"manage_template.delete({template_id=}) can't load template"
|
||||
)
|
||||
if helpers.ask_yes_no(
|
||||
"Delete template",
|
||||
f"Delete template '{template.name}': " "Are you sure?",
|
||||
):
|
||||
# If template is currently open, re-check
|
||||
open_idx = self.get_tab_index_for_playlist(template_id)
|
||||
if open_idx:
|
||||
if not helpers.ask_yes_no(
|
||||
"Delete open template",
|
||||
f"Template '{template.name}' is currently open. Really delete?",
|
||||
):
|
||||
return
|
||||
else:
|
||||
self.playlist_section.tabPlaylist.removeTab(open_idx)
|
||||
|
||||
log.info(f"manage_templates: delete {template=}")
|
||||
session.delete(template)
|
||||
session.commit()
|
||||
|
||||
def edit(template_id: int) -> None:
|
||||
"""Edit template"""
|
||||
|
||||
template = session.get(Playlists, template_id)
|
||||
if not template:
|
||||
raise ApplicationError(
|
||||
f"manage_template.edit({template_id=}) can't load template"
|
||||
)
|
||||
# Simply load the template as a playlist. Any changes
|
||||
# made will persist
|
||||
self._open_playlist(template, is_template=True)
|
||||
|
||||
def favourite(template_id: int, favourite: bool) -> None:
|
||||
"""Mark template as (not) favourite"""
|
||||
|
||||
template = session.get(Playlists, template_id)
|
||||
template.favourite = favourite
|
||||
session.commit()
|
||||
|
||||
def new_item() -> None:
|
||||
"""Create new template"""
|
||||
|
||||
# Get base template
|
||||
template_id = self.solicit_template_to_use(
|
||||
session, template_prompt="New template based upon:"
|
||||
)
|
||||
if template_id is None:
|
||||
return
|
||||
|
||||
# Get new template name
|
||||
name = self.solicit_name(
|
||||
session, default="", prompt="New template name:"
|
||||
)
|
||||
if not name:
|
||||
return
|
||||
|
||||
# Create playlist for template and mark is as a template
|
||||
template = self._create_playlist(session, name, template_id)
|
||||
template.is_template = True
|
||||
session.commit()
|
||||
|
||||
# Open it for editing
|
||||
self._open_playlist(template, is_template=True)
|
||||
|
||||
def rename(template_id: int) -> Optional[str]:
|
||||
"""rename template"""
|
||||
|
||||
template = session.get(Playlists, template_id)
|
||||
if not template:
|
||||
raise ApplicationError(
|
||||
f"manage_template.delete({template_id=}) can't load template"
|
||||
)
|
||||
new_name = self.solicit_name(session, template.name)
|
||||
if new_name:
|
||||
template.rename(session, new_name)
|
||||
idx = self.tabBar.currentIndex()
|
||||
self.tabBar.setTabText(idx, new_name)
|
||||
session.commit()
|
||||
return new_name
|
||||
|
||||
return None
|
||||
|
||||
# Call listitem management dialog to manage templates
|
||||
callbacks = ItemlistManagerCallbacks(
|
||||
delete=delete,
|
||||
edit=edit,
|
||||
favourite=favourite,
|
||||
new_item=new_item,
|
||||
rename=rename,
|
||||
)
|
||||
|
||||
# Build a list of templates
|
||||
template_list: list[ItemlistItem] = []
|
||||
|
||||
with db.Session() as session:
|
||||
for template in Playlists.get_all_templates(session):
|
||||
template_list.append(
|
||||
ItemlistItem(
|
||||
name=template.name, id=template.id, favourite=template.favourite
|
||||
)
|
||||
)
|
||||
# We need to retain a reference to the dialog box to stop it
|
||||
# going out of scope and being garbage-collected.
|
||||
self.dlg = ItemlistManager(template_list, callbacks)
|
||||
self.dlg.show()
|
||||
|
||||
# # # # # # # # # # Miscellaneous functions # # # # # # # # # #
|
||||
|
||||
def select_duplicate_rows(self) -> None:
|
||||
@ -1341,125 +1681,6 @@ class Window(QMainWindow):
|
||||
|
||||
self.signals.search_wikipedia_signal.emit(track_info.title)
|
||||
|
||||
def manage_templates(self) -> None:
|
||||
"""
|
||||
Delete / edit templates
|
||||
"""
|
||||
|
||||
# Define callbacks to handle management options
|
||||
def delete(template_id: int) -> None:
|
||||
"""delete template"""
|
||||
|
||||
template = session.get(Playlists, template_id)
|
||||
if not template:
|
||||
raise ApplicationError(
|
||||
f"manage_templeate.delete({template_id=}) can't load template"
|
||||
)
|
||||
if helpers.ask_yes_no(
|
||||
"Delete template",
|
||||
f"Delete template '{template.name}': " "Are you sure?",
|
||||
):
|
||||
# If template is currently open, re-check
|
||||
open_idx = self.get_tab_index_for_playlist(template_id)
|
||||
if open_idx:
|
||||
if not helpers.ask_yes_no(
|
||||
"Delete open template",
|
||||
f"Template '{template.name}' is currently open. Really delete?",
|
||||
):
|
||||
return
|
||||
else:
|
||||
self.playlist_section.tabPlaylist.removeTab(open_idx)
|
||||
|
||||
log.info(f"manage_templates: delete {template=}")
|
||||
template.delete(session)
|
||||
session.commit()
|
||||
|
||||
def edit(template_id: int) -> None:
|
||||
"""Edit template"""
|
||||
|
||||
template = session.get(Playlists, template_id)
|
||||
if not template:
|
||||
raise ApplicationError(
|
||||
f"manage_templeate.edit({template_id=}) can't load template"
|
||||
)
|
||||
# Simply load the template as a playlist. Any changes
|
||||
# made will persist
|
||||
self._open_playlist(template, is_template=True)
|
||||
|
||||
def favourite(template_id: int, favourite: bool) -> None:
|
||||
"""Mark template as (not) favourite"""
|
||||
|
||||
template = session.get(Playlists, template_id)
|
||||
template.favourite = favourite
|
||||
session.commit()
|
||||
|
||||
def new_item() -> None:
|
||||
"""Create new template"""
|
||||
|
||||
# Get base template
|
||||
template_id = self.solicit_template_to_use(
|
||||
session, template_prompt="New template based upon:"
|
||||
)
|
||||
if template_id is None:
|
||||
return
|
||||
|
||||
# Get new template name
|
||||
name = self.solicit_playlist_name(
|
||||
session, default="", prompt="New template name:"
|
||||
)
|
||||
if not name:
|
||||
return
|
||||
|
||||
# Create playlist for template and mark is as a template
|
||||
template = self._create_playlist(session, name, template_id)
|
||||
template.is_template = True
|
||||
session.commit()
|
||||
|
||||
# Open it for editing
|
||||
self._open_playlist(template, is_template=True)
|
||||
|
||||
def rename(template_id: int) -> Optional[str]:
|
||||
"""rename template"""
|
||||
|
||||
template = session.get(Playlists, template_id)
|
||||
if not template:
|
||||
raise ApplicationError(
|
||||
f"manage_templeate.delete({template_id=}) can't load template"
|
||||
)
|
||||
new_name = self.solicit_playlist_name(session, template.name)
|
||||
if new_name:
|
||||
template.rename(session, new_name)
|
||||
idx = self.tabBar.currentIndex()
|
||||
self.tabBar.setTabText(idx, new_name)
|
||||
session.commit()
|
||||
return new_name
|
||||
|
||||
return None
|
||||
|
||||
# Call listitem management dialog to manage templates
|
||||
callbacks = ItemlistManagerCallbacks(
|
||||
delete=delete,
|
||||
edit=edit,
|
||||
favourite=favourite,
|
||||
new_item=new_item,
|
||||
rename=rename,
|
||||
)
|
||||
|
||||
# Build a list of templates
|
||||
template_list: list[ItemlistItem] = []
|
||||
|
||||
with db.Session() as session:
|
||||
for template in Playlists.get_all_templates(session):
|
||||
template_list.append(
|
||||
ItemlistItem(
|
||||
name=template.name, id=template.id, favourite=template.favourite
|
||||
)
|
||||
)
|
||||
# We need to retain a reference to the dialog box to stop it
|
||||
# going out of scope and being garbage-collected.
|
||||
self.dlg = ItemlistManager(template_list, callbacks)
|
||||
self.dlg.show()
|
||||
|
||||
def mark_rows_for_moving(self) -> None:
|
||||
"""
|
||||
Cut rows ready for pasting.
|
||||
@ -1778,7 +1999,7 @@ class Window(QMainWindow):
|
||||
playlist_id = self.current.playlist_id
|
||||
playlist = session.get(Playlists, playlist_id)
|
||||
if playlist:
|
||||
new_name = self.solicit_playlist_name(session, playlist.name)
|
||||
new_name = self.solicit_name(session, playlist.name)
|
||||
if new_name:
|
||||
playlist.rename(session, new_name)
|
||||
idx = self.tabBar.currentIndex()
|
||||
@ -2199,7 +2420,12 @@ class Window(QMainWindow):
|
||||
self.playlist_section.tabPlaylist.setTabIcon(
|
||||
idx, QIcon(Config.PLAYLIST_ICON_CURRENT)
|
||||
)
|
||||
elif self.playlist_section.tabPlaylist.widget(idx).model().sourceModel().is_template:
|
||||
elif (
|
||||
self.playlist_section.tabPlaylist.widget(idx)
|
||||
.model()
|
||||
.sourceModel()
|
||||
.is_template
|
||||
):
|
||||
self.playlist_section.tabPlaylist.setTabIcon(
|
||||
idx, QIcon(Config.PLAYLIST_ICON_TEMPLATE)
|
||||
)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user