song: make keys case-insensitive
[nephilim.git] / nephilim / winMain.py
blobc8ae92a45ea20a7d49e3bb1a996fba34ae4de6d2
2 # Copyright (C) 2008 jerous <jerous@gmail.com>
3 # Copyright (C) 2009 Anton Khirnov <wyskas@gmail.com>
5 # Nephilim is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation, either version 3 of the License, or
8 # (at your option) any later version.
10 # Nephilim is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with Nephilim. If not, see <http://www.gnu.org/licenses/>.
19 from PyQt4 import QtGui, QtCore
20 from PyQt4.QtCore import QVariant, pyqtSlot as Slot
21 import logging
23 from common import APPNAME, sec2min, appIcon
24 import icons
25 import data
27 DEFAULT_LAYOUT_FILE = 'nephilim/default_layout'
29 class winMain(QtGui.QMainWindow):
30 """The winMain class is mpc's main window, showing the playlists and control-interface"""
31 mpclient = None
32 settings = None
33 " menus"
34 mConnect = None
35 mDisconnect = None
36 __layout_menu = None
38 # Statusbar objects
39 __statuslabel = None
40 __time_slider = None
41 __time_label = None
43 __docks = []
45 def __init__(self, mpclient):
46 QtGui.QMainWindow.__init__(self)
47 self.settings = QtCore.QSettings()
48 self.mpclient = mpclient
51 # statusbar
52 self.statusBar()
53 self.__statuslabel = QtGui.QLabel()
54 self.__time_slider = QtGui.QSlider(QtCore.Qt.Horizontal, self)
55 self.__time_slider.setMaximumWidth(self.width()/4)
56 self.__time_slider.sliderReleased.connect( self.__on___time_slider_change)
57 self.__time_label = TimeLabel(self, mpclient)
59 self.statusBar().addWidget(self.__statuslabel)
60 self.statusBar().addPermanentWidget(self.__time_label)
61 self.statusBar().addPermanentWidget(self.__time_slider)
63 mBar = QtGui.QMenuBar() # create a menubar
64 # File menu
65 m = mBar.addMenu("File")
66 # connect
67 self.mConnect=m.addAction('Connect ...', QtGui.QApplication.instance().show_connect_win)
68 self.mConnect.setIcon(QtGui.QIcon(appIcon))
69 # disconnect
70 self.mDisconnect=m.addAction('Disconnect', self.mpclient.disconnect_mpd)
71 self.mDisconnect.setIcon(QtGui.QIcon(':icons/disconnect.png'))
72 # separator
73 m.addSeparator()
74 # quit
75 m.addAction("Quit", QtGui.QApplication.instance().quit).setIcon(QtGui.QIcon(':icons/gtk-quit.svg'))
77 # menu options
78 m=mBar.addMenu("Options")
79 # settings
80 m.addAction("Settings", QtGui.QApplication.instance().show_settings_win).setIcon(QtGui.QIcon(':icons/gtk-preferences.svg'))
82 # menu layout
83 self.__layout_menu=mBar.addMenu("Layout")
85 # create a toolbar for the main menu
86 menu_toolbar = QtGui.QToolBar('Main menu', self)
87 menu_toolbar.addWidget(mBar)
88 self.addToolBar(QtCore.Qt.TopToolBarArea, menu_toolbar)
90 self.__update_layout_menu()
91 self.setDockOptions(QtGui.QMainWindow.AllowNestedDocks \
92 |QtGui.QMainWindow.AllowTabbedDocks \
93 |QtGui.QMainWindow.VerticalTabs)
94 self.setDockNestingEnabled(True)
95 self.restoreGeometry(self.settings.value('geometry').toByteArray())
97 " add event handlers"
98 self.mpclient.connect_changed.connect(self.__on_connect_changed)
99 self.mpclient.song_changed.connect(self.__on_song_change)
100 self.mpclient.state_changed.connect(self.__update_state_messages)
101 self.mpclient.time_changed.connect(self.__on_time_change)
103 self.__update_state_messages()
104 self.show()
106 def on_quit(self):
107 self.settings.setValue('geometry', QVariant(self.saveGeometry()))
109 def __update_layout_menu(self):
110 self.__layout_menu.clear()
111 self.__layout_menu.addAction('Save layout', self.save_layout)
112 self.__layout_menu.addAction('Restore layout', self.restore_layout)
113 self.__layout_menu.addSeparator()
114 # create checkable menu
115 a = QtGui.QAction('Show titlebars', self)
116 a.setCheckable(True)
117 a.setChecked(self.settings.value('show_titlebars', QVariant(True)).toBool())
118 self.__toggle_titlebars(a.isChecked())
119 a.toggled.connect(self.__toggle_titlebars)
120 self.__layout_menu.addAction(a)
121 self.__layout_menu.addSeparator()
123 m = self.createPopupMenu()
124 if m:
125 for action in m.actions():
126 self.__layout_menu.addAction(action)
128 def __toggle_titlebars(self, val):
129 if val:
130 self.settings.setValue('show_titlebars', QVariant(True))
131 else:
132 self.settings.setValue('show_titlebars', QVariant(False))
133 for dock in self.__docks:
134 if val:
135 dock.setTitleBarWidget(None)
136 else:
137 dock.setTitleBarWidget(QtGui.QWidget())
138 def add_dock(self, dock):
139 if dock:
140 self.__docks.append(dock)
141 self.addDockWidget(QtCore.Qt.TopDockWidgetArea, dock)
142 self.__update_layout_menu()
143 def remove_dock(self, dock):
144 if dock:
145 self.removeDockWidget(dock)
146 if dock in self.__docks:
147 self.__docks.remove(dock)
148 self.__update_layout_menu()
150 def save_layout(self):
151 self.settings.setValue('layout', QVariant(self.saveState()))
152 def restore_layout(self):
153 layout = self.settings.value('layout').toByteArray()
154 if not layout:
155 layout = QtCore.QFile(':default_layout').readAll()
156 self.restoreState(layout)
159 def __on_connect_changed(self, val):
160 if val:
161 self.mDisconnect.setEnabled(True)
162 self.mConnect.setEnabled(False)
163 else:
164 self.mDisconnect.setEnabled(False)
165 self.mConnect.setEnabled(True)
167 def __update_state_messages(self):
168 """Update window title and statusbar"""
169 song = self.mpclient.current_song()
170 state = self.mpclient.status()['state']
171 state = 'playing' if state == 'play' else 'paused' if state == 'pause' else 'stopped'
172 if song:
173 self.setWindowTitle('%s by %s - %s [%s]'%(song['?title'], song['?artist'], APPNAME, state))
174 self.__statuslabel.setText('%s by %s on %s [%s]'%(song['?title'], song['?artist'],song['?album'], state))
175 else:
176 self.setWindowTitle(APPNAME)
177 self.__statuslabel.setText('')
179 def __on___time_slider_change(self):
180 self.mpclient.seek(self.__time_slider.value())
182 def __on_song_change(self):
183 status = self.mpclient.status()
184 self.__time_slider.setMaximum(status['length'])
185 self.__time_slider.setEnabled(True)
186 self.__update_state_messages()
188 def __on_time_change(self, new_time):
189 if not self.__time_slider.isSliderDown():
190 self.__time_slider.setValue(new_time)
192 class TimeLabel(QtGui.QLabel):
194 _mpclient = None
196 def __init__(self, parent, mpclient):
197 QtGui.QLabel.__init__(self, parent)
199 self._mpclient = mpclient
201 self._mpclient.time_changed.connect(self._update_text)
202 self._update_text(self._mpclient.status()['time'])
204 @Slot(int)
205 def _update_text(self, time):
206 self.setText('%s/%s'%(sec2min(time), sec2min(self._mpclient.status()['length'])))