from PyQt4 import QtGui, QtCore, QtSvg from traceback import print_exc import time import copy from misc import * from clSettings import settings,mpdSettings from clMonty import monty import plugins from winConnect import winConnect from winSettings import winSettings import log class winMain(QtGui.QMainWindow): """The winMain class is mpc's main window, showing the playlists and control-interface""" docks=[] " menus" mConnect=None mDisconnect=None mLayout=None " connection window" wConnect=None wSettings=None def __init__(self, parent=None): QtGui.QWidget.__init__(self, parent) self.setWindowTitle("montypc - An MPD client") self.wConnect=winConnect() self.statusBar() # create a statusbar mBar=self.menuBar() # create a menubar # menu file m=mBar.addMenu("File") m.setTearOffEnabled(True) # connect self.mConnect=m.addAction('Connect ...', self.wConnect.monitor) self.mConnect.setIcon(QtGui.QIcon('gfx/connect.png')) # disconnect self.mDisconnect=m.addAction('Disconnect', monty.disconnect) self.mDisconnect.setIcon(QtGui.QIcon('gfx/disconnect.png')) # separator m.addSeparator() # quit m.addAction("Quit", self.quit).setIcon(QtGui.QIcon('gfx/gtk-quit.svg')) # menu options m=mBar.addMenu("Options") m.setTearOffEnabled(True) # settings m.addAction("Settings", self.showWinSettings).setIcon(QtGui.QIcon('gfx/gtk-preferences.svg')) # menu layout self.mLayout=mBar.addMenu("Layout") self.mLayout.setTearOffEnabled(True) newPlugins=False # are there new plugins? for k, entry in plugins.listPlugins().iteritems(): # load the plugin plugin=plugins.loadPlugin(entry[plugins.PLUGIN_CLASS], self) if plugin: newPlugins=newPlugins|(settings.get('%s.load'%(plugin.getName(True)), None)==None) if settings.get('%s.load'%(plugin.getName(True)), '1')=='1': # load new plugins by default plugin.load() else: newPlugins=True self.updateLayoutMenu() self.setDockOptions(QtGui.QMainWindow.AllowNestedDocks \ |QtGui.QMainWindow.AllowTabbedDocks \ |QtGui.QMainWindow.VerticalTabs) self.setDockNestingEnabled(True) size=settings.get('winMain.size', '800 600') try: w=int(size[0:size.find(' ')].strip()) h=int(size[size.find(' '):].strip()) except: w,h=800,600 self.resize(w,h) self.restoreLayout() " add event handlers" monty.addListener('onReady', self.onReady) monty.addListener('onConnect', self.onConnect) monty.addListener('onDisconnect', self.onDisconnect) monty.addListener('onUpdateDBStart', self.onUpdateDBStart) monty.addListener('onUpdateDBFinish', self.onUpdateDBFinish) self.enableAll(True) self.setWindowIcon(appIcon) # set icon in system tray self.wConnect.monitor() self.show() if newPlugins: self.showWinSettings() doEvents() def quit(self): # unload all plugins for entry in plugins.listPlugins().values(): p=entry[plugins.PLUGIN_INSTANCE] if p and p.isLoaded(): p.unload() QtCore.QCoreApplication.exit() def updateLayoutMenu(self): self.mLayout.clear() self.mLayout.addAction('Save layout', self.saveLayout) self.mLayout.addAction('Restore layout', self.restoreLayout) self.mLayout.addSeparator() # create checkable menu a=QtGui.QAction('Show titlebars', self) a.setCheckable(True) a.setChecked(settings.get('winMain.show.titlebars', '1')=='1') self.toggleTitleBars(a.isChecked()) self.connect(a, QtCore.SIGNAL('toggled(bool)'), self.toggleTitleBars) self.mLayout.addAction(a) self.mLayout.addSeparator() # can not use iterators, as that gives some creepy error 'bout c++ actions=self.createPopupMenu().actions() for i in xrange(len(actions)): self.mLayout.addAction(actions[i]) def toggleTitleBars(self, val): if val: settings.set('winMain.show.titlebars', '1') else: settings.set('winMain.show.titlebars', '0') for dock in self.docks: if val: dock.setTitleBarWidget(None) else: dock.setTitleBarWidget(QtGui.QWidget()) def addDock(self, dock): if dock: self.docks.append(dock) self.addDockWidget(QtCore.Qt.TopDockWidgetArea, dock) self.updateLayoutMenu() def removeDock(self, dock): if dock: self.docks.remove(dock) self.removeDockWidget(dock) self.updateLayoutMenu() mMenuVisible=None def createPopupMenu(self): ret=QtGui.QMenu('Test', self) if self.mMenuVisible==None: # create checkable menu a=QtGui.QAction('Menubar', self) a.setCheckable(True) a.setChecked(True) self.connect(a, QtCore.SIGNAL('toggled(bool)'), self.switchMenubar) self.mMenuVisible=a ret.addAction(self.mMenuVisible) ret.addSeparator() actions=QtGui.QMainWindow.createPopupMenu(self).actions() for i in xrange(len(actions)-1): ret.addAction(actions[i]) return ret def switchMenubar(self, val): self.menuBar().setVisible(val) def setStatus(self, status): """Set the text of the statusbar.""" self.statusBar().showMessage(status) log.extended(status) def saveLayout(self): f=open('layout', 'wb') f.write(self.saveState()) f.close() log.normal("Layout saved") def restoreLayout(self): try: f=open('layout', 'rb') self.restoreState(f.read()) f.close() except: pass def showWinSettings(self): if not self.wSettings: self.wSettings=winSettings(self) self.wSettings.show() self.wSettings.raise_() def onReady(self, params): self.initialiseData() def onConnect(self, params): log.normal("Connected to MPD") self.setStatus('Restoring library and playlist ...') self.mDisconnect.setEnabled(True) self.mConnect.setEnabled(False) doEvents() def enableAll(self, value): for k,entry in plugins.listPlugins().iteritems(): try: plugin=entry[plugins.PLUGIN_INSTANCE] plugin.o.setEnabled(value) except: pass def initialiseData(self): """Initialise the library, playlist and some other small things""" self.setStatus("Filling library ...") doEvents() self.fillLibrary() doEvents() self.setStatus("Filling playlist ...") doEvents() self.fillPlaylist() doEvents() self.setStatus("Doing the rest ...") doEvents() self.enableAll(True) self.setStatus("") doEvents() def resizeEvent(self, event): settings.set('winMain.size', '%i %i'%(self.width(),self.height())) def onDisconnect(self, params): log.normal("Disconnected from MPD") try: self.getPlaylistList().updateSongs([]) except: pass try: self.getLibraryList().updateSongs([]) except: pass self.mDisconnect.setEnabled(False) self.mConnect.setEnabled(True) self.enableAll(False) self.setStatus("You are disconnected. Choose File->Connect to reconnect!") def fillPlaylist(self): """Fill the playlist.""" try: self.getPlaylistList().updateSongs(monty.listPlaylist()) except: pass def fillLibrary(self): """Fill the library.""" try: self.getLibraryList().updateSongs(monty.listLibrary()) except: pass def getPlaylistList(self): try: return plugins.getPlugin('Playlist').getList() except: print "Missing playlist plugin!" return None def getLibraryList(self): try: return plugins.getPlugin('Library').getList() except: print "Missing library plugin!" return None def onUpdateDBFinish(self, params): self.setStatus('') def onUpdateDBStart(self, params): self.setStatus('Updating the database. Please wait ...')