Compare commits
10 Commits
b4671ccc89
...
f859a08a5f
Author | SHA1 | Date |
---|---|---|
Martin Wagner | f859a08a5f | |
Martin Wagner | da14ac2ef6 | |
Martin Wagner | 1231e07f52 | |
Martin Wagner | 11e45a5d5d | |
Martin Wagner | 3e4ca4a116 | |
Martin Wagner | fab8604fd3 | |
Martin Wagner | 0e556a39f1 | |
Emmanuel Averty | cf79da1f88 | |
Martin Wagner | 9683c62274 | |
Emmanuel Averty | 9a7f1e431e |
1
AUTHORS
1
AUTHORS
|
@ -7,6 +7,7 @@ Translators:
|
|||
Georgi Kamenov (Bulgarian)
|
||||
Oğuz Ersen (Turkish)
|
||||
Łukasz Drukała (Polish)
|
||||
Emmanuel Averty (French)
|
||||
|
||||
Gentoo ebuild:
|
||||
Martin Wagner <martin.wagner.dev@gmail.com>
|
||||
|
|
|
@ -73,4 +73,4 @@ sudo update-desktop-database
|
|||
Translation
|
||||
-----------
|
||||
|
||||
This program is currently available in English, German, Dutch, Bulgarian, Turkish and Polish. If you speak one of these or even another language, you can easily translate it by using [poedit](https://poedit.net). Just import `po/mpdevil.pot` from this repo into `poedit`. To test your translation, copy the new `.po` file into the `po` directory of your cloned mpdevil repo and proceed as described in the [Building](#building) section. To get your translation merged, just send me an e-mail or create a pull request.
|
||||
This program is currently available in English, German, Dutch, Bulgarian, Turkish, Polish and French. If you speak one of these or even another language, you can easily translate it by using [poedit](https://poedit.net). Just import `po/mpdevil.pot` from this repo into `poedit`. To test your translation, copy the new `.po` file into the `po` directory of your cloned mpdevil repo and proceed as described in the [Building](#building) section. To get your translation merged, just send me an e-mail or create a pull request.
|
||||
|
|
|
@ -10,7 +10,8 @@
|
|||
Martin de Reuver
|
||||
Georgi Kamenov
|
||||
Oğuz Ersen
|
||||
Łukasz Drukała</property>
|
||||
Łukasz Drukała
|
||||
Emmanuel Averty</property>
|
||||
<property name="website">https://github.com/SoongNoonien/mpdevil</property>
|
||||
<property name="copyright">Copyright © 2020-2022 Martin Wagner</property>
|
||||
<property name="license_type">gpl-3-0</property>
|
||||
|
|
|
@ -110,10 +110,6 @@
|
|||
<default>false</default>
|
||||
<summary>Stop playback on quit</summary>
|
||||
</key>
|
||||
<key type="b" name="force-mode">
|
||||
<default>false</default>
|
||||
<summary>Play selected albums directly</summary>
|
||||
</key>
|
||||
<key type="b" name="mpris">
|
||||
<default>true</default>
|
||||
<summary>Provide MPRIS</summary>
|
||||
|
|
|
@ -1 +1 @@
|
|||
de nl bg tr pl
|
||||
de nl bg tr pl fr
|
||||
|
|
|
@ -0,0 +1,482 @@
|
|||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the mpdevil package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: mpdevil\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2022-11-06 11:32+0100\n"
|
||||
"PO-Revision-Date: 2022-11-19 15:38+0100\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: \n"
|
||||
"Language: fr\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||
"X-Generator: Poedit 3.1.1\n"
|
||||
|
||||
#: src/mpdevil.py:502
|
||||
#, python-brace-format
|
||||
msgid "{days} day"
|
||||
msgid_plural "{days} days"
|
||||
msgstr[0] "{days} jour"
|
||||
msgstr[1] "{days} jours"
|
||||
|
||||
#: src/mpdevil.py:539
|
||||
#, python-brace-format
|
||||
msgid "{channels} channel"
|
||||
msgid_plural "{channels} channels"
|
||||
msgstr[0] "{channels} canal"
|
||||
msgstr[1] "{channels} canaux"
|
||||
|
||||
#: src/mpdevil.py:1002
|
||||
msgid "(restart required)"
|
||||
msgstr "(redémarrage nécessaire)"
|
||||
|
||||
#: src/mpdevil.py:1048
|
||||
msgid "Use Client-side decoration"
|
||||
msgstr "Utiliser les décorations côté client"
|
||||
|
||||
#: src/mpdevil.py:1049
|
||||
msgid "Show stop button"
|
||||
msgstr "Afficher le bouton stop"
|
||||
|
||||
#: src/mpdevil.py:1050
|
||||
msgid "Show audio format"
|
||||
msgstr "Afficher le format audio"
|
||||
|
||||
#: src/mpdevil.py:1051
|
||||
msgid "Show lyrics button"
|
||||
msgstr "Afficher le bouton paroles"
|
||||
|
||||
#: src/mpdevil.py:1052
|
||||
msgid "Place playlist at the side"
|
||||
msgstr "Placer la liste de lecture sur le côté"
|
||||
|
||||
#: src/mpdevil.py:1058
|
||||
msgid "Album view cover size"
|
||||
msgstr "Taille de la vue couverture d'album"
|
||||
|
||||
#: src/mpdevil.py:1059
|
||||
msgid "Action bar icon size"
|
||||
msgstr "Taille de la barre des icônes d'action"
|
||||
|
||||
#: src/mpdevil.py:1069
|
||||
msgid "Support “MPRIS”"
|
||||
msgstr "Support du \"MPRIS\""
|
||||
|
||||
#: src/mpdevil.py:1070
|
||||
msgid "Sort albums by year"
|
||||
msgstr "Trier les albums par année"
|
||||
|
||||
#: src/mpdevil.py:1071
|
||||
msgid "Send notification on title change"
|
||||
msgstr "Notifier lors du changement de titre"
|
||||
|
||||
#: src/mpdevil.py:1072
|
||||
msgid "Play selected albums and titles immediately"
|
||||
msgstr "Jouer l'album sélectionné et les titres immédiatement"
|
||||
|
||||
#: src/mpdevil.py:1073
|
||||
msgid "Rewind via previous button"
|
||||
msgstr "Retour au début via bouton précédent"
|
||||
|
||||
#: src/mpdevil.py:1074
|
||||
msgid "Stop playback on quit"
|
||||
msgstr "Arrêt de la lecture en quittant"
|
||||
|
||||
#: src/mpdevil.py:1101
|
||||
msgid "Choose directory"
|
||||
msgstr "Choisir le répertoire"
|
||||
|
||||
#. labels and entries
|
||||
#: src/mpdevil.py:1116
|
||||
msgid "Connect via Unix domain socket"
|
||||
msgstr "Connexion via socket Unix"
|
||||
|
||||
#: src/mpdevil.py:1135
|
||||
msgid ""
|
||||
"The first image in the same directory as the song file matching this regex "
|
||||
"will be displayed. %AlbumArtist% and %Album% will be replaced by the "
|
||||
"corresponding tags of the song."
|
||||
msgstr ""
|
||||
"La première image dans le même répertoire que le fichier de la chanson "
|
||||
"correspondant à l'expression régulière sera affiché. %AlbumArtist% et "
|
||||
"%Album% seront replacés par les étiquettes correspondantes de la chanson."
|
||||
|
||||
#: src/mpdevil.py:1140
|
||||
msgid "Socket:"
|
||||
msgstr "Socket :"
|
||||
|
||||
#: src/mpdevil.py:1142
|
||||
msgid "Host:"
|
||||
msgstr "Hôte :"
|
||||
|
||||
#: src/mpdevil.py:1144
|
||||
msgid "Password:"
|
||||
msgstr "Mot de passe :"
|
||||
|
||||
#: src/mpdevil.py:1145
|
||||
msgid "Music lib:"
|
||||
msgstr "Bibliothèque musicale :"
|
||||
|
||||
#: src/mpdevil.py:1147
|
||||
msgid "Cover regex:"
|
||||
msgstr "Regex des couvertures :"
|
||||
|
||||
#. connect button
|
||||
#: src/mpdevil.py:1150 src/mpdevil.py:3139
|
||||
msgid "Connect"
|
||||
msgstr "Se connecter"
|
||||
|
||||
#: src/mpdevil.py:1173 src/mpdevil.py:1175 src/mpdevil.py:3140
|
||||
#: src/mpdevil.py:3236
|
||||
msgid "Preferences"
|
||||
msgstr "Préférences"
|
||||
|
||||
#: src/mpdevil.py:1187 src/mpdevil.py:1197
|
||||
msgid "View"
|
||||
msgstr "Vue"
|
||||
|
||||
#: src/mpdevil.py:1188 src/mpdevil.py:1198
|
||||
msgid "Behavior"
|
||||
msgstr "Comportement"
|
||||
|
||||
#: src/mpdevil.py:1189 src/mpdevil.py:1199
|
||||
msgid "Connection"
|
||||
msgstr "Connexion"
|
||||
|
||||
#: src/mpdevil.py:1216
|
||||
msgid "Stats"
|
||||
msgstr "Statistiques"
|
||||
|
||||
#: src/mpdevil.py:1225
|
||||
msgid "<b>Protocol:</b>"
|
||||
msgstr "<b>Protocole :</b>"
|
||||
|
||||
#: src/mpdevil.py:1226
|
||||
msgid "<b>Uptime:</b>"
|
||||
msgstr "<b>Durée d’activité :</b>"
|
||||
|
||||
#: src/mpdevil.py:1227
|
||||
msgid "<b>Playtime:</b>"
|
||||
msgstr "<b>Durée de lecture :</b>"
|
||||
|
||||
#: src/mpdevil.py:1228
|
||||
msgid "<b>Artists:</b>"
|
||||
msgstr "<b>Artistes :</b>"
|
||||
|
||||
#: src/mpdevil.py:1229
|
||||
msgid "<b>Albums:</b>"
|
||||
msgstr "<b>Albums :</b>"
|
||||
|
||||
#: src/mpdevil.py:1230
|
||||
msgid "<b>Songs:</b>"
|
||||
msgstr "<b>Chansons :</b>"
|
||||
|
||||
#: src/mpdevil.py:1231
|
||||
msgid "<b>Total Playtime:</b>"
|
||||
msgstr "<b>Temps total de lecture :</b>"
|
||||
|
||||
#: src/mpdevil.py:1232
|
||||
msgid "<b>Database Update:</b>"
|
||||
msgstr "<b>Mise à jour de la base :</b>"
|
||||
|
||||
#: src/mpdevil.py:1292
|
||||
msgid "Show in file manager"
|
||||
msgstr "Afficher dans le gestionnaire de fichiers"
|
||||
|
||||
#: src/mpdevil.py:1296 data/ShortcutsWindow.ui:208
|
||||
msgid "Append"
|
||||
msgstr "Ajouter"
|
||||
|
||||
#: src/mpdevil.py:1296 src/mpdevil.py:2690 src/mpdevil.py:2723
|
||||
msgid "Play"
|
||||
msgstr "Jouer"
|
||||
|
||||
#: src/mpdevil.py:1312
|
||||
msgid "MPD-Tag"
|
||||
msgstr "Étiquette MPD"
|
||||
|
||||
#: src/mpdevil.py:1315
|
||||
msgid "Value"
|
||||
msgstr "Valeur"
|
||||
|
||||
#: src/mpdevil.py:1385 src/mpdevil.py:2212
|
||||
msgid "No"
|
||||
msgstr "Non"
|
||||
|
||||
#: src/mpdevil.py:1386 src/mpdevil.py:2213
|
||||
msgid "Title"
|
||||
msgstr "Titre"
|
||||
|
||||
#: src/mpdevil.py:1387 src/mpdevil.py:2214
|
||||
msgid "Length"
|
||||
msgstr "Longueur"
|
||||
|
||||
#: src/mpdevil.py:1400
|
||||
msgid "Add all titles to playlist"
|
||||
msgstr "Ajouter tous les titres à la liste de lecture"
|
||||
|
||||
#: src/mpdevil.py:1401
|
||||
msgid "Directly play all titles"
|
||||
msgstr "Jouer directement tous les titres"
|
||||
|
||||
#: src/mpdevil.py:1494
|
||||
#, python-brace-format
|
||||
msgid "{number} song ({duration})"
|
||||
msgid_plural "{number} songs ({duration})"
|
||||
msgstr[0] "{number} chanson ({duration})"
|
||||
msgstr[1] "{number} chansons ({duration})"
|
||||
|
||||
#: src/mpdevil.py:1557
|
||||
#, python-brace-format
|
||||
msgid "{hits} hit"
|
||||
msgid_plural "{hits} hits"
|
||||
msgstr[0] "{hits} hit"
|
||||
msgstr[1] "{hits} hits"
|
||||
|
||||
#: src/mpdevil.py:1642
|
||||
msgid "all tags"
|
||||
msgstr "toutes les étiquettes"
|
||||
|
||||
#: src/mpdevil.py:1774
|
||||
msgid "all genres"
|
||||
msgstr "tous les genres"
|
||||
|
||||
#: src/mpdevil.py:1797
|
||||
msgid "all artists"
|
||||
msgstr "tous les artistes"
|
||||
|
||||
#: src/mpdevil.py:2384
|
||||
msgid "Scroll to current song"
|
||||
msgstr "Défiler jusqu'à la chanson courante"
|
||||
|
||||
#: src/mpdevil.py:2502
|
||||
msgid "searching…"
|
||||
msgstr "recherche…"
|
||||
|
||||
#: src/mpdevil.py:2507
|
||||
msgid "connection error"
|
||||
msgstr "erreur de connexion"
|
||||
|
||||
#: src/mpdevil.py:2509
|
||||
msgid "lyrics not found"
|
||||
msgstr "paroles introuvables"
|
||||
|
||||
#: src/mpdevil.py:2634
|
||||
msgid "Lyrics"
|
||||
msgstr "Paroles"
|
||||
|
||||
#: src/mpdevil.py:2692 data/ShortcutsWindow.ui:105
|
||||
msgid "Stop"
|
||||
msgstr "Stop"
|
||||
|
||||
#: src/mpdevil.py:2696 data/ShortcutsWindow.ui:126
|
||||
msgid "Previous title"
|
||||
msgstr "Titre précédent"
|
||||
|
||||
#: src/mpdevil.py:2699 data/ShortcutsWindow.ui:119
|
||||
msgid "Next title"
|
||||
msgstr "Titre suivant"
|
||||
|
||||
#: src/mpdevil.py:2720
|
||||
msgid "Pause"
|
||||
msgstr "Pause"
|
||||
|
||||
#: src/mpdevil.py:2892
|
||||
msgid "Repeat mode"
|
||||
msgstr "Mode répétition"
|
||||
|
||||
#: src/mpdevil.py:2893
|
||||
msgid "Random mode"
|
||||
msgstr "Mode aléatoire"
|
||||
|
||||
#: src/mpdevil.py:2894
|
||||
msgid "Single mode"
|
||||
msgstr "Mode chanson unique"
|
||||
|
||||
#: src/mpdevil.py:2895
|
||||
msgid "Consume mode"
|
||||
msgstr "Mode consommer"
|
||||
|
||||
#: src/mpdevil.py:3109
|
||||
msgid "Updating Database…"
|
||||
msgstr "Mise à jour de la base…"
|
||||
|
||||
#: src/mpdevil.py:3157
|
||||
#, python-brace-format
|
||||
msgid "Connection to “{socket}” failed"
|
||||
msgstr "La connexion à “{socket}” a échoué"
|
||||
|
||||
#: src/mpdevil.py:3159
|
||||
#, python-brace-format
|
||||
msgid "Connection to “{host}:{port}” failed"
|
||||
msgstr "La connexion à “{host}:{port}” a échoué"
|
||||
|
||||
#: src/mpdevil.py:3220
|
||||
msgid "Search"
|
||||
msgstr "Rechercher"
|
||||
|
||||
#: src/mpdevil.py:3223 data/ShortcutsWindow.ui:85
|
||||
msgid "Back to current album"
|
||||
msgstr "Retour à l'album courant"
|
||||
|
||||
#: src/mpdevil.py:3237
|
||||
msgid "Keyboard Shortcuts"
|
||||
msgstr "Raccourcis clavier"
|
||||
|
||||
#: src/mpdevil.py:3238
|
||||
msgid "Help"
|
||||
msgstr "Aide"
|
||||
|
||||
#: src/mpdevil.py:3239
|
||||
msgid "About mpdevil"
|
||||
msgstr "À propos de mpdevil"
|
||||
|
||||
#: src/mpdevil.py:3241
|
||||
msgid "Update Database"
|
||||
msgstr "Mettre à jour la base"
|
||||
|
||||
#: src/mpdevil.py:3242
|
||||
msgid "Server Stats"
|
||||
msgstr "Statistiques serveur"
|
||||
|
||||
#: src/mpdevil.py:3244
|
||||
msgid "Mini Player"
|
||||
msgstr "Mini lecteur"
|
||||
|
||||
#: src/mpdevil.py:3245
|
||||
msgid "Genre Filter"
|
||||
msgstr "Filtre genre"
|
||||
|
||||
#: src/mpdevil.py:3254
|
||||
msgid "Menu"
|
||||
msgstr "Menu"
|
||||
|
||||
#: src/mpdevil.py:3438 src/mpdevil.py:3440
|
||||
msgid "connecting…"
|
||||
msgstr "connexion…"
|
||||
|
||||
#: src/mpdevil.py:3478
|
||||
msgid "Debug mode"
|
||||
msgstr "Mode debug"
|
||||
|
||||
#: data/org.mpdevil.mpdevil.desktop.in:3
|
||||
msgid "mpdevil"
|
||||
msgstr "mpdevil"
|
||||
|
||||
#: data/org.mpdevil.mpdevil.desktop.in:4
|
||||
msgid "MPD Client"
|
||||
msgstr "Client MPD"
|
||||
|
||||
#: data/org.mpdevil.mpdevil.desktop.in:5 data/AboutDialog.ui:7
|
||||
msgid "A simple music browser for MPD"
|
||||
msgstr "Un simple navigateur de musique pour MPD"
|
||||
|
||||
#: data/ShortcutsWindow.ui:12
|
||||
msgid "General"
|
||||
msgstr "Général"
|
||||
|
||||
#: data/ShortcutsWindow.ui:16
|
||||
msgid "Open online help"
|
||||
msgstr "Ouvrir l'aide en ligne"
|
||||
|
||||
#: data/ShortcutsWindow.ui:23
|
||||
msgid "Open shortcuts window"
|
||||
msgstr "Ouvrir la fenêtre des raccourcis"
|
||||
|
||||
#: data/ShortcutsWindow.ui:30
|
||||
msgid "Open menu"
|
||||
msgstr "Ouvrir le menu"
|
||||
|
||||
#: data/ShortcutsWindow.ui:37
|
||||
msgid "Update database"
|
||||
msgstr "Mettre à jour la base"
|
||||
|
||||
#: data/ShortcutsWindow.ui:44
|
||||
msgid "Quit"
|
||||
msgstr "Quitter"
|
||||
|
||||
#: data/ShortcutsWindow.ui:53
|
||||
msgid "Window"
|
||||
msgstr "Fenêtre"
|
||||
|
||||
#: data/ShortcutsWindow.ui:57
|
||||
msgid "Toggle mini player"
|
||||
msgstr "(Dés-)activer mini lecteur"
|
||||
|
||||
#: data/ShortcutsWindow.ui:64
|
||||
msgid "Toggle genre filter"
|
||||
msgstr "(Dés-)activer le filtre de genre"
|
||||
|
||||
#: data/ShortcutsWindow.ui:71
|
||||
msgid "Toggle lyrics"
|
||||
msgstr "(Dés-)activer les paroles"
|
||||
|
||||
#: data/ShortcutsWindow.ui:78
|
||||
msgid "Toggle search"
|
||||
msgstr "(Dés-)activer la recherche"
|
||||
|
||||
#: data/ShortcutsWindow.ui:94
|
||||
msgid "Playback"
|
||||
msgstr "Playback"
|
||||
|
||||
#: data/ShortcutsWindow.ui:98
|
||||
msgid "Play/Pause"
|
||||
msgstr "Jouer/Pause"
|
||||
|
||||
#: data/ShortcutsWindow.ui:112
|
||||
msgid "Stop after current title"
|
||||
msgstr "Arrêter après le titre courant"
|
||||
|
||||
#: data/ShortcutsWindow.ui:133
|
||||
msgid "Seek forward"
|
||||
msgstr "Atteindre vers l'avant"
|
||||
|
||||
#: data/ShortcutsWindow.ui:140
|
||||
msgid "Seek backward"
|
||||
msgstr "Atteindre vers l'arrière"
|
||||
|
||||
#: data/ShortcutsWindow.ui:147
|
||||
msgid "Toggle repeat mode"
|
||||
msgstr "(Dés-)activer le mode répétition"
|
||||
|
||||
#: data/ShortcutsWindow.ui:154
|
||||
msgid "Toggle random mode"
|
||||
msgstr "(Dés-)activer le mode aléatoire"
|
||||
|
||||
#: data/ShortcutsWindow.ui:161
|
||||
msgid "Toggle single mode"
|
||||
msgstr "(Dés-)activer le mode titre unique"
|
||||
|
||||
#: data/ShortcutsWindow.ui:168
|
||||
msgid "Toggle consume mode"
|
||||
msgstr "(Dés-)activer le mode consommer"
|
||||
|
||||
#: data/ShortcutsWindow.ui:177
|
||||
msgid "Playlist"
|
||||
msgstr "Liste de lecture"
|
||||
|
||||
#: data/ShortcutsWindow.ui:181
|
||||
msgid "Remove song"
|
||||
msgstr "Supprimer la chanson"
|
||||
|
||||
#: data/ShortcutsWindow.ui:188
|
||||
msgid "Clear playlist"
|
||||
msgstr "Effacer la liste de lecture"
|
||||
|
||||
#: data/ShortcutsWindow.ui:195 data/ShortcutsWindow.ui:222
|
||||
msgid "Show information"
|
||||
msgstr "Afficher les informations"
|
||||
|
||||
#: data/ShortcutsWindow.ui:204
|
||||
msgid "Search, Album Dialog and Album List"
|
||||
msgstr "Recherche, Boîte de dialogue album et Liste d’album"
|
||||
|
||||
#: data/ShortcutsWindow.ui:215
|
||||
msgid "Play immediately"
|
||||
msgstr "Jouer immédiatement"
|
293
src/mpdevil.py
293
src/mpdevil.py
|
@ -763,12 +763,7 @@ class Client(MPDClient):
|
|||
except:
|
||||
return False
|
||||
|
||||
def _to_playlist(self, append, mode="default"): # modes: default, play, append, enqueue
|
||||
if mode == "default":
|
||||
if self._settings.get_boolean("force-mode"):
|
||||
mode="play"
|
||||
else:
|
||||
mode="enqueue"
|
||||
def _to_playlist(self, append, mode): # modes: play, append, enqueue
|
||||
if mode == "append":
|
||||
append()
|
||||
elif mode == "play":
|
||||
|
@ -793,13 +788,13 @@ class Client(MPDClient):
|
|||
self.move(0, duplicates[1]["pos"])
|
||||
self.delete(int(duplicates[1]["pos"])-1)
|
||||
|
||||
def files_to_playlist(self, files, mode="default"):
|
||||
def files_to_playlist(self, files, mode):
|
||||
def append():
|
||||
for f in files:
|
||||
self.add(f)
|
||||
self._to_playlist(append, mode)
|
||||
|
||||
def filter_to_playlist(self, tag_filter, mode="default"):
|
||||
def filter_to_playlist(self, tag_filter, mode):
|
||||
def append():
|
||||
if tag_filter:
|
||||
self.findadd(*tag_filter)
|
||||
|
@ -807,7 +802,7 @@ class Client(MPDClient):
|
|||
self.searchadd("any", "")
|
||||
self._to_playlist(append, mode)
|
||||
|
||||
def album_to_playlist(self, albumartist, album, date, mode="default"):
|
||||
def album_to_playlist(self, albumartist, album, date, mode):
|
||||
self.filter_to_playlist(("albumartist", albumartist, "album", album, "date", date), mode)
|
||||
|
||||
def comp_list(self, *args): # simulates listing behavior of python-mpd2 1.0
|
||||
|
@ -1069,7 +1064,6 @@ class BehaviorSettings(SettingsList):
|
|||
(_("Support “MPRIS”"), "mpris", True),
|
||||
(_("Sort albums by year"), "sort-albums-by-year", False),
|
||||
(_("Send notification on title change"), "send-notify", False),
|
||||
(_("Play selected albums and titles immediately"), "force-mode", False),
|
||||
(_("Rewind via previous button"), "rewind-mode", False),
|
||||
(_("Stop playback on quit"), "stop-on-quit", False),
|
||||
)
|
||||
|
@ -1365,18 +1359,17 @@ class SongPopover(Gtk.Popover):
|
|||
self.popdown()
|
||||
|
||||
class SongsList(TreeView):
|
||||
__gsignals__={"button-clicked": (GObject.SignalFlags.RUN_FIRST, None, ())}
|
||||
def __init__(self, client, width=-1):
|
||||
super().__init__(enable_search=False, activate_on_single_click=True, headers_visible=False)
|
||||
def __init__(self, client):
|
||||
super().__init__(activate_on_single_click=True, headers_visible=False, enable_search=False, search_column=4)
|
||||
self._client=client
|
||||
|
||||
# store
|
||||
# (track, title, duration, file)
|
||||
self._store=Gtk.ListStore(str, str, str, str)
|
||||
# (track, title, duration, file, search string)
|
||||
self._store=Gtk.ListStore(str, str, str, str, str)
|
||||
self.set_model(self._store)
|
||||
|
||||
# columns
|
||||
renderer_text=Gtk.CellRendererText(width_chars=width, ellipsize=Pango.EllipsizeMode.END, ellipsize_set=True)
|
||||
renderer_text=Gtk.CellRendererText(ellipsize=Pango.EllipsizeMode.END, ellipsize_set=True)
|
||||
attrs=Pango.AttrList()
|
||||
attrs.insert(Pango.AttrFontFeatures.new("tnum 1"))
|
||||
renderer_text_ralign_tnum=Gtk.CellRendererText(xalign=1, attributes=attrs, ypad=6)
|
||||
|
@ -1394,6 +1387,7 @@ class SongsList(TreeView):
|
|||
|
||||
# selection
|
||||
self._selection=self.get_selection()
|
||||
self._selection.set_mode(Gtk.SelectionMode.BROWSE)
|
||||
|
||||
# buttons
|
||||
self.buttons=Gtk.ButtonBox(layout_style=Gtk.ButtonBoxStyle.EXPAND)
|
||||
|
@ -1417,11 +1411,11 @@ class SongsList(TreeView):
|
|||
self._song_popover.popdown()
|
||||
self._store.clear()
|
||||
|
||||
def append(self, track, title, duration, file):
|
||||
self._store.insert_with_valuesv(-1, range(4), [track, title, duration, file])
|
||||
def append(self, track, title, duration, file, search_string=""):
|
||||
self._store.insert_with_valuesv(-1, range(5), [track, title, duration, file, search_string])
|
||||
|
||||
def _on_row_activated(self, widget, path, view_column):
|
||||
self._client.files_to_playlist([self._store[path][3]])
|
||||
self._client.files_to_playlist([self._store[path][3]], "play")
|
||||
|
||||
def _on_button_press_event(self, widget, event):
|
||||
if (path_re:=widget.get_path_at_pos(int(event.x), int(event.y))) is not None:
|
||||
|
@ -1437,7 +1431,6 @@ class SongsList(TreeView):
|
|||
|
||||
def _on_button_clicked(self, widget, mode):
|
||||
self._client.files_to_playlist((row[3] for row in self._store), mode)
|
||||
self.emit("button-clicked")
|
||||
|
||||
def show_info(self):
|
||||
if (path:=self.get_cursor()[0]) is not None:
|
||||
|
@ -1447,71 +1440,6 @@ class SongsList(TreeView):
|
|||
if (path:=self.get_cursor()[0]) is not None:
|
||||
self._client.files_to_playlist([self._store[path][3]], mode)
|
||||
|
||||
class AlbumPopover(Gtk.Popover):
|
||||
def __init__(self, client, settings):
|
||||
super().__init__(position=Gtk.PositionType.BOTTOM)
|
||||
self._client=client
|
||||
self._settings=settings
|
||||
self._rect=Gdk.Rectangle()
|
||||
|
||||
# songs list
|
||||
# sizing needed for correct popover height
|
||||
self._songs_list=SongsList(self._client, width=60)
|
||||
|
||||
# scroll
|
||||
self._scroll=Gtk.ScrolledWindow(child=self._songs_list, propagate_natural_height=True)
|
||||
self._scroll.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC)
|
||||
|
||||
# label
|
||||
self._label=Gtk.Label()
|
||||
|
||||
# connect
|
||||
self._songs_list.connect("button-clicked", lambda *args: self.popdown())
|
||||
|
||||
# packing
|
||||
vbox=Gtk.Box(orientation=Gtk.Orientation.VERTICAL, border_width=6, spacing=6)
|
||||
hbox=Gtk.Box(spacing=6)
|
||||
hbox.pack_end(self._songs_list.buttons, False, False, 0)
|
||||
hbox.pack_start(self._label, False, False, 6)
|
||||
frame=Gtk.Frame(child=self._scroll)
|
||||
vbox.pack_start(frame, True, True, 0)
|
||||
vbox.pack_end(hbox, False, False, 0)
|
||||
self.add(vbox)
|
||||
vbox.show_all()
|
||||
|
||||
def open(self, albumartist, album, date, widget, x, y):
|
||||
self._rect.x=x
|
||||
self._rect.y=y
|
||||
self.set_pointing_to(self._rect)
|
||||
self.set_relative_to(widget)
|
||||
window=self.get_toplevel()
|
||||
self._scroll.set_max_content_height(window.get_size()[1]//2)
|
||||
self._songs_list.clear()
|
||||
tag_filter=("albumartist", albumartist, "album", album, "date", date)
|
||||
count=self._client.count(*tag_filter)
|
||||
duration=str(Duration(count["playtime"]))
|
||||
length=int(count["songs"])
|
||||
text=ngettext("{number} song ({duration})", "{number} songs ({duration})", length).format(number=length, duration=duration)
|
||||
self._label.set_text(text)
|
||||
self._client.restrict_tagtypes("track", "title", "artist")
|
||||
songs=self._client.find(*tag_filter)
|
||||
self._client.tagtypes("all")
|
||||
for song in songs:
|
||||
# only show artists =/= albumartist
|
||||
try:
|
||||
song["artist"].remove(albumartist)
|
||||
except ValueError:
|
||||
pass
|
||||
artist=str(song['artist'])
|
||||
if artist == albumartist or not artist:
|
||||
title_artist=f"<b>{GLib.markup_escape_text(song['title'][0])}</b>"
|
||||
else:
|
||||
title_artist=f"<b>{GLib.markup_escape_text(song['title'][0])}</b> • {GLib.markup_escape_text(artist)}"
|
||||
self._songs_list.append(song["track"][0], title_artist, str(song["duration"]), song["file"])
|
||||
self._songs_list.scroll_to_cell(Gtk.TreePath(0), None, False) # clear old scroll position
|
||||
self.popup()
|
||||
self._songs_list.columns_autosize()
|
||||
|
||||
##########
|
||||
# search #
|
||||
##########
|
||||
|
@ -1677,7 +1605,9 @@ class SearchWindow(Gtk.Box):
|
|||
###########
|
||||
|
||||
class SelectionList(TreeView):
|
||||
__gsignals__={"item-selected": (GObject.SignalFlags.RUN_FIRST, None, ()), "clear": (GObject.SignalFlags.RUN_FIRST, None, ())}
|
||||
__gsignals__={"item-selected": (GObject.SignalFlags.RUN_FIRST, None, ()),
|
||||
"item-reselected": (GObject.SignalFlags.RUN_FIRST, None, ()),
|
||||
"clear": (GObject.SignalFlags.RUN_FIRST, None, ())}
|
||||
def __init__(self, select_all_string):
|
||||
super().__init__(search_column=0, headers_visible=False, fixed_height_mode=True)
|
||||
self.select_all_string=select_all_string
|
||||
|
@ -1737,7 +1667,7 @@ class SelectionList(TreeView):
|
|||
return len(self._store)-1
|
||||
|
||||
def select_path(self, path):
|
||||
self._selection.select_path(path)
|
||||
self.set_cursor(path)
|
||||
|
||||
def select(self, item):
|
||||
row_num=len(self._store)
|
||||
|
@ -1760,12 +1690,13 @@ class SelectionList(TreeView):
|
|||
return self.get_item_at_path(self.get_path_selected())
|
||||
|
||||
def scroll_to_selected(self):
|
||||
self.set_cursor(Gtk.TreePath(len(self._store)), None, False) # unset cursor
|
||||
self.save_scroll_to_cell(self._selected_path, None, True, 0.25)
|
||||
|
||||
def _on_selection_changed(self, *args):
|
||||
if (treeiter:=self._selection.get_selected()[1]) is not None:
|
||||
if (path:=self._store.get_path(treeiter)) != self._selected_path:
|
||||
if (path:=self._store.get_path(treeiter)) == self._selected_path:
|
||||
self.emit("item-reselected")
|
||||
else:
|
||||
self._selected_path=path
|
||||
self.emit("item-selected")
|
||||
|
||||
|
@ -1997,6 +1928,7 @@ class AlbumLoadingThread(threading.Thread):
|
|||
idle_add(callback)
|
||||
|
||||
class AlbumList(Gtk.IconView):
|
||||
__gsignals__={"album-selected": (GObject.SignalFlags.RUN_FIRST, None, (str,str,str,))}
|
||||
def __init__(self, client, settings, artist_list):
|
||||
super().__init__(item_width=0,pixbuf_column=0,markup_column=1,activate_on_single_click=True,selection_mode=Gtk.SelectionMode.BROWSE)
|
||||
self._settings=settings
|
||||
|
@ -2012,15 +1944,11 @@ class AlbumList(Gtk.IconView):
|
|||
self.progress_bar=Gtk.ProgressBar(no_show_all=True, valign=Gtk.Align.END, vexpand=False)
|
||||
self.progress_bar.get_style_context().add_class("osd")
|
||||
|
||||
# popover
|
||||
self._album_popover=AlbumPopover(self._client, self._settings)
|
||||
|
||||
# cover thread
|
||||
self._cover_thread=AlbumLoadingThread(self._client, self._settings, self.progress_bar, self, self._store, None, None)
|
||||
|
||||
# connect
|
||||
self.connect("item-activated", self._on_item_activated)
|
||||
self.connect("button-press-event", self._on_button_press_event)
|
||||
self._client.emitter.connect("disconnected", self._on_disconnected)
|
||||
self._client.emitter.connect("connected", self._on_connected)
|
||||
self._settings.connect("changed::sort-albums-by-year", self._sort_settings)
|
||||
|
@ -2036,7 +1964,6 @@ class AlbumList(Gtk.IconView):
|
|||
|
||||
def _clear(self, *args):
|
||||
def callback():
|
||||
self._album_popover.popdown()
|
||||
self._workaround_clear()
|
||||
if self._cover_thread.is_alive():
|
||||
self._cover_thread.set_callback(callback)
|
||||
|
@ -2087,28 +2014,13 @@ class AlbumList(Gtk.IconView):
|
|||
else:
|
||||
callback()
|
||||
|
||||
def _path_to_playlist(self, path, mode="default"):
|
||||
def _path_to_playlist(self, path, mode):
|
||||
tags=self._store[path][3:6]
|
||||
self._client.album_to_playlist(*tags, mode)
|
||||
|
||||
def _on_button_press_event(self, widget, event):
|
||||
path=widget.get_path_at_pos(int(event.x), int(event.y))
|
||||
if event.button == 1 and event.type == Gdk.EventType._2BUTTON_PRESS:
|
||||
if path is not None:
|
||||
self._path_to_playlist(path, "play")
|
||||
elif event.button == 2 and event.type == Gdk.EventType.BUTTON_PRESS:
|
||||
if path is not None:
|
||||
self._path_to_playlist(path, "append")
|
||||
elif event.button == 3 and event.type == Gdk.EventType.BUTTON_PRESS:
|
||||
v=self.get_vadjustment().get_value()
|
||||
h=self.get_hadjustment().get_value()
|
||||
if path is not None:
|
||||
tags=self._store[path][3:6]
|
||||
# when using "button-press-event" in iconview popovers only show up in combination with idle_add (bug in GTK?)
|
||||
idle_add(self._album_popover.open, *tags, widget, event.x-h, event.y-v)
|
||||
|
||||
def _on_item_activated(self, widget, path):
|
||||
self._path_to_playlist(path)
|
||||
tags=self._store[path][3:6]
|
||||
self.emit("album-selected", *tags)
|
||||
|
||||
def _on_disconnected(self, *args):
|
||||
self.set_sensitive(False)
|
||||
|
@ -2116,23 +2028,97 @@ class AlbumList(Gtk.IconView):
|
|||
def _on_connected(self, *args):
|
||||
self.set_sensitive(True)
|
||||
|
||||
def show_info(self):
|
||||
if (path:=self.get_cursor()[1]) is not None:
|
||||
cell=self.get_cell_rect(path, None)[1]
|
||||
rect=self.get_allocation()
|
||||
x=max(min(cell.x+cell.width//2, rect.x+rect.width), rect.x)
|
||||
y=max(min(cell.y+cell.height//2, rect.y+rect.height), rect.y)
|
||||
tags=self._store[path][3:6]
|
||||
self._album_popover.open(*tags, self, x, y)
|
||||
|
||||
def add_to_playlist(self, mode):
|
||||
if (path:=self.get_cursor()[1]) is not None:
|
||||
self._path_to_playlist(path, mode)
|
||||
|
||||
def _on_cover_size_changed(self, *args):
|
||||
if self._client.connected():
|
||||
self._refresh()
|
||||
|
||||
class AlbumView(Gtk.Box):
|
||||
__gsignals__={"close": (GObject.SignalFlags.RUN_FIRST, None, ())}
|
||||
def __init__(self, client, settings):
|
||||
super().__init__(orientation=Gtk.Orientation.VERTICAL)
|
||||
self._client=client
|
||||
self._settings=settings
|
||||
|
||||
# songs list
|
||||
self.songs_list=SongsList(self._client)
|
||||
self.songs_list.set_enable_search(True)
|
||||
self.songs_list.buttons.set_halign(Gtk.Align.END)
|
||||
scroll=Gtk.ScrolledWindow(child=self.songs_list)
|
||||
scroll.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC)
|
||||
|
||||
# cover
|
||||
self._cover=Gtk.Image()
|
||||
size=self._settings.get_int("album-cover")*1.5
|
||||
pixbuf=GdkPixbuf.Pixbuf.new_from_file_at_size(FALLBACK_COVER, size, size)
|
||||
self._cover.set_from_pixbuf(pixbuf)
|
||||
|
||||
# labels
|
||||
self._title=Gtk.Label(margin_start=12, margin_end=12, xalign=0)
|
||||
self._title.set_line_wrap(True) # wrap=True is not working
|
||||
self._duration=Gtk.Label(xalign=1, ellipsize=Pango.EllipsizeMode.END)
|
||||
|
||||
# close button
|
||||
close_button=Gtk.Button(image=Gtk.Image.new_from_icon_name("go-previous-symbolic", Gtk.IconSize.BUTTON), halign=Gtk.Align.START)
|
||||
close_button.set_focus_on_click(False)
|
||||
|
||||
# connect
|
||||
self.connect("hide", lambda *args: print("test"))
|
||||
close_button.connect("clicked", lambda *args: self.emit("close"))
|
||||
|
||||
# packing
|
||||
hbox=Gtk.Box(spacing=12)
|
||||
hbox.pack_end(self.songs_list.buttons, False, False, 0)
|
||||
hbox.pack_end(self._duration, False, False, 0)
|
||||
vbox=Gtk.Box(orientation=Gtk.Orientation.VERTICAL, border_width=6)
|
||||
vbox.pack_start(close_button, False, False, 0)
|
||||
vbox.set_center_widget(self._title)
|
||||
vbox.pack_end(hbox, False, False, 0)
|
||||
header=Gtk.Box()
|
||||
header.pack_start(self._cover, False, False, 0)
|
||||
header.pack_start(Gtk.Separator(), False, False, 0)
|
||||
header.pack_start(vbox, True, True, 0)
|
||||
self.pack_start(header, False, False, 0)
|
||||
self.pack_start(Gtk.Separator(), False, False, 0)
|
||||
self.pack_start(scroll, True, True, 0)
|
||||
|
||||
def display(self, albumartist, album, date):
|
||||
if date:
|
||||
self._title.set_markup(f"<b>{GLib.markup_escape_text(album)}</b> ({GLib.markup_escape_text(date)})\n"
|
||||
f"{GLib.markup_escape_text(albumartist)}")
|
||||
else:
|
||||
self._title.set_markup(f"<b>{GLib.markup_escape_text(album)}</b>\n{GLib.markup_escape_text(albumartist)}")
|
||||
self.songs_list.clear()
|
||||
tag_filter=("albumartist", albumartist, "album", album, "date", date)
|
||||
count=self._client.count(*tag_filter)
|
||||
duration=str(Duration(count["playtime"]))
|
||||
length=int(count["songs"])
|
||||
text=ngettext("{number} song ({duration})", "{number} songs ({duration})", length).format(number=length, duration=duration)
|
||||
self._duration.set_text(text)
|
||||
self._client.restrict_tagtypes("track", "title", "artist")
|
||||
songs=self._client.find(*tag_filter)
|
||||
self._client.tagtypes("all")
|
||||
for song in songs:
|
||||
# only show artists =/= albumartist
|
||||
try:
|
||||
song["artist"].remove(albumartist)
|
||||
except ValueError:
|
||||
pass
|
||||
artist=str(song['artist'])
|
||||
if artist == albumartist or not artist:
|
||||
title_artist=f"<b>{GLib.markup_escape_text(song['title'][0])}</b>"
|
||||
else:
|
||||
title_artist=f"<b>{GLib.markup_escape_text(song['title'][0])}</b> • {GLib.markup_escape_text(artist)}"
|
||||
self.songs_list.append(song["track"][0], title_artist, str(song["duration"]), song["file"], song["title"][0])
|
||||
self.songs_list.save_set_cursor(Gtk.TreePath(0))
|
||||
self.songs_list.columns_autosize()
|
||||
if (cover:=self._client.get_cover({"file": songs[0]["file"], "albumartist": albumartist, "album": album})) is None:
|
||||
size=self._settings.get_int("album-cover")*1.5
|
||||
pixbuf=GdkPixbuf.Pixbuf.new_from_file_at_size(FALLBACK_COVER, size, size)
|
||||
self._cover.set_from_pixbuf(pixbuf)
|
||||
else:
|
||||
size=self._settings.get_int("album-cover")*1.5
|
||||
self._cover.set_from_pixbuf(cover.get_pixbuf(size))
|
||||
|
||||
class Browser(Gtk.Paned):
|
||||
def __init__(self, client, settings):
|
||||
super().__init__()
|
||||
|
@ -2146,6 +2132,16 @@ class Browser(Gtk.Paned):
|
|||
genre_window=Gtk.ScrolledWindow(child=self._genre_list)
|
||||
artist_window=Gtk.ScrolledWindow(child=self._artist_list)
|
||||
album_window=Gtk.ScrolledWindow(child=self._album_list)
|
||||
self._album_view=AlbumView(self._client, self._settings)
|
||||
|
||||
# album overlay
|
||||
album_overlay=Gtk.Overlay(child=album_window)
|
||||
album_overlay.add_overlay(self._album_list.progress_bar)
|
||||
|
||||
# album stack
|
||||
self._album_stack=Gtk.Stack(transition_type=Gtk.StackTransitionType.SLIDE_LEFT_RIGHT, homogeneous=False)
|
||||
self._album_stack.add_named(album_overlay, "album_list")
|
||||
self._album_stack.add_named(self._album_view, "album_view")
|
||||
|
||||
# hide/show genre filter
|
||||
self._genre_list.set_property("visible", True)
|
||||
|
@ -2153,16 +2149,23 @@ class Browser(Gtk.Paned):
|
|||
self._settings.bind("genre-filter", genre_window, "visible", Gio.SettingsBindFlags.GET)
|
||||
self._settings.connect("changed::genre-filter", self._on_genre_filter_changed)
|
||||
|
||||
# connect
|
||||
self._album_list.connect("album-selected", self._on_album_list_show_info)
|
||||
self._album_view.connect("close", lambda *args: self._album_stack.set_visible_child_name("album_list"))
|
||||
self._artist_list.connect("item-selected", lambda *args: self._album_stack.set_visible_child_name("album_list"))
|
||||
self._artist_list.connect("item-reselected", lambda *args: self._album_stack.set_visible_child_name("album_list"))
|
||||
self._client.emitter.connect("disconnected", lambda *args: self._album_stack.set_visible_child_name("album_list"))
|
||||
self._settings.connect("changed::album-cover", lambda *args: self._album_stack.set_visible_child_name("album_list"))
|
||||
|
||||
# packing
|
||||
album_overlay=Gtk.Overlay(child=album_window)
|
||||
album_overlay.add_overlay(self._album_list.progress_bar)
|
||||
self.paned1=Gtk.Paned()
|
||||
self.paned1.pack1(artist_window, False, False)
|
||||
self.paned1.pack2(album_overlay, True, False)
|
||||
self.paned1.pack2(self._album_stack, True, False)
|
||||
self.pack1(genre_window, False, False)
|
||||
self.pack2(self.paned1, True, False)
|
||||
|
||||
def back_to_current_album(self):
|
||||
self._album_stack.set_visible_child_name("album_list")
|
||||
song=self._client.currentsong()
|
||||
artist,genre=self._artist_list.get_artist_selected()
|
||||
if genre is None or song["genre"][0] == genre:
|
||||
|
@ -2180,6 +2183,11 @@ class Browser(Gtk.Paned):
|
|||
if not settings.get_boolean(key):
|
||||
self._genre_list.select_all()
|
||||
|
||||
def _on_album_list_show_info(self, widget, *tags):
|
||||
self._album_view.display(*tags)
|
||||
self._album_stack.set_visible_child_name("album_view")
|
||||
GLib.idle_add(self._album_view.songs_list.grab_focus)
|
||||
|
||||
############
|
||||
# playlist #
|
||||
############
|
||||
|
@ -2261,6 +2269,12 @@ class PlaylistView(TreeView):
|
|||
except IndexError: # invalid path
|
||||
pass
|
||||
|
||||
def _delete(self, path):
|
||||
if path == self.get_property("selected-path"):
|
||||
self._client.files_to_playlist([self._store[path][3]], "enqueue")
|
||||
else:
|
||||
self._store.remove(self._store.get_iter(path))
|
||||
|
||||
def _scroll_to_path(self, path):
|
||||
self.save_scroll_to_cell(path, None, True, 0.25)
|
||||
|
||||
|
@ -2281,7 +2295,7 @@ class PlaylistView(TreeView):
|
|||
if (path_re:=widget.get_path_at_pos(int(event.x), int(event.y))) is not None:
|
||||
path=path_re[0]
|
||||
if event.button == 2 and event.type == Gdk.EventType.BUTTON_PRESS:
|
||||
self._store.remove(self._store.get_iter(path))
|
||||
self._delete(path)
|
||||
elif event.button == 3 and event.type == Gdk.EventType.BUTTON_PRESS:
|
||||
point=self.convert_bin_window_to_widget_coords(event.x,event.y)
|
||||
self._song_popover.open(self._store[path][3], widget, *point)
|
||||
|
@ -2290,7 +2304,7 @@ class PlaylistView(TreeView):
|
|||
if event.keyval == Gdk.keyval_from_name("Delete"):
|
||||
if (path:=self.get_cursor()[0]) is not None:
|
||||
try:
|
||||
self._store.remove(self._store.get_iter(path))
|
||||
self._delete(path)
|
||||
except:
|
||||
pass
|
||||
|
||||
|
@ -2533,15 +2547,10 @@ class CoverEventBox(Gtk.EventBox):
|
|||
self._settings=settings
|
||||
self._click_pos=()
|
||||
self.set_events(Gdk.EventMask.POINTER_MOTION_MASK)
|
||||
|
||||
# album popover
|
||||
self._album_popover=AlbumPopover(self._client, self._settings)
|
||||
|
||||
# connect
|
||||
self.connect("button-press-event", self._on_button_press_event)
|
||||
self.connect("button-release-event", self._on_button_release_event)
|
||||
self.connect("motion-notify-event", self._on_motion_notify_event)
|
||||
self._client.emitter.connect("disconnected", self._on_disconnected)
|
||||
|
||||
def _on_button_press_event(self, widget, event):
|
||||
if event.button == 1 and event.type == Gdk.EventType.BUTTON_PRESS:
|
||||
|
@ -2553,9 +2562,7 @@ class CoverEventBox(Gtk.EventBox):
|
|||
if (song:=self._client.currentsong()):
|
||||
tags=(song["albumartist"][0], song["album"][0], song["date"][0])
|
||||
if event.button == 1:
|
||||
self._client.album_to_playlist(*tags)
|
||||
elif event.button == 3:
|
||||
self._album_popover.open(*tags, widget, event.x, event.y)
|
||||
self._client.album_to_playlist(*tags, "enqueue")
|
||||
self._click_pos=()
|
||||
|
||||
def _on_motion_notify_event(self, widget, event):
|
||||
|
@ -2569,14 +2576,10 @@ class CoverEventBox(Gtk.EventBox):
|
|||
window.begin_move_drag(1, event.x_root, event.y_root, Gdk.CURRENT_TIME)
|
||||
self._click_pos=()
|
||||
|
||||
def _on_disconnected(self, *args):
|
||||
self._album_popover.popdown()
|
||||
|
||||
class MainCover(Gtk.DrawingArea):
|
||||
def __init__(self, client, settings):
|
||||
def __init__(self, client):
|
||||
super().__init__()
|
||||
self._client=client
|
||||
self._settings=settings
|
||||
self._fallback=True
|
||||
|
||||
# connect
|
||||
|
@ -2625,7 +2628,7 @@ class CoverLyricsWindow(Gtk.Overlay):
|
|||
self._settings=settings
|
||||
|
||||
# cover
|
||||
main_cover=MainCover(self._client, self._settings)
|
||||
main_cover=MainCover(self._client)
|
||||
self._cover_event_box=CoverEventBox(self._client, self._settings)
|
||||
self._cover_event_box.add(Gtk.AspectFrame(child=main_cover, shadow_type=Gtk.ShadowType.NONE))
|
||||
|
||||
|
@ -3267,7 +3270,6 @@ class MainWindow(Gtk.ApplicationWindow):
|
|||
self._client.emitter.connect("connection_error", self._on_connection_error)
|
||||
# auto save window state and size
|
||||
self.connect("size-allocate", self._on_size_allocate)
|
||||
self._settings.bind("maximize", self, "is-maximized", Gio.SettingsBindFlags.SET)
|
||||
|
||||
# packing
|
||||
self._on_playlist_pos_changed() # set orientation
|
||||
|
@ -3314,6 +3316,7 @@ class MainWindow(Gtk.ApplicationWindow):
|
|||
Gtk.main_iteration_do(True)
|
||||
if not self._settings.get_boolean("mini-player"):
|
||||
self._bind_paned_settings() # restore paned settings when window is visible (fixes a bug when window is maximized)
|
||||
self._settings.bind("maximize", self, "is-maximized", Gio.SettingsBindFlags.SET) # same problem as one line above
|
||||
self._client.start()
|
||||
|
||||
def _clear_title(self):
|
||||
|
|
Loading…
Reference in New Issue