common: split MetadataFetcher into its own file
[nephilim.git] / nephilim / plugins / Songinfo.py
blob074bb30f8510e02e269d67c21e3a6d49a88ed180
2 # Copyright (C) 2009 Anton Khirnov <wyskas@gmail.com>
4 # Nephilim is free software: you can redistribute it and/or modify
5 # it under the terms of the GNU General Public License as published by
6 # the Free Software Foundation, either version 3 of the License, or
7 # (at your option) any later version.
9 # Nephilim is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
14 # You should have received a copy of the GNU General Public License
15 # along with Nephilim. If not, see <http://www.gnu.org/licenses/>.
18 from PyQt4 import QtGui, QtCore
20 from ..plugin import Plugin
22 class Songinfo(Plugin):
24 #### PUBLIC ####
25 # const
26 info = 'Displays song metadata provided by MPD.'
28 # read-only
29 o = None
30 tags = None
32 #### PRIVATE ####
33 DEFAULTS = {'tagtypes' : ['track', 'title', 'artist', 'album',
34 'albumartist', 'disc', 'genre', 'date', 'composer', 'performer', 'file']}
36 #### PUBLIC ####
37 def __init__(self, parent, mpclient, name):
38 Plugin.__init__(self, parent, mpclient, name)
40 self.tags = []
41 def _load(self):
42 self.o = SonginfoWidget(self)
43 self.mpclient.song_changed.connect(self.refresh)
44 self.mpclient.connect_changed.connect(self.update_tagtypes)
46 if self.mpclient.is_connected():
47 self.update_tagtypes()
48 self.refresh()
49 def _unload(self):
50 self.mpclient.song_changed.disconnect(self.refresh)
51 self.mpclient.connect_changed.disconnect(self.update_tagtypes)
52 self.o = None
53 def _get_dock_widget(self):
54 return self._create_dock(self.o)
55 def get_settings_widget(self):
56 return SettingsWidgetSonginfo(self)
58 def update_tagtypes(self):
59 self.tags = [tag for tag in self.settings.value(self.name + '/tagtypes') if tag in self.mpclient.tagtypes]
60 self.o.set_tagtypes(self.tags)
61 def refresh(self):
62 self.logger.info('Refreshing.')
63 metadata = {}
64 song = self.mpclient.cur_song
66 if not song:
67 return self.o.clear()
69 for tag in self.tags:
70 metadata[tag] = song[tag] if tag in song else ''
71 self.o.set_metadata(metadata)
73 class SonginfoWidget(QtGui.QWidget):
75 #### PUBLIC ####
76 "parent plugin"
77 plugin = None
79 #### PRIVATE ####
80 _labels = None
81 _st_label = None
82 _stickers = None
84 #### PUBLIC ####
85 def __init__(self, plugin):
86 QtGui.QWidget.__init__(self)
87 self.plugin = plugin
88 self._labels = {}
89 self.setLayout(QtGui.QGridLayout())
90 self.layout().setColumnStretch(1, 1)
92 def set_tagtypes(self, tagtypes):
93 """Setup labels for each tagtype in the list."""
94 # clear old data
95 for i in range(self.layout().rowCount()):
96 it = self.layout().itemAtPosition(i, 0)
97 it1 = self.layout().itemAtPosition(i, 1)
98 if it:
99 self.layout().removeItem(it)
100 it.widget().setParent(None)
101 if it1:
102 self.layout().removeItem(it1)
103 it1.widget().setParent(None)
104 self._labels = {}
106 for tag in tagtypes:
107 label = QtGui.QLabel('<b>%s</b>'%tag) #TODO sort known tags
108 label1 = QtGui.QLabel() # tag value will go here
109 label1.setTextInteractionFlags(QtCore.Qt.TextSelectableByMouse)
110 label.setWordWrap(True)
111 label1.setWordWrap(True)
112 self.layout().addWidget(label, len(self._labels), 0, QtCore.Qt.AlignRight)
113 self.layout().addWidget(label1, len(self._labels), 1)
114 self._labels[tag] = label1
116 def set_metadata(self, metadata):
117 """Set displayed metadata, which is provided in a dict of { tag : value }."""
118 for tag in metadata:
119 self._labels[tag].setText(metadata[tag])
121 def clear(self):
122 """ Clear displayed metadata. """
123 for label in self._labels.values():
124 label.clear()
126 class SettingsWidgetSonginfo(Plugin.SettingsWidget):
127 #### PRIVATE ####
128 _taglist = None
130 #### PUBLIC ####
131 def __init__(self, plugin):
132 Plugin.SettingsWidget.__init__(self, plugin)
133 self.settings.beginGroup(self.plugin.name)
135 self._taglist = QtGui.QListWidget(self)
136 self._taglist.setDragDropMode(QtGui.QAbstractItemView.InternalMove)
137 self._update_tags()
138 self.plugin.mpclient.connect_changed.connect(self._update_tags)
140 self.setLayout(QtGui.QVBoxLayout())
141 self._add_widget(self._taglist, label = 'Tags', tooltip = 'A list of tags that should be displayed.\n'
142 'Use drag and drop to change their order')
144 def save_settings(self):
145 if not self._taglist.isEnabled():
146 return
148 tags = []
149 for i in range(self._taglist.count()):
150 it = self._taglist.item(i)
151 if it.checkState() == QtCore.Qt.Checked:
152 tags.append(it.text())
153 self.settings.setValue('tagtypes', tags)
155 self.plugin.update_tagtypes()
156 self.plugin.refresh()
158 #### PRIVATE ####
159 def _update_tags(self):
160 self._taglist.setEnabled(self.plugin.mpclient.is_connected())
161 if not self.plugin.mpclient.is_connected():
162 return
164 self._taglist.clear()
165 tags_enabled = self.settings.value('tagtypes')
166 tags = self.plugin.mpclient.tagtypes
167 for tag in [tag for tag in tags_enabled if tag in tags]:
168 it = QtGui.QListWidgetItem(tag)
169 it.setCheckState(QtCore.Qt.Checked)
170 self._taglist.addItem(it)
171 for tag in [tag for tag in tags if tag not in tags_enabled]:
172 it = QtGui.QListWidgetItem(tag)
173 it.setCheckState(QtCore.Qt.Unchecked)
174 self._taglist.addItem(it)