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 pyqtSlot
as Slot
23 from common
import APPNAME
, sec2min
, appIcon
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"""
45 def __init__(self
, mpclient
):
46 QtGui
.QMainWindow
.__init
__(self
)
47 self
.settings
= QtCore
.QSettings()
48 self
.mpclient
= mpclient
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
)
58 self
.mpclient
.time_changed
.connect(self
.__on
_time
_change
)
60 self
.statusBar().addWidget(self
.__statuslabel
)
61 self
.statusBar().addPermanentWidget(self
.__time
_label
)
62 self
.statusBar().addPermanentWidget(self
.__time
_slider
)
64 mBar
= QtGui
.QMenuBar() # create a menubar
66 m
= mBar
.addMenu("File")
68 self
.mConnect
=m
.addAction('Connect ...', QtGui
.QApplication
.instance().show_connect_win
)
69 self
.mConnect
.setIcon(QtGui
.QIcon(appIcon
))
71 self
.mDisconnect
=m
.addAction('Disconnect', self
.mpclient
.disconnect_mpd
)
72 self
.mDisconnect
.setIcon(QtGui
.QIcon(':icons/disconnect.png'))
76 m
.addAction("Quit", QtGui
.QApplication
.instance().quit
).setIcon(QtGui
.QIcon(':icons/gtk-quit.svg'))
79 m
=mBar
.addMenu("Options")
81 m
.addAction("Settings", QtGui
.QApplication
.instance().show_settings_win
).setIcon(QtGui
.QIcon(':icons/gtk-preferences.svg'))
84 self
.__layout
_menu
=mBar
.addMenu("Layout")
86 # create a toolbar for the main menu
87 menu_toolbar
= QtGui
.QToolBar('Main menu', self
)
88 menu_toolbar
.addWidget(mBar
)
89 self
.addToolBar(QtCore
.Qt
.TopToolBarArea
, menu_toolbar
)
91 self
.__update
_layout
_menu
()
92 self
.setDockOptions(QtGui
.QMainWindow
.AllowNestedDocks \
93 |QtGui
.QMainWindow
.AllowTabbedDocks \
94 |QtGui
.QMainWindow
.VerticalTabs
)
95 self
.setDockNestingEnabled(True)
96 self
.restoreGeometry(self
.settings
.value('geometry'))
99 self
.mpclient
.connect_changed
.connect(self
.__on
_connect
_changed
)
100 self
.mpclient
.song_changed
.connect(self
.__on
_song
_change
)
101 self
.mpclient
.state_changed
.connect(self
.__update
_state
_messages
)
103 self
.__update
_state
_messages
()
107 self
.settings
.setValue('geometry', 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
)
117 a
.setChecked(int(self
.settings
.value('show_titlebars', 1)))
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()
125 for action
in m
.actions():
126 self
.__layout
_menu
.addAction(action
)
128 def __toggle_titlebars(self
, val
):
130 self
.settings
.setValue('show_titlebars', 1)
132 self
.settings
.setValue('show_titlebars', 0)
133 for dock
in self
.__docks
:
135 dock
.setTitleBarWidget(None)
137 dock
.setTitleBarWidget(QtGui
.QWidget())
138 def add_dock(self
, dock
):
140 self
.__docks
.append(dock
)
141 self
.addDockWidget(QtCore
.Qt
.TopDockWidgetArea
, dock
)
142 self
.__update
_layout
_menu
()
143 def remove_dock(self
, 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', self
.saveState())
152 def restore_layout(self
):
153 layout
= self
.settings
.value('layout')
155 layout
= QtCore
.QFile(':default_layout').readAll()
156 self
.restoreState(layout
)
159 def __on_connect_changed(self
, val
):
161 self
.mDisconnect
.setEnabled(True)
162 self
.mConnect
.setEnabled(False)
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
.cur_song
170 state
= self
.mpclient
.status
['state']
171 state
= 'playing' if state
== 'play' else 'paused' if state
== 'pause' else 'stopped'
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
))
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
['time'][1])
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
):
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'][0])
205 def _update_text(self
, time
):
206 self
.setText('%s/%s'%(sec2min(time
), sec2min(self
._mpclient
.status
['time'][1])))