class Table: SELECTION_LIMIT: int = 500 def __init__(self, browser: aqt.browser.Browser) -> None: self.browser = browser self.col: Collection = browser.col self._state: ItemState = (NoteState( self.col) if self.col.get_config_bool( Config.Bool.BROWSER_TABLE_SHOW_NOTES_MODE) else CardState( self.col)) self._model = DataModel(self.col, self._state) self._view: Optional[QTableView] = None self._current_item: Optional[ItemId] = None self._selected_items: Sequence[ItemId] = [] def set_view(self, view: QTableView) -> None: self._view = view self._setup_view() self._setup_headers() def cleanup(self) -> None: self._save_header() # Public Methods ###################################################################### # Get metadata def len(self) -> int: return self._model.len_rows() def len_selection(self) -> int: return len(self._view.selectionModel().selectedRows()) def has_current(self) -> bool: return self._view.selectionModel().currentIndex().isValid() def has_previous(self) -> bool: return self.has_current() and self._current().row() > 0 def has_next(self) -> bool: return self.has_current() and self._current().row() < self.len() - 1 def is_notes_mode(self) -> bool: return self._state.is_notes_mode() # Get objects def get_current_card(self) -> Optional[Card]: if not self.has_current(): return None return self._model.get_card(self._current()) def get_current_note(self) -> Optional[Note]: if not self.has_current(): return None return self._model.get_note(self._current()) def get_single_selected_card(self) -> Optional[Card]: """If there is only one row selected return its card, else None. This may be a different one than the current card.""" if self.len_selection() != 1: return None return self._model.get_card(self._selected()[0]) # Get ids def get_selected_card_ids(self) -> Sequence[CardId]: return self._model.get_card_ids(self._selected()) def get_selected_note_ids(self) -> Sequence[NoteId]: return self._model.get_note_ids(self._selected()) def get_card_ids_from_selected_note_ids(self) -> Sequence[CardId]: return self._state.card_ids_from_note_ids(self.get_selected_note_ids()) # Selecting def select_all(self) -> None: self._view.selectAll() def clear_selection(self) -> None: self._view.selectionModel().clear() def invert_selection(self) -> None: selection = self._view.selectionModel().selection() self.select_all() self._view.selectionModel().select( selection, cast( QItemSelectionModel.SelectionFlags, QItemSelectionModel.Deselect | QItemSelectionModel.Rows, ), ) def select_single_card(self, card_id: CardId) -> None: """Try to set the selection to the item corresponding to the given card.""" self.clear_selection() if (row := self._model.get_card_row(card_id)) is not None: self._view.selectRow(row)
class Table: SELECTION_LIMIT: int = 500 def __init__(self, browser: aqt.browser.Browser) -> None: self.browser = browser self.col: Collection = browser.col self._state: ItemState = (NoteState( self.col) if self.col.get_config_bool( Config.Bool.BROWSER_TABLE_SHOW_NOTES_MODE) else CardState( self.col)) self._model = DataModel( self.col, self._state, self._on_row_state_will_change, self._on_row_state_changed, ) self._view: QTableView | None = None # cached for performance self._len_selection = 0 self._selected_rows: list[QModelIndex] | None = None # temporarily set for selection preservation self._current_item: ItemId | None = None self._selected_items: Sequence[ItemId] = [] def set_view(self, view: QTableView) -> None: self._view = view self._setup_view() self._setup_headers() def cleanup(self) -> None: self._save_header() # Public Methods ###################################################################### # Get metadata def len(self) -> int: return self._model.len_rows() def len_selection(self, refresh: bool = False) -> int: # `len(self._view.selectionModel().selectedRows())` is slow for large # selections, because Qt queries flags() for every selected cell, so we # calculate the number of selected rows ourselves return self._len_selection def has_current(self) -> bool: return self._view.selectionModel().currentIndex().isValid() def has_previous(self) -> bool: return self.has_current() and self._current().row() > 0 def has_next(self) -> bool: return self.has_current() and self._current().row() < self.len() - 1 def is_notes_mode(self) -> bool: return self._state.is_notes_mode() # Get objects def get_current_card(self) -> Card | None: return self._model.get_card(self._current()) def get_current_note(self) -> Note | None: return self._model.get_note(self._current()) def get_single_selected_card(self) -> Card | None: """If there is only one row selected return its card, else None. This may be a different one than the current card.""" if self.len_selection() != 1: return None return self._model.get_card(self._selected()[0]) # Get ids def get_selected_card_ids(self) -> Sequence[CardId]: return self._model.get_card_ids(self._selected()) def get_selected_note_ids(self) -> Sequence[NoteId]: return self._model.get_note_ids(self._selected()) def get_card_ids_from_selected_note_ids(self) -> Sequence[CardId]: return self._state.card_ids_from_note_ids(self.get_selected_note_ids()) # Selecting def select_all(self) -> None: self._view.selectAll() def clear_selection(self) -> None: self._len_selection = 0 self._selected_rows = None self._view.selectionModel().clear() def invert_selection(self) -> None: selection = self._view.selectionModel().selection() self.select_all() self._view.selectionModel().select( selection, QItemSelectionModel.SelectionFlag.Deselect | QItemSelectionModel.SelectionFlag.Rows, ) def select_single_card(self, card_id: CardId) -> None: """Try to set the selection to the item corresponding to the given card.""" self._reset_selection() if (row := self._model.get_card_row(card_id)) is not None: self._view.selectRow(row) self._scroll_to_row(row, scroll_even_if_visible=True) else: