Esempio n. 1
0
    def _update_completer(self, values):
        #Get the items in a tuple and put them in a list
        field_formatter = self.config.LookupFormatters.get(
            self.currentFieldName(), None)

        # Store display and actual values in a
        # model for easier mapping and
        # retrieval when carrying out searches

        model_attr_mapping = []

        # Check if there are formaters specified
        # for the current field name
        for mv in values:
            f_model_values = []

            m_val = mv[0]

            #2-column model - display (0) and actual(1)
            if field_formatter is None:
                f_model_values.append(m_val)
                f_model_values.append(m_val)

            else:
                f_model_values.append(field_formatter(m_val))
                f_model_values.append(m_val)

            model_attr_mapping.append(f_model_values)

        self._completer_model = BaseSTDMTableModel(model_attr_mapping,
                                                   ["", ""], self)

        #We will use the QSortFilterProxyModel for filtering purposes
        self._proxy_completer_model = QSortFilterProxyModel()
        self._proxy_completer_model.setDynamicSortFilter(True)
        self._proxy_completer_model.setSourceModel(self._completer_model)
        self._proxy_completer_model.setSortCaseSensitivity(Qt.CaseInsensitive)
        self._proxy_completer_model.setFilterKeyColumn(0)

        #Configure completer
        mod_completer = QCompleter(self._completer_model, self)
        mod_completer.setCaseSensitivity(Qt.CaseInsensitive)
        mod_completer.setCompletionMode(QCompleter.PopupCompletion)
        mod_completer.setCompletionColumn(0)
        mod_completer.setCompletionRole(Qt.DisplayRole)

        self.txtFilterPattern.setCompleter(mod_completer)
Esempio n. 2
0
    def _update_completer(self, values):
        # Get the items in a tuple and put them in a list

        # Store display and actual values in a
        # model for easier mapping and
        # retrieval when carrying out searches

        model_attr_mapping = []

        # Check if there are formaters specified
        # for the current field name
        for mv in values:
            f_model_values = []

            m_val = mv[0]

            if m_val is not None:
                col_label = self.currentFieldName()
                if col_label in self.config.LookupFormatters:
                    formatter = self.config.LookupFormatters[col_label]
                    if formatter.column.TYPE_INFO == 'LOOKUP':
                        m_val = formatter.code_value(m_val)[0]
                    else:
                        m_val = formatter.format_column_value(m_val)
            f_model_values.extend([m_val, m_val])

            model_attr_mapping.append(f_model_values)

        self._completer_model = BaseSTDMTableModel(model_attr_mapping,
                                                   ["", ""], self)

        # We will use the QSortFilterProxyModel for filtering purposes
        self._proxy_completer_model = QSortFilterProxyModel()
        self._proxy_completer_model.setDynamicSortFilter(True)
        self._proxy_completer_model.setSourceModel(self._completer_model)
        self._proxy_completer_model.setSortCaseSensitivity(Qt.CaseInsensitive)
        self._proxy_completer_model.setFilterKeyColumn(0)

        # Configure completer
        mod_completer = QCompleter(self._completer_model, self)
        mod_completer.setCaseSensitivity(Qt.CaseInsensitive)
        mod_completer.setCompletionMode(QCompleter.PopupCompletion)
        mod_completer.setCompletionColumn(0)
        mod_completer.setCompletionRole(Qt.DisplayRole)

        self.txtFilterPattern.setCompleter(mod_completer)
Esempio n. 3
0
    def _initializeData(self, filtered_records=None):
        '''
        Set table model and load data into it.
        '''
        if self._dbmodel is None:
            msg = QApplication.translate(
                'EntityBrowser',
                'The data model for the entity could not be loaded, \n'
                'please contact your database administrator.')
            QMessageBox.critical(
                self, QApplication.translate('EntityBrowser',
                                             'Entity Browser'), msg)

        else:
            self._init_entity_columns()
            # Load entity data. There might be a better way in future in order
            # to ensure that there is a balance between user data discovery
            # experience and performance.
            if filtered_records is not None:
                self.current_records = filtered_records.rowcount

            numRecords = self.recomputeRecordCount(init_data=True)

            # Load progress dialog
            progressLabel = QApplication.translate("EntityBrowser",
                                                   "Fetching Records...")
            progressDialog = QProgressDialog(progressLabel, None, 0,
                                             numRecords, self)

            QApplication.processEvents()
            progressDialog.show()
            progressDialog.setValue(0)

            #Add records to nested list for enumeration in table model
            load_data = True
            if self.plugin is not None:
                if self._entity.name in self.plugin.entity_table_model.keys():
                    if filtered_records is None:
                        self._tableModel = self.plugin.entity_table_model[
                            self._entity.name]
                        #load_data = False
                    #else:
                    #load_data = True

            if isinstance(self._parent, EntityEditorDialog):
                load_data = True

            if load_data:
                # Only one filter is possible.
                if filtered_records is not None:
                    entity_records = filtered_records
                else:
                    entity_records = fetch_from_table(self._entity.name,
                                                      limit=self.record_limit)

            # if self._tableModel is None:
                entity_records_collection = []
                for i, er in enumerate(entity_records):
                    if i == self.record_limit:
                        break
                    QApplication.processEvents()
                    entity_row_info = []
                    progressDialog.setValue(i)
                    try:
                        # for attr, attr_val in er.items():
                        # print e
                        for attr in self._entity_attrs:
                            # attr_val = getattr(er, attr)
                            attr_val = er[attr]

                            # Check if there are display formatters and apply if
                            # one exists for the given attribute.
                            if attr_val is not None:  # No need of formatter for None value
                                if attr in self._cell_formatters:
                                    formatter = self._cell_formatters[attr]
                                    attr_val = formatter.format_column_value(
                                        attr_val)
                            entity_row_info.append(attr_val)
                    except Exception as ex:
                        QMessageBox.critical(
                            self,
                            QApplication.translate('EntityBrowser',
                                                   'Loading Records'),
                            unicode(ex.message))
                        return

                    entity_records_collection.append(entity_row_info)

                self._tableModel = BaseSTDMTableModel(
                    entity_records_collection, self._headers, self)
                if self.plugin is not None:
                    self.plugin.entity_table_model[self._entity.name] = \
                            self._tableModel
            # Add filter columns
            for header, info in self._searchable_columns.iteritems():
                column_name, index = info['name'], info['header_index']
                if column_name != 'id':
                    self.cboFilterColumn.addItem(header, info)

            #Use sortfilter proxy model for the view
            self._proxyModel = VerticalHeaderSortFilterProxyModel()
            self._proxyModel.setDynamicSortFilter(True)
            self._proxyModel.setSourceModel(self._tableModel)
            self._proxyModel.setSortCaseSensitivity(Qt.CaseInsensitive)

            #USe first column in the combo for filtering
            if self.cboFilterColumn.count() > 0:
                self.set_proxy_model_filter_column(0)

            self.tbEntity.setModel(self._proxyModel)
            if numRecords < self.record_limit:
                self.tbEntity.setSortingEnabled(True)
                self.tbEntity.sortByColumn(1, Qt.AscendingOrder)

            #First (ID) column will always be hidden
            self.tbEntity.hideColumn(0)

            self.tbEntity.horizontalHeader().setResizeMode(
                QHeaderView.Interactive)

            self.tbEntity.resizeColumnsToContents()

            #Connect signals
            self.connect(self.cboFilterColumn,
                         SIGNAL('currentIndexChanged (int)'),
                         self.onFilterColumnChanged)
            self.connect(self.txtFilterPattern,
                         SIGNAL('textChanged(const QString&)'),
                         self.onFilterRegExpChanged)

            #Select record with the given ID if specified
            if not self._select_item is None:
                self._select_record(self._select_item)

            if numRecords > 0:
                # Set maximum value of the progress dialog
                progressDialog.setValue(numRecords)
            else:
                progressDialog.hide()
Esempio n. 4
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()
Esempio n. 5
0
    def _init_fk_columns(self):
        """
        Asserts if the entity columns actually do exist in the database. The
        method also initializes the table headers, entity column and cell
        formatters.
        """
        self._headers[:] = []
        self._entity_attrs[:] = []
        if self._dbmodel is None:
            msg = QApplication.translate(
                'ForeignKeyMapper', 'The data model for '
                'the entity could '
                'not be loaded, '
                'please contact '
                'your database '
                'administrator.')
            QMessageBox.critical(
                self, QApplication.translate('EntityBrowser',
                                             'Entity Browser'), msg)

            return

        table_name = self._entity.name
        columns = table_column_names(table_name)
        missing_columns = []

        header_idx = 0

        # Iterate entity column and assert if they exist
        for c in self._entity.columns.values():
            # Do not include virtual columns in list of missing columns
            if not c.name in columns and not isinstance(c, VirtualColumn):
                missing_columns.append(c.name)

            else:
                header = c.header()
                self._headers.append(header)
                '''
                If it is a virtual column then use column name as the header
                but fully qualified column name (created by SQLAlchemy
                relationship) as the entity attribute name.
                '''
                col_name = c.name

                if isinstance(c, MultipleSelectColumn):
                    col_name = c.model_attribute_name

                self._entity_attrs.append(col_name)

                # Get widget factory so that we can use the value formatter
                w_factory = ColumnWidgetRegistry.factory(c.TYPE_INFO)
                if not w_factory is None:
                    try:
                        formatter = w_factory(c)
                        self._cell_formatters[col_name] = formatter
                    except WidgetException as we:
                        msg = QApplication.translate(
                            'ForeignKeyMapper', 'Error in creating column:')
                        msg = '{0} {1}:{2}\n{3}'.format(
                            msg, self._entity.name, c.name, str(we))
                        QMessageBox.critical(
                            self,
                            QApplication.translate('ForeignKeyMapper',
                                                   'Widget Creation Error'),
                            msg)

                # Set searchable columns
                if c.searchable:
                    self._searchable_columns[header] = {
                        'name': c.name,
                        'header_index': header_idx
                    }

                header_idx += 1

        if len(missing_columns) > 0:
            msg = QApplication.translate(
                'ForeignKeyMapper',
                'The following columns have been defined in the '
                'configuration but are missing in corresponding '
                'database table, please re-run the configuration wizard '
                'to create them.\n{0}'.format('\n'.join(missing_columns)))

            QMessageBox.warning(
                self,
                QApplication.translate('ForeignKeyMapper', 'Entity Browser'),
                msg)

        self._tableModel = BaseSTDMTableModel([], self._headers, self)
        self._tbFKEntity.setModel(self._tableModel)
        # First (id) column will always be hidden
        self._tbFKEntity.hideColumn(0)

        self._tbFKEntity.horizontalHeader().setSectionResizeMode(
            QHeaderView.Interactive)
        self._tbFKEntity.horizontalHeader().setStretchLastSection(True)

        self._tbFKEntity.verticalHeader().setVisible(True)
Esempio n. 6
0
    def _initializeData(self):
        '''
        Set table model and load data into it.
        '''
        if self._dbmodel is None:
            msg = QApplication.translate('EntityBrowser', 'The data model for '
                                                          'the entity could '
                                                          'not be loaded, '
                                                          'please contact '
                                                          'your database '
                                                          'administrator.')
            QMessageBox.critical(self, QApplication.translate('EntityBrowser',
                                                              'Entity Browser'),
                                 msg)

            return

        else:

            self._init_entity_columns()
            '''
            Load entity data. There might be a better way in future in order to ensure that
            there is a balance between user data discovery experience and performance.
            '''
            numRecords = self.recomputeRecordCount()
                        
            #Load progress dialog
            progressLabel = QApplication.translate("EntityBrowser", "Fetching Records...")
            progressDialog = QProgressDialog(progressLabel, None, 0, numRecords, self)
            
            entity_cls = self._dbmodel()
            entity_records = entity_cls.queryObject().filter().all()
            
            #Add records to nested list for enumeration in table model
            entity_records_collection = []
            for i,er in enumerate(entity_records):
                entity_row_info = []
                progressDialog.setValue(i)
                try:
                    for attr in self._entity_attrs:
                        attr_val = getattr(er, attr)

                        '''
                        Check if there are display formatters and apply if
                        one exists for the given attribute.
                        '''
                        if attr in self._cell_formatters:
                            formatter = self._cell_formatters[attr]
                            attr_val = formatter.format_column_value(attr_val)

                        entity_row_info.append(attr_val)

                except Exception as ex:
                    QMessageBox.critical(self,
                                         QApplication.translate(
                                             'EntityBrowser',
                                             'Loading Records'
                                         ),
                                         unicode(ex.message))
                    return

                entity_records_collection.append(entity_row_info)
                
            #Set maximum value of the progress dialog
            progressDialog.setValue(numRecords)
        
            self._tableModel = BaseSTDMTableModel(entity_records_collection,
                                                  self._headers, self)

            #Add filter columns
            for header, info in self._searchable_columns.iteritems():
                column_name, index = info['name'], info['header_index']
                if column_name != 'id':
                    self.cboFilterColumn.addItem(header, info)
            
            #Use sortfilter proxy model for the view
            self._proxyModel = VerticalHeaderSortFilterProxyModel()
            self._proxyModel.setDynamicSortFilter(True)
            self._proxyModel.setSourceModel(self._tableModel)
            self._proxyModel.setSortCaseSensitivity(Qt.CaseInsensitive)

            #USe first column in the combo for filtering
            if self.cboFilterColumn.count() > 0:
                self.set_proxy_model_filter_column(0)
            
            self.tbEntity.setModel(self._proxyModel)
            self.tbEntity.setSortingEnabled(True)
            self.tbEntity.sortByColumn(1, Qt.AscendingOrder)
            
            #First (ID) column will always be hidden
            self.tbEntity.hideColumn(0)
            
            self.tbEntity.horizontalHeader().setResizeMode(QHeaderView.Interactive)

            self.tbEntity.resizeColumnsToContents()

            #Connect signals
            self.connect(self.cboFilterColumn, SIGNAL('currentIndexChanged (int)'), self.onFilterColumnChanged)
            self.connect(self.txtFilterPattern, SIGNAL('textChanged(const QString&)'), self.onFilterRegExpChanged)

            #Select record with the given ID if specified
            if not self._select_item is None:
                self._select_record(self._select_item)