# # Copyright (C) 2009 Anton Khirnov # # Nephilim is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # Nephilim is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with Nephilim. If not, see . # from PyQt5 import QtGui, QtWidgets, QtCore from ..plugin import Plugin class Songinfo(Plugin): #### PUBLIC #### # const info = 'Displays song metadata provided by MPD.' # read-only o = None tags = None #### PRIVATE #### DEFAULTS = {'tagtypes' : ['track', 'title', 'artist', 'album', 'albumartist', 'disc', 'genre', 'date', 'composer', 'performer', 'file']} #### PUBLIC #### def __init__(self, parent, mpclient, name): Plugin.__init__(self, parent, mpclient, name) self.tags = [] def _load(self): self.o = SonginfoWidget(self) self.mpclient.song_changed.connect(self.refresh) self.mpclient.connect_changed.connect(self.update_tagtypes) if self.mpclient.is_connected(): self.update_tagtypes() self.refresh() def _unload(self): self.mpclient.song_changed.disconnect(self.refresh) self.mpclient.connect_changed.disconnect(self.update_tagtypes) self.o = None def _get_dock_widget(self): return self._create_dock(self.o) def get_settings_widget(self): return SettingsWidgetSonginfo(self) def update_tagtypes(self): self.tags = [tag for tag in self.settings.value(self.name + '/tagtypes') if tag in self.mpclient.tagtypes] self.o.set_tagtypes(self.tags) def refresh(self): self.logger.info('Refreshing.') metadata = {} song = self.mpclient.cur_song if not song: return self.o.clear() for tag in self.tags: metadata[tag] = song[tag] if tag in song else '' self.o.set_metadata(metadata) self.mpclient.sticker_list(song['file'], self.o.set_stickers) class SonginfoWidget(QtWidgets.QWidget): #### PUBLIC #### "parent plugin" plugin = None #### PRIVATE #### _labels = None _st_label = None _stickers = None #### PUBLIC #### def __init__(self, plugin): QtWidgets.QWidget.__init__(self) self.plugin = plugin self._labels = {} self._st_label = QtWidgets.QLabel('Stickers:', self) self._st_label.setAlignment(QtCore.Qt.AlignHCenter) self._stickers = StickersList(self.plugin.mpclient, self) self.setLayout(QtWidgets.QGridLayout()) self.layout().setColumnStretch(1, 1) def set_tagtypes(self, tagtypes): """Setup labels for each tagtype in the list.""" # clear old data for i in range(len(self._labels)): it = self.layout().itemAtPosition(i, 0) it1 = self.layout().itemAtPosition(i, 1) if it: self.layout().removeItem(it) it.widget().setParent(None) if it1: self.layout().removeItem(it1) it1.widget().setParent(None) self._labels = {} self.layout().removeWidget(self._st_label) self.layout().removeWidget(self._stickers) for tag in tagtypes: label = QtWidgets.QLabel('%s'%tag) #TODO sort known tags label1 = QtWidgets.QLabel() # tag value will go here label1.setTextInteractionFlags(QtCore.Qt.TextSelectableByMouse) label.setWordWrap(True) label1.setWordWrap(True) self.layout().addWidget(label, len(self._labels), 0, QtCore.Qt.AlignRight) self.layout().addWidget(label1, len(self._labels), 1) self._labels[tag] = label1 self.layout().addWidget(self._st_label, self.layout().rowCount(), 0, 1, 2) self.layout().addWidget(self._stickers, self.layout().rowCount(), 0, 1, 2) def set_metadata(self, metadata): """Set displayed metadata, which is provided in a dict of { tag : value }.""" for tag in metadata: self._labels[tag].setText(metadata[tag]) def set_stickers(self, stickers): """Set displayed stickers from a (key, value) iterator.""" self._stickers.set_stickers(stickers) def clear(self): """ Clear displayed metadata. """ for label in self._labels.values(): label.clear() self._stickers.clear() class SettingsWidgetSonginfo(Plugin.SettingsWidget): #### PRIVATE #### _taglist = None #### PUBLIC #### def __init__(self, plugin): Plugin.SettingsWidget.__init__(self, plugin) self.settings.beginGroup(self.plugin.name) self._taglist = QtWidgets.QListWidget(self) self._taglist.setDragDropMode(QtWidgets.QAbstractItemView.InternalMove) self._update_tags() self.plugin.mpclient.connect_changed.connect(self._update_tags) self.setLayout(QtWidgets.QVBoxLayout()) self._add_widget(self._taglist, label = 'Tags', tooltip = 'A list of tags that should be displayed.\n' 'Use drag and drop to change their order') def save_settings(self): if not self._taglist.isEnabled(): return tags = [] for i in range(self._taglist.count()): it = self._taglist.item(i) if it.checkState() == QtCore.Qt.Checked: tags.append(it.text()) self.settings.setValue('tagtypes', tags) self.plugin.update_tagtypes() self.plugin.refresh() #### PRIVATE #### def _update_tags(self): self._taglist.setEnabled(self.plugin.mpclient.is_connected()) if not self.plugin.mpclient.is_connected(): return self._taglist.clear() tags_enabled = self.settings.value('tagtypes') tags = self.plugin.mpclient.tagtypes for tag in [tag for tag in tags_enabled if tag in tags]: it = QtWidgets.QListWidgetItem(tag) it.setCheckState(QtCore.Qt.Checked) self._taglist.addItem(it) for tag in [tag for tag in tags if tag not in tags_enabled]: it = QtWidgets.QListWidgetItem(tag) it.setCheckState(QtCore.Qt.Unchecked) self._taglist.addItem(it) class StickersList(QtWidgets.QTreeWidget): #### PUBLIC #### mpclient = None def __init__(self, mpclient, parent): QtWidgets.QTreeWidget.__init__(self, parent) self.mpclient = mpclient self.setAlternatingRowColors(True) self.setRootIsDecorated(False) self.setColumnCount(2) self.setHeaderLabels(['key', 'value']) def set_stickers(self, stickers): """Set displayed stickers from a (key, value) iterator.""" self.clear() for key, value in stickers: it = QtWidgets.QTreeWidgetItem([key, value]) self.addTopLevelItem(it)