def on_selection_changed(self, selected: QItemSelection, _deselected: QItemSelection) -> None: """Updates the state of the delete button.""" if selected.empty(): self.cancel_button.setEnabled(False) return self.cancel_button.setEnabled(self.can_cancel(selected.indexes()[0]))
def select_in_direction(self, key): """Selects fields in one direction. :param Qt.Key key: """ model = self.model() selection_model = self.selectionModel() selection = selection_model.selection()[0] # There should only ever be one top_left_current = selection.topLeft() bottom_right_current = selection.bottomRight() top_left = top_left_current bottom_right = bottom_right_current if key in [Qt.Key_PageUp, Qt.Key_Up]: top_left = model.index(0, top_left_current.column()) bottom_right = model.index(bottom_right_current.row(), bottom_right_current.column()) elif key in [Qt.Key_PageDown, Qt.Key_Down]: top_left = model.index(top_left_current.row(), top_left_current.column()) bottom_right = model.index(model.rowCount()-1, bottom_right_current.column()) elif key in [Qt.Key_Left]: top_left = model.index(top_left_current.row(), 0) bottom_right = model.index(bottom_right_current.row(), bottom_right_current.column()) elif key in [Qt.Key_Right]: top_left = model.index(top_left_current.row(), top_left_current.column()) bottom_right = model.index(bottom_right_current.row(), model.columnCount()-1) selection = QItemSelection() sel_range = QItemSelectionRange(top_left, bottom_right) selection.append(sel_range) selection_model.reset() selection_model.select(selection, QItemSelectionModel.SelectCurrent)
def selectionChanged(self, selected: QItemSelection, deselected: QItemSelection) -> None: """ Emit signal when current selection changes """ super().selectionChanged(selected, deselected) current: QModelIndex = selected.indexes()[0] if selected.indexes( ) else QModelIndex() previous: QModelIndex = deselected.indexes()[0] if deselected.indexes( ) else QModelIndex() crow: int = -1 prow: int = -1 cdata: str = current.data(Qt.DisplayRole) pdata: str = previous.data(Qt.DisplayRole) if isinstance(self.model(), QAbstractProxyModel): current = self.model().mapToSource( current) if current.isValid() else current previous = self.model().mapToSource( previous) if previous.isValid() else previous if current.isValid(): crow = current.row() if previous.isValid(): prow = previous.row() self.selectedRowChanged[int, int].emit(crow, prow) # If data is string, also emit the signal with string if isinstance(cdata, str): self.selectedRowChanged[str, str].emit(cdata, pdata)
def mapSelectionToSource(self, selection): return_selection = QItemSelection() for sel in selection: top_left = self.mapToSource(sel.topLeft()) bottom_right = self.mapToSource(sel.bottomRight()) sel_range = QItemSelectionRange(top_left, bottom_right) return_selection.append(sel_range) return return_selection
def doIt(self, args): # Use an MArgDatabase to parse the command invocation. # try: argDb = OpenMaya.MArgDatabase(self.syntax(), args) except RuntimeError as ex: raise RunTimeError(kParsingError % str(ex)) # add and deselect are non-query mode flags add = argDb.isFlagSet(RenderSetupSelectCmd.kAddFlag) deselect = argDb.isFlagSet(RenderSetupSelectCmd.kDeselectFlag) if argDb.isQuery and (add or deselect): raise RuntimeError(kAddAndDeselectEditOnly) # renderLayers, collections, and overrides are query mode flags renderLayers = argDb.isFlagSet(RenderSetupSelectCmd.kRenderLayersFlag) collections = argDb.isFlagSet(RenderSetupSelectCmd.kCollectionsFlag) overrides = argDb.isFlagSet(RenderSetupSelectCmd.kOverridesFlag) if not argDb.isQuery and (renderLayers or collections or overrides): raise RuntimeError(kNotEditableFlags) if argDb.isQuery: results = getSelection(renderLayers, collections, overrides) self.setResult(results) else: selectionModel = getSelectionModel() if selectionModel is None: if argDb.numberOfFlagsUsed: raise RuntimeError(kSelectionEditFailed) # Can't have both add and deselect at the same time if add and deselect: raise RuntimeError(kAddAndDeselectNoTogether) # Find the items that we are selecting and add them to our item selection from PySide2.QtCore import QItemSelection, QItemSelectionModel import maya.app.renderSetup.views.proxy.renderSetup as renderSetupProxy itemsToSelect = argDb.getObjectStrings() selection = QItemSelection() models = itertools.ifilter(None, (utils.nameToUserNode(item) for item in itemsToSelect)) proxies = [renderSetupProxy.getProxy(model) for model in models] for proxy in proxies: selection.select(proxy.index(), proxy.index()) if not deselect: treeview = getRenderSetupView() for proxy in proxies: parent = proxy.parent() while parent: treeview.setExpanded(parent.index(), True) parent = parent.parent() # Use the appropriate selection method selectMode = QItemSelectionModel.Select if add else QItemSelectionModel.Deselect if deselect else QItemSelectionModel.ClearAndSelect selectionModel.select(selection, selectMode)
def _onSelectionChanged(self, selected: QtCore.QItemSelection, deselected: QtCore.QItemSelection) -> None: self._logger.info("On selection changed") selectedIndexes = {x.row() for x in selected.indexes()} deselectedIndexes = {x.row() for x in deselected.indexes()} oldSelectedIndexes = self._player.getSelectedMusicIndexes() newSelectedIndexes = oldSelectedIndexes.union( selectedIndexes).difference(deselectedIndexes) self.blockSignals(True) self._player.setSelectedMusicIndexes(newSelectedIndexes) self.blockSignals(False)
def headerData(self, section: int, orientation: Qt.Orientation, role: int = ...) -> Any: """ Redefined to handle selection by clicking on header """ if orientation == Qt.Horizontal and role == AttributeTableModel.AllCheckedRole and section == \ self.checkboxColumn: # Return True if all visible items are checked checkedAttr = self.checked if not checkedAttr: # No item are checked in source model, so they are not checked in proxy return False if self.sourceModel().headerData(section, orientation, role) is True: # If all items are checked in source model then they are checked also in proxy return True # Check if all visible items are checked (mapSelectionToSource can be slow) allIndexes = QItemSelection( self.index(0, self.checkboxColumn, QModelIndex()), self.index(self.rowCount() - 1, self.checkboxColumn, QModelIndex())) sourceIndexes: List[QModelIndex] = self.mapSelectionToSource( allIndexes).indexes() return all(map(lambda x: x.row() in checkedAttr, sourceIndexes)) if orientation == Qt.Vertical and role == Qt.DisplayRole: # Display the true column number (as in source model) sourceSection = self.mapToSource( self.index(section, 0, QModelIndex())).row() return self.sourceModel().headerData(sourceSection, orientation, role) return self.sourceModel().headerData(section, orientation, role)
def _on_selection_changed( self, selected: QItemSelection, unselected: QItemSelection, ) -> None: has_selection = selected.count() != 0 self._del_button.setEnabled(has_selection)
def __init__(self, parameter_name, indexing_setting, available_existing_domains, new_domains, parent): """ Args: parameter_name (str): parameter's name indexing_setting (IndexingSetting): indexing settings for the parameter available_existing_domains (dict): a dict from existing domain name to a list of its record keys new_domains (dict): a dict from new domain name to a list of its record keys parent (QWidget): a parent widget """ from ..ui.parameter_index_settings import Ui_Form super().__init__(parent) self._indexing_setting = indexing_setting self._state = IndexSettingsState.OK self._ui = Ui_Form() self._ui.setupUi(self) self._ui.box.setTitle(parameter_name) self._indexing_table_model = _IndexingTableModel(indexing_setting.parameter) self._ui.index_table_view.setModel(self._indexing_table_model) self._ui.index_table_view.selectionModel().selectionChanged.connect(self._update_model_to_selection) self._available_domains = available_existing_domains for domain_name in sorted(name for name in available_existing_domains.keys()): self._ui.existing_domains_combo.addItem(domain_name) self._ui.existing_domains_combo.activated.connect(self._existing_domain_changed) self._ui.use_existing_domain_radio_button.toggled.connect(self._set_enabled_use_existing_domain_widgets) self._ui.create_domain_radio_button.toggled.connect(self._set_enabled_create_domain_widgets) self._ui.pick_expression_edit.textChanged.connect(self._update_index_list_selection) self._ui.generator_expression_edit.textChanged.connect(self._generate_index) self._ui.extract_indexes_button.clicked.connect(self._extract_index_from_parameter) self._ui.domain_name_edit.textChanged.connect(self._domain_name_changed) self._ui.move_domain_left_button.clicked.connect(self._move_indexing_domain_left) self._ui.move_domain_right_button.clicked.connect(self._move_indexing_domain_right) indexing_domain = indexing_setting.indexing_domain if indexing_domain is not None: if indexing_domain.name in available_existing_domains: self._ui.existing_domains_combo.setCurrentText(indexing_domain.name) self._set_enabled_use_existing_domain_widgets(True) self._set_enabled_create_domain_widgets(False) else: self._ui.create_domain_radio_button.setChecked(True) self._set_enabled_use_existing_domain_widgets(False) self._set_enabled_create_domain_widgets(True) self._ui.domain_name_edit.setText(indexing_domain.name) self._ui.domain_description_edit.setText(indexing_domain.description) self._indexing_table_model.set_indexes(new_domains[indexing_domain.name]) selection_model = self._ui.index_table_view.selectionModel() selection_model.clearSelection() index = self._indexing_table_model.index last_column = self._indexing_table_model.columnCount() - 1 for i, pick in enumerate(indexing_domain.pick_list): if pick: top_left = index(i, 0) bottom_right = index(i, last_column) selection = QItemSelection(top_left, bottom_right) selection_model.select(selection, QItemSelectionModel.Select) else: self._set_enabled_use_existing_domain_widgets(True) self._set_enabled_create_domain_widgets(False) self._check_state()
def _do_select(self, start_bindex, end_bindex): """ select the given range by buffer indices selects items like this: .................. ......xxxxxxxxxxxx xxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxx xxxxxxxxxxxx...... .................. *not* like this: .................. ......xxxxxx...... ......xxxxxx...... ......xxxxxx...... ......xxxxxx...... .................. """ self.select(QItemSelection(), QItemSelectionModel.Clear) if start_bindex > end_bindex: start_bindex, end_bindex = end_bindex, start_bindex selection = QItemSelection() if row_number(end_bindex) - row_number(start_bindex) == 0: # all on one line self._bselect(selection, start_bindex, end_bindex) elif row_number(end_bindex) - row_number(start_bindex) == 1: # two lines self._bselect(selection, start_bindex, row_end_index(start_bindex)) self._bselect(selection, row_start_index(end_bindex), end_bindex) else: # many lines self._bselect(selection, start_bindex, row_end_index(start_bindex)) self._bselect(selection, row_start_index(start_bindex) + 0x10, row_end_index(end_bindex) - 0x10) self._bselect(selection, row_start_index(end_bindex), end_bindex) self.select(selection, QItemSelectionModel.SelectCurrent) self.start = start_bindex self.end = end_bindex self.selectionRangeChanged.emit(end_bindex)
def testLen(self): model = QStandardItemModel(2, 2) model.insertRow(0) model.insertRow(1) model.insertColumn(0) model.insertColumn(1) selection = QItemSelection(model.index(0, 0), model.index(1, 1)) self.assertEqual(len(selection), 1)
def selectionChanged(self, selected: QItemSelection, deselected: QItemSelection) -> None: """ Emit signal when current selection changes """ super().selectionChanged(selected, deselected) current: QModelIndex = selected.indexes()[0] if selected.indexes() else QModelIndex() previous: QModelIndex = deselected.indexes()[0] if deselected.indexes() else QModelIndex() currRow: int = -1 prevRow: int = -1 currName: str = '' prevName: str = '' if current.isValid(): currRow = current.row() currName = current.data(Qt.DisplayRole) if previous.isValid(): prevRow = previous.row() prevName = previous.data(Qt.DisplayRole) self.selectedRowChanged[int, int].emit(currRow, prevRow) self.selectedRowChanged[str, str].emit(currName, prevName)
def on_selection_changed(self, selected: QItemSelection, _deselected: QItemSelection) -> None: indexes = selected.indexes() if len(indexes) > 1: raise RuntimeError( "Aircraft list should not allow multi-selection") if not indexes: return self.page_index_changed.emit(indexes[0].row())
def setAllChecked(self, value: bool) -> None: """ Sets all proxy items check state to 'value' """ # Get all shown items rows in source model and set their value allIndexes = QItemSelection( self.index(0, self.checkboxColumn, QModelIndex()), self.index(self.rowCount() - 1, self.checkboxColumn, QModelIndex())) sourceIndexes: List[QModelIndex] = self.mapSelectionToSource( allIndexes).indexes() self.setChecked(list(map(lambda x: x.row(), sourceIndexes)), value)
def _update_index_list_selection(self, expression, clear_selection_if_expression_empty=True): """Updates selection according to changed selection expression.""" if not expression: if clear_selection_if_expression_empty: self._ui.index_table_view.clearSelection() return get_index = self._indexing_table_model.index selection = QItemSelection() selected_domain_name = self._ui.existing_domains_combo.currentText() try: for index in range(len(self._available_domains[selected_domain_name])): if eval(expression, {}, {"i": index + 1}): # pylint: disable=eval-used selected_top_left = get_index(index, 0) selected_bottom_right = get_index(index, 1) selection.select(selected_top_left, selected_bottom_right) except (AttributeError, NameError, SyntaxError): return selection_model = self._ui.index_table_view.selectionModel() selection_model.select(selection, QItemSelectionModel.ClearAndSelect)
def open_repo(self): """ called either on start or after open dialog """ self.setWindowTitle(f'{self.dir_name} - pqgit ({VERSION})') self.repo = pygit2.Repository(self.dir_name) # remove existing files and folder from watch if self.fs_watch.files(): self.fs_watch.removePaths(self.fs_watch.files()) if self.fs_watch.directories(): self.fs_watch.removePaths(self.fs_watch.directories()) wd = self.repo.workdir self.fs_watch.addPath(wd) # get head tree for list of files in repo target = self.repo.head.target last_commit = self.repo[target] tree_id = last_commit.tree_id tree = self.repo[tree_id] # add those files and folder to watch self.fs_watch.addPaths([wd + o[0] for o in parse_tree_rec(tree, True)]) # get files/folders not in repo from status self.fs_watch.addPaths([ wd + p for p, f in self.repo.status().items() if GIT_STATUS[f] != 'I' ]) # (doesn't matter some are in both lists, already monitored ones will not be added by Qt) # local branches branches = [] selected_branch_row = 0 for idx, b_str in enumerate(self.repo.branches.local): b = self.repo.branches[b_str] if b.is_checked_out(): selected_branch_row = idx branches.append( Branch(name=b.branch_name, ref=b.name, c_o=b.is_checked_out())) # tags regex = re.compile('^refs/tags') tags = list(filter(regex.match, self.repo.listall_references())) branches += [Branch(name=t[10:], ref=t, c_o=False) for t in tags] self.branches_model.update(branches) idx1 = self.branches_model.index(selected_branch_row, 0) idx2 = self.branches_model.index(selected_branch_row, self.branches_model.columnCount() - 1) self.ui.tvBranches.selectionModel().select(QItemSelection(idx1, idx2), QItemSelectionModel.Select) self.ui.tvHistory.resizeColumnsToContents()
def testOperators(self): model = QStandardItemModel() for i in range(100): model.appendRow(QStandardItem("Item: %d" % i)) first = model.index(0, 0) second = model.index(10, 0) third = model.index(20, 0) fourth = model.index(30, 0) sel = QItemSelection(first, second) sel2 = QItemSelection() sel2.select(third, fourth) sel3 = sel + sel2 #check operator + self.assertEqual(len(sel3), 2) sel4 = sel sel4 += sel2 #check operator += self.assertEqual(len(sel4), 2) self.assertEqual(sel4, sel3)
def _RestoreSelection(self): # I have no idea why this does not work if executed at the end of reset(), # which, by the way, is triggered by the same signal! if self._selected_ids == []: self.StatusUpdated.emit(self.model().rowCount(), 0) return ids = self.model().FilterSelection(self._selected_ids) if ids == []: self.ItemSelected.emit(-1) self.StatusUpdated.emit(self.model().rowCount(), 0) return indices = self.model().IndicesFromIds(ids) selection = QItemSelection() for i in indices: selection.select(i, i) self.selectionModel().select( selection, QItemSelectionModel.ClearAndSelect | QItemSelectionModel.Rows)
def on_dir_changed(self, path): """ file added/deleted; refresh history to show it in 'working' """ # remember history selection history_ids = [] for idx in self.ui.tvHistory.selectionModel().selectedRows(): history_ids.append(self.history_model.commits[idx.row()].id) bak_path = self.files_model.patches[ self.ui.tvFiles.selectionModel().selectedRows()[0].row()].path self.refresh_history() # restore history selection for i in history_ids: for row, c in enumerate(self.history_model.commits): if c.id == i: idx1 = self.history_model.index(row, 0) idx2 = self.history_model.index( row, self.history_model.columnCount() - 1) self.ui.tvHistory.selectionModel().select( QItemSelection(idx1, idx2), QItemSelectionModel.Select) # restore file selection if not bak_path: return for row, patch in enumerate(self.files_model.patches): if patch.path == bak_path: idx1 = self.files_model.index(row, 0) idx2 = self.files_model.index( row, self.files_model.columnCount() - 1) self.ui.tvFiles.selectionModel().select( QItemSelection(idx1, idx2), QItemSelectionModel.Select) break
def paste(self): """ Pastes data from clipboard. Returns: bool: True if data was pasted successfully, False otherwise """ selection_model = self.selectionModel() if not selection_model.hasSelection(): return False clipboard = QApplication.clipboard() mime_data = clipboard.mimeData() data_formats = mime_data.formats() if 'text/plain' not in data_formats: return False pasted_table = self._read_pasted_text(QApplication.clipboard().text()) paste_length = len(pasted_table) paste_width = len(pasted_table[0]) if pasted_table else 0 first_row, last_row, first_column, last_column = _range(selection_model.selection()) selection_length = last_row - first_row + 1 selection_width = last_column - first_column + 1 model = self.model() if ( (selection_length == 1 and selection_width == 1) or model.is_expanse_row(last_row) or model.is_expanse_column(last_column) ): # If a single cell or expanse is selected, we paste everything. model_row_count = model.rowCount() if model_row_count <= first_row + paste_length: model.insertRows(model_row_count, paste_length - (model_row_count - 1 - first_row)) model_column_count = model.columnCount() if model_column_count <= first_column + paste_width: model.insertColumns(model_column_count, paste_width - (model_column_count - 1 - first_column)) capped_length = paste_length capped_width = paste_width else: capped_length = min(paste_length, selection_length) capped_width = min(paste_length, selection_width) top_left = model.index(first_row, first_column) bottom_right = model.index(first_row + capped_length - 1, first_column + capped_width - 1) model.set_box(top_left, bottom_right, pasted_table) selection = QItemSelection(top_left, bottom_right) self.selectionModel().select(selection, QItemSelectionModel.ClearAndSelect) return True
def mousePressEvent(self, event): if event.button() == Qt.LeftButton: ix = self.indexAt(event.pos()) # When opening combobox, also select current row selection = self.selectionModel() if selection: # select entire row of currently selected index top_left = self.model().index(ix.row(), 0) bottom_right = self.model().index(ix.row(), 14) item_selection = QItemSelection(top_left, bottom_right) selection.select( item_selection, QItemSelectionModel.ClearAndSelect) QTimer.singleShot(1, self, self.edit(ix)) event.setAccepted(True) return QTableView.mousePressEvent(event)
def selectionChanged(self, selected: QItemSelection, deselected: QItemSelection) -> None: """ Run this slot when an index is selected. This slot will emit the following 3 signals depending on what was selected: componentSelected, behaviorSelected, pipelineSelected :param selected: The new selection :type selected: QItemSelection :param deselected: The old selection :type deselected: QItemSelection :return: None :rtype: NoneType """ listSelected = selected.indexes() if len(listSelected) > 0: rows = set() for i in listSelected: rows.add(i.row()) if len(rows) == 1: index = listSelected[0] data = index.internalPointer() if isinstance(data, str): return None elif isinstance(data, Component): self.componentSelected.emit(data) elif isinstance(data, VisibilityBehavior): self.behaviorSelected.emit(data) elif isinstance(data, ActionPipeline): self.pipelineSelected.emit(data) elif isinstance(data, ProjectExplorerModel.LeafIndex): data = data.getData() if isinstance(data, Component): self.componentSelected.emit(data) else: raise ProjectExplorerModel.InvalidSelectionException( "Multiple row selection is not supported")
def onProjectExplorerIndexSelected(self, selected: QItemSelection, deselected: QItemSelection) -> None: """ This slot is called when an item is selected in the project explorer. :param selected: The newly selected items :type selected: QItemSelection :param deselected: The items that used to be selected. :type deselected: QItemSelection :return: None :rtype: NoneType """ selectedIndexes = selected.indexes() index = selectedIndexes[0] entity = index.internalPointer() if not isinstance(entity, (ProjectExplorerModel.LeafIndex, str)): scene = sm.StateMachine.instance.view.ui.targetGUIModelView.scene() scene.clearSelection() scene.getGraphics(entity).setSelected(True) self.ui.propertyEditorView.setModel( entity.getProperties().getModel()) self.ui.propertyEditorView.expandAll()
def on_selection_changed(self, selected: QItemSelection, _deselected: QItemSelection) -> None: """Updates the state of the delete button.""" self.delete_flight_button.setEnabled(not selected.empty())
def on_selection_changed( self, selected: QItemSelection, _deselected: QItemSelection ) -> None: index = selected.indexes()[0] self.reset_ai_toggle_state(index) self.reset_leave_toggle_state(index)
def on_selection_changed(self, selected: QtCore.QItemSelection, _: QtCore.QItemSelection) -> None: """Callback when the selected team changes.""" indexes: List[QtCore.QModelIndex] = selected.indexes() self.team_changed.emit( self.__profits[indexes[0].row()][0] if indexes else "")
def update_selection(self, highlight_size=None, offset=None): """Ensures that the selection is up-to-date and changes it if not. :param highlight_size: :param offset: """ # Use stored selection to reconstruct indexes for the current model. selection = QItemSelection() for sel in self.selection_saved: if self.obj_orientation == self.main_window.obj_orientation: top_left = self.model.index(sel[0].row(), sel[0].column()) bottom_right = self.model.index(sel[1].row(), sel[1].column()) else: top_left = self.model.index(sel[0].column(), sel[0].row()) bottom_right = self.model.index(sel[1].column(), sel[1].row()) sel_range = QItemSelectionRange(top_left, bottom_right) selection.append(sel_range) if not selection: col_count = self.model.columnCount(self.model.index(0, 0)) row_count = self.model.rowCount(self.model.index(0, 0)) # print(row_count, col_count) if self.obj_orientation == self.main_window.obj_orientation: top_left = self.model.index(0, col_count - 1) bottom_right = self.model.index(row_count - 1, col_count - 1) # print('using 1') else: top_left = self.model.index(0, row_count - 1) bottom_right = self.model.index(row_count - 1, col_count - 1) # print('using 2') # print('1 br: {},{}'.format(bottom_right.row(), bottom_right.column())) sel_range = QItemSelectionRange(top_left, bottom_right) selection.append(sel_range) last_sel = selection[-1] selection_new = QItemSelection() if not self.selection_saved: self.selection_saved.append( (last_sel.topLeft(), last_sel.bottomRight())) # Define the offset and range if self.main_window.obj_orientation == Qt.Vertical: row_offset = 0 col_offset = 0 if not offset else selection[-1].width() range_size = selection[-1].width() else: row_offset = 0 if not offset else selection[-1].height() col_offset = 0 range_size = selection[-1].height() if highlight_size is None: highlight_size = range_size # Construct the selection range indexes for the current model if self.main_window.obj_orientation == Qt.Vertical: top_left = self.model.index(last_sel.top() + row_offset, last_sel.left() + col_offset) bottom_right = self.model.index( last_sel.bottom() + row_offset, last_sel.left() + highlight_size - 1 + col_offset) else: top_left = self.model.index(last_sel.top() + row_offset, last_sel.left() + col_offset) bottom_right = self.model.index( last_sel.top() + highlight_size - 1 + row_offset, last_sel.right() + col_offset) # Check for a selection range that extends beyond the size of the current model if not bottom_right.isValid(): sel = self.selection_saved[-1] if self.obj_orientation == Qt.Vertical and \ self.obj_orientation == self.main_window.obj_orientation: count = self.model.columnCount(top_left) bottom_right = self.model.index(sel[1].row() + row_offset, count - 1 + col_offset) # print('1 br: {},{}'.format(bottom_right.row(), bottom_right.column())) elif self.obj_orientation == Qt.Vertical and \ self.obj_orientation != self.main_window.obj_orientation: count = self.model.rowCount(top_left) bottom_right = self.model.index(count - 1 + row_offset, sel[1].row() + col_offset) # print('2 br: {},{}'.format(bottom_right.row(), bottom_right.column())) elif self.obj_orientation == Qt.Horizontal and \ self.obj_orientation == self.main_window.obj_orientation: count = self.model.rowCount(top_left) bottom_right = self.model.index(count - 1 + row_offset, sel[1].column() + col_offset) # print('3 br: {},{}'.format(bottom_right.row(), bottom_right.column())) elif self.obj_orientation == Qt.Horizontal and \ self.obj_orientation != self.main_window.obj_orientation: count = self.model.columnCount(top_left) bottom_right = self.model.index(sel[1].column() + row_offset, count - 1 + col_offset) # print('4 br: {},{}'.format(bottom_right.row(), bottom_right.column())) # Create the selection range and append it to the new selection sel_range = QItemSelectionRange(top_left, bottom_right) selection_new.append(sel_range) # Clear the selection model and reselect the appropriate indexes if necessary self.selection_model.reset() self.selection_model.select(selection_new, QItemSelectionModel.SelectCurrent) self.main_window.classTable.setFocus() # Hack to 'refresh' the class tree self.main_window.classTree.expandAll()
def setSelection(self, rect, flags): """ Overrides QTableView.setSelection(). Qt Tables force multi-cell selections to be grid like, but we want this to act like a text box for selection purposes. That is to say that we want selections to wrap around. Since Qt doesn't have any setting that lets us do that, we have to subclass QTableView and reimplement setSelection. """ def is_index_enabled(index): """ Reimplementation of the Qt private inline function of the same name.""" return self.model().flags(index) & Qt.ItemIsEnabled # # Partial reimplementation of the original function. # tl = self.indexAt( QPoint( max(rect.left(), rect.right()) if self.isRightToLeft() else min(rect.left(), rect.right()), min(rect.top(), rect.bottom()))) br = self.indexAt( QPoint( min(rect.left(), rect.right()) if self.isRightToLeft() else max(rect.left(), rect.right()), max(rect.top(), rect.bottom()))) if (not self.selectionModel) or (not tl.isValid()) or (not br.isValid()) or \ (not is_index_enabled(tl)) or (not is_index_enabled(br)): return # # My code follows. # bytes_per_row = self.model().columnCount() // 2 # Don't let the user touch or cross the separator. if tl.column() <= bytes_per_row <= br.column(): return # Don't let the user select empty items. # Note: There's a reason we're using item() instead of itemFromIndex(), which is that # itemFromIndex() will lazily create an item at that index if there isn't one, # and we explicitly want to check if there is an item or not. if self.model().item(tl.row(), tl.column()) is None or \ self.model().item(br.row(), br.column()) is None: return selection = QItemSelection() selection_range = QItemSelectionRange(tl, br) if not selection_range.isEmpty(): # Add this range, and then my custom range. selection.append(selection_range) # If we have a multi-line selection. if tl.row() < br.row(): # If the selection is on the hex side... if br.column() < bytes_per_row: # ...each line will be limited to first and last hex item of that row. left_min = 0 right_max = bytes_per_row - 1 # If the selection is on the ASCII side... else: # ...each line will be limited to the first and last ASCII item of that row. left_min = bytes_per_row + 1 right_max = bytes_per_row * 2 # Select the rest of each row except the bottom row. for row in range(tl.row(), br.row()): left_index = self.model().createIndex(row, tl.column()) right_index = self.model().createIndex(row, right_max) selection.append( QItemSelectionRange(left_index, right_index)) # Select the beginning for each row except the top row. for row in range(tl.row() + 1, br.row() + 1): left_index = self.model().createIndex(row, left_min) right_index = self.model().createIndex( row, br.column()) selection.append( QItemSelectionRange(left_index, right_index)) self.selectionModel().select(selection, flags)
def _on_device_table_selection_changed( self, selected: QItemSelection, _deselected: QItemSelection) -> None: self._controls_section.setVisible(not selected.isEmpty())
def item_selection(self, direct: bool = True) -> QItemSelection: sel = QItemSelection() sel1 = QItemSelection() if direct: for i, file in enumerate(self.files): if fnmatch(file, self.renamer.src_mask): sel1.select(self.index(i, 0), self.index(i, 3)) sel.merge(sel1, QItemSelectionModel.SelectCurrent) else: for i, file in enumerate(self.files): if file in self.renamer.load_names(): sel1.select(self.index(i, 0), self.index(i, 3)) sel.merge(sel1, QItemSelectionModel.SelectCurrent) return sel