Пример #1
0
 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)
Пример #2
0
 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)
Пример #3
0
    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)
Пример #4
0
    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')
Пример #5
0
    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')