class StatisticsSelectionWidget(GroupBoxWidget): #this value is set up in __createModel__ method VALUE_COLUMN = 0 """ widget which gives ability to select statistics """ @temporarySettingsDecorator() def __init__(self, parent, **params): get_or_put(params, 'layout', QVBoxLayout()) get_or_put(params, 'i18n_def', 'Statistics') super(StatisticsSelectionWidget, self).__init__(parent, **params) self.params = Params(**params) if self.params.statistics_base_classes == None: self.params.statistics_base_classes = [Asymmetry] if self.params.data_accessor: self.params.data_accessor.addListener(self, __StatisticsSelectionVectorListener__(self)) self.__createButtons__() self.__createTable__() self.__createModel__() self.__fillStatistics__(self.params.statistics_base_classes) def __createTable__(self): self.__table__ = TableViewWidget(self, change_check_count_handler=self.params.change_selection_count_handler, # @IgnorePep8 check_handler=self.__check_handler__) self.__table__.setSelectionMode(QAbstractItemView.MultiSelection) self.__table__.setSelectionBehavior(QAbstractItemView.SelectRows) def __createModel__(self): model = __StatisticsSelectionModel__(self) labels = QStringList(["Statistic", "Description", "Value"]) StatisticsSelectionWidget.VALUE_COLUMN = labels.indexOf("Value") model.setNumValueColumn(StatisticsSelectionWidget.VALUE_COLUMN) model.setHorizontalHeaderLabels(labels) self.__table__.setModel(model) self.__table__.setColumnHidden(StatisticsSelectionWidget.VALUE_COLUMN, True) def __createButtons__(self): buttons_composite = CompositeWidget(self, layout=QHBoxLayout()) PushButtonWidget(buttons_composite, i18n_def="Select all", clicked_handler=self.__select_all_handler__) PushButtonWidget(buttons_composite, i18n_def="Unselect all", clicked_handler=self.__unselect_all_handler__) def __select_all_handler__(self): self.__table__.changeCheckStatForAll(True) def __unselect_all_handler__(self): self.__table__.changeCheckStatForAll(False) def __fillStatistics__(self, _statistics_base_classes): model = self.__table__.model() model.removeRows(0, model.rowCount()) self.__statistics_classes__ = [] for base_class in _statistics_base_classes: for subclass in get_subclasses(base_class): self.__statistics_classes__.append(subclass) #sort alphabetically cmp_stat = lambda x, y: cmp(x.__name__, y.__name__) self.__statistics_classes__ = sorted(self.__statistics_classes__, cmp_stat) for statistic_class in self.__statistics_classes__: check_column = QStandardItem('%s' % statistic_class.__name__) check_column.setCheckState(Qt.Unchecked) check_column.setCheckable(True) description_column = QStandardItem(str(statistic_class().description)) # @IgnorePep8 value_column = QStandardItem('') model.appendRow([check_column, description_column, value_column]) @property def statistics_classes(self): return self.__statistics_classes__ def getSelectedStatisticsClasses(self): selected_classes = [] model = self.__table__.model() for idx in range(model.rowCount()): item = model.item(idx) if item.isCheckable() and item.checkState() == Qt.Checked: selected_classes.append(self.__statistics_classes__[idx]) return selected_classes def setStatisticsValues(self, values_map): """ method to set up statistics values """ if values_map == None: return #show value column self.__table__.setColumnHidden(StatisticsSelectionWidget.VALUE_COLUMN, False) for statistic_class in values_map: row = self.__statistics_classes__.index(statistic_class) self.__table__.model().setItem(row, StatisticsSelectionWidget.VALUE_COLUMN, QStandardItem(str(values_map[statistic_class]))) def __check_handler__(self, item): """ handler invoked when a user check selected row in statistics table view, the parameter is an model's item """ if self.params.check_handler: if item.isCheckable(): statistic_class = self.__statistics_classes__[item.row()] #parameters of outer handler check_handler are #statistics object and whether is checked or unchecked self.params.check_handler(statistic_class(), item.checkState() == Qt.Checked) def checkStatistic(self, _statistic): """ method checks statistic identified by a parameter - statistic class """ row = self.__statistics_classes__.index(_statistic) if row >= 0: item = self.__table__.model().item(row) if item.isCheckable(): item.setCheckState(Qt.Checked) def __getSelectedStatisticsClassesNames__(self): return [statistic_class.__name__ for statistic_class in self.getSelectedStatisticsClasses()] @temporarySetterDecorator(name='selected_statistics', _conv=QVariant.toPyObject, _getter_handler=__getSelectedStatisticsClassesNames__) def __setSelectedStatistics__(self, _statistics_class_names): if not _statistics_class_names == None: model = self.__table__.model() for idx in range(model.rowCount()): item = model.item(idx) if item.isCheckable() and item.checkState() == Qt.Unchecked \ and self.__statistics_classes__[idx].__name__ in _statistics_class_names: # @IgnorePep8 item.setCheckState(Qt.Checked)
class FilesTableView(object): def __init__(self, parent, **params): self.parent = parent self.__completed_count__ = 0 self.selectedRow = None self.params = Params(**params) labels = [ "", # first column is checkable column QT_I18N("datasource.files.column.filename", "Filename"), QT_I18N("datasource.files.column.size", "Size"), QT_I18N("datasource.files.column.path", "File path") ] self.labels = QStringList(labels) self.filesTableView = TableViewWidget( parent, selectionBehavior=QAbstractItemView.SelectRows, selectionMode=QAbstractItemView.SingleSelection, enabled_precheck_handler=self.params.enabled_precheck_handler) if self.params.model: self.filesTableView.setModel(self.params.model) self.filesTableView.model().setHorizontalHeaderLabels(labels) self.filesTableView.setEditTriggers(QAbstractItemView.NoEditTriggers) if self.params.onClickedAction: self.filesTableView.connect(self.filesTableView, SIGNAL('clicked(QModelIndex)'), self.params.onClickedAction) if not self.filesTableView.model() == None: #a signal used when selected row state is changed self.filesTableView.connect( self.filesTableView.model(), SIGNAL('itemChanged(QStandardItem *)'), self.__itemChanged__) if self.params.sorting: self.filesTableView.setSortingEnabled(True) def reload(self): if self.filesTableView.model().rowCount() > 0: self.filesTableView.resizeColumnsToContents() self.filesTableView.scrollToTop() def __itemChanged__(self, item): self.changeCompleteState( 1, 'add' if item.checkState() == Qt.Checked else 'sub') def addRow(self, row): self.filesTableView.model().appendRow(row) def clear(self): self.filesTableView.model().removeRows( 0, self.filesTableView.model().rowCount()) self.minCompleteState() def getSelectedPathAndFilename(self): return self.getPathAndFilename(self.selectedRow) def getPathAndFilename(self, modelIdx): if not modelIdx == None: model = modelIdx.model() path = model.item(modelIdx.row(), 3) filename = model.item(modelIdx.row(), 1) return FilePath(str(path.text()), str(filename.text())) def onClickedAction(self, selectedRow): self.selectedRow = selectedRow #do not remove leave as an useful example #checked = self.__rowChecked__(selectedRow) def getSelectedItems(self): return [ self.filesTableView.model().item(row) for row in range(0, self.filesTableView.model().rowCount()) if self.filesTableView.model().item(row).checkState() == Qt.Checked ] def setCheckedRowState(self, idx, state): self.filesTableView.model().item(idx).setCheckState(state) def getRowCount(self): return self.filesTableView.model().rowCount() def setEnabled(self, enabled): self.filesTableView.setEnabled(enabled) def resizeColumnsToContents(self): self.filesTableView.resizeColumnsToContents() def changeCompleteState(self, value=0, operation='set'): """ a method instead of emitting a signal completeChanged() which is intercepted by QWizard to enable/disable next, previous buttons based on value returned by isComplete method of a wizard page set up wizard operational's buttons enable states, because use of the completeChange signal causes jump to the beginning of a table view instead of sticking to the position where it was already and also dim of a selected row is observed """ if operation == 'set' and value != 0: self.__completed_count__ = value elif operation == 'add': self.__completed_count__ = self.__completed_count__ + value elif operation == 'sub': if self.__completed_count__ - value >= 0: self.__completed_count__ = self.__completed_count__ - value #self.emit(SIGNAL("completeChanged()")) if self.params.wizardButtons and self.params.wizard_handler: for button in self.params.wizardButtons: self.params.wizard_handler().button(button).setEnabled( self.isCompletedCount()) def isCompletedCount(self): return self.getCompletedCount() > 0 def getCompletedCount(self): return self.__completed_count__ def maxCompleteState(self): self.changeCompleteState(self.getRowCount()) def minCompleteState(self): self.changeCompleteState(0) def getModel(self): return self.filesTableView.model() def setColumnHidden(self, column, hide=True): self.filesTableView.setColumnHidden(column, hide) def getSelectedRow(self): return self.selectedRow def model(self): return self.filesTableView.model() def count(self): return self.filesTableView.model().rowCount() def getSelectedRowCount(self): return len(self.filesTableView.selectedIndexes()) / len(self.labels) def selectRow(self, row, emulate_click=True): self.filesTableView.selectRow(row) if emulate_click: model = self.filesTableView.model() for column in range(model.columnCount()): if self.filesTableView.isColumnHidden(column) == False: #simulate a click on the first visible column self.filesTableView.emit(SIGNAL('clicked(QModelIndex)'), model.index(row, column)) break
class StatisticsSelectionWidget(GroupBoxWidget): #this value is set up in __createModel__ method VALUE_COLUMN = 0 """ widget which gives ability to select statistics """ @temporarySettingsDecorator() def __init__(self, parent, **params): get_or_put(params, 'layout', QVBoxLayout()) get_or_put(params, 'i18n_def', 'Statistics') super(StatisticsSelectionWidget, self).__init__(parent, **params) self.params = Params(**params) if self.params.statistics_base_classes == None: self.params.statistics_base_classes = [Asymmetry] if self.params.data_accessor: self.params.data_accessor.addListener( self, __StatisticsSelectionVectorListener__(self)) self.__createButtons__() self.__createTable__() self.__createModel__() self.__fillStatistics__(self.params.statistics_base_classes) def __createTable__(self): self.__table__ = TableViewWidget( self, change_check_count_handler=self.params. change_selection_count_handler, # @IgnorePep8 check_handler=self.__check_handler__) self.__table__.setSelectionMode(QAbstractItemView.MultiSelection) self.__table__.setSelectionBehavior(QAbstractItemView.SelectRows) def __createModel__(self): model = __StatisticsSelectionModel__(self) labels = QStringList(["Statistic", "Description", "Value"]) StatisticsSelectionWidget.VALUE_COLUMN = labels.indexOf("Value") model.setNumValueColumn(StatisticsSelectionWidget.VALUE_COLUMN) model.setHorizontalHeaderLabels(labels) self.__table__.setModel(model) self.__table__.setColumnHidden(StatisticsSelectionWidget.VALUE_COLUMN, True) def __createButtons__(self): buttons_composite = CompositeWidget(self, layout=QHBoxLayout()) PushButtonWidget(buttons_composite, i18n_def="Select all", clicked_handler=self.__select_all_handler__) PushButtonWidget(buttons_composite, i18n_def="Unselect all", clicked_handler=self.__unselect_all_handler__) def __select_all_handler__(self): self.__table__.changeCheckStatForAll(True) def __unselect_all_handler__(self): self.__table__.changeCheckStatForAll(False) def __fillStatistics__(self, _statistics_base_classes): model = self.__table__.model() model.removeRows(0, model.rowCount()) self.__statistics_classes__ = [] for base_class in _statistics_base_classes: for subclass in get_subclasses(base_class): self.__statistics_classes__.append(subclass) #sort alphabetically cmp_stat = lambda x, y: cmp(x.__name__, y.__name__) self.__statistics_classes__ = sorted(self.__statistics_classes__, cmp_stat) for statistic_class in self.__statistics_classes__: check_column = QStandardItem('%s' % statistic_class.__name__) check_column.setCheckState(Qt.Unchecked) check_column.setCheckable(True) description_column = QStandardItem( str(statistic_class().description)) # @IgnorePep8 value_column = QStandardItem('') model.appendRow([check_column, description_column, value_column]) @property def statistics_classes(self): return self.__statistics_classes__ def getSelectedStatisticsClasses(self): selected_classes = [] model = self.__table__.model() for idx in range(model.rowCount()): item = model.item(idx) if item.isCheckable() and item.checkState() == Qt.Checked: selected_classes.append(self.__statistics_classes__[idx]) return selected_classes def setStatisticsValues(self, values_map): """ method to set up statistics values """ if values_map == None: return #show value column self.__table__.setColumnHidden(StatisticsSelectionWidget.VALUE_COLUMN, False) for statistic_class in values_map: row = self.__statistics_classes__.index(statistic_class) self.__table__.model().setItem( row, StatisticsSelectionWidget.VALUE_COLUMN, QStandardItem(str(values_map[statistic_class]))) def __check_handler__(self, item): """ handler invoked when a user check selected row in statistics table view, the parameter is an model's item """ if self.params.check_handler: if item.isCheckable(): statistic_class = self.__statistics_classes__[item.row()] #parameters of outer handler check_handler are #statistics object and whether is checked or unchecked self.params.check_handler(statistic_class(), item.checkState() == Qt.Checked) def checkStatistic(self, _statistic): """ method checks statistic identified by a parameter - statistic class """ row = self.__statistics_classes__.index(_statistic) if row >= 0: item = self.__table__.model().item(row) if item.isCheckable(): item.setCheckState(Qt.Checked) def __getSelectedStatisticsClassesNames__(self): return [ statistic_class.__name__ for statistic_class in self.getSelectedStatisticsClasses() ] @temporarySetterDecorator( name='selected_statistics', _conv=QVariant.toPyObject, _getter_handler=__getSelectedStatisticsClassesNames__) def __setSelectedStatistics__(self, _statistics_class_names): if not _statistics_class_names == None: model = self.__table__.model() for idx in range(model.rowCount()): item = model.item(idx) if item.isCheckable() and item.checkState() == Qt.Unchecked \ and self.__statistics_classes__[idx].__name__ in _statistics_class_names: # @IgnorePep8 item.setCheckState(Qt.Checked)
class FilesTableView(object): def __init__(self, parent, **params): self.parent = parent self.__completed_count__ = 0 self.selectedRow = None self.params = Params(**params) labels = ["", # first column is checkable column QT_I18N("datasource.files.column.filename", "Filename"), QT_I18N("datasource.files.column.size", "Size"), QT_I18N("datasource.files.column.path", "File path")] self.labels = QStringList(labels) self.filesTableView = TableViewWidget(parent, selectionBehavior=QAbstractItemView.SelectRows, selectionMode=QAbstractItemView.SingleSelection, enabled_precheck_handler=self.params.enabled_precheck_handler) if self.params.model: self.filesTableView.setModel(self.params.model) self.filesTableView.model().setHorizontalHeaderLabels(labels) self.filesTableView.setEditTriggers(QAbstractItemView.NoEditTriggers) if self.params.onClickedAction: self.filesTableView.connect(self.filesTableView, SIGNAL('clicked(QModelIndex)'), self.params.onClickedAction) if not self.filesTableView.model() == None: #a signal used when selected row state is changed self.filesTableView.connect(self.filesTableView.model(), SIGNAL('itemChanged(QStandardItem *)'), self.__itemChanged__) if self.params.sorting: self.filesTableView.setSortingEnabled(True) def reload(self): if self.filesTableView.model().rowCount() > 0: self.filesTableView.resizeColumnsToContents() self.filesTableView.scrollToTop() def __itemChanged__(self, item): self.changeCompleteState(1, 'add' if item.checkState() == Qt.Checked else 'sub') def addRow(self, row): self.filesTableView.model().appendRow(row) def clear(self): self.filesTableView.model().removeRows(0, self.filesTableView.model().rowCount()) self.minCompleteState() def getSelectedPathAndFilename(self): return self.getPathAndFilename(self.selectedRow) def getPathAndFilename(self, modelIdx): if not modelIdx == None: model = modelIdx.model() path = model.item(modelIdx.row(), 3) filename = model.item(modelIdx.row(), 1) return FilePath(str(path.text()), str(filename.text())) def onClickedAction(self, selectedRow): self.selectedRow = selectedRow #do not remove leave as an useful example #checked = self.__rowChecked__(selectedRow) def getSelectedItems(self): return [self.filesTableView.model().item(row) for row in range(0, self.filesTableView.model().rowCount()) if self.filesTableView.model().item(row).checkState() == Qt.Checked] def setCheckedRowState(self, idx, state): self.filesTableView.model().item(idx).setCheckState(state) def getRowCount(self): return self.filesTableView.model().rowCount() def setEnabled(self, enabled): self.filesTableView.setEnabled(enabled) def resizeColumnsToContents(self): self.filesTableView.resizeColumnsToContents() def changeCompleteState(self, value=0, operation='set'): """ a method instead of emitting a signal completeChanged() which is intercepted by QWizard to enable/disable next, previous buttons based on value returned by isComplete method of a wizard page set up wizard operational's buttons enable states, because use of the completeChange signal causes jump to the beginning of a table view instead of sticking to the position where it was already and also dim of a selected row is observed """ if operation == 'set' and value != 0: self.__completed_count__ = value elif operation == 'add': self.__completed_count__ = self.__completed_count__ + value elif operation == 'sub': if self.__completed_count__ - value >= 0: self.__completed_count__ = self.__completed_count__ - value #self.emit(SIGNAL("completeChanged()")) if self.params.wizardButtons and self.params.wizard_handler: for button in self.params.wizardButtons: self.params.wizard_handler().button(button).setEnabled( self.isCompletedCount()) def isCompletedCount(self): return self.getCompletedCount() > 0 def getCompletedCount(self): return self.__completed_count__ def maxCompleteState(self): self.changeCompleteState(self.getRowCount()) def minCompleteState(self): self.changeCompleteState(0) def getModel(self): return self.filesTableView.model() def setColumnHidden(self, column, hide=True): self.filesTableView.setColumnHidden(column, hide) def getSelectedRow(self): return self.selectedRow def model(self): return self.filesTableView.model() def count(self): return self.filesTableView.model().rowCount() def getSelectedRowCount(self): return len(self.filesTableView.selectedIndexes()) / len(self.labels) def selectRow(self, row, emulate_click=True): self.filesTableView.selectRow(row) if emulate_click: model = self.filesTableView.model() for column in range(model.columnCount()): if self.filesTableView.isColumnHidden(column) == False: #simulate a click on the first visible column self.filesTableView.emit(SIGNAL('clicked(QModelIndex)'), model.index(row, column)) break