from PyQt4 import QtGui, QtCore, QtSvg from traceback import print_exc import time import sys import copy from misc import * from clSettings import settings,mpdSettings from clMonty import monty #from plugins import * import plugins from winConnect import winConnect from winSettings import winSettings from wgSongList import SongList from wgPlaylist import Playlist class winMain(QtGui.QMainWindow): """The winMain class is mpc's main window, showing the playlists and control-interface""" " list of plugins that are loaded. name=>Plugin" plugins={} docks=[] " menus" mConnect=None mDisconnect=None mLayout=None " connection window" wConnect=None wSettings=None "Other vars" " all objects which should be disabled when there is no connection" plugins=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", QtCore.QCoreApplication.exit).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) self.plugins={} newPlugins=False # are there new plugins? for p in plugins.listPlugins(): pkg,name=p[0],p[1] # WARNING - dirty hack ahead! plugin=eval('%s.%s'%(pkg,name))(self) newPlugins=newPlugins|(settings.get('%s.load'%(plugin.getName(True)), None)==None) self.plugins[plugin.getName().lower()]=plugin if settings.get('%s.load'%(plugin.getName(True)), '1')=='1': # load new plugins by default plugin.load() 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 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 getPlugin(self, name): try: return self.plugins[name.lower()] except: return None 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) def saveLayout(self): f=open('layout', 'wb') f.write(self.saveState()) f.close() 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): self.setStatus('Restoring library and playlist ...') self.mDisconnect.setEnabled(True) self.mConnect.setEnabled(False) doEvents() def enableAll(self, value): for o in self.plugins: try: self.plugins[o].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): # store new size settings.set('winMain.size', '%i %i'%(self.width(),self.height())) def onDisconnect(self, params): try: self.getPlaylistList().update([]) except: pass try: self.getLibraryList().update([]) 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().update(monty.listPlaylist()) except: pass def fillLibrary(self): """Fill the library.""" try: self.getLibraryList().update(monty.listLibrary()) except: pass def getPlaylistList(self): try: return self.plugins['playlist'].getList() except: print "Missing playlist plugin!" return None def getLibraryList(self): try: return self.plugins['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 ...')