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
23 from misc
import APPNAME
, sec2min
, appIcon
25 DEFAULT_LAYOUT_FILE
= 'default_layout'
27 class winMain(QtGui
.QMainWindow
):
28 """The winMain class is mpc's main window, showing the playlists and control-interface"""
43 def __init__(self
, mpclient
):
44 QtGui
.QWidget
.__init
__(self
)
45 self
.settings
= QtCore
.QSettings()
46 self
.mpclient
= mpclient
51 self
.__statuslabel
= QtGui
.QLabel()
52 self
.__time
_slider
= QtGui
.QSlider(QtCore
.Qt
.Horizontal
, self
)
53 self
.__time
_slider
.setMaximumWidth(self
.width()/4)
54 self
.connect(self
.__time
_slider
, QtCore
.SIGNAL('sliderReleased()'), self
.__on
___time
_slider
_change
)
55 self
.__time
_label
= QtGui
.QLabel()
56 self
.__time
_label
.duration
= '0:00'
58 self
.statusBar().addWidget(self
.__statuslabel
)
59 self
.statusBar().addPermanentWidget(self
.__time
_label
)
60 self
.statusBar().addPermanentWidget(self
.__time
_slider
)
62 mBar
= QtGui
.QMenuBar() # create a menubar
64 m
= mBar
.addMenu("File")
65 m
.setTearOffEnabled(True)
67 self
.mConnect
=m
.addAction('Connect ...', QtGui
.QApplication
.instance().show_connect_win
)
68 self
.mConnect
.setIcon(QtGui
.QIcon(appIcon
))
70 self
.mDisconnect
=m
.addAction('Disconnect', self
.mpclient
.disconnect_mpd
)
71 self
.mDisconnect
.setIcon(QtGui
.QIcon('gfx/disconnect.png'))
75 m
.addAction("Quit", QtGui
.QApplication
.instance().quit
).setIcon(QtGui
.QIcon('gfx/gtk-quit.svg'))
78 m
=mBar
.addMenu("Options")
79 m
.setTearOffEnabled(True)
81 m
.addAction("Settings", QtGui
.QApplication
.instance().show_settings_win
).setIcon(QtGui
.QIcon('gfx/gtk-preferences.svg'))
84 self
.__layout
_menu
=mBar
.addMenu("Layout")
85 self
.__layout
_menu
.setTearOffEnabled(True)
87 # create a toolbar for the main menu
88 menu_toolbar
= QtGui
.QToolBar('Main menu', self
)
89 menu_toolbar
.addWidget(mBar
)
90 self
.addToolBar(QtCore
.Qt
.TopToolBarArea
, menu_toolbar
)
92 self
.__update
_layout
_menu
()
93 self
.setDockOptions(QtGui
.QMainWindow
.AllowNestedDocks \
94 |QtGui
.QMainWindow
.AllowTabbedDocks \
95 |QtGui
.QMainWindow
.VerticalTabs
)
96 self
.setDockNestingEnabled(True)
97 self
.restoreGeometry(self
.settings
.value('geometry').toByteArray())
100 self
.connect(self
.mpclient
, QtCore
.SIGNAL('connect_changed'), self
.__on
_connect
_changed
)
101 self
.connect(self
.mpclient
, QtCore
.SIGNAL('song_changed'), self
.__on
_song
_change
)
102 self
.connect(self
.mpclient
, QtCore
.SIGNAL('state_changed'), self
.__update
_state
_messages
)
103 self
.connect(self
.mpclient
, QtCore
.SIGNAL('time_changed'), self
.__on
_time
_change
)
105 self
.__update
_state
_messages
()
109 self
.settings
.setValue('geometry', QVariant(self
.saveGeometry()))
111 def __update_layout_menu(self
):
112 self
.__layout
_menu
.clear()
113 self
.__layout
_menu
.addAction('Save layout', self
.save_layout
)
114 self
.__layout
_menu
.addAction('Restore layout', self
.restore_layout
)
115 self
.__layout
_menu
.addSeparator()
116 # create checkable menu
117 a
= QtGui
.QAction('Show titlebars', self
)
119 a
.setChecked(self
.settings
.value('show_titlebars', QVariant(True)).toBool())
120 self
.__toggle
_titlebars
(a
.isChecked())
121 self
.connect(a
, QtCore
.SIGNAL('toggled(bool)'), self
.__toggle
_titlebars
)
122 self
.__layout
_menu
.addAction(a
)
123 self
.__layout
_menu
.addSeparator()
125 m
= self
.createPopupMenu()
127 for action
in m
.actions():
128 self
.__layout
_menu
.addAction(action
)
130 def __toggle_titlebars(self
, val
):
132 self
.settings
.setValue('show_titlebars', QVariant(True))
134 self
.settings
.setValue('show_titlebars', QVariant(False))
135 for dock
in self
.__docks
:
137 dock
.setTitleBarWidget(None)
139 dock
.setTitleBarWidget(QtGui
.QWidget())
140 def add_dock(self
, dock
):
142 self
.__docks
.append(dock
)
143 self
.addDockWidget(QtCore
.Qt
.TopDockWidgetArea
, dock
)
144 self
.__update
_layout
_menu
()
145 def remove_dock(self
, dock
):
147 if dock
in self
.__docks
:
148 self
.__docks
.remove(dock
)
149 self
.removeDockWidget(dock
)
150 self
.__update
_layout
_menu
()
152 def setStatus(self
, status
):
153 """Set the text of the statusbar."""
154 self
.statusBar().showMessage(status
, 5000)
157 def save_layout(self
):
158 self
.settings
.setValue('layout', QVariant(self
.saveState()))
159 def restore_layout(self
):
160 layout
= self
.settings
.value('layout').toByteArray()
163 layout
= open(DEFAULT_LAYOUT_FILE
, 'rb').read()
165 logging
.error("Error reading default layout.")
167 self
.restoreState(layout
)
170 def __on_connect_changed(self
, val
):
172 self
.mDisconnect
.setEnabled(True)
173 self
.mConnect
.setEnabled(False)
175 self
.mDisconnect
.setEnabled(False)
176 self
.mConnect
.setEnabled(True)
178 def __update_state_messages(self
):
179 """Update window title and statusbar"""
180 song
= self
.mpclient
.current_song()
181 state
= self
.mpclient
.status()['state']
182 state
= 'playing' if state
== 'play' else 'paused' if state
== 'pause' else 'stopped'
184 self
.setWindowTitle('%s by %s - %s [%s]'%(song
.title(), song
.artist(), APPNAME
, state
))
185 self
.__statuslabel
.setText('%s by %s on %s [%s]'%(song
.title(), song
.artist(),song
.album(), state
))
187 self
.setWindowTitle(APPNAME
)
188 self
.__statuslabel
.setText('')
190 def __on___time_slider_change(self
):
191 self
.mpclient
.seek(self
.__time
_slider
.value())
193 def __on_song_change(self
):
194 status
= self
.mpclient
.status()
195 self
.__time
_slider
.setMaximum(status
['length'])
196 self
.__time
_slider
.setEnabled(True)
197 self
.__time
_label
.duration
= sec2min(status
['length'])
198 self
.__update
_state
_messages
()
200 def __on_time_change(self
, new_time
):
201 if not self
.__time
_slider
.isSliderDown():
202 self
.__time
_slider
.setValue(new_time
)
203 self
.__time
_label
.setText(sec2min(new_time
) + '/' + self
.__time
_label
.duration
)