Example #1
0
 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 )
Example #2
0
    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)
Example #4
0
    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 )
Example #5
0
    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)
Example #6
0
    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 )
Example #7
0
    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)
Example #9
0
    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
Example #10
0
 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)
Example #11
0
    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)
Example #12
0
    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
Example #14
0
    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 )
Example #15
0
    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 )
Example #16
0
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)
Example #17
0
    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() )
Example #18
0
    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
        )
Example #19
0
    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 )
Example #20
0
    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
Example #21
0
    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
Example #22
0
    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 = []
Example #23
0
    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)
Example #24
0
    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)
Example #25
0
    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)
Example #26
0
    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)
Example #27
0
	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)
Example #28
0
 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)
Example #29
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
Example #30
0
    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
Example #31
0
    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)
Example #32
0
    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()
Example #33
0
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)
Example #34
0
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)
Example #35
0
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)
Example #36
0
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)
Example #38
0
    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
Example #39
0
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)
Example #40
0
    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()
Example #41
0
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
Example #42
0
 def sort(self, column, order):
     " Sorts the items "
     self.__sortColumn = column
     self.__sortOrder = order
     QSortFilterProxyModel.sort(self, column, order)
     return
Example #43
0
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(
            "")
Example #44
0
 def sourceModel(self):
     """ @rtype: DataTypeKeysListModel """
     return QSortFilterProxyModel.sourceModel(self)
Example #45
0
 def headerData(self, section, orientation, role):
     if orientation != Qt.Vertical or role != Qt.DisplayRole:
         return QSortFilterProxyModel.headerData(self, section, orientation, role)
     return section+1
Example #46
0
 def __init__(self):
     QSortFilterProxyModel.__init__(self) 
     self.toggle_mode_sig.connect(self.toggle_mode)        
Example #47
0
    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())
Example #48
0
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)
Example #49
0
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_()
Example #50
0
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()
Example #51
0
 def __init__(self, parent):
     QSortFilterProxyModel.__init__(self, parent)
     core.fileFilter().regExpChanged.connect(self.invalidate)
Example #52
0
 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
Example #56
0
 def __init__(self, parent=None):
     QSortFilterProxyModel.__init__(self, parent)
Example #57
0
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()
Example #58
0
 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
Example #59
0
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
Example #60
0
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)