def _create_filter_models( self ): #CREAR PROXY MODEL self.proxymodel.setDynamicSortFilter( True ) self.proxymodel.setFilterRole( Qt.EditRole ) self.proxymodel.setFilterRegExp( "1" ) self.proxymodel.setFilterKeyColumn( CONCILIADO ) #CREAR PROXY MODEL PARA VERIFICAR SI FUE GENERADO POR EL BANCO delbancoproxymodel = QSortFilterProxyModel( self ) delbancoproxymodel.setSourceModel( self.proxymodel ) delbancoproxymodel.setDynamicSortFilter( True ) delbancoproxymodel.setFilterRole( Qt.EditRole ) delbancoproxymodel.setFilterRegExp( "0" ) delbancoproxymodel.setFilterKeyColumn( DELBANCO ) #CREAR PROXY MODEL PARA VERIFICAR SI FUE GENERADO POR LA EMPRESA empresaproxymodel = QSortFilterProxyModel( self ) empresaproxymodel.setSourceModel( self.proxymodel ) empresaproxymodel.setDynamicSortFilter( True ) empresaproxymodel.setFilterRole( Qt.EditRole ) empresaproxymodel.setFilterRegExp( "1" ) empresaproxymodel.setFilterKeyColumn( DELBANCO ) filtroMenos = "^" + str( constantes.IDND ) + "$|^" + str( constantes.IDCHEQUE ) + "$|^" + str( constantes.IDERROR ) +"$|^" + str( constantes.IDERROR ) + "$" filtroMas = "[" + filtroMenos + "]" #CREAR MODELO PARA DEPOSITOS self._setup_proxy_model(DetalleTableModel(self), empresaproxymodel, filtroMas, IDTIPODOC, self.tablalibromas) #CREAR MODELO PARA CHEQUES self._setup_proxy_model(DetalleTableModel(self), empresaproxymodel, filtroMenos, IDTIPODOC, self.tablalibromenos) #CREAR MODELO PARA NOTAS DE CREDITO self._setup_proxy_model(DetalleTableModel(self), delbancoproxymodel, filtroMas, IDTIPODOC, self.tablabancomas) #CREAR MODELO PARA NOTAS DE DEBITO self._setup_proxy_model(DetalleTableModel(self), delbancoproxymodel, filtroMenos, IDTIPODOC, self.tablabancomenos)
class FrmConciliacion( Base , Ui_frmConciliacion ): """ Formulario para crear nuevas conciliaciones bancarias """ def __init__( self , parent = None ): """ Constructor """ super( FrmConciliacion, self ).__init__( parent ) self.user = parent.user self.editmodel = None self.status = True # las acciones deberian de estar ocultas self.actionSave.setVisible( False ) self.actionCancel.setVisible( False ) # El modelo principal self.navmodel = RONavigationModel( self ) # El modelo que filtra a self.navmodel self.navproxymodel = QSortFilterProxyModel( self ) self.navproxymodel.setFilterKeyColumn( -1 ) self.navproxymodel.setSourceModel( self.navmodel ) self.navproxymodel.setFilterCaseSensitivity ( Qt.CaseInsensitive ) # Este es el modelo con los datos de la tabla para navegar self.detailsmodel = ReadOnlyTableModel( self ) self.proxymodel = QSortFilterProxyModel( self ) # CREAR TODOS LOS PROXY MODEL self._create_filter_models() self.detailsmodel.dataChanged[QModelIndex, QModelIndex].connect( self.updateLabels ) # Cargar los modelos en un hilo aparte QTimer.singleShot( 0, self.loadModels ) def _create_filter_models( self ): #CREAR PROXY MODEL self.proxymodel.setDynamicSortFilter( True ) self.proxymodel.setFilterRole( Qt.EditRole ) self.proxymodel.setFilterRegExp( "1" ) self.proxymodel.setFilterKeyColumn( CONCILIADO ) #CREAR PROXY MODEL PARA VERIFICAR SI FUE GENERADO POR EL BANCO delbancoproxymodel = QSortFilterProxyModel( self ) delbancoproxymodel.setSourceModel( self.proxymodel ) delbancoproxymodel.setDynamicSortFilter( True ) delbancoproxymodel.setFilterRole( Qt.EditRole ) delbancoproxymodel.setFilterRegExp( "0" ) delbancoproxymodel.setFilterKeyColumn( DELBANCO ) #CREAR PROXY MODEL PARA VERIFICAR SI FUE GENERADO POR LA EMPRESA empresaproxymodel = QSortFilterProxyModel( self ) empresaproxymodel.setSourceModel( self.proxymodel ) empresaproxymodel.setDynamicSortFilter( True ) empresaproxymodel.setFilterRole( Qt.EditRole ) empresaproxymodel.setFilterRegExp( "1" ) empresaproxymodel.setFilterKeyColumn( DELBANCO ) filtroMenos = "^" + str( constantes.IDND ) + "$|^" + str( constantes.IDCHEQUE ) + "$|^" + str( constantes.IDERROR ) +"$|^" + str( constantes.IDERROR ) + "$" filtroMas = "[" + filtroMenos + "]" #CREAR MODELO PARA DEPOSITOS self._setup_proxy_model(DetalleTableModel(self), empresaproxymodel, filtroMas, IDTIPODOC, self.tablalibromas) #CREAR MODELO PARA CHEQUES self._setup_proxy_model(DetalleTableModel(self), empresaproxymodel, filtroMenos, IDTIPODOC, self.tablalibromenos) #CREAR MODELO PARA NOTAS DE CREDITO self._setup_proxy_model(DetalleTableModel(self), delbancoproxymodel, filtroMas, IDTIPODOC, self.tablabancomas) #CREAR MODELO PARA NOTAS DE DEBITO self._setup_proxy_model(DetalleTableModel(self), delbancoproxymodel, filtroMenos, IDTIPODOC, self.tablabancomenos) def _setup_proxy_model(self, model, source, regexp, column, table, role = Qt.DisplayRole): model.setSourceModel( source ) model.setFilterRegExp( regexp ) model.setFilterKeyColumn( column ) model.setFilterRole(role) table.setModel( model ) def updateModels( self ): """ Recargar todos los modelos """ try: if not(QSqlDatabase.database().isOpen() or QSqlDatabase.database().open()): raise Exception( "No se pudo abrir la base" ) self.navmodel.setQuery( """ SELECT c.Fecha, b.descripcion as Banco, cb.ctabancaria, m.Simbolo, cc.Codigo, c.saldolibro, c.saldobanco, cb.idcuentacontable, c.iddocumento FROM conciliaciones c JOIN cuentasbancarias cb ON c.idcuentabancaria = cb.idcuentacontable JOIN bancos b ON b.idbanco = cb.idbanco JOIN tiposmoneda m ON m.idtipomoneda = cb.idtipomoneda JOIN cuentascontables cc ON cc.idcuenta = cb.idcuentacontable ORDER BY c.iddocumento ; """ ) # Este objeto mapea una fila del modelo self.navproxymodel a los controles self.mapper.setSubmitPolicy( QDataWidgetMapper.ManualSubmit ) self.mapper.setModel( self.navproxymodel ) self.mapper.addMapping( self.txtbanco, BANCO ) self.mapper.addMapping( self.txtmoneda, MONEDA ) self.mapper.addMapping( self.txtcuentabanco, CUENTABANCO ) self.mapper.addMapping( self.txtcuenta, CUENTA ) # asignar los modelos a sus tablas self.tablenavigation.setModel( self.navproxymodel ) self.tabledetails.setModel( self.detailsmodel ) self.proxymodel.setSourceModel( self.detailsmodel ) self.tablenavigation.setColumnHidden( SALDOBANCO, True ) self.tablenavigation.setColumnHidden( SALDOLIBRO, True ) self.tablenavigation.setColumnHidden( IDCUENTABANCO, True ) self.tablenavigation.setColumnHidden( IDDOC, True ) self._ocultar_columnas() except UserWarning as inst: logging.error( unicode( inst ) ) QMessageBox.critical( self, qApp.organizationName(), unicode( inst ) ) except Exception as inst: logging.critical( unicode( inst ) ) QMessageBox.critical( self, qApp.organizationName(), u"Hubo un error al tratar de iniciar una nueva conciliación "\ + "bancaria" ) finally: if QSqlDatabase.database().isOpen(): QSqlDatabase.database().close() def updateDetailFilter( self, _index ): if self.tabWidget.currentIndex() == 0: self.cargarMovimientos() def cargarMovimientos( self ): index = self.mapper.currentIndex() saldobanco = Decimal( self.navmodel.record( index ).value( "saldobanco" ).toString() ) saldolibro = Decimal( self.navmodel.record( index ).value( "saldolibro" ).toString() ) fecha = self.navmodel.record( index ).value( "fecha" ).toDate() self.lblfecha.setText( fecha.toString( "MMMM yyyy" ).upper() ) ctaBanco = self.navmodel.record( index ).value( "idcuentacontable" ).toString() try: if not self.database.isOpen(): if not self.database.open(): raise Exception( "No se pudo abrir la base" ) self.detailsmodel.setQuery( "CALL spMovimientoCuenta(" + ctaBanco + "," + fecha.toString( "yyyyMMdd" ) + ");" ) self.proxymodel.setSourceModel( self.detailsmodel ) except Exception as inst: logging.error( unicode( inst ) ) finally: if self.database.isOpen(): self.database.close() self.tablenavigation.selectRow( self.mapper.currentIndex() ) self.spbsaldobanco.setValue( saldobanco ) self.txtsaldolibro.setText( moneyfmt( saldolibro, 4, "C$" ) ) nc = self.tablabancomas.model().total nd = self.tablabancomenos.model().total depositos = self.tablalibromas.model().total cheques = self.tablalibromenos.model().total self.txtcheque.setText( moneyfmt( cheques, 4, "C$" ) ) self.txtdeposito.setText( moneyfmt( depositos, 4, self.editmodel.moneda ) ) self.txtnotacredito.setText( moneyfmt( nc, 4, self.editmodel.moneda ) ) self.txtnotadebito.setText( moneyfmt( nd, 4, self.editmodel.moneda ) ) self.txttotallibro.setText( moneyfmt( saldobanco + depositos + cheques, 4, self.editmodel.moneda ) ) self.txttotalbanco.setText( moneyfmt( saldolibro + nc + nd , 4, self.editmodel.moneda ) ) dif = saldobanco + depositos + cheques - ( saldolibro + nc + nd ) self.lbldiferencia.setText( moneyfmt( dif, 4, self.editmodel.moneda ) if dif != 0 else "CONCILIADO" ) def updateLabels( self ): self.txttotallibro.setText( moneyfmt( self.editmodel.total_libro, 4, self.editmodel.moneda ) ) self.txtcheque.setText( moneyfmt( self.editmodel.total_cheques, 4, self.editmodel.moneda ) ) self.txtdeposito.setText( moneyfmt( self.editmodel.total_depositos, 4, self.editmodel.moneda ) ) self.txtnotacredito.setText( moneyfmt( self.editmodel.total_nota_credito, 4, self.editmodel.moneda ) ) self.txtnotadebito.setText( moneyfmt( self.editmodel.total_nota_debito, 4, self.editmodel.moneda ) ) self.txttotalbanco.setText( moneyfmt( self.editmodel.total_banco, 4, self.editmodel.moneda ) ) dif = self.editmodel.diferencia self.lbldiferencia.setText( ( "Diferencia " + moneyfmt( dif, 4, self.editmodel.moneda ) ) if dif != 0 else "CONCILIADO" ) @pyqtSlot( float ) def on_spbsaldobanco_valueChanged ( self, value ): """ Asignar el saldo inicial del banco al modelo """ if not self.editmodel is None: # value = self.spbsaldobanco.value() self.editmodel.saldo_inicial_banco = Decimal( str( value ) ) self.updateLabels() @pyqtSlot( ) def on_btnAdd_clicked(self): if not self.database.isOpen(): if not self.database.open(): raise UserWarning( u"No se pudo establecer la conexión con "\ + "la base de datos" ) try: mov = dlgmovimientosbancarios(self) # Rellenar el combobox de las CONCEPTOS if mov.conceptosModel.rowCount() == 0: raise UserWarning( u"No existen conceptos en la base de "\ + "datos que justifiquen la elaboración de Notas de Crédito o Débito" ) mov.exec_() except UserWarning as inst: QMessageBox.critical( self, qApp.organizationName(), unicode( inst ) ) logging.error( unicode( inst ) ) logging.error( mov.conceptosModel.query().lastError().text() ) # except Exception as inst: # QMessageBox.critical( self, qApp.organizationName(), # "Hubo un problema al tratar de crear"\ # + " el nuevo pago" ) # logging.critical( unicode( inst ) ) # logging.error( query.lastError().text() ) finally: if QSqlDatabase.database().isOpen(): QSqlDatabase.database().close() # notas = dlgMovimientosBancarios( self ) # notas.setWindowModality( Qt.WindowModal ) # if notas.exec_() == QDialog.Accepted: # row = self.editmodel.rowCount() # # datosDoc = notas.editmodel.datos # # linea = LineaConciliacion( self.editmodel ) # linea.fecha = datosDoc.dateTime.toString( "dd/MM/yy" ) # linea.monto = datosDoc.total # linea.idTipoDoc = datosDoc.idTipoDoc # # linea.concepto = notas.editmodel.codigoDoc + " " + linea.fecha # linea.saldo = self.editmodel.lines[row - 1].saldo + linea.monto # linea.conciliado = 1 # linea.delBanco = 1 # linea.concepto2 = notas.editmodel.descripcionDoc + " " + linea.fecha # linea.idDoc = 0 # linea.datos = datosDoc # self.editmodel.insertRows( row ) # self.editmodel.lines[row] = linea # index = self.editmodel.index( row, CONCILIADO ) # self.editmodel.dataChanged.emit( index, index ) def setControls( self, status ): """ En esta funcion cambio el estado enabled de todos los items en el formulario @param status: false = editando true = navegando """ self.actionPrint.setVisible( status ) self.btnAdd.setVisible( not status ) self.btnRemove.setVisible( not status ) self.actionSave.setVisible( not status ) self.actionCancel.setVisible( not status ) self.tabnavigation.setEnabled( status ) self.actionNew.setVisible( status ) self.actionGoFirst.setVisible( status ) self.actionGoPrevious.setVisible( status ) self.actionGoNext.setVisible( status ) self.actionGoLast.setVisible( status ) self.actionPreview.setVisible( status ) self.spbsaldobanco.setReadOnly( status ) # self.tabledetails.setColumnHidden(DELBANCO,not status) if status: self.navigate( 'last' ) self.tabledetails.setEditTriggers( QAbstractItemView.NoEditTriggers ) else: self.tabledetails.setEditTriggers( QAbstractItemView.AllEditTriggers ) self.spbsaldobanco.setValue( 0 ) self.tabWidget.setCurrentIndex( 0 ) def newDocument( self ): """ Iniciar un nuevo documento """ query = QSqlQuery() try: if not QSqlDatabase.database().isOpen() and not QSqlDatabase.database().open(): raise UserWarning( u"No se pudo establecer una conexión " "con la base de datos" ) dlgCuenta = dlgSelectCuenta( self ) fila = -1 #REPETIR MIENTRAS NO SELECCIONE UNA FILA while fila == -1: if dlgCuenta.exec_() == QDialog.Accepted: fila = dlgCuenta.tblCuenta.selectionModel().currentIndex().row() if fila == -1: QMessageBox.information( self, qApp.organizationName(), "Por favor seleccione una cuenta" ) else: #SALIR return # SI SELECCIONO UNA FILA SIGUE self.editmodel = ConciliacionModel( dlgCuenta.data['saldo_inicial_libro'], dlgCuenta.data['fecha'], dlgCuenta.data['banco'], dlgCuenta.data['cuenta_bancaria'], dlgCuenta.data['id_cuenta_contable'], dlgCuenta.data['codigo_cuenta_contable'], dlgCuenta.data['moneda'] ) self.txtbanco.setText( self.editmodel.banco ) self.txtcuentabanco.setText( self.editmodel.cuenta_bancaria ) self.txtmoneda.setText( self.editmodel.moneda ) self.txtcuenta.setText( self.editmodel.codigo_cuenta_contable ) self.lblfecha.setText( self.editmodel.datetime.toString( "MMMM yyyy" ).upper() ) if not query.exec_( "CALL spMovimientoCuenta( %d, %s )" % ( self.editmodel.id_cuenta_contable, self.editmodel.fecha_conciliacion.toString( "yyyyMMdd" ) ) ): raise Exception( query.lastError().text() ) row = 0 while query.next(): linea = LineaConciliacion( query.value( 5 ).toBool(), #del_banco Decimal( query.value( 3 ).toString() ), #saldo_inicial Decimal( query.value( DEBE ).toString() ), #monto QDate.fromString( query.value( FECHA ).toString(), 'dd/M/yy' ), #fecha query.value( 6 ).toInt()[0], # tipo_doc query.value( 8 ).toInt()[0], # id_documento query.value( CONCEPTO ).toString() #descripcion ) linea.monto = Decimal( query.value( 2 ).toString() ) self.editmodel.insertRows( row ) self.editmodel.lines[row] = linea row += 1 #self.editmodel.saldoInicialLibro = self.editmodel.lines[row - 1].saldo self.txtsaldolibro.setText( moneyfmt( self.editmodel.saldo_inicial_libro, 4, self.editmodel.moneda ) ) self.updateLabels() self.proxymodel.setSourceModel( self.editmodel ) self.setControls( False ) self.tabnavigation.setEnabled( False ) self.tabWidget.setCurrentIndex( 0 ) self.tabledetails.setModel( self.editmodel ) self.tabledetails.resizeColumnsToContents() self._ocultar_columnas() self.editmodel.dataChanged[QModelIndex, QModelIndex].connect( self.updateLabels ) except UserWarning as inst: logging.error( unicode( inst ) ) QMessageBox.critical( self, qApp.organizationName(), unicode( inst ) ) except Exception as inst: logging.critical( unicode( inst ) ) QMessageBox.critical( self, qApp.organizationName(), u"Hubo un error al intentar iniciar una" + u" nueva conciliación" ) finally: if self.database.isOpen(): self.database.close() def _ocultar_columnas( self ): for table in ( self.tablabancomas, self.tablalibromas, self.tablabancomenos, self.tablalibromenos): table.setColumnHidden( HABER, True ) table.setColumnHidden( CONCILIADO, True ) table.setColumnHidden( SALDO, True ) table.setColumnHidden( IDTIPODOC, True ) table.setColumnHidden( DELBANCO, True ) self.tabledetails.setColumnHidden( IDTIPODOC, True ) def save( self ): """ Guardar el documento actual """ if not self.valid: return None if QMessageBox.question( self, qApp.organizationName(), u"¿Desea guardar el documento?", QMessageBox.Yes | QMessageBox.No ) == QMessageBox.Yes: if self.editmodel.save(): QMessageBox.information( self, qApp.organizationName(), u"El documento se ha guardado con éxito" ) self.editmodel = None self.updateModels() self.navigate( 'last' ) self.status = True else: QMessageBox.critical( self, qApp.organizationName(), "Ha ocurrido un error al guardar el documento" ) def cancel( self ): self.editmodel = None self.tablenavigation.setModel( self.navproxymodel ) self.tabledetails.setModel( self.detailsmodel ) self.proxymodel.setSourceModel( self.detailsmodel ) self._ocultar_columnas() self.status = True @pyqtSlot( bool ) @if_edit_model def on_btnremove_clicked( self, _checked ): filas = [] for index in self.tabledetails.selectedIndexes(): pos = index.row() if pos > 0 and not pos in filas and self.editmodel.lines[pos].idDoc == 0: filas.append( pos ) if len( filas ) > 0: filas.sort( None, None, True ) for pos in filas: self.editmodel.removeRows( pos ) self.updateLabels()
class CurrentPlaylistForm(QWidget, auxilia.Actions, CurrentListForm): '''List and controls for the currently loaded playlist''' editing = 0 def __init__(self, modelManager, view, app, config): QWidget.__init__(self) self.app = app self.view = view self.config = config self._temp = {} self.playQueue = modelManager.playQueue self.playerState = modelManager.playerState self.modelManager = modelManager self.playQueueDelegate = PlayQueueDelegate(self.config) self.setupUi(self) self.connect(self.playerState, SIGNAL('repeatChanged'), self.repeatButton.setChecked) self.connect(self.playerState, SIGNAL('randomChanged'), self.randomButton.setChecked) self.connect(self.playerState, SIGNAL('xFadeChanged'), self.crossFade.setValue) self.connect(self.crossFade, SIGNAL('valueChanged(int)'), self.playerState.setXFade) self.connect(self.repeatButton, SIGNAL('toggled(bool)'), self.playerState.setRepeat) self.connect(self.randomButton, SIGNAL('toggled(bool)'), self.playerState.setRandom) self.playQueueProxy = QSortFilterProxyModel() self.playQueueProxy.setSourceModel(self.playQueue) self.playQueueProxy.setFilterCaseSensitivity(Qt.CaseInsensitive) self.playQueueProxy.setDynamicSortFilter(True) self.playQueueProxy.setFilterRole(Qt.AccessibleTextRole) self.currentList.setModel(self.playQueueProxy) self.currentList.setItemDelegateForColumn(0, self.playQueueDelegate) self.currentList.horizontalHeader().setResizeMode(1) if config.oneLinePlaylist: self.oneLinePlaylist.setChecked(True) self.keepPlayingVisible.setChecked(self.config.keepPlayingVisible) self._togglePlaylistTools(self.config.playlistControls) self.connect(self.playQueue, SIGNAL('aboutToUpdate'), self.prepareForUpdate) self.connect(self.playQueue, SIGNAL('updated'), self.updated) self.connect(self.playQueue, SIGNAL('currentSongChanged'), self._ensurePlayingVisable) # Connect to the view for double click action. self.connect(self.currentList, SIGNAL('doubleClicked(const QModelIndex &)'), self._playSong) self.connect(self.currentFilter,SIGNAL('textEdited(QString)'),self.playQueueProxy.setFilterFixedString) self.connect(self.currentRemove,SIGNAL('clicked()'),self._removeSelected) self.connect(self.currentClear,SIGNAL('clicked()'),self.playQueue.clear) self.connect(self.currentSave,SIGNAL('clicked()'),self._saveCurrent) self.connect(self.addStream,SIGNAL('clicked()'),self._addStream) self.connect(self.currentBottom, SIGNAL('clicked()'), self._togglePlaylistTools) self.connect(self.currentList,SIGNAL('selectionChanged()'),self._setEditing) self.connect(self.currentList.verticalScrollBar(), SIGNAL('valueChanged(int)'), self._setEditing) self.connect(self.keepPlayingVisible,SIGNAL('toggled(bool)'),self._toggleKeepPlayingVisible) self.connect(self.oneLinePlaylist,SIGNAL('toggled(bool)'),self._setOneLinePlaylist) self.connect(self.showNumbers,SIGNAL('toggled(bool)'),self._setNumbers) self.showNumbers.setChecked(self.config.showNumbers) # Menu for current playlist. # Create actions. self.currentMenuPlay = self.action(self.currentList, self._playSong, icon="media-playback-start", text='play', tooltip='Start playing the selected song.') self.currentMenuRemove = self.action(self.currentList, self._removeSelected, icon="list-remove", text='Remove', tooltip="Remove the selected songs from the playlist.") self.currentMenuClear = self.action(self.currentList, self.playQueue.clear, icon="document-new", text='Clear', tooltip="Remove all songs from the playlist.") self.currentMenuSave = self.action(self.currentList, self._saveCurrent, icon="document-save-as", text='Save', tooltip="Save the current playlist.") self.currentMenuCrop = self.action(self.currentList, self._cropCurrent, icon="project-development-close", text='Crop', tooltip="Remove all but the selected songs.") self.currentMenuShuffle = self.action(self.currentList, self.playQueue.shuffle, icon="media-playlist-shuffle", text='Shuffle', tooltip="Shuffle the songs in the playlist.") # Set the Off icon for the repeat and random buttons. icon = self.randomButton.icon() icon.addPixmap( icon.pixmap(32,32,QIcon.Normal), QIcon.Normal, QIcon.On) icon.addPixmap( icon.pixmap(32,32,QIcon.Disabled), QIcon.Normal, QIcon.Off) self.randomButton.setIcon(icon) icon = self.repeatButton.icon() icon.addPixmap( icon.pixmap(32,32,QIcon.Normal), QIcon.Normal, QIcon.On) icon.addPixmap( icon.pixmap(32,32,QIcon.Disabled), QIcon.Normal, QIcon.Off) self.repeatButton.setIcon(icon) def prepareForUpdate(self): '''Save some state prior to applying changes to the play queue.''' self._temp['oldLength'] = len(self.playQueue) scrollBar = self.currentList.verticalScrollBar() oldScroll = scrollBar.value() self._temp['setBottom'] = oldScroll == scrollBar.maximum() self._temp['oldScroll'] = oldScroll def updated(self): self._setEditing() self.view.numSongsLabel.setText(str(len(self.playQueue))+' Songs') self._setPlayTime(self.playQueue.totalTime()) self._resize() self.app.processEvents() scrollBar = self.currentList.verticalScrollBar() if self._temp.get('oldLength') == 0: self._ensurePlayingVisable(force=True) elif self._temp.get('setBottom'): scrollBar.setValue(scrollBar.maximum()) else: scrollBar.setValue(self._temp.get('oldScroll', 0)) try: del self._temp['oldLength'] del self._temp['setBottom'] del self._temp['oldScroll'] except KeyError: pass def keyPressEvent(self, event): if event.matches(QKeySequence.Delete): self._removeSelected() elif event.key() == Qt.Key_Escape: self.currentList.reset() else: QListView.keyPressEvent(self.currentList, event) def _getSelectedRows(self): return (self.playQueueProxy.mapToSource(index).row() for index in self.currentList.selectedIndexes()) def _ensurePlayingVisable(self, force=False): if time() - self.playQueue.lastEdit <= 5 and not force == True: return if self.playQueue.playing is None: return playing = self.playQueue.id_index(self.playQueue.playing) if self.currentList.isRowHidden(playing): return playing = self.playQueueProxy.mapFromSource(self.playQueue.createIndex(playing, 0)) self.currentList.scrollTo(playing, 1) # PositionAtTop height = self.currentList.viewport().height() scrollBar = self.currentList.verticalScrollBar() correction = (height / 8) - self.currentList.rowViewportPosition(playing.row()) new_pos = scrollBar.value() - correction scrollBar.setValue(new_pos) def _saveCurrent(self): '''Save the current playlist''' playlistModel = self.modelManager.playlists (name, ok) = QInputDialog.getItem(self, 'Save Playlist', 'Enter or select the playlist name', [name for name in playlistModel], 0, True) if ok == True: playlistModel.saveCurrent(name) def _removeSelected(self): '''Remove the selected item(s) from the current playlist''' self._removeSongs(self._getSelectedRows()) self.currentList.reset() def _cropCurrent(self): selection = set(self._getSelectedRows()) rows = set(xrange(len(self.playQueue))) self._removeSongs(list(rows - selection)) def _removeSongs(self, rowList): start = rowList.next() end = start + 1 for row in rowList: if row != end: del self.playQueue[start:end] start = row end = row + 1 del self.playQueue[start:end] def _playSong(self, index=None): try: row = self._getSelectedRows().next() except StopIteration: return self.playerState.currentSong = row self.playerState.play() def _setPlayTime(self, playTime=0): self.view.playTimeLabel.setText('Total play time: %s' % mpdlibrary.Time(playTime).human) def _setNumbers(self, value): self.config.showNumbers = value self.currentList.verticalHeader().setVisible(value) def _toggleKeepPlayingVisible(self, value): self.config.keepPlayingVisible = value if value: self._ensurePlayingVisable(force=True) def _setOneLinePlaylist(self, value): self.config.oneLinePlaylist = value self.playQueueDelegate.setOneLine(value) self._resize() def _resize(self): metrics = QFontMetrics(QFont()) length = 0 for song in self.playQueue: artist = metrics.width(song.artist) title = metrics.width(song.title) if self.config.oneLinePlaylist: length = max(artist + title, length) else: length = max(artist, title, length) width = length + self.playQueueDelegate.height + 4 header = self.currentList.horizontalHeader() header.setMinimumSectionSize(width) self.currentList.verticalHeader().setDefaultSectionSize(self.playQueueDelegate.height) def _togglePlaylistTools(self, value=None): text = ('Show Playlist Tools', 'Hide Playlist Tools') if value == None: value = not self.playlistTools.isVisible() scrollBar = self.currentList.verticalScrollBar() scrollValue = scrollBar.value() scrollMax = scrollBar.maximum() self.playlistTools.setVisible(value) self.currentBottom.setArrowType(int(value)+1) self.currentBottom.setText(text[value]) self.config.playlistControls = bool(self.playlistTools.isVisible()) if scrollValue == scrollMax: scrollBar.setValue(scrollBar.maximum()) def _addStream(self): '''Ask the user for the url of the stream to add.''' (url,ok) = QInputDialog.getText(self , 'Add Stream' , 'Please enter the url of the stream you like to add to the playlist.' , 0 , 'Add Stream') url = str(url) if ok == True and url: try: streamList = streamTools.getStreamList(url) except streamTools.ParseError: print 'error: Could not parse stream address.' return self.playQueue.extend(streamList) def _setEditing(self): self.playQueue.lastEdit = time()