Esempio n. 1
0
 def switchFavoritesView(self, tree):
     """ Show all/favorites """
     self.saveTreeState()
     self.showOnlyFavs = not self.showOnlyFavs
     prefs.set(__name__, 'show-only-favorites', self.showOnlyFavs)
     self.loadArtists(self.tree, self.currLib)
     self.restoreTreeState()
Esempio n. 2
0
def load(name):
    """ Load the given module, may raise LoadException """
    mModulesLock.acquire()
    module = mModules[name]
    mModulesLock.release()

    # Check dependencies
    unmetDeps = __checkDeps(module[MOD_INFO][MODINFO_DEPS])
    if len(unmetDeps) != 0:
        errMsg = _('The following Python modules are not available:')
        errMsg += '\n     * '
        errMsg += '\n     * '.join(unmetDeps)
        errMsg += '\n\n'
        errMsg += _('You must install them if you want to enable this module.')
        raise LoadException(errMsg)

    # Instantiate the module
    try:
        module[MOD_INSTANCE] = getattr(module[MOD_PMODULE],
                                       module[MOD_CLASSNAME])()
        module[MOD_INSTANCE].start()

        mHandlersLock.acquire()
        if module[MOD_INSTANCE] in mHandlers[consts.MSG_EVT_MOD_LOADED]:
            module[MOD_INSTANCE].postMsg(consts.MSG_EVT_MOD_LOADED)
        mHandlersLock.release()

        log.logger.info('Module loaded: %s' % module[MOD_CLASSNAME])
        mEnabledModules.append(name)
        prefs.set(__name__, 'enabled_modules', mEnabledModules)
    except:
        raise LoadException(traceback.format_exc())
Esempio n. 3
0
    def timerFunc(self):
        """ Move a bit the scales to their target value """
        isFinished = True

        # Disconnect handlers before moving the scales
        for i in xrange(10):
            self.scales[i].disconnect(self.handlers[i])

        # Move the scales a bit
        for i in xrange(10):
            currLvl    = self.scales[i].get_value()
            targetLvl  = self.targetLvls[i]
            difference = targetLvl - currLvl

            if abs(difference) <= 0.25:
                newLvl = targetLvl
            else:
                newLvl     = currLvl + (difference / 8.0)
                isFinished = False

            self.lvls[i] = newLvl
            self.scales[i].set_value(newLvl)

        # Reconnect the handlers
        for i in xrange(10):
            self.handlers[i] = self.scales[i].connect('value-changed', self.onScaleValueChanged, i)

        # Set the equalizer to the new levels
        prefs.set(__name__, 'levels', self.lvls)
        modules.postMsg(consts.MSG_CMD_SET_EQZ_LVLS, {'lvls': self.lvls})

        return not isFinished
Esempio n. 4
0
def load_enabled_modules():
    # Find modules, instantiate those that are mandatory or that have been previously enabled by the user
    sys.path.append(mModDir)
    for file in sorted(os.path.splitext(file)[0] for file in os.listdir(mModDir)
                       if file.endswith('.py') and file not in blacklist):
        try:
            pModule = __import__(file)
            modInfo = getattr(pModule, 'MOD_INFO')

            # Should it be instanciated?
            instance = None
            if modInfo[MODINFO_MANDATORY] or modInfo[MODINFO_NAME] in mEnabledModules:
                if len(__checkDeps(modInfo[MODINFO_DEPS])) == 0:
                    instance = getattr(pModule, file)()
                    instance.start()
                    log.logger.info('Module loaded: %s' % file)
                else:
                    log.logger.error('Unable to load module %s because of missing dependencies' % file)

            # Add it to the dictionary
            mModules[modInfo[MODINFO_NAME]] = [pModule, file, instance, modInfo]
        except:
            log.logger.error('Unable to load module %s\n\n%s' % (file, traceback.format_exc()))

    # Remove enabled modules that are no longer available
    mEnabledModules[:] = [module for module in mEnabledModules if module in mModules]
    prefs.set(__name__, 'enabled_modules', mEnabledModules)
def delayedStartup():
    """
        Perform all the initialization stuff that is not mandatory to display the window
        This function should be called within the GTK main loop, once the window has been displayed
    """
    import atexit, dbus.mainloop.glib, modules, signal

    def atExit():
        """ Final function, called just before exiting the Python interpreter """
        prefs.save()
        log.logger.info('Stopped')

    def onInterrupt(window):
        """ Handler for interrupt signals e.g., Ctrl-C """
        window.hide()
        modules.postQuitMsg()

    # D-Bus
    dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)

    # Register a few handlers
    atexit.register(atExit)
    signal.signal(signal.SIGINT,  lambda sig, frame: onInterrupt(window))
    signal.signal(signal.SIGTERM, lambda sig, frame: onInterrupt(window))

    # Now we can start all modules
    gobject.idle_add(modules.postMsg, consts.MSG_EVT_APP_STARTED)

    # Immediately show the preferences the first time the application is started
    if prefs.get(__name__, 'first-time', True):
        prefs.set(__name__, 'first-time', False)
        gobject.idle_add(modules.showPreferences)
Esempio n. 6
0
def load(name):
    """ Load the given module, may raise LoadException """
    mModulesLock.acquire()
    module = mModules[name]
    mModulesLock.release()

    # Check dependencies
    unmetDeps = __checkDeps(module[MOD_INFO][MODINFO_DEPS])
    if len(unmetDeps) != 0:
        errMsg  = _('The following Python modules are not available:')
        errMsg += '\n     * '
        errMsg += '\n     * '.join(unmetDeps)
        errMsg += '\n\n'
        errMsg += _('You must install them if you want to enable this module.')
        raise LoadException, errMsg

    # Instantiate the module
    try:
        module[MOD_INSTANCE] = getattr(module[MOD_PMODULE], module[MOD_CLASSNAME])()
        module[MOD_INSTANCE].start()

        mHandlersLock.acquire()
        if module[MOD_INSTANCE] in mHandlers[consts.MSG_EVT_MOD_LOADED]:
            module[MOD_INSTANCE].postMsg(consts.MSG_EVT_MOD_LOADED)
        mHandlersLock.release()

        log.logger.info('Module loaded: %s' % module[MOD_CLASSNAME])
        mEnabledModules.append(name)
        prefs.set(__name__, 'enabled_modules', mEnabledModules)
    except:
        raise LoadException, traceback.format_exc()
 def onModUnloaded(self):
     """ The module is being unloaded """
     prefs.set(__name__, 'was-paused', self.paused)
     prefs.set(__name__, 'was-playing', self.playing)
     prefs.set(__name__, 'position', self.currPos)
     prefs.set(__name__, 'track', self.currTrack)
     prefs.set(__name__, 'tracklist', self.currTracklist)
    def setViewMode(self, mode):
        """ Change the view mode to the given one """
        currMode = prefs.get(__name__, 'view-mode', DEFAULT_VIEW_MODE)

        # Give up if the new mode is the same as the current one
        if currMode == mode:
            return

        requestedSize = self.window.get_size()

        # First restore the initial window state (e.g., VIEW_MODE_FULL)
        if currMode == consts.VIEW_MODE_LEAN:       requestedSize = self.__fromModeLean(requestedSize)
        elif currMode == consts.VIEW_MODE_MINI:     requestedSize = self.__fromModeMini(requestedSize)
        elif currMode == consts.VIEW_MODE_NETBOOK:  requestedSize = self.__fromModeNetbook(requestedSize)
        elif currMode == consts.VIEW_MODE_PLAYLIST: requestedSize = self.__fromModePlaylist(requestedSize)

        # Now we can switch to the new mode
        if mode == consts.VIEW_MODE_LEAN:       requestedSize = self.__toModeLean(requestedSize)
        elif mode == consts.VIEW_MODE_MINI:     requestedSize = self.__toModeMini(requestedSize)
        elif mode == consts.VIEW_MODE_NETBOOK:  requestedSize = self.__toModeNetbook(requestedSize)
        elif mode == consts.VIEW_MODE_PLAYLIST: requestedSize = self.__toModePlaylist(requestedSize)

        # Do only one resize(), because intermediate get_size() don't return the correct size until the event queue has been processed by GTK
        self.window.resize(requestedSize[0], requestedSize[1])

        # Save the new mode
        prefs.set(__name__, 'view-mode', mode)
Esempio n. 9
0
    def timerFunc(self):
        """ Move a bit the scales to their target value """
        isFinished = True

        # Move the scales a bit
        for i in xrange(10):
            currLvl    = self.scales[i].get_value()
            targetLvl  = self.targetLvls[i]
            difference = targetLvl - currLvl

            if abs(difference) <= 0.25:
                newLvl = targetLvl
            else:
                newLvl     = currLvl + (difference / 8.0)
                isFinished = False

            self.lvls[i] = newLvl
            self.scales[i].set_value(newLvl)

        # Set the equalizer to the new levels
        modules.postMsg(consts.MSG_CMD_SET_EQZ_LVLS, {'lvls': self.lvls})

        if isFinished:
            self.timer = None
            prefs.set(__name__, 'levels', self.lvls)

            # Make sure labels are up to date (sometimes they aren't when we're done with the animation)
            # Also unblock the handlers
            for i in xrange(10):
                self.scales[i].queue_draw()
                self.scales[i].handler_unblock_by_func(self.onScaleValueChanged)

            return False

        return True
Esempio n. 10
0
    def handleMsg(self, msg, params):
        """ Handle messages sent to this module """
        if msg == consts.MSG_EVT_APP_STARTED or msg == consts.MSG_EVT_MOD_LOADED:
            self.onAppStarted()
            idle_add(self.addAllExplorers)

        elif msg == consts.MSG_EVT_EXPLORER_CHANGED and params['modName'] == MOD_L10N and params['expName'] != self.currLib:
            # Create the tree if needed
            if self.tree is None:
                self.__createTree()

            # Save the state of the current library
            if self.currLib is not None:
                self.treeState[self.currLib] = self.tree.saveState(ROW_NAME)

            # Switch to the new one
            self.currLib = params['expName']
            self.loadLibrary(self.tree, self.currLib)

            # Restore the state of the new library
            if len(self.tree) != 0 and self.currLib in self.treeState:
                self.tree.restoreState(self.treeState[self.currLib], ROW_NAME)

        elif msg == consts.MSG_EVT_APP_QUIT or msg == consts.MSG_EVT_MOD_UNLOADED:
            if self.currLib is not None:
                self.treeState[self.currLib] = self.tree.saveState(ROW_NAME)
                prefs.set(__name__, 'tree-state', self.treeState)

            prefs.set(__name__, 'libraries',  self.libraries)
            self.removeAllExplorers()
Esempio n. 11
0
    def onModUnloaded(self):
        """ The module has been unloaded """
        if self.currLib is not None:
            self.saveTreeState()
            self.saveFavorites(self.currLib, self.favorites)
            prefs.set(__name__, 'tree-states-2', self.treeStates)

        prefs.set(__name__, 'libraries',  self.libraries)
        self.removeAllExplorers()
Esempio n. 12
0
    def handleMsg(self, msg, params):
        """ Handle messages sent to this module """
        if msg == consts.MSG_EVT_EXPLORER_CHANGED and params['modName'] == MOD_L10N and self.currRoot != params['expName']:
            newRoot = params['expName']

            # Create the tree if needed (this is done only the very first time)
            if self.tree is None:
                columns = (('',   [(gtk.CellRendererPixbuf(), gtk.gdk.Pixbuf), (gtk.CellRendererText(), TYPE_STRING)], True),
                           (None, [(None, TYPE_INT)],                                                                  False),
                           (None, [(None, TYPE_STRING)],                                                               False))

                self.tree = extTreeview.ExtTreeView(columns, True)

                self.scrolled.add(self.tree)
                self.tree.setDNDSources([consts.DND_TARGETS[consts.DND_DAP_URI]])
                self.tree.connect('drag-data-get', self.onDragDataGet)
                self.tree.connect('key-press-event', self.onKeyPressed)
                self.tree.connect('exttreeview-button-pressed', self.onMouseButton)
                self.tree.connect('exttreeview-row-collapsed', self.onRowCollapsed)
                self.expandedHandler = self.tree.connect('exttreeview-row-expanded', self.onRowExpanded)

            savedStates = prefs.get(__name__, 'saved-states', {})

            # Save the current state if needed
            if self.currRoot is not None:
                savedStates[self.currRoot] = {
                                                'tree-state':     self.dumpTree(),
                                                'selected-paths': self.tree.getSelectedPaths(),
                                                'vscrollbar-pos': self.scrolled.get_vscrollbar().get_value(),
                                                'hscrollbar-pos': self.scrolled.get_hscrollbar().get_value(),
                                             }
                prefs.set(__name__, 'saved-states', savedStates)
                self.tree.clear()

            self.currRoot = newRoot

            if newRoot not in savedStates:
                self.exploreDir(None, self.folders[self.currRoot])
                if len(self.tree) != 0:
                    self.tree.scroll_to_cell(0)
            else:
                savedState = savedStates[newRoot]

                self.tree.disconnect(self.expandedHandler)
                self.restoreTree(savedState['tree-state'])
                self.expandedHandler  = self.tree.connect('exttreeview-row-expanded', self.onRowExpanded)

                idle_add(self.scrolled.get_vscrollbar().set_value, savedState['vscrollbar-pos'])
                idle_add(self.scrolled.get_hscrollbar().set_value, savedState['hscrollbar-pos'])
                idle_add(self.tree.selectPaths, savedState['selected-paths'])
                idle_add(self.refresh)

        elif msg == consts.MSG_EVT_APP_STARTED:
            self.onModLoaded()
        elif msg == consts.MSG_EVT_APP_QUIT:
            self.onModUnloaded()
Esempio n. 13
0
 def saveTreeState(self):
     """ Create a dictionary representing the current state of the tree """
     self.treeState = {
                 'tree-state':     self.getTreeDump(),
                 'selected-paths': self.tree.getSelectedPaths(),
                 'vscrollbar-pos': self.scrolled.get_vscrollbar().get_value(),
                 'hscrollbar-pos': self.scrolled.get_hscrollbar().get_value(),
                 }
     prefs.set(__name__, 'saved-states', self.treeState)
     self.music_paths = self.get_music_paths_from_tree()
Esempio n. 14
0
 def handleMsg(self, msg, params):
     """ Handle message sent to this module """
     if   msg == consts.MSG_EVT_TRACK_POSITION: self.onNewTrackPosition(params['seconds'])
     elif msg == consts.MSG_EVT_PAUSED:         self.onPaused()
     elif msg == consts.MSG_EVT_STOPPED:        self.onStopped()
     elif msg == consts.MSG_EVT_UNPAUSED:       self.onUnpaused()
     elif msg == consts.MSG_EVT_APP_QUIT:       prefs.set(__name__, 'volume', self.btnVolume.get_value())
     elif msg == consts.MSG_EVT_NEW_TRACK:      self.onNewTrack(params['track'])
     elif msg == consts.MSG_EVT_APP_STARTED:    self.onAppStarted()
     elif msg == consts.MSG_EVT_TRACK_MOVED:    self.onTrackMoved(params['hasPrevious'], params['hasNext'])
     elif msg == consts.MSG_EVT_NEW_TRACKLIST:  self.btnPlay.set_sensitive(len(params['tracks']) != 0)
     elif msg == consts.MSG_EVT_VOLUME_CHANGED: self.onVolumeChanged(params['value'])
Esempio n. 15
0
    def renameFolder(self, oldName, newName):
        """ Rename a folder """
        self.folders[newName] = self.folders[oldName]
        del self.folders[oldName]

        savedStates = prefs.get(__name__, 'saved-states', {})
        if oldName in savedStates:
            savedStates[newName] = savedStates[oldName]
            del savedStates[oldName]
            prefs.set(__name__, 'saved-states', savedStates)

        modules.postMsg(consts.MSG_CMD_EXPLORER_RENAME,   {'modName': MOD_L10N, 'expName': oldName, 'newExpName': newName})
Esempio n. 16
0
    def __init__(self, wtree, window):
        """ Constructor """
        self.wtree  = wtree
        self.paned  = wtree.get_object('pan-main')
        self.window = window

        # Enable the right radio menu button
        viewmode = prefs.get(__name__, 'view-mode', DEFAULT_VIEW_MODE)

        if viewmode == consts.VIEW_MODE_FULL:       self.wtree.get_object('menu-mode-full').set_active(True)
        elif viewmode == consts.VIEW_MODE_LEAN:     self.wtree.get_object('menu-mode-lean').set_active(True)
        elif viewmode == consts.VIEW_MODE_MINI:     self.wtree.get_object('menu-mode-mini').set_active(True)
        elif viewmode == consts.VIEW_MODE_NETBOOK:  self.wtree.get_object('menu-mode-netbook').set_active(True)
        elif viewmode == consts.VIEW_MODE_PLAYLIST: self.wtree.get_object('menu-mode-playlist').set_active(True)

        # Restore the size and the state of the window
        if prefs.get(__name__, 'win-is-maximized', DEFAULT_MAXIMIZED_STATE):
            self.window.maximize()

        savedWidth  = prefs.get(__name__, 'win-width', DEFAULT_WIN_WIDTH)
        savedHeight = prefs.get(__name__, 'win-height', DEFAULT_WIN_HEIGHT)
        savedPanPos = prefs.get(__name__, 'paned-pos', DEFAULT_PANED_POS)

        self.window.resize(savedWidth, savedHeight)
        self.paned.set_position(savedPanPos)
        self.window.show_all()

        # Restore the view mode
        # We set the mode to VIEW_MODE_FULL in the preferences because the window is currently in this mode (initial startup state)
        prefs.set(__name__, 'view-mode', consts.VIEW_MODE_FULL)
        self.setViewMode(viewmode)

        # Restore once again the size (may have been modified while restoring the view mode)
        self.window.resize(savedWidth, savedHeight)
        self.paned.set_position(savedPanPos)

        # Finally connect the event handlers
        self.window.connect('delete-event', self.onDelete)
        self.window.connect('size-allocate', self.onResize)
        self.window.connect('window-state-event', self.onState)

        self.wtree.get_object('menu-mode-mini').connect('activate', self.onViewMode, consts.VIEW_MODE_MINI)
        self.wtree.get_object('menu-mode-full').connect('activate', self.onViewMode, consts.VIEW_MODE_FULL)
        self.wtree.get_object('menu-mode-lean').connect('activate', self.onViewMode, consts.VIEW_MODE_LEAN)
        self.wtree.get_object('menu-mode-netbook').connect('activate', self.onViewMode, consts.VIEW_MODE_NETBOOK)
        self.wtree.get_object('menu-mode-playlist').connect('activate', self.onViewMode, consts.VIEW_MODE_PLAYLIST)

        self.wtree.get_object('menu-help').connect('activate', self.onHelp)
        self.wtree.get_object('menu-about').connect('activate', self.onAbout)
        self.wtree.get_object('menu-preferences').connect('activate', self.onShowPreferences)
        self.wtree.get_object('menu-quit').connect('activate', lambda item: self.onDelete(window, None))
        self.wtree.get_object('pan-main').connect('size-allocate', lambda win, rect: prefs.set(__name__, 'paned-pos', self.paned.get_position()))
Esempio n. 17
0
    def save_track_tree(self):
        # Save playing track
        if self.tree.hasMark():
            last_path = tuple(self.tree.mark.get_path())
        else:
            last_path = None
        prefs.set(__name__, 'last-played-track', last_path)

        dump = self.getTreeDump()
        logging.info('Saving playlist')
        pickleSave(self.savedPlaylist, dump)
        # tell gobject to keep saving the content in regular intervals
        return True
Esempio n. 18
0
    def onChanged(self, combo):
        """ A new explorer has been selected with the combo box """
        idx = combo.get_active()

        if idx == -1:
            self.notebook.set_current_page(0)
        elif self.store[idx][ROW_IS_HEADER]:
            combo.set_active(self.currExplorerIdx)
        else:
            self.currExplorerIdx = idx
            prefs.set(__name__, 'last-explorer', (self.store[idx][ROW_MODULE], self.store[idx][ROW_NAME]))
            modules.postMsg(consts.MSG_EVT_EXPLORER_CHANGED, {'modName': self.store[idx][ROW_MODULE], 'expName': self.store[idx][ROW_NAME]})
            self.notebook.set_current_page(self.store[idx][ROW_PAGE_NUM])
Esempio n. 19
0
    def save_track_tree(self):
        # Save playing track
        if self.tree.hasMark():
            last_path = self.tree.mark.get_path()
        else:
            last_path = None
        prefs.set(__name__, 'last-played-track', last_path)

        dump = self.getTreeDump()
        logging.info('Saving playlist')
        pickleSave(self.savedPlaylist, dump)
        # tell gobject to keep saving the content in regular intervals
        return True
Esempio n. 20
0
    def onBtnOk(self, btn):
        """ Save new preferences """
        # Skipping tracks
        newSkipTrack = self.cfgWin.getWidget('chk-skipTrack').get_active()
        oldSkipTrack = prefs.get(__name__, 'skip-track',
                                 PREFS_DEFAULT_SKIP_TRACK)
        prefs.set(__name__, 'skip-track', newSkipTrack)

        if oldSkipTrack != newSkipTrack and self.notif is not None:
            if newSkipTrack:
                self.notif.add_action('stop', _('Skip track'),
                                      self.onSkipTrack)
            else:
                self.notif.clear_actions()

        # Timeout
        newTimeout = int(self.cfgWin.getWidget('spn-duration').get_value())
        oldTimeout = prefs.get(__name__, 'timeout', PREFS_DEFAULT_TIMEOUT)

        prefs.set(__name__, 'timeout', newTimeout)

        if oldTimeout != newTimeout and self.notif is not None:
            self.notif.set_timeout(newTimeout * 1000)

        # Other preferences
        prefs.set(__name__, 'title',
                  self.cfgWin.getWidget('txt-title').get_text())
        (start,
         end) = self.cfgWin.getWidget('txt-body').get_buffer().get_bounds()
        prefs.set(
            __name__, 'body',
            self.cfgWin.getWidget('txt-body').get_buffer().get_text(
                start, end, False))
        self.cfgWin.hide()
    def onBtnOk(self, btn):
        """ Save new preferences """
        # Skipping tracks
        newSkipTrack = self.cfgWin.getWidget('chk-skipTrack').get_active()
        oldSkipTrack = prefs.get(__name__, 'skip-track', PREFS_DEFAULT_SKIP_TRACK)
        prefs.set(__name__, 'skip-track', newSkipTrack)

        if oldSkipTrack != newSkipTrack and self.notif is not None:
            if newSkipTrack: self.notif.add_action('stop', _('Skip track'), self.onSkipTrack)
            else:            self.notif.clear_actions()

        # Timeout
        newTimeout = int(self.cfgWin.getWidget('spn-duration').get_value())
        oldTimeout = prefs.get(__name__, 'timeout', PREFS_DEFAULT_TIMEOUT)

        prefs.set(__name__, 'timeout', newTimeout)

        if oldTimeout != newTimeout and self.notif is not None:
            self.notif.set_timeout(newTimeout * 1000)

        # Other preferences
        prefs.set(__name__, 'title', self.cfgWin.getWidget('txt-title').get_text())
        (start, end) = self.cfgWin.getWidget('txt-body').get_buffer().get_bounds()
        prefs.set(__name__, 'body', self.cfgWin.getWidget('txt-body').get_buffer().get_text(start, end))
        self.cfgWin.hide()
Esempio n. 22
0
 def onOk(self, btn):
     """ Save the new preferences """
     if not os.path.isdir(os.path.dirname(self.txtFile.get_text())):
         gui.errorMsgBox(
             self.cfgWindow,
             _("Invalid path"),
             _("The path to the selected file is not valid. Please choose an existing path."),
         )
         self.txtFile.grab_focus()
     else:
         prefs.set(__name__, "file", self.txtFile.get_text())
         (start, end) = self.txtStatus.get_buffer().get_bounds()
         prefs.set(__name__, "status", self.txtStatus.get_buffer().get_text(start, end))
         self.cfgWindow.hide()
Esempio n. 23
0
    def onRenameExplorer(self, modName, expName, newExpName):
        """ Rename the given explorer """
        if newExpName != expName:
            self.allExplorers[(modName, newExpName)] = self.allExplorers[(modName, expName)]
            del self.allExplorers[(modName, expName)]

            # If the explorer we're renaming is currently selected, we need to rename the row
            # Otherwise, fillComboBox() won't be able to keep it selected
            idx = self.combo.get_active()
            if idx != -1 and self.store[idx][ROW_MODULE] == modName and self.store[idx][ROW_NAME] == expName:
                self.store[idx][ROW_NAME] = newExpName
                prefs.set(__name__, 'last-explorer', (modName, newExpName))

            self.fillComboBox()
 def onAppQuit(self):
     """ The module is going to be unloaded """
     self.saveTreeState()
     prefs.set(__name__, 'saved-states',      self.treeState)
     prefs.set(__name__, 'media-folders',     self.folders)
     prefs.set(__name__, 'add-by-filename',   self.addByFilename)
     prefs.set(__name__, 'show-hidden-files', self.showHiddenFiles)
Esempio n. 25
0
 def onAppQuit(self):
     """ The module is going to be unloaded """
     self.saveTreeState()
     prefs.set(__name__, 'saved-states', self.treeState)
     prefs.set(__name__, 'media-folders', self.folders)
     prefs.set(__name__, 'add-by-filename', self.addByFilename)
     prefs.set(__name__, 'show-hidden-files', self.showHiddenFiles)
Esempio n. 26
0
    def onScaleValueChanged(self, scale, idx):
        """ The user has moved one of the scales """
        # Add a 'custom' entry to the presets if needed
        if self.preset is not None:
            self.preset = None
            prefs.set(__name__, 'preset', self.preset)
            self.combo.handler_block_by_func(self.onPresetChanged)
            self.comboStore.insert(0, (False, _('Custom'), None))
            self.comboStore.insert(1, (True, '', None))
            self.combo.set_active(0)
            self.combo.handler_unblock_by_func(self.onPresetChanged)

        self.lvls[idx] = scale.get_value()
        prefs.set(__name__, 'levels', self.lvls)
        modules.postMsg(consts.MSG_CMD_SET_EQZ_LVLS, {'lvls': self.lvls})
Esempio n. 27
0
    def onPresetChanged(self, combo):
        """ A preset has been selected """
        idx = combo.get_active()
        if idx != -1:
            iter = self.comboStore.get_iter(idx)
            preset = self.comboStore.get_value(iter, ROW_PRESET_NAME)
            self.jumpToTargetLvls(self.comboStore.get_value(iter, ROW_PRESET_VALUES))

            # Remove the 'Custom' entry if needed
            if self.preset is None:
                self.comboStore.remove(self.comboStore.get_iter((0, )))
                self.comboStore.remove(self.comboStore.get_iter((0, )))

            self.preset = preset
            prefs.set(__name__, 'preset', self.preset)
Esempio n. 28
0
    def onScaleValueChanged(self, scale, idx):
        """ The user has moved one of the scales """
        # Add a 'custom' entry to the presets if needed
        if self.preset is not None:
            self.preset = None
            prefs.set(__name__, 'preset', self.preset)
            self.combo.handler_block_by_func(self.onPresetChanged)
            self.comboStore.insert(0, (False, _('Custom'), None))
            self.comboStore.insert(1, (True,  '',          None))
            self.combo.set_active(0)
            self.combo.handler_unblock_by_func(self.onPresetChanged)

        self.lvls[idx] = scale.get_value()
        prefs.set(__name__, 'levels', self.lvls)
        modules.postMsg(consts.MSG_CMD_SET_EQZ_LVLS, {'lvls': self.lvls})
Esempio n. 29
0
    def onPresetChanged(self, combo):
        """ A preset has been selected """
        idx = combo.get_active()
        if idx != -1:
            iter = self.comboStore.get_iter(idx)
            preset = self.comboStore.get_value(iter, ROW_PRESET_NAME)
            self.jumpToTargetLvls(
                self.comboStore.get_value(iter, ROW_PRESET_VALUES))

            # Remove the 'Custom' entry if needed
            if self.preset is None:
                self.comboStore.remove(self.comboStore.get_iter((0, )))
                self.comboStore.remove(self.comboStore.get_iter((0, )))

            self.preset = preset
            prefs.set(__name__, 'preset', self.preset)
Esempio n. 30
0
    def onBtnOk(self, btn):
        """ The button 'Ok' has been pressed """
        self.enabled     = self.cfgWin.getWidget('chk-enabled').get_active()
        self.periodicity = int(self.cfgWin.getWidget('slider-periodicity').get_value())

        prefs.set(__name__, 'enabled', self.enabled)
        prefs.set(__name__, 'periodicity', self.periodicity)

        # Restart timer, periodicity may have changed
        if self.timer is not None:
            gobject.source_remove(self.timer)

            if self.enabled:
                self.timer = gobject.timeout_add_seconds(self.periodicity * 60, self.timerFunc)

        self.cfgWin.hide()
Esempio n. 31
0
def unload(name):
    """ Unload the given module """
    mModulesLock.acquire()
    module               = mModules[name]
    instance             = module[MOD_INSTANCE]
    module[MOD_INSTANCE] = None
    mModulesLock.release()

    if instance is not None:
        mHandlersLock.acquire()
        instance.postMsg(consts.MSG_EVT_MOD_UNLOADED)
        for handlers in [handler for handler in mHandlers.itervalues() if instance in handler]:
            handlers.remove(instance)
        mHandlersLock.release()

        mEnabledModules.remove(name)
        log.logger.info('Module unloaded: %s' % module[MOD_CLASSNAME])
        prefs.set(__name__, 'enabled_modules', mEnabledModules)
Esempio n. 32
0
    def onBtnOpen(self, btn):
        """ Load the levels from a file"""
        inFile = gui.fileChooser.openFile(self.cfgWindow, _('Load levels'))

        if inFile is not None:
            input = open(inFile, 'rt')
            lines = input.readlines()
            input.close()

            lvls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
            isInvalid = True

            if len(lines) == 10:
                isInvalid = False
                for i in range(10):
                    elts = lines[i].split()

                    try:
                        if len(elts) == 1:
                            lvls[i] = float(elts[0])
                            if lvls[i] >= -24 and lvls[i] <= 12:
                                continue
                    except:
                        pass

                    isInvalid = True
                    break

            if isInvalid:
                gui.errorMsgBox(self.cfgWindow, _('Could not load the file'),
                                _('The format of the file is incorrect.'))
            else:
                self.jumpToTargetLvls(lvls)

                # Add a 'custom' entry to the presets if needed
                if self.preset is not None:
                    self.preset = None
                    prefs.set(__name__, 'preset', self.preset)
                    self.combo.handler_block_by_func(self.onPresetChanged)
                    self.comboStore.insert(0, (False, _('Custom'), None))
                    self.comboStore.insert(1, (True, '', None))
                    self.combo.set_active(0)
                    self.combo.handler_unblock_by_func(self.onPresetChanged)
def setViewMode(mode, resize):
    """ Change the view mode to the given one """
    lastMode = prefs.get(__name__, 'view-mode', DEFAULT_VIEW_MODE)
    prefs.set(__name__, 'view-mode', mode)

    (winWidth, winHeight) = window.get_size()

    if mode == consts.VIEW_MODE_FULL:
        paned.get_child1().show()
        wTree.get_widget('statusbar').show()
        wTree.get_widget('box-btn-tracklist').show()
        wTree.get_widget('scrolled-tracklist').show()
        wTree.get_widget('box-trkinfo').show()
        if resize:
            if lastMode != consts.VIEW_MODE_FULL: winWidth  = winWidth + paned.get_position()
            if lastMode == consts.VIEW_MODE_MINI: winHeight = prefs.get(__name__, 'full-win-height', DEFAULT_WIN_HEIGHT)

            window.resize(winWidth, winHeight)
        return

    paned.get_child1().hide()
    if resize and lastMode == consts.VIEW_MODE_FULL:
        winWidth = winWidth - paned.get_position()
        window.resize(winWidth, winHeight)

    if mode == consts.VIEW_MODE_PLAYLIST:
        wTree.get_widget('statusbar').show()
        wTree.get_widget('box-btn-tracklist').hide()
        wTree.get_widget('scrolled-tracklist').show()
        wTree.get_widget('box-trkinfo').show()
        if resize and lastMode == consts.VIEW_MODE_MINI:
            window.resize(winWidth, prefs.get(__name__, 'full-win-height', DEFAULT_WIN_HEIGHT))
        return

    wTree.get_widget('statusbar').hide()
    wTree.get_widget('box-btn-tracklist').hide()
    wTree.get_widget('scrolled-tracklist').hide()

    if mode == consts.VIEW_MODE_MINI: wTree.get_widget('box-trkinfo').show()
    else:                             wTree.get_widget('box-trkinfo').hide()

    if resize: window.resize(winWidth, 1)
Esempio n. 34
0
    def onBtnOpen(self, btn):
        """ Load the levels from a file"""
        inFile = gui.fileChooser.openFile(self.cfgWindow, _('Load levels'))

        if inFile is not None:
            input = open(inFile, 'rt')
            lines = input.readlines()
            input.close()

            lvls      = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
            isInvalid = True

            if len(lines) == 10:
                isInvalid = False
                for i in xrange(10):
                    elts = lines[i].split()

                    try:
                        if len(elts) == 1:
                            lvls[i] = float(elts[0])
                            if lvls[i] >= -24 and lvls[i] <= 12:
                                continue
                    except:
                        pass

                    isInvalid = True
                    break

            if isInvalid:
                gui.errorMsgBox(self.cfgWindow, _('Could not load the file'), _('The format of the file is incorrect.'))
            else:
                self.jumpToTargetLvls(lvls)

                # Add a 'custom' entry to the presets if needed
                if self.preset is not None:
                    self.preset = None
                    prefs.set(__name__, 'preset', self.preset)
                    self.combo.handler_block_by_func(self.onPresetChanged)
                    self.comboStore.insert(0, (False, _('Custom'), None))
                    self.comboStore.insert(1, (True,  '',          None))
                    self.combo.set_active(0)
                    self.combo.handler_unblock_by_func(self.onPresetChanged)
Esempio n. 35
0
    def onChanged(self, combo):
        """ A new explorer has been selected with the combo box """
        currExplorer = self.combo.get_active()

        if currExplorer == -1:
            self.notebook.set_current_page(0)
        else:
            modName, expName, isHeader = self.store.get(self.store.get_iter(currExplorer), ROW_MODULE, ROW_NAME, ROW_IS_HEADER)

            if isHeader:
                if self.currExplorer is not None:
                    self.combo.set_active(self.currExplorer)
            else:
                if self.currExplorer != currExplorer:
                    self.currExplorer = currExplorer
                    prefs.set(__name__, 'last-explorer', (modName, expName))
                    modules.postMsg(consts.MSG_EVT_EXPLORER_CHANGED, {'modName': modName, 'expName': expName})

                (pixbuf, widget) = self.explorers[modName][expName]
                self.notebook.set_current_page(self.widgets[widget])
def realStartup():
    """
        Perform all the initialization stuff which is not mandatory to display the window
        This function should be called within the GTK main loop, once the window has been displayed
    """
    import atexit, dbus.mainloop.glib, gui.about, modules, webbrowser

    def onDelete(win, event):
        """ Use our own quit sequence, that will itself destroy the window """
        window.hide()
        modules.postQuitMsg()
        return True

    def onResize(win, rect):
        """ Save the new size of the window """
        if win.window is not None and not win.window.get_state() & gtk.gdk.WINDOW_STATE_MAXIMIZED:
            prefs.set(__name__, 'win-width',  rect.width)
            prefs.set(__name__, 'win-height', rect.height)

            if prefs.get(__name__, 'view-mode', DEFAULT_VIEW_MODE)in (consts.VIEW_MODE_FULL, consts.VIEW_MODE_PLAYLIST):
                prefs.set(__name__, 'full-win-height', rect.height)

    def onState(win, evt):
        """ Save the new state of the window """
        prefs.set(__name__, 'win-is-maximized', bool(evt.new_window_state & gtk.gdk.WINDOW_STATE_MAXIMIZED))

    def atExit():
        """ Final function, called just before exiting the Python interpreter """
        prefs.save()
        log.logger.info('Stopped')

    # D-Bus
    dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)

    # Make sure to perform a few actions before exiting the Python interpreter
    atexit.register(atExit)
    signal.signal(signal.SIGTERM, lambda sig, frame: onDelete(window, None))

    # GTK handlers
    window.connect('delete-event', onDelete)
    window.connect('size-allocate', onResize)
    window.connect('window-state-event', onState)
    paned.connect('size-allocate', lambda win, rect: prefs.set(__name__, 'paned-pos', paned.get_position()))
    wTree.get_widget('menu-mode-mini').connect('activate', onViewMode, consts.VIEW_MODE_MINI)
    wTree.get_widget('menu-mode-full').connect('activate', onViewMode, consts.VIEW_MODE_FULL)
    wTree.get_widget('menu-mode-playlist').connect('activate', onViewMode, consts.VIEW_MODE_PLAYLIST)
    wTree.get_widget('menu-quit').connect('activate', lambda item: onDelete(window, None))
    wTree.get_widget('menu-about').connect('activate', lambda item: gui.about.show(window))
    wTree.get_widget('menu-help').connect('activate', lambda item: webbrowser.open(consts.urlHelp))
    wTree.get_widget('menu-preferences').connect('activate', lambda item: modules.showPreferences())

    # Let's go
    modules.postMsg(consts.MSG_EVT_APP_STARTED)
Esempio n. 37
0
def unload(name):
    """ Unload the given module """
    mModulesLock.acquire()
    module = mModules[name]
    instance = module[MOD_INSTANCE]
    module[MOD_INSTANCE] = None
    mModulesLock.release()

    if instance is not None:
        mHandlersLock.acquire()
        instance.postMsg(consts.MSG_EVT_MOD_UNLOADED)
        for handlers in [
                handler for handler in mHandlers.values()
                if instance in handler
        ]:
            handlers.remove(instance)
        mHandlersLock.release()

        mEnabledModules.remove(name)
        log.logger.info('Module unloaded: %s' % module[MOD_CLASSNAME])
        prefs.set(__name__, 'enabled_modules', mEnabledModules)
def __storeAuthInfo(id, login, passwd):
    """ Store the login/password associated with id, either in the Gnome keyring or in the prefs """
    try:
        import gnomekeyring as gk

        useGK = True
    except:
        useGK = False

    # No Gnome keyring
    if not useGK:
        prefs.set(__name__, id + '_login',  login)
        prefs.set(__name__, id + '_passwd', b64encode(passwd))  # Pretty useless, but the user prefers not to see his password as clear text
        return

    # From here we can use the Gnome keyring
    __loadKeyring()

    try:
        label    = '%s (%s)' % (consts.appName, id)
        authInfo = '\n'.join((login, passwd))
        token    = gk.item_create_sync(__keyring, gk.ITEM_GENERIC_SECRET, label, {'appName': consts.appName, 'id': id}, authInfo, True)
        prefs.set(__name__, id + '_gkToken', token)
    except:
        pass
Esempio n. 39
0
    def timerFunc(self):
        """ Move a bit the scales to their target value """
        isFinished = True

        # Move the scales a bit
        for i in range(10):
            currLvl = self.scales[i].get_value()
            targetLvl = self.targetLvls[i]
            difference = targetLvl - currLvl

            if abs(difference) <= 0.25:
                newLvl = targetLvl
            else:
                newLvl = currLvl + (difference / 8.0)
                isFinished = False

            self.lvls[i] = newLvl
            self.scales[i].set_value(newLvl)

        # Set the equalizer to the new levels
        modules.postMsg(consts.MSG_CMD_SET_EQZ_LVLS, {'lvls': self.lvls})

        if isFinished:
            self.timer = None
            prefs.set(__name__, 'levels', self.lvls)

            # Make sure labels are up to date (sometimes they aren't when we're done with the animation)
            # Also unblock the handlers
            for i in range(10):
                self.scales[i].queue_draw()
                self.scales[i].handler_unblock_by_func(
                    self.onScaleValueChanged)

            return False

        return True
Esempio n. 40
0
def load_enabled_modules():
    # Find modules, instantiate those that are mandatory or that have been previously enabled by the user
    sys.path.append(mModDir)
    for file in sorted(
            os.path.splitext(file)[0] for file in os.listdir(mModDir)
            if file.endswith('.py') and file not in blacklist):
        try:
            pModule = __import__(file)
            modInfo = getattr(pModule, 'MOD_INFO')

            # Should it be instantiated?
            instance = None
            if modInfo[MODINFO_MANDATORY] or modInfo[
                    MODINFO_NAME] in mEnabledModules:
                if len(__checkDeps(modInfo[MODINFO_DEPS])) == 0:
                    log.logger.info('Loading module: %s' % file)
                    instance = getattr(pModule, file)()
                    instance.start()
                else:
                    log.logger.error(
                        'Unable to load module %s because of missing dependencies'
                        % file)

            # Add it to the dictionary
            mModules[modInfo[MODINFO_NAME]] = [
                pModule, file, instance, modInfo
            ]
        except:
            log.logger.error('Unable to load module %s\n\n%s' %
                             (file, traceback.format_exc()))

    # Remove enabled modules that are no longer available
    mEnabledModules[:] = [
        module for module in mEnabledModules if module in mModules
    ]
    prefs.set(__name__, 'enabled_modules', mEnabledModules)
Esempio n. 41
0
    def onResize(win, rect):
        """ Save the new size of the window """
        maximized = win.get_state() & Gdk.WindowState.MAXIMIZED
        if not maximized:
            prefs.set(__name__, 'win-width',  rect.width)
            prefs.set(__name__, 'win-height', rect.height)

            view_mode = prefs.get(__name__, 'view-mode', DEFAULT_VIEW_MODE)
            if view_mode in (consts.VIEW_MODE_FULL, consts.VIEW_MODE_PLAYLIST):
                prefs.set(__name__, 'full-win-height', rect.height)
Esempio n. 42
0
    def onBtnOk(self, btn):
        """ Save configuration """
        downloadCovers = self.cfgWin.getWidget(
            'chk-downloadCovers').get_active()
        preferUserCovers = self.cfgWin.getWidget(
            'chk-preferUserCovers').get_active()
        userCoverFilenames = [
            word.strip() for word in self.cfgWin.getWidget(
                'txt-filenames').get_text().split(',')
        ]

        prefs.set(__name__, 'download-covers', downloadCovers)
        prefs.set(__name__, 'prefer-user-covers', preferUserCovers)
        prefs.set(__name__, 'user-cover-filenames', userCoverFilenames)

        self.cfgWin.hide()
Esempio n. 43
0
 def onState(win, event):
     """ Save the new state of the window """
     if event.changed_mask & Gdk.WindowState.MAXIMIZED:
         maximized = bool(event.new_window_state & Gdk.WindowState.MAXIMIZED)
         prefs.set(__name__, 'win-is-maximized', maximized)
Esempio n. 44
0
 def onPanedResize(win, rect):
     prefs.set(__name__, 'paned-pos', paned.get_position())
Esempio n. 45
0
 def onAppQuit(self):
     """ The application is about to terminate """
     prefs.set(__name__, 'show_thumb', self.cover_spot.show_thumb)
Esempio n. 46
0
def realStartup(window, paned):
    """
    Perform all the initialization stuff which is not mandatory to display the
    window. This function should be called within the GTK main loop, once the
    window has been displayed
    """

    # Is the application started for the first time?
    first_start = prefs.get(__name__, 'first-time', True)
    logging.debug('First start: {}'.format(first_start))
    if first_start:
        prefs.set(__name__, 'first-time', False)

        # Enable some modules by default
        prefs.set('modules', 'enabled_modules', ['Covers', 'Desktop Notification'])

    import atexit
    import signal
    import dbus.mainloop.glib
    import modules

    modules.load_enabled_modules()

    def onDelete(win, event):
        """ Use our own quit sequence, that will itself destroy the window """
        win.hide()
        modules.postQuitMsg()
        return True

    def onResize(win, rect):
        """ Save the new size of the window """
        maximized = win.get_state() & Gdk.WindowState.MAXIMIZED
        if not maximized:
            prefs.set(__name__, 'win-width',  rect.width)
            prefs.set(__name__, 'win-height', rect.height)

            view_mode = prefs.get(__name__, 'view-mode', DEFAULT_VIEW_MODE)
            if view_mode in (consts.VIEW_MODE_FULL, consts.VIEW_MODE_PLAYLIST):
                prefs.set(__name__, 'full-win-height', rect.height)

    def onPanedResize(win, rect):
        prefs.set(__name__, 'paned-pos', paned.get_position())

    def onState(win, event):
        """ Save the new state of the window """
        if event.changed_mask & Gdk.WindowState.MAXIMIZED:
            maximized = bool(event.new_window_state & Gdk.WindowState.MAXIMIZED)
            prefs.set(__name__, 'win-is-maximized', maximized)

    def atExit():
        """
        Final function, called just before exiting the Python interpreter
        """
        prefs.save()
        log.logger.info('Stopped')

    # D-Bus
    dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)

    # Register some handlers (Signal SIGKILL cannot be caught)
    atexit.register(atExit)
    signal.signal(signal.SIGINT,  lambda sig, frame: onDelete(window, None))
    signal.signal(signal.SIGTERM, lambda sig, frame: onDelete(window, None))

    # GTK handlers
    window.connect('delete-event', onDelete)
    window.connect('size-allocate', onResize)
    window.connect('window-state-event', onState)
    paned.connect('size-allocate', onPanedResize)

    # Let's go
    GObject.idle_add(modules.postMsg, consts.MSG_EVT_APP_STARTED)