From ffb97dfaeb19f9db1c14bef8a92d9ce83adb13fb Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Fri, 28 Aug 2009 10:38:30 +0200 Subject: mpclient: encapsulate audio outputs in a class. --- nephilim/mpclient.py | 79 ++++++++++++++++++++++++++++++++++++++++--------- nephilim/settings_wg.py | 30 +++++++------------ 2 files changed, 75 insertions(+), 34 deletions(-) diff --git a/nephilim/mpclient.py b/nephilim/mpclient.py index fa5fd3c..73dc44a 100644 --- a/nephilim/mpclient.py +++ b/nephilim/mpclient.py @@ -25,6 +25,11 @@ from song import Song, SongRef, PlaylistEntryRef class MPClient(QtCore.QObject): """This class offers another layer above pympd, with usefull events.""" + # public, read-only + "a list of audio outputs" + outputs = None + + # private _client = None _cur_song = None _status = {'volume' : 0, 'repeat' : 0, 'random' : 0, @@ -55,8 +60,40 @@ class MPClient(QtCore.QObject): consume_changed = QtCore.pyqtSignal(bool) playlist_changed = QtCore.pyqtSignal() + class Output(QtCore.QObject): + """This class represents an MPD audio output.""" + # public, const + mpclient = None + name = None + id = None + state = None + + # SIGNALS + state_changed = QtCore.pyqtSignal(bool) + + #### public #### + def __init__(self, mpclient, name, id, state): + QtCore.QObject.__init__(self, mpclient) + + self.mpclient = mpclient + self.name = name + self.id = id + self.state = state + + @QtCore.pyqtSlot(bool) + def set_state(self, state): + self.mpclient.set_output(self.id, state) + + #### private #### + def mpd_toggle_state(self): + """This is called by mpclient to inform about output state change.""" + self.state = not self.state + self.state_changed.emit(self.state) + def __init__(self): QtCore.QObject.__init__(self) + + self.outputs = [] self._commands = [] self._status = dict(MPClient._status) self.logger = logging.getLogger('mpclient') @@ -88,6 +125,7 @@ class MPClient(QtCore.QObject): return self.disconnect_mpd() self.__update_current_song() + self.__update_outputs() self._db_update = self.stats()['db_update'] self.emit(QtCore.SIGNAL('connected')) #should be removed @@ -118,6 +156,7 @@ class MPClient(QtCore.QObject): self._status = dict(MPClient._status) self._cur_song = None self._commands = [] + self.outputs = [] self.emit(QtCore.SIGNAL('disconnected')) #should be removed self.connect_changed.emit(False) self.logger.info('Disconnected from MPD.') @@ -178,20 +217,6 @@ class MPClient(QtCore.QObject): self._client.update(path) self._client.command_list_end() - def outputs(self): - """Returns an array of configured MPD audio outputs.""" - if self._client: - return self._retrieve(self._client.outputs) - else: - return [] - def set_output(self, output_id, state): - """Set audio output output_id to state (0/1).""" - if not self.__check_command_ok('enableoutput'): - return - if state: - self._client.enableoutput(output_id) - else: - self._client.disableoutput(output_id) def volume(self): """Get current volume.""" @@ -354,6 +379,7 @@ class MPClient(QtCore.QObject): i += 1 self._client.command_list_end() + #### private #### def _retrieve(self, method): """Makes sure only one call is made at a time to MPD.""" self._retr_mutex.lock() @@ -410,6 +436,25 @@ class MPClient(QtCore.QObject): return self.logger.error('Command %s not accessible'%cmd) return True + def __update_outputs(self): + """Update the list of MPD audio outputs.""" + if self.__check_command_ok('outputs'): + outputs = [] + for output in self._retrieve(self._client.outputs): + outputs.append(MPClient.Output(self, output['outputname'], output['outputid'], + bool(output['outputenabled']))) + self.outputs = outputs + else: + self.outputs = [] + def set_output(self, output_id, state): + """Set audio output output_id to state (0/1).""" + if not self.__check_command_ok('enableoutput'): + return + if state: + self._client.enableoutput(output_id) + else: + self._client.disableoutput(output_id) + def timerEvent(self, event): """Check for changes since last check.""" if event.timerId() == self._db_timer_id: @@ -456,3 +501,9 @@ class MPClient(QtCore.QObject): if self._status['playlist'] != old_status['playlist']: self.playlist_changed.emit() + + outputs = self._retrieve(self._client.outputs) + for i in range(len(outputs)): + if int(outputs[i]['outputenabled']) != int(self.outputs[i].state): + self.outputs[i].mpd_toggle_state() + diff --git a/nephilim/settings_wg.py b/nephilim/settings_wg.py index 145114a..f1c07d1 100644 --- a/nephilim/settings_wg.py +++ b/nephilim/settings_wg.py @@ -41,7 +41,6 @@ class SettingsWidget(QtGui.QWidget): pass_txt = None lib_txt = None update = None - outputs = None xfade = None def __init__(self, mpclient): @@ -59,27 +58,18 @@ class SettingsWidget(QtGui.QWidget): self.update = QtGui.QPushButton('Update MPD database') self.update.clicked.connect(self.update_db) - self.outputs = QtGui.QGroupBox('Audio outputs') - self.outputs.setLayout(QtGui.QVBoxLayout()) - class Output(QtGui.QCheckBox): - id = None - mpclient = None - def __init__(self, text, mpclient, id): - QtGui.QCheckBox.__init__(self, text) - self.mpclient = mpclient - self.id = id - self.stateChanged.connect(self.change_state) - - def change_state(self, state): - self.mpclient.set_output(self.id, state) - - for output in self.mpclient.outputs(): - box = Output(output['outputname'], self.mpclient, output['outputid']) - if output['outputenabled'] == '1': + outputs = QtGui.QGroupBox('Audio outputs') + outputs.setLayout(QtGui.QVBoxLayout()) + + for output in self.mpclient.outputs: + box = QtGui.QCheckBox(output.name, self) + if output.state: box.setChecked(True) else: box.setChecked(False) - self.outputs.layout().addWidget(box) + box.clicked.connect(output.set_state) + output.state_changed.connect(box.setChecked) + outputs.layout().addWidget(box) self.xfade = QtGui.QSpinBox() self.xfade.setValue(int(self.mpclient.status()['xfade'])) @@ -91,7 +81,7 @@ class SettingsWidget(QtGui.QWidget): self._add_widget(self.pass_txt, 'Password', 'Password') self._add_widget(self.lib_txt, 'Music library', 'Path to music library') self.layout().addWidget(self.update) - self.layout().addWidget(self.outputs) + self.layout().addWidget(outputs) self._add_widget(self.xfade, 'Crossfade', 'Set crossfade between songs (in seconds).') def save_settings(self): -- cgit v1.2.3