Merge pull request #105 from exislow/87-feature-add-a-possibilty-to-filter-columns

87 feature add a possibilty to filter columns
This commit is contained in:
exislow
2024-05-15 09:07:04 +02:00
committed by GitHub
4 changed files with 227 additions and 104 deletions
+83 -42
View File
@@ -1,19 +1,21 @@
import math import math
import sys import sys
import time import time
from collections.abc import Callable from collections.abc import Callable, Sequence
from PySide6.QtGui import QStandardItem
from requests.exceptions import HTTPError from requests.exceptions import HTTPError
from tidal_dl_ng import __version__, update_available from tidal_dl_ng import __version__, update_available
from tidal_dl_ng.dialog import DialogLogin, DialogPreferences, DialogVersion from tidal_dl_ng.dialog import DialogLogin, DialogPreferences, DialogVersion
from tidal_dl_ng.helper.gui import ( from tidal_dl_ng.helper.gui import (
FilterHeader,
HumanProxyModel,
get_queue_download_media, get_queue_download_media,
get_queue_download_quality, get_queue_download_quality,
get_results_media_item, get_results_media_item,
get_user_list_media_item, get_user_list_media_item,
set_queue_download_media, set_queue_download_media,
set_results_media,
set_user_list_media, set_user_list_media,
) )
from tidal_dl_ng.helper.path import get_format_template, resource_path from tidal_dl_ng.helper.path import get_format_template, resource_path
@@ -64,6 +66,8 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
tray: QtWidgets.QSystemTrayIcon tray: QtWidgets.QSystemTrayIcon
spinner: QtWaitingSpinner spinner: QtWaitingSpinner
cover_url_current: str = "" cover_url_current: str = ""
model_tr_results: QtGui.QStandardItemModel = QtGui.QStandardItemModel()
proxy_tr_results: HumanProxyModel
s_spinner_start: QtCore.Signal = QtCore.Signal(QtWidgets.QWidget) s_spinner_start: QtCore.Signal = QtCore.Signal(QtWidgets.QWidget)
s_spinner_stop: QtCore.Signal = QtCore.Signal() s_spinner_stop: QtCore.Signal = QtCore.Signal()
pb_item: QtWidgets.QProgressBar pb_item: QtWidgets.QProgressBar
@@ -98,7 +102,8 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
self.settings = Settings() self.settings = Settings()
self._init_threads() self._init_threads()
self._init_tree_results(self.tr_results) self._init_tree_results_model(self.model_tr_results)
self._init_tree_results(self.tr_results, self.model_tr_results)
self._init_tree_lists(self.tr_lists_user) self._init_tree_lists(self.tr_lists_user)
self._init_tree_queue(self.tr_queue_download) self._init_tree_queue(self.tr_queue_download)
self._init_info() self._init_info()
@@ -213,7 +218,30 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
self.cb_search_type.setCurrentIndex(2) self.cb_search_type.setCurrentIndex(2)
def _init_tree_results(self, tree: QtWidgets.QTableWidget): def handle_filter_activated(self):
header: FilterHeader = self.tr_results.header()
filters = []
for i in range(header.count()):
text: str = header.filter_text(i)
if text:
filters.append((i, text))
proxy_model: HumanProxyModel = self.tr_results.model()
proxy_model.filters = filters
def _init_tree_results(self, tree: QtWidgets.QTreeView, model: QtGui.QStandardItemModel) -> None:
header: FilterHeader = FilterHeader(tree)
self.proxy_tr_results: HumanProxyModel = HumanProxyModel(self)
tree.setHeader(header)
tree.setModel(model)
self.proxy_tr_results.setSourceModel(model)
tree.setModel(self.proxy_tr_results)
header.set_filter_boxes(model.columnCount())
header.filter_activated.connect(self.handle_filter_activated)
## Styling
tree.sortByColumn(0, QtCore.Qt.SortOrder.AscendingOrder) tree.sortByColumn(0, QtCore.Qt.SortOrder.AscendingOrder)
tree.setColumnHidden(1, True) tree.setColumnHidden(1, True)
tree.setColumnWidth(2, 150) tree.setColumnWidth(2, 150)
@@ -224,6 +252,11 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
header.setSectionResizeMode(0, QtWidgets.QHeaderView.ResizeToContents) header.setSectionResizeMode(0, QtWidgets.QHeaderView.ResizeToContents)
def _init_tree_results_model(self, model: QtGui.QStandardItemModel) -> None:
model.setColumnCount(7)
model.setRowCount(0)
model.setHorizontalHeaderLabels(["#", "obj", "Artist", "Title", "Album", "Duration", "Quality"])
def _init_tree_queue(self, tree: QtWidgets.QTableWidget): def _init_tree_queue(self, tree: QtWidgets.QTableWidget):
tree.setColumnHidden(1, True) tree.setColumnHidden(1, True)
tree.setColumnWidth(2, 200) tree.setColumnWidth(2, 200)
@@ -357,28 +390,30 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
self.queue_download_media(queue_dl_item) self.queue_download_media(queue_dl_item)
def search_populate_results(self, query: str, type_media: SearchTypes): def search_populate_results(self, query: str, type_media: SearchTypes):
self.tr_results.clear() self.model_tr_results.removeRows(0, self.model_tr_results.rowCount())
results: [ResultItem] = self.search(query, [type_media]) results: [ResultItem] = self.search(query, [type_media])
self.populate_tree_results(results) self.populate_tree_results(results)
def populate_tree_results(self, results: [ResultItem], parent: QtWidgets.QTreeWidgetItem = None): def populate_tree_results(self, results: [ResultItem], parent: QtGui.QStandardItem = None):
if not parent: if not parent:
self.tr_results.clear() self.model_tr_results.removeRows(0, self.model_tr_results.rowCount())
# Count how many digits the list length has, # Count how many digits the list length has,
count_digits: int = int(math.log10(len(results) if results else 1)) + 1 count_digits: int = int(math.log10(len(results) if results else 1)) + 1
for item in results: for item in results:
child = self.populate_tree_result_child(item=item, index_count_digits=count_digits) child: tuple = self.populate_tree_result_child(item=item, index_count_digits=count_digits)
if parent: if parent:
parent.addChild(child) parent.appendRow(child)
else: else:
self.s_tr_results_add_top_level_item.emit(child) self.s_tr_results_add_top_level_item.emit(child)
def populate_tree_result_child(self, item: [Track | Video | Mix | Album | Playlist], index_count_digits: int): def populate_tree_result_child(
self, item: [Track | Video | Mix | Album | Playlist], index_count_digits: int
) -> Sequence[QStandardItem]:
duration: str = "" duration: str = ""
# TODO: Duration needs to be calculated later to properly fill with zeros. # TODO: Duration needs to be calculated later to properly fill with zeros.
@@ -391,26 +426,30 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
index: str = str(item.position + 1).zfill(index_count_digits) index: str = str(item.position + 1).zfill(index_count_digits)
# Populate child # Populate child
child: QtWidgets.QTreeWidgetItem = QtWidgets.QTreeWidgetItem() child_index: QtGui.QStandardItem = QtGui.QStandardItem(index)
child.setText(0, index) # TODO: Move to own method
set_results_media(child, item.obj) child_obj: QtGui.QStandardItem = QtGui.QStandardItem()
child.setText(2, item.artist)
child.setText(3, item.title) child_obj.setData(item.obj, QtCore.Qt.ItemDataRole.UserRole)
child.setText(4, item.album) # set_results_media(child, item.obj)
child.setText(5, duration)
child.setText(6, item.quality) child_artist: QtGui.QStandardItem = QtGui.QStandardItem(item.artist)
child_title: QtGui.QStandardItem = QtGui.QStandardItem(item.title)
child_album: QtGui.QStandardItem = QtGui.QStandardItem(item.album)
child_duration: QtGui.QStandardItem = QtGui.QStandardItem(duration)
child_quality: QtGui.QStandardItem = QtGui.QStandardItem(item.quality)
if isinstance(item.obj, Mix | Playlist | Album | Artist): if isinstance(item.obj, Mix | Playlist | Album | Artist):
# Add a disabled dummy child, so expansion arrow will appear. This Child will be replaced on expansion. # Add a disabled dummy child, so expansion arrow will appear. This Child will be replaced on expansion.
child_dummy: QtWidgets.QTreeWidgetItem = QtWidgets.QTreeWidgetItem() child_dummy: QtGui.QStandardItem = QtGui.QStandardItem()
child_dummy.setDisabled(True) child_dummy.setEnabled(False)
child.addChild(child_dummy) child_index.appendRow(child_dummy)
return child return child_index, child_obj, child_artist, child_title, child_album, child_duration, child_quality
def on_tr_results_add_top_level_item(self, widget_item: QtWidgets.QTreeWidgetItem): def on_tr_results_add_top_level_item(self, item_child: Sequence[QtGui.QStandardItem]):
self.tr_results.addTopLevelItem(widget_item) self.model_tr_results.appendRow(item_child)
def on_settings_save(self): def on_settings_save(self):
self.settings.save() self.settings.save()
@@ -625,11 +664,11 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
self.a_version.triggered.connect(self.on_version) self.a_version.triggered.connect(self.on_version)
self.a_preferences.triggered.connect(self.on_preferences) self.a_preferences.triggered.connect(self.on_preferences)
self.a_logout.triggered.connect(self.on_logout) self.a_logout.triggered.connect(self.on_logout)
self.a_updates_check.triggered.connect(lambda x: self.on_update_check(False)) self.a_updates_check.triggered.connect(lambda: self.on_update_check(False))
# Results # Results
self.tr_results.itemExpanded.connect(self.on_tr_results_expanded) self.tr_results.expanded.connect(self.on_tr_results_expanded)
self.tr_results.itemClicked.connect(self.on_result_item_clicked) self.tr_results.clicked.connect(self.on_result_item_clicked)
# Download Queue # Download Queue
self.tr_queue_download.itemClicked.connect(self.on_queue_download_item_clicked) self.tr_queue_download.itemClicked.connect(self.on_queue_download_item_clicked)
@@ -678,8 +717,10 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
self.list_items_show_result(media_list) self.list_items_show_result(media_list)
self.cover_show(media_list) self.cover_show(media_list)
def on_result_item_clicked(self, item: QtWidgets.QTreeWidgetItem, column: int) -> None: def on_result_item_clicked(self, index: QtCore.QModelIndex) -> None:
media: Track | Video | Album | Artist = get_results_media_item(item) media: Track | Video | Album | Artist = get_results_media_item(
index, self.proxy_tr_results, self.model_tr_results
)
self.cover_show(media) self.cover_show(media)
@@ -688,11 +729,6 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
self.cover_show(media) self.cover_show(media)
def on_download_item_clicked(self, item: QtWidgets.QTreeWidgetItem, column: int) -> None:
media: Track | Video | Album | Artist = get_results_media_item(item)
self.cover_show(media)
def cover_show(self, media: Album | Playlist | Track | Video | Album | Artist) -> None: def cover_show(self, media: Album | Playlist | Track | Video | Album | Artist) -> None:
cover_url: str cover_url: str
@@ -715,7 +751,7 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
self, self,
media_list: Album | Playlist | Mix | Artist | None = None, media_list: Album | Playlist | Mix | Artist | None = None,
point: QtCore.QPoint | None = None, point: QtCore.QPoint | None = None,
parent: QtWidgets.QTreeWidgetItem = None, parent: QtGui.QStandardItem = None,
) -> None: ) -> None:
if point: if point:
item = self.tr_lists_user.itemAt(point) item = self.tr_lists_user.itemAt(point)
@@ -766,13 +802,15 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
# TODO: Must happen in main thread. Do not thread this. # TODO: Must happen in main thread. Do not thread this.
def on_download_results(self) -> None: def on_download_results(self) -> None:
items: [QtWidgets.QTreeWidgetItem | None] = self.tr_results.selectedItems() items: [HumanProxyModel | None] = self.tr_results.selectionModel().selectedRows()
if len(items) == 0: if len(items) == 0:
logger_gui.error("Please select a row first.") logger_gui.error("Please select a row first.")
else: else:
for item in items: for item in items:
media: Track | Album | Playlist | Video | Artist = get_results_media_item(item) media: Track | Album | Playlist | Video | Artist = get_results_media_item(
item, self.proxy_tr_results, self.model_tr_results
)
queue_dl_item: QueueDownloadItem = self.media_to_queue_download_model(media) queue_dl_item: QueueDownloadItem = self.media_to_queue_download_model(media)
if queue_dl_item: if queue_dl_item:
@@ -921,15 +959,18 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
def on_preferences(self) -> None: def on_preferences(self) -> None:
DialogPreferences(settings=self.settings, settings_save=self.s_settings_save, parent=self) DialogPreferences(settings=self.settings, settings_save=self.s_settings_save, parent=self)
def on_tr_results_expanded(self, list_item: QtWidgets.QTreeWidgetItem) -> None: def on_tr_results_expanded(self, index: QtCore.QModelIndex) -> None:
# If the child is a dummy the list_item has not been expanded before # If the child is a dummy the list_item has not been expanded before
load_children: bool = list_item.child(0).isDisabled() item: QtGui.QStandardItem = self.model_tr_results.itemFromIndex(self.proxy_tr_results.mapToSource(index))
load_children: bool = not item.child(0, 0).isEnabled()
if load_children: if load_children:
list_item.removeChild(list_item.child(0)) item.removeRow(0)
media_list: [Mix | Album | Playlist | Artist] = list_item.data(1, QtCore.Qt.ItemDataRole.UserRole) media_list: [Mix | Album | Playlist | Artist] = get_results_media_item(
index, self.proxy_tr_results, self.model_tr_results
)
self.list_items_show_result(media_list=media_list, parent=list_item) self.list_items_show_result(media_list=media_list, parent=item)
def button_reload_status(self, status: bool): def button_reload_status(self, status: bool):
button_text: str = "Reloading..." button_text: str = "Reloading..."
+135 -3
View File
@@ -1,4 +1,6 @@
from PySide6 import QtCore, QtWidgets import re
from PySide6 import QtCore, QtGui, QtWidgets
from tidalapi import Album, Mix, Playlist, Track, UserPlaylist, Video from tidalapi import Album, Mix, Playlist, Track, UserPlaylist, Video
from tidalapi.artist import Artist from tidalapi.artist import Artist
from tidalapi.media import Quality from tidalapi.media import Quality
@@ -18,8 +20,12 @@ def get_table_text(item: QtWidgets.QTreeWidgetItem, column: int) -> str:
return result return result
def get_results_media_item(item: QtWidgets.QTreeWidgetItem) -> Track | Video | Album | Artist | Playlist | Mix: def get_results_media_item(
result: Track | Video | Album | Artist | Playlist | Mix = get_table_data(item, 1) index: QtCore.QModelIndex, proxy: QtCore.QSortFilterProxyModel, model: QtGui.QStandardItemModel
) -> Track | Video | Album | Artist | Playlist | Mix:
# Switch column to "obj" column and map proxy data to our model.
item: QtGui.QStandardItem = model.itemFromIndex(proxy.mapToSource(index.siblingAtColumn(1)))
result: Track | Video | Album | Artist = item.data(QtCore.Qt.ItemDataRole.UserRole)
return result return result
@@ -66,3 +72,129 @@ def set_queue_download_media(
item: QtWidgets.QTreeWidgetItem, media: Mix | Playlist | UserPlaylist | Track | Video | Album | Artist item: QtWidgets.QTreeWidgetItem, media: Mix | Playlist | UserPlaylist | Track | Video | Album | Artist
): ):
set_table_data(item, media, 1) set_table_data(item, media, 1)
class FilterHeader(QtWidgets.QHeaderView):
filter_activated = QtCore.Signal()
def __init__(self, parent):
super().__init__(QtCore.Qt.Horizontal, parent)
self._editors = []
self._padding = 4
self.setStretchLastSection(True)
self.setSectionResizeMode(QtWidgets.QHeaderView.Stretch)
self.setDefaultAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter)
self.setSortIndicatorShown(False)
self.setSectionsMovable(True)
self.sectionResized.connect(self.adjust_positions)
parent.horizontalScrollBar().valueChanged.connect(self.adjust_positions)
def set_filter_boxes(self, count):
while self._editors:
editor = self._editors.pop()
editor.deleteLater()
for _ in range(count):
editor = QtWidgets.QLineEdit(self.parent())
editor.setPlaceholderText("Filter")
editor.setClearButtonEnabled(True)
editor.returnPressed.connect(self.filter_activated.emit)
self._editors.append(editor)
self.adjust_positions()
def sizeHint(self):
size = super().sizeHint()
if self._editors:
height = self._editors[0].sizeHint().height()
size.setHeight(size.height() + height + self._padding)
return size
def updateGeometries(self):
if self._editors:
height = self._editors[0].sizeHint().height()
self.setViewportMargins(0, 0, 0, height + self._padding)
else:
self.setViewportMargins(0, 0, 0, 0)
super().updateGeometries()
self.adjust_positions()
def adjust_positions(self):
for index, editor in enumerate(self._editors):
height = editor.sizeHint().height()
editor.move(self.sectionPosition(index) - self.offset() + 2, height + (self._padding // 2))
editor.resize(self.sectionSize(index), height)
def filter_text(self, index) -> str:
if 0 <= index < len(self._editors):
return self._editors[index].text()
return ""
def set_filter_text(self, index, text):
if 0 <= index < len(self._editors):
self._editors[index].setText(text)
def clear_filters(self):
for editor in self._editors:
editor.clear()
class HumanProxyModel(QtCore.QSortFilterProxyModel):
def _human_key(self, key):
parts = re.split(r"(\d*\.\d+|\d+)", key)
return tuple((e.swapcase() if i % 2 == 0 else float(e)) for i, e in enumerate(parts))
def lessThan(self, source_left, source_right):
data_left = source_left.data()
data_right = source_right.data()
if isinstance(data_left, str) and isinstance(data_right, str):
return self._human_key(data_left) < self._human_key(data_right)
return super().lessThan(source_left, source_right)
@property
def filters(self):
if not hasattr(self, "_filters"):
self._filters = []
return self._filters
@filters.setter
def filters(self, filters):
self._filters = filters
self.invalidateFilter()
def filterAcceptsRow(self, source_row: int, source_parent: QtCore.QModelIndex) -> bool:
model = self.sourceModel()
source_index = model.index(source_row, 0, source_parent)
result: [bool] = []
# Show top level children
for child_row in range(model.rowCount(source_index)):
if self.filterAcceptsRow(child_row, source_index):
return True
# Filter for actual needle
for i, text in self.filters:
if 0 <= i < self.columnCount():
ix = self.sourceModel().index(source_row, i, source_parent)
data = ix.data()
# Append results to list to enable an AND operator for filtering.
result.append(bool(text.lower() in str(data).lower()))
# If no filter set, just set the result to True.
if not result:
result.append(True)
return all(result)
+8 -17
View File
@@ -1,7 +1,7 @@
################################################################################ ################################################################################
## Form generated from reading UI file 'main.ui' ## Form generated from reading UI file 'main.ui'
## ##
## Created by: Qt User Interface Compiler version 6.6.2 ## Created by: Qt User Interface Compiler version 6.7.0
## ##
## WARNING! All changes made in this file will be lost when recompiling UI file! ## WARNING! All changes made in this file will be lost when recompiling UI file!
################################################################################ ################################################################################
@@ -21,6 +21,7 @@ from PySide6.QtWidgets import (
QPushButton, QPushButton,
QSizePolicy, QSizePolicy,
QStatusBar, QStatusBar,
QTreeView,
QTreeWidget, QTreeWidget,
QTreeWidgetItem, QTreeWidgetItem,
QVBoxLayout, QVBoxLayout,
@@ -223,7 +224,7 @@ class Ui_MainWindow:
self.lv_search_result.addLayout(self.lh_search) self.lv_search_result.addLayout(self.lh_search)
self.tr_results = QTreeWidget(self.w_central) self.tr_results = QTreeView(self.w_central)
self.tr_results.setObjectName("tr_results") self.tr_results.setObjectName("tr_results")
self.tr_results.setEditTriggers(QAbstractItemView.NoEditTriggers) self.tr_results.setEditTriggers(QAbstractItemView.NoEditTriggers)
self.tr_results.setProperty("showDropIndicator", False) self.tr_results.setProperty("showDropIndicator", False)
@@ -232,8 +233,6 @@ class Ui_MainWindow:
self.tr_results.setSelectionMode(QAbstractItemView.ExtendedSelection) self.tr_results.setSelectionMode(QAbstractItemView.ExtendedSelection)
self.tr_results.setIndentation(10) self.tr_results.setIndentation(10)
self.tr_results.setSortingEnabled(True) self.tr_results.setSortingEnabled(True)
self.tr_results.header().setProperty("showSortIndicator", True)
self.tr_results.header().setStretchLastSection(False)
self.lv_search_result.addWidget(self.tr_results) self.lv_search_result.addWidget(self.tr_results)
@@ -572,22 +571,14 @@ class Ui_MainWindow:
self.pb_reload_user_lists.setText(QCoreApplication.translate("MainWindow", "Reload", None)) self.pb_reload_user_lists.setText(QCoreApplication.translate("MainWindow", "Reload", None))
self.pb_download_list.setText(QCoreApplication.translate("MainWindow", "Download List", None)) self.pb_download_list.setText(QCoreApplication.translate("MainWindow", "Download List", None))
___qtreewidgetitem4 = self.tr_results.headerItem()
___qtreewidgetitem4.setText(6, QCoreApplication.translate("MainWindow", "Quality", None))
___qtreewidgetitem4.setText(5, QCoreApplication.translate("MainWindow", "Duration", None))
___qtreewidgetitem4.setText(4, QCoreApplication.translate("MainWindow", "Album", None))
___qtreewidgetitem4.setText(3, QCoreApplication.translate("MainWindow", "Title", None))
___qtreewidgetitem4.setText(2, QCoreApplication.translate("MainWindow", "Artist", None))
___qtreewidgetitem4.setText(1, QCoreApplication.translate("MainWindow", "obj", None))
___qtreewidgetitem4.setText(0, QCoreApplication.translate("MainWindow", "#", None))
self.te_debug.setPlaceholderText(QCoreApplication.translate("MainWindow", "Logs...", None)) self.te_debug.setPlaceholderText(QCoreApplication.translate("MainWindow", "Logs...", None))
self.l_pm_cover.setText("") self.l_pm_cover.setText("")
self.l_h_queue_download.setText(QCoreApplication.translate("MainWindow", "Download Queue", None)) self.l_h_queue_download.setText(QCoreApplication.translate("MainWindow", "Download Queue", None))
___qtreewidgetitem5 = self.tr_queue_download.headerItem() ___qtreewidgetitem4 = self.tr_queue_download.headerItem()
___qtreewidgetitem5.setText(4, QCoreApplication.translate("MainWindow", "Quality", None)) ___qtreewidgetitem4.setText(4, QCoreApplication.translate("MainWindow", "Quality", None))
___qtreewidgetitem5.setText(3, QCoreApplication.translate("MainWindow", "Type", None)) ___qtreewidgetitem4.setText(3, QCoreApplication.translate("MainWindow", "Type", None))
___qtreewidgetitem5.setText(2, QCoreApplication.translate("MainWindow", "Name", None)) ___qtreewidgetitem4.setText(2, QCoreApplication.translate("MainWindow", "Name", None))
___qtreewidgetitem5.setText(1, QCoreApplication.translate("MainWindow", "obj", None)) ___qtreewidgetitem4.setText(1, QCoreApplication.translate("MainWindow", "obj", None))
self.pb_queue_download_remove.setText(QCoreApplication.translate("MainWindow", "Remove", None)) self.pb_queue_download_remove.setText(QCoreApplication.translate("MainWindow", "Remove", None))
self.pb_queue_download_clear_finished.setText(QCoreApplication.translate("MainWindow", "Clear Finished", None)) self.pb_queue_download_clear_finished.setText(QCoreApplication.translate("MainWindow", "Clear Finished", None))
self.pb_queue_download_clear_all.setText(QCoreApplication.translate("MainWindow", "Clear All", None)) self.pb_queue_download_clear_all.setText(QCoreApplication.translate("MainWindow", "Clear All", None))
+1 -42
View File
@@ -294,7 +294,7 @@
</layout> </layout>
</item> </item>
<item> <item>
<widget class="QTreeWidget" name="tr_results"> <widget class="QTreeView" name="tr_results">
<property name="editTriggers"> <property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set> <set>QAbstractItemView::NoEditTriggers</set>
</property> </property>
@@ -316,47 +316,6 @@
<property name="sortingEnabled"> <property name="sortingEnabled">
<bool>true</bool> <bool>true</bool>
</property> </property>
<attribute name="headerShowSortIndicator" stdset="0">
<bool>true</bool>
</attribute>
<attribute name="headerStretchLastSection">
<bool>false</bool>
</attribute>
<column>
<property name="text">
<string>#</string>
</property>
</column>
<column>
<property name="text">
<string>obj</string>
</property>
</column>
<column>
<property name="text">
<string>Artist</string>
</property>
</column>
<column>
<property name="text">
<string>Title</string>
</property>
</column>
<column>
<property name="text">
<string>Album</string>
</property>
</column>
<column>
<property name="text">
<string>Duration</string>
</property>
</column>
<column>
<property name="text">
<string>Quality</string>
</property>
</column>
</widget> </widget>
</item> </item>
<item> <item>