Move info tabs to below playlist
This commit is contained in:
parent
70c2c18fb3
commit
afc27c988d
49
app/infotabs.py
Normal file
49
app/infotabs.py
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
import urllib.parse
|
||||||
|
|
||||||
|
from datetime import datetime
|
||||||
|
from typing import Dict, Optional
|
||||||
|
from PyQt5.QtCore import QUrl
|
||||||
|
from PyQt5.QtWebEngineWidgets import QWebEngineView
|
||||||
|
from PyQt5.QtWidgets import QTabWidget
|
||||||
|
from config import Config
|
||||||
|
|
||||||
|
|
||||||
|
class InfoTabs(QTabWidget):
|
||||||
|
"""
|
||||||
|
Class to manage info tabs
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, parent=None) -> None:
|
||||||
|
super().__init__(parent)
|
||||||
|
|
||||||
|
# Dictionary to record when tabs were last updated (so we can
|
||||||
|
# re-use the oldest one later)
|
||||||
|
self.last_update: Dict[QWebEngineView, datetime] = {}
|
||||||
|
|
||||||
|
def open_tab(self, title: str) -> None:
|
||||||
|
"""
|
||||||
|
Open passed URL. Create new tab if we're below the maximum
|
||||||
|
number otherwise reuse oldest content tab.
|
||||||
|
"""
|
||||||
|
|
||||||
|
short_title = title[:Config.INFO_TAB_TITLE_LENGTH]
|
||||||
|
|
||||||
|
if self.count() < Config.MAX_INFO_TABS:
|
||||||
|
# Create a new tab
|
||||||
|
widget = QWebEngineView()
|
||||||
|
widget.setZoomFactor(Config.WEB_ZOOM_FACTOR)
|
||||||
|
tab_index = self.addTab(widget, short_title)
|
||||||
|
|
||||||
|
else:
|
||||||
|
# Reuse oldest widget
|
||||||
|
widget = min(self.last_update, key=self.last_update.get)
|
||||||
|
tab_index = self.indexOf(widget)
|
||||||
|
self.setTabText(tab_index, short_title)
|
||||||
|
|
||||||
|
txt = urllib.parse.quote_plus(title)
|
||||||
|
url = Config.INFO_TAB_URL % txt
|
||||||
|
widget.setUrl(QUrl(url))
|
||||||
|
self.last_update[widget] = datetime.now()
|
||||||
|
|
||||||
|
# Show newly updated tab
|
||||||
|
self.setCurrentIndex(tab_index)
|
||||||
@ -5,7 +5,6 @@ from log import log
|
|||||||
# import psutil
|
# import psutil
|
||||||
import sys
|
import sys
|
||||||
# import threading
|
# import threading
|
||||||
# import urllib.parse
|
|
||||||
# import webbrowser
|
# import webbrowser
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
@ -15,7 +14,6 @@ import sys
|
|||||||
# from PyQt5.QtCore import QDate, QEvent, QProcess, Qt, QTime, QTimer, QUrl
|
# from PyQt5.QtCore import QDate, QEvent, QProcess, Qt, QTime, QTimer, QUrl
|
||||||
from PyQt5.QtCore import Qt
|
from PyQt5.QtCore import Qt
|
||||||
from PyQt5.QtGui import QColor
|
from PyQt5.QtGui import QColor
|
||||||
# from PyQt5.QtWebEngineWidgets import QWebEngineView as QWebView
|
|
||||||
from PyQt5.QtWidgets import (
|
from PyQt5.QtWidgets import (
|
||||||
QApplication,
|
QApplication,
|
||||||
QDialog,
|
QDialog,
|
||||||
@ -32,7 +30,6 @@ from dbconfig import engine, Session
|
|||||||
# import helpers
|
# import helpers
|
||||||
# import music
|
# import music
|
||||||
#
|
#
|
||||||
# from config import Config
|
|
||||||
from models import (
|
from models import (
|
||||||
Base,
|
Base,
|
||||||
# Playdates,
|
# Playdates,
|
||||||
@ -78,7 +75,6 @@ class Window(QMainWindow, Ui_MainWindow):
|
|||||||
# self.music: music.Music = music.Music()
|
# self.music: music.Music = music.Music()
|
||||||
self.current_track: Optional[TrackData] = None
|
self.current_track: Optional[TrackData] = None
|
||||||
self.current_track_playlist_tab: Optional[PlaylistTab] = None
|
self.current_track_playlist_tab: Optional[PlaylistTab] = None
|
||||||
self.info_tabs: Optional[Dict[str, QWebView]] = {}
|
|
||||||
self.next_track: Optional[TrackData] = None
|
self.next_track: Optional[TrackData] = None
|
||||||
self.next_track_playlist_tab: Optional[PlaylistTab] = None
|
self.next_track_playlist_tab: Optional[PlaylistTab] = None
|
||||||
self.previous_track: Optional[TrackData] = None
|
self.previous_track: Optional[TrackData] = None
|
||||||
@ -92,6 +88,7 @@ class Window(QMainWindow, Ui_MainWindow):
|
|||||||
# self.txtSearch.setHidden(True)
|
# self.txtSearch.setHidden(True)
|
||||||
# self.hide_played_tracks = False
|
# self.hide_played_tracks = False
|
||||||
#
|
#
|
||||||
|
self.splitter.setSizes([200, 200])
|
||||||
self.visible_playlist_tab: Callable[[], PlaylistTab] = \
|
self.visible_playlist_tab: Callable[[], PlaylistTab] = \
|
||||||
self.tabPlaylist.currentWidget
|
self.tabPlaylist.currentWidget
|
||||||
#
|
#
|
||||||
@ -557,52 +554,6 @@ class Window(QMainWindow, Ui_MainWindow):
|
|||||||
destination_visible_playlist_tab.populate(
|
destination_visible_playlist_tab.populate(
|
||||||
session, dlg.playlist.id)
|
session, dlg.playlist.id)
|
||||||
#
|
#
|
||||||
# def open_info_tabs(self) -> None:
|
|
||||||
# """
|
|
||||||
# Ensure we have info tabs for next and current track titles
|
|
||||||
# """
|
|
||||||
#
|
|
||||||
# title_list: List[str] = []
|
|
||||||
#
|
|
||||||
# if self.previous_track:
|
|
||||||
# title_list.append(self.previous_track.title)
|
|
||||||
# if self.current_track:
|
|
||||||
# title_list.append(self.current_track.title)
|
|
||||||
# if self.next_track:
|
|
||||||
# title_list.append(self.next_track.title)
|
|
||||||
#
|
|
||||||
# for title in title_list:
|
|
||||||
# if title in self.info_tabs.keys():
|
|
||||||
# # We already have a tab for this track
|
|
||||||
# continue
|
|
||||||
# if len(self.info_tabs) >= Config.MAX_log.info_TABS:
|
|
||||||
# # Find an unneeded info tab
|
|
||||||
# try:
|
|
||||||
# old_title = list(
|
|
||||||
# set(self.info_tabs.keys()) - set(title_list)
|
|
||||||
# )[0]
|
|
||||||
# except IndexError:
|
|
||||||
# log.debug(
|
|
||||||
# f"ensure_info_tabs({title_list}): unable to add "
|
|
||||||
# f"{title=}"
|
|
||||||
# )
|
|
||||||
# return
|
|
||||||
# # Assign redundant widget a new title
|
|
||||||
# widget = self.info_tabs[title] = self.info_tabs[old_title]
|
|
||||||
# idx = self.tabPlaylist.indexOf(widget)
|
|
||||||
# self.tabPlaylist.setTabText(
|
|
||||||
# idx, title[:Config.log.info_TAB_TITLE_LENGTH])
|
|
||||||
# del self.info_tabs[old_title]
|
|
||||||
# else:
|
|
||||||
# # Create a new tab for this title
|
|
||||||
# widget = self.info_tabs[title] = QWebView()
|
|
||||||
# widget.setZoomFactor(Config.WEB_ZOOM_FACTOR)
|
|
||||||
# self.tabPlaylist.addTab(
|
|
||||||
# widget, title[:Config.log.info_TAB_TITLE_LENGTH])
|
|
||||||
# txt = urllib.parse.quote_plus(title)
|
|
||||||
# url = Config.log.info_TAB_URL % txt
|
|
||||||
# widget.setUrl(QUrl(url))
|
|
||||||
#
|
|
||||||
# def play_next(self) -> None:
|
# def play_next(self) -> None:
|
||||||
# """
|
# """
|
||||||
# Play next track.
|
# Play next track.
|
||||||
@ -783,7 +734,7 @@ class Window(QMainWindow, Ui_MainWindow):
|
|||||||
# title = self.current_track.title
|
# title = self.current_track.title
|
||||||
# if title:
|
# if title:
|
||||||
# txt = urllib.parse.quote_plus(title)
|
# txt = urllib.parse.quote_plus(title)
|
||||||
# url = Config.log.info_TAB_URL % txt
|
# url = Config.TAB_URL % txt
|
||||||
# webbrowser.open(url, new=2)
|
# webbrowser.open(url, new=2)
|
||||||
#
|
#
|
||||||
# def stop(self) -> None:
|
# def stop(self) -> None:
|
||||||
@ -879,8 +830,8 @@ class Window(QMainWindow, Ui_MainWindow):
|
|||||||
self.update_headers()
|
self.update_headers()
|
||||||
|
|
||||||
# Populate 'info' tabs
|
# Populate 'info' tabs
|
||||||
self.open_info_tabs()
|
self.tabInfolist.open_tab(track.title)
|
||||||
#
|
|
||||||
# def tick(self) -> None:
|
# def tick(self) -> None:
|
||||||
# """
|
# """
|
||||||
# Carry out clock tick actions.
|
# Carry out clock tick actions.
|
||||||
|
|||||||
@ -4,6 +4,7 @@ from typing import List, Optional
|
|||||||
from PyQt5 import QtCore
|
from PyQt5 import QtCore
|
||||||
from PyQt5.QtCore import Qt
|
from PyQt5.QtCore import Qt
|
||||||
from PyQt5.QtGui import (
|
from PyQt5.QtGui import (
|
||||||
|
QBrush,
|
||||||
QColor,
|
QColor,
|
||||||
QFont,
|
QFont,
|
||||||
QDropEvent
|
QDropEvent
|
||||||
@ -364,12 +365,12 @@ class PlaylistTab(QTableWidget):
|
|||||||
# playlist.close(session)
|
# playlist.close(session)
|
||||||
#
|
#
|
||||||
# event.accept()
|
# event.accept()
|
||||||
#
|
|
||||||
# def clear_next(self, session) -> None:
|
def clear_next(self, session) -> None:
|
||||||
# """Clear next track"""
|
"""Clear next track marker"""
|
||||||
#
|
|
||||||
# self._meta_clear_next()
|
self._meta_clear_next()
|
||||||
# self.update_display(session)
|
self.update_display(session)
|
||||||
#
|
#
|
||||||
# def create_note(self) -> None:
|
# def create_note(self) -> None:
|
||||||
# """
|
# """
|
||||||
@ -1044,6 +1045,9 @@ class PlaylistTab(QTableWidget):
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
# This is a track row other than next or current
|
# This is a track row other than next or current
|
||||||
|
# Reset colour in case it was current/next
|
||||||
|
self._set_row_colour(row, None)
|
||||||
|
|
||||||
if row in played:
|
if row in played:
|
||||||
# Played today, so update last played column
|
# Played today, so update last played column
|
||||||
last_playedtime = track.lastplayed
|
last_playedtime = track.lastplayed
|
||||||
@ -1852,14 +1856,22 @@ class PlaylistTab(QTableWidget):
|
|||||||
if self.item(row, j):
|
if self.item(row, j):
|
||||||
self.item(row, j).setFont(boldfont)
|
self.item(row, j).setFont(boldfont)
|
||||||
|
|
||||||
def _set_row_colour(self, row: int, colour: QColor) -> None:
|
def _set_row_colour(self, row: int,
|
||||||
"""Set row background colour"""
|
colour: Optional[QColor] = None) -> None:
|
||||||
|
"""
|
||||||
|
Set or reset row background colour
|
||||||
|
"""
|
||||||
|
|
||||||
j: int
|
j: int
|
||||||
|
|
||||||
|
if colour:
|
||||||
|
brush = QBrush(colour)
|
||||||
|
else:
|
||||||
|
brush = QBrush()
|
||||||
|
|
||||||
for j in range(1, self.columnCount()):
|
for j in range(1, self.columnCount()):
|
||||||
if self.item(row, j):
|
if self.item(row, j):
|
||||||
self.item(row, j).setBackground(colour)
|
self.item(row, j).setBackground(brush)
|
||||||
#
|
#
|
||||||
# def _set_row_content(self, row: int, object_id: int) -> None:
|
# def _set_row_content(self, row: int, object_id: int) -> None:
|
||||||
# """Set content associated with this row"""
|
# """Set content associated with this row"""
|
||||||
|
|||||||
@ -282,6 +282,10 @@ border: 1px solid rgb(85, 87, 83);</string>
|
|||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="0">
|
<item row="2" column="0">
|
||||||
|
<widget class="QSplitter" name="splitter">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
<widget class="QTabWidget" name="tabPlaylist">
|
<widget class="QTabWidget" name="tabPlaylist">
|
||||||
<property name="currentIndex">
|
<property name="currentIndex">
|
||||||
<number>-1</number>
|
<number>-1</number>
|
||||||
@ -296,6 +300,21 @@ border: 1px solid rgb(85, 87, 83);</string>
|
|||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
|
<widget class="InfoTabs" name="tabInfolist">
|
||||||
|
<property name="currentIndex">
|
||||||
|
<number>-1</number>
|
||||||
|
</property>
|
||||||
|
<property name="documentMode">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="tabsClosable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="movable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="3" column="0">
|
<item row="3" column="0">
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
@ -1022,6 +1041,14 @@ border: 1px solid rgb(85, 87, 83);</string>
|
|||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
</widget>
|
</widget>
|
||||||
|
<customwidgets>
|
||||||
|
<customwidget>
|
||||||
|
<class>InfoTabs</class>
|
||||||
|
<extends>QTabWidget</extends>
|
||||||
|
<header>infotabs</header>
|
||||||
|
<container>1</container>
|
||||||
|
</customwidget>
|
||||||
|
</customwidgets>
|
||||||
<resources>
|
<resources>
|
||||||
<include location="icons.qrc"/>
|
<include location="icons.qrc"/>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@ -142,12 +142,20 @@ class Ui_MainWindow(object):
|
|||||||
self.frame_4.setFrameShadow(QtWidgets.QFrame.Raised)
|
self.frame_4.setFrameShadow(QtWidgets.QFrame.Raised)
|
||||||
self.frame_4.setObjectName("frame_4")
|
self.frame_4.setObjectName("frame_4")
|
||||||
self.gridLayout_4.addWidget(self.frame_4, 1, 0, 1, 1)
|
self.gridLayout_4.addWidget(self.frame_4, 1, 0, 1, 1)
|
||||||
self.tabPlaylist = QtWidgets.QTabWidget(self.centralwidget)
|
self.splitter = QtWidgets.QSplitter(self.centralwidget)
|
||||||
|
self.splitter.setOrientation(QtCore.Qt.Vertical)
|
||||||
|
self.splitter.setObjectName("splitter")
|
||||||
|
self.tabPlaylist = QtWidgets.QTabWidget(self.splitter)
|
||||||
self.tabPlaylist.setDocumentMode(False)
|
self.tabPlaylist.setDocumentMode(False)
|
||||||
self.tabPlaylist.setTabsClosable(True)
|
self.tabPlaylist.setTabsClosable(True)
|
||||||
self.tabPlaylist.setMovable(True)
|
self.tabPlaylist.setMovable(True)
|
||||||
self.tabPlaylist.setObjectName("tabPlaylist")
|
self.tabPlaylist.setObjectName("tabPlaylist")
|
||||||
self.gridLayout_4.addWidget(self.tabPlaylist, 2, 0, 1, 1)
|
self.tabInfolist = InfoTabs(self.splitter)
|
||||||
|
self.tabInfolist.setDocumentMode(False)
|
||||||
|
self.tabInfolist.setTabsClosable(True)
|
||||||
|
self.tabInfolist.setMovable(True)
|
||||||
|
self.tabInfolist.setObjectName("tabInfolist")
|
||||||
|
self.gridLayout_4.addWidget(self.splitter, 2, 0, 1, 1)
|
||||||
self.horizontalLayout = QtWidgets.QHBoxLayout()
|
self.horizontalLayout = QtWidgets.QHBoxLayout()
|
||||||
self.horizontalLayout.setObjectName("horizontalLayout")
|
self.horizontalLayout.setObjectName("horizontalLayout")
|
||||||
self.frame = QtWidgets.QFrame(self.centralwidget)
|
self.frame = QtWidgets.QFrame(self.centralwidget)
|
||||||
@ -473,6 +481,7 @@ class Ui_MainWindow(object):
|
|||||||
|
|
||||||
self.retranslateUi(MainWindow)
|
self.retranslateUi(MainWindow)
|
||||||
self.tabPlaylist.setCurrentIndex(-1)
|
self.tabPlaylist.setCurrentIndex(-1)
|
||||||
|
self.tabInfolist.setCurrentIndex(-1)
|
||||||
self.actionE_xit.triggered.connect(MainWindow.close) # type: ignore
|
self.actionE_xit.triggered.connect(MainWindow.close) # type: ignore
|
||||||
QtCore.QMetaObject.connectSlotsByName(MainWindow)
|
QtCore.QMetaObject.connectSlotsByName(MainWindow)
|
||||||
|
|
||||||
@ -550,4 +559,5 @@ class Ui_MainWindow(object):
|
|||||||
self.actionSearch.setShortcut(_translate("MainWindow", "/"))
|
self.actionSearch.setShortcut(_translate("MainWindow", "/"))
|
||||||
self.actionInsert_section_header.setText(_translate("MainWindow", "Insert §ion header..."))
|
self.actionInsert_section_header.setText(_translate("MainWindow", "Insert §ion header..."))
|
||||||
self.actionRemove.setText(_translate("MainWindow", "&Remove track"))
|
self.actionRemove.setText(_translate("MainWindow", "&Remove track"))
|
||||||
|
from infotabs import InfoTabs
|
||||||
import icons_rc
|
import icons_rc
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user