def _refresh_content(self, rows): self.display_cache = Fifo(10 * self.max_number_of_rows) self.edit_cache = Fifo(10 * self.max_number_of_rows) self.attributes_cache = Fifo(10 * self.max_number_of_rows) locker = QtCore.QMutexLocker(self._mutex) self.rows_under_request = set() self.unflushed_rows = set() locker.unlock() self.setRowCount(rows)
def _refresh_content(self, rows): assert object_thread(self) locker = QtCore.QMutexLocker(self._mutex) self.display_cache = Fifo(10 * self.max_number_of_rows) self.edit_cache = Fifo(10 * self.max_number_of_rows) self.attributes_cache = Fifo(10 * self.max_number_of_rows) self.rows_under_request = set() self.unflushed_rows = set() # once the cache has been cleared, no updates ought to be accepted self._update_requests = list() locker.unlock() self.setRowCount(rows)
def __init__(self, admin, model, initial_validation=False): """ :param mode: a collection proxy the validator should inspect, or None if only the objectValidity method is going to get used. :param verifiy_initial_validity: do an inital check to see if all rows in a model are valid, defaults to False, since this might take a lot of time on large collections. """ super(ObjectValidator, self).__init__() self.admin = admin self.model = model self.message_cache = Fifo(10) if model: model.dataChanged.connect( self.data_changed ) model.layoutChanged.connect( self.layout_changed ) self._invalid_rows = set() if initial_validation: post(self.validate_all_rows)
def __init__(self, admin, collection_getter, columns_getter, max_number_of_rows=10, edits=None, flush_changes=True, cache_collection_proxy=None): """ :param admin: the admin interface for the items in the collection :param collection_getter: a function that takes no arguments and returns the collection that will be visualized. This function will be called inside the model thread, to prevent delays when this function causes the database to be hit. If the collection is a list, it should not contain any duplicate elements. :param columns_getter: a function that takes no arguments and returns the columns that will be cached in the proxy. This function will be called inside the model thread. :param cache_collection_proxy: the CollectionProxy on which this CollectionProxy will reuse the cache. Passing a cache has the advantage that objects that were present in the original cache will remain at the same row in the new cache This is used when a form is created from a tableview. Because between the last query of the tableview, and the first of the form, the object might have changed position in the query. """ super(CollectionProxy, self).__init__() from camelot.view.model_thread import get_model_thread self.logger = logging.getLogger(logger.name + '.%s' % id(self)) self.logger.debug('initialize query table for %s' % (admin.get_verbose_name())) self._mutex = QtCore.QMutex() self.admin = admin self._horizontal_header_height = QtGui.QFontMetrics( self._header_font_required).height() + 10 vertical_header_font_height = QtGui.QFontMetrics( self._header_font).height() self._vertical_header_height = vertical_header_font_height * self.admin.lines_per_row + 10 self.iconSize = QtCore.QSize(vertical_header_font_height, vertical_header_font_height) if self.header_icon: self.form_icon = QtCore.QVariant( self.header_icon.getQIcon().pixmap(self.iconSize)) else: self.form_icon = QtCore.QVariant() self.validator = admin.create_validator(self) self._collection_getter = collection_getter self.column_count = 0 self.flush_changes = flush_changes self.delegate_manager = None self.mt = get_model_thread() # Set database connection and load data self._rows = 0 self._columns = [] self._static_field_attributes = [] self._max_number_of_rows = max_number_of_rows if cache_collection_proxy: self.display_cache = cache_collection_proxy.display_cache.shallow_copy( 10 * self.max_number_of_rows) self.edit_cache = cache_collection_proxy.edit_cache.shallow_copy( 10 * self.max_number_of_rows) self.attributes_cache = cache_collection_proxy.attributes_cache.shallow_copy( 10 * self.max_number_of_rows) else: self.display_cache = Fifo(10 * self.max_number_of_rows) self.edit_cache = Fifo(10 * self.max_number_of_rows) self.attributes_cache = Fifo(10 * self.max_number_of_rows) # The rows in the table for which a cache refill is under request self.rows_under_request = set() self._update_requests = list() # The rows that have unflushed changes self.unflushed_rows = set() self._sort_and_filter = SortingRowMapper() # Set edits self.edits = edits or [] self.row_changed_signal.connect(self._emit_changes) self.rsh = get_signal_handler() self.rsh.connect_signals(self) def get_columns(): self._columns = columns_getter() self._static_field_attributes = list( self.admin.get_static_field_attributes( [c[0] for c in self._columns])) return self._columns post(get_columns, self.setColumns) # # the initial collection might contain unflushed rows post(self.updateUnflushedRows) # # in that way the number of rows is requested as well if cache_collection_proxy: self.setRowCount(cache_collection_proxy.rowCount()) else: post(self.getRowCount, self.setRowCount) self.logger.debug('initialization finished')
def __init__( self, admin, max_number_of_rows=10, flush_changes=True, cache_collection_proxy=None, ): """ :param admin: the admin interface for the items in the collection :param cache_collection_proxy: the CollectionProxy on which this CollectionProxy will reuse the cache. Passing a cache has the advantage that objects that were present in the original cache will remain at the same row in the new cache This is used when a form is created from a tableview. Because between the last query of the tableview, and the first of the form, the object might have changed position in the query. """ super(CollectionProxy, self).__init__() assert object_thread(self) from camelot.view.model_thread import get_model_thread # # The source model will contain the actual data stripped from the # objects in the collection. # self.source_model = QtGui.QStandardItemModel() self.setSourceModel(self.source_model) self.logger = logging.getLogger(logger.name + '.%s' % id(self)) self.logger.debug('initialize query table for %s' % (admin.get_verbose_name())) # the mutex is recursive to avoid blocking during unittest, when # model and view are used in the same thread self._mutex = QtCore.QMutex(QtCore.QMutex.Recursive) self.admin = admin self.list_action = admin.list_action self.row_model_context = RowModelContext() self.row_model_context.admin = admin self.settings = self.admin.get_settings() self._horizontal_header_height = QtGui.QFontMetrics( self._header_font_required).height() + 10 self._header_font_metrics = QtGui.QFontMetrics(self._header_font) vertical_header_font_height = QtGui.QFontMetrics( self._header_font).height() self._vertical_header_height = vertical_header_font_height * self.admin.lines_per_row + 10 self.vertical_header_size = QtCore.QSize(16 + 10, self._vertical_header_height) self.validator = admin.get_validator(self) self._collection = [] self.flush_changes = flush_changes self.mt = get_model_thread() # Set database connection and load data self._rows = None self._columns = [] self._static_field_attributes = [] self._max_number_of_rows = max_number_of_rows max_cache = 10 * self.max_number_of_rows if cache_collection_proxy: cached_entries = len(cache_collection_proxy.display_cache) max_cache = max(cached_entries, max_cache) self.display_cache = cache_collection_proxy.display_cache.shallow_copy( max_cache) self.edit_cache = cache_collection_proxy.edit_cache.shallow_copy( max_cache) self.attributes_cache = cache_collection_proxy.attributes_cache.shallow_copy( max_cache) self.action_state_cache = cache_collection_proxy.action_state_cache.shallow_copy( max_cache) else: self.display_cache = Fifo(max_cache) self.edit_cache = Fifo(max_cache) self.attributes_cache = Fifo(max_cache) self.action_state_cache = Fifo(max_cache) # The rows in the table for which a cache refill is under request self.rows_under_request = set() self._update_requests = list() self._rowcount_requests = list() # The rows that have unflushed changes self.unflushed_rows = set() self._sort_and_filter = SortingRowMapper() self.row_changed_signal.connect(self._emit_changes) self._rows_about_to_be_inserted_signal.connect( self._rows_about_to_be_inserted, Qt.QueuedConnection) self._rows_inserted_signal.connect(self._rows_inserted, Qt.QueuedConnection) self.rsh = get_signal_handler() self.rsh.connect_signals(self) # # the initial collection might contain unflushed rows post(self._update_unflushed_rows) # # in that way the number of rows is requested as well if cache_collection_proxy: self.setRowCount(cache_collection_proxy.rowCount()) self.logger.debug('initialization finished')