def setData( self, index, data, role = Qt.DisplayRole ): if not index.isValid(): return False if index.column() == ACTIVO and role == Qt.CheckStateRole: return QSortFilterProxyModel.setData( self, index, 1 if data == Qt.Checked else 0, Qt.EditRole ) else: return QSortFilterProxyModel.setData( self, index, data, role )
def __init__( self, tiposdoc, parent = None, edit = True ): ''' Constructor ''' super( FrmKardex, self ).__init__( parent ) self.tiposdoc = ",".join( [str( item ) for item in tiposdoc] ) self.edit = edit self.navigationmodel = QSqlQueryModel() self.detailsModel = QSqlQueryModel() self.navproxymodel = QSortFilterProxyModel() self.navproxymodel.setSourceModel( self.navigationmodel ) self.detailsproxymodel = QSortFilterProxyModel() self.detailsproxymodel.setSourceModel( self.detailsModel ) self.tabledetails.setModel( self.detailsproxymodel ) self.tablenavigation.setModel( self.navproxymodel ) self.editmodel = None QTimer.singleShot( 0, self.loadModels )
def __init__(self, parent): """Constructor for the model. :param parent: Parent widget of this model. :type parent: QWidget """ QSortFilterProxyModel.__init__(self, parent)
def __init__( self, parent = None ): ''' Constructor ''' super( FrmKardexOther, self ).__init__( parent ) self.actionNew.setEnabled( False ) self.navmodel = QSqlQueryModel() self.detailsModel = QSqlQueryModel() self.navproxymodel = QSortFilterProxyModel() self.navproxymodel.setSourceModel( self.navmodel ) self.detailsproxymodel = QSortFilterProxyModel() self.detailsproxymodel.setSourceModel( self.detailsModel ) self.accountsnavmodel = QSqlQueryModel() self.accountsproxymodel = QSortFilterProxyModel() self.accountsproxymodel.setSourceModel( self.accountsnavmodel ) self.editmodel = None if not self.user.hasRole( "contabilidad" ): self.tableaccounts.setVisible( False ) self.lblaccounts.setVisible( False ) QTimer.singleShot( 0, self.loadModels )
def __init__(self, model , parent=None): QSortFilterProxyModel.__init__(self, parent) self.__show_summary_keys = True self.__show_block_keys = True self.setFilterCaseSensitivity(Qt.CaseInsensitive) self.setSourceModel(model)
def __init__( self, parent = None ): """ Constructor """ super( FrmDevolucion, self ).__init__( parent ) self.editmodel = None self.status = True # las acciones deberian de estar ocultas # El modelo principal self.navmodel = RONavigationModel( self ) # El modelo que filtra a self.navmodel self.navproxymodel = QSortFilterProxyModel( self ) self.navproxymodel.setSourceModel( self.navmodel ) # Este es el modelo con los datos de la tabla para navegar self.detailsmodel = QSqlQueryModel( self ) # Este es el filtro del modelo anterior self.detailsproxymodel = QSortFilterProxyModel( self ) self.detailsproxymodel.setSourceModel( self.detailsmodel ) # Cargar los modelos en un hilo aparte QTimer.singleShot( 0, self.loadModels )
def __init__(self, messages, parent=None): """ Initializer. @param messages sequence of broker messages @param parent ancestor object """ QSortFilterProxyModel.__init__(self, parent) self.messages = messages self.acceptTypes = None
def __init__(self, parent = None): """ Constructor @param parent reference to the parent object (QObject) """ QSortFilterProxyModel.__init__(self, parent) self.setFilterCaseSensitivity(Qt.CaseInsensitive)
def __init__( self, parent = None ): QSortFilterProxyModel.__init__( self, parent ) self.__sortColumn = None # Avoid pylint complains self.__sortOrder = None # Avoid pylint complains self.__filters = [] self.__filtersCount = 0 self.__sourceModelRoot = None return
def setSourceModel(self, model): """Set the source model for the filter. """ self._filter_strings = [] self._cache = {} self._cache_fixed = {} self._cache_prefix = {} self._row_text = {} QSortFilterProxyModel.setSourceModel(self, model)
def __init__(self, parent=None, **kwargs): super(AddonManagerWidget, self).__init__(parent, **kwargs) #: list of Available | Installed self.__items = [] self.setLayout(QVBoxLayout()) self.__header = QLabel( wordWrap=True, textFormat=Qt.RichText ) self.__search = QLineEdit( placeholderText=self.tr("Filter") ) self.layout().addWidget(self.__search) self.__view = view = QTreeView( rootIsDecorated=False, editTriggers=QTreeView.NoEditTriggers, selectionMode=QTreeView.SingleSelection, alternatingRowColors=True ) self.__view.setItemDelegateForColumn(0, TristateCheckItemDelegate()) self.layout().addWidget(view) self.__model = model = QStandardItemModel() model.setHorizontalHeaderLabels(["", "Name", "Version", "Action"]) model.dataChanged.connect(self.__data_changed) proxy = QSortFilterProxyModel( filterKeyColumn=1, filterCaseSensitivity=Qt.CaseInsensitive ) proxy.setSourceModel(model) self.__search.textChanged.connect(proxy.setFilterFixedString) view.setModel(proxy) view.selectionModel().selectionChanged.connect( self.__update_details ) header = self.__view.header() header.setResizeMode(0, QHeaderView.Fixed) header.setResizeMode(2, QHeaderView.ResizeToContents) self.__details = QTextBrowser( frameShape=QTextBrowser.NoFrame, readOnly=True, lineWrapMode=QTextBrowser.WidgetWidth, openExternalLinks=True, ) self.__details.setWordWrapMode(QTextOption.WordWrap) palette = QPalette(self.palette()) palette.setColor(QPalette.Base, Qt.transparent) self.__details.setPalette(palette) self.layout().addWidget(self.__details)
def __init__(self, parent=None): QSortFilterProxyModel.__init__(self, parent) self._filter_strings = [] self._cache = {} self._cache_fixed = {} self._cache_prefix = {} self._row_text = {} # Create a cached version of _filteredRows self._filteredRows = lru_cache(100)(self._filteredRows)
def _initPeerList(self, mode): capsuleWidget = QWidget() capsuleLayout = QVBoxLayout(capsuleWidget) capsuleLayout.setContentsMargins(10, 0, 10, 0) if mode in (PrivacySettings.POLICY_EVERYBODY_EX, PrivacySettings.POLICY_NOBODY_EX, PrivacySettings.POLICY_PEER_EXCEPTION): exceptions = PrivacySettings.get().getExceptions(self._action, self._category, mode, useModified=True, categoryPolicy=self._getCategoryPolicy()) else: exceptions = {} self._peerModel = PeerModel(exceptions, mode == PrivacySettings.POLICY_PEER_EXCEPTION, self.logger) self._peerModel.itemChanged.connect(self._peerDataChanged) proxyModel = QSortFilterProxyModel(self) proxyModel.setDynamicSortFilter(True) proxyModel.setSortCaseSensitivity(Qt.CaseInsensitive) proxyModel.setSourceModel(self._peerModel) proxyModel.sort(0) self._peerList = QTreeView(self) self._peerList.setAlternatingRowColors(False) self._peerList.setHeaderHidden(True) self._peerList.setItemsExpandable(False) self._peerList.setIndentation(0) self._peerList.setModel(proxyModel) self._peerList.setSelectionMode(QTreeView.NoSelection) self._peerList.setAutoFillBackground(False) self._peerList.viewport().setAutoFillBackground(False) self._peerList.setFrameShape(QFrame.NoFrame) self._peerList.setFocusPolicy(Qt.NoFocus) capsuleLayout.addWidget(self._peerList) return capsuleWidget
def __init__( self, datos_sesion, parent, edit = False ): u''' @param datos_sesion: La información de la sesion de caja ''' super( FrmArqueo, self ).__init__( parent, True ) self.sesion = datos_sesion self.setWindowModality( Qt.WindowModal ) self.setWindowFlags( Qt.Dialog ) # self.status = False self.__dolar_proxy = ArqueoProxyModel() self.__cordoba_proxy = ArqueoProxyModel() self.editmodel = None # El modelo principal self.navmodel = QSqlQueryModel( self ) # El modelo que filtra a self.navmodel self.navproxymodel = QSortFilterProxyModel( self ) self.__details_proxymodel_d = QSortFilterProxyModel( self ) self.__details_proxymodel_c = QSortFilterProxyModel( self ) self.navproxymodel.setSourceModel( self.navmodel ) # Este es el modelo con los datos de la tabla con los detalles self.detailsModel = QSqlQueryModel( self ) # Este es el filtro del modelo anterior self.detailsproxymodel = QSortFilterProxyModel( self ) self.detailsproxymodel.setSourceModel( self.detailsModel ) #filtrar en dolares y en cordobas self.__details_proxymodel_d.setSourceModel( self.detailsproxymodel ) self.__details_proxymodel_d.setFilterKeyColumn( MONEDA ) self.__details_proxymodel_d.setFilterRegExp( "^%d$" % constantes.IDDOLARES ) self.__details_proxymodel_c.setSourceModel( self.detailsproxymodel ) self.__details_proxymodel_c.setFilterKeyColumn( MONEDA ) self.__details_proxymodel_c.setFilterRegExp( "^%d$" % constantes.IDCORDOBAS ) if edit: self.status = False self.newDocument() self.actionCancel.setVisible(False) self.tabWidget.setTabEnabled(1,False) else: self.status = True QTimer.singleShot( 0, self.loadModels )
def __init__( self, parent ): ''' Constructor ''' super( FrmFactura, self ).__init__( parent ) self.readOnly = True self.recibo = None self.clientesModel = QSqlQueryModel() # las acciones deberian de estar ocultas self.actionSave.setVisible( False ) self.actionCancel.setVisible( False ) # El modelo principal self.navmodel = QSqlQueryModel( self ) # El modelo que filtra a self.navmodel self.navproxymodel = QSortFilterProxyModel( self ) self.navproxymodel.setSourceModel( self.navmodel ) self.navproxymodel.setFilterKeyColumn( -1 ) self.navproxymodel.setFilterCaseSensitivity ( Qt.CaseInsensitive ) # Este es el modelo con los datos de la con los detalles self.detailsmodel = QSqlQueryModel( self ) self.detailsproxymodel = QSortFilterProxyModel( self ) self.detailsproxymodel.setSourceModel( self.detailsmodel ) #inicializando el documento self.editmodel = None self.lblanulado.setHidden( True ) self.toolBar.removeAction( self.actionAnular ) self.toolBar.addAction( self.actionAnular ) self.recibo = None self.cargarRecibos() self.existenciaModel = QSqlQueryModel() self.vendedoresModel = QSqlQueryModel() self.bodegasModel = QSqlQueryModel() self.anulable = 2 """ @ivar: Si la factura actual se puede anular o no @type: int """ self.tabledetails.setOrder( 1, 3 ) self.completer = QCompleter() self.completerVendedor = QCompleter() QTimer.singleShot( 0, self.loadModels )
class ExtendedComboBox(QComboBox): def __init__(self, parent=None): super(ExtendedComboBox, self).__init__(parent) self.setFocusPolicy(Qt.StrongFocus) self.setEditable(True) self.pFilterModel = QSortFilterProxyModel(self) self.pFilterModel.setFilterCaseSensitivity(Qt.CaseInsensitive) self.pFilterModel.setSourceModel(self.model()) self.completer = QCompleter(self.pFilterModel, self) self.completer.setCompletionMode(QCompleter.UnfilteredPopupCompletion) self.completer.popup().setStyleSheet('min-height: 150px') self.completer.popup().setAlternatingRowColors(True) self.setCompleter(self.completer) self.lineEdit().textEdited[unicode].connect(self.pFilterModel.setFilterFixedString)
def __init__( self, user, parent = None ): """ Constructor """ super( FrmBalanceGeneral, self ).__init__( parent ) self.setupUi( self ) self.user = user self.pasivofiltermodel = QSortFilterProxyModel() self.model = CuentasModel( self.dtPicker.date() ) self.activofiltermodel = QSortFilterProxyModel() self.capitalfiltermodel = QSortFilterProxyModel() self.dtPicker.setMaximumDate( QDate.currentDate() ) self.dtPicker.setDate( QDate.currentDate() )
def __init__(self, model, parent=None, showTable=False): super(SearchPanel, self).__init__(parent) self.tabla = None self.setFocusPolicy(Qt.StrongFocus) self.setEditable(True) # self.setModel( model ) self.setEditable(True) self.completer = QCompleter(self) # always show all completions self.completer.setCompletionMode(QCompleter.UnfilteredPopupCompletion) self.pFilterModel = QSortFilterProxyModel(self) self.pFilterModel.setFilterCaseSensitivity(Qt.CaseInsensitive) self.showTable = showTable if model != None: self.setModel(model) # self.pFilterModel.setSourceModel( model ); self.completer.setModel(self.pFilterModel) self.completerTable = SearchPanelView() self.completer.setPopup(self.completerTable) # Mostrar el Popup en forma de Tabla if self.showTable: self.tabla = SearchPanelView() self.setView(self.tabla) self.setCompleter(self.completer) self.setColumn(1) self.lineEdit().textEdited[unicode].connect( self.pFilterModel.setFilterFixedString if not showTable else self.pFilterModel.setFilterWildcard )
def __init__( self, parent = None ): super( ReciboDelegate, self ).__init__( parent ) query = QSqlQuery( """ SELECT idtipomovimiento, CONCAT(descripcion, ' ' , moneda) as tipopago, idtipomoneda, m.simbolo FROM tiposmoneda m JOIN tiposmovimientocaja p ; """ ) self.filtrados = [] query.exec_() while query.next(): self.filtrados.append( query.value( 1 ).toString() ) self.abonosmodel = QSqlQueryModel() self.abonosmodel.setQuery( query ) self.proxymodel = QSortFilterProxyModel() self.proxymodel.setSourceModel( self.abonosmodel ) self.proxymodel.setFilterKeyColumn( 1 ) self.completer = QCompleter() self.completer.setModel( self.proxymodel ) self.completer.setCompletionColumn( 1 ) self.completer.setCaseSensitivity( Qt.CaseInsensitive ) self.completer.setCompletionMode( QCompleter.UnfilteredPopupCompletion ) query = QSqlQuery( """ SELECT idbanco,descripcion FROM bancos; """ ) self.bancosmodel = QSqlQueryModel() self.bancosmodel.setQuery( query )
def __init__( self, parent = None ): """ @param parent: El formulario padre de este frm """ super( FrmArticulos, self ).__init__( parent ) self.setupUi( self ) self.database = QSqlDatabase.database() # self.__status = True self.backmodel = ArticlesModel() self.filtermodel = QSortFilterProxyModel() self.filtermodel.setSourceModel( self.backmodel ) self.filtermodel.setFilterCaseSensitivity( Qt.CaseInsensitive ) self.update_models() # self.tableview.addActions( ( self.actionEdit, self.actionNew ) ) self.tableview.setColumnHidden( 0, True ) self.tableview.resizeColumnsToContents() self.setWindowTitle( "Catalogo de Articulos" ) self.tableview.setEditTriggers( QAbstractItemView.AllEditTriggers ) self.actionEdit.setVisible( True ) self.actionSave.setVisible( False ) self.actionCancel.setVisible( False ) self.nuevoarticulo = None
def updateModels( self ): try: if not self.database.isOpen(): if not self.database.open(): raise UserWarning( u"No se pudo conectar con la base de datos" ) self.backmodel.setTable( self.table ) self.backmodel.select() self.filtermodel = QSortFilterProxyModel() self.filtermodel.setSourceModel( self.backmodel ) self.filtermodel.setFilterKeyColumn( -1 ) self.filtermodel.setFilterCaseSensitivity( Qt.CaseInsensitive ) self.tableview.setModel( self.filtermodel ) self.database.close() self.tableview.setColumnHidden( 0, True ) return True except UserWarning as inst: logging.error( inst ) QMessageBox.critical( self, qApp.organizationName(), unicode( inst ) ) except Exception as inst: logging.critical( inst ) finally: if self.database.isOpen(): self.database.close() return False
def __init__(self, parent): QFrame.__init__(self, parent) self.setContentsMargins(0, 0, 0, 0) layout = QVBoxLayout() layout.setContentsMargins(0, 0, 0, 0) layout.setSpacing(1) self._setNameLineEdit = QLineEdit(self) layout.addWidget(self._setNameLineEdit) self._setListView = QListView(self) self._listModel = QStandardItemModel(self) self._proxyModel = QSortFilterProxyModel(self) self._proxyModel.setSourceModel(self._listModel) self._setListView.setModel(self._proxyModel) self._setListView.setItemDelegate(ListItemDelegate(self)) self._setNameLineEdit.textChanged.connect( self._proxyModel.setFilterFixedString) self._completer = QCompleter(self._listModel, self) self._setNameLineEdit.setCompleter(self._completer) self._listModel.itemChanged.connect(self._onSetNameChange) layout.addWidget(self._setListView) buttonLayout = QHBoxLayout() self._addAction = QAction( "+", self, toolTip="Add a new sort key") self._updateAction = QAction( "Update", self, toolTip="Update/save current selection") self._removeAction = QAction( "\u2212", self, toolTip="Remove selected sort key.") self._addToolButton = QToolButton(self) self._updateToolButton = QToolButton(self) self._removeToolButton = QToolButton(self) self._updateToolButton.setSizePolicy( QSizePolicy.MinimumExpanding, QSizePolicy.Minimum) self._addToolButton.setDefaultAction(self._addAction) self._updateToolButton.setDefaultAction(self._updateAction) self._removeToolButton.setDefaultAction(self._removeAction) buttonLayout.addWidget(self._addToolButton) buttonLayout.addWidget(self._updateToolButton) buttonLayout.addWidget(self._removeToolButton) layout.addLayout(buttonLayout) self.setLayout(layout) self._addAction.triggered.connect(self.addCurrentSelection) self._updateAction.triggered.connect(self.updateSelectedSelection) self._removeAction.triggered.connect(self.removeSelectedSelection) self._setListView.selectionModel().selectionChanged.connect( self._onListViewSelectionChanged) self.selectionModel = None self._selections = []
def __init__(self, dl_path=DL_PATH, store_file=STORAGE_PATH, autostart=True): QObject.__init__(self) self._gui = MyMainWindow() self._autostart = autostart self._dlpath = dl_path self.ui = Ui_MPLayerGui() self.ui.setupUi(self._gui) self.dlList = download.DownloadList() self.nameStorage = naming.SeriesStorage(store_file) self.valid_url = False self._timer = QTimer() self._timeout = 500 # init-settings self.ui.pubAddSimple.setEnabled(False) self.ui.pubStart.setEnabled(False) self.ui.pubKill.setEnabled(False) self.ui.pubRemove.setEnabled(False) self._filter_model = QSortFilterProxyModel() self._filter_model.setSourceModel(self.nameStorage) self.ui.lvSeries.setModel(self._filter_model) self._epiController = EpisodeController(self) self.ui.lvDownloads.setModel(self.dlList) self._selDM = self.ui.lvDownloads.selectionModel() self._gui.setExitChecker(self._isSafeToExit) self._doConnections() self._loadHistory() # completion self._completer = QCompleter() self._completer.setModel(self._filter_model) self._completer.setCompletionMode(QCompleter.PopupCompletion) self._completer.setCaseSensitivity(Qt.CaseInsensitive) self._completer.setCompletionRole(Qt.DisplayRole) self.ui.ledEName.setCompleter(self._completer)
def lessThan(self, left, right): if left.column() == 1: # size return left.data(USER_ROLE_SIZE) < right.data(USER_ROLE_SIZE) elif left.column() == 2: # last modified return left.data(USER_ROLE_LAST_MODIFIED) < right.data(USER_ROLE_LAST_MODIFIED) return QSortFilterProxyModel.lessThan(self, left, right)
def __init__(self, parent): """ Constructor """ super(FrmCheques, self).__init__(parent) self.navmodel = QSqlQueryModel(self) self.navproxymodel = QSortFilterProxyModel(self) self.navproxymodel.setSourceModel(self.navmodel) self.accountsModel = QSqlQueryModel() self.accountsProxyModel = ROAccountsModel(self) self.accountsProxyModel.setSourceModel(self.accountsModel) # El modelo que filtra a self.navmodel self.navproxymodel.setFilterKeyColumn(-1) self.navproxymodel.setFilterCaseSensitivity(Qt.CaseInsensitive) self.editmodel = None self.status = True # las acciones deberian de estar ocultas # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ QTimer.singleShot(0, self.loadModels)
def __init__(self): QDialog.__init__(self) self.setupUi(self) self.settings = MySettings() SettingDialog.__init__(self, self.settings) # new declaration of ProjectFinder since changes can be cancelled self.projectFinder = ProjectFinder(self) # table model self.projectSearchModel = ProjectSearchModel(self.projectFinder) self.proxyModel = QSortFilterProxyModel(self) self.proxyModel.setSourceModel(self.projectSearchModel) self.projectSearchTable.setModel(self.proxyModel) header = self.projectSearchTable.horizontalHeader() header.setResizeMode(QHeaderView.ResizeToContents) # open/create QuickFinder file self.createFileButton.clicked.connect(self.createQFTSfile) self.openFileButton.clicked.connect(self.openQFTSfile) self.readQFTSfile() # project search self.addSearchButton.clicked.connect(self.addProjectSearch) self.removeSearchButton.clicked.connect(self.removeProjectSearch) self.editSearchButton.clicked.connect(self.editProjectSearch) self.refreshButton.clicked.connect(self.refreshProjectSearch) self.projectSearchTable.selectionModel().selectionChanged.connect(self.enableButtons) self.enableButtons() # geomapfish self.geomapfishCrsButton.clicked.connect(self.geomapfishCrsButtonClicked)
def data(self, index, role=Qt.DisplayRole): """ Reimplements the :meth:`QSortFilterProxyModel.data` method. :param index: Index. :type index: QModelIndex :param role: Role. :type role: int :return: Data. :rtype: QVariant """ if role == Qt.DisplayRole: node = self.getNode(index) if node.family == "Editor": data = self.__editorNodeFormat.format(node.name) elif node.family == "File": data = self.__fileNodeFormat.format(node.name) elif node.family == "Directory": data = self.__directoryNodeFormat.format(node.name) elif node.family == "Project": if node is self.sourceModel().defaultProjectNode: data = self.__defaultProjectNodeFormat.format(node.name) else: data = self.__projectNodeFormat.format(node.name) else: data = QVariant() return data else: return QSortFilterProxyModel.data(self, index, role)
def __init__(self, query): super(ChequesFiltroDelegate, self).__init__(query) self.__accounts = self.accounts self.accounts = QSortFilterProxyModel() self.accounts.setDynamicSortFilter(True) self.accounts.setSourceModel(self.__accounts) self.accounts.setFilterKeyColumn(0)
def __init__( self, tipo, rol, parent ): super( FrmPersona, self ).__init__( parent, True ) self.tabledetails = None self.setWindowModality( Qt.WindowModal ) self.setWindowFlags( Qt.Dialog ) self.tipo = tipo self.rol = rol self.lbltitulo.setText( u"<B>Datos del %s</B>" % rol ) self.editmodel = None # self.parent = parent self.navmodel = QSqlQueryModel() self.navproxymodel = QSortFilterProxyModel() self.navproxymodel.setFilterKeyColumn( -1 ) self.navproxymodel.setSourceModel( self.navmodel ) self.navproxymodel.setFilterCaseSensitivity( Qt.CaseInsensitive ) self.tablenavigation.setModel( self.navproxymodel ) self.actionPreview.setVisible( False ) self.actionPrint.setVisible( False ) self.updateModels() self.status = True
def filterAcceptsRow(self, index, q_model_index): show = QSortFilterProxyModel.filterAcceptsRow(self, index, q_model_index) if show: source_model = self.sourceModel() source_index = source_model.index(index, 0, q_model_index) key = source_model.itemAt(source_index) if not self.__show_summary_keys and source_model.isSummaryKey(key): show = False elif not self.__show_block_keys and source_model.isBlockKey(key): show = False elif not self.__show_gen_kw_keys and source_model.isGenKWKey(key): show = False elif not self.__show_gen_data_keys and source_model.isGenDataKey(key): show = False elif not self.__show_custom_kw_keys and source_model.isCustomKwKey(key): show = False elif not self.__show_custom_pca_keys and source_model.isCustomPcaKey(key): show = False return show
def __init__(self, model, parent=None, showTable=False): super(SearchPanel, self).__init__(parent) self.tabla = None self.setFocusPolicy(Qt.StrongFocus) self.setEditable(True) # self.setModel( model ) self.setEditable(True) self.completer = QCompleter(self) # always show all completions self.completer.setCompletionMode(QCompleter.UnfilteredPopupCompletion) self.pFilterModel = QSortFilterProxyModel(self) self.pFilterModel.setFilterCaseSensitivity(Qt.CaseInsensitive) self.showTable = showTable if model != None: self.setModel(model) # self.pFilterModel.setSourceModel( model ); self.completer.setModel(self.pFilterModel) self.completerTable = SearchPanelView() self.completer.setPopup(self.completerTable) #Mostrar el Popup en forma de Tabla if self.showTable: self.tabla = SearchPanelView() self.setView(self.tabla) self.setCompleter(self.completer) self.setColumn(1) self.lineEdit().textEdited[unicode].connect( self.pFilterModel.setFilterFixedString if not showTable else self. pFilterModel.setFilterWildcard)
def load_presentations_model(self): # Load Presentation Model self.presentationModel = self.db.get_presentations_model() self.proxy = QSortFilterProxyModel() self.proxy.setSourceModel(self.presentationModel) self.tableView.setModel(self.proxy) self.proxy.setFilterCaseSensitivity(QtCore.Qt.CaseInsensitive) # Fill table whitespace. self.tableView.horizontalHeader().setStretchLastSection(False) self.tableView.horizontalHeader().setResizeMode(1, QHeaderView.Stretch) # Hide the ID field self.tableView.setColumnHidden(0, True) # Map data to widgets self.mapper = QDataWidgetMapper() self.mapper.setModel(self.proxy) self.mapper.addMapping(self.talkDetailsWidget.titleLineEdit, 1) self.mapper.addMapping(self.talkDetailsWidget.presenterLineEdit, 2) self.mapper.addMapping(self.talkDetailsWidget.categoryLineEdit, 4) self.mapper.addMapping(self.talkDetailsWidget.eventLineEdit, 5) self.mapper.addMapping(self.talkDetailsWidget.roomLineEdit, 6) self.mapper.addMapping(self.talkDetailsWidget.descriptionTextEdit, 3) self.mapper.addMapping(self.talkDetailsWidget.dateEdit, 7) self.mapper.addMapping(self.talkDetailsWidget.timeEdit, 8) # Load StringLists self.titleList = QStringList(self.db.get_string_list("Title")) #self.speakerList = QStringList(self.db.get_speaker_list()) #self.categoryList = QStringList(self.db.get_category_list()) #self.eventList = QStringList(self.db.get_event_list()) #self.roomList = QStringList(self.db.get_room_list()) #Disble input self.talkDetailsWidget.disable_input_fields()
class ExtendedComboBox(QComboBox): """Extended class of QComboBox so we can perform a filtering of items. """ def __init__(self, parent=None): super(ExtendedComboBox, self).__init__(parent) self.setFocusPolicy(Qt.StrongFocus) self.setEditable(True) # add a filter model to filter matching items self.pFilterModel = QSortFilterProxyModel(self) self.pFilterModel.setFilterCaseSensitivity(Qt.CaseInsensitive) self.pFilterModel.setSourceModel(self.model()) # add a completer, which uses the filter model self.completer = QCompleter(self.pFilterModel, self) # always show all (filtered) completions self.completer.setCompletionMode(QCompleter.UnfilteredPopupCompletion) self.setCompleter(self.completer) # connect signals self.lineEdit().textEdited[unicode].connect( self.pFilterModel.setFilterFixedString) self.completer.activated.connect(self.on_completer_activated) # on selection of an item from the completer, # select the corresponding item from combobox def on_completer_activated(self, text): if text: index = self.findText(text) self.setCurrentIndex(index) # on model change, update the models of the filter and completer as well def setModel(self, model): super(ExtendedComboBox, self).setModel(model) self.pFilterModel.setSourceModel(model) self.completer.setModel(self.pFilterModel) # on model column change, update the model column of # the filter and completer as well def setModelColumn(self, column): self.completer.setCompletionColumn(column) self.pFilterModel.setFilterKeyColumn(column) super(ExtendedComboBox, self).setModelColumn(column)
class BigList(Ui_BigList, QWidget): itemselected = pyqtSignal(QModelIndex) closewidget = pyqtSignal() savewidget = pyqtSignal() def __init__(self, parent=None): super(BigList, self).__init__(parent) self.setupUi(self) self.listView.clicked.connect(self.selected) self.saveButton.pressed.connect(self.savewidget.emit) self.closebutton.pressed.connect(self.closewidget.emit) self._index = None self.search.textEdited.connect(self.set_filter) self.filtermodel = QSortFilterProxyModel() self.filtermodel.setFilterCaseSensitivity(Qt.CaseInsensitive) self.listView.setModel(self.filtermodel) self.charm = FlickCharm() self.charm.activateOn(self.listView) def set_filter(self, text): self.filtermodel.setFilterRegExp(text + ".*") def selected(self, index): self._index = index self._index = self.filtermodel.mapToSource(index) self.itemselected.emit(self._index) def setmodel(self, model): self.filtermodel.setSourceModel(model) def setlabel(self, fieldname): self.fieldnameLabel.setText(fieldname) def currentindex(self): return self._index def setcurrentindex(self, index): if index is None: index = QModelIndex() if isinstance(index, int): index = self.listView.model().index(index, 0) self.listView.setCurrentIndex(index)
def set_model_by_list(string_list, widget, proxy_model): """ Set the model according to the list """ model = QStringListModel() model.setStringList(string_list) proxy_model.setSourceModel(model) proxy_model.setFilterKeyColumn(0) proxy_model_aux = QSortFilterProxyModel() proxy_model_aux.setSourceModel(model) proxy_model_aux.setFilterKeyColumn(0) widget.setModel(proxy_model_aux) widget.setModelColumn(0) completer = QCompleter() completer.setModel(proxy_model) completer.setCompletionColumn(0) completer.setCompletionMode(QCompleter.UnfilteredPopupCompletion) widget.setCompleter(completer)
class ExtendedCombo(QComboBox): def __init__(self, parent=None): super(ExtendedCombo, self).__init__(parent) self.setFocusPolicy(Qt.StrongFocus) self.setEditable(True) self.completer = QCompleter(self) self.selected_id = None # always show all completions self.completer.setCompletionMode(QCompleter.UnfilteredPopupCompletion ) self.pFilterModel = QSortFilterProxyModel(self) self.pFilterModel.setFilterCaseSensitivity(Qt.CaseInsensitive) self.completer.setPopup(self.view()) self.setCompleter(self.completer) self.lineEdit().textEdited[unicode].connect(self.pFilterModel.setFilterFixedString) self.completer.activated.connect(self.setTextIfCompleterIsClicked) self.currentIndexChanged.connect(self.currentSelected) def setModel( self, model ): super(ExtendedCombo, self).setModel( model ) self.pFilterModel.setSourceModel( model ) self.completer.setModel(self.pFilterModel) def setModelColumn( self, column): self.completer.setCompletionColumn( column ) self.pFilterModel.setFilterKeyColumn( column ) super(ExtendedCombo, self).setModelColumn( column ) def view(self): return self.completer.popup() def index(self): return self.currentIndex() def setTextIfCompleterIsClicked(self, text): if text: index = self.findText(text) self.setCurrentIndex(index) def currentSelected(self, text): if text: self.selected_id = self.currentText()
class ExtendedComboBox(QComboBox): """ Based off the extension of the combo box from below: http://stackoverflow.com/questions/4827207/how-do-i-filter-the-pyqt-qcombobox-items-based-on-the-text-input """ def __init__(self, parent=None): super(ExtendedComboBox, self).__init__(parent) self.setFocusPolicy(Qt.StrongFocus) self.setEditable(True) self.setEditable(True) self.completer = QCompleter(self) # always show all completions self.completer.setCompletionMode(QCompleter.PopupCompletion) self.pFilterModel = QSortFilterProxyModel(self) self.pFilterModel.setFilterCaseSensitivity(Qt.CaseInsensitive) self.completer.setPopup(self.view()) self.setCompleter(self.completer) self.lineEdit().textEdited[unicode].connect( self.pFilterModel.setFilterFixedString) self.completer.activated.connect(self.setTextIfCompleterIsClicked) def setModel(self, model): super(ExtendedComboBox, self).setModel(model) self.pFilterModel.setSourceModel(model) self.completer.setModel(self.pFilterModel) def setModelColumn(self, column): self.completer.setCompletionColumn(column) self.pFilterModel.setFilterKeyColumn(column) super(ExtendedComboBox, self).setModelColumn(column) def view(self): return self.completer.popup() def index(self): return self.currentIndex() def setTextIfCompleterIsClicked(self, text): if text: index = self.findText(text) self.setCurrentIndex(index)
def get_matched_row_list(self, key_column, search_criteria, case_sensitivity): search_proxy = QSortFilterProxyModel() search_proxy.setSourceModel(self.user_interface.tblLogData.model()) search_proxy.setFilterCaseSensitivity(case_sensitivity) search_proxy.setFilterKeyColumn(key_column) if self.is_match_whole_word: search_criteria = r"\b{}\b".format(search_criteria) search_proxy.setFilterRegExp(search_criteria) matched_row_list = [] for proxy_row in range(search_proxy.rowCount()): match_index = search_proxy.mapToSource( search_proxy.index(proxy_row, key_column)) matched_row_list.append(match_index.row()) self.search_criteria_updated = False return matched_row_list
class OWRuleViewer(widget.OWWidget): name = "CN2 Rule Viewer" description = "Review rules induced from data." icon = "icons/CN2RuleViewer.svg" priority = 1140 inputs = [("Data", Table, 'set_data'), ("Classifier", _RuleClassifier, 'set_classifier')] data_output_identifier = "Filtered data" outputs = [(data_output_identifier, Table)] compact_view = settings.Setting(False) want_basic_layout = True want_main_area = True want_control_area = False def __init__(self): self.data = None self.classifier = None self.selected = None self.model = CustomRuleViewerTableModel(parent=self) self.model.set_horizontal_header_labels([ "IF conditions", "", "THEN class", "Distribution", "Probabilities [%]", "Quality", "Length" ]) self.proxy_model = QSortFilterProxyModel(parent=self) self.proxy_model.setSourceModel(self.model) self.proxy_model.setSortRole(self.model.SortRole) self.view = gui.TableView(self, wordWrap=False) self.view.setModel(self.proxy_model) self.view.verticalHeader().setVisible(True) self.view.horizontalHeader().setStretchLastSection(False) self.view.selectionModel().selectionChanged.connect(self.commit) self.dist_item_delegate = DistributionItemDelegate(self) self.view.setItemDelegateForColumn(3, self.dist_item_delegate) self.mainArea.layout().setContentsMargins(0, 0, 0, 0) self.mainArea.layout().addWidget(self.view) bottom_box = gui.hBox(widget=self.mainArea, box=None, margin=0, spacing=0) original_order_button = QPushButton("Restore original order", autoDefault=False) original_order_button.setFixedWidth(180) bottom_box.layout().addWidget(original_order_button) original_order_button.clicked.connect(self.restore_original_order) gui.separator(bottom_box, width=5, height=0) gui.checkBox(widget=bottom_box, master=self, value="compact_view", label="Compact view", callback=self.on_update) self.report_button.setFixedWidth(180) bottom_box.layout().addWidget(self.report_button) def set_data(self, data): self.data = data self.commit() def set_classifier(self, classifier): self.classifier = classifier self.selected = None self.model.clear() if classifier is not None and hasattr(classifier, "rule_list"): self.model.set_vertical_header_labels( list(range(len(classifier.rule_list)))) self.dist_item_delegate.color_schema = \ [QColor(*c) for c in classifier.domain.class_var.colors] self.model.wrap(self.classifier.domain, self.classifier.rule_list) self.on_update() self.commit() def on_update(self): self._save_selected() self.model.set_compact_view(self.compact_view) if self.compact_view: self.view.horizontalHeader().setResizeMode( 0, QHeaderView.Interactive) # QHeaderView.Stretch else: self.view.horizontalHeader().setResizeMode( QHeaderView.ResizeToContents) self.view.resizeColumnsToContents() self.view.resizeRowsToContents() self._restore_selected() def _save_selected(self, actual=False): self.selected = None selection_model = self.view.selectionModel() if selection_model.hasSelection(): selection = (selection_model.selection() if not actual else self.proxy_model.mapSelectionToSource( selection_model.selection())) self.selected = sorted( set(index.row() for index in selection.indexes())) def _restore_selected(self): if self.selected is not None: selection_model = self.view.selectionModel() for row in self.selected: selection_model.select( self.proxy_model.index(row, 0), selection_model.Select | selection_model.Rows) def restore_original_order(self): self.proxy_model.sort(-1) def copy_to_clipboard(self): self._save_selected(actual=True) if self.selected is not None: output = "\n".join( [str(self.classifier.rule_list[i]) for i in self.selected]) QApplication.clipboard().setText(output) def commit(self): data_output = None self._save_selected(actual=True) data = self.data or self.classifier and self.classifier.instances if (self.selected is not None and data is not None and self.classifier is not None and data.domain.attributes == self.classifier.original_domain.attributes): status = np.ones(data.X.shape[0], dtype=bool) for i in self.selected: rule = self.classifier.rule_list[i] status &= rule.evaluate_data(data.X) data_output = data.from_table_rows(data, status.nonzero()[0]) self.send(OWRuleViewer.data_output_identifier, data_output) def send_report(self): if self.classifier is not None: self.report_domain("Data domain", self.classifier.original_domain) self.report_items("Rule induction algorithm", self.classifier.params) self.report_table("Induced rules", self.view) def sizeHint(self): return QSize(800, 450)
def __init__(self, table_data, headers, parent=None, *args): """ Creates two QTableViews one of which is a frozen table while the other one can scroll behind it. :param table_data: The data that goes into the tables :type table_data: List :param headers: The header data of the tables. :type headers: List :param parent: The parent of the QTableView :type parent: QWidget :param args: :type args: """ QTableView.__init__(self, parent) # set the table model self.table_model = BaseSTDMTableModel(table_data, headers, parent) # set the proxy model proxy_model = QSortFilterProxyModel(self) proxy_model.setSourceModel(self.table_model) # Assign a data model for TableView self.setModel(self.table_model) # frozen_table_view - first column self.frozen_table_view = QTableView(self) # Set the model for the widget, fixed column self.frozen_table_view.setModel(self.table_model) # Hide row headers self.frozen_table_view.verticalHeader().hide() # Widget does not accept focus self.frozen_table_view.setFocusPolicy(Qt.StrongFocus | Qt.TabFocus | Qt.ClickFocus) # The user can not resize columns self.frozen_table_view.horizontalHeader().\ setResizeMode(QHeaderView.Fixed) self.frozen_table_view.setObjectName('frozen_table') self.setSelectionMode(QAbstractItemView.NoSelection) self.set_style() # Remove the scroll bar self.frozen_table_view.setHorizontalScrollBarPolicy( Qt.ScrollBarAlwaysOff) self.frozen_table_view.setVerticalScrollBarPolicy( Qt.ScrollBarAlwaysOff) # Puts more widgets to the foreground self.viewport().stackUnder(self.frozen_table_view) # # Log in to edit mode - even with one click # Set the properties of the column headings hh = self.horizontalHeader() # Text alignment centered hh.setDefaultAlignment(Qt.AlignCenter) self.set_column_width() # Set properties header lines vh = self.verticalHeader() vh.setDefaultSectionSize(25) # height lines # text alignment centered vh.setDefaultAlignment(Qt.AlignCenter) vh.setVisible(True) # Height of rows - as in the main widget self.frozen_table_view.verticalHeader().\ setDefaultSectionSize( vh.defaultSectionSize() ) # Show frozen table view self.frozen_table_view.show() # Set the size of him like the main self.setHorizontalScrollMode(QAbstractItemView.ScrollPerPixel) self.setVerticalScrollMode(QAbstractItemView.ScrollPerPixel) self.frozen_table_view.setVerticalScrollMode( QAbstractItemView.ScrollPerPixel) ## select the first column (STR Type) self.frozen_table_view.selectColumn(0) self.frozen_table_view.setEditTriggers( QAbstractItemView.AllEditTriggers) self.set_size() self.signals()
class WatchPointView(QTreeView): " Watch expression viewer widget " def __init__(self, parent, wpointsModel): QTreeView.__init__(self, parent) self.__model = None self.setModel(wpointsModel) self.setItemsExpandable(False) self.setRootIsDecorated(False) self.setAlternatingRowColors(True) self.setUniformRowHeights(True) self.setSelectionMode(QAbstractItemView.SingleSelection) self.setSelectionBehavior(QAbstractItemView.SelectRows) self.setItemDelegate(NoOutlineHeightDelegate(4)) self.setContextMenuPolicy(Qt.CustomContextMenu) self.customContextMenuRequested.connect(self.__showContextMenu) self.doubleClicked.connect(self.__doubleClicked) self.__createPopupMenus() return def setModel(self, model): " Sets the watch expression model " self.__model = model self.sortingModel = QSortFilterProxyModel() self.sortingModel.setSourceModel(self.__model) QTreeView.setModel(self, self.sortingModel) header = self.header() header.setSortIndicator(0, Qt.AscendingOrder) header.setSortIndicatorShown(True) header.setClickable(True) self.setSortingEnabled(True) self.__layoutDisplay() return def __layoutDisplay(self): " Performs the layout operation " self.__resizeColumns() self.__resort() return def __resizeColumns(self): " Resizes the view when items get added, edited or deleted " self.header().resizeSections(QHeaderView.ResizeToContents) self.header().setStretchLastSection(True) return def __resort(self): " Resorts the tree " self.model().sort(self.header().sortIndicatorSection(), self.header().sortIndicatorOrder()) return def __toSourceIndex(self, index): " Converts an index to a source index " return self.sortingModel.mapToSource(index) def __fromSourceIndex(self, sindex): " Converts a source index to an index " return self.sortingModel.mapFromSource(sindex) def __setRowSelected(self, index, selected=True): " Selects a row " if not index.isValid(): return if selected: flags = QItemSelectionModel.SelectionFlags( QItemSelectionModel.ClearAndSelect | QItemSelectionModel.Rows) else: flags = QItemSelectionModel.SelectionFlags( QItemSelectionModel.Deselect | QItemSelectionModel.Rows) self.selectionModel().select(index, flags) return def __createPopupMenus(self): """ Private method to generate the popup menus. """ self.menu = QMenu() self.menu.addAction(self.trUtf8("Add"), self.__addWatchPoint) self.menu.addAction(self.trUtf8("Edit..."), self.__editWatchPoint) self.menu.addSeparator() self.menu.addAction(self.trUtf8("Enable"), self.__enableWatchPoint) self.menu.addAction(self.trUtf8("Enable all"), self.__enableAllWatchPoints) self.menu.addSeparator() self.menu.addAction(self.trUtf8("Disable"), self.__disableWatchPoint) self.menu.addAction(self.trUtf8("Disable all"), self.__disableAllWatchPoints) self.menu.addSeparator() self.menu.addAction(self.trUtf8("Delete"), self.__deleteWatchPoint) self.menu.addAction(self.trUtf8("Delete all"), self.__deleteAllWatchPoints) self.backMenuActions = {} self.backMenu = QMenu() self.backMenu.addAction(self.trUtf8("Add"), self.__addWatchPoint) self.backMenuActions["EnableAll"] = \ self.backMenu.addAction(self.trUtf8("Enable all"), self.__enableAllWatchPoints) self.backMenuActions["DisableAll"] = \ self.backMenu.addAction(self.trUtf8("Disable all"), self.__disableAllWatchPoints) self.backMenuActions["DeleteAll"] = \ self.backMenu.addAction(self.trUtf8("Delete all"), self.__deleteAllWatchPoints) self.backMenu.aboutToShow.connect(self.__showBackMenu) self.multiMenu = QMenu() self.multiMenu.addAction(self.trUtf8("Add"), self.__addWatchPoint) self.multiMenu.addSeparator() self.multiMenu.addAction(self.trUtf8("Enable selected"), self.__enableSelectedWatchPoints) self.multiMenu.addAction(self.trUtf8("Enable all"), self.__enableAllWatchPoints) self.multiMenu.addSeparator() self.multiMenu.addAction(self.trUtf8("Disable selected"), self.__disableSelectedWatchPoints) self.multiMenu.addAction(self.trUtf8("Disable all"), self.__disableAllWatchPoints) self.multiMenu.addSeparator() self.multiMenu.addAction(self.trUtf8("Delete selected"), self.__deleteSelectedWatchPoints) self.multiMenu.addAction(self.trUtf8("Delete all"), self.__deleteAllWatchPoints) return def __showContextMenu(self, coord): """ Private slot to show the context menu. @param coord the position of the mouse pointer (QPoint) """ cnt = self.__getSelectedItemsCount() if cnt <= 1: index = self.indexAt(coord) if index.isValid(): cnt = 1 self.__setRowSelected(index) coord = self.mapToGlobal(coord) if cnt > 1: self.multiMenu.popup(coord) elif cnt == 1: self.menu.popup(coord) else: self.backMenu.popup(coord) def __findDuplicates(self, cond, special, showMessage=False, index=QModelIndex()): " Checks if an entry already exists " cond = unicode(cond) special = unicode(special) idx = self.__model.getWatchPointIndex(cond, special) duplicate = idx.isValid( ) and idx.internalPointer() != index.internalPointer() # if showMessage and duplicate: # if not special: # msg = """<p>A watch expression '<b>%1</b>'""" # """ already exists.</p>""".arg(Utilities.html_encode(unicode(cond))) # else: # msg = self.trUtf8("""<p>A watch expression '<b>%1</b>'""" # """ for the variable <b>%2</b> already exists.</p>""")\ # .arg(special)\ # .arg(Utilities.html_encode(unicode(cond))) # KQMessageBox.warning(None, # self.trUtf8("Watch expression already exists"), # msg) return duplicate def __clearSelection(self): " Clears the selection " for index in self.selectedIndexes(): self.__setRowSelected(index, False) return def __addWatchPoint(self): " Adds watch expression via a context menu entry " # dlg = EditWatchpointDialog( ( "", False, True, 0, "" ), self ) # if dlg.exec_() == QDialog.Accepted: # cond, temp, enabled, ignorecount, special = dlg.getData() # if not self.__findDuplicates(cond, special, True): # self.__model.addWatchPoint(cond, special, (temp, enabled, ignorecount)) # self.__resizeColumns() # self.__resort() return def __doubleClicked(self, index): " Handles the double clicked signal " if index.isValid(): self.__doEditWatchPoint(index) return def __editWatchPoint(self): " Handles the edit watch expression context menu entry " index = self.currentIndex() if index.isValid(): self.__doEditWatchPoint(index) return def __doEditWatchPoint(self, index): " Edits a watch expression " sindex = self.__toSourceIndex(index) if sindex.isValid(): wp = self.__model.getWatchPointByIndex(sindex) if not wp: return cond, special, temp, enabled, count = wp[:5] # dlg = EditWatchpointDialog( # (cond, temp, enabled, count, special), self) # if dlg.exec_() == QDialog.Accepted: # cond, temp, enabled, count, special = dlg.getData() # if not self.__findDuplicates(cond, special, True, sindex): # self.__model.setWatchPointByIndex(sindex, # unicode(cond), unicode(special), (temp, enabled, count)) # self.__resizeColumns() # self.__resort() return def __setWpEnabled(self, index, enabled): " Sets the enabled status of a watch expression " sindex = self.__toSourceIndex(index) if sindex.isValid(): self.__model.setWatchPointEnabledByIndex(sindex, enabled) return def __enableWatchPoint(self): " Handles the enable watch expression context menu entry " index = self.currentIndex() self.__setWpEnabled(index, True) self.__resizeColumns() self.__resort() return def __enableAllWatchPoints(self): " Handles the enable all watch expressions context menu entry " index = self.model().index(0, 0) while index.isValid(): self.__setWpEnabled(index, True) index = self.indexBelow(index) self.__resizeColumns() self.__resort() return def __enableSelectedWatchPoints(self): " Handles the enable selected watch expressions context menu entry " for index in self.selectedIndexes(): if index.column() == 0: self.__setWpEnabled(index, True) self.__resizeColumns() self.__resort() return def __disableWatchPoint(self): " Handles the disable watch expression context menu entry " index = self.currentIndex() self.__setWpEnabled(index, False) self.__resizeColumns() self.__resort() return def __disableAllWatchPoints(self): " Handles the disable all watch expressions context menu entry " index = self.model().index(0, 0) while index.isValid(): self.__setWpEnabled(index, False) index = self.indexBelow(index) self.__resizeColumns() self.__resort() return def __disableSelectedWatchPoints(self): " Handles the disable selected watch expressions context menu entry " for index in self.selectedIndexes(): if index.column() == 0: self.__setWpEnabled(index, False) self.__resizeColumns() self.__resort() return def __deleteWatchPoint(self): " Handles the delete watch expression context menu entry " index = self.currentIndex() sindex = self.__toSourceIndex(index) if sindex.isValid(): self.__model.deleteWatchPointByIndex(sindex) return def __deleteAllWatchPoints(self): " Handles the delete all watch expressions context menu entry " self.__model.deleteAll() return def __deleteSelectedWatchPoints(self): " Handles the delete selected watch expressions context menu entry " idxList = [] for index in self.selectedIndexes(): sindex = self.__toSourceIndex(index) if sindex.isValid() and index.column() == 0: lastrow = index.row() idxList.append(sindex) self.__model.deleteWatchPoints(idxList) return def __showBackMenu(self): " Handles the aboutToShow signal of the background menu " if self.model().rowCount() == 0: self.backMenuActions["EnableAll"].setEnabled(False) self.backMenuActions["DisableAll"].setEnabled(False) self.backMenuActions["DeleteAll"].setEnabled(False) else: self.backMenuActions["EnableAll"].setEnabled(True) self.backMenuActions["DisableAll"].setEnabled(True) self.backMenuActions["DeleteAll"].setEnabled(True) return def __getSelectedItemsCount(self): " Provides the count of items selected " count = len(self.selectedIndexes()) / (self.__model.columnCount() - 1) # column count is 1 greater than selectable return count
def sort(self, column, order): " Sorts the items " self.__sortColumn = column self.__sortOrder = order QSortFilterProxyModel.sort(self, column, order) return
class TalkEditorApp(FreeseerApp): '''Freeseer talk database editor main gui class''' def __init__(self, config, db): super(TalkEditorApp, self).__init__(config) self.db = db icon = QIcon() icon.addPixmap(QPixmap(':/freeseer/logo.png'), QIcon.Normal, QIcon.Off) self.setWindowIcon(icon) self.resize(960, 600) # # Setup Layout # self.mainWidget = QWidget() self.mainLayout = QVBoxLayout() self.mainWidget.setLayout(self.mainLayout) self.setCentralWidget(self.mainWidget) self.mainLayout.setAlignment(Qt.AlignTop) # Add custom widgets self.commandButtons = CommandButtons() self.tableView = QTableView() self.tableView.setSortingEnabled(True) self.tableView.setSelectionBehavior(QAbstractItemView.SelectRows) self.talkDetailsWidget = TalkDetailsWidget() self.importTalksWidget = ImportTalksWidget() self.newTalkWidget = NewTalkWidget() self.mainLayout.addWidget(self.importTalksWidget) #self.mainLayout.addLayout(self.titleLayout) self.mainLayout.addWidget(self.commandButtons) self.mainLayout.addWidget(self.tableView) self.mainLayout.addWidget(self.talkDetailsWidget) self.mainLayout.addWidget(self.importTalksWidget) # --- End Layout # Keep track of index of the most recently selected talk self.currentTalkIndex = QPersistentModelIndex() # Prompt user to "Continue Editing", "Discard Changes" or "Save Changes" self.savePromptBox = QMessageBox() self.savePromptBox.setWindowTitle("Unsaved Changes Exist") self.savePromptBox.setIcon(QMessageBox.Information) self.savePromptBox.setText( "The talk you were editing has unsaved changes.") self.continueButton = self.savePromptBox.addButton( "Continue Editing", QMessageBox.RejectRole) self.discardButton = self.savePromptBox.addButton( "Discard Changes", QMessageBox.DestructiveRole) self.saveButton = self.savePromptBox.addButton("Save Changes", QMessageBox.AcceptRole) self.savePromptBox.setDefaultButton(self.saveButton) # Initialize geometry, to be used for restoring window positioning. self.geometry = None # # Setup Menubar # self.actionExportCsv = QAction(self) self.actionExportCsv.setObjectName('actionExportCsv') self.actionRemoveAll = QAction(self) self.actionRemoveAll.setObjectName('actionRemoveAll') # Actions self.menuFile.insertAction(self.actionExit, self.actionExportCsv) self.menuFile.insertAction(self.actionExit, self.actionRemoveAll) # --- End Menubar # # TableView Connections # self.connect(self.tableView, SIGNAL('activated(const QModelIndex)'), self.click_talk) self.connect(self.tableView, SIGNAL('selected(const QModelIndex)'), self.click_talk) self.connect(self.tableView, SIGNAL('clicked(const QModelIndex)'), self.click_talk) # Import Widget self.connect(self.importTalksWidget.csvRadioButton, SIGNAL('toggled(bool)'), self.toggle_import) self.connect(self.importTalksWidget.importButton, SIGNAL('clicked()'), self.import_talks) self.connect(self.importTalksWidget.cancelButton, SIGNAL('clicked()'), self.hide_import_talks_widget) self.importTalksWidget.setHidden(True) self.connect(self.importTalksWidget.csvFileSelectButton, SIGNAL('clicked()'), self.csv_file_select) self.connect(self.importTalksWidget.csvLineEdit, SIGNAL('returnPressed()'), self.importTalksWidget.importButton.click) self.connect(self.importTalksWidget.rssLineEdit, SIGNAL('returnPressed()'), self.importTalksWidget.importButton.click) self.connect(self.actionExportCsv, SIGNAL('triggered()'), self.export_talks_to_csv) self.connect(self.actionRemoveAll, SIGNAL('triggered()'), self.confirm_reset) # Command Buttons self.connect(self.commandButtons.addButton, SIGNAL('clicked()'), self.click_add_button) self.connect(self.commandButtons.removeButton, SIGNAL('clicked()'), self.remove_talk) self.connect(self.commandButtons.removeAllButton, SIGNAL('clicked()'), self.confirm_reset) self.connect(self.commandButtons.importButton, SIGNAL('clicked()'), self.show_import_talks_widget) self.connect(self.commandButtons.exportButton, SIGNAL('clicked()'), self.export_talks_to_csv) self.connect(self.commandButtons.searchButton, SIGNAL('clicked()'), self.search_talks) self.connect(self.commandButtons.searchLineEdit, SIGNAL('textEdited(QString)'), self.search_talks) self.connect(self.commandButtons.searchLineEdit, SIGNAL('returnPressed()'), self.search_talks) # Talk Details Buttons self.connect(self.talkDetailsWidget.saveButton, SIGNAL('clicked()'), self.update_talk) # Talk Details Widget self.connect(self.talkDetailsWidget.titleLineEdit, SIGNAL('textEdited(const QString)'), self.enable_save) self.connect(self.talkDetailsWidget.presenterLineEdit, SIGNAL('textEdited(const QString)'), self.enable_save) self.connect(self.talkDetailsWidget.categoryLineEdit, SIGNAL('textEdited(const QString)'), self.enable_save) self.connect(self.talkDetailsWidget.eventLineEdit, SIGNAL('textEdited(const QString)'), self.enable_save) self.connect(self.talkDetailsWidget.roomLineEdit, SIGNAL('textEdited(const QString)'), self.enable_save) self.connect(self.talkDetailsWidget.descriptionTextEdit, SIGNAL('modificationChanged(bool)'), self.enable_save) self.connect(self.talkDetailsWidget.dateEdit, SIGNAL('dateChanged(const QDate)'), self.enable_save) self.connect(self.talkDetailsWidget.startTimeEdit, SIGNAL('timeChanged(const QTime)'), self.enable_save) self.connect(self.talkDetailsWidget.endTimeEdit, SIGNAL('timeChanged(const QTime)'), self.enable_save) # New Talk Widget self.newTalkWidget.connect(self.newTalkWidget.addButton, SIGNAL('clicked()'), self.add_talk) self.newTalkWidget.connect(self.newTalkWidget.cancelButton, SIGNAL('clicked()'), self.newTalkWidget.reject) # Load default language actions = self.menuLanguage.actions() for action in actions: if action.data().toString() == self.config.default_language: action.setChecked(True) self.translate(action) break # Load Talk Database self.load_presentations_model() # Setup Autocompletion self.update_autocomplete_fields() self.talkDetailsWidget.saveButton.setEnabled(False) # Select first item #self.tableView.setCurrentIndex(self.proxy.index(0,0)) #self.talk_selected(self.proxy.index(0,0)) # # Translation # def retranslate(self): self.setWindowTitle( self.app.translate("TalkEditorApp", "Freeseer Talk Editor")) # # Reusable Strings # self.confirmDBClearTitleString = self.app.translate( "TalkEditorApp", "Remove All Talks from Database") self.confirmDBClearQuestionString = self.app.translate( "TalkEditorApp", "Are you sure you want to clear the DB?") self.confirmTalkDetailsClearTitleString = self.app.translate( "TalkEditorApp", "Unsaved Data") self.confirmTalkDetailsClearQuestionString = self.app.translate( "TalkEditorApp", "Unsaved talk details will be lost. Continue?") # --- End Reusable Strings # # Menubar # self.actionExportCsv.setText( self.app.translate("TalkEditorApp", "&Export to CSV")) self.actionRemoveAll.setText( self.app.translate("TalkEditorApp", "&Remove All Talks")) # --- End Menubar # # TalkDetailsWidget # self.talkDetailsWidget.titleLabel.setText( self.app.translate("TalkEditorApp", "Title")) self.talkDetailsWidget.presenterLabel.setText( self.app.translate("TalkEditorApp", "Presenter")) self.talkDetailsWidget.categoryLabel.setText( self.app.translate("TalkEditorApp", "Category")) self.talkDetailsWidget.eventLabel.setText( self.app.translate("TalkEditorApp", "Event")) self.talkDetailsWidget.roomLabel.setText( self.app.translate("TalkEditorApp", "Room")) self.talkDetailsWidget.dateLabel.setText( self.app.translate("TalkEditorApp", "Date")) self.talkDetailsWidget.startTimeLabel.setText( self.app.translate("TalkEditorApp", "Start Time")) self.talkDetailsWidget.endTimeLabel.setText( self.app.translate("TalkEditorApp", "End Time")) # --- End TalkDetailsWidget # # Import Talks Widget Translations # self.importTalksWidget.rssRadioButton.setText( self.app.translate("TalkEditorApp", "RSS URL")) self.importTalksWidget.csvRadioButton.setText( self.app.translate("TalkEditorApp", "CSV File")) self.importTalksWidget.importButton.setText( self.app.translate("TalkEditorApp", "Import")) # --- End Talks Widget Translations # # Command Button Translations\ # self.commandButtons.importButton.setText( self.app.translate("TalkEditorApp", "Import")) self.commandButtons.exportButton.setText( self.app.translate("TalkEditorApp", "Export")) self.commandButtons.addButton.setText( self.app.translate("TalkEditorApp", "Add New Talk")) self.commandButtons.removeButton.setText( self.app.translate("TalkEditorApp", "Remove")) self.commandButtons.removeAllButton.setText( self.app.translate("TalkEditorApp", "Remove All")) # --- End Command Butotn Translations # # Search Widget Translations # self.commandButtons.searchButton.setText( self.app.translate("TalkEditorApp", "Search")) # --- End Command Button Translations def load_presentations_model(self): # Load Presentation Model self.presentationModel = self.db.get_presentations_model() self.proxy = QSortFilterProxyModel() self.proxy.setSourceModel(self.presentationModel) self.tableView.setModel(self.proxy) self.proxy.setFilterCaseSensitivity(Qt.CaseInsensitive) # Fill table whitespace. self.tableView.horizontalHeader().setStretchLastSection(False) self.tableView.horizontalHeader().setResizeMode(1, QHeaderView.Stretch) # Hide the ID field self.tableView.setColumnHidden(0, True) # Map data to widgets self.mapper = QDataWidgetMapper() self.mapper.setModel(self.proxy) self.mapper.setSubmitPolicy(QDataWidgetMapper.ManualSubmit) self.mapper.addMapping(self.talkDetailsWidget.titleLineEdit, 1) self.mapper.addMapping(self.talkDetailsWidget.presenterLineEdit, 2) self.mapper.addMapping(self.talkDetailsWidget.categoryLineEdit, 4) self.mapper.addMapping(self.talkDetailsWidget.eventLineEdit, 5) self.mapper.addMapping(self.talkDetailsWidget.roomLineEdit, 6) self.mapper.addMapping(self.talkDetailsWidget.descriptionTextEdit, 3) self.mapper.addMapping(self.talkDetailsWidget.dateEdit, 7) self.mapper.addMapping(self.talkDetailsWidget.startTimeEdit, 8) self.mapper.addMapping(self.talkDetailsWidget.endTimeEdit, 9) # Load StringLists self.titleList = QStringList(self.db.get_string_list("Title")) #self.speakerList = QStringList(self.db.get_speaker_list()) #self.categoryList = QStringList(self.db.get_category_list()) #self.eventList = QStringList(self.db.get_event_list()) #self.roomList = QStringList(self.db.get_room_list()) #Disble input self.talkDetailsWidget.disable_input_fields() def search_talks(self): # The default value is 0. If the value is -1, the keys will be read from all columns. self.proxy.setFilterKeyColumn(-1) self.proxy.setFilterFixedString( self.commandButtons.searchLineEdit.text()) def show_save_prompt(self): """Prompts the user to save or discard changes, or continue editing.""" self.savePromptBox.exec_() self.savePromptBox.setDefaultButton(self.saveButton) return self.savePromptBox.clickedButton() def click_talk(self, model): """Warns user if there are unsaved changes, and selects talk clicked by the user.""" log.info("Selecting row %d", model.row()) modelRow = model.row() if self.unsaved_details_exist(): log.info("Unsaved changes exist in row %d", self.currentTalkIndex.row()) confirm = self.show_save_prompt() if confirm == self.saveButton: log.info("Saving changes in row %d...", self.currentTalkIndex.row()) self.tableView.selectRow(self.currentTalkIndex.row()) self.update_talk() newModel = self.tableView.currentIndex().sibling(modelRow, 0) self.select_talk(newModel) elif confirm == self.discardButton: log.info("Discarding changes in row %d...", self.currentTalkIndex.row()) self.talk_selected(model) else: log.info("Continue editing row %d", self.currentTalkIndex.row()) self.tableView.selectRow(self.currentTalkIndex.row()) else: self.talk_selected(model) def click_add_button(self): """Warns user if there are unsaved changes, and shows the New Talk window.""" if self.unsaved_details_exist(): log.info("Unsaved changes exist in row %d", self.currentTalkIndex.row()) confirm = self.show_save_prompt() if confirm == self.saveButton: log.info("Saving changes in row %d...", self.currentTalkIndex.row()) self.update_talk() self.show_new_talk_popup() elif confirm == self.discardButton: log.info("Discarding changes in row %d...", self.currentTalkIndex.row()) # Ensure that changes are discarded self.talk_selected(self.currentTalkIndex) self.show_new_talk_popup() else: log.info("Continue editing row %d", self.currentTalkIndex.row()) else: self.show_new_talk_popup() def talk_selected(self, model): self.mapper.setCurrentIndex(model.row()) self.talkDetailsWidget.enable_input_fields() self.talkDetailsWidget.saveButton.setEnabled(False) self.currentTalkIndex = QPersistentModelIndex(model) def toggle_import(self): if self.importTalksWidget.csvRadioButton.isChecked(): self.importTalksWidget.csvLineEdit.setEnabled(True) self.importTalksWidget.csvFileSelectButton.setEnabled(True) self.importTalksWidget.rssLineEdit.setEnabled(False) else: self.importTalksWidget.csvLineEdit.setEnabled(False) self.importTalksWidget.csvFileSelectButton.setEnabled(False) self.importTalksWidget.rssLineEdit.setEnabled(True) def show_import_talks_widget(self): self.commandButtons.setHidden(True) self.tableView.setHidden(True) self.talkDetailsWidget.setHidden(True) self.importTalksWidget.setHidden(False) def hide_import_talks_widget(self): self.commandButtons.setHidden(False) self.tableView.setHidden(False) self.talkDetailsWidget.setHidden(False) self.importTalksWidget.setHidden(True) def add_talk(self): """Adds a new talk to the database using data from the NewTalkWidget input fields""" presentation = self.create_presentation( self.newTalkWidget.talkDetailsWidget) if presentation: self.db.insert_presentation(presentation) self.newTalkWidget.accept() # Close the dialog def update_talk(self): """Updates the currently selected talk using data from the TalkEditorApp input fields""" selected_talk = self.tableView.currentIndex() if selected_talk.row( ) >= 0: # The tableView index begins at 0 and is -1 by default talk_id = selected_talk.sibling(selected_talk.row(), 0).data().toString() presentation = self.create_presentation(self.talkDetailsWidget) if presentation: self.db.update_presentation(talk_id, presentation) self.apply_changes(selected_talk) self.talkDetailsWidget.saveButton.setEnabled(False) def create_presentation(self, talkDetailsWidget): """Creates and returns an instance of Presentation using data from the input fields""" date = talkDetailsWidget.dateEdit.date() startTime = talkDetailsWidget.startTimeEdit.time() endTime = talkDetailsWidget.endTimeEdit.time() title = unicode(talkDetailsWidget.titleLineEdit.text()).strip() if title: return Presentation( unicode(talkDetailsWidget.titleLineEdit.text()).strip(), unicode(talkDetailsWidget.presenterLineEdit.text()).strip(), unicode(talkDetailsWidget.descriptionTextEdit.toPlainText()). strip(), unicode(talkDetailsWidget.categoryLineEdit.text()).strip(), unicode(talkDetailsWidget.eventLineEdit.text()).strip(), unicode(talkDetailsWidget.roomLineEdit.text()).strip(), unicode(date.toString(Qt.ISODate)), unicode(startTime.toString(Qt.ISODate)), unicode(endTime.toString(Qt.ISODate))) def show_new_talk_popup(self): """Displays a modal dialog with a talk details view When Add is selected, a new talk is added to the database using the input field data. When Cancel is selected, no talk is added. """ log.info('Opening Add Talk window...') self.clear_new_talk_fields() self.remove_new_talk_placeholder_text() self.newTalkWidget.talkDetailsWidget.titleLineEdit.setFocus() if self.newTalkWidget.exec_() == 1: self.apply_changes() self.talkDetailsWidget.disable_input_fields() else: log.info('No talk added...') def apply_changes(self, updated_talk=None): """Repopulates the model to display the effective changes Updates the autocomplete fields. Displays the updated model in the table view, and selects the newly updated/added talk. """ self.presentationModel.select() self.select_talk(updated_talk) self.update_autocomplete_fields() def select_talk(self, talk=None): """Selects the given talk in the table view If no talk is given, the last row in the table view is selected. """ if talk: row = talk.row() column = talk.column() else: row = self.presentationModel.rowCount() - 1 # Select last row column = 0 self.tableView.selectRow(row) self.tableView.setCurrentIndex(self.proxy.index(row, column)) self.talk_selected(self.proxy.index(row, column)) def remove_talk(self): try: rows_selected = self.tableView.selectionModel().selectedRows() except: return # Reversed because rows in list change position once row is removed for row in reversed(rows_selected): self.presentationModel.removeRow(row.row()) self.talkDetailsWidget.clear_input_fields() self.talkDetailsWidget.disable_input_fields() def load_talk(self): try: self.tableView.currentIndex().row() except: return self.mapper.addMapping(self.talkDetailsWidget.roomLineEdit, 6) self.presentationModel.select() def reset(self): self.db.clear_database() self.presentationModel.select() self.talkDetailsWidget.clear_input_fields() self.talkDetailsWidget.disable_input_fields() def confirm_reset(self): """Presents a confirmation dialog to ask the user if they are sure they wish to remove the talk database. If Yes call the reset() function""" confirm = QMessageBox.question(self, self.confirmDBClearTitleString, self.confirmDBClearQuestionString, QMessageBox.Yes | QMessageBox.No, QMessageBox.No) if confirm == QMessageBox.Yes: self.reset() def add_talks_from_rss(self): rss_url = unicode(self.importTalksWidget.rssLineEdit.text()) if rss_url: self.db.add_talks_from_rss(rss_url) self.presentationModel.select() self.hide_import_talks_widget() else: error = QMessageBox() error.setText("Please enter a RSS URL") error.exec_() def closeEvent(self, event): if self.unsaved_details_exist(): log.info("Unsaved changes exist in row %d", self.currentTalkIndex.row()) confirm = self.show_save_prompt() if confirm == self.saveButton: log.info("Saving changes in row %d...", self.currentTalkIndex.row()) self.update_talk() log.info('Exiting talk database editor...') self.geometry = self.saveGeometry() event.accept() elif confirm == self.discardButton: log.info("Discarding changes in row %d...", self.currentTalkIndex.row()) # Ensure that changes are discarded self.talk_selected(self.currentTalkIndex) log.info('Exiting talk database editor...') self.geometry = self.saveGeometry() event.accept() else: log.info("Continue editing row %d", self.currentTalkIndex.row()) event.ignore() else: log.info('Exiting talk database editor...') self.geometry = self.saveGeometry() event.accept() def csv_file_select(self): fname = QFileDialog.getOpenFileName(self, 'Select file', "", "*.csv") if fname: self.importTalksWidget.csvLineEdit.setText(fname) def add_talks_from_csv(self): fname = self.importTalksWidget.csvLineEdit.text() if fname: self.db.add_talks_from_csv(fname) self.presentationModel.select() self.hide_import_talks_widget() else: error = QMessageBox() error.setText("Please select a file") error.exec_() def import_talks(self): if self.importTalksWidget.csvRadioButton.isChecked(): self.add_talks_from_csv() else: self.add_talks_from_rss() self.update_autocomplete_fields() def export_talks_to_csv(self): fname = QFileDialog.getSaveFileName(self, 'Select file', "", "*.csv") if fname: self.db.export_talks_to_csv(fname) def update_autocomplete_fields(self): self.titleList = QStringList(self.db.get_string_list("Title")) self.speakerList = QStringList(self.db.get_string_list("Speaker")) self.categoryList = QStringList(self.db.get_string_list("Category")) self.eventList = QStringList(self.db.get_string_list("Event")) self.roomList = QStringList(self.db.get_string_list("Room")) self.titleCompleter = QCompleter(self.titleList) self.titleCompleter.setCaseSensitivity(Qt.CaseInsensitive) self.speakerCompleter = QCompleter(self.speakerList) self.speakerCompleter.setCaseSensitivity(Qt.CaseInsensitive) self.categoryCompleter = QCompleter(self.categoryList) self.categoryCompleter.setCaseSensitivity(Qt.CaseInsensitive) self.eventCompleter = QCompleter(self.eventList) self.eventCompleter.setCaseSensitivity(Qt.CaseInsensitive) self.roomCompleter = QCompleter(self.roomList) self.roomCompleter.setCaseSensitivity(Qt.CaseInsensitive) self.talkDetailsWidget.titleLineEdit.setCompleter(self.titleCompleter) self.talkDetailsWidget.presenterLineEdit.setCompleter( self.speakerCompleter) self.talkDetailsWidget.categoryLineEdit.setCompleter( self.categoryCompleter) self.talkDetailsWidget.eventLineEdit.setCompleter(self.eventCompleter) self.talkDetailsWidget.roomLineEdit.setCompleter(self.roomCompleter) def are_fields_enabled(self): return (self.talkDetailsWidget.titleLineEdit.isEnabled() and self.talkDetailsWidget.presenterLineEdit.isEnabled() and self.talkDetailsWidget.categoryLineEdit.isEnabled() and self.talkDetailsWidget.eventLineEdit.isEnabled() and self.talkDetailsWidget.roomLineEdit.isEnabled() and self.talkDetailsWidget.dateEdit.isEnabled() and self.talkDetailsWidget.startTimeEdit.isEnabled() and self.talkDetailsWidget.endTimeEdit.isEnabled()) def unsaved_details_exist(self): """Checks if changes have been made to new/existing talk details Looks for text in the input fields and check the enabled state of the Save Talk button If the Save Talk button is enabled, the input fields contain modified values """ return (self.talkDetailsWidget.saveButton.isEnabled() and (self.talkDetailsWidget.titleLineEdit.text() or self.talkDetailsWidget.presenterLineEdit.text() or self.talkDetailsWidget.categoryLineEdit.text() or self.talkDetailsWidget.descriptionTextEdit.toPlainText())) def enable_save(self): self.talkDetailsWidget.saveButton.setEnabled(True) def clear_new_talk_fields(self): """Removes existing data from all NewTalkWidget fields except event, room, date and time""" self.newTalkWidget.talkDetailsWidget.titleLineEdit.clear() self.newTalkWidget.talkDetailsWidget.presenterLineEdit.clear() self.newTalkWidget.talkDetailsWidget.descriptionTextEdit.clear() self.newTalkWidget.talkDetailsWidget.categoryLineEdit.clear() def remove_new_talk_placeholder_text(self): """Removes placeholder text in NewTalkWidget originally set by TalkDetailsWidget""" self.newTalkWidget.talkDetailsWidget.titleLineEdit.setPlaceholderText( "") self.newTalkWidget.talkDetailsWidget.presenterLineEdit.setPlaceholderText( "") self.newTalkWidget.talkDetailsWidget.categoryLineEdit.setPlaceholderText( "") self.newTalkWidget.talkDetailsWidget.eventLineEdit.setPlaceholderText( "") self.newTalkWidget.talkDetailsWidget.roomLineEdit.setPlaceholderText( "")
def sourceModel(self): """ @rtype: DataTypeKeysListModel """ return QSortFilterProxyModel.sourceModel(self)
def headerData(self, section, orientation, role): if orientation != Qt.Vertical or role != Qt.DisplayRole: return QSortFilterProxyModel.headerData(self, section, orientation, role) return section+1
def __init__(self): QSortFilterProxyModel.__init__(self) self.toggle_mode_sig.connect(self.toggle_mode)
def __init__(self, parent=None): """ initialize the widget """ QDialog.__init__(self, parent) Ui_FileDialog.__init__(self) self.setupUi(self) #flags = 0 #flags = Qt.Window | Qt.WindowMinimizeButtonHint; #self.setWindowFlags( flags ) self.hideTckFilter() self.__controler = ControlerFileDialog(self, parent.getControler()) self.connect(self.closeButton, SIGNAL("clicked()"), self.__controler.close) self.connect(self.saveButton, SIGNAL("clicked()"), self.__controler.save) self.connect(self.advancedSave, SIGNAL("clicked()"), self.__controler.advancedSave) self.connect(self.nextButton, SIGNAL("clicked()"), self.__controler.next) self.__model = {} self.__path = None self.__fileExtension = None self.__popUp = QMenu(self.tableView) self.__jobAction = QAction(self.tr("Job Info"), self.tableView) self.connect(self.__jobAction, SIGNAL("triggered()"), self.__controler.jobinfo) self.__popUp.addAction(self.__jobAction) self.__ancesstorsAction = QAction(self.tr("Get Anccestors"), self.tableView) self.connect(self.__ancesstorsAction, SIGNAL("triggered()"), self.__controler.getancesstots) self.__popUp.addAction(self.__ancesstorsAction) self.__loginfoAction = QAction(self.tr("Logginig informations"), self.tableView) self.connect(self.__loginfoAction, SIGNAL("triggered()"), self.__controler.loggininginfo) self.__popUp.addAction(self.__loginfoAction) self.__copyAction = QAction(self.tr("Copy data"), self.tableView) self.connect(self.__copyAction, SIGNAL("triggered()"), self.__controler.copy) self.__popUp.addAction(self.__copyAction) self.tableView.setContextMenuPolicy(Qt.CustomContextMenu) self.connect(self.tableView, SIGNAL('customContextMenuRequested(QPoint)'), self.popUpMenu) self.__advancedSave = AdvancedSave(self) self.__advancedSave.setFocus() self.__controler.addChild('AdvancedSave', self.__advancedSave.getControler()) self.__historyDialog = HistoryDialog(self) self.__controler.addChild('HistoryDialog', self.__historyDialog.getControler()) self.connect(self.tckcombo, SIGNAL('currentIndexChanged(QString)'), self.getControler().tckChanged) self.__proxy = QSortFilterProxyModel() self.connect(self.tckButton, SIGNAL("clicked()"), self.__controler.tckButtonPressed) self.connect(self.tckcloseButton, SIGNAL("clicked()"), self.__controler.hideFilterWidget) self.filterWidget.setupControler(self) self.__controler.addChild('TckFilterWidget', self.filterWidget.getControler())
class FileDialog(QDialog, Ui_FileDialog): """ FileDialog class """ ############################################################################# def __init__(self, parent=None): """ initialize the widget """ QDialog.__init__(self, parent) Ui_FileDialog.__init__(self) self.setupUi(self) #flags = 0 #flags = Qt.Window | Qt.WindowMinimizeButtonHint; #self.setWindowFlags( flags ) self.hideTckFilter() self.__controler = ControlerFileDialog(self, parent.getControler()) self.connect(self.closeButton, SIGNAL("clicked()"), self.__controler.close) self.connect(self.saveButton, SIGNAL("clicked()"), self.__controler.save) self.connect(self.advancedSave, SIGNAL("clicked()"), self.__controler.advancedSave) self.connect(self.nextButton, SIGNAL("clicked()"), self.__controler.next) self.__model = {} self.__path = None self.__fileExtension = None self.__popUp = QMenu(self.tableView) self.__jobAction = QAction(self.tr("Job Info"), self.tableView) self.connect(self.__jobAction, SIGNAL("triggered()"), self.__controler.jobinfo) self.__popUp.addAction(self.__jobAction) self.__ancesstorsAction = QAction(self.tr("Get Anccestors"), self.tableView) self.connect(self.__ancesstorsAction, SIGNAL("triggered()"), self.__controler.getancesstots) self.__popUp.addAction(self.__ancesstorsAction) self.__loginfoAction = QAction(self.tr("Logginig informations"), self.tableView) self.connect(self.__loginfoAction, SIGNAL("triggered()"), self.__controler.loggininginfo) self.__popUp.addAction(self.__loginfoAction) self.__copyAction = QAction(self.tr("Copy data"), self.tableView) self.connect(self.__copyAction, SIGNAL("triggered()"), self.__controler.copy) self.__popUp.addAction(self.__copyAction) self.tableView.setContextMenuPolicy(Qt.CustomContextMenu) self.connect(self.tableView, SIGNAL('customContextMenuRequested(QPoint)'), self.popUpMenu) self.__advancedSave = AdvancedSave(self) self.__advancedSave.setFocus() self.__controler.addChild('AdvancedSave', self.__advancedSave.getControler()) self.__historyDialog = HistoryDialog(self) self.__controler.addChild('HistoryDialog', self.__historyDialog.getControler()) self.connect(self.tckcombo, SIGNAL('currentIndexChanged(QString)'), self.getControler().tckChanged) self.__proxy = QSortFilterProxyModel() self.connect(self.tckButton, SIGNAL("clicked()"), self.__controler.tckButtonPressed) self.connect(self.tckcloseButton, SIGNAL("clicked()"), self.__controler.hideFilterWidget) self.filterWidget.setupControler(self) self.__controler.addChild('TckFilterWidget', self.filterWidget.getControler()) ############################################################################# def closeEvent(self, event): """handles the close action""" gLogger.debug(event) self.getControler().close() ############################################################################# def getControler(self): """returns the controller""" return self.__controler ############################################################################# def setModel(self, model): """sets the model""" self.__model = model def updateModel(self, model): """updates the model in case of change""" self.__model.update(model) ############################################################################# def getModel(self): """returns the model""" return self.__model ############################################################################# def setPath(self, path): """sets the path""" self.__path = path ############################################################################# def getPath(self): """returns the path""" return self.__path ############################################################################# def showNumberOfEvents(self, number): """shows the number of events""" self.lineEdit_2.setText(str(number)) ############################################################################# def showNumberOfFiles(self, number): """shows the number of files""" self.lineEdit.setText(str(number)) ############################################################################# def showEventInputStat(self, number): """shows the number of processed input events""" self.alleventinputstat.setText(str(number)) ############################################################################# def showFilesSize(self, number): """shows the size of the files""" self.lineEdit_5.setText(str(number) + ' GB') ############################################################################# def showSelectedNumberOfEvents(self, number): """shows the selected number of events""" self.lineEdit_4.setText(str(number)) ############################################################################# def showSelectedEventInputStat(self, number): """shows the selected processed input events""" self.eventInputstat.setText(str(number)) ############################################################################# def showSelectedNumberOfFiles(self, number): """shoes the selected number of files""" self.lineEdit_3.setText(str(number)) ############################################################################# def showSelectedFileSize(self, number): """shows the selected file size""" self.lineEdit_6.setText(str(number) + ' GB') ############################################################################# def showTotalLuminosity(self, number): """shows the total luminosity""" self.alltotalluminosity.setText(str(number)) ############################################################################# def showSelectedTotalLuminosity(self, number): """selected total luminosity""" self.totalluminosity.setText(str(number)) ############################################################################# def showLuminosity(self, number): """luminosity""" self.allluminosity.setText(str(number)) ############################################################################# def showSelectedLuminosity(self, number): """selected luminosity""" self.luminosity.setText(str(number)) ############################################################################# def showError(self, message): """shows the message as an ERROR""" QMessageBox.critical(self, "ERROR", message, QMessageBox.Ok) ############################################################################# def showData(self, data): """shows the files in the table widget""" self.waitCursor() tabledata = [] header = [ 'FileName', 'EventStat', 'FileSize', 'CreationDate', 'JobStart', 'JobEnd', 'WorkerNode', 'RunNumber', 'FillNumber', 'FullStat', 'DataqualityFlag', 'EventInputStat', 'TotalLuminosity', 'Luminosity', 'InstLuminosity', 'TCK' ] data.update(self.__model) keys = data.keys() keys.sort() for item in keys: lfn = data[item] i = [] for info in header: value = lfn[info] if value == None: value = '' i += [value] tabledata += [i] if len(tabledata) > 0: self.filltable(header, tabledata) self.arrowCursor() return True ############################################################################# def filltable(self, header, tabledata): """ fill the table widget""" # set the table model tm = TableModel(tabledata, header, self) self.__proxy.setSourceModel(tm) self.tableView.setModel(self.__proxy) self.tableView.setSelectionBehavior(QAbstractItemView.SelectRows) self.tableView.setSelectionMode(QAbstractItemView.ExtendedSelection) self.tableView.setAlternatingRowColors(True) sm = self.tableView.selectionModel() self.connect( sm, SIGNAL("selectionChanged(QItemSelection, QItemSelection)"), self.__controler.selection) # set the minimum size self.setMinimumSize(400, 300) # hide grid self.tableView.setShowGrid(True) # set the font #font = QFont("Courier New", 12) #self.tableView.setFont(font) # hide vertical header vh = self.tableView.verticalHeader() vh.setVisible(True) # set horizontal header properties hh = self.tableView.horizontalHeader() hh.setStretchLastSection(True) # set column width to fit contents self.tableView.resizeColumnsToContents() self.tableView.setSortingEnabled(True) # set row height nrows = len(tabledata) for row in xrange(nrows): self.tableView.setRowHeight(row, 18) self.__proxy.sort(0, Qt.AscendingOrder) # enable sorting # this doesn't work #tv.setSortingEnabled(True) ############################################################################# def saveAs(self, filename=''): """saves the selected files""" saveDialog = QFileDialog( self, 'Feicim Save file(s) dialog', QDir.currentPath(), 'Python option(*.py);;Option file (*.opts);;Text file (*.txt);;CSV (*.csv)' ) saveDialog.setAcceptMode(QFileDialog.AcceptSave) saveDialog.selectFile(filename) #self.connect(saveDialog, SIGNAL("filterSelected(const QString &)"),self.filter ) ##saveDialog.setDirectory (QDir.currentPath()) #filters = ['Option file (*.opts)' ,'Pool xml file (*.xml)','*.txt'] #filters = ['Option file (*.opts)','*.py','*.txt'] #saveDialog.setFilter(';;'.join(filters)) #saveDialog.setFilter('Option file (*.opts);;Text file (*.txt);;Python option') #saveDialog.setFileMode(QFileDialog.AnyFile) #saveDialog.setViewMode(QFileDialog.Detail) ext = '' if saveDialog.exec_(): filename = str(saveDialog.selectedFiles()[0]) ext = saveDialog.selectedFilter() if 'Text file (*.txt)' in ext: if not filename.endswith('.txt'): filename += '.txt' elif 'Option file (*.opts)' in ext: if not filename.endswith('.opts'): filename += '.opts' elif 'Python option(*.py)' in ext: if not filename.endswith('.py'): filename += '.py' elif 'CSV (*.csv)' in ext: if not filename.endswith('.csv'): filename += '.csv' try: open(filename) except IOError: pass else: response = QMessageBox.warning(self, "File dialog", "File exists, overwrite?", QMessageBox.Ok, QMessageBox.No) if response == QMessageBox.No: filename = '' if filename == '': return '', '' return filename, ext ############################################################################# def popUpMenu(self): """shows the popup menu""" self.__popUp.popup(QCursor.pos()) ############################################################################# def showSelection(self, in_dict): """ shows the Bookkeeping query, the selected dataset""" if in_dict.has_key('ConfigName'): self.configname.setText(in_dict["ConfigName"]) if in_dict.has_key('ConfigVersion'): self.configversion.setText(in_dict["ConfigVersion"]) if in_dict.has_key('ConditionDescription'): self.simulation.setText(in_dict["ConditionDescription"]) if in_dict.has_key('ProcessingPass'): self.processing.setText(in_dict["ProcessingPass"]) if in_dict.has_key('EventTypeId'): self.eventtype.setText(in_dict["EventTypeId"]) if in_dict.has_key('Production'): self.production.setText('') if in_dict.has_key('FileType'): self.filetype.setText(in_dict["FileType"]) self.progrnameandversion.setText('') ############################################################################# def clearTable(self): """clear the elements from the table""" #self.tableView().clear() self.__model = {} ############################################################################# def fillTckFilter(self, data): """fills the tck combo box""" tcks = data + ['All'] self.tckcombo.clear() j = 0 for i in tcks: self.tckcombo.addItem(i, QVariant(i)) if i == 'All': self.tckcombo.setCurrentIndex(j) j += 1 #self.tckcombo.view().setSelectionMode(QAbstractItemView.MultiSelection) ############################################################################# def applyFilter(self, data): """performs filter over the files""" if data == 'All': gLogger.debug('applyFilter-ALL') self.__proxy.clear() self.__proxy.invalidateFilter() filterCondition = "^\\S+$" gLogger.debug('Filter condition:' + filterCondition) self.__proxy.setFilterKeyColumn(15) self.__proxy.setFilterRegExp(filterCondition) for row in xrange(self.__proxy.rowCount()): self.tableView.setRowHeight(row, 18) else: gLogger.debug('applyFilter-Selected') self.__proxy.setFilterKeyColumn(15) filterCondition = '%s' % (data) gLogger.debug('Filter condition:' + filterCondition) self.__proxy.setFilterRegExp(filterCondition) for row in xrange(self.__proxy.rowCount()): self.tableView.setRowHeight(row, 18) def applyListFilter(self, data): """specific filter""" gLogger.debug('applyListFilter') filterCondition = '\\b' cond = '(' for i in data: cond += i cond += '|' cond = cond[:-1] filterCondition += cond + ')\\b' gLogger.debug('Filter condition:' + filterCondition) self.__proxy.setFilterKeyColumn(15) self.__proxy.setFilterRegExp(filterCondition) for row in xrange(self.__proxy.rowCount()): self.tableView.setRowHeight(row, 18) ############################################################################# def showTckFilter(self): """shows the tcks""" self.tckButton.hide() self.tckcloseButton.show() self.tckcombo.hide() self.filterWidget.show() ############################################################################# def hideTckFilter(self): """hides the tcks""" self.tckButton.show() self.tckcloseButton.hide() self.tckcombo.show() self.filterWidget.hide() ############################################################################# def getLFNs(self): """returns the lfns""" lfns = [] for row in xrange(self.__proxy.rowCount()): index = self.__proxy.index( row, 0) # this add the files to my selected list lfns += [str(self.__proxy.data(index).toString())] return lfns ############################################################################# def waitCursor(self): """shows the wait cursor""" self.setCursor(Qt.WaitCursor) ############################################################################# def arrowCursor(self): """shows the normal cursor""" self.setCursor(Qt.ArrowCursor)
def main(icon_spec): app = QApplication(sys.argv) main_window = QMainWindow() def sigint_handler(*args): main_window.close() signal.signal(signal.SIGINT, sigint_handler) # the timer enables triggering the sigint_handler signal_timer = QTimer() signal_timer.start(100) signal_timer.timeout.connect(lambda: None) tool_bar = QToolBar() main_window.addToolBar(Qt.TopToolBarArea, tool_bar) table_view = QTableView() table_view.setSelectionBehavior(QAbstractItemView.SelectRows) table_view.setSelectionMode(QAbstractItemView.SingleSelection) table_view.setSortingEnabled(True) main_window.setCentralWidget(table_view) proxy_model = QSortFilterProxyModel() proxy_model.setFilterCaseSensitivity(Qt.CaseInsensitive) proxy_model.setFilterKeyColumn(1) table_view.setModel(proxy_model) proxy_model.layoutChanged.connect(table_view.resizeRowsToContents) item_model = QStandardItemModel() proxy_model.setSourceModel(item_model) # get all icons and their available sizes QIcon.setThemeName("gnome") icons = [] all_sizes = set([]) for context, icon_names in icon_spec: for icon_name in icon_names: icon = QIcon.fromTheme(icon_name) sizes = [] for size in icon.availableSizes(): size = (size.width(), size.height()) sizes.append(size) all_sizes.add(size) sizes.sort() icons.append({ 'context': context, 'icon_name': icon_name, 'icon': icon, 'sizes': sizes, }) all_sizes = list(all_sizes) all_sizes.sort() # input field for filter def filter_changed(value): proxy_model.setFilterRegExp(value) table_view.resizeRowsToContents() filter_line_edit = QLineEdit() filter_line_edit.setMaximumWidth(200) filter_line_edit.setPlaceholderText('Filter name') filter_line_edit.setToolTip( 'Filter name optionally using regular expressions (' + QKeySequence(QKeySequence.Find).toString() + ')') filter_line_edit.textChanged.connect(filter_changed) tool_bar.addWidget(filter_line_edit) # actions to toggle visibility of available sizes/columns def action_toggled(index): column = 2 + index table_view.setColumnHidden(column, not table_view.isColumnHidden(column)) table_view.resizeColumnsToContents() table_view.resizeRowsToContents() signal_mapper = QSignalMapper() for i, size in enumerate(all_sizes): action = QAction('%dx%d' % size, tool_bar) action.setCheckable(True) action.setChecked(True) tool_bar.addAction(action) action.toggled.connect(signal_mapper.map) signal_mapper.setMapping(action, i) # set tool tip and handle key sequence tool_tip = 'Toggle visibility of column' if i < 10: digit = ('%d' % (i + 1))[-1] tool_tip += ' (%s)' % QKeySequence('Ctrl+%s' % digit).toString() action.setToolTip(tool_tip) signal_mapper.mapped.connect(action_toggled) # label columns header_labels = ['context', 'name'] for width, height in all_sizes: header_labels.append('%dx%d' % (width, height)) item_model.setColumnCount(len(header_labels)) item_model.setHorizontalHeaderLabels(header_labels) # fill rows item_model.setRowCount(len(icons)) for row, icon_data in enumerate(icons): # context item = QStandardItem(icon_data['context']) item.setFlags(item.flags() ^ Qt.ItemIsEditable) item_model.setItem(row, 0, item) # icon name item = QStandardItem(icon_data['icon_name']) item.setFlags(item.flags() ^ Qt.ItemIsEditable) item_model.setItem(row, 1, item) for index_in_all_sizes, size in enumerate(all_sizes): column = 2 + index_in_all_sizes if size in icon_data['sizes']: # icon as pixmap to keep specific size item = QStandardItem('') pixmap = icon_data['icon'].pixmap(size[0], size[1]) item.setData(pixmap, Qt.DecorationRole) item.setFlags(item.flags() ^ Qt.ItemIsEditable) item_model.setItem(row, column, item) else: # single space to be sortable against icons item = QStandardItem(' ') item.setFlags(item.flags() ^ Qt.ItemIsEditable) item_model.setItem(row, column, item) table_view.resizeColumnsToContents() # manually set row heights because resizeRowsToContents is not working properly for row, icon_data in enumerate(icons): if len(icon_data['sizes']) > 0: max_size = icon_data['sizes'][-1] table_view.setRowHeight(row, max_size[1]) # enable focus find (ctrl+f) and toggle columns (ctrl+NUM) def main_window_keyPressEvent(self, event, old_keyPressEvent=QMainWindow.keyPressEvent): if event.matches(QKeySequence.Find): filter_line_edit.setFocus() return if event.modifiers() == Qt.ControlModifier and event.key( ) >= Qt.Key_0 and event.key() <= Qt.Key_9: index = event.key() - Qt.Key_1 if event.key() == Qt.Key_0: index += 10 action = signal_mapper.mapping(index) if action: action.toggle() return old_keyPressEvent(self, event) main_window.keyPressEvent = new.instancemethod(main_window_keyPressEvent, table_view, None) # enable copy (ctrl+c) name of icon to clipboard def table_view_keyPressEvent(self, event, old_keyPressEvent=QTableView.keyPressEvent): if event.matches(QKeySequence.Copy): selection_model = self.selectionModel() if selection_model.hasSelection(): index = selection_model.selectedRows()[0] source_index = self.model().mapToSource(index) item = self.model().sourceModel().item(source_index.row(), 1) icon_name = item.data(Qt.EditRole) app.clipboard().setText(icon_name.toString()) return old_keyPressEvent(self, event) table_view.keyPressEvent = new.instancemethod(table_view_keyPressEvent, table_view, None) print 'Icon Theme: ', QIcon.themeName() print 'Theme Search Paths:' for item in QIcon.themeSearchPaths(): print item main_window.showMaximized() return app.exec_()
class StepsTableView(QTableView): """ Steps table view """ DataChanged = pyqtSignal() def __init__(self, parent, helper): """ Description table view constructor """ QTableView.__init__(self, parent) self.helper = helper self.createWidgets() self.createConnections() self.createActions() def createWidgets (self): """ Create qt widgets """ self.proxyModel = QSortFilterProxyModel(self) self.proxyModel.setDynamicSortFilter(True) self.model = DescriptionTableModel(self) self.setModel(self.proxyModel) self.proxyModel.setSourceModel(self.model) self.setFrameShape(QFrame.StyledPanel) self.setShowGrid(True) self.setSelectionMode(QAbstractItemView.SingleSelection) self.setSelectionBehavior(QAbstractItemView.SelectRows) self.setContextMenuPolicy(Qt.CustomContextMenu) self.verticalHeader().setVisible(False) self.horizontalHeader().setHighlightSections(False) self.setHorizontalScrollMode(QAbstractItemView.ScrollPerPixel) self.horizontalHeader().setStretchLastSection(True) self.setItemDelegateForColumn( COL_SUMMARY_STEP, StepSummaryDelegate(self) ) self.setColumnWidth(COL_ID_STEP, 45) def createConnections (self): """ Create qt connections """ self.customContextMenuRequested.connect(self.onPopupMenu) self.clicked.connect( self.onAbstractItemClicked) def createActions (self): """ Qt actions """ self.addAction = QtHelper.createAction(self, self.tr("&Add"), self.addStep, icon = QIcon(":/step-add.png"), tip = self.tr('Add a new step') ) self.delAction = QtHelper.createAction(self, self.tr("&Delete"), self.deleteAction, icon = QIcon(":/step-del.png"), tip = self.tr('Delete the selected step')) self.delAllAction = QtHelper.createAction(self, self.tr("&Delete All"), self.clearItems, icon = QIcon(":/test-parameter-clear.png"), tip = self.tr('Delete all steps')) # set default actions self.delAction.setEnabled(False) self.delAllAction.setEnabled(False) def onAbstractItemClicked(self): """ Called on item clicked """ indexes = self.selectedIndexes() if not indexes: self.delAction.setEnabled(False) else: self.delAction.setEnabled(True) def onPopupMenu(self, pos): """ Display menu on right click @param pos: @type pos: """ self.menu = QMenu(self) index = self.currentIndex() indexes = self.selectedIndexes() if not indexes: self.delAction.setEnabled(False) self.menu.addAction( self.addAction ) self.menu.addSeparator() else: self.delAction.setEnabled(True) self.menu.addAction( self.addAction ) self.menu.addSeparator() self.menu.popup( self.mapToGlobal(pos) ) def getHelpFramework(self): """ Get help from framework """ self.helper = Helper.instance() val = self.helper.helpFramework(moduleName='TestExecutor', className='TestCase', functionName='addStep') if val is None: val = {} val['obj'] = {} else: desc = val['desc'].strip() desc_splitted = desc.splitlines() val['return-value'] = False params = [] param = {} for line in desc_splitted: line = line.strip() if line.startswith('@param '): paramName = line.split(':', 1)[0].split('@param ')[1].strip() param['name'] = paramName elif line.startswith('@type '): paramType = line.split(':', 1)[1].strip() param['type'] = paramType params.append( param ) param = {} elif line.startswith('@return'): val['return-value'] = True else: pass val['obj'] = params return val def addStep(self): """ Add step """ helpFramework = self.getHelpFramework() stepDialog = StepDialog(helpFramework) #, stepId=stepId) if stepDialog.exec_() == QDialog.Accepted: stepParams = stepDialog.getValues() self.insertItem(stepParams=stepParams) def insertItem(self, stepParams): """ Insert item """ indexes = self.selectedIndexes() if not len(indexes): row = self.model.rowCount() else: index = self.currentIndex() row = index.row() data = self.model.getData() # add data to model stepParams['id'] = "%s" % (len(data) + 1) data.insert(row + 1, stepParams) if sys.version_info > (3,): self.model.beginResetModel() self.model.endResetModel() else: self.reset() self.delAllAction.setEnabled(True) self.setData() def deleteAction(self): """ Delete action """ indexes = self.selectedIndexes() if not indexes: return # map proxy indexes to source sourceIndexes = [] for proxyIndex in indexes: if not proxyIndex.isValid(): return else: sourceIndexes.append( self.proxyModel.mapToSource( proxyIndex ) ) if sourceIndexes: answer = QMessageBox.question(self, self.tr("Remove"), self.tr("Do you want to remove the selection?"), QMessageBox.Yes | QMessageBox.No) if answer == QMessageBox.Yes: self.removeValues(sourceIndexes) def removeValues(self, indexes): """ Remove values from data @param indexes: @type indexes: """ if not indexes: return # data from model datas = self.model.getData() # remove duplicate index cleanIndexes = {} for index in indexes: if index.row() not in cleanIndexes: cleanIndexes[index.row()] = index for cleanIndex in list(cleanIndexes.keys()): # for python3 support datas.pop(cleanIndex) if sys.version_info > (3,): self.model.beginResetModel() self.model.endResetModel() else: self.reset() self.setData( signal = True ) def setSteps(self, steps): """ Set steps """ self.model.setDataModel( steps ) self.setData( signal = False ) def clearItems(self): """ Clear all items """ reply = QMessageBox.question(self, self.tr("Clear all steps"), self.tr("Are you sure ?"), QMessageBox.Yes | QMessageBox.No ) if reply == QMessageBox.Yes: data = self.model.getData() try: for i in xrange(len(data)): data.pop() except Exception as e: pass if sys.version_info > (3,): self.model.beginResetModel() self.model.endResetModel() else: self.reset() self.setData() self.delAllAction.setEnabled(False) self.delAction.setEnabled(False) def clear (self): """ clear contents """ self.model.setDataModel( [] ) def setData(self, signal = True): """ Set table data @param signal: @type signal: boolean """ if signal: self.DataChanged.emit()
def __init__(self, parent): QSortFilterProxyModel.__init__(self, parent) core.fileFilter().regExpChanged.connect(self.invalidate)
def setFilterFixedString(self, string): """Should this raise an error? It is not being used. """ QSortFilterProxyModel.setFilterFixedString(self, string)
def __init__(self, parent=None, aptinkerQSettings=None): """Constructor""" QDialog.__init__(self, parent=parent) self.setupUi(self) self.setWindowFlags(Qt.Window) # To add Maximize & Minimize buttons self.setWindowTitle('Select Snapshot from Database') # Load Startup Preferences for Snapshot Table self.default_ss_pref = dict( vis_col_key_list=config.DEF_VIS_COL_KEYS['snapshot_DB'][:]) if osp.exists(PREF_SS_JSON_FILEPATH): with open(PREF_SS_JSON_FILEPATH, 'r') as f: self.ss_pref = json.load(f) else: self.ss_pref = self.default_ss_pref # Load Startup Preferences for Snapshot Meta Table self.default_ss_meta_pref = dict(vis_col_key_list=[ 'ss_id', 'config_id', 'ss_ctime', 'ss_name', 'ss_username' ]) if osp.exists(PREF_SS_META_JSON_FILEPATH): with open(PREF_SS_META_JSON_FILEPATH, 'r') as f: self.ss_meta_pref = json.load(f) else: self.ss_meta_pref = self.default_ss_meta_pref self.ssDBViewWidget = SnapshotDBViewWidget(self.groupBox_selected_ss, DB_selector=True) self.tableView_ss = self.ssDBViewWidget.tableView self.ssMetaDBViewWidget = SnapshotMetaDBViewWidget( self.groupBox_search_result) self.tableView_ss_meta = self.ssMetaDBViewWidget.tableView self.textEdit_description = \ self.ssMetaDBViewWidget.textEdit_description self.settings = QSettings('APHLA', 'TinkerSSDBSelector') self.loadViewSettings() self._aptinkerQSettings = aptinkerQSettings self.pushButton_search.setIcon(QIcon(':/search.png')) all_ctime_operators = [ self.comboBox_time_created_1.itemText(i) for i in range(self.comboBox_time_created_1.count()) ] self.comboBox_time_created_1.setCurrentIndex( all_ctime_operators.index('')) self.dateTimeEdit_time_created_1.setDateTime( QDateTime.currentDateTime()) self.dateTimeEdit_time_created_2.setDateTime( QDateTime.currentDateTime()) self.search_params = dict(ss_id_1='', ss_id_2='', config_id_1='', config_id_2='', ss_ref_step_size_1='', ss_ref_step_size_2='', ss_name='', ss_desc='', ss_username='', ss_ctime_1='', ss_ctime_2='', ss_synced_gruop_weight='', ss_masar_id_1='', ss_masar_id_2='') db_id_validator = QIntValidator() db_id_validator.setBottom(1) self.lineEdit_ss_id_1.setValidator(db_id_validator) self.lineEdit_ss_id_2.setValidator(db_id_validator) self.lineEdit_config_id_1.setValidator(db_id_validator) self.lineEdit_config_id_2.setValidator(db_id_validator) self.lineEdit_masar_id_1.setValidator(db_id_validator) self.lineEdit_masar_id_2.setValidator(db_id_validator) self.prev_valid_ref_step_sizes = dict(lineEdit_ref_step_size_1=np.nan, lineEdit_ref_step_size_2=np.nan) # Set up Snapshot Table self.ss_model = SnapshotModel(self.ss_pref['vis_col_key_list']) self.tableModel_ss = self.ss_model.table proxyModel = QSortFilterProxyModel() proxyModel.setSourceModel(self.tableModel_ss) proxyModel.setDynamicSortFilter(False) tbV = self.tableView_ss tbV.setModel(proxyModel) tbV.setItemDelegate( SnapshotDBTableViewItemDelegate(tbV, self.tableModel_ss, tbV.parent())) #self.db = TinkerMainDatabase() self.db = self.ss_model.db if '[ss_meta_table text view]' not in self.db.getViewNames( square_brackets=True): self.db.create_temp_ss_meta_table_text_view() # Set up Snapshot Meta Table self.ss_meta_all_col_keys = self.ssMetaDBViewWidget.all_col_keys self.search_result = {k: [] for k in self.ss_meta_all_col_keys} self.tableModel_ss_meta = MetaTableModel(self.search_result, self.ssMetaDBViewWidget) proxyModel = QSortFilterProxyModel() proxyModel.setSourceModel(self.tableModel_ss_meta) proxyModel.setDynamicSortFilter(False) tbV = self.tableView_ss_meta tbV.setModel(proxyModel) self.selectionModel = QItemSelectionModel(proxyModel) tbV.setSelectionModel(self.selectionModel) # Apply Visible Column Preference to Snapshot Meta Table ss_meta_vis_col_name_list = [ self.ssMetaDBViewWidget.col_names_wo_desc[ self.ssMetaDBViewWidget.col_keys_wo_desc.index(k)] for k in self.ss_meta_pref['vis_col_key_list'] ] self.ssMetaDBViewWidget.on_column_selection_change( ss_meta_vis_col_name_list, force_visibility_update=True) # Make connection self.connect(self.lineEdit_ref_step_size_1, SIGNAL('editingFinished()'), self.validate_ref_step_size) self.connect(self.lineEdit_ref_step_size_2, SIGNAL('editingFinished()'), self.validate_ref_step_size) self.connect(self.pushButton_search, SIGNAL('clicked()'), self.update_search) self.connect( self.selectionModel, SIGNAL( 'currentRowChanged(const QModelIndex &, const QModelIndex &)'), self.on_selection_change)
def __init__(self, surfacesList, fileWriter=None): QSortFilterProxyModel.__init__(self) ObstacleTable.SelectionMode = SelectionModeType.Automatic self.manualPolygon = None self.surfacesList = surfacesList self.surfaceType = None self.source = QStandardItemModel() self.setSourceModel(self.source) # tableView.hideColumn(self.IndexObjectId) # tableView.hideColumn(self.IndexLayerId) # tableView.hideColumn(self.IndexX) # tableView.hideColumn(self.IndexY) # tableView.hideColumn(self.IndexLat) # tableView.hideColumn(self.IndexLon) # tableView.hideColumn(self.IndexSurface) self.hideColumnLabels = [ ObstacleTableColumnType.ObjectId, ObstacleTableColumnType.LayerId, ObstacleTableColumnType.X, ObstacleTableColumnType.Y, ObstacleTableColumnType.Lat, ObstacleTableColumnType.Lon, ObstacleTableColumnType.Surface ] self.fixedColumnLabels = [ ObstacleTableColumnType.ObjectId, ObstacleTableColumnType.LayerId, ObstacleTableColumnType.Name, ObstacleTableColumnType.X, ObstacleTableColumnType.Y, ObstacleTableColumnType.Lat, ObstacleTableColumnType.Lon, ObstacleTableColumnType.AltM, ObstacleTableColumnType.AltFt, ObstacleTableColumnType.TreesM, ObstacleTableColumnType.TreesFt ] self.IndexObjectId = 0 self.IndexLayerId = 1 self.IndexName = 2 self.IndexX = 3 self.IndexY = 4 self.IndexLat = 5 self.IndexLon = 6 self.IndexAltM = 7 self.IndexAltFt = 8 self.IndexTreesM = 9 self.IndexTreesFt = 10 self.IndexOcaM = -1 self.IndexOcaFt = -1 self.IndexOchM = -1 self.IndexOchFt = -1 self.IndexObstArea = -1 self.IndexDistInSecM = -1 self.IndexMocAppliedM = -1 self.IndexMocAppliedFt = -1 self.IndexMocMultiplier = -1 self.IndexMocReqM = -1 self.IndexMocReqFt = -1 self.IndexDoM = -1 self.IndexDrM = -1 self.IndexDzM = -1 self.IndexDxM = -1 self.IndexDsocM = -1 self.IndexHeightLossM = -1 self.IndexHeightLossFt = -1 self.IndexAcAltM = -1 self.IndexAcAltFt = -1 self.IndexAltReqM = -1 self.IndexAltReqFt = -1 self.IndexCritical = -1 self.IndexMACG = -1 self.IndexPDG = -1 self.IndexSurfAltM = -1 self.IndexSurfAltFt = -1 self.IndexDifferenceM = -1 self.IndexDifferenceFt = -1 self.IndexIlsX = -1 self.IndexIlsY = -1 self.IndexEqAltM = -1 self.IndexEqAltFt = -1 self.IndexSurfaceName = -1 self.IndexDisregardable = -1 self.IndexCloseIn = -1 self.IndexTag = -1 self.IndexSurface = -1 self.IndexArea = -1 self.IndexHLAppliedM = -1 self.setHeaderLabels() self.setFilterKeyColumn(self.IndexSurface) self.setSortRole(Qt.UserRole + 1) self.layoutChanged.connect(self.setVerticalHeader) self.btnLocate = None self.tblObstacles = None
class SearchPlus(QObject): def __init__(self, iface, srid, controller): """ Constructor """ self.iface = iface self.srid = srid self.controller = controller self.schema_name = self.controller.schema_name self.project_type = self.controller.get_project_type() self.feature_cat = {} def init_config(self): """ Initial configuration """ # Create dialog self.dlg = SearchPlusDockWidget(self.iface.mainWindow()) # Load configuration data from tables if not self.load_config_data(): return False # Check adress parameters message = "Parameter not found" if not 'street_field_expl' in self.params: self.controller.show_warning(message, parameter='street_field_expl') return False if not 'portal_field_postal' in self.params: self.controller.show_warning(message, parameter='portal_field_postal') return False self.street_field_expl = self.params['street_field_expl'] portal_field_postal = self.params['portal_field_postal'] # Set signals self.dlg.address_exploitation.currentIndexChanged.connect(partial(self.address_fill_postal_code, self.dlg.address_postal_code)) self.dlg.address_exploitation.currentIndexChanged.connect(partial(self.address_populate, self.dlg.address_street, 'street_layer', 'street_field_code', 'street_field_name')) self.dlg.address_exploitation.currentIndexChanged.connect(partial(self.address_get_numbers, self.dlg.address_exploitation, self.street_field_expl, False)) self.dlg.address_postal_code.currentIndexChanged.connect(partial(self.address_get_numbers, self.dlg.address_postal_code, portal_field_postal, False)) self.dlg.address_street.activated.connect(partial(self.address_get_numbers, self.dlg.address_street, self.params['portal_field_code'], True)) self.dlg.address_number.activated.connect(partial(self.address_zoom_portal)) self.dlg.network_geom_type.activated.connect(partial(self.network_geom_type_changed)) self.dlg.network_code.activated.connect(partial(self.network_zoom, self.dlg.network_code, self.dlg.network_geom_type)) self.dlg.network_code.editTextChanged.connect(partial(self.filter_by_list, self.dlg.network_code)) self.dlg.hydrometer_connec.activated.connect(partial(self.hydrometer_get_hydrometers)) self.dlg.hydrometer_id.activated.connect(partial(self.hydrometer_zoom, self.params['hydrometer_urban_propierties_field_code'], self.dlg.hydrometer_connec)) self.dlg.hydrometer_id.editTextChanged.connect(partial(self.filter_by_list, self.dlg.hydrometer_id)) self.dlg.workcat_id.activated.connect(partial(self.workcat_open_table_items)) return True def update_state_selector(self): """ Force to 0,1,2... the selector_state user values""" sql = ("SELECT state_id, cur_user FROM " +self.schema_name+".selector_state " "WHERE cur_user=current_user") self.current_selector = self.controller.get_rows(sql) sql = ("DELETE FROM "+self.schema_name+".selector_state " "WHERE cur_user = current_user") self.controller.execute_sql(sql) sql = ("SELECT id FROM "+self.schema_name+".value_state") rows = self.controller.get_rows(sql) for row in rows: sql = ("INSERT INTO "+self.schema_name+".selector_state (state_id, cur_user)" " VALUES("+str(row[0])+", current_user)") self.controller.execute_sql(sql) def restore_state_selector(self): """ Restore values to selector_state after update (def update_state_selector(self)) """ sql = ("DELETE FROM " + self.schema_name + ".selector_state " " WHERE cur_user = current_user") self.controller.execute_sql(sql) for row in self.current_selector: sql = ("INSERT INTO " + self.schema_name + ".selector_state (state_id, cur_user)" " VALUES(" + str(row[0]) + ", current_user)") self.controller.execute_sql(sql) def workcat_populate(self, combo): """ Fill @combo """ sql = ("SELECT DISTINCT(workcat_id) FROM " + self.controller.schema_name + ".arc" " WHERE workcat_id LIKE '%%' or workcat_id is NULL" " UNION" " SELECT DISTINCT(workcat_id) FROM " + self.controller.schema_name + ".connec" " WHERE workcat_id LIKE '%%' or workcat_id is NULL" " UNION" " SELECT DISTINCT(workcat_id) FROM " + self.controller.schema_name + ".node" " WHERE workcat_id LIKE '%%' or workcat_id is NULL") if self.project_type == 'ud': sql += (" UNION" " SELECT DISTINCT(workcat_id) FROM " + self.controller.schema_name + ".gully" " WHERE workcat_id LIKE '%%' or workcat_id is NULL") rows = self.controller.get_rows(sql) utils_giswater.fillComboBox(combo, rows) return rows def update_selector_workcat(self, workcat_id): """ Update table selector_workcat """ sql = ("DELETE FROM "+self.schema_name+".selector_workcat " "WHERE cur_user = current_user") self.controller.execute_sql(sql) sql = ("INSERT INTO "+self.schema_name+".selector_workcat(workcat_id, cur_user) " " VALUES('"+workcat_id+"',current_user)") self.controller.execute_sql(sql) def zoom_to_workcat(self): layer = self.controller.get_layer_by_tablename("v_ui_workcat_polygon") self.iface.setActiveLayer(layer) # Build an expression to select them aux = "workcat_id ILIKE '%%'" # Get a featureIterator from this expression expr = QgsExpression(aux) if expr.hasParserError(): message = "Expression Error" self.controller.show_warning(message, parameter=expr.parserErrorString()) return # Select features with these id's it = layer.getFeatures(QgsFeatureRequest(expr)) # Build a list of feature id's from the previous result id_list = [i.id() for i in it] # Select features with these id's layer.selectByIds(id_list) self.iface.mapCanvas().zoomToSelected() layer.removeSelection() self.iface.mapCanvas().refreshAllLayers() def workcat_open_table_items(self): """ Create the view and open the dialog with his content """ self.update_state_selector() workcat_id = utils_giswater.getWidgetText(self.dlg.workcat_id) if workcat_id == "null": return False self.update_selector_workcat(workcat_id) self.zoom_to_workcat() self.items_dialog = ListItems() utils_giswater.setDialog(self.items_dialog) self.load_settings(self.items_dialog) self.items_dialog.tbl_psm.setSelectionBehavior(QAbstractItemView.SelectRows) self.items_dialog.tbl_psm_end.setSelectionBehavior(QAbstractItemView.SelectRows) table_name = "v_ui_workcat_x_feature" table_name_end = "v_ui_workcat_x_feature_end" self.items_dialog.btn_close.pressed.connect(partial(self.close_dialog, self.items_dialog)) self.items_dialog.btn_close.pressed.connect(partial(self.restore_state_selector)) self.items_dialog.rejected.connect(partial(self.close_dialog, self.items_dialog)) self.items_dialog.rejected.connect(partial(self.restore_state_selector)) self.items_dialog.txt_name.textChanged.connect(partial(self.workcat_filter_by_text, self.items_dialog.tbl_psm, self.items_dialog.txt_name, table_name, workcat_id)) self.items_dialog.txt_name_end.textChanged.connect(partial(self.workcat_filter_by_text, self.items_dialog.tbl_psm_end, self.items_dialog.txt_name_end, table_name_end, workcat_id)) self.items_dialog.tbl_psm.doubleClicked.connect(partial(self.workcat_zoom, self.items_dialog.tbl_psm)) self.items_dialog.tbl_psm_end.doubleClicked.connect(partial(self.workcat_zoom, self.items_dialog.tbl_psm_end)) expr = "workcat_id ILIKE '%" + str(workcat_id) + "%'" self.workcat_fill_table(self.items_dialog.tbl_psm, table_name, expr=expr) self.set_table_columns(self.items_dialog.tbl_psm, table_name) self.workcat_fill_table(self.items_dialog.tbl_psm_end, table_name_end, expr=expr) self.set_table_columns(self.items_dialog.tbl_psm_end, table_name_end) self.items_dialog.setWindowFlags(Qt.WindowMaximizeButtonHint | Qt.WindowStaysOnTopHint) self.items_dialog.open() def workcat_zoom(self, qtable): """ Zoom feature with the code set in 'network_code' of the layer set in 'network_geom_type' """ # Get selected code from combo element = qtable.selectionModel().selectedRows() if len(element) == 0: message = "Any record selected" self.controller.show_warning(message) return row = element[0].row() feature_id = qtable.model().record(row).value('feature_id') # Get selected layer geom_type = qtable.model().record(row).value('feature_type').lower() fieldname = geom_type + "_id" # Check if the expression is valid aux = fieldname + " = '" + str(feature_id) + "'" expr = QgsExpression(aux) if expr.hasParserError(): message = expr.parserErrorString() + ": " + aux self.controller.show_warning(message) return for value in self.feature_cat.itervalues(): if value.type.lower() == geom_type: layer = self.controller.get_layer_by_layername(value.layername) if layer: it = layer.getFeatures(QgsFeatureRequest(expr)) ids = [i.id() for i in it] layer.selectByIds(ids) # If any feature found, zoom it and exit function if layer.selectedFeatureCount() > 0: self.iface.setActiveLayer(layer) self.iface.legendInterface().setLayerVisible(layer, True) self.workcat_open_custom_form(layer, expr) self.zoom_to_selected_features(layer, geom_type) return # If the feature is not in views because the selectors are "disabled"... message = "Modify values of selectors to see the feature" self.controller.show_warning(message) def workcat_open_custom_form(self, layer, expr): """ Open custom form from selected layer """ it = layer.getFeatures(QgsFeatureRequest(expr)) features = [i for i in it] if features: self.iface.openFeatureForm(layer, features[0]) def workcat_fill_table(self, widget, table_name, hidde=False, set_edit_triggers=QTableView.NoEditTriggers, expr=None): """ Fill table @widget filtering query by @workcat_id Set a model with selected filter. Attach that model to selected table @setEditStrategy: 0: OnFieldChange 1: OnRowChange 2: OnManualSubmit """ # Set model model = QSqlTableModel() model.setTable(self.schema_name+"."+table_name) model.setEditStrategy(QSqlTableModel.OnFieldChange) model.setSort(0, 0) model.select() widget.setEditTriggers(set_edit_triggers) # Check for errors if model.lastError().isValid(): self.controller.show_warning(model.lastError().text()) # Attach model to table view if expr: widget.setModel(model) widget.model().setFilter(expr) else: widget.setModel(model) if hidde: self.refresh_table(widget) def workcat_filter_by_text(self, qtable, widget_txt, table_name, workcat_id): result_select = utils_giswater.getWidgetText(widget_txt) if result_select != 'null': expr = "workcat_id = '" + str(workcat_id) + "'" expr += "and feature_id ILIKE '%" + str(result_select) + "%'" else: expr = "workcat_id ILIKE '%" + str(workcat_id) + "%'" self.workcat_fill_table(qtable, table_name, expr=expr) self.set_table_columns(qtable, table_name) def address_fill_postal_code(self, combo): """ Fill @combo """ # Get exploitation code: 'expl_id' elem = self.dlg.address_exploitation.itemData(self.dlg.address_exploitation.currentIndex()) code = elem[0] # Get postcodes related with selected 'expl_id' sql = "SELECT DISTINCT(postcode) FROM " + self.controller.schema_name + ".ext_address" if code != -1: sql += " WHERE " + self.street_field_expl + " = '" + str(code) + "'" sql += " ORDER BY postcode" rows = self.controller.get_rows(sql) if not rows: return False records = [(-1, '', '')] for row in rows: field_code = row[0] elem = [field_code, field_code, None] records.append(elem) # Fill combo combo.blockSignals(True) combo.clear() records_sorted = sorted(records, key=operator.itemgetter(1)) for i in range(len(records_sorted)): record = records_sorted[i] combo.addItem(record[1], record) combo.blockSignals(False) return True def load_config_data(self): """ Load configuration data from tables """ self.params = {} sql = ("SELECT parameter, value FROM " + self.controller.schema_name + ".config_param_system" " WHERE context = 'searchplus' ORDER BY parameter") rows = self.controller.get_rows(sql) if not rows: message = "Parameters related with 'searchplus' not set in table 'config_param_system'" self.controller.log_warning(message) return False for row in rows: self.params[row['parameter']] = str(row['value']) # Get scale zoom if not 'scale_zoom' in self.params: self.scale_zoom = 2500 else: self.scale_zoom = self.params['scale_zoom'] return True def dock_dialog(self): """ Dock dialog into left dock widget area """ if not self.populate_dialog(): return False # Get path of .ui file ui_path = os.path.join(self.controller.plugin_dir, 'search', 'ui', 'search_plus_dialog.ui') if not os.path.exists(ui_path): self.controller.show_warning("File not found", parameter=ui_path) return False # Make it dockable in left dock widget area self.dock = uic.loadUi(ui_path) self.iface.addDockWidget(Qt.LeftDockWidgetArea, self.dlg) self.dlg.setFixedHeight(162) # Set his backgroundcolor p = self.dlg.palette() self.dlg.setAutoFillBackground(True) p.setColor(self.dlg.backgroundRole(), Qt.white) self.dlg.setPalette(p) return True def get_layers(self): """ Iterate over all layers to get the ones set in config file """ # Check if we have any layer loaded layers = self.iface.legendInterface().layers() if len(layers) == 0: return # Iterate over all layers to get the ones specified parameters '*_layer' self.layers = {} for cur_layer in layers: layer_source = self.controller.get_layer_source(cur_layer) uri_table = layer_source['table'] if uri_table is not None: if self.params['expl_layer'] == uri_table: self.layers['expl_layer'] = cur_layer if self.params['street_layer'] == uri_table: self.layers['street_layer'] = cur_layer if self.params['portal_layer'] == uri_table: self.layers['portal_layer'] = cur_layer if self.params['hydrometer_layer'] == uri_table: self.layers['hydrometer_layer'] = cur_layer if self.params['hydrometer_urban_propierties_layer'] == uri_table: self.layers['hydrometer_urban_propierties_layer'] = cur_layer if self.params['network_layer_arc'] == uri_table: self.layers['network_layer_arc'] = cur_layer if self.params['network_layer_connec'] == uri_table: self.layers['network_layer_connec'] = cur_layer if self.params['network_layer_element'] == uri_table: self.layers['network_layer_element'] = cur_layer if self.params['network_layer_gully'] == uri_table: self.layers['network_layer_gully'] = cur_layer if self.params['network_layer_node'] == uri_table: self.layers['network_layer_node'] = cur_layer def populate_dialog(self): """ Populate the interface with values get from layers """ # Get layers and full extent self.get_layers() # Tab 'WorkCat' status = self.workcat_populate(self.dlg.workcat_id) if not status: self.dlg.tab_main.removeTab(3) # Tab 'Address' status = self.address_populate(self.dlg.address_exploitation, 'expl_layer', 'expl_field_code', 'expl_field_name') if not status: self.dlg.tab_main.removeTab(2) else: # Get project variable 'expl_id' expl_id = QgsExpressionContextUtils.projectScope().variable(str(self.street_field_expl)) if expl_id: # Set SQL to get 'expl_name' sql = ("SELECT " + self.params['expl_field_name'] + "" " FROM " + self.controller.schema_name + "." + self.params['expl_layer'] + "" " WHERE " + self.params['expl_field_code'] + " = " + str(expl_id)) row = self.controller.get_row(sql) if row: utils_giswater.setSelectedItem(self.dlg.address_exploitation, row[0]) # Tab 'Hydrometer' self.populate_combo('hydrometer_urban_propierties_layer', self.dlg.hydrometer_connec, self.params['hydrometer_field_urban_propierties_code']) status = self.populate_combo('hydrometer_layer', self.dlg.hydrometer_id, self.params['hydrometer_field_urban_propierties_code'], self.params['hydrometer_field_code']) if not status: self.dlg.tab_main.removeTab(1) # Tab 'Network' self.network_code_create_lists() status = self.network_geom_type_populate() if not status: self.dlg.tab_main.removeTab(0) return True def network_code_create_lists(self): """ Create one list for each geom type and other one with all geom types """ self.list_arc = [] self.list_connec = [] self.list_element = [] self.list_gully = [] self.list_node = [] self.list_all = [] # Check which layers are available and get its list of codes if 'network_layer_arc' in self.layers: self.list_arc = self.network_code_layer('network_layer_arc') if 'network_layer_connec' in self.layers: self.list_connec = self.network_code_layer('network_layer_connec') if 'network_layer_element' in self.layers: self.list_element = self.network_code_layer('network_layer_element') if 'network_layer_gully' in self.layers: self.list_gully = self.network_code_layer('network_layer_gully') if 'network_layer_node' in self.layers: self.list_node = self.network_code_layer('network_layer_node') try: self.list_all = self.list_arc + self.list_connec + self.list_element + self.list_gully + self.list_node self.list_all = sorted(set(self.list_all)) self.set_model_by_list(self.list_all, self.dlg.network_code) except: pass return True def network_code_layer(self, layername): """ Get codes of selected layer and add them to the combo 'network_code' """ viewname = self.params[layername] viewname_parts = viewname.split("_") if len(viewname_parts) < 3: return feature_type = str(viewname_parts[2]).lower() field_type = "" if self.project_type == 'ws': if str(viewname_parts[2]) == "arc": viewname_parts[2] = "cat_arc" field_type = viewname_parts[2] + "type_id" elif self.project_type == 'ud': field_type = viewname_parts[2] + "_type" sql = ("SELECT value FROM "+self.schema_name+".config_param_system " " WHERE parameter = 'network_field_"+feature_type+"_code' " " AND context='searchplus'") row = self.controller.get_row(sql, log_info=True) self.field_to_search = row[0] sql = ("SELECT DISTINCT(" + str(self.field_to_search) + "), " + str(field_type) + "" " FROM " + self.controller.schema_name + "." + viewname + "" " WHERE " + str(self.field_to_search) + " IS NOT NULL" " ORDER BY " + str(self.field_to_search) + "") rows = self.controller.get_rows(sql) if not rows: return False list_codes = [''] for row in rows: list_codes.append(row[0] + " " + row[1]) return list_codes def network_geom_type_populate(self): """ Populate combo 'network_geom_type' """ # Add null value self.dlg.network_geom_type.clear() self.dlg.network_geom_type.addItem('') # Check which layers are available if 'network_layer_arc' in self.layers: self.dlg.network_geom_type.addItem(self.controller.tr('Arc')) if 'network_layer_connec' in self.layers: self.dlg.network_geom_type.addItem(self.controller.tr('Connec')) if 'network_layer_element' in self.layers: self.dlg.network_geom_type.addItem(self.controller.tr('Element')) if 'network_layer_gully' in self.layers: self.dlg.network_geom_type.addItem(self.controller.tr('Gully')) if 'network_layer_node' in self.layers: self.dlg.network_geom_type.addItem(self.controller.tr('Node')) return self.dlg.network_geom_type > 0 def network_geom_type_changed(self): """ Get 'geom_type' to filter 'code' values """ geom_type = utils_giswater.getWidgetText(self.dlg.network_geom_type) list_codes = [] if geom_type == self.controller.tr('Arc'): list_codes = self.list_arc elif geom_type == self.controller.tr('Connec'): list_codes = self.list_connec elif geom_type == self.controller.tr('Element'): list_codes = self.list_element elif geom_type == self.controller.tr('Gully'): list_codes = self.list_gully elif geom_type == self.controller.tr('Node'): list_codes = self.list_node else: list_codes = self.list_all self.set_model_by_list(list_codes, self.dlg.network_code) return True def set_model_by_list(self, string_list, widget): model = QStringListModel() model.setStringList(string_list) self.proxy_model = QSortFilterProxyModel() self.proxy_model.setSourceModel(model) self.proxy_model.setFilterKeyColumn(0) proxy_model_aux = QSortFilterProxyModel() proxy_model_aux.setSourceModel(model) proxy_model_aux.setFilterKeyColumn(0) widget.setModel(proxy_model_aux) widget.setModelColumn(0) completer = QCompleter() completer.setModel(self.proxy_model) completer.setCompletionColumn(0) completer.setCompletionMode(QCompleter.UnfilteredPopupCompletion) widget.setCompleter(completer) def filter_by_list(self, widget): self.proxy_model.setFilterFixedString(widget.currentText()) def network_zoom(self, network_code, network_geom_type): """ Zoom feature with the code set in 'network_code' of the layer set in 'network_geom_type' """ # Get selected code from combo element = utils_giswater.getWidgetText(network_code) if element == 'null': return # Split element. [0]: feature_id, [1]: cat_feature_id row = element.split(' ', 1) feature_id = str(row[0]) cat_feature_id = str(row[1]) # Get selected layer geom_type = utils_giswater.getWidgetText(network_geom_type).lower() if geom_type == "null": sql = ("SELECT feature_type FROM " + self.controller.schema_name + ".cat_feature" " WHERE id = '" + cat_feature_id + "'") row = self.controller.get_row(sql) if not row: return geom_type = row[0].lower() # Check if the expression is valid aux = self.field_to_search + " = '" + feature_id + "'" expr = QgsExpression(aux) if expr.hasParserError(): message = expr.parserErrorString() + ": " + aux self.controller.show_warning(message) return for value in self.feature_cat.itervalues(): if value.type.lower() == geom_type: layer = self.controller.get_layer_by_layername(value.layername) if layer: it = layer.getFeatures(QgsFeatureRequest(expr)) ids = [i.id() for i in it] layer.selectByIds(ids) # If any feature found, zoom it and exit function if layer.selectedFeatureCount() > 0: self.zoom_to_selected_features(layer, geom_type) # Set the layer checked (i.e. set it's visibility) self.iface.legendInterface().setLayerVisible(layer, True) return def hydrometer_get_hydrometers(self): """ Populate hydrometers depending on selected connec """ # Get selected connec selected = utils_giswater.getWidgetText(self.dlg.hydrometer_connec) # If any conenc selected, get again all hydrometers if selected == 'null': self.populate_combo('hydrometer_layer', self.dlg.hydrometer_id, self.params['hydrometer_field_urban_propierties_code'], self.params['hydrometer_field_code']) return # Get connec_id elem = self.dlg.hydrometer_connec.itemData(self.dlg.hydrometer_connec.currentIndex()) code = elem[0] # to know the index see the query that populate the combo records = [[-1, '']] # Check if layer exists if not 'hydrometer_layer' in self.layers: message = "Layer not found. Check parameter" self.controller.show_warning(message, parameter='hydrometer_layer') return False # Set filter expression layer = self.layers['hydrometer_layer'] idx_field_code = layer.fieldNameIndex(self.params['hydrometer_field_urban_propierties_code']) idx_field_number = layer.fieldNameIndex(self.params['hydrometer_field_code']) aux = self.params['hydrometer_field_urban_propierties_code'] + " = '" + str(code) + "'" # Check filter and existence of fields expr = QgsExpression(aux) if expr.hasParserError(): message = expr.parserErrorString() self.controller.show_warning(message, parameter=aux) return if idx_field_code == -1: message = "Field '{}' not found in layer '{}'. Open '{}' and check parameter '{}'" \ .format(self.params['hydrometer_field_urban_propierties_code'], layer.name(), self.setting_file, 'hydrometer_field_urban_propierties_code') self.controller.show_warning(message) return if idx_field_number == -1: message = "Field '{}' not found in layer '{}'. Open '{}' and check parameter '{}'" \ .format(self.params['hydrometer_field_code'], layer.name(), self.setting_file, 'hydrometer_field_code') self.controller.show_warning(message) return # Get a featureIterator from an expression: # Get features from the iterator and do something it = layer.getFeatures(QgsFeatureRequest(expr)) for feature in it: attrs = feature.attributes() field_number = attrs[idx_field_number] if not type(field_number) is QPyNullVariant: elem = [code, field_number] records.append(elem) # Fill hydrometers records_sorted = sorted(records, key=operator.itemgetter(1)) self.dlg.hydrometer_id.blockSignals(True) self.dlg.hydrometer_id.clear() hydrometer_list = [] #hydrometer_list.append('') for record in records_sorted: self.dlg.hydrometer_id.addItem(str(record[1]), record) if record[1] != '': hydrometer_list.append(str(record[1])) self.set_model_by_list(hydrometer_list, self.dlg.hydrometer_id) self.hydrometer_zoom(self.params['hydrometer_urban_propierties_field_code'], self.dlg.hydrometer_connec) self.dlg.hydrometer_id.blockSignals(False) def hydrometer_zoom(self, fieldname, combo): """ Zoom to layer set in parameter 'hydrometer_urban_propierties_layer' """ expr = self.generic_zoom(fieldname, combo) if expr is None: return # Check if layer exists if not 'hydrometer_urban_propierties_layer' in self.layers: message = "Layer not found. Check parameter" self.controller.show_warning(message, parameter='hydrometer_urban_propierties_layer') return False # Build a list of feature id's from the expression and select them layer = self.layers['hydrometer_urban_propierties_layer'] it = layer.getFeatures(QgsFeatureRequest(expr)) ids = [i.id() for i in it] layer.selectByIds(ids) # Zoom to selected feature of the layer self.zoom_to_selected_features(layer, 'connec') # Toggles 'Show feature count' self.show_feature_count() def address_populate(self, combo, layername, field_code, field_name): """ Populate @combo """ # Check if we have this search option available if layername not in self.layers: return False # Get features layer = self.layers[layername] records = [(-1, '', '')] idx_field_code = layer.fieldNameIndex(self.params[field_code]) idx_field_name = layer.fieldNameIndex(self.params[field_name]) it = layer.getFeatures() if layername == 'street_layer': # Get 'expl_id' field_expl_id = self.street_field_expl elem = self.dlg.address_exploitation.itemData(self.dlg.address_exploitation.currentIndex()) expl_id = elem[0] records = [[-1, '']] # Set filter expression aux = field_expl_id + " = '" + str(expl_id) + "'" # Check filter and existence of fields expr = QgsExpression(aux) if expr.hasParserError(): message = expr.parserErrorString() + ": " + aux self.controller.show_warning(message) return it = layer.getFeatures(QgsFeatureRequest(expr)) # Iterate over features for feature in it: geom = feature.geometry() attrs = feature.attributes() value_code = attrs[idx_field_code] value_name = attrs[idx_field_name] if not type(value_code) is QPyNullVariant and geom is not None: elem = [value_code, value_name, geom.exportToWkt()] else: elem = [value_code, value_name, None] records.append(elem) # Fill combo combo.blockSignals(True) combo.clear() records_sorted = sorted(records, key = operator.itemgetter(1)) for record in records_sorted: combo.addItem(record[1], record) combo.blockSignals(False) return True def address_get_numbers(self, combo, field_code, fill_combo=False): """ Populate civic numbers depending on value of selected @combo. Build an expression with @field_code """ # Get selected street selected = utils_giswater.getWidgetText(combo) if selected == 'null': return # Get street code elem = combo.itemData(combo.currentIndex()) code = elem[0] # to know the index see the query that populate the combo records = [[-1, '']] # Check if layer exists if not 'portal_layer' in self.layers: message = "Layer not found. Check parameter" self.controller.show_warning(message, parameter='portal_layer') return # Set filter expression layer = self.layers['portal_layer'] idx_field_code = layer.fieldNameIndex(field_code) idx_field_number = layer.fieldNameIndex(self.params['portal_field_number']) aux = field_code + " = '" + str(code) + "'" # Check filter and existence of fields expr = QgsExpression(aux) if expr.hasParserError(): message = expr.parserErrorString() + ": " + aux self.controller.show_warning(message) return if idx_field_code == -1: message = "Field '{}' not found in layer '{}'. Open '{}' and check parameter '{}'" \ .format(self.params['portal_field_code'], layer.name(), self.setting_file, 'portal_field_code') self.controller.show_warning(message) return if idx_field_number == -1: message = "Field '{}' not found in layer '{}'. Open '{}' and check parameter '{}'" \ .format(self.params['portal_field_number'], layer.name(), self.setting_file, 'portal_field_number') self.controller.show_warning(message) return self.dlg.address_number.blockSignals(True) self.dlg.address_number.clear() if fill_combo: it = layer.getFeatures(QgsFeatureRequest(expr)) for feature in it: attrs = feature.attributes() field_number = attrs[idx_field_number] if not type(field_number) is QPyNullVariant: elem = [code, field_number] records.append(elem) # Fill numbers combo records_sorted = sorted(records, key=operator.itemgetter(1)) for record in records_sorted: self.dlg.address_number.addItem(record[1], record) self.dlg.address_number.blockSignals(False) # Get a featureIterator from an expression: # Select featureswith the ids obtained it = layer.getFeatures(QgsFeatureRequest(expr)) ids = [i.id() for i in it] layer.selectByIds(ids) # Zoom to selected feature of the layer self.zoom_to_selected_features(layer, 'arc') def address_zoom_portal(self): """ Show street data on the canvas when selected street and number in street tab """ # Get selected street street = utils_giswater.getWidgetText(self.dlg.address_street) civic = utils_giswater.getWidgetText(self.dlg.address_number) if street == 'null' or civic == 'null': return # Get selected portal elem = self.dlg.address_number.itemData(self.dlg.address_number.currentIndex()) if not elem: # that means that user has edited manually the combo but the element # does not correspond to any combo element message = 'Element {} does not exist'.format(civic) self.controller.show_warning(message) return # select this feature in order to copy to memory layer aux = (self.params['portal_field_code'] + " = '" + str(elem[0]) + "'" " AND " + self.params['portal_field_number'] + " = '" + str(elem[1]) + "'") expr = QgsExpression(aux) if expr.hasParserError(): message = expr.parserErrorString() + ": " + aux self.controller.show_warning(message) return # Get a featureIterator from an expression # Build a list of feature Ids from the previous result # Select featureswith the ids obtained layer = self.layers['portal_layer'] it = self.layers['portal_layer'].getFeatures(QgsFeatureRequest(expr)) ids = [i.id() for i in it] layer.selectByIds(ids) # Zoom to selected feature of the layer self.zoom_to_selected_features(self.layers['portal_layer'], 'node') # Toggles 'Show feature count' self.show_feature_count() def generic_zoom(self, fieldname, combo, field_index=0): """ Get selected element from the combo, and returns a feature request expression """ # Get selected element from combo element = utils_giswater.getWidgetText(combo) if element == 'null': return None elem = combo.itemData(combo.currentIndex()) if not elem: # that means that user has edited manually the combo but the element # does not correspond to any combo element message = 'Element {} does not exist'.format(element) self.controller.show_warning(message) return None # Check if the expression is valid aux = fieldname + " = '" + str(elem[field_index]) + "'" expr = QgsExpression(aux) if expr.hasParserError(): message = expr.parserErrorString() + ": " + aux self.controller.show_warning(message) return return expr def populate_combo(self, parameter, combo, fieldname, fieldname_2=None): """ Populate selected combo from features of selected layer """ # Check if we have this search option available if not parameter in self.layers: return False # Fields management layer = self.layers[parameter] records = [] idx_field = layer.fieldNameIndex(fieldname) if idx_field == -1: message = "Field '{}' not found in the layer specified in parameter '{}'".format(fieldname, parameter) self.controller.show_warning(message) return False idx_field_2 = idx_field if fieldname_2 is not None: idx_field_2 = layer.fieldNameIndex(fieldname_2) if idx_field_2 == -1: message = "Field '{}' not found in the layer specified in parameter '{}'".format(fieldname_2, parameter) self.controller.show_warning(message) return False # Iterate over all features to get distinct records list_elements = [] for feature in layer.getFeatures(): attrs = feature.attributes() field = attrs[idx_field] field_2 = attrs[idx_field_2] if not type(field) is QPyNullVariant: if field not in list_elements: elem = [field, field_2] list_elements.append(field) records.append(elem) # Fill combo box combo.blockSignals(True) combo.clear() records_sorted = sorted(records, key=operator.itemgetter(1)) combo.addItem('', '') hydrometer_list = [] hydrometer_list.append('') for i in range(len(records_sorted)): record = records_sorted[i] combo.addItem(str(record[1]), record) if record[1] != '': hydrometer_list.append(record[1]) self.set_model_by_list(hydrometer_list, self.dlg.hydrometer_id) combo.blockSignals(False) return True def show_feature_count(self): """ Toggles 'Show Feature Count' of all the layers in the root path of the TOC """ root = QgsProject.instance().layerTreeRoot() for child in root.children(): if isinstance(child, QgsLayerTreeLayer): child.setCustomProperty("showFeatureCount", True) def zoom_to_selected_features(self, layer, geom_type): """ Zoom to selected features of the @layer with @geom_type """ if not layer: return self.iface.setActiveLayer(layer) self.iface.actionZoomToSelected().trigger() # Set scale = scale_zoom if geom_type in ('node', 'connec', 'gully'): scale = self.scale_zoom # Set scale = max(current_scale, scale_zoom) elif geom_type == 'arc': scale = self.iface.mapCanvas().scale() if int(scale) < int(self.scale_zoom): scale = self.scale_zoom self.iface.mapCanvas().zoomScale(float(scale)) def unload(self): """ Removes dialog """ if self.dlg: self.dlg.deleteLater() del self.dlg def set_table_columns(self, widget, table_name): """ Configuration of tables. Set visibility and width of columns """ widget = utils_giswater.getWidget(widget) if not widget: return # Set width and alias of visible columns columns_to_delete = [] sql = ("SELECT column_index, width, alias, status" " FROM " + self.schema_name + ".config_client_forms" " WHERE table_id = '" + table_name + "'" " ORDER BY column_index") rows = self.controller.get_rows(sql, log_info=False) if not rows: return for row in rows: if not row['status']: columns_to_delete.append(row['column_index'] - 1) else: width = row['width'] if width is None: width = 100 widget.setColumnWidth(row['column_index'] - 1, width) widget.model().setHeaderData(row['column_index'] - 1, Qt.Horizontal, row['alias']) # Set order # widget.model().setSort(0, Qt.AscendingOrder) widget.model().select() # Delete columns for column in columns_to_delete: widget.hideColumn(column) def load_settings(self, dialog=None): """ Load QGIS settings related with dialog position and size """ if dialog is None: dialog = self.dlg try: width = self.controller.plugin_settings_value(dialog.objectName() + "_width", dialog.width()) height = self.controller.plugin_settings_value(dialog.objectName() + "_height", dialog.height()) x = self.controller.plugin_settings_value(dialog.objectName() + "_x") y = self.controller.plugin_settings_value(dialog.objectName() + "_y") if int(x) < 0 or int(y) < 0: dialog.resize(int(width), int(height)) else: dialog.setGeometry(int(x), int(y), int(width), int(height)) except: pass def save_settings(self, dialog=None): """ Save QGIS settings related with dialog position and size """ if dialog is None: dialog = self.dlg self.controller.plugin_settings_set_value(dialog.objectName() + "_width", dialog.width()) self.controller.plugin_settings_set_value(dialog.objectName() + "_height", dialog.height()) self.controller.plugin_settings_set_value(dialog.objectName() + "_x", dialog.pos().x() + 8) self.controller.plugin_settings_set_value(dialog.objectName() + "_y", dialog.pos().y() + 31) def close_dialog(self, dlg=None): """ Close dialog """ if dlg is None or type(dlg) is bool: dlg = self.dlg try: self.save_settings(dlg) dlg.close() map_tool = self.canvas.mapTool() # If selected map tool is from the plugin, set 'Pan' as current one if map_tool.toolName() == '': self.iface.actionPan().trigger() except AttributeError: pass
def __init__(self, parent=None): QSortFilterProxyModel.__init__(self, parent)
class AdaptersTableView(QTableView): """ Adapters table view """ DataChanged = pyqtSignal() def __init__(self, parent, helper, testParams, testDescrs): """ Description table view constructor """ QTableView.__init__(self, parent) self.__parent = parent self.helper = helper self.testParams = testParams self.testDescrs = testDescrs self.createWidgets() self.createConnections() self.createActions() def getAgents(self): """ Get test agents """ return self.testParams.agents.table().model.getData() def getInputs(self): """ Get test inputs """ return self.testParams.parameters.table().model.getData() def getOutputs(self): """ Get test outputs """ return self.testParams.parametersOutput.table().model.getData() def createWidgets(self): """ Create qt widgets """ self.proxyModel = QSortFilterProxyModel(self) self.proxyModel.setDynamicSortFilter(True) self.model = DescriptionTableModel(self) self.setModel(self.proxyModel) self.proxyModel.setSourceModel(self.model) self.setFrameShape(QFrame.StyledPanel) self.setShowGrid(True) self.setGridStyle(Qt.DotLine) self.setSelectionMode(QAbstractItemView.SingleSelection) self.setSelectionBehavior(QAbstractItemView.SelectRows) self.setContextMenuPolicy(Qt.CustomContextMenu) self.verticalHeader().setVisible(False) self.horizontalHeader().setHighlightSections(False) self.setHorizontalScrollMode(QAbstractItemView.ScrollPerPixel) self.horizontalHeader().setStretchLastSection(True) self.setItemDelegateForColumn(COL_SUMMARY_ACTION, AdapterDelegate(self)) self.setColumnWidth(COL_ID_ACTION, 45) def createConnections(self): """ Create qt connections """ self.customContextMenuRequested.connect(self.onPopupMenu) self.clicked.connect(self.onAbstractItemClicked) def createActions(self): """ Qt actions """ self.delAction = QtHelper.createAction( self, self.tr("&Delete"), self.deleteAction, icon=QIcon(":/adapters-del.png"), tip=self.tr('Delete the selected adapter')) self.delAllAction = QtHelper.createAction( self, self.tr("&Delete All"), self.clearItems, icon=QIcon(":/test-parameter-clear.png"), tip=self.tr('Delete all adapters')) # set default actions self.delAction.setEnabled(False) self.delAllAction.setEnabled(False) def onAbstractItemClicked(self): """ Called on item clicked """ indexes = self.selectedIndexes() if not indexes: self.delAction.setEnabled(False) else: self.delAction.setEnabled(True) def deleteAction(self): """ Delete action """ indexes = self.selectedIndexes() if not indexes: return # map proxy indexes to source sourceIndexes = [] for proxyIndex in indexes: if not proxyIndex.isValid(): return else: sourceIndexes.append(self.proxyModel.mapToSource(proxyIndex)) if sourceIndexes: answer = QMessageBox.question( self, self.tr("Remove"), self.tr("Do you want to remove the selection?"), QMessageBox.Yes | QMessageBox.No) if answer == QMessageBox.Yes: self.removeValues(sourceIndexes) def removeValues(self, indexes): """ Remove values from data @param indexes: @type indexes: """ if not indexes: return # data from model datas = self.model.getData() # remove duplicate index cleanIndexes = {} for index in indexes: if index.row() not in cleanIndexes: cleanIndexes[index.row()] = index for cleanIndex in list(cleanIndexes.keys()): # for python3 support datas.pop(cleanIndex) self.model.beginResetModel() self.model.endResetModel() self.setData(signal=True) def getHelpAdapters(self): """ Return the help of all adapters according to the current version of the test """ testDescrs = self.testDescrs.table().model.getData() currentAdpVersion = None for descr in testDescrs: if descr['key'] == 'adapters': currentAdpVersion = descr['value'] break return Helper.instance().helpAdapters(name=currentAdpVersion) def onPopupMenu(self, pos): """ Display menu on right click @param pos: @type pos: """ self.menu = QMenu(self) index = self.currentIndex() indexes = self.selectedIndexes() adapters = self.getHelpAdapters() # adapters adpsMenu = QMenu("Add", self) if adapters is not None: for adp in adapters: adpMenu = QMenu(adp['name'], self) adpsMenu.addMenu(adpMenu) for cls in adp['classes']: # extract __init__ function only fct = None for fct in cls['functions']: if fct['name'] == '__init__': break if fct is not None: argsFct = self.parseDocString(docstring=fct['desc']) argsFct['function'] = "%s::%s" % (adp['name'], cls['name']) argsFct['main-name'] = "%s" % adp['name'] argsFct['sub-name'] = "%s" % cls['name'] if 'default-args' in fct: self.addDefaultValues( defaultValues=fct['default-args'], currentFunction=argsFct) adpMenu.addAction( QtHelper.createAction(self, cls['name'], self.addAdapter, cb_arg=argsFct)) if not indexes: self.delAction.setEnabled(False) self.menu.addAction(self.delAction) self.menu.addSeparator() self.menu.addMenu(adpsMenu) self.menu.addSeparator() else: self.delAction.setEnabled(True) self.menu.addAction(self.delAction) self.menu.addSeparator() self.menu.addMenu(adpsMenu) self.menu.addSeparator() self.menu.popup(self.mapToGlobal(pos)) def addDefaultValues(self, defaultValues, currentFunction): """ Add default values """ for curArg in currentFunction['obj']: for k, v in defaultValues: if k == curArg['name']: curArg['advanced'] = "True" if curArg['type'] in ['strconstant', 'intconstant']: curArg['default-value'] = self.parseConstant( descr=curArg['descr']) else: curArg['default-value'] = unicode(v) def parseDocString(self, docstring): """ Parse doc string """ val = {} desc = docstring.strip() desc_splitted = desc.splitlines() val['return-value'] = "False" params = [] param = {} for line in desc_splitted: line = line.strip() if line.startswith('@param '): paramName = line.split(':', 1)[0].split('@param ')[1].strip() paramDescr = line.split(':', 1)[1].strip() param['name'] = paramName param['value'] = '' param['descr'] = paramDescr param['selected-type'] = '' param['advanced'] = "False" elif line.startswith('@type '): paramType = line.split(':', 1)[1].strip() param['type'] = paramType params.append(param) param = {} elif line.startswith('@return'): val['return-value'] = "True" val['return-descr'] = line.split(':', 1)[1].strip() else: pass val['obj'] = params return val def parseConstant(self, descr): """ Parse constant """ tmpvals = descr.split("|") nameConstant = '' for zz in xrange(len(tmpvals)): if '(default)' in tmpvals[zz]: nameConstant = tmpvals[zz].split('(default)')[0].strip() return nameConstant def addAdapter(self, fctParams): """ Add testcase function """ actionId = self.getActionId() tpl = {'action': ACTION_ADAPTER, 'data': fctParams} self.insertItem(actionParams=tpl) def getActionId(self): """ Return action Id """ data = self.model.getData() actionId = len(data) + 1 return actionId def insertItem(self, actionParams): """ Insert item """ indexes = self.selectedIndexes() if not len(indexes): row = self.model.rowCount() else: index = self.currentIndex() row = index.row() data = self.model.getData() # add data to model data.insert(row + 1, actionParams) # self.model.reset() self.model.beginResetModel() self.model.endResetModel() # open properties on adding, workaround to fix an error (bad agent type) actionDialog = GenericConfigDialog.ActionDialog( self, self.helper, actionParams, owner=self, variables=[], adapterMode=True, testParams=self.testParams, noCancel=True) actionDialog.exec_() newActionParams = actionDialog.getValues() data[row]['data']['obj'] = newActionParams self.delAllAction.setEnabled(True) self.setData() def setAdapters(self, adapters): """ Set adapters """ self.model.setDataModel(adapters) self.setData(signal=False) def clearItems(self): """ Clear all items """ reply = QMessageBox.question(self, self.tr("Clear all adapters"), self.tr("Are you sure ?"), QMessageBox.Yes | QMessageBox.No) if reply == QMessageBox.Yes: data = self.model.getData() try: for i in xrange(len(data)): data.pop() except Exception as e: pass # self.model.reset() self.model.beginResetModel() self.model.endResetModel() self.setData() self.delAllAction.setEnabled(False) self.delAction.setEnabled(False) def clear(self): """ clear contents """ self.model.setDataModel([]) def setData(self, signal=True): """ Set table data @param signal: @type signal: boolean """ if signal: self.DataChanged.emit()
def __init__(self, isProjectFilter, parent=None): QSortFilterProxyModel.__init__(self, parent) self.__sortColumn = None # Avoid pylint complains self.__sortOrder = None # Avoid pylint complains self.__shouldFilter = isProjectFilter return
class SearchPlus(QObject): def __init__(self, iface, srid, controller): """ Constructor """ self.iface = iface self.srid = srid self.controller = controller self.schema_name = self.controller.schema_name self.project_type = self.controller.get_project_type() self.feature_cat = {} # Create dialog self.dlg = SearchPlusDockWidget(self.iface.mainWindow()) # Load configuration data from tables if not self.load_config_data(): self.enabled = False return sql = ("SELECT value FROM " + self.controller.schema_name + ".config_param_system WHERE parameter='street_field_expl'") self.street_field_expl = self.controller.get_row(sql) if not self.street_field_expl: message = "Param street_field_expl not found" self.controller.show_warning(message) return sql = ("SELECT value FROM " + self.controller.schema_name + ".config_param_system WHERE parameter='portal_field_postal'") portal_field_postal = self.controller.get_row(sql) if not portal_field_postal: message = "Param portal_field_postal not found" self.controller.show_warning(message) return # Set signals self.dlg.address_exploitation.currentIndexChanged.connect(partial(self.address_fill_postal_code, self.dlg.address_postal_code)) self.dlg.address_exploitation.currentIndexChanged.connect(partial(self.address_populate, self.dlg.address_street, 'street_layer', 'street_field_code', 'street_field_name')) self.dlg.address_exploitation.currentIndexChanged.connect(partial(self.address_get_numbers, self.dlg.address_exploitation, self.street_field_expl[0], False)) self.dlg.address_postal_code.currentIndexChanged.connect(partial(self.address_get_numbers, self.dlg.address_postal_code, portal_field_postal[0], False)) self.dlg.address_street.activated.connect(partial(self.address_get_numbers, self.dlg.address_street, self.params['portal_field_code'], True)) self.dlg.address_number.activated.connect(partial(self.address_zoom_portal)) self.dlg.network_geom_type.activated.connect(partial(self.network_geom_type_changed)) self.dlg.network_code.activated.connect(partial(self.network_zoom, self.dlg.network_code, self.dlg.network_geom_type)) self.dlg.network_code.editTextChanged.connect(partial(self.filter_by_list, self.dlg.network_code)) self.dlg.hydrometer_connec.activated.connect(partial(self.hydrometer_get_hydrometers)) self.dlg.hydrometer_id.activated.connect(partial(self.hydrometer_zoom, self.params['hydrometer_urban_propierties_field_code'], self.dlg.hydrometer_connec)) self.dlg.hydrometer_id.editTextChanged.connect(partial(self.filter_by_list, self.dlg.hydrometer_id)) self.dlg.workcat_id.activated.connect(partial(self.workcat_open_table_items)) self.enabled = True def workcat_populate(self, combo): """ Fill @combo """ sql = ("SELECT DISTINCT(workcat_id) FROM " + self.controller.schema_name + ".arc" " WHERE workcat_id LIKE '%%' or workcat_id is NULL" " UNION" " SELECT DISTINCT(workcat_id) FROM " + self.controller.schema_name + ".connec" " WHERE workcat_id LIKE '%%' or workcat_id is NULL" " UNION" " SELECT DISTINCT(workcat_id) FROM " + self.controller.schema_name + ".node" " WHERE workcat_id LIKE '%%' or workcat_id is NULL") if self.project_type == 'ud': sql += (" UNION" " SELECT DISTINCT(workcat_id) FROM " + self.controller.schema_name + ".gully" " WHERE workcat_id LIKE '%%' or workcat_id is NULL") rows = self.controller.get_rows(sql) utils_giswater.fillComboBox(combo, rows) return rows def workcat_open_table_items(self): """ Create the view and open the dialog with his content """ self.workcat_id = utils_giswater.getWidgetText(self.dlg.workcat_id) if self.workcat_id == "null": return False self.items_dialog = ListItems() utils_giswater.setDialog(self.items_dialog) self.tbl_psm = self.items_dialog.findChild(QTableView, "tbl_psm") self.tbl_psm.setSelectionBehavior(QAbstractItemView.SelectRows) self.items_dialog.btn_accept.pressed.connect(partial(self.workcat_zoom)) self.items_dialog.btn_cancel.pressed.connect(self.items_dialog.close) self.items_dialog.txt_name.textChanged.connect(partial(self.workcat_filter_by_text, self.tbl_psm, self.items_dialog.txt_name)) self.workcat_fill_table(self.workcat_id) self.items_dialog.exec_() def workcat_zoom(self): """ Zoom feature with the code set in 'network_code' of the layer set in 'network_geom_type' """ # Get selected code from combo element = self.tbl_psm.selectionModel().selectedRows() if len(element) == 0: message = "Any record selected" self.controller.show_warning(message) return row = element[0].row() feature_id = self.tbl_psm.model().record(row).value(2) # Get selected layer geom_type = self.tbl_psm.model().record(row).value('feature_type').lower() fieldname = geom_type + "_id" self.items_dialog.close() # Check if the expression is valid aux = fieldname + " = '" + str(feature_id) + "'" expr = QgsExpression(aux) if expr.hasParserError(): message = expr.parserErrorString() + ": " + aux self.controller.show_warning(message) return for value in self.feature_cat.itervalues(): if value.type.lower() == geom_type: layer = self.controller.get_layer_by_layername(value.layername) if layer: it = layer.getFeatures(QgsFeatureRequest(expr)) ids = [i.id() for i in it] layer.selectByIds(ids) # If any feature found, zoom it and exit function if layer.selectedFeatureCount() > 0: self.workcat_open_custom_form(layer, expr) self.zoom_to_selected_features(layer) return def workcat_open_custom_form(self, layer, expr): """ Open custom form from selected layer """ it = layer.getFeatures(QgsFeatureRequest(expr)) features = [i for i in it] if features: self.iface.openFeatureForm(layer, features[0]) def workcat_fill_table(self, workcat_id): """ Fill table @widget filtering query by @workcat_id """ result_select = utils_giswater.getWidgetText(self.items_dialog.txt_name) if result_select != 'null': expr = " feature_id LIKE '%" + result_select + "%'" # Refresh model with selected filter self.controller.log_info(expr) self.tbl_psm.model().setFilter(expr) self.tbl_psm.model().select() return # Define SQL sql = ("SELECT 'NODE' as feature_type, nodecat_id AS featurecat_id, node_id AS feature_id, code, name as state" " FROM " + self.schema_name + ".v_edit_node JOIN " + self.schema_name + ".value_state ON id = state" " WHERE workcat_id = '" + str(workcat_id) + "'" " UNION" " SELECT 'ARC', arccat_id, arc_id, code, name" " FROM " + self.schema_name + ".v_edit_arc JOIN " + self.schema_name + ".value_state ON id = state" " WHERE workcat_id = '" + str(workcat_id) + "'" " UNION" " SELECT 'ELEMENT', elementcat_id, element_id, code, name" " FROM " + self.schema_name + ".v_edit_element JOIN " + self.schema_name + ".value_state ON id = state" " WHERE workcat_id = '" + str(workcat_id) + "'" " UNION" " SELECT 'CONNEC', connecat_id, connec_id, code, name" " FROM " + self.schema_name + ".v_edit_connec JOIN " + self.schema_name + ".value_state ON id = state" " WHERE workcat_id = '" + str(workcat_id) + "'") # Set model self.model = QSqlQueryModel() self.model.setQuery(sql) # Check for errors if self.model.lastError().isValid(): self.controller.show_warning(self.model.lastError().text()) # Attach model to table view self.tbl_psm.setModel(self.model) def workcat_filter_by_text(self, table, widget_txt): result_select = utils_giswater.getWidgetText(widget_txt) if result_select != 'null': expr = " feature_id LIKE '%" + result_select + "%'" # Refresh model with selected filter table.model().setFilter(expr) table.model().select() else: self.workcat_fill_table(self.workcat_id) def address_fill_postal_code(self, combo): """ Fill @combo """ # Get exploitation code: 'expl_id' elem = self.dlg.address_exploitation.itemData(self.dlg.address_exploitation.currentIndex()) code = elem[0] # Get postcodes related with selected 'expl_id' sql = "SELECT DISTINCT(postcode) FROM " + self.controller.schema_name + ".ext_address" if code != -1: sql += " WHERE "+self.street_field_expl[0]+"= '" + str(code) + "'" sql += " ORDER BY postcode" rows = self.controller.get_rows(sql) if not rows: return False records = [(-1, '', '')] for row in rows: field_code = row[0] elem = [field_code, field_code, None] records.append(elem) # Fill combo combo.blockSignals(True) combo.clear() records_sorted = sorted(records, key=operator.itemgetter(1)) for i in range(len(records_sorted)): record = records_sorted[i] combo.addItem(str(record[1]), record) combo.blockSignals(False) return True def load_config_data(self): """ Load configuration data from tables """ self.params = {} sql = "SELECT parameter, value FROM " + self.controller.schema_name + ".config_param_system" sql += " WHERE context = 'searchplus' ORDER BY parameter" rows = self.controller.get_rows(sql) if rows: for row in rows: self.params[row['parameter']] = str(row['value']) return True else: self.controller.log_warning("Parameters related with 'searchplus' not set in table 'config_param_system'") return False # Get scale zoom self.scale_zoom = 2500 sql = "SELECT value FROM " + self.schema_name + ".config_param_system" sql += " WHERE parameter = 'scale_zoom'" row = self.controller.get_row(sql) if row: self.scale_zoom = row['value'] def dock_dialog(self): """ Dock dialog into left dock widget area """ # Get path of .ui file ui_path = os.path.join(self.controller.plugin_dir, 'search', 'ui', 'search_plus_dialog.ui') if not os.path.exists(ui_path): self.controller.show_warning("File not found", parameter=ui_path) return False # Make it dockable in left dock widget area self.dock = uic.loadUi(ui_path) self.iface.addDockWidget(Qt.LeftDockWidgetArea, self.dlg) self.dlg.setFixedHeight(162) # Set his backgroundcolor p = self.dlg.palette() self.dlg.setAutoFillBackground(True) p.setColor(self.dlg.backgroundRole(), Qt.white) self.dlg.setPalette(p) return True def get_layers(self): """ Iterate over all layers to get the ones set in config file """ # Check if we have any layer loaded layers = self.iface.legendInterface().layers() if len(layers) == 0: return # Iterate over all layers to get the ones specified parameters '*_layer' self.layers = {} for cur_layer in layers: layer_source = self.controller.get_layer_source(cur_layer) uri_table = layer_source['table'] if uri_table is not None: if self.params['expl_layer'] == uri_table: self.layers['expl_layer'] = cur_layer if self.params['street_layer'] == uri_table: self.layers['street_layer'] = cur_layer if self.params['portal_layer'] == uri_table: self.layers['portal_layer'] = cur_layer if self.params['hydrometer_layer'] == uri_table: self.layers['hydrometer_layer'] = cur_layer if self.params['hydrometer_urban_propierties_layer'] == uri_table: self.layers['hydrometer_urban_propierties_layer'] = cur_layer if self.params['network_layer_arc'] == uri_table: self.layers['network_layer_arc'] = cur_layer if self.params['network_layer_connec'] == uri_table: self.layers['network_layer_connec'] = cur_layer if self.params['network_layer_element'] == uri_table: self.layers['network_layer_element'] = cur_layer if self.params['network_layer_gully'] == uri_table: self.layers['network_layer_gully'] = cur_layer if self.params['network_layer_node'] == uri_table: self.layers['network_layer_node'] = cur_layer def populate_dialog(self): """ Populate the interface with values get from layers """ if not self.enabled: return False # Get layers and full extent self.get_layers() # Tab 'WorkCat' self.dlg.workcat_items_list.setVisible(False) status = self.workcat_populate(self.dlg.workcat_id) if not status: self.dlg.tab_main.removeTab(3) # Tab 'Address' status = self.address_populate(self.dlg.address_exploitation, 'expl_layer', 'expl_field_code', 'expl_field_name') if not status: self.dlg.tab_main.removeTab(2) else: # Get project variable 'expl_id' expl_id = QgsExpressionContextUtils.projectScope().variable(str(self.street_field_expl[0])) if expl_id is not None: self.controller.log_info(expl_id) # Set SQL to get 'expl_name' sql = "SELECT " + self.params['expl_field_name'] + " FROM " + self.controller.schema_name + "." + self.params['expl_layer'] sql += " WHERE " + self.params['expl_field_code'] + " = " + str(expl_id) row = self.controller.get_row(sql) if row: utils_giswater.setSelectedItem(self.dlg.address_exploitation, row[0]) # Tab 'Hydrometer' self.populate_combo('hydrometer_urban_propierties_layer', self.dlg.hydrometer_connec, self.params['hydrometer_field_urban_propierties_code']) status = self.populate_combo('hydrometer_layer', self.dlg.hydrometer_id, self.params['hydrometer_field_urban_propierties_code'], self.params['hydrometer_field_code']) if not status: self.dlg.tab_main.removeTab(1) # Tab 'Network' self.network_code_create_lists() status = self.network_geom_type_populate() if not status: self.dlg.tab_main.removeTab(0) return True def network_code_create_lists(self): """ Create one list for each geom type and other one with all geom types """ self.list_arc = [] self.list_connec = [] self.list_element = [] self.list_gully = [] self.list_node = [] self.list_all = [] # Check which layers are available and get its list of codes if 'network_layer_arc' in self.layers: self.list_arc = self.network_code_layer('network_layer_arc') if 'network_layer_connec' in self.layers: self.list_connec = self.network_code_layer('network_layer_connec') if 'network_layer_element' in self.layers: self.list_element = self.network_code_layer('network_layer_element') if 'network_layer_gully' in self.layers: self.list_gully = self.network_code_layer('network_layer_gully') if 'network_layer_node' in self.layers: self.list_node = self.network_code_layer('network_layer_node') try: self.list_all = self.list_arc + self.list_connec + self.list_element + self.list_gully + self.list_node self.list_all = sorted(set(self.list_all)) self.set_model_by_list(self.list_all, self.dlg.network_code) except: pass return True def network_code_layer(self, layername): """ Get codes of selected layer and add them to the combo 'network_code' """ viewname = self.params[layername] feature_type = viewname.split("_") if len(feature_type) < 3: return field_id = str(feature_type[2]).lower() field_type = "" if self.project_type == 'ws': if str(feature_type[2]) == "arc": feature_type[2] = "cat_arc" field_type = feature_type[2] + "type_id" elif self.project_type == 'ud': field_type = feature_type[2] + "_type" sql = ("SELECT DISTINCT(" + str(field_id) + "_id), " + str(field_type) + "" " FROM " + self.controller.schema_name + "." + viewname + "" " WHERE " + str(field_id) + "_id IS NOT NULL" " ORDER BY " + str(field_id) + "_id") rows = self.controller.get_rows(sql) if not rows: return False list_codes = [''] for row in rows: list_codes.append(row[0] + " " + row[1]) return list_codes def network_geom_type_populate(self): """ Populate combo 'network_geom_type' """ # Add null value self.dlg.network_geom_type.clear() self.dlg.network_geom_type.addItem('') # Check which layers are available if 'network_layer_arc' in self.layers: self.dlg.network_geom_type.addItem(self.controller.tr('Arc')) if 'network_layer_connec' in self.layers: self.dlg.network_geom_type.addItem(self.controller.tr('Connec')) if 'network_layer_element' in self.layers: self.dlg.network_geom_type.addItem(self.controller.tr('Element')) if 'network_layer_gully' in self.layers: self.dlg.network_geom_type.addItem(self.controller.tr('Gully')) if 'network_layer_node' in self.layers: self.dlg.network_geom_type.addItem(self.controller.tr('Node')) return self.dlg.network_geom_type > 0 def network_geom_type_changed(self): """ Get 'geom_type' to filter 'code' values """ geom_type = utils_giswater.getWidgetText(self.dlg.network_geom_type) list_codes = [] if geom_type == self.controller.tr('Arc'): list_codes = self.list_arc elif geom_type == self.controller.tr('Connec'): list_codes = self.list_connec elif geom_type == self.controller.tr('Element'): list_codes = self.list_element elif geom_type == self.controller.tr('Gully'): list_codes = self.list_gully elif geom_type == self.controller.tr('Node'): list_codes = self.list_node else: list_codes = self.list_all self.set_model_by_list(list_codes, self.dlg.network_code) return True def set_model_by_list(self, string_list, widget): model = QStringListModel() model.setStringList(string_list) self.proxy_model = QSortFilterProxyModel() self.proxy_model.setSourceModel(model) self.proxy_model.setFilterKeyColumn(0) proxy_model_aux = QSortFilterProxyModel() proxy_model_aux.setSourceModel(model) proxy_model_aux.setFilterKeyColumn(0) widget.setModel(proxy_model_aux) widget.setModelColumn(0) completer = QCompleter() completer.setModel(self.proxy_model) completer.setCompletionColumn(0) completer.setCompletionMode(QCompleter.UnfilteredPopupCompletion) widget.setCompleter(completer) def filter_by_list(self, widget): self.proxy_model.setFilterFixedString(widget.currentText()) def network_zoom(self, network_code, network_geom_type): """ Zoom feature with the code set in 'network_code' of the layer set in 'network_geom_type' """ # Get selected code from combo element = utils_giswater.getWidgetText(network_code) if element == 'null': return # Split element. [0]: feature_id, [1]: cat_feature_id row = element.split(' ', 1) feature_id = str(row[0]) cat_feature_id = str(row[1]) # Get selected layer geom_type = utils_giswater.getWidgetText(network_geom_type).lower() if geom_type == "null": sql = ("SELECT feature_type FROM " + self.controller.schema_name + ".cat_feature" " WHERE id = '" + cat_feature_id + "'") row = self.controller.get_row(sql) if not row: return geom_type = row[0].lower() fieldname = geom_type + "_id" # Check if the expression is valid aux = fieldname + " = '" + feature_id + "'" expr = QgsExpression(aux) if expr.hasParserError(): message = expr.parserErrorString() + ": " + aux self.controller.show_warning(message) return for value in self.feature_cat.itervalues(): if value.type.lower() == geom_type: layer = self.controller.get_layer_by_layername(value.layername) if layer: it = layer.getFeatures(QgsFeatureRequest(expr)) ids = [i.id() for i in it] layer.selectByIds(ids) # If any feature found, zoom it and exit function if layer.selectedFeatureCount() > 0: self.zoom_to_selected_features(layer) return def hydrometer_get_hydrometers(self): """ Populate hydrometers depending on selected connec """ # Get selected connec selected = utils_giswater.getWidgetText(self.dlg.hydrometer_connec) # If any conenc selected, get again all hydrometers if selected == 'null': self.populate_combo('hydrometer_layer', self.dlg.hydrometer_id, self.params['hydrometer_field_urban_propierties_code'], self.params['hydrometer_field_code']) return # Get connec_id elem = self.dlg.hydrometer_connec.itemData(self.dlg.hydrometer_connec.currentIndex()) code = elem[0] # to know the index see the query that populate the combo records = [[-1, '']] # Set filter expression layer = self.layers['hydrometer_layer'] idx_field_code = layer.fieldNameIndex(self.params['hydrometer_field_urban_propierties_code']) idx_field_number = layer.fieldNameIndex(self.params['hydrometer_field_code']) aux = self.params['hydrometer_field_urban_propierties_code'] + " = '" + str(code) + "'" # Check filter and existence of fields expr = QgsExpression(aux) if expr.hasParserError(): message = expr.parserErrorString() + ": " + aux self.controller.show_warning(message) return if idx_field_code == -1: message = "Field '{}' not found in layer '{}'. Open '{}' and check parameter '{}'" \ .format(self.params['hydrometer_field_urban_propierties_code'], layer.name(), self.setting_file, 'hydrometer_field_urban_propierties_code') self.controller.show_warning(message) return if idx_field_number == -1: message = "Field '{}' not found in layer '{}'. Open '{}' and check parameter '{}'" \ .format(self.params['hydrometer_field_code'], layer.name(), self.setting_file, 'hydrometer_field_code') self.controller.show_warning(message) return # Get a featureIterator from an expression: # Get features from the iterator and do something it = layer.getFeatures(QgsFeatureRequest(expr)) for feature in it: attrs = feature.attributes() field_number = attrs[idx_field_number] if not type(field_number) is QPyNullVariant: elem = [code, field_number] records.append(elem) # Fill hydrometers records_sorted = sorted(records, key=operator.itemgetter(1)) self.dlg.hydrometer_id.blockSignals(True) self.dlg.hydrometer_id.clear() hydrometer_list = [] #hydrometer_list.append('') for record in records_sorted: self.dlg.hydrometer_id.addItem(str(record[1]), record) if record[1] != '': hydrometer_list.append(str(record[1])) self.set_model_by_list(hydrometer_list, self.dlg.hydrometer_id) self.hydrometer_zoom(self.params['hydrometer_urban_propierties_field_code'], self.dlg.hydrometer_connec) self.dlg.hydrometer_id.blockSignals(False) def hydrometer_zoom(self, fieldname, combo): """ Zoom to layer set in parameter 'hydrometer_urban_propierties_layer' """ expr = self.generic_zoom(fieldname, combo) if expr is None: return # Build a list of feature id's from the expression and select them try: layer = self.layers['hydrometer_urban_propierties_layer'] except KeyError as e: self.controller.show_warning(str(e)) return False it = layer.getFeatures(QgsFeatureRequest(expr)) ids = [i.id() for i in it] layer.selectByIds(ids) # Zoom to selected feature of the layer self.zoom_to_selected_features(layer) # Toggles 'Show feature count' self.show_feature_count() def address_populate(self, combo, layername, field_code, field_name): """ Populate @combo """ # Check if we have this search option available if layername not in self.layers: return False # Get features layer = self.layers[layername] records = [(-1, '', '')] idx_field_code = layer.fieldNameIndex(self.params[field_code]) idx_field_name = layer.fieldNameIndex(self.params[field_name]) it = layer.getFeatures() if layername == 'street_layer': # Get 'expl_id' field_expl_id = self.street_field_expl[0] elem = self.dlg.address_exploitation.itemData(self.dlg.address_exploitation.currentIndex()) expl_id = elem[0] records = [[-1, '']] # Set filter expression aux = self.street_field_expl[0] + " = '" + str(expl_id) + "'" # Check filter and existence of fields expr = QgsExpression(aux) if expr.hasParserError(): message = expr.parserErrorString() + ": " + aux self.controller.show_warning(message) return it = layer.getFeatures(QgsFeatureRequest(expr)) # Iterate over features for feature in it: geom = feature.geometry() attrs = feature.attributes() value_code = attrs[idx_field_code] value_name = attrs[idx_field_name] if not type(value_code) is QPyNullVariant and geom is not None: elem = [value_code, value_name, geom.exportToWkt()] else: elem = [value_code, value_name, None] records.append(elem) # Fill combo combo.blockSignals(True) combo.clear() records_sorted = sorted(records, key = operator.itemgetter(1)) for record in records_sorted: combo.addItem(str(record[1]), record) combo.blockSignals(False) return True def address_get_numbers(self, combo, field_code, fill_combo=False): """ Populate civic numbers depending on value of selected @combo. Build an expression with @field_code """ # Get selected street selected = utils_giswater.getWidgetText(combo) if selected == 'null': return # Get street code elem = combo.itemData(combo.currentIndex()) code = elem[0] # to know the index see the query that populate the combo records = [[-1, '']] # Set filter expression layer = self.layers['portal_layer'] idx_field_code = layer.fieldNameIndex(field_code) idx_field_number = layer.fieldNameIndex(self.params['portal_field_number']) aux = field_code + " = '" + str(code) + "'" # Check filter and existence of fields expr = QgsExpression(aux) if expr.hasParserError(): message = expr.parserErrorString() + ": " + aux self.controller.show_warning(message) return if idx_field_code == -1: message = "Field '{}' not found in layer '{}'. Open '{}' and check parameter '{}'" \ .format(self.params['portal_field_code'], layer.name(), self.setting_file, 'portal_field_code') self.controller.show_warning(message) return if idx_field_number == -1: message = "Field '{}' not found in layer '{}'. Open '{}' and check parameter '{}'" \ .format(self.params['portal_field_number'], layer.name(), self.setting_file, 'portal_field_number') self.controller.show_warning(message) return self.dlg.address_number.blockSignals(True) self.dlg.address_number.clear() if fill_combo: it = layer.getFeatures(QgsFeatureRequest(expr)) for feature in it: attrs = feature.attributes() field_number = attrs[idx_field_number] if not type(field_number) is QPyNullVariant: elem = [code, field_number] records.append(elem) # Fill numbers combo records_sorted = sorted(records, key=operator.itemgetter(1)) for record in records_sorted: self.dlg.address_number.addItem(str(record[1]), record) self.dlg.address_number.blockSignals(False) # Get a featureIterator from an expression: # Select featureswith the ids obtained it = layer.getFeatures(QgsFeatureRequest(expr)) ids = [i.id() for i in it] layer.selectByIds(ids) # Zoom to selected feature of the layer self.zoom_to_selected_features(layer) def address_zoom_portal(self): """ Show street data on the canvas when selected street and number in street tab """ # Get selected street street = utils_giswater.getWidgetText(self.dlg.address_street) civic = utils_giswater.getWidgetText(self.dlg.address_number) if street == 'null' or civic == 'null': return # Get selected portal elem = self.dlg.address_number.itemData(self.dlg.address_number.currentIndex()) if not elem: # that means that user has edited manually the combo but the element # does not correspond to any combo element message = 'Element {} does not exist'.format(civic) self.controller.show_warning(message) return # select this feature in order to copy to memory layer aux = self.params['portal_field_code'] + " = '" + str(elem[0]) + "' AND " + self.params['portal_field_number'] + " = '" + str(elem[1]) + "'" expr = QgsExpression(aux) if expr.hasParserError(): message = expr.parserErrorString() + ": " + aux self.controller.show_warning(message) return # Get a featureIterator from an expression # Build a list of feature Ids from the previous result # Select featureswith the ids obtained layer = self.layers['portal_layer'] it = self.layers['portal_layer'].getFeatures(QgsFeatureRequest(expr)) ids = [i.id() for i in it] layer.selectByIds(ids) # Zoom to selected feature of the layer self.zoom_to_selected_features(self.layers['portal_layer']) # Toggles 'Show feature count' self.show_feature_count() def generic_zoom(self, fieldname, combo, field_index=0): """ Get selected element from the combo, and returns a feature request expression """ # Get selected element from combo element = utils_giswater.getWidgetText(combo) if element == 'null': return None elem = combo.itemData(combo.currentIndex()) if not elem: # that means that user has edited manually the combo but the element # does not correspond to any combo element message = 'Element {} does not exist'.format(element) self.controller.show_warning(message) return None # Check if the expression is valid aux = fieldname + " = '" + str(elem[field_index]) + "'" expr = QgsExpression(aux) if expr.hasParserError(): message = expr.parserErrorString() + ": " + aux self.controller.show_warning(message) return return expr def populate_combo(self, parameter, combo, fieldname, fieldname_2=None): """ Populate selected combo from features of selected layer """ # Check if we have this search option available if not parameter in self.layers: return False # Fields management layer = self.layers[parameter] records = [] idx_field = layer.fieldNameIndex(fieldname) if idx_field == -1: message = "Field '{}' not found in the layer specified in parameter '{}'".format(fieldname, parameter) self.controller.show_warning(message) return False idx_field_2 = idx_field if fieldname_2 is not None: idx_field_2 = layer.fieldNameIndex(fieldname_2) if idx_field_2 == -1: message = "Field '{}' not found in the layer specified in parameter '{}'".format(fieldname_2, parameter) self.controller.show_warning(message) return False # Iterate over all features to get distinct records list_elements = [] for feature in layer.getFeatures(): attrs = feature.attributes() field = attrs[idx_field] field_2 = attrs[idx_field_2] if not type(field) is QPyNullVariant: if field not in list_elements: elem = [field, field_2] list_elements.append(field) records.append(elem) # Fill combo box combo.blockSignals(True) combo.clear() records_sorted = sorted(records, key=operator.itemgetter(1)) combo.addItem('', '') hydrometer_list = [] hydrometer_list.append('') for i in range(len(records_sorted)): record = records_sorted[i] combo.addItem(str(record[1]), record) if record[1] != '': hydrometer_list.append(record[1]) self.set_model_by_list(hydrometer_list, self.dlg.hydrometer_id) combo.blockSignals(False) return True def show_feature_count(self): """ Toggles 'Show Feature Count' of all the layers in the root path of the TOC """ root = QgsProject.instance().layerTreeRoot() for child in root.children(): if isinstance(child, QgsLayerTreeLayer): child.setCustomProperty("showFeatureCount", True) def zoom_to_selected_features(self, layer): """ Zoom to selected features of the @layer """ if not layer: return self.iface.setActiveLayer(layer) self.iface.actionZoomToSelected().trigger() scale = self.iface.mapCanvas().scale() if int(scale) < int(self.scale_zoom): self.iface.mapCanvas().zoomScale(float(self.scale_zoom)) def unload(self): """ Removes dialog """ if self.dlg: self.dlg.deleteLater() del self.dlg
class DlgPais(QDialog, Ui_DlgPais): def __init__(self, parent): ''' Constructor ''' super(DlgPais, self).__init__(parent) self.setupUi(self) self.table = "" self.backmodel = QSqlQueryModel() self.database = parent.database self.filtermodel = QSortFilterProxyModel(self) self.filtermodel.setSourceModel(self.backmodel) self.filtermodel.setDynamicSortFilter(True) self.filtermodel.setFilterKeyColumn(-1) self.filtermodel.setFilterCaseSensitivity(Qt.CaseInsensitive) # self.tableview.setModel(self.filtermodel) self.setReadOnly(True) QTimer.singleShot(0, self.updateModels) @pyqtSlot("QString") def on_txtSearch_textChanged(self, text): """ Cambiar el filtro de busqueda """ self.filtermodel.setFilterRegExp(text) def setReadOnly(self, status): self.txtSearch.setText("") if status: self.editmodel = None self.swpanel.setCurrentIndex(0) self.txtnombre.setText("") self.txtcodigo.setText("") else: self.editmodel = PaisModel(self.database) self.swpanel.setCurrentIndex(1) # # if status: # self.tableview.setEditTriggers( QAbstractItemView.AllEditTriggers ) ## self.tableview.edit( self.tableview.selectionModel().currentIndex() ) # else: # self.tableview.setEditTriggers( QAbstractItemView.NoEditTriggers ) # # self.actionNew.setVisible( status ) # self.actionEdit.setVisible( status ) # self.actionDelete.setVisible( status ) # self.actionCancel.setVisible( not status ) # self.actionSave.setVisible(not status ) # self.backmodel.readOnly = status def updateModels(self): """ Actualizar los modelos, despues de toda operacion que cambie la base de datos se tienen que actualizar los modelos """ try: if not self.database.isOpen(): if not self.database.open(): raise UserWarning( u"No se pudo conectar con la base de datos") self.backmodel.setQuery( "Select codigoarea as 'Codigo Area' , nombre as Pais from paises" ) self.tableview.setModel(self.filtermodel) # self.tableview.setColumnHidden(0,True) # self.tableview.setColumnWidth(0,200) # self.tableview.set self.database.close() except: return False finally: if self.database.isOpen(): self.database.close() return True @pyqtSlot() def on_btnadd_clicked(self): self.setReadOnly(False) @pyqtSlot() def on_btncancelar_clicked(self): self.setReadOnly(True) @pyqtSlot() def on_btnguardar_clicked(self): self.editmodel.nombre = self.txtnombre.text() self.editmodel.codigo = self.txtcodigo.text() if self.editmodel.valid(): if self.editmodel.save(): QMessageBox.information(None, "Guardar", self.editmodel.mensaje) self.setReadOnly(True) self.updateModels() else: QMessageBox.critical(None, "Guardar", self.editmodel.mensaje) else: QMessageBox.critical(None, "Guardar", self.editmodel.mensaje)