diff options
| author | Warry <FunWarry@users.noreply.github.com> | 2025-12-29 17:37:39 +0100 |
|---|---|---|
| committer | Warry <FunWarry@users.noreply.github.com> | 2025-12-29 17:37:39 +0100 |
| commit | 296c6c7d6b319b38958b2aacb9904f18f6f46fd1 (patch) | |
| tree | a3e72a9326defee5804cc9387ecee779b9bf02a2 /tidal_dl_ng/ui | |
| parent | 75868b32d07aafe46b69649d2da0dc2c833f112d (diff) | |
| download | tidal-dl-ng-296c6c7d6b319b38958b2aacb9904f18f6f46fd1.tar.gz | |
feat: Add playlist management functionality and compliance checks
- Introduced a new "Playlists" column in results view with visual indicators for membership.
- Added `playlist_api.py` to handle playlist-related operations (fetch, add, remove tracks).
- Implemented `PlaylistManagerDialog` for seamless playlist addition/removal with caching.
- Integrated compliance check script (`check_agents_compliance.py`) for ensuring coding standards.
- Added extensive documentation (`playlist_membership_manager.md`) covering architecture and flow.
- Updated GUI logic and QStandardItemModel setup to include playlist data.
- Included unit tests for playlist management components and API.
Diffstat (limited to 'tidal_dl_ng/ui')
| -rw-r--r-- | tidal_dl_ng/ui/dialog_playlist_manager.py | 115 | ||||
| -rw-r--r-- | tidal_dl_ng/ui/dialog_playlist_manager.ui | 147 |
2 files changed, 262 insertions, 0 deletions
diff --git a/tidal_dl_ng/ui/dialog_playlist_manager.py b/tidal_dl_ng/ui/dialog_playlist_manager.py new file mode 100644 index 0000000..17327f6 --- /dev/null +++ b/tidal_dl_ng/ui/dialog_playlist_manager.py @@ -0,0 +1,115 @@ +################################################################################ +## Form generated from reading UI file 'dialog_playlist_manager.ui' +## +## Created by: Qt User Interface Compiler version 6.10.0 +## +## WARNING! All changes made in this file will be lost when recompiling UI file! +################################################################################ + +from PySide6.QtCore import QCoreApplication, QMetaObject, QRect, QSize, Qt +from PySide6.QtWidgets import ( + QFrame, + QHBoxLayout, + QLabel, + QPushButton, + QScrollArea, + QSizePolicy, + QSpacerItem, + QVBoxLayout, + QWidget, +) + + +class Ui_DialogPlaylistManager: + def setupUi(self, DialogPlaylistManager): + if not DialogPlaylistManager.objectName(): + DialogPlaylistManager.setObjectName("DialogPlaylistManager") + DialogPlaylistManager.resize(609, 760) + DialogPlaylistManager.setMinimumSize(QSize(520, 560)) + self.verticalLayoutRoot = QVBoxLayout(DialogPlaylistManager) + self.verticalLayoutRoot.setObjectName("verticalLayoutRoot") + self.horizontalLayoutHeader = QHBoxLayout() + self.horizontalLayoutHeader.setObjectName("horizontalLayoutHeader") + self.labelTitle = QLabel(DialogPlaylistManager) + self.labelTitle.setObjectName("labelTitle") + self.labelTitle.setWordWrap(True) + + self.horizontalLayoutHeader.addWidget(self.labelTitle) + + self.verticalLayoutRoot.addLayout(self.horizontalLayoutHeader) + + self.frameSeparator = QFrame(DialogPlaylistManager) + self.frameSeparator.setObjectName("frameSeparator") + self.frameSeparator.setFrameShape(QFrame.Shape.HLine) + self.frameSeparator.setFrameShadow(QFrame.Shadow.Sunken) + + self.verticalLayoutRoot.addWidget(self.frameSeparator) + + self.scrollArea = QScrollArea(DialogPlaylistManager) + self.scrollArea.setObjectName("scrollArea") + self.scrollArea.setWidgetResizable(True) + self.scrollAreaWidgetContents = QWidget() + self.scrollAreaWidgetContents.setObjectName("scrollAreaWidgetContents") + self.scrollAreaWidgetContents.setGeometry(QRect(0, 0, 589, 666)) + self.verticalLayoutList = QVBoxLayout(self.scrollAreaWidgetContents) + self.verticalLayoutList.setObjectName("verticalLayoutList") + self.labelEmpty = QLabel(self.scrollAreaWidgetContents) + self.labelEmpty.setObjectName("labelEmpty") + self.labelEmpty.setAlignment(Qt.AlignmentFlag.AlignCenter) + + self.verticalLayoutList.addWidget(self.labelEmpty) + + self.verticalSpacer = QSpacerItem(20, 40, QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Expanding) + + self.verticalLayoutList.addItem(self.verticalSpacer) + + self.scrollArea.setWidget(self.scrollAreaWidgetContents) + + self.verticalLayoutRoot.addWidget(self.scrollArea) + + self.frameFooterSeparator = QFrame(DialogPlaylistManager) + self.frameFooterSeparator.setObjectName("frameFooterSeparator") + self.frameFooterSeparator.setFrameShape(QFrame.Shape.HLine) + self.frameFooterSeparator.setFrameShadow(QFrame.Shadow.Sunken) + + self.verticalLayoutRoot.addWidget(self.frameFooterSeparator) + + self.horizontalLayoutFooter = QHBoxLayout() + self.horizontalLayoutFooter.setObjectName("horizontalLayoutFooter") + self.horizontalSpacer = QSpacerItem(40, 20, QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum) + + self.horizontalLayoutFooter.addItem(self.horizontalSpacer) + + self.buttonClose = QPushButton(DialogPlaylistManager) + self.buttonClose.setObjectName("buttonClose") + + self.horizontalLayoutFooter.addWidget(self.buttonClose) + + self.verticalLayoutRoot.addLayout(self.horizontalLayoutFooter) + + self.retranslateUi(DialogPlaylistManager) + self.buttonClose.clicked.connect(DialogPlaylistManager.accept) + + self.buttonClose.setDefault(True) + + QMetaObject.connectSlotsByName(DialogPlaylistManager) + + # setupUi + + def retranslateUi(self, DialogPlaylistManager): + DialogPlaylistManager.setWindowTitle( + QCoreApplication.translate("DialogPlaylistManager", "G\u00e9rer les playlists", None) + ) + self.labelTitle.setText( + QCoreApplication.translate( + "DialogPlaylistManager", + 'G\u00e9rer les playlists pour : <b><span style="color:#1e88e5;">Titre de la Piste</span></b>', + None, + ) + ) + self.labelEmpty.setText( + QCoreApplication.translate("DialogPlaylistManager", "Aucune playlist disponible.", None) + ) + self.buttonClose.setText(QCoreApplication.translate("DialogPlaylistManager", "Fermer", None)) + + # retranslateUi diff --git a/tidal_dl_ng/ui/dialog_playlist_manager.ui b/tidal_dl_ng/ui/dialog_playlist_manager.ui new file mode 100644 index 0000000..5f7b831 --- /dev/null +++ b/tidal_dl_ng/ui/dialog_playlist_manager.ui @@ -0,0 +1,147 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>DialogPlaylistManager</class> + <widget class="QDialog" name="DialogPlaylistManager"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>609</width> + <height>760</height> + </rect> + </property> + <property name="minimumSize"> + <size> + <width>520</width> + <height>560</height> + </size> + </property> + <property name="windowTitle"> + <string>Gérer les playlists</string> + </property> + <layout class="QVBoxLayout" name="verticalLayoutRoot"> + <item> + <layout class="QHBoxLayout" name="horizontalLayoutHeader"> + <item> + <widget class="QLabel" name="labelTitle"> + <property name="text"> + <string>Gérer les playlists pour : <b><span style="color:#1e88e5;">Titre de la Piste</span></b></string> + </property> + <property name="wordWrap"> + <bool>true</bool> + </property> + </widget> + </item> + </layout> + </item> + <item> + <widget class="QFrame" name="frameSeparator"> + <property name="frameShape"> + <enum>QFrame::Shape::HLine</enum> + </property> + <property name="frameShadow"> + <enum>QFrame::Shadow::Sunken</enum> + </property> + </widget> + </item> + <item> + <widget class="QScrollArea" name="scrollArea"> + <property name="widgetResizable"> + <bool>true</bool> + </property> + <widget class="QWidget" name="scrollAreaWidgetContents"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>589</width> + <height>666</height> + </rect> + </property> + <layout class="QVBoxLayout" name="verticalLayoutList"> + <item> + <widget class="QLabel" name="labelEmpty"> + <property name="text"> + <string>Aucune playlist disponible.</string> + </property> + <property name="alignment"> + <set>Qt::AlignmentFlag::AlignCenter</set> + </property> + </widget> + </item> + <item> + <spacer name="verticalSpacer"> + <property name="orientation"> + <enum>Qt::Orientation::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + </layout> + </widget> + </widget> + </item> + <item> + <widget class="QFrame" name="frameFooterSeparator"> + <property name="frameShape"> + <enum>QFrame::Shape::HLine</enum> + </property> + <property name="frameShadow"> + <enum>QFrame::Shadow::Sunken</enum> + </property> + </widget> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayoutFooter"> + <item> + <spacer name="horizontalSpacer"> + <property name="orientation"> + <enum>Qt::Orientation::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QPushButton" name="buttonClose"> + <property name="text"> + <string>Fermer</string> + </property> + <property name="default"> + <bool>true</bool> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + <resources/> + <connections> + <connection> + <sender>buttonClose</sender> + <signal>clicked()</signal> + <receiver>DialogPlaylistManager</receiver> + <slot>accept()</slot> + <hints> + <hint type="sourcelabel"> + <x>20</x> + <y>20</y> + </hint> + <hint type="destinationlabel"> + <x>20</x> + <y>20</y> + </hint> + </hints> + </connection> + </connections> +</ui> |
