WIP V3: ready for testing
This commit is contained in:
parent
00d7258afd
commit
4eabf4a02a
@ -868,7 +868,7 @@ class Window(QMainWindow, Ui_MainWindow):
|
||||
dlg = TrackSelectDialog(
|
||||
session=session,
|
||||
new_row_number=self.active_tab().selected_model_row_number(),
|
||||
model=self.active_model()
|
||||
model=self.active_model(),
|
||||
)
|
||||
dlg.exec()
|
||||
|
||||
@ -1067,12 +1067,6 @@ class Window(QMainWindow, Ui_MainWindow):
|
||||
# Clear next track
|
||||
self.clear_next()
|
||||
|
||||
# Set current track playlist_tab colour
|
||||
# TODO Reimplement without reference to self.current_track.playlist_tab
|
||||
# current_tab = self.current_track.playlist_tab
|
||||
# if current_tab:
|
||||
# self.set_tab_colour(current_tab, QColor(Config.COLOUR_CURRENT_TAB))
|
||||
|
||||
# Restore volume if -3dB active
|
||||
if self.btnDrop3db.isChecked():
|
||||
self.btnDrop3db.setChecked(False)
|
||||
@ -1422,85 +1416,6 @@ class Window(QMainWindow, Ui_MainWindow):
|
||||
# Enable controls
|
||||
self.enable_play_next_controls()
|
||||
|
||||
def set_next_plr_id(
|
||||
self, next_plr_id: Optional[int], playlist_tab: PlaylistTab
|
||||
) -> None:
|
||||
"""
|
||||
Set passed plr_id as next track to play, or clear next track if None
|
||||
|
||||
Actions required:
|
||||
- Update playing_track
|
||||
- Tell playlist tabs to update their 'next track' highlighting
|
||||
- Update headers
|
||||
- Set playlist tab colours
|
||||
- Populate ‘info’ tabs
|
||||
"""
|
||||
|
||||
return
|
||||
# with Session() as session:
|
||||
# # Update self.next_track PlaylistTrack structure
|
||||
# self.next_track = NextTrack()
|
||||
# if next_plr_id:
|
||||
# next_plr = session.get(PlaylistRows, next_plr_id)
|
||||
# if next_plr:
|
||||
# self.next_track.set_plr(session, next_plr)
|
||||
# self.signals.set_next_track_signal.emit(next_plr.playlist_id)
|
||||
|
||||
# # Update headers
|
||||
# self.update_headers()
|
||||
|
||||
# TODO: reimlement
|
||||
# # Set playlist tab colours
|
||||
# self._set_next_track_playlist_tab_colours(old_next_track)
|
||||
|
||||
# if next_plr_id:
|
||||
# # Populate 'info' tabs with Wikipedia info, but queue it
|
||||
# # because it isn't quick
|
||||
# if self.next_track.title:
|
||||
# QTimer.singleShot(
|
||||
# 0,
|
||||
# lambda: self.tabInfolist.open_in_wikipedia(
|
||||
# self.next_track.title
|
||||
# ),
|
||||
# )
|
||||
|
||||
def _set_next_track_playlist_tab_colours(
|
||||
self, old_next_track: Optional[PlaylistTrack]
|
||||
) -> None:
|
||||
"""
|
||||
Set playlist tab colour for next track. self.next_track needs
|
||||
to be set before calling.
|
||||
"""
|
||||
|
||||
# If the original next playlist tab isn't the same as the
|
||||
# new one or the current track, it needs its colour reset.
|
||||
return
|
||||
# TODO Reimplement
|
||||
# if (
|
||||
# old_next_track
|
||||
# and old_next_track.playlist_tab
|
||||
# and old_next_track.playlist_tab
|
||||
# not in [self.next_track.playlist_tab, self.current_track.playlist_tab]
|
||||
# ):
|
||||
# self.set_tab_colour(
|
||||
# old_next_track.playlist_tab, QColor(Config.COLOUR_NORMAL_TAB)
|
||||
# )
|
||||
# # If the new next playlist tab isn't the same as the
|
||||
# # old one or the current track, it needs its colour set.
|
||||
# if old_next_track:
|
||||
# old_tab = old_next_track.playlist_tab
|
||||
# else:
|
||||
# old_tab = None
|
||||
# if (
|
||||
# self.next_track
|
||||
# and self.next_track.playlist_tab
|
||||
# and self.next_track.playlist_tab
|
||||
# not in [old_tab, self.current_track.playlist_tab]
|
||||
# ):
|
||||
# self.set_tab_colour(
|
||||
# self.next_track.playlist_tab, QColor(Config.COLOUR_NEXT_TAB)
|
||||
# )
|
||||
|
||||
def tick_10ms(self) -> None:
|
||||
"""
|
||||
Called every 10ms
|
||||
|
||||
@ -5,7 +5,7 @@ from datetime import datetime, timedelta
|
||||
from enum import auto, Enum
|
||||
from operator import attrgetter
|
||||
from pprint import pprint
|
||||
from typing import cast, List, Optional
|
||||
from typing import List, Optional
|
||||
|
||||
from PyQt6.QtCore import (
|
||||
QAbstractTableModel,
|
||||
@ -144,10 +144,7 @@ class PlaylistModel(QAbstractTableModel):
|
||||
)
|
||||
|
||||
def add_track_to_header(
|
||||
self,
|
||||
row_number: int,
|
||||
track_id: int,
|
||||
note: Optional[str] = None
|
||||
self, row_number: int, track_id: int, note: Optional[str] = None
|
||||
) -> None:
|
||||
"""
|
||||
Add track to existing header row
|
||||
@ -934,7 +931,7 @@ class PlaylistModel(QAbstractTableModel):
|
||||
except obs.error.OBSSDKError as e:
|
||||
log.error(f"OBS SDK error ({e})")
|
||||
return
|
||||
|
||||
|
||||
def open_in_audacity(self, row_number: int) -> None:
|
||||
"""
|
||||
Open track at passed row number in Audacity
|
||||
@ -1423,12 +1420,16 @@ class PlaylistProxyModel(QSortFilterProxyModel):
|
||||
def move_track_add_note(
|
||||
self, new_row_number: int, existing_prd: PlaylistRowData, note: str
|
||||
) -> None:
|
||||
return self.playlist_model.move_track_add_note(new_row_number, existing_prd, note)
|
||||
return self.playlist_model.move_track_add_note(
|
||||
new_row_number, existing_prd, note
|
||||
)
|
||||
|
||||
def move_track_to_header(
|
||||
self, header_row_number: int, existing_prd: PlaylistRowData, note: Optional[str]
|
||||
) -> None:
|
||||
return self.playlist_model.move_track_to_header(header_row_number, existing_prd)
|
||||
return self.playlist_model.move_track_to_header(
|
||||
header_row_number, existing_prd, note
|
||||
)
|
||||
|
||||
def open_in_audacity(self, row_number: int) -> None:
|
||||
return self.playlist_model.open_in_audacity(row_number)
|
||||
|
||||
370
app/playlists.py
370
app/playlists.py
@ -1,8 +1,3 @@
|
||||
import subprocess
|
||||
|
||||
import obsws_python as obs # type: ignore
|
||||
|
||||
from datetime import datetime, timedelta
|
||||
from pprint import pprint
|
||||
from typing import Callable, cast, List, Optional, TYPE_CHECKING
|
||||
|
||||
@ -11,11 +6,9 @@ from PyQt6.QtCore import (
|
||||
QModelIndex,
|
||||
QObject,
|
||||
QItemSelection,
|
||||
QItemSelectionModel,
|
||||
Qt,
|
||||
# QTimer,
|
||||
)
|
||||
from PyQt6.QtGui import QAction, QDropEvent, QKeyEvent
|
||||
from PyQt6.QtGui import QAction, QKeyEvent
|
||||
from PyQt6.QtWidgets import (
|
||||
QAbstractItemDelegate,
|
||||
QAbstractItemView,
|
||||
@ -34,29 +27,21 @@ from PyQt6.QtWidgets import (
|
||||
QStyleOption,
|
||||
)
|
||||
|
||||
from dbconfig import Session, scoped_session
|
||||
from dbconfig import Session
|
||||
from dialogs import TrackSelectDialog
|
||||
from classes import MusicMusterSignals, track_sequence
|
||||
from config import Config
|
||||
from helpers import (
|
||||
ask_yes_no,
|
||||
file_is_unreadable,
|
||||
get_relative_date,
|
||||
ms_to_mmss,
|
||||
open_in_audacity,
|
||||
send_mail,
|
||||
set_track_metadata,
|
||||
show_warning,
|
||||
)
|
||||
from log import log
|
||||
from models import PlaylistRows, Settings, Tracks, NoteColours
|
||||
from models import Settings
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from musicmuster import Window
|
||||
from playlistmodel import PlaylistModel, PlaylistProxyModel
|
||||
|
||||
# HEADER_NOTES_COLUMN = 2
|
||||
|
||||
|
||||
class EscapeDelegate(QStyledItemDelegate):
|
||||
"""
|
||||
@ -180,7 +165,6 @@ class PlaylistTab(QTableView):
|
||||
self.proxy_model = PlaylistProxyModel(self.playlist_model)
|
||||
self.setItemDelegate(EscapeDelegate(self, self.playlist_model))
|
||||
self.setAlternatingRowColors(True)
|
||||
# self.setEditTriggers(QAbstractItemView.EditTrigger.DoubleClicked)
|
||||
self.setVerticalScrollMode(QAbstractItemView.ScrollMode.ScrollPerPixel)
|
||||
self.setDragDropMode(QAbstractItemView.DragDropMode.InternalMove)
|
||||
self.setDragDropOverwriteMode(False)
|
||||
@ -205,13 +189,9 @@ class PlaylistTab(QTableView):
|
||||
self.signals = MusicMusterSignals()
|
||||
self.signals.span_cells_signal.connect(self._span_cells)
|
||||
|
||||
# Call self.eventFilter() for events
|
||||
# self.installEventFilter(self)
|
||||
|
||||
# Initialise miscellaneous instance variables
|
||||
self.search_text: str = ""
|
||||
self.sort_undo: List[int] = []
|
||||
# self.edit_cell_type: Optional[int]
|
||||
|
||||
# Selection model
|
||||
self.setSelectionMode(QAbstractItemView.SelectionMode.ExtendedSelection)
|
||||
@ -358,7 +338,7 @@ class PlaylistTab(QTableView):
|
||||
return self.proxy_model.mapToSource(selected_index).row()
|
||||
return selected_index.row()
|
||||
|
||||
def selected_model_row_numbers(self) -> Optional[List[int]]:
|
||||
def selected_model_row_numbers(self) -> List[int]:
|
||||
"""
|
||||
Return a list of model row numbers corresponding to the selected rows or
|
||||
an empty list.
|
||||
@ -366,7 +346,7 @@ class PlaylistTab(QTableView):
|
||||
|
||||
selected_indexes = self._selected_row_indexes()
|
||||
if selected_indexes is None:
|
||||
return None
|
||||
return []
|
||||
if hasattr(self.proxy_model, "mapToSource"):
|
||||
return [self.proxy_model.mapToSource(a).row() for a in selected_indexes]
|
||||
return [a.row() for a in selected_indexes]
|
||||
@ -407,137 +387,6 @@ class PlaylistTab(QTableView):
|
||||
return ""
|
||||
return self.playlist_model.get_row_track_path(model_row_number)
|
||||
|
||||
# def lookup_row_in_songfacts(self) -> None:
|
||||
# """
|
||||
# If there is a selected row and it is a track row,
|
||||
# look up its title in songfacts.
|
||||
|
||||
# If multiple rows are selected, only consider the first one.
|
||||
|
||||
# Otherwise return.
|
||||
# """
|
||||
|
||||
# self._look_up_row(website="songfacts")
|
||||
|
||||
# def lookup_row_in_wikipedia(self) -> None:
|
||||
# """
|
||||
# If there is a selected row and it is a track row,
|
||||
# look up its title in wikipedia.
|
||||
|
||||
# If multiple rows are selected, only consider the first one.
|
||||
|
||||
# Otherwise return.
|
||||
# """
|
||||
|
||||
# self._look_up_row(website="wikipedia")
|
||||
|
||||
# def scroll_current_to_top(self) -> None:
|
||||
# """Scroll currently-playing row to top"""
|
||||
|
||||
# current_row = track_sequence.now.plr_rownum
|
||||
# if current_row is not None:
|
||||
# self._scroll_to_top(current_row)
|
||||
|
||||
# def scroll_next_to_top(self) -> None:
|
||||
# """Scroll nextly-playing row to top"""
|
||||
|
||||
# next_row = track_sequence.now.plr_rownum
|
||||
# if next_row is not None:
|
||||
# self._scroll_to_top(next_row)
|
||||
|
||||
def set_search(self, text: str) -> None:
|
||||
"""Set search text and find first match"""
|
||||
|
||||
self.search_text = text
|
||||
if not text:
|
||||
# Search string has been reset
|
||||
return
|
||||
self._search(next=True)
|
||||
|
||||
# def search_next(self) -> None:
|
||||
# """
|
||||
# Select next row containg self.search_string.
|
||||
# """
|
||||
|
||||
# self._search(next=True)
|
||||
|
||||
# def search_previous(self) -> None:
|
||||
# """
|
||||
# Select previous row containg self.search_string.
|
||||
# """
|
||||
|
||||
# self._search(next=False)
|
||||
|
||||
# def select_next_row(self) -> None:
|
||||
# """
|
||||
# Select next or first row. Don't select section headers.
|
||||
|
||||
# Wrap at last row.
|
||||
# """
|
||||
|
||||
# selected_rows = self._get_selected_rows()
|
||||
# # we will only handle zero or one selected rows
|
||||
# if len(selected_rows) > 1:
|
||||
# return
|
||||
# # select first row if none selected
|
||||
# if len(selected_rows) == 0:
|
||||
# row_number = 0
|
||||
# else:
|
||||
# row_number = selected_rows[0] + 1
|
||||
# if row_number >= self.rowCount():
|
||||
# row_number = 0
|
||||
|
||||
# # Don't select section headers
|
||||
# wrapped = False
|
||||
# track_id = self._get_row_track_id(row_number)
|
||||
# while not track_id:
|
||||
# row_number += 1
|
||||
# if row_number >= self.rowCount():
|
||||
# if wrapped:
|
||||
# # we're already wrapped once, so there are no
|
||||
# # non-headers
|
||||
# return
|
||||
# row_number = 0
|
||||
# wrapped = True
|
||||
# track_id = self._get_row_track_id(row_number)
|
||||
|
||||
# self.selectRow(row_number)
|
||||
|
||||
# def select_previous_row(self) -> None:
|
||||
# """
|
||||
# Select previous or last track. Don't select section headers.
|
||||
# Wrap at first row.
|
||||
# """
|
||||
|
||||
# selected_rows = self._get_selected_rows()
|
||||
# # we will only handle zero or one selected rows
|
||||
# if len(selected_rows) > 1:
|
||||
# return
|
||||
# # select last row if none selected
|
||||
# last_row = self.rowCount() - 1
|
||||
# if len(selected_rows) == 0:
|
||||
# row_number = last_row
|
||||
# else:
|
||||
# row_number = selected_rows[0] - 1
|
||||
# if row_number < 0:
|
||||
# row_number = last_row
|
||||
|
||||
# # Don't select section headers
|
||||
# wrapped = False
|
||||
# track_id = self._get_row_track_id(row_number)
|
||||
# while not track_id:
|
||||
# row_number -= 1
|
||||
# if row_number < 0:
|
||||
# if wrapped:
|
||||
# # we're already wrapped once, so there are no
|
||||
# # non-notes
|
||||
# return
|
||||
# row_number = last_row
|
||||
# wrapped = True
|
||||
# track_id = self._get_row_track_id(row_number)
|
||||
|
||||
# self.selectRow(row_number)
|
||||
|
||||
def set_row_as_next_track(self) -> None:
|
||||
"""
|
||||
Set selected row as next track
|
||||
@ -660,22 +509,12 @@ class PlaylistTab(QTableView):
|
||||
if track_row:
|
||||
self._add_context_menu("Info", lambda: self._info_row(model_row_number))
|
||||
|
||||
# Track path TODO
|
||||
# Track path
|
||||
if track_row:
|
||||
self._add_context_menu(
|
||||
"Copy track path", lambda: self._copy_path(model_row_number)
|
||||
)
|
||||
|
||||
def _calculate_end_time(
|
||||
self, start: Optional[datetime], duration: int
|
||||
) -> Optional[datetime]:
|
||||
"""Return datetime 'duration' ms after 'start'"""
|
||||
|
||||
if start is None:
|
||||
return None
|
||||
|
||||
return start + timedelta(milliseconds=duration)
|
||||
|
||||
def _column_resize(self, column_number: int, _old: int, _new: int) -> None:
|
||||
"""
|
||||
Called when column width changes. Save new width to database.
|
||||
@ -776,132 +615,18 @@ class PlaylistTab(QTableView):
|
||||
info.setDefaultButton(QMessageBox.StandardButton.Cancel)
|
||||
info.exec()
|
||||
|
||||
def _look_up_row(self, website: str) -> None:
|
||||
"""
|
||||
If there is a selected row and it is a track row,
|
||||
look up its title in the passed website
|
||||
|
||||
If multiple rows are selected, only consider the first one.
|
||||
|
||||
Otherwise return.
|
||||
"""
|
||||
|
||||
print("playlists_v3:_look_up_row()")
|
||||
return
|
||||
# selected_row = self._get_selected_row()
|
||||
# if not selected_row:
|
||||
# return
|
||||
|
||||
# if not self._get_row_track_id(selected_row):
|
||||
# return
|
||||
|
||||
# title = self._get_row_title(selected_row)
|
||||
|
||||
# if website == "wikipedia":
|
||||
# QTimer.singleShot(
|
||||
# 0, lambda: self.musicmuster.tabInfolist.open_in_wikipedia(title)
|
||||
# )
|
||||
# elif website == "songfacts":
|
||||
# QTimer.singleShot(
|
||||
# 0, lambda: self.musicmuster.tabInfolist.open_in_songfacts(title)
|
||||
# )
|
||||
# else:
|
||||
# return
|
||||
|
||||
def _mark_as_unplayed(self, row_numbers: List[int]) -> None:
|
||||
"""Rescan track"""
|
||||
|
||||
self.playlist_model.mark_unplayed(row_numbers)
|
||||
self.clear_selection()
|
||||
|
||||
def _obs_change_scene(self, current_row: int) -> None:
|
||||
"""
|
||||
Try to change OBS scene to the name passed
|
||||
"""
|
||||
|
||||
check_row = current_row
|
||||
while True:
|
||||
# If we have a note and it has a scene change command,
|
||||
# execute it
|
||||
note_text = self._get_row_note(check_row)
|
||||
if note_text:
|
||||
match_obj = scene_change_re.search(note_text)
|
||||
if match_obj:
|
||||
scene_name = match_obj.group(1)
|
||||
if scene_name:
|
||||
try:
|
||||
cl = obs.ReqClient(
|
||||
host=Config.OBS_HOST,
|
||||
port=Config.OBS_PORT,
|
||||
password=Config.OBS_PASSWORD,
|
||||
)
|
||||
except ConnectionRefusedError:
|
||||
log.error("OBS connection refused")
|
||||
return
|
||||
|
||||
try:
|
||||
cl.set_current_program_scene(scene_name)
|
||||
log.info(f"OBS scene changed to '{scene_name}'")
|
||||
return
|
||||
except obs.error.OBSSDKError as e:
|
||||
log.error(f"OBS SDK error ({e})")
|
||||
return
|
||||
# After current track row, only check header rows and stop
|
||||
# at first non-header row
|
||||
check_row -= 1
|
||||
if check_row < 0:
|
||||
break
|
||||
if self._get_row_track_id(check_row):
|
||||
break
|
||||
|
||||
def _rescan(self, row_number: int) -> None:
|
||||
"""Rescan track"""
|
||||
|
||||
self.playlist_model.rescan_track(row_number)
|
||||
self.clear_selection()
|
||||
|
||||
# def _reset_next(self, old_plrid: int, new_plrid: int) -> None:
|
||||
# """
|
||||
# Called when set_next_track_signal signal received.
|
||||
|
||||
# Actions required:
|
||||
# - If old_plrid points to this playlist:
|
||||
# - Remove existing next track
|
||||
# - If new_plrid points to this playlist:
|
||||
# - Set track as next
|
||||
# - Display row as next track
|
||||
# - Update start/stop times
|
||||
# """
|
||||
|
||||
# with Session() as session:
|
||||
# # Get plrs
|
||||
# old_plr = new_plr = None
|
||||
# if old_plrid:
|
||||
# old_plr = session.get(PlaylistRows, old_plrid)
|
||||
|
||||
# # Unmark next track
|
||||
# if old_plr and old_plr.playlist_id == self.playlist_id:
|
||||
# self._set_row_colour_default(old_plr.plr_rownum)
|
||||
|
||||
# # Mark next track
|
||||
# if new_plrid:
|
||||
# new_plr = session.get(PlaylistRows, new_plrid)
|
||||
# if not new_plr:
|
||||
# log.error(f"_reset_next({new_plrid=}): plr not found")
|
||||
# return
|
||||
# if new_plr.playlist_id == self.playlist_id:
|
||||
# self._set_row_colour_next(new_plr.plr_rownum)
|
||||
|
||||
# # Update start/stop times
|
||||
# self._update_start_end_times(session)
|
||||
|
||||
# self.clear_selection()
|
||||
|
||||
def _run_subprocess(self, args):
|
||||
"""Run args in subprocess"""
|
||||
|
||||
subprocess.call(args)
|
||||
|
||||
def scroll_to_top(self, row_number: int) -> None:
|
||||
"""
|
||||
Scroll to put passed row_number Config.SCROLL_TOP_MARGIN from the
|
||||
@ -914,65 +639,6 @@ class PlaylistTab(QTableView):
|
||||
row_index = self.proxy_model.index(row_number, 0)
|
||||
self.scrollTo(row_index, QAbstractItemView.ScrollHint.PositionAtTop)
|
||||
|
||||
# def _search(self, next: bool = True) -> None:
|
||||
# """
|
||||
# Select next/previous row containg self.search_string. Start from
|
||||
# top selected row if there is one, else from top.
|
||||
|
||||
# Wrap at last/first row.
|
||||
# """
|
||||
|
||||
# if not self.search_text:
|
||||
# return
|
||||
|
||||
# selected_row = self._get_selected_row()
|
||||
# if next:
|
||||
# if selected_row is not None and selected_row < self.rowCount() - 1:
|
||||
# starting_row = selected_row + 1
|
||||
# else:
|
||||
# starting_row = 0
|
||||
# else:
|
||||
# if selected_row is not None and selected_row > 0:
|
||||
# starting_row = selected_row - 1
|
||||
# else:
|
||||
# starting_row = self.rowCount() - 1
|
||||
|
||||
# wrapped = False
|
||||
# match_row = None
|
||||
# row_number = starting_row
|
||||
# needle = self.search_text.lower()
|
||||
# while True:
|
||||
# # Check for match in title, artist or notes
|
||||
# title = self._get_row_title(row_number)
|
||||
# if title and needle in title.lower():
|
||||
# match_row = row_number
|
||||
# break
|
||||
# artist = self._get_row_artist(row_number)
|
||||
# if artist and needle in artist.lower():
|
||||
# match_row = row_number
|
||||
# break
|
||||
# note = self._get_row_note(row_number)
|
||||
# if note and needle in note.lower():
|
||||
# match_row = row_number
|
||||
# break
|
||||
# if next:
|
||||
# row_number += 1
|
||||
# if wrapped and row_number >= starting_row:
|
||||
# break
|
||||
# if row_number >= self.rowCount():
|
||||
# row_number = 0
|
||||
# wrapped = True
|
||||
# else:
|
||||
# row_number -= 1
|
||||
# if wrapped and row_number <= starting_row:
|
||||
# break
|
||||
# if row_number < 0:
|
||||
# row_number = self.rowCount() - 1
|
||||
# wrapped = True
|
||||
|
||||
# if match_row is not None:
|
||||
# self.selectRow(row_number)
|
||||
|
||||
def select_duplicate_rows(self) -> None:
|
||||
"""
|
||||
Select the last of any rows with duplicate tracks in current playlist.
|
||||
@ -1036,30 +702,6 @@ class PlaylistTab(QTableView):
|
||||
else:
|
||||
self.setColumnWidth(column_number, Config.DEFAULT_COLUMN_WIDTH)
|
||||
|
||||
# def _set_row_note_colour(self, session: scoped_session, row_number: int) -> None:
|
||||
# """
|
||||
# Set row note colour
|
||||
# """
|
||||
|
||||
# # Sanity check: this should be a track row and thus have a
|
||||
# # track associated
|
||||
# if not self._get_row_track_id(row_number):
|
||||
# if os.environ["MM_ENV"] == "PRODUCTION":
|
||||
# send_mail(
|
||||
# Config.ERRORS_TO,
|
||||
# Config.ERRORS_FROM,
|
||||
# "playlists:_set_row_note_colour() on header row",
|
||||
# stackprinter.format(),
|
||||
# )
|
||||
# # stackprinter.show(add_summary=True, style="darkbg")
|
||||
# print(f"playists:_set_row_note_colour() called on track row ({row_number=}")
|
||||
# return
|
||||
|
||||
# # Set colour
|
||||
# note_text = self._get_row_note(row_number)
|
||||
# note_colour = NoteColours.get_colour(session, note_text)
|
||||
# self._set_cell_colour(row_number, ROW_NOTES, note_colour)
|
||||
|
||||
def _span_cells(self, row: int, column: int, rowSpan: int, columnSpan: int) -> None:
|
||||
"""
|
||||
Implement spanning of cells, initiated by signal
|
||||
|
||||
Loading…
Reference in New Issue
Block a user