Merge dev

This commit is contained in:
Keith Edmunds 2024-12-11 12:49:01 +00:00
commit d7751008bd
11 changed files with 1309 additions and 111 deletions

View File

@ -12,6 +12,7 @@ from typing import Any, Optional, NamedTuple
# Third party imports
import numpy as np
import pyqtgraph as pg # type: ignore
from sqlalchemy.orm.session import Session
import vlc # type: ignore
# PyQt imports
@ -761,6 +762,17 @@ class RowAndTrack:
self.fade_graph.tick(self.time_playing())
def update_playlist_and_row(self, session: Session) -> None:
"""
Update local playlist_id and row_number from playlistrow_id
"""
plr = session.get(PlaylistRows, self.playlistrow_id)
if not plr:
raise ApplicationError(f"(Can't retrieve PlaylistRows entry, {self=}")
self.playlist_id = plr.playlist_id
self.row_number = plr.row_number
@dataclass
class TrackFileData:

View File

@ -85,6 +85,8 @@ class Config(object):
OBS_PORT = 4455
PLAY_NEXT_GUARD_MS = 10000
PLAY_SETTLE = 500000
PLAYLIST_ICON_CURRENT = ":/icons/green-circle.png"
PLAYLIST_ICON_NEXT = ":/icons/yellow-circle.png"
PREVIEW_ADVANCE_MS = 5000
PREVIEW_BACK_MS = 5000
PREVIEW_END_BUFFER_MS = 1000

View File

@ -479,9 +479,7 @@ class PlaylistRows(dbtables.PlaylistRowsTable):
"""
plrs = session.scalars(
select(cls)
.where(cls.playlist_id == playlist_id)
.order_by(cls.row_number)
select(cls).where(cls.playlist_id == playlist_id).order_by(cls.row_number)
).all()
return plrs
@ -566,7 +564,10 @@ class PlaylistRows(dbtables.PlaylistRowsTable):
@staticmethod
@line_profiler.profile
def update_plr_row_numbers(
session: Session, playlist_id: int, sqla_map: List[dict[str, int]], dummy_for_profiling=None
session: Session,
playlist_id: int,
sqla_map: List[dict[str, int]],
dummy_for_profiling=None,
) -> None:
"""
Take a {plrid: row_number} dictionary and update the row numbers accordingly

View File

@ -26,6 +26,7 @@ from PyQt6.QtCore import (
from PyQt6.QtGui import (
QCloseEvent,
QColor,
QIcon,
QKeySequence,
QPalette,
QShortcut,
@ -460,7 +461,7 @@ class Window(QMainWindow, Ui_MainWindow):
self.actionImport.triggered.connect(self.import_track)
self.actionInsertSectionHeader.triggered.connect(self.insert_header)
self.actionInsertTrack.triggered.connect(self.insert_track)
self.actionMark_for_moving.triggered.connect(self.cut_rows)
self.actionMark_for_moving.triggered.connect(self.mark_rows_for_moving)
self.actionMoveSelected.triggered.connect(self.move_selected)
self.actionNew_from_template.triggered.connect(self.new_from_template)
self.actionNewPlaylist.triggered.connect(self.create_and_show_playlist)
@ -564,18 +565,6 @@ class Window(QMainWindow, Ui_MainWindow):
log.debug(f"create_playlist_tab() returned: {idx=}")
return idx
def cut_rows(self) -> None:
"""
Cut rows ready for pasting.
"""
# Save the selected PlaylistRows items ready for a later
# paste
self.move_source_rows = self.active_tab().get_selected_rows()
self.move_source_model = self.active_proxy_model()
log.debug(f"cut_rows(): {self.move_source_rows=} {self.move_source_model=}")
def debug(self):
"""Invoke debugger"""
@ -929,6 +918,18 @@ class Window(QMainWindow, Ui_MainWindow):
self.signals.search_wikipedia_signal.emit(track_info.title)
def mark_rows_for_moving(self) -> None:
"""
Cut rows ready for pasting.
"""
# Save the selected PlaylistRows items ready for a later
# paste
self.move_source_rows = self.active_tab().get_selected_rows()
self.move_source_model = self.active_proxy_model()
log.debug(f"mark_rows_for_moving(): {self.move_source_rows=} {self.move_source_model=}")
def move_playlist_rows(self, row_numbers: List[int]) -> None:
"""
Move passed playlist rows to another playlist
@ -964,6 +965,16 @@ class Window(QMainWindow, Ui_MainWindow):
row_numbers, to_row, to_playlist_id
)
# Reset track_sequences
with db.Session() as session:
for ts in [
track_sequence.next,
track_sequence.current,
track_sequence.previous,
]:
if ts:
ts.update_playlist_and_row(session)
def move_selected(self) -> None:
"""
Move selected rows to another playlist
@ -1814,6 +1825,38 @@ class Window(QMainWindow, Ui_MainWindow):
else:
self.hdrNextTrack.setText("")
self.update_playlist_icons()
def update_playlist_icons(self) -> None:
"""
Set current / next playlist tab icons
"""
# Do we need to set a 'next' icon?
set_next = True
if (
track_sequence.current
and track_sequence.next
and track_sequence.current.playlist_id == track_sequence.next.playlist_id
):
set_next = False
for idx in range(self.tabBar.count()):
widget = self.tabPlaylist.widget(idx)
if (
track_sequence.next
and set_next
and widget.playlist_id == track_sequence.next.playlist_id
):
self.tabPlaylist.setTabIcon(idx, QIcon(Config.PLAYLIST_ICON_NEXT))
elif (
track_sequence.current
and widget.playlist_id == track_sequence.current.playlist_id
):
self.tabPlaylist.setTabIcon(idx, QIcon(Config.PLAYLIST_ICON_CURRENT))
else:
self.tabPlaylist.setTabIcon(idx, QIcon())
class DownloadCSV(QDialog):
def __init__(self, parent=None):

View File

@ -40,6 +40,7 @@ from classes import (
)
from config import Config
from helpers import (
ask_yes_no,
file_is_unreadable,
get_embedded_time,
get_relative_date,
@ -67,7 +68,7 @@ class PlaylistModel(QAbstractTableModel):
database
refresh_data() will repopulate all of playlist_rows from the
database
database.
"""
def __init__(
@ -155,10 +156,18 @@ class PlaylistModel(QAbstractTableModel):
if file_is_unreadable(rat.path):
return QBrush(QColor(Config.COLOUR_UNREADABLE))
# Current track
if track_sequence.current and track_sequence.current.row_number == row:
if (
track_sequence.current
and track_sequence.current.playlist_id == self.playlist_id
and track_sequence.current.row_number == row
):
return QBrush(QColor(Config.COLOUR_CURRENT_PLAYLIST))
# Next track
if track_sequence.next and track_sequence.next.row_number == row:
if (
track_sequence.next
and track_sequence.next.playlist_id == self.playlist_id
and track_sequence.next.row_number == row
):
return QBrush(QColor(Config.COLOUR_NEXT_PLAYLIST))
# Individual cell colouring
@ -738,7 +747,9 @@ class PlaylistModel(QAbstractTableModel):
self.invalidate_rows(row_numbers)
@line_profiler.profile
def move_rows(self, from_rows: list[int], to_row_number: int, dummy_for_profiling=None) -> None:
def move_rows(
self, from_rows: list[int], to_row_number: int, dummy_for_profiling=None
) -> None:
"""
Move the playlist rows given to to_row and below.
"""
@ -805,8 +816,11 @@ class PlaylistModel(QAbstractTableModel):
@line_profiler.profile
def move_rows_between_playlists(
self, from_rows: list[int], to_row_number: int, to_playlist_id: int,
dummy_for_profiling=None
self,
from_rows: list[int],
to_row_number: int,
to_playlist_id: int,
dummy_for_profiling=None,
) -> None:
"""
Move the playlist rows given to to_row and below of to_playlist.
@ -826,7 +840,6 @@ class PlaylistModel(QAbstractTableModel):
self.signals.begin_reset_model_signal.emit(to_playlist_id)
with db.Session() as session:
for row_group in row_groups:
# Make room in destination playlist
max_destination_row_number = PlaylistRows.get_last_used_row(
@ -981,8 +994,43 @@ class PlaylistModel(QAbstractTableModel):
@line_profiler.profile
def refresh_data(self, session: db.session, dummy_for_profiling=None) -> None:
"""
Populate self.playlist_rows with playlist data
We used to clear self.playlist_rows each time but that's
expensive and slow on big playlists. Instead we track where rows
are in database versus self.playlist_rows and fixup the latter.
This works well for news rows added and for rows moved, but
doesn't work for changed comments so they must be handled using
refresh_row().
"""
# Note where each playlist_id is
plid_to_row: dict[int, int] = {}
for oldrow in self.playlist_rows:
plrdata = self.playlist_rows[oldrow]
plid_to_row[plrdata.playlistrow_id] = plrdata.row_number
# build a new playlist_rows
new_playlist_rows: dict[int, RowAndTrack] = {}
for p in PlaylistRows.get_playlist_rows(session, self.playlist_id):
if p.id not in plid_to_row:
new_playlist_rows[p.row_number] = RowAndTrack(p)
else:
new_playlist_rows[p.row_number] = self.playlist_rows[plid_to_row[p.id]]
new_playlist_rows[p.row_number].row_number = p.row_number
# Copy to self.playlist_rows
self.playlist_rows = new_playlist_rows
def load_data(self, session: db.session, dummy_for_profiling=None) -> None:
"""Populate self.playlist_rows with playlist data"""
# Same as refresh data, but only used when creating playslit.
# Distinguishes profile time between initial load and other
# refreshes.
# We used to clear self.playlist_rows each time but that's
# expensive and slow on big playlists
@ -1090,13 +1138,43 @@ class PlaylistModel(QAbstractTableModel):
track_sequence.current,
track_sequence.previous,
]:
if ts and ts.playlist_id == self.playlist_id and ts.row_number:
playlist_row = session.get(PlaylistRows, ts.playlistrow_id)
if playlist_row and playlist_row.row_number != ts.row_number:
ts.row_number = playlist_row.row_number
if ts:
ts.update_playlist_and_row(session)
self.update_track_times()
def remove_comments(self, row_numbers: list[int]) -> None:
"""
Remove comments from passed rows
"""
if not row_numbers:
return
# Safety check
if not ask_yes_no(
title="Remove comments",
question=f"Remove comments from {len(row_numbers)} rows?"
):
return
with db.Session() as session:
for row_number in row_numbers:
playlist_row = session.get(
PlaylistRows, self.playlist_rows[row_number].playlistrow_id
)
if playlist_row.track_id:
playlist_row.note = ""
# We can't use refresh_data() because its
# optimisations mean it won't update comments in
# self.playlist_rows
# The "correct" approach would be to re-read from the
# database but we optimise here by simply updating
# self.playlist_rows directly.
self.playlist_rows[row_number].note = ""
session.commit()
self.invalidate_rows(row_numbers)
def _reversed_contiguous_row_groups(
self, row_numbers: list[int]
) -> list[list[int]]:

View File

@ -483,6 +483,13 @@ class PlaylistTab(QTableView):
self._add_context_menu(
"Rescan track", lambda: self._rescan(model_row_number)
)
self._add_context_menu(
"Mark for moving", lambda: self._mark_for_moving()
)
if self.musicmuster.move_source_rows:
self._add_context_menu(
"Move selected rows here", lambda: self._move_selected_rows()
)
# ----------------------
self.menu.addSeparator()
@ -498,6 +505,9 @@ class PlaylistTab(QTableView):
lambda: proxy_model.remove_track(model_row_number),
)
# Remove comments
self._add_context_menu("Remove comments", lambda: self._remove_comments())
# Add track to section header (ie, make this a track row)
if header_row:
self._add_context_menu("Add a track", lambda: self._add_track())
@ -740,6 +750,20 @@ class PlaylistTab(QTableView):
self.source_model.mark_unplayed(row_numbers)
self.clear_selection()
def _mark_for_moving(self) -> None:
"""
Mark selected rows for pasting
"""
self.musicmuster.mark_rows_for_moving()
def _move_selected_rows(self) -> None:
"""
Move selected rows here
"""
self.musicmuster.paste_rows()
def _open_in_audacity(self, row_number: int) -> None:
"""
Open track in passed row in Audacity
@ -757,6 +781,17 @@ class PlaylistTab(QTableView):
except ApplicationError as e:
show_warning(self.musicmuster, "Audacity error", str(e))
def _remove_comments(self) -> None:
"""
Remove comments from selected rows
"""
row_numbers = self.selected_model_row_numbers()
if not row_numbers:
return
self.source_model.remove_comments(row_numbers)
def _rescan(self, row_number: int) -> None:
"""Rescan track"""

BIN
app/ui/green-circle.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

View File

@ -1,5 +1,7 @@
<RCC>
<qresource prefix="icons">
<file>yellow-circle.png</file>
<file>green-circle.png</file>
<file>star.png</file>
<file>star_empty.png</file>
<file>record-red-button.png</file>

View File

@ -5154,6 +5154,430 @@ I\x92$I\x92$I\x92$I\x92$I\x92$I\
$I\x92$I\x92$I\x92$I\x92$I\x92\xa4\
U\xfd/\xdc\xe3\x0a%XB:O\x00\x00\x00\x00I\
END\xaeB`\x82\
\x00\x00\x1aX\
\x89\
PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\
\x00\x02\x00\x00\x00\x02\x00\x08\x06\x00\x00\x00\xf4x\xd4\xfa\
\x00\x00\x00\xc5zTXtRaw prof\
ile type exif\x00\x00x\
\xdamP\xdb\x0d\x830\x0c\xfc\xf7\x14\x1d!~\x908\
\xe3\x04H\xa5n\xd0\xf1\xeb`\xa7\x02\x84\xa5\x9c\xcd\x1d\
:?\xa0\x7f?ox\x8d \x14\x90\xa5h\xae9'\
\x0b\xa9R\xa9Y\xa1\xc9\xa3\x1d\x88I\x0e\x9cA\xc1^\
x\xf8\x0bd\x14[f\x174{\xc6\xc9O\xa3\xc8\xd8\
\xacZNF\xba\x85\xb0^\x85*\xd1^oF\xd1\x88\
\xc7Dc\x84=\x8cj\x181\xb9\x80a\xd0|\xad\x94\
\xab\x96\xf3\x0akO\xd7P\x7f0`\xeb\xbe\x1eF\xb7\
\xfb\xb7\x14\xbb\xde\xbe\x18\xc9D\x9d\x8d6d\x16\x1f\x80\
\xc7\x13\xe0f\x02\x19&.\xf6#r\xb1\x9a\xb8\x1e8\
'\xb1\x83<\xddi\x06\xfc\x00<\xd0Y\xd6\xc84}\
\xda\x00\x00\x01\x84iCCPICC pro\
file\x00\x00x\x9c}\x91=H\xc3@\x1c\xc5\
_S\xa5\x22\x15\x11;\x88:d\xa8Nv\xf1\x0b\xc7\
Z\x85\x22T\x08\xb5B\xab\x0e&\x97~\x08M\x1a\x92\
\x14\x17G\xc1\xb5\xe0\xe0\xc7b\xd5\xc1\xc5YW\x07W\
A\x10\xfc\x00qvpRt\x91\x12\xff\x97\x14Z\xc4\
xp\xdc\x8fw\xf7\x1ew\xef\x00\xa1^f\x9a\xd5\x11\
\x074\xdd6\xd3\xc9\x84\x98\xcd\xad\x88\xa1W\x84\x11B\
\x1f\x860%3\xcb\x98\x95\xa4\x14|\xc7\xd7=\x02|\
\xbd\x8b\xf1,\xffs\x7f\x8e\x1e5o1 \x12\xc7\
\x99a\xda\xc4\xeb\xc4\xd3\x9b\xb6\xc1y\x9f8\xc2J\xb2\
J|N<f\xd2\x05\x89\x1f\xb9\xaex\xfc\xc6\xb9\xe8\
\xb2\xc03#f&=G\x1c!\x16\x8bm\xac\xb41\
+\x99\x1a\xf1$qT\xd5t\xca\x17\xb2\x1e\xab\x9c\xb7\
8k\xe5*k\xde\x93\xbf0\x9c\xd7\x97\x97\xb8Ns\
\x18I,`\x11\x12D(\xa8b\x03e\xd8\x88\xd1\xaa\
\x93b!M\xfb\x09\x1f\xff\xa0\xeb\x97\xc8\xa5\x90k\x03\
\x8c\x1c\xf3\xa8@\x83\xec\xfa\xc1\xff\xe0w\xb7Vab\
\xdcK\x0a'\x80\xce\x17\xc7\xf9\x18\x01B\xbb@\xa3\xe6\
8\xdf\xc7\x8e\xd38\x01\x82\xcf\xc0\x95\xde\xf2W\xea\xc0\
\xcc'\xe9\xb5\x96\x16=\x02z\xb7\x81\x8b\xeb\x96\xa6\xec\
\x01\x97;\xc0\xc0\x93!\x9b\xb2+\x05i\x0a\x85\x02\xf0\
~F\xdf\x94\x03\xfao\x81\xeeU\xaf\xb7\xe6>N\x1f\
\x80\x0cu\x95\xba\x01\x0e\x0e\x81\xd1\x22e\xaf\xf9\xbc\xbb\
\xab\xbd\xb7\x7f\xcf4\xfb\xfb\x01\xbfSr\xc5n=\xc5\
\x13\x00\x00\x0e[iTXtXML:com\
.adobe.xmp\x00\x00\x00\x00\x00<\
?xpacket begin=\x22\
\xef\xbb\xbf\x22 id=\x22W5M0MpC\
ehiHzreSzNTczkc9\
d\x22?>\x0a<x:xmpmeta \
xmlns:x=\x22adobe:n\
s:meta/\x22 x:xmptk\
=\x22XMP Core 4.4.0\
-Exiv2\x22>\x0a <rdf:R\
DF xmlns:rdf=\x22ht\
tp://www.w3.org/\
1999/02/22-rdf-s\
yntax-ns#\x22>\x0a <r\
df:Description r\
df:about=\x22\x22\x0a \
xmlns:xmpMM=\x22htt\
p://ns.adobe.com\
/xap/1.0/mm/\x22\x0a \
xmlns:stEvt=\x22h\
ttp://ns.adobe.c\
om/xap/1.0/sType\
/ResourceEvent#\x22\
\x0a xmlns:dc=\x22h\
ttp://purl.org/d\
c/elements/1.1/\x22\
\x0a xmlns:GIMP=\
\x22http://www.gimp\
.org/xmp/\x22\x0a x\
mlns:tiff=\x22http:\
//ns.adobe.com/t\
iff/1.0/\x22\x0a xm\
lns:xmp=\x22http://\
ns.adobe.com/xap\
/1.0/\x22\x0a xmpMM:\
DocumentID=\x22gimp\
:docid:gimp:66ad\
c484-6096-437b-a\
a0d-3b0c0a65c53d\
\x22\x0a xmpMM:Insta\
nceID=\x22xmp.iid:6\
00b1000-6c7f-476\
2-8fe3-9531ebbc8\
723\x22\x0a xmpMM:Or\
iginalDocumentID\
=\x22xmp.did:9f854f\
62-b4a5-42e7-98c\
2-a9cc8ee1f29f\x22\x0a\
dc:Format=\x22im\
age/png\x22\x0a GIMP\
:API=\x222.0\x22\x0a GI\
MP:Platform=\x22Lin\
ux\x22\x0a GIMP:Time\
Stamp=\x22173359256\
6381835\x22\x0a GIMP\
:Version=\x222.10.3\
4\x22\x0a tiff:Orien\
tation=\x221\x22\x0a xm\
p:CreatorTool=\x22G\
IMP 2.10\x22\x0a xmp\
:MetadataDate=\x222\
024:12:07T17:29:\
24+00:00\x22\x0a xmp\
:ModifyDate=\x22202\
4:12:07T17:29:24\
+00:00\x22>\x0a <xmp\
MM:History>\x0a \
<rdf:Seq>\x0a <\
rdf:li\x0a stE\
vt:action=\x22saved\
\x22\x0a stEvt:ch\
anged=\x22/\x22\x0a \
stEvt:instanceID\
=\x22xmp.iid:0eb6ed\
ca-2091-4bcf-976\
3-62819213ae14\x22\x0a\
stEvt:soft\
wareAgent=\x22Gimp \
2.10 (Linux)\x22\x0a \
stEvt:when=\x22\
2024-05-06T17:21\
:44+01:00\x22/>\x0a \
<rdf:li\x0a \
stEvt:action=\x22sa\
ved\x22\x0a stEvt\
:changed=\x22/\x22\x0a \
stEvt:instanc\
eID=\x22xmp.iid:b7c\
9a22b-cd77-4f39-\
b09a-81e90c02ece\
2\x22\x0a stEvt:s\
oftwareAgent=\x22Gi\
mp 2.10 (Linux)\x22\
\x0a stEvt:whe\
n=\x222024-12-07T17\
:29:26+00:00\x22/>\x0a\
</rdf:Seq>\x0a \
</xmpMM:Histor\
y>\x0a </rdf:Descr\
iption>\x0a </rdf:R\
DF>\x0a</x:xmpmeta>\
\x0a \
\
\
\
\
\
\x0a \
\
\
\
\
\
\x0a \
\
\
\
\
\
\x0a\
\
\
\
\
\
\
\x0a \
\
\
\
\
\
\x0a \
\
\
\
\
\
\x0a \
\
\
\
\
\
\
\x0a \
\
\
\
\
\
\x0a \
\
\
\
\
\
\x0a \
\
\
\
\
\
\
\x0a \
\
\
\
\
\
\x0a \
\
\
\
\
\
\x0a \
\
\
\
\
\
\
\x0a \
\
\
\
\
\
\x0a \
\
\
\
\
\
\x0a \
\
\
\
\
\
\
\x0a \
\
\
\
\
\
\x0a \
\
\
\
\
\
\x0a \
\
\
\
\
\
\x0a\
\
\
\
\
\
\
\x0a \
\
\x0a<?xpacket end=\x22\
w\x22?>\x99\xb0bn\x00\x00\x00\x06bKGD\
\x00\xff\x00\xff\x00\xff\xa0\xbd\xa7\x93\x00\x00\x00\x09pH\
Ys\x00\x00\x0e\xc3\x00\x00\x0e\xc3\x01\xc7o\xa8d\x00\
\x00\x00\x07tIME\x07\xe8\x0c\x07\x11\x1d\x1aq\x0e\
\xba\xd6\x00\x00\x09\x1dIDATx\xda\xed\xdc\xdd\x8d\
\xea\xca\x16\x85Q\xe8X\x9c \x91\x90\xa0s\x81\x07\x9e\
L[\x08\xaaj\xd5\xef\x18\x09\x5ciK\xe7\xce\xcf\xcb\
\xa6/\x17\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe0\xe0\xea\x9f\x00\
\xc6\xb6\xdd\xb7G\x8b\xff\xdd\xfd\xb6\xfb\xff\x0f\x10\x00\xc0\
L\xe3.\x12@\x00\x00\x86^\x18\x80\x00\x00\x0c\xbd0\
\x00\x01\x00\x18|A\x00\x02\x00\x0c\xbe\xc1\x17\x04 \x00\
\xc0\xe0#\x08@\x00\x80\xd1G\x0c\x80\x00\x00\xa3\x8f\x18\
\x00\x01\x00F\x1f1\x00\x02\x00\x8c>b\x00\x04\x00\x18\
~\x84\x00\x08\x000\xfa\x88\x01\x10\x00`\xf8\x11\x02 \
\x00\xc0\xe8#\x06@\x00`\xf8A\x08\x80\x00\xc0\xf0\x83\
\x10\x00\x01\x80\xe1\x07!\x80\x00\x00\xc3\x0fB\x00\x01\x00\
\x86\x1f\x84\x00\x02\x00\x0c?\x08\x01\x04\x00\x18~\x10\x02\
\x08\x000\xfe \x02\x10\x00`\xf8\x11\x02 \x00\xc0\xf0\
#\x04@\x00\x80\xf1G\x04\x80\x00\x00\xc3\x8f\x10\x00\x01\
\x80\xe1\x07!\x00\x02\x00\xe3\x0f\x22\x00\x04\x00\x86\x1f\x84\
\x00\x08\x00\x8c?\x88\x00\x10\x00\x18\x7f\x10\x01 \x000\
\xfc \x04@\x00`\xfcA\x04\x80\x00\xc0\xf0\x83\x10@\
\x00\x80\xf1\x07\x11\x80\x00\x00\xe3\x0f\x22\x00\x01\x00\xc6\x1f\
D\x00\x02\x00\x0c?\x08\x01\x04\x00\xc6\xdf\xf8\x83\x08@\
\x00`\xfc\x01\x11\x80\x00\xc0\xf8\x03\x22\x00\x01\x80\xf1\x07\
D\x00\x02\x00\xe3\x0f\x88\x00\x04\x00\x86\x1f\x10\x02\x08\x00\
\x8c? \x02\x10\x00\x18\x7f@\x04 \x000\xfe\x80\x08\
@\x00`\xfc\x01\x11\x80\x00\xc0\xf8\x83\x08\x10\x01\x08\x00\
\x8c?\x88\x00\x10\x00\x18\x7f\x10\x01\x08\x000\xfe \x02\
\x10\x00\x18\x7f@\x04 \x000\xfe\x80\x08@\x00`\xfc\
\x01\x11\xc0\xd8\xfe\xfc\x13\x00\x80\x0b\x00\x9e\xfe\x01W\x00\
\x04\x00\xc6\x1f\x10\x01\x08\x00\x8c? \x02\x10\x00\x18\x7f\
@\x04 \x000\xfe\x80\x08@\x00`\xfc\x01\x11@\xaf\
\xfc\x0c\x10\x00\x5c\x00\xf0\xf4\x0f\xb8\x02\xb8\x02\x08\x00\x8c\
? \x02\x10\x00\x18\x7f@\x04 \x000\xfe\x80\x08`\
P>\x02\x04\x00\x17\x00<\xfd\x03\xb8\x02\x08\x00\x8c?\
\x80\x08\x98\x92W\x00\x00\xe0\x02\x80\xa7\x7f\x00W\x00\x01\
\x80\xf1\x07\x10\x01\x02\x00\xe3\x0f \x02\xe6\xe0\x1b\x00\x00\
p\x01\xc0\xd3?\x80+\x80\x00\xc0\xf8\x03\x88\x80)y\
\x05\x00\x00.\x00x\xfa\x07p\x05p\x01\x00\x00\x5c\x00\
\xf0\xf4\x0f\xe0\x0a \x000\xfe\x00\x22`P^\x01\x00\
\x80\x0b\x00\x9e\xfe\x01\x5c\x01\x5c\x00\x00\x00\x17\x00<\xfd\
\x03\xb8\x02\x08\x00\x8c?\x80\x08\x18\x94W\x00\x00\xe0\x02\
\x80\xa7\x7f\x00W\x00\x17\x00\x00\xc0\x05\x00O\xff\x00\xae\
\x00.\x00\x00\x80\x0b\x00\x9e\xfe\x01\x5c\x01\x5c\x00\x00\x00\
\x17\x00<\xfd\x03\xae\x00\xb8\x00\x00\x00.\x00x\xfa\x07\
\x5c\x01p\x01\x00\x00\x5c\x00<\xfd\x03\xb8\x02\xe0\x02\x00\
\x00\xb8\x00x\xfa\x07p\x05\xc0\x05\x00\x00\x10\x00\x00\xc0\
\x7fN1\x9dp\xfe\x07V\xe15\x80\x0b\x00\x00\xe0\x02\
\xe0\xe9\x1f\xc0\x15\x00\x17\x00\x00@\x00\x00\x00\xe58\xc1\
4\xe6\xfc\x0f\xac\xcak\x00\x17\x00\x00\xc0\x05\xc0\xd3?\
\x80+\x00.\x00\x00\x80\x00\x00\x00\xf29\xbd4\xe2\xfc\
\x0f\xf0\xe25\x80\x0b\x00\x00 \x00\x00\x80(\xce.\x0d\
8\xff\x03\x1cy\x0d\xe0\x02\x00\x00\x08\x00\x00 \x82\x93\
Ke\xce\xff\x00\xe7\xbc\x06p\x01\x00\x00\x04\x00\x00P\
\x9asKE\xce\xff\x00\x9fy\x0d\xe0\x02\x00\x00\x08\x00\
\x00@\x00\x00\x00Y\xbck\xa9\xc4\xfb\x7f\x80\xef\xf8\x0e\
\xc0\x05\x00\x00\x10\x00\x00\x80\x00\x00\x00\x92y\xcfR\x81\
\xf7\xff\x00\xbf\xf1\x1d\x80\x0b\x00\x00 \x00\x00\x00\x01\x00\
\x00$\xf1\x8e%\x98\xf7\xff\x00i|\x07\xe0\x02\x00\x00\
\x08\x00\x00@\x00\x00\x00\x02\x00\x00\x10\x00\x00\xc0\x09_\
X\x06\xf2\x0b\x00\x80<~\x09\xe0\x02\x00\x00\x08\x00\x00\
@\x00\x00\x00\x02\x00\x00\x10\x00\x00\xc0\x1b_W\x06\xf1\
\x0b\x00\x802\xfc\x12\xc0\x05\x00\x00\x10\x00\x00\x80\x00\x00\
\x00\x04\x00\x00 \x00\x00\x00\x01\x00\x00\x02\x00\x00\x10\x00\
\x00\xc0\xec\xfcq\x85\x00\xfe\x08\x10@Y\xfe\x18\x90\x0b\
\x00\x00 \x00\x00\x00\x01\x00\x00\x08\x00\x00@\x00\x00\x00\
\x02\x00\x00\x04\x00\x00 \x00\x00\x00\x01\x00\x00\x08\x00\x00\
@\x00\x00\x00\x02\x00\x00\x10\x00\x00\x80\x00\x00\x00\x04\x00\
\x00 \x00\x00\x00\x01\x00\x00\x08\x00\x00@\x00\x00\x00\x02\
\x00\x00\x10\x00\x00\x80\x00\x00\x00\x04\x00\x00\x08\x00\x00@\
\x00\x00\x00\x02\x00\x00\x10\x00\x00\x80\x00\x00\x00\x04\x00\x00\
0\x80\xab\x7f\x82\x18\xdb}{\xf8W\x00\xc8\xb7\xdfv\
[\xe5\x02\x00\x00\x08\x00\x00@\x00\x00\x00\x02\x00\x00\x10\
\x00\x00\x80\x00\x00\x00\x01\x00\x00\x08\x00\x00`j\xfe\xb8\
B \x7f\x0c\x08 \x8f?\x02\xe4\x02\x00\x00\x08\x00\x00\
@\x00\x00\x00\x02\x00\x00\x10\x00\x00\xc0\x1b_W\x06\xf3\
K\x00\x804~\x01\xe0\x02\x00\x00\x08\x00\x00@\x00\x00\
\x00\x02\x00\x00\x10\x00\x00\xc0\x09_XV\xe0\x97\x00\x00\
\xbf\xf1\x0b\x00\x17\x00\x00@\x00\x00\x00\x02\x00\x00H\xe2\
\x1dK%\xbe\x03\x00\xf8\x8e\xf7\xff.\x00\x00\x80\x00\x00\
\x00\x04\x00\x00\x90\xcc{\x96\x8a|\x07\x00\xf0\x99\xf7\xff\
.\x00\x00\x80\x00\x00\x00\x04\x00\x00\x90\xc5\xbb\x96\xca|\
\x07\x00p\xce\xfb\x7f\x17\x00\x00@\x00\x00\x00\xa59\xb7\
4\xe05\x00\xc0\x91\xf3\xbf\x0b\x00\x00 \x00\x00\x80\x08\
N.\x8dx\x0d\x00\xf0\xe2\xfc\xef\x02\x00\x00\x08\x00\x00\
\x8a\xb3KC^\x03\x00\xabs\xfew\x01\x00\x00\x04\
\x00\x00\x10\xc9\xe9\xa51\xaf\x01\x80U9\xff\xbb\x00\x00\
\x00.\x00\xae\x00\x00\x9e\xfeq\x01\x00\x00\x04\x00\x00\x90\
\xcf\x09\xa6\x13^\x03\x00\xabp\xfew\x01\x00\x00\x5c\x00\
p\x05\x00<\xfd\xe3\x02\x00\x00\x08\x00\x00\xa0\x1c\xa7\x98\
\xcex\x0d\x00\xcc\xca\xf9\xdf\x05\x00\x00p\x01\xc0\x15\x00\
\xf0\xf4\x8f\x0b\x00\x00\xe0\x02\xe0\x0a\x00\xe0\xe9\x1f\x17\x00\
\x00\xc0\x05\xc0\x15\x00\xc0\xd3?.\x00\x00\x80\x0b\x80+\
\x00\x80\xa7\x7f\x5c\x00\x00\x00\x17\x00W\x00\x00O\xff.\
\x00\x00\x80\x0b\x00\xae\x00\x00\x9e\xfe]\x00\x00\x00\x17\x00\
\x5c\x01\x00<\xfd\x0b\x00D\x00\x80\xf1\x1f\x8cW\x00\x00\
\xe0\x02\x80+\x00\x80\xa7\x7f\x17\x00\x00\xc0\x05\x00W\x00\
\x00O\xff\x02\x00\x11\x00\x18\x7f;2(\xaf\x00\x00\xc0\
\x05\x00W\x00\x00O\xff.\x00\x00\x80\x0b\x00\xae\x00\x00\
\x9e\xfe\x05\x00\x22\x000\xfe\x0c\xca+\x00\x00p\x01\xc0\
\x15\x00\xc0\xd3\xbf\x00@\x04\x00\x18\x7f\x01\x80\x08\x00\x8c\
?s\xf0\x0d\x00\x00\xb8\x00\xe0\x0a\x00\xe0\xe9_\x00 \
\x02\x00\xe3\xcf\x94\xbc\x02\x00\xc0\xf8\x0b\x00\xfc\xc7\x0b\xc0\
\x0a\x0c\xc4\x02\xbc\x0a\x00<@ \x00D\x00\x80\xf1G\
\x00\x88\x00\x00\xe3\xbf\x22\xdf\x00\x00\x80\x0b\x00\xae\x00\x80\
\xa7\x7f\x04\x00\x22\x000\xfe\x08\x00D\x00`\xfc\x11\x00\
\x88\x00\xc0\xf8#\x00\x10\x01\x80\xf1G\x00 \x02\x00\xe3\
O\xb7\xfc\x0c\x10\x00\x5c\x00p\x05\x00<\xfd#\x00\x10\
\x01\x80\xf1G\x00 \x02\x00\xe3\x8f\x00@\x04\x00\xc6\x1f\
\x01\x80\x08\x00\x8c?\x02\x00\x11\x00\x18\x7f\x04\x00\x22\x00\
0\xfe\x08\x00D\x00`\xfc\x11\x00\x88\x00\xc0\xf8#\x00\
\x10\x01\x80\xf1G\x00 \x02\x00\xe3\x8f\x00@\x08\x00\x86\
\x1f\x01\x80\x08\x00\xe3\x0f\x02\x00\x11\x00\xc6\x1f\x04\x00\x22\
\x00\x8c?\x08\x00D\x00\x18\x7f\x10\x00\x88\x000\xfe\x08\
\x00\x10\x02`\xf8\x11\x00 \x02\xc0\xf8#\x00@\x04\x80\
\xf1G\x00\x80\x08\x00\xc3\x8f\x00\x00!\x00\xc6\x1f\x01\x00\
\x22\x00\x8c?\x02\x00\x84\x00\x18~\x04\x00\x88\x000\xfe\
\x08\x00D\x00\x18\x7f\x10\x00\x08\x010\xfc \x00\x10\x01\
`\xfcA\x00 \x04\xc0\xf0\x83\x00@\x08\x80\xe1\x07\x01\
\x80\x08\x00\xe3\x0f\x02\x00!\x00\x86\x1f\x04\x00B\x00\x0c\
?\x08\x00D\x00\x18\x7f\x04\x00\x08\x010\xfc\x08\x00\x10\
\x02`\xf8\x11\x00 \x04\xc0\xf0#\x00@\x08`\xf8A\
\x00\x80\x10\xc0\xf0\x83\x00\x00!\x80\xe1\x07\x01\x00B\x00\
\xc3\x0f\x02\x00\xc4\x00F\x1f\x04\x00\x08\x01\x0c?\x08\x00\
\x10\x03\x18}\x10\x00 \x040\xfc \x00@\x0c`\xf4\
A\x00\x80\x18\xc0\xe8\x83\x00\x001`\xf4\x01\x01\x00\x82\
\xc0\xe8\x03\x02\x00\xc4\x80\xc1\x07\x04\x00\x08\x02\x83\x0f\x02\
\x00\x10\x04\x06\x1f\x04\x00 \x0c\x0c=\x08\x00@\x18\x18\
z\x10\x00\x80H0\xee\x00\x00\x00\x00\x00\x00\x00\x00\x00\
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
L\xe6\x09l=\x1eh\xbb\x22\xdfY\x00\x00\x00\x00I\
END\xaeB`\x82\
\x00\x00\x1aS\
\x89\
PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\
@ -6987,6 +7411,432 @@ PH\x00\x00@!\x01\x00\x00\x85\x04\x00\x00\x14\x12\x00\
\x00\x00PH\x00\x00@!\x01\x00\x00\x85\xfe\x17S\xd3\
\xbcN3\xeb\xa5U\x00\x00\x00\x00IEND\xaeB\
`\x82\
\x00\x00\x1az\
\x89\
PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\
\x00\x02\x00\x00\x00\x02\x00\x08\x06\x00\x00\x00\xf4x\xd4\xfa\
\x00\x00\x00\xc6zTXtRaw prof\
ile type exif\x00\x00x\
\xdamP[\x0e\xc30\x08\xfb\xe7\x14;B\x024\x8f\
\xe3\xa4m&\xed\x06;\xfe\x9cB\xa6\xb6\xaa\xa5\x00\xb1\
#\x03\xa1\xfe\xfd\xbc\xe95\xc0QI\x97\x5cRM)\
\x00Z\xb5rCQ\x82\xa1\x1d1\x06=\xe2\x04;{\
\xe1\xe9/0(A\x16\x13J\xb2\x1c'?\x8d<\xc7\
\x86j9\x19\x95\xcd\x85\xf5*T\xf5\xf6\xe5f\xe4\x8d\
dL4F\xd8\xdd\xa8\xba\x91\xb0\x09\xd1\x0d\x9a\xad\x15\
R-\xf9\xbc\xc2\xda\xc3\x15\xc5\x0e\x8d\xb0u[/z\
\xb7\xfb]3~o_@\x0as\x17\xd0\x88\x22j\x03\
\xc88J\xd2 0b\x90\x8c\x87Q2j\xc1m\xf0\
\xd9'\xc1\x87<\xfd\xd3\x04\xfd\x00;\xb0Y\xd0\xf2*\
1\xb7\x00\x00\x01\x84iCCPICC pr\
ofile\x00\x00x\x9c}\x91=H\xc3@\x1c\
\xc5_S\xa5\x22\x15\x11;\x88:d\xa8Nv\xf1\x0b\
\xc7Z\x85\x22T\x08\xb5B\xab\x0e&\x97~\x08M\x1a\
\x92\x14\x17G\xc1\xb5\xe0\xe0\xc7b\xd5\xc1\xc5YW\x07\
WA\x10\xfc\x00qvpRt\x91\x12\xff\x97\x14Z\
\xc4xp\xdc\x8fw\xf7\x1ew\xef\x00\xa1^f\x9a\xd5\
\x11\x074\xdd6\xd3\xc9\x84\x98\xcd\xad\x88\xa1W\x84\x11\
B\x1f\x860%3\xcb\x98\x95\xa4\x14|\xc7\xd7=\x02\
|\xbd\x8b\xf1,\xffs\x7f\x8e\x1e5o1 \x12\
\xc7\x99a\xda\xc4\xeb\xc4\xd3\x9b\xb6\xc1y\x9f8\xc2J\
\xb2J|N<f\xd2\x05\x89\x1f\xb9\xaex\xfc\xc6\xb9\
\xe8\xb2\xc03#f&=G\x1c!\x16\x8bm\xac\xb4\
1+\x99\x1a\xf1$qT\xd5t\xca\x17\xb2\x1e\xab\x9c\
\xb78k\xe5*k\xde\x93\xbf0\x9c\xd7\x97\x97\xb8N\
s\x18I,`\x11\x12D(\xa8b\x03e\xd8\x88\xd1\
\xaa\x93b!M\xfb\x09\x1f\xff\xa0\xeb\x97\xc8\xa5\x90k\
\x03\x8c\x1c\xf3\xa8@\x83\xec\xfa\xc1\xff\xe0w\xb7Va\
b\xdcK\x0a'\x80\xce\x17\xc7\xf9\x18\x01B\xbb@\xa3\
\xe68\xdf\xc7\x8e\xd38\x01\x82\xcf\xc0\x95\xde\xf2W\xea\
\xc0\xcc'\xe9\xb5\x96\x16=\x02z\xb7\x81\x8b\xeb\x96\xa6\
\xec\x01\x97;\xc0\xc0\x93!\x9b\xb2+\x05i\x0a\x85\x02\
\xf0~F\xdf\x94\x03\xfao\x81\xeeU\xaf\xb7\xe6>N\
\x1f\x80\x0cu\x95\xba\x01\x0e\x0e\x81\xd1\x22e\xaf\xf9\xbc\
\xbb\xab\xbd\xb7\x7f\xcf4\xfb\xfb\x01\xbfSr\xc5n=\
\xc5\x13\x00\x00\x0e[iTXtXML:co\
m.adobe.xmp\x00\x00\x00\x00\x00\
<?xpacket begin=\
\x22\xef\xbb\xbf\x22 id=\x22W5M0Mp\
CehiHzreSzNTczkc\
9d\x22?>\x0a<x:xmpmeta\
xmlns:x=\x22adobe:\
ns:meta/\x22 x:xmpt\
k=\x22XMP Core 4.4.\
0-Exiv2\x22>\x0a <rdf:\
RDF xmlns:rdf=\x22h\
ttp://www.w3.org\
/1999/02/22-rdf-\
syntax-ns#\x22>\x0a <\
rdf:Description \
rdf:about=\x22\x22\x0a \
xmlns:xmpMM=\x22ht\
tp://ns.adobe.co\
m/xap/1.0/mm/\x22\x0a \
xmlns:stEvt=\x22\
http://ns.adobe.\
com/xap/1.0/sTyp\
e/ResourceEvent#\
\x22\x0a xmlns:dc=\x22\
http://purl.org/\
dc/elements/1.1/\
\x22\x0a xmlns:GIMP\
=\x22http://www.gim\
p.org/xmp/\x22\x0a \
xmlns:tiff=\x22http\
://ns.adobe.com/\
tiff/1.0/\x22\x0a x\
mlns:xmp=\x22http:/\
/ns.adobe.com/xa\
p/1.0/\x22\x0a xmpMM\
:DocumentID=\x22gim\
p:docid:gimp:66a\
dc484-6096-437b-\
aa0d-3b0c0a65c53\
d\x22\x0a xmpMM:Inst\
anceID=\x22xmp.iid:\
35e7befe-1312-42\
39-acb8-27e7aad8\
cbff\x22\x0a xmpMM:O\
riginalDocumentI\
D=\x22xmp.did:9f854\
f62-b4a5-42e7-98\
c2-a9cc8ee1f29f\x22\
\x0a dc:Format=\x22i\
mage/png\x22\x0a GIM\
P:API=\x222.0\x22\x0a G\
IMP:Platform=\x22Li\
nux\x22\x0a GIMP:Tim\
eStamp=\x2217335926\
19389840\x22\x0a GIM\
P:Version=\x222.10.\
34\x22\x0a tiff:Orie\
ntation=\x221\x22\x0a x\
mp:CreatorTool=\x22\
GIMP 2.10\x22\x0a xm\
p:MetadataDate=\x22\
2024:12:07T17:30\
:17+00:00\x22\x0a xm\
p:ModifyDate=\x2220\
24:12:07T17:30:1\
7+00:00\x22>\x0a <xm\
pMM:History>\x0a \
<rdf:Seq>\x0a \
<rdf:li\x0a st\
Evt:action=\x22save\
d\x22\x0a stEvt:c\
hanged=\x22/\x22\x0a \
stEvt:instanceI\
D=\x22xmp.iid:0eb6e\
dca-2091-4bcf-97\
63-62819213ae14\x22\
\x0a stEvt:sof\
twareAgent=\x22Gimp\
2.10 (Linux)\x22\x0a \
stEvt:when=\
\x222024-05-06T17:2\
1:44+01:00\x22/>\x0a \
<rdf:li\x0a \
stEvt:action=\x22s\
aved\x22\x0a stEv\
t:changed=\x22/\x22\x0a \
stEvt:instan\
ceID=\x22xmp.iid:3e\
800089-7558-4e1a\
-813d-7043d0f502\
d8\x22\x0a stEvt:\
softwareAgent=\x22G\
imp 2.10 (Linux)\
\x22\x0a stEvt:wh\
en=\x222024-12-07T1\
7:30:19+00:00\x22/>\
\x0a </rdf:Seq>\x0a\
</xmpMM:Histo\
ry>\x0a </rdf:Desc\
ription>\x0a </rdf:\
RDF>\x0a</x:xmpmeta\
>\x0a \
\
\
\
\
\
\x0a \
\
\
\
\
\
\x0a \
\
\
\
\
\
\
\x0a \
\
\
\
\
\
\x0a \
\
\
\
\
\
\x0a \
\
\
\
\
\
\x0a\
\
\
\
\
\
\
\x0a \
\
\
\
\
\
\x0a \
\
\
\
\
\
\x0a \
\
\
\
\
\
\
\x0a \
\
\
\
\
\
\x0a \
\
\
\
\
\
\x0a \
\
\
\
\
\
\
\x0a \
\
\
\
\
\
\x0a \
\
\
\
\
\
\x0a \
\
\
\
\
\
\
\x0a \
\
\
\
\
\
\x0a \
\
\
\
\
\
\x0a \
\
\
\
\
\
\
\x0a \
\
\
\
\
\
\x0a \
\
\x0a<?xpacket end=\
\x22w\x22?>\xc2\x0b\x10K\x00\x00\x00\x06bKG\
D\x00\xff\x00\xff\x00\xff\xa0\xbd\xa7\x93\x00\x00\x00\x09p\
HYs\x00\x00\x0e\xc3\x00\x00\x0e\xc3\x01\xc7o\xa8d\
\x00\x00\x00\x07tIME\x07\xe8\x0c\x07\x11\x1e\x13#\
\xffQ\xb1\x00\x00\x09>IDATx\xda\xed\xdc\xcb\
\xb1\xe2@\x10EA`\x83Y\xd8\x8eY\xac\xc4\x86\x8d\
P\x10@wW\x7f3Mx\x113\xf7\xa8\x04\x9cN\
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
\x00\x00\x00\x00\x00\x00\x00\x00\xc0\xce\xd9\x9f\x00\xc6\xb6\xdd\
\xaf[\x93\xff<n\x0f\xff\x7f\x80\x00\x00f\x1aw\x91\
\x00\x02\x000\xf4\xc2\x00\x04\x00`\xe8\x85\x01\x08\x00\xc0\
\xe0\x0b\x02\x10\x00`\xf0\x0d\xbe \x00\x01\x00\x06\x1fA\
\x00\x02\x00\x8c>b\x00\x04\x00\x18}\xc4\x00\x08\x000\
\xfa\x88\x01\x10\x00`\xf4\x11\x03 \x00\xc0\xf0#\x04@\
\x00\x80\xd1G\x0c\x80\x00\x00\xc3\x8f\x10\x00\x01\x00F\x1f\
1\x00\x02\x00\xc3\x0fB\x00\x04\x00\x86\x1f\x84\x00\x08\x00\
\x0c?\x08\x01\x04\x00\x18~\x10\x02\x08\x000\xfc \x04\
\x10\x00`\xf8A\x08 \x00\xc0\xf0\x83\x10@\x00\x80\xf1\
\x07\x11\x80\x00\x00\xc3\x8f\x10\x00\x01\x00\x86\x1f!\x00\x02\
\x00\x8c?\x22\x00\x04\x00\x18~\x84\x00\x08\x00\x0c?\x08\
\x01\x10\x00\x18\x7f\x10\x01 \x000\xfc \x04@\x00`\
\xfcA\x04\x80\x00\xc0\xf8\x83\x08\x00\x01\x80\xe1\x07!\x00\
\x02\x00\xe3\x0f\x22\x00\x04\x00\x86\x1f\x84\x00\x02\x00\x8c?\
\x88\x00\x04\x00\x18\x7f\x10\x01\x08\x000\xfe \x02\x10\x00\
`\xf8A\x08 \x000\xfe\xc6\x1fD\x00\x02\x00\xe3\x0f\
\x88\x00\x04\x00\xc6\x1f\x10\x01\x08\x00\x8c? \x02\x10\x00\
\x18\x7f@\x04 \x000\xfc\x80\x10@\x00`\xfc\x01\x11\
\x80\x00\xc0\xf8\x03\x22\x00\x01\x80\xf1\x07D\x00\x02\x00\xe3\
\x0f\x88\x00\x04\x00\xc6\x1fD\x80\x08@\x00`\xfcA\x04\
\x80\x00\xc0\xf8\x83\x08@\x00\x80\xf1\x07\x11\x80\x00\xc0\xf8\
\x03\x22\x00\x01\x80\xf1\x07D\x00\x02\x00\xe3\x0f\x88\x00\xc6\
v\xf1'\x00\x00\x17\x00<\xfd\x03\xae\x00\x08\x00\x8c?\
\x02\x10\x00\x18\x7f@\x04 \x000\xfe\x80\x08@\x00\
`\xfc\x01\x11\x80\x00\xc0\xf8\x03\x22\x80^\xf9\x1a \x00\
\xb8\x00\xe0\xe9\x1fp\x05p\x05\x10\x00\x18\x7f@\x04 \
\x000\xfe\x80\x08@\x00`\xfc\x01\x11\xc0\xa0|\x08\x10\
\x00\x5c\x00\xf0\xf4\x0f\xe0\x0a \x000\xfe\x00\x22`J\
^\x01\x00\x80\x0b\x00\x9e\xfe\x01\x5c\x01\x04\x00\xc6\x1f@\
\x04\x08\x00\x8c?\x80\x08\x98\x83\xcf\x00\x00\x80\x0b\x00\x9e\
\xfe\x01\x5c\x01\x04\x00\xc6\x1f@\x04L\xc9+\x00\x00p\
\x01\xc0\xd3?\x80+\x80\x0b\x00\x00\xe0\x02\x80\xa7\x7f\x00\
W\x00\x01\x80\xf1\x07\x10\x01\x83\xf2\x0a\x00\x00\x5c\x00\xf0\
\xf4\x0f\xe0\x0a\xe0\x02\x00\x00\xb8\x00\xe0\xe9\x1f\xc0\x15@\
\x00`\xfc\x01D\xc0\xa0\xbc\x02\x00\x00\x17\x00<\xfd\x03\
\xb8\x02\xb8\x00\x00\x00.\x00x\xfa\x07p\x05p\x01\x00\
\x00\x5c\x00\xf0\xf4\x0f\xe0\x0a\xe0\x02\x00\x00\xb8\x00\xe0\xe9\
\x1fp\x05\xc0\x05\x00\x00p\x01\xc0\xd3?\xe0\x0a\x80\x0b\
\x00\x00\xe0\x02\xe0\xe9\x1f\xc0\x15\x00\x17\x00\x00\xc0\x05\xc0\
\xd3?\x80+\x00.\x00\x00\x80\x00\x00\x00\x8e\x9cb:\
\xe1\xfc\x0f,3<^\x03\xb8\x00\x00\x00.\x00\x9e\xfe\
\x01\x5c\x01p\x01\x00\x00\x04\x00\x00P\x8c\x13Lc\xce\
\xff\xc0\xb2\x03\xe45\x80\x0b\x00\x00\xe0\x02\xe0\xe9\x1f\xc0\
\x15\x00\x17\x00\x00@\x00\x00\x00\xd9\x9c^\x1aq\xfe\x07\
x\x0d\x91\xd7\x00.\x00\x00\x80\x00\x00\x00\x828\xbb4\
\xe0\xfc\x0f\xf06F^\x03\xb8\x00\x00\x00\x02\x00\x00\x08\
\xe0\xe4R\x99\xf3?\xc0\x87A\xf2\x1a\xc0\x05\x00\x00\x10\
\x00\x00@a\xce-\x159\xff\x03|\x19%\xaf\x01\x5c\
\x00\x00\x00\x01\x00\x00\x08\x00\x00 \x87w-\x95x\xff\
\x0f\xf0\xe30\xf9\x1c\x80\x0b\x00\x00 \x00\x00\x00\x01\x00\
\x00\xa4\xf2\x9e\xa5\x02\xef\xff\x01\xfe\x1c'\x9f\x03p\x01\
\x00\x00\x04\x00\x00 \x00\x00\x80\x14\xde\xb1\x04\xf3\xfe\x1f\
q\xa0|\x0e\xc0\x05\x00\x00\x10\x00\x00\x80\x00\x00\x00\
\x04\x00\x00 \x00\x00\x80#\x9f\xb0\x0c\xe4\x1b\x00\x00\x99\
#\xe5\x9b\x00.\x00\x00\x80\x00\x00\x00\x04\x00\x00 \x00\
\x00\x00\x01\x00\x00\xec\xf9te\x10\xdf\x00\x00(4T\
\xbe\x09\xe0\x02\x00\x00\x08\x00\x00@\x00\x00\x00\x02\x00\x00\
\x10\x00\x00\x80\x00\x00\x00\x01\x00\x00\x08\x00\x00`r~\
\x5c!\x80\x1f\x01\x02(<V~\x0c\xc8\x05\x00\x00\x10\
\x00\x00\x80\x00\x00\x00\x04\x00\x00 \x00\x00\x00\x01\x00\x00\
\x02\x00\x00\x10\x00\x00\x80\x00\x00\x00\x04\x00\x00 \x00\x00\
\x00\x01\x00\x00\x08\x00\x00@\x00\x00\x00\x02\x00\x00\x10\x00\
\x00\x80\x00\x00\x00\x04\x00\x00 \x00\x00\x00\x01\x00\x00\x08\
\x00\x00@\x00\x00\x00\x02\x00\x00\x04\x00\x00 \x00\x00\x00\
\x01\x00\x00\x08\x00\x00@\x00\x00\x00\x02\x00\x00\xe8\xdf\xd9\
\x9f \xc6v\xbfn\xfe\x0a\x00\x05\x86\xea\xf6\xb0U.\
\x00\x00\x80\x00\x00\x00\x04\x00\x00 \x00\x00\x00\x01\x00\x00\
\x08\x00\x00\x10\x00\x00\x80\x00\x00\x00\xa6\xe6\xc7\x15\x02\xf9\
1 \x80\xcc\x91\xf2#@.\x00\x00\x80\x00\x00\x00\x04\
\x00\x00 \x00\x00\x00\x01\x00\x00\xec\xf9te0\xdf\x04\
\x00H\x1c(\xdf\x00p\x01\x00\x00\x04\x00\x00 \x00\x00\
\x00\x01\x00\x00\x08\x00\x00\xe0\xc8',+\xf0M\x00\x80\
?\xc7\xc97\x00\x5c\x00\x00\x00\x01\x00\x00\x08\x00\x00 \
\x85w,\x95\xf8\x1c\x00\xc0\x8f\xc3\xe4\xfd\xbf\x0b\x00\x00\
\x00\x00\x00\x01\x00\x00\xa4\xf2\x9e\xa5\x22\x9f\x03\x00\xf8\
2J\xde\xff\xbb\x00\x00\x00\x02\x00\x00\x10\x00\x00@\x0e\
\xefZ*\xf39\x00\x80\x0f\x83\xe4\xfd\xbf\x0b\x00\x00 \
\x00\x00\x80\xc2\x9c[\x1a\xf0\x1a\x00\xe0m\x8c\x9c\xff]\
\x00\x00\x00\x01\x00\x00\x04pri\xc4k\x00\x80\xd7\x10\
9\xff\xbb\x00\x00\x00\x02\x00\x00\x08\xe2\xec\xd2\x90\xd7\x00\
\xc0\xf2#\xe4\xfc\xef\x02\x00\x00\x08\x00\x00 \x90\xd3K\
c^\x03\x00\xcb\x0e\x90\xf3\xbf\x0b\x00\x00\xe0\x02\xe0\x0a\
\x00\xe0\xe9\x1f\x17\x00\x00@\x00\x00\x00\xd9\x9c`:\xe1\
5\x00\xb0\xcc\xf08\xff\xbb\x00\x00\x00.\x00\xae\x00\xae\
\x00\x80\xa7\x7f\x5c\x00\x00\x00\x01\x00\x00\x14\xe3\x14\xd3\x19\
\xaf\x01\x80i\x07\xc7\xf9\xdf\x05\x00\x00p\x01\xc0\x15\x00\
\xf0\xf4\x8f\x0b\x00\x00\xe0\x02\xe0\x0a\x00\xe0\xe9\x1f\x17\x00\
\x00\xc0\x05\xc0\x15\x00\xc0\xd3?.\x00\x00\x80\x0b\x80+\
\x00\x80\xa7\x7f\x5c\x00\x00\x00\x17\x00W\x00\x00O\xff.\
\x00\x00\x80\x0b\x00\xae\x00\x00\x9e\xfe]\x00\x00\x00\x17\x00\
\x5c\x01\x00<\xfd\x0b\x00D\x00\x80\xf1\x1f\x8bW\x00\x00\
\xe0\x02\x80+\x00\x80\xa7\x7f\x17\x00\x00\xc0\x05\x00W\x00\
\x00O\xff\x02\x00\x11\x00\x18\x7f;2(\xaf\x00\x00\xc0\
\x05\x00W\x00\x00O\xff.\x00\x00\x80\x0b\x00\xae\x00\x00\
\x9e\xfe\x05\x00\x22\x000\xfe\x0c\xca+\x00\x00p\x01\xc0\
\x15\x00\xc0\xd3\xbf\x00@\x04\x00\x18\x7f\x01\x80\x08\x00\x8c\
?s\xf0\x19\x00\x00p\x01\xc0\x15\x00\xc0\xd3\xbf\x00@\
\x04\x00\xc6\x9f)y\x05\x00\x80\xf1\x17\x00\xf8\xc7\x0b\xc0\
\x12\x1b\xe1O0?\xaf\x02\x00\x0f\x10\x08\x00\x11\x00`\
\xfc\x11\x00\x22\x00\xc0\xf8\xaf\xc8g\x00\x00\xc0\x05\x00W\
\x00\xc0\xd3?\x02\x00\x11\x00\x18\x7f\x04\x00\x22\x000\xfe\
\x08\x00D\x00`\xfc\x11\x00\x88\x00\xc0\xf8#\x00\x10\x01\
\x80\xf1\xa7[\xbe\x06\x08\x00.\x00\xb8\x02\x00\x9e\xfe\x11\
\x00\x88\x00\xc0\xf8#\x00\x10\x01\x80\xf1G\x00 \x02\x00\
\xe3\x8f\x00@\x04\x00\xc6\x1f\x01\x80\x08\x00\x8c?\x02\x00\
\x11\x00\x18\x7f\x04\x00\x22\x000\xfe\x08\x00D\x00`\xfc\
\x11\x00\x88\x00\xc0\xf8#\x00\x10\x01\x80\xf1G\x00 \x04\
\x00\xc3\x8f\x00@\x04\x80\xf1\x07\x01\x80\x08\x00\xe3\x0f\x02\
\x00\x11\x00\xc6\x1f\x04\x00\x22\x00\x8c?\x08\x00D\x00\x18\
\x7f\x04\x00\x08\x010\xfc\x08\x00\x10\x01`\xfc\x11\x00 \
\x02\xc0\xf8#\x00@\x04\x80\xe1G\x00\x80\x10\x00\xe3\x8f\
\x00\x00\x11\x00\xc6\x1f\x01\x00B\x00\x0c?\x02\x00D\x00\
\x18\x7f\x04\x00\x22\x00\x8c?\x08\x00\x84\x00\x18~\x10\x00\
\x88\x000\xfe \x00\x10\x02`\xf8A\x00 \x04\xc0\xf0\
\x83\x00@\x04\x80\xf1\x07\x01\x80\x10\x00\xc3\x0f\x02\x00!\
\x00\x86\x1f\x04\x00\x22\x00\x8c?\x02\x00\x84\x00\x18~\x04\
\x00\x08\x010\xfc\x08\x00\x10\x02`\xf8\x11\x00 \x040\
\xfc \x00@\x08`\xf8A\x00\x80\x10\xc0\xf0\x83\x00\x00\
!\x80\xe1\x07\x01\x00b\x00\xa3\x0f\x02\x00\x84\x00\x86\x1f\
\x04\x00\x88\x01\x8c>\x08\x00\x10\x02\x18~\x10\x00 \x06\
0\xfa \x00@\x0c`\xf4A\x00\x80\x180\xfa\x80\x00\
\x00A`\xf4\x01\x01\x00b\xc0\xe0\x03\x02\x00\x04\x81\xc1\
\x07\x01\x00\x08\x02\x83\x0f\x02\x00\x10\x06\x86\x1e\x04\x00 \
\x0c\x0c=\x08\x00@$\x18w\x00\x00\x00\x00\x00\x00\x00\
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
\x00\x00&\xf3\x042\xbc\x1c\x88\x0c\xb2\xbfh\x00\x00\x00\
\x00IEND\xaeB`\x82\
\x00\x03\x03W\
\xff\
\xd8\xff\xe0\x00\x10JFIF\x00\x01\x01\x00\x00\x01\x00\
@ -21203,6 +22053,10 @@ qt_resource_name = b"\
\x02\xac\xf9g\
\x00s\
\x00t\x00a\x00r\x00_\x00e\x00m\x00p\x00t\x00y\x00.\x00p\x00n\x00g\
\x00\x10\
\x02\x1c\xb4\xa7\
\x00g\
\x00r\x00e\x00e\x00n\x00-\x00c\x00i\x00r\x00c\x00l\x00e\x00.\x00p\x00n\x00g\
\x00\x0a\
\x0bb\xb2#\
\x00h\
@ -21215,6 +22069,11 @@ qt_resource_name = b"\
\x00\x06\xc7\xa5\
\x00f\
\x00a\x00d\x00e\
\x00\x11\
\x07 \x1a\x87\
\x00y\
\x00e\x00l\x00l\x00o\x00w\x00-\x00c\x00i\x00r\x00c\x00l\x00e\x00.\x00p\x00n\x00g\
\
\x00\x08\
\x0bg\x90\x9e\
\x00s\
@ -21241,11 +22100,11 @@ qt_resource_name = b"\
qt_resource_struct = b"\
\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x01\
\x00\x00\x00\x00\x00\x00\x00\x00\
\x00\x00\x00\x00\x00\x02\x00\x00\x00\x12\x00\x00\x00\x02\
\x00\x00\x00\x00\x00\x02\x00\x00\x00\x14\x00\x00\x00\x02\
\x00\x00\x00\x00\x00\x00\x00\x00\
\x00\x00\x01*\x00\x00\x00\x00\x00\x01\x00\x01\xa2\x89\
\x00\x00\x01P\x00\x00\x00\x00\x00\x01\x00\x01\xbc\xe5\
\x00\x00\x01xr\xe9}\xc0\
\x00\x00\x01\xb2\x00\x00\x00\x00\x00\x01\x00\x05&\x0f\
\x00\x00\x02\x00\x00\x00\x00\x00\x00\x01\x00\x05Z\xe9\
\x00\x00\x01x\x84r}X\
\x00\x00\x00\x10\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\
\x00\x00\x01x\xbb\xe5wh\
@ -21253,25 +22112,29 @@ qt_resource_struct = b"\
\x00\x00\x01xJ\xff\x88\xe0\
\x00\x00\x00\xb0\x00\x00\x00\x00\x00\x01\x00\x01\x0aa\
\x00\x00\x01x\x84r}X\
\x00\x00\x01\x9a\x00\x00\x00\x00\x00\x01\x00\x05\x11D\
\x00\x00\x01\xe8\x00\x00\x00\x00\x00\x01\x00\x05F\x1e\
\x00\x00\x01y/9=X\
\x00\x00\x00\xfa\x00\x00\x00\x00\x00\x01\x00\x01@o\
\x00\x00\x01\x93\xa2+J\x8e\
\x00\x00\x00\xd8\x00\x00\x00\x00\x00\x01\x00\x01\x12\x83\
\x00\x00\x01\x8fTX\xa5\x95\
\x00\x00\x01j\x00\x00\x00\x00\x00\x01\x00\x04\xf7\xc9\
\x00\x00\x01\x8fN\xb6\x0a3\
\x00\x00\x01\x90x\xb0R\x0a\
\x00\x00\x01\xb8\x00\x00\x00\x00\x00\x01\x00\x05,\xa3\
\x00\x00\x01\x90x\xb0R\x06\
\x00\x00\x01^\x00\x00\x00\x00\x00\x01\x00\x01\xcc\xec\
\x00\x00\x01\x93\xa2,\x19\x82\
\x00\x00\x00\x1e\x00\x00\x00\x00\x00\x01\x00\x00\x04\x98\
\x00\x00\x01xr\xe5\x9d\x90\
\x00\x00\x006\x00\x00\x00\x00\x00\x01\x00\x00d\xab\
\x00\x00\x01x\x84r}X\
\x00\x00\x00b\x00\x00\x00\x00\x00\x01\x00\x00\x80\x85\
\x00\x00\x01\x8fN\xb2\xe2%\
\x00\x00\x01\x14\x00\x00\x00\x00\x00\x01\x00\x01Z\xc6\
\x00\x00\x01\x8fTd\x16^\
\x00\x00\x01N\x00\x00\x00\x00\x00\x01\x00\x04\xb5\xeb\
\x00\x00\x01\x90x\xb0R\x06\
\x00\x00\x01:\x00\x00\x00\x00\x00\x01\x00\x01u\x22\
\x00\x00\x01\x90x\xb0R\x06\
\x00\x00\x01\x9c\x00\x00\x00\x00\x00\x01\x00\x04\xea\xc5\
\x00\x00\x01\x80A\xd4\xb2`\
\x00\x00\x00\xfa\x00\x00\x00\x00\x00\x01\x00\x01@o\
\x00\x00\x01 \x00\x00\x00\x00\x00\x01\x00\x01Z\xcb\
\x00\x00\x01\x8bRz\xee0\
\x00\x00\x018\x00\x00\x00\x00\x00\x01\x00\x01\xb2\x90\
\x00\x00\x01\x86\x00\x00\x00\x00\x00\x01\x00\x01\xe7j\
\x00\x00\x01x\xe8\xe8Z\xc8\
\x00\x00\x00\x98\x00\x00\x00\x00\x00\x01\x00\x00\xbf\x98\
\x00\x00\x01xr\xe6\xdd\xe0\

View File

@ -1,6 +1,6 @@
# Form implementation generated from reading ui file 'app/ui/main_window.ui'
#
# Created by: PyQt6 UI code generator 6.7.0
# Created by: PyQt6 UI code generator 6.7.1
#
# WARNING: Any manual changes made to this file will be lost when pyuic6 is
# run again. Do not edit this file unless you know what you are doing.
@ -15,7 +15,11 @@ class Ui_MainWindow(object):
MainWindow.resize(1280, 857)
MainWindow.setMinimumSize(QtCore.QSize(1280, 0))
icon = QtGui.QIcon()
icon.addPixmap(QtGui.QPixmap(":/icons/musicmuster"), QtGui.QIcon.Mode.Normal, QtGui.QIcon.State.Off)
icon.addPixmap(
QtGui.QPixmap(":/icons/musicmuster"),
QtGui.QIcon.Mode.Normal,
QtGui.QIcon.State.Off,
)
MainWindow.setWindowIcon(icon)
MainWindow.setStyleSheet("")
self.centralwidget = QtWidgets.QWidget(parent=MainWindow)
@ -27,39 +31,62 @@ class Ui_MainWindow(object):
self.verticalLayout_3 = QtWidgets.QVBoxLayout()
self.verticalLayout_3.setObjectName("verticalLayout_3")
self.previous_track_2 = QtWidgets.QLabel(parent=self.centralwidget)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Preferred, QtWidgets.QSizePolicy.Policy.Preferred)
sizePolicy = QtWidgets.QSizePolicy(
QtWidgets.QSizePolicy.Policy.Preferred,
QtWidgets.QSizePolicy.Policy.Preferred,
)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.previous_track_2.sizePolicy().hasHeightForWidth())
sizePolicy.setHeightForWidth(
self.previous_track_2.sizePolicy().hasHeightForWidth()
)
self.previous_track_2.setSizePolicy(sizePolicy)
self.previous_track_2.setMaximumSize(QtCore.QSize(230, 16777215))
font = QtGui.QFont()
font.setFamily("Sans")
font.setPointSize(20)
self.previous_track_2.setFont(font)
self.previous_track_2.setStyleSheet("background-color: #f8d7da;\n"
"border: 1px solid rgb(85, 87, 83);")
self.previous_track_2.setAlignment(QtCore.Qt.AlignmentFlag.AlignRight|QtCore.Qt.AlignmentFlag.AlignTrailing|QtCore.Qt.AlignmentFlag.AlignVCenter)
self.previous_track_2.setStyleSheet(
"background-color: #f8d7da;\n" "border: 1px solid rgb(85, 87, 83);"
)
self.previous_track_2.setAlignment(
QtCore.Qt.AlignmentFlag.AlignRight
| QtCore.Qt.AlignmentFlag.AlignTrailing
| QtCore.Qt.AlignmentFlag.AlignVCenter
)
self.previous_track_2.setObjectName("previous_track_2")
self.verticalLayout_3.addWidget(self.previous_track_2)
self.current_track_2 = QtWidgets.QLabel(parent=self.centralwidget)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Preferred, QtWidgets.QSizePolicy.Policy.Preferred)
sizePolicy = QtWidgets.QSizePolicy(
QtWidgets.QSizePolicy.Policy.Preferred,
QtWidgets.QSizePolicy.Policy.Preferred,
)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.current_track_2.sizePolicy().hasHeightForWidth())
sizePolicy.setHeightForWidth(
self.current_track_2.sizePolicy().hasHeightForWidth()
)
self.current_track_2.setSizePolicy(sizePolicy)
self.current_track_2.setMaximumSize(QtCore.QSize(230, 16777215))
font = QtGui.QFont()
font.setFamily("Sans")
font.setPointSize(20)
self.current_track_2.setFont(font)
self.current_track_2.setStyleSheet("background-color: #d4edda;\n"
"border: 1px solid rgb(85, 87, 83);")
self.current_track_2.setAlignment(QtCore.Qt.AlignmentFlag.AlignRight|QtCore.Qt.AlignmentFlag.AlignTrailing|QtCore.Qt.AlignmentFlag.AlignVCenter)
self.current_track_2.setStyleSheet(
"background-color: #d4edda;\n" "border: 1px solid rgb(85, 87, 83);"
)
self.current_track_2.setAlignment(
QtCore.Qt.AlignmentFlag.AlignRight
| QtCore.Qt.AlignmentFlag.AlignTrailing
| QtCore.Qt.AlignmentFlag.AlignVCenter
)
self.current_track_2.setObjectName("current_track_2")
self.verticalLayout_3.addWidget(self.current_track_2)
self.next_track_2 = QtWidgets.QLabel(parent=self.centralwidget)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Preferred, QtWidgets.QSizePolicy.Policy.Preferred)
sizePolicy = QtWidgets.QSizePolicy(
QtWidgets.QSizePolicy.Policy.Preferred,
QtWidgets.QSizePolicy.Policy.Preferred,
)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.next_track_2.sizePolicy().hasHeightForWidth())
@ -69,19 +96,29 @@ class Ui_MainWindow(object):
font.setFamily("Sans")
font.setPointSize(20)
self.next_track_2.setFont(font)
self.next_track_2.setStyleSheet("background-color: #fff3cd;\n"
"border: 1px solid rgb(85, 87, 83);")
self.next_track_2.setAlignment(QtCore.Qt.AlignmentFlag.AlignRight|QtCore.Qt.AlignmentFlag.AlignTrailing|QtCore.Qt.AlignmentFlag.AlignVCenter)
self.next_track_2.setStyleSheet(
"background-color: #fff3cd;\n" "border: 1px solid rgb(85, 87, 83);"
)
self.next_track_2.setAlignment(
QtCore.Qt.AlignmentFlag.AlignRight
| QtCore.Qt.AlignmentFlag.AlignTrailing
| QtCore.Qt.AlignmentFlag.AlignVCenter
)
self.next_track_2.setObjectName("next_track_2")
self.verticalLayout_3.addWidget(self.next_track_2)
self.horizontalLayout_3.addLayout(self.verticalLayout_3)
self.verticalLayout = QtWidgets.QVBoxLayout()
self.verticalLayout.setObjectName("verticalLayout")
self.hdrPreviousTrack = QtWidgets.QLabel(parent=self.centralwidget)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Preferred, QtWidgets.QSizePolicy.Policy.Preferred)
sizePolicy = QtWidgets.QSizePolicy(
QtWidgets.QSizePolicy.Policy.Preferred,
QtWidgets.QSizePolicy.Policy.Preferred,
)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.hdrPreviousTrack.sizePolicy().hasHeightForWidth())
sizePolicy.setHeightForWidth(
self.hdrPreviousTrack.sizePolicy().hasHeightForWidth()
)
self.hdrPreviousTrack.setSizePolicy(sizePolicy)
self.hdrPreviousTrack.setMinimumSize(QtCore.QSize(0, 0))
self.hdrPreviousTrack.setMaximumSize(QtCore.QSize(16777215, 16777215))
@ -89,32 +126,43 @@ class Ui_MainWindow(object):
font.setFamily("Sans")
font.setPointSize(20)
self.hdrPreviousTrack.setFont(font)
self.hdrPreviousTrack.setStyleSheet("background-color: #f8d7da;\n"
"border: 1px solid rgb(85, 87, 83);")
self.hdrPreviousTrack.setStyleSheet(
"background-color: #f8d7da;\n" "border: 1px solid rgb(85, 87, 83);"
)
self.hdrPreviousTrack.setText("")
self.hdrPreviousTrack.setWordWrap(False)
self.hdrPreviousTrack.setObjectName("hdrPreviousTrack")
self.verticalLayout.addWidget(self.hdrPreviousTrack)
self.hdrCurrentTrack = QtWidgets.QPushButton(parent=self.centralwidget)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Preferred, QtWidgets.QSizePolicy.Policy.Preferred)
sizePolicy = QtWidgets.QSizePolicy(
QtWidgets.QSizePolicy.Policy.Preferred,
QtWidgets.QSizePolicy.Policy.Preferred,
)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.hdrCurrentTrack.sizePolicy().hasHeightForWidth())
sizePolicy.setHeightForWidth(
self.hdrCurrentTrack.sizePolicy().hasHeightForWidth()
)
self.hdrCurrentTrack.setSizePolicy(sizePolicy)
font = QtGui.QFont()
font.setPointSize(20)
self.hdrCurrentTrack.setFont(font)
self.hdrCurrentTrack.setStyleSheet("background-color: #d4edda;\n"
"border: 1px solid rgb(85, 87, 83);\n"
"text-align: left;\n"
"padding-left: 8px;\n"
"")
self.hdrCurrentTrack.setStyleSheet(
"background-color: #d4edda;\n"
"border: 1px solid rgb(85, 87, 83);\n"
"text-align: left;\n"
"padding-left: 8px;\n"
""
)
self.hdrCurrentTrack.setText("")
self.hdrCurrentTrack.setFlat(True)
self.hdrCurrentTrack.setObjectName("hdrCurrentTrack")
self.verticalLayout.addWidget(self.hdrCurrentTrack)
self.hdrNextTrack = QtWidgets.QPushButton(parent=self.centralwidget)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Preferred, QtWidgets.QSizePolicy.Policy.Preferred)
sizePolicy = QtWidgets.QSizePolicy(
QtWidgets.QSizePolicy.Policy.Preferred,
QtWidgets.QSizePolicy.Policy.Preferred,
)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.hdrNextTrack.sizePolicy().hasHeightForWidth())
@ -122,10 +170,12 @@ class Ui_MainWindow(object):
font = QtGui.QFont()
font.setPointSize(20)
self.hdrNextTrack.setFont(font)
self.hdrNextTrack.setStyleSheet("background-color: #fff3cd;\n"
"border: 1px solid rgb(85, 87, 83);\n"
"text-align: left;\n"
"padding-left: 8px;")
self.hdrNextTrack.setStyleSheet(
"background-color: #fff3cd;\n"
"border: 1px solid rgb(85, 87, 83);\n"
"text-align: left;\n"
"padding-left: 8px;"
)
self.hdrNextTrack.setText("")
self.hdrNextTrack.setFlat(True)
self.hdrNextTrack.setObjectName("hdrNextTrack")
@ -172,7 +222,12 @@ class Ui_MainWindow(object):
self.cartsWidget.setObjectName("cartsWidget")
self.horizontalLayout_Carts = QtWidgets.QHBoxLayout(self.cartsWidget)
self.horizontalLayout_Carts.setObjectName("horizontalLayout_Carts")
spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Minimum)
spacerItem = QtWidgets.QSpacerItem(
40,
20,
QtWidgets.QSizePolicy.Policy.Expanding,
QtWidgets.QSizePolicy.Policy.Minimum,
)
self.horizontalLayout_Carts.addItem(spacerItem)
self.gridLayout_4.addWidget(self.cartsWidget, 2, 0, 1, 1)
self.frame_6 = QtWidgets.QFrame(parent=self.centralwidget)
@ -217,7 +272,11 @@ class Ui_MainWindow(object):
self.btnPreview = QtWidgets.QPushButton(parent=self.FadeStopInfoFrame)
self.btnPreview.setMinimumSize(QtCore.QSize(132, 41))
icon1 = QtGui.QIcon()
icon1.addPixmap(QtGui.QPixmap(":/icons/headphones"), QtGui.QIcon.Mode.Normal, QtGui.QIcon.State.Off)
icon1.addPixmap(
QtGui.QPixmap(":/icons/headphones"),
QtGui.QIcon.Mode.Normal,
QtGui.QIcon.State.Off,
)
self.btnPreview.setIcon(icon1)
self.btnPreview.setIconSize(QtCore.QSize(30, 30))
self.btnPreview.setCheckable(True)
@ -239,8 +298,16 @@ class Ui_MainWindow(object):
self.btnPreviewArm.setMaximumSize(QtCore.QSize(44, 23))
self.btnPreviewArm.setText("")
icon2 = QtGui.QIcon()
icon2.addPixmap(QtGui.QPixmap(":/icons/record-button.png"), QtGui.QIcon.Mode.Normal, QtGui.QIcon.State.Off)
icon2.addPixmap(QtGui.QPixmap(":/icons/record-red-button.png"), QtGui.QIcon.Mode.Normal, QtGui.QIcon.State.On)
icon2.addPixmap(
QtGui.QPixmap(":/icons/record-button.png"),
QtGui.QIcon.Mode.Normal,
QtGui.QIcon.State.Off,
)
icon2.addPixmap(
QtGui.QPixmap(":/icons/record-red-button.png"),
QtGui.QIcon.Mode.Normal,
QtGui.QIcon.State.On,
)
self.btnPreviewArm.setIcon(icon2)
self.btnPreviewArm.setCheckable(True)
self.btnPreviewArm.setObjectName("btnPreviewArm")
@ -261,8 +328,16 @@ class Ui_MainWindow(object):
self.btnPreviewMark.setMaximumSize(QtCore.QSize(44, 23))
self.btnPreviewMark.setText("")
icon3 = QtGui.QIcon()
icon3.addPixmap(QtGui.QPixmap(":/icons/star.png"), QtGui.QIcon.Mode.Normal, QtGui.QIcon.State.On)
icon3.addPixmap(QtGui.QPixmap(":/icons/star_empty.png"), QtGui.QIcon.Mode.Disabled, QtGui.QIcon.State.Off)
icon3.addPixmap(
QtGui.QPixmap(":/icons/star.png"),
QtGui.QIcon.Mode.Normal,
QtGui.QIcon.State.On,
)
icon3.addPixmap(
QtGui.QPixmap(":/icons/star_empty.png"),
QtGui.QIcon.Mode.Disabled,
QtGui.QIcon.State.Off,
)
self.btnPreviewMark.setIcon(icon3)
self.btnPreviewMark.setObjectName("btnPreviewMark")
self.btnPreviewFwd = QtWidgets.QPushButton(parent=self.groupBoxIntroControls)
@ -363,10 +438,15 @@ class Ui_MainWindow(object):
self.verticalLayout_7.addWidget(self.label_silent_timer)
self.horizontalLayout.addWidget(self.frame_silent)
self.widgetFadeVolume = PlotWidget(parent=self.InfoFooterFrame)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Preferred, QtWidgets.QSizePolicy.Policy.Preferred)
sizePolicy = QtWidgets.QSizePolicy(
QtWidgets.QSizePolicy.Policy.Preferred,
QtWidgets.QSizePolicy.Policy.Preferred,
)
sizePolicy.setHorizontalStretch(1)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.widgetFadeVolume.sizePolicy().hasHeightForWidth())
sizePolicy.setHeightForWidth(
self.widgetFadeVolume.sizePolicy().hasHeightForWidth()
)
self.widgetFadeVolume.setSizePolicy(sizePolicy)
self.widgetFadeVolume.setMinimumSize(QtCore.QSize(0, 0))
self.widgetFadeVolume.setObjectName("widgetFadeVolume")
@ -383,7 +463,11 @@ class Ui_MainWindow(object):
self.btnFade.setMinimumSize(QtCore.QSize(132, 32))
self.btnFade.setMaximumSize(QtCore.QSize(164, 16777215))
icon4 = QtGui.QIcon()
icon4.addPixmap(QtGui.QPixmap(":/icons/fade"), QtGui.QIcon.Mode.Normal, QtGui.QIcon.State.Off)
icon4.addPixmap(
QtGui.QPixmap(":/icons/fade"),
QtGui.QIcon.Mode.Normal,
QtGui.QIcon.State.Off,
)
self.btnFade.setIcon(icon4)
self.btnFade.setIconSize(QtCore.QSize(30, 30))
self.btnFade.setObjectName("btnFade")
@ -391,7 +475,11 @@ class Ui_MainWindow(object):
self.btnStop = QtWidgets.QPushButton(parent=self.frame)
self.btnStop.setMinimumSize(QtCore.QSize(0, 36))
icon5 = QtGui.QIcon()
icon5.addPixmap(QtGui.QPixmap(":/icons/stopsign"), QtGui.QIcon.Mode.Normal, QtGui.QIcon.State.Off)
icon5.addPixmap(
QtGui.QPixmap(":/icons/stopsign"),
QtGui.QIcon.Mode.Normal,
QtGui.QIcon.State.Off,
)
self.btnStop.setIcon(icon5)
self.btnStop.setObjectName("btnStop")
self.verticalLayout_5.addWidget(self.btnStop)
@ -417,39 +505,71 @@ class Ui_MainWindow(object):
MainWindow.setStatusBar(self.statusbar)
self.actionPlay_next = QtGui.QAction(parent=MainWindow)
icon6 = QtGui.QIcon()
icon6.addPixmap(QtGui.QPixmap("app/ui/../../../../../../.designer/backup/icon-play.png"), QtGui.QIcon.Mode.Normal, QtGui.QIcon.State.Off)
icon6.addPixmap(
QtGui.QPixmap("app/ui/../../../../../../.designer/backup/icon-play.png"),
QtGui.QIcon.Mode.Normal,
QtGui.QIcon.State.Off,
)
self.actionPlay_next.setIcon(icon6)
self.actionPlay_next.setObjectName("actionPlay_next")
self.actionSkipToNext = QtGui.QAction(parent=MainWindow)
icon7 = QtGui.QIcon()
icon7.addPixmap(QtGui.QPixmap(":/icons/next"), QtGui.QIcon.Mode.Normal, QtGui.QIcon.State.Off)
icon7.addPixmap(
QtGui.QPixmap(":/icons/next"),
QtGui.QIcon.Mode.Normal,
QtGui.QIcon.State.Off,
)
self.actionSkipToNext.setIcon(icon7)
self.actionSkipToNext.setObjectName("actionSkipToNext")
self.actionInsertTrack = QtGui.QAction(parent=MainWindow)
icon8 = QtGui.QIcon()
icon8.addPixmap(QtGui.QPixmap("app/ui/../../../../../../.designer/backup/icon_search_database.png"), QtGui.QIcon.Mode.Normal, QtGui.QIcon.State.Off)
icon8.addPixmap(
QtGui.QPixmap(
"app/ui/../../../../../../.designer/backup/icon_search_database.png"
),
QtGui.QIcon.Mode.Normal,
QtGui.QIcon.State.Off,
)
self.actionInsertTrack.setIcon(icon8)
self.actionInsertTrack.setObjectName("actionInsertTrack")
self.actionAdd_file = QtGui.QAction(parent=MainWindow)
icon9 = QtGui.QIcon()
icon9.addPixmap(QtGui.QPixmap("app/ui/../../../../../../.designer/backup/icon_open_file.png"), QtGui.QIcon.Mode.Normal, QtGui.QIcon.State.Off)
icon9.addPixmap(
QtGui.QPixmap(
"app/ui/../../../../../../.designer/backup/icon_open_file.png"
),
QtGui.QIcon.Mode.Normal,
QtGui.QIcon.State.Off,
)
self.actionAdd_file.setIcon(icon9)
self.actionAdd_file.setObjectName("actionAdd_file")
self.actionFade = QtGui.QAction(parent=MainWindow)
icon10 = QtGui.QIcon()
icon10.addPixmap(QtGui.QPixmap("app/ui/../../../../../../.designer/backup/icon-fade.png"), QtGui.QIcon.Mode.Normal, QtGui.QIcon.State.Off)
icon10.addPixmap(
QtGui.QPixmap("app/ui/../../../../../../.designer/backup/icon-fade.png"),
QtGui.QIcon.Mode.Normal,
QtGui.QIcon.State.Off,
)
self.actionFade.setIcon(icon10)
self.actionFade.setObjectName("actionFade")
self.actionStop = QtGui.QAction(parent=MainWindow)
icon11 = QtGui.QIcon()
icon11.addPixmap(QtGui.QPixmap(":/icons/stop"), QtGui.QIcon.Mode.Normal, QtGui.QIcon.State.Off)
icon11.addPixmap(
QtGui.QPixmap(":/icons/stop"),
QtGui.QIcon.Mode.Normal,
QtGui.QIcon.State.Off,
)
self.actionStop.setIcon(icon11)
self.actionStop.setObjectName("actionStop")
self.action_Clear_selection = QtGui.QAction(parent=MainWindow)
self.action_Clear_selection.setObjectName("action_Clear_selection")
self.action_Resume_previous = QtGui.QAction(parent=MainWindow)
icon12 = QtGui.QIcon()
icon12.addPixmap(QtGui.QPixmap(":/icons/previous"), QtGui.QIcon.Mode.Normal, QtGui.QIcon.State.Off)
icon12.addPixmap(
QtGui.QPixmap(":/icons/previous"),
QtGui.QIcon.Mode.Normal,
QtGui.QIcon.State.Off,
)
self.action_Resume_previous.setIcon(icon12)
self.action_Resume_previous.setObjectName("action_Resume_previous")
self.actionE_xit = QtGui.QAction(parent=MainWindow)
@ -496,7 +616,9 @@ class Ui_MainWindow(object):
self.actionImport = QtGui.QAction(parent=MainWindow)
self.actionImport.setObjectName("actionImport")
self.actionDownload_CSV_of_played_tracks = QtGui.QAction(parent=MainWindow)
self.actionDownload_CSV_of_played_tracks.setObjectName("actionDownload_CSV_of_played_tracks")
self.actionDownload_CSV_of_played_tracks.setObjectName(
"actionDownload_CSV_of_played_tracks"
)
self.actionSearch = QtGui.QAction(parent=MainWindow)
self.actionSearch.setObjectName("actionSearch")
self.actionInsertSectionHeader = QtGui.QAction(parent=MainWindow)
@ -524,9 +646,13 @@ class Ui_MainWindow(object):
self.actionResume = QtGui.QAction(parent=MainWindow)
self.actionResume.setObjectName("actionResume")
self.actionSearch_title_in_Wikipedia = QtGui.QAction(parent=MainWindow)
self.actionSearch_title_in_Wikipedia.setObjectName("actionSearch_title_in_Wikipedia")
self.actionSearch_title_in_Wikipedia.setObjectName(
"actionSearch_title_in_Wikipedia"
)
self.actionSearch_title_in_Songfacts = QtGui.QAction(parent=MainWindow)
self.actionSearch_title_in_Songfacts.setObjectName("actionSearch_title_in_Songfacts")
self.actionSearch_title_in_Songfacts.setObjectName(
"actionSearch_title_in_Songfacts"
)
self.actionSelect_duplicate_rows = QtGui.QAction(parent=MainWindow)
self.actionSelect_duplicate_rows.setObjectName("actionSelect_duplicate_rows")
self.actionReplace_files = QtGui.QAction(parent=MainWindow)
@ -581,7 +707,7 @@ class Ui_MainWindow(object):
self.retranslateUi(MainWindow)
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)
def retranslateUi(self, MainWindow):
@ -623,38 +749,58 @@ class Ui_MainWindow(object):
self.actionFade.setShortcut(_translate("MainWindow", "Ctrl+Z"))
self.actionStop.setText(_translate("MainWindow", "S&top"))
self.actionStop.setShortcut(_translate("MainWindow", "Ctrl+Alt+S"))
self.action_Clear_selection.setText(_translate("MainWindow", "Clear &selection"))
self.action_Clear_selection.setText(
_translate("MainWindow", "Clear &selection")
)
self.action_Clear_selection.setShortcut(_translate("MainWindow", "Esc"))
self.action_Resume_previous.setText(_translate("MainWindow", "&Resume previous"))
self.action_Resume_previous.setText(
_translate("MainWindow", "&Resume previous")
)
self.actionE_xit.setText(_translate("MainWindow", "E&xit"))
self.actionTest.setText(_translate("MainWindow", "&Test"))
self.actionOpenPlaylist.setText(_translate("MainWindow", "O&pen..."))
self.actionNewPlaylist.setText(_translate("MainWindow", "&New..."))
self.actionTestFunction.setText(_translate("MainWindow", "&Test function"))
self.actionSkipToFade.setText(_translate("MainWindow", "&Skip to start of fade"))
self.actionSkipToFade.setText(
_translate("MainWindow", "&Skip to start of fade")
)
self.actionSkipToEnd.setText(_translate("MainWindow", "Skip to &end of track"))
self.actionClosePlaylist.setText(_translate("MainWindow", "&Close"))
self.actionRenamePlaylist.setText(_translate("MainWindow", "&Rename..."))
self.actionDeletePlaylist.setText(_translate("MainWindow", "Dele&te..."))
self.actionMoveSelected.setText(_translate("MainWindow", "Mo&ve selected tracks to..."))
self.actionMoveSelected.setText(
_translate("MainWindow", "Mo&ve selected tracks to...")
)
self.actionExport_playlist.setText(_translate("MainWindow", "E&xport..."))
self.actionSetNext.setText(_translate("MainWindow", "Set &next"))
self.actionSetNext.setShortcut(_translate("MainWindow", "Ctrl+N"))
self.actionSelect_next_track.setText(_translate("MainWindow", "Select next track"))
self.actionSelect_next_track.setText(
_translate("MainWindow", "Select next track")
)
self.actionSelect_next_track.setShortcut(_translate("MainWindow", "J"))
self.actionSelect_previous_track.setText(_translate("MainWindow", "Select previous track"))
self.actionSelect_previous_track.setText(
_translate("MainWindow", "Select previous track")
)
self.actionSelect_previous_track.setShortcut(_translate("MainWindow", "K"))
self.actionSelect_played_tracks.setText(_translate("MainWindow", "Select played tracks"))
self.actionMoveUnplayed.setText(_translate("MainWindow", "Move &unplayed tracks to..."))
self.actionSelect_played_tracks.setText(
_translate("MainWindow", "Select played tracks")
)
self.actionMoveUnplayed.setText(
_translate("MainWindow", "Move &unplayed tracks to...")
)
self.actionAdd_note.setText(_translate("MainWindow", "Add note..."))
self.actionAdd_note.setShortcut(_translate("MainWindow", "Ctrl+T"))
self.actionEnable_controls.setText(_translate("MainWindow", "Enable controls"))
self.actionImport.setText(_translate("MainWindow", "Import track..."))
self.actionImport.setShortcut(_translate("MainWindow", "Ctrl+Shift+I"))
self.actionDownload_CSV_of_played_tracks.setText(_translate("MainWindow", "Download CSV of played tracks..."))
self.actionDownload_CSV_of_played_tracks.setText(
_translate("MainWindow", "Download CSV of played tracks...")
)
self.actionSearch.setText(_translate("MainWindow", "Search..."))
self.actionSearch.setShortcut(_translate("MainWindow", "/"))
self.actionInsertSectionHeader.setText(_translate("MainWindow", "Insert &section header..."))
self.actionInsertSectionHeader.setText(
_translate("MainWindow", "Insert &section header...")
)
self.actionInsertSectionHeader.setShortcut(_translate("MainWindow", "Ctrl+H"))
self.actionRemove.setText(_translate("MainWindow", "&Remove track"))
self.actionFind_next.setText(_translate("MainWindow", "Find next"))
@ -662,8 +808,12 @@ class Ui_MainWindow(object):
self.actionFind_previous.setText(_translate("MainWindow", "Find previous"))
self.actionFind_previous.setShortcut(_translate("MainWindow", "P"))
self.action_About.setText(_translate("MainWindow", "&About"))
self.actionSave_as_template.setText(_translate("MainWindow", "Save as template..."))
self.actionNew_from_template.setText(_translate("MainWindow", "New from template..."))
self.actionSave_as_template.setText(
_translate("MainWindow", "Save as template...")
)
self.actionNew_from_template.setText(
_translate("MainWindow", "New from template...")
)
self.actionDebug.setText(_translate("MainWindow", "Debug"))
self.actionAdd_cart.setText(_translate("MainWindow", "Edit cart &1..."))
self.actionMark_for_moving.setText(_translate("MainWindow", "Mark for moving"))
@ -672,11 +822,23 @@ class Ui_MainWindow(object):
self.actionPaste.setShortcut(_translate("MainWindow", "Ctrl+V"))
self.actionResume.setText(_translate("MainWindow", "Resume"))
self.actionResume.setShortcut(_translate("MainWindow", "Ctrl+R"))
self.actionSearch_title_in_Wikipedia.setText(_translate("MainWindow", "Search title in Wikipedia"))
self.actionSearch_title_in_Wikipedia.setShortcut(_translate("MainWindow", "Ctrl+W"))
self.actionSearch_title_in_Songfacts.setText(_translate("MainWindow", "Search title in Songfacts"))
self.actionSearch_title_in_Songfacts.setShortcut(_translate("MainWindow", "Ctrl+S"))
self.actionSelect_duplicate_rows.setText(_translate("MainWindow", "Select duplicate rows..."))
self.actionSearch_title_in_Wikipedia.setText(
_translate("MainWindow", "Search title in Wikipedia")
)
self.actionSearch_title_in_Wikipedia.setShortcut(
_translate("MainWindow", "Ctrl+W")
)
self.actionSearch_title_in_Songfacts.setText(
_translate("MainWindow", "Search title in Songfacts")
)
self.actionSearch_title_in_Songfacts.setShortcut(
_translate("MainWindow", "Ctrl+S")
)
self.actionSelect_duplicate_rows.setText(
_translate("MainWindow", "Select duplicate rows...")
)
self.actionReplace_files.setText(_translate("MainWindow", "Import files..."))
from infotabs import InfoTabs # type: ignore
from pyqtgraph import PlotWidget # type: ignore

BIN
app/ui/yellow-circle.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB