Пример #1
0
 def load_translations(self, application):
     """Fill the QApplication with the needed translations
     :param application: the QApplication on which to install the translator
     """
     from camelot.core.utils import load_translations
     from camelot.view.model_thread import get_model_thread
     get_model_thread().post(load_translations)
     for translator in self.application_admin.get_translator():
         application.installTranslator(translator)
Пример #2
0
 def load_translations(self, application):
     """Fill the QApplication with the needed translations
     :param application: the QApplication on which to install the translator
     """
     from camelot.core.utils import load_translations
     from camelot.view.model_thread import get_model_thread
     get_model_thread().post(load_translations)
     for translator in self.application_admin.get_translator():
         application.installTranslator(translator)
Пример #3
0
    def test_schema_display(self):
        def schema_display_task():
            import os
            from camelot.bin.camelot_manage import schema_display
            schema_display(os.path.join(self.images_path, 'schema.png'))

        from camelot.view.model_thread import get_model_thread, post
        post(schema_display_task)
        get_model_thread().wait_on_work()
Пример #4
0
 def test_schema_display(self):
   
     def schema_display_task():
         import os
         from camelot.bin.camelot_manage import schema_display
         schema_display(os.path.join(self.images_path, 'schema.png'))
         
     from camelot.view.model_thread import get_model_thread, post
     post( schema_display_task )
     get_model_thread().wait_on_work()
Пример #5
0
 def closeEvent( self, event ):
     from camelot.view.model_thread import get_model_thread
     model_thread = get_model_thread()
     self.workspace.close_all_views()
     self.write_settings()
     logger.info( 'closing mainwindow' )
     model_thread.stop()
     super( MainWindow, self ).closeEvent( event )
     QtCore.QCoreApplication.exit(0)
Пример #6
0
 def gui_run(self, gui_context):
     from camelot.view.model_thread import get_model_thread
     model_thread = get_model_thread()
     # we might exit the application when the workspace is not even there
     if gui_context.workspace != None:
         gui_context.workspace.close_all_views()
     if model_thread != None:
         model_thread.stop()
     QtCore.QCoreApplication.exit(0)
Пример #7
0
 def start_model_thread(self):
     """Launch the second thread where the model lives"""
     from camelot.view.model_thread import get_model_thread, construct_model_thread
     from camelot.view.remote_signals import construct_signal_handler
     construct_model_thread()
     construct_signal_handler()
     mt = get_model_thread()
     mt.setup_exception_signal.connect(self.setup_exception)
     mt.start()
Пример #8
0
 def closeEvent(self, event):
     from camelot.view.model_thread import get_model_thread
     model_thread = get_model_thread()
     self.workspace.close_all_views()
     self.write_settings()
     logger.info('closing mainwindow')
     model_thread.stop()
     super(MainWindow, self).closeEvent(event)
     QtCore.QCoreApplication.exit(0)
Пример #9
0
    def start_model_thread(self):
        """Launch the second thread where the model lives"""
        from camelot.view.model_thread import get_model_thread, construct_model_thread
        from camelot.view.remote_signals import construct_signal_handler

        construct_model_thread()
        construct_signal_handler()
        mt = get_model_thread()
        mt.setup_exception_signal.connect(self.setup_exception)
        mt.start()
Пример #10
0
 def __init__(self, parent):
     QtGui.QStatusBar.__init__(self, parent)
     from camelot.view.controls.busy_widget import BusyWidget
     self.busy_widget = BusyWidget(self)
     self.busy_widget.setMinimumWidth(100)
     self.addPermanentWidget(self.busy_widget, 0)
     mt = get_model_thread()
     mt.thread_busy_signal.connect(self.busy_widget.set_busy)
     # the model thread might allready be busy before we connected to it
     self.busy_widget.set_busy(mt.busy())
Пример #11
0
 def __init__(self, parent):
     QtGui.QStatusBar.__init__(self, parent)
     from camelot.view.controls.busy_widget import BusyWidget
     self.busy_widget = BusyWidget(self)
     self.busy_widget.setMinimumWidth(100)
     self.addPermanentWidget(self.busy_widget, 0)
     mt = get_model_thread()
     mt.thread_busy_signal.connect( self.busy_widget.set_busy )
     # the model thread might allready be busy before we connected to it
     self.busy_widget.set_busy(mt.busy())
Пример #12
0
 def start_model_thread(self):
     """Launch the second thread where the model lives"""
     from camelot.view.model_thread import get_model_thread, construct_model_thread
     from camelot.view.remote_signals import construct_signal_handler
     from camelot.core.conf import settings
     from camelot.core.sql import metadata
     metadata.bind = settings.ENGINE()
     construct_model_thread()
     construct_signal_handler()
     mt = get_model_thread()
     mt.setup_exception_signal.connect( self.initialization_exception )
     mt.start()
Пример #13
0
 def start_model_thread(self):
     """Launch the second thread where the model lives"""
     from camelot.view.model_thread import get_model_thread, construct_model_thread
     from camelot.view.remote_signals import construct_signal_handler
     from camelot.core.conf import settings
     from camelot.core.sql import metadata
     metadata.bind = settings.ENGINE()
     construct_model_thread()
     construct_signal_handler()
     mt = get_model_thread()
     mt.setup_exception_signal.connect( self.initialization_exception )
     mt.start()
Пример #14
0
 def __init__(self, parent=None):
     from camelot.view.controls.busy_widget import BusyWidget
     from camelot.view.model_thread import get_model_thread
     super(Dashboard, self).__init__(parent)
     desktop = QCoreApplication.instance().desktop()
     self.resize(desktop.width() * Dashboard.SCALE, desktop.height() * Dashboard.SCALE)
     self.closemark = CloseMark(QPixmap('close-mark.png'), self)
     self.setBGColor(Qt.white)
     busy_widget = BusyWidget(self)
     busy_widget.setMinimumSize( desktop.width() * Dashboard.SCALE, desktop.height() * Dashboard.SCALE )
     #self.addPermanentWidget(busy_widget, 0)
     mt = get_model_thread()
     mt.thread_busy_signal.connect( busy_widget.set_busy )
     busy_widget.set_busy(mt.busy())
Пример #15
0
 def __init__(self, parent=None):
     from camelot.view.controls.busy_widget import BusyWidget
     from camelot.view.model_thread import get_model_thread
     super(Dashboard, self).__init__(parent)
     desktop = QCoreApplication.instance().desktop()
     self.resize(desktop.width() * Dashboard.SCALE,
                 desktop.height() * Dashboard.SCALE)
     self.closemark = CloseMark(QPixmap('close-mark.png'), self)
     self.setBGColor(Qt.white)
     busy_widget = BusyWidget(self)
     busy_widget.setMinimumSize(desktop.width() * Dashboard.SCALE,
                                desktop.height() * Dashboard.SCALE)
     #self.addPermanentWidget(busy_widget, 0)
     mt = get_model_thread()
     mt.thread_busy_signal.connect(busy_widget.set_busy)
     busy_widget.set_busy(mt.busy())
Пример #16
0
 def setUp(self):
     self.app = get_application()
     from camelot.view import model_thread
     from camelot.view.model_thread.no_thread_model_thread import NoThreadModelThread
     from camelot.view.model_thread import get_model_thread, has_model_thread
     from camelot.view.remote_signals import construct_signal_handler, has_signal_handler
     if not has_model_thread():
         #
         # Run the tests without real threading, to avoid timing problems with screenshots etc.
         #
         model_thread._model_thread_.insert(0, NoThreadModelThread())
     if not has_signal_handler():
         construct_signal_handler()
     self.mt = get_model_thread()
     if not self.mt.isRunning():
         self.mt.start()
     # make sure the startup sequence has passed
     self.process()
Пример #17
0
def launch_meta_camelot():
    import sys
    from camelot.view.model_thread import construct_model_thread, get_model_thread
    from camelot.admin.action import GuiContext
    from PyQt4 import QtGui
    app = QtGui.QApplication([a for a in sys.argv if a])
    construct_model_thread()
    mt = get_model_thread()
    mt.start()
    settings.append( MetaSettings() )
    new_project = CreateNewProject()
    gui_context = GuiContext()
    admin = MetaCamelotAdmin()
    admin.get_stylesheet()
    gui_context.admin = admin
    new_project.gui_run( gui_context )
    # keep app alive during running of app
    return app
Пример #18
0
 def setUp(self):
     self.app = get_application()
     from camelot.view import model_thread
     from camelot.view.model_thread.no_thread_model_thread import NoThreadModelThread
     from camelot.view.model_thread import get_model_thread, has_model_thread
     from camelot.view.remote_signals import construct_signal_handler, has_signal_handler
     if not has_model_thread():
         #
         # Run the tests without real threading, to avoid timing problems with screenshots etc.
         #
         model_thread._model_thread_.insert( 0, NoThreadModelThread() )
     if not has_signal_handler():
         construct_signal_handler()
     self.mt = get_model_thread()
     if not self.mt.isRunning():
         self.mt.start()
     # make sure the startup sequence has passed
     self.process()
Пример #19
0
def launch_meta_camelot():
    import sys
    from camelot.view.model_thread import construct_model_thread, get_model_thread
    from camelot.admin.action import GuiContext
    from PyQt4 import QtGui
    app = QtGui.QApplication([a for a in sys.argv if a])
    construct_model_thread()
    mt = get_model_thread()
    mt.start()
    settings.append(MetaSettings())
    new_project = CreateNewProject()
    gui_context = GuiContext()
    admin = MetaCamelotAdmin()
    admin.get_stylesheet()
    gui_context.admin = admin
    new_project.gui_run(gui_context)
    # keep app alive during running of app
    return app
Пример #20
0
 def __init__(self, parent = None):
     super( BusyWidget, self ).__init__( parent )
     palette = QtGui.QPalette( self.palette() )
     palette.setColor( palette.Background, Qt.transparent )
     self.setPalette( palette )
     self.setAttribute( Qt.WA_TransparentForMouseEvents )
     pixmap = working_pixmap.getQPixmap()
     rows = 4
     self.cols = 8
     self.frame_height = pixmap.height() / rows
     self.frame_width = pixmap.width() / self.cols
     self.orbs = rows * self.cols
     self.highlighted_orb = 0
     self.timer = None
     self.setSizePolicy( QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding )
     mt = get_model_thread()
     mt.thread_busy_signal.connect( self.set_busy )
     # the model thread might already be busy before we connected to it
     self.set_busy( mt.busy() )
Пример #21
0
 def __init__(self, parent=None):
     super(BusyWidget, self).__init__(parent)
     palette = QtGui.QPalette(self.palette())
     palette.setColor(palette.Background, Qt.transparent)
     self.setPalette(palette)
     self.setAttribute(Qt.WA_TransparentForMouseEvents)
     pixmap = working_pixmap.getQPixmap()
     rows = 4
     self.cols = 8
     self.frame_height = pixmap.height() / rows
     self.frame_width = pixmap.width() / self.cols
     self.orbs = rows * self.cols
     self.highlighted_orb = 0
     self.timer = None
     self.setSizePolicy(QtGui.QSizePolicy.Expanding,
                        QtGui.QSizePolicy.Expanding)
     mt = get_model_thread()
     mt.thread_busy_signal.connect(self.set_busy)
     # the model thread might already be busy before we connected to it
     self.set_busy(mt.busy())
Пример #22
0
    def __init__(self, app_admin, entity):
        """

        :param app_admin: the application admin object for this application, if None,
        then the default application_admin is taken
        :param entity: the entity class for which this admin instance is to be
        used
        """
        from camelot.view.remote_signals import get_signal_handler
        if not app_admin:
            from camelot.admin.application_admin import get_application_admin
            self.app_admin = get_application_admin()
        else:
            self.app_admin = app_admin
        self.rsh = get_signal_handler()
        if entity:
            from camelot.view.model_thread import get_model_thread
            self.entity = entity
            self.mt = get_model_thread()
        #
        # caches to prevent recalculation of things
        #
        self._field_attributes = dict()
        self._subclasses = None
Пример #23
0
    def __init__(self, app_admin, entity):
        """

        :param app_admin: the application admin object for this application, if None,
        then the default application_admin is taken
        :param entity: the entity class for which this admin instance is to be
        used
        """
        from camelot.view.remote_signals import get_signal_handler
        if not app_admin:
            from camelot.admin.application_admin import get_application_admin
            self.app_admin = get_application_admin()
        else:
            self.app_admin = app_admin
        self.rsh = get_signal_handler()
        if entity:
            from camelot.view.model_thread import get_model_thread
            self.entity = entity
            self.mt = get_model_thread()
        #
        # caches to prevent recalculation of things
        #
        self._field_attributes = dict()
        self._subclasses = None
Пример #24
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')
Пример #25
0
 def gui_run(self, gui_context):
     from camelot.view.model_thread import get_model_thread
     model_thread = get_model_thread()
     gui_context.workspace.close_all_views()
     model_thread.stop()
     QtCore.QCoreApplication.exit(0)
Пример #26
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' )
Пример #27
0
 def gui_run( self, gui_context ):
     from camelot.view.model_thread import get_model_thread
     model_thread = get_model_thread()
     gui_context.workspace.close_all_views()
     model_thread.stop()
     QtCore.QCoreApplication.exit(0)
Пример #28
0
    def main(self):
        """the main function of the application, this will call all other
        functions before starting the event loop"""
        import logging

        logger = logging.getLogger("camelot.view.main")

        try:
            #
            # before anything else happens or is imported, the splash screen should be there
            #
            import sys
            from PyQt4 import QtGui, QtCore

            app = QtGui.QApplication([a for a in sys.argv if a])
            splash_window = self.show_splashscreen()

            self.show_splash_message(splash_window, _("Initialize application"))
            # regularly call processEvents to keep the splash alive
            app.processEvents()
            #  font = app.font()
            #  font.setStyleStrategy(QtGui.QFont.PreferAntialias)
            #  font.setPointSize(font.pointSize()+1)
            #  app.setFont(font)

            QT_MAJOR_VERSION = float(".".join(str(QtCore.QT_VERSION_STR).split(".")[0:2]))
            logger.debug("qt version %s, pyqt version %s" % (QtCore.QT_VERSION_STR, QtCore.PYQT_VERSION_STR))
            logger.debug("qt major version %f" % QT_MAJOR_VERSION)
            app.processEvents()
            import sqlalchemy, elixir

            logger.debug("sqlalchemy version %s" % sqlalchemy.__version__)
            logger.debug("elixir version %s" % elixir.__version__)
            app.processEvents()
            self.set_application_attributes(app)
            self.pre_initialization()
            app.processEvents()
            # regularly call processEvents to keep the splash alive
            self.show_splash_message(splash_window, _("Setup database"))
            app.processEvents()
            self.start_model_thread()
            app.processEvents()

            #
            # WEIRD, if we put this code in a method, the translations
            # don't work
            #
            from camelot.core.utils import load_translations
            from camelot.view.model_thread import get_model_thread

            self.show_splash_message(splash_window, _("Load translations"))
            app.processEvents()
            get_model_thread().post(load_translations)
            self.show_splash_message(splash_window, _("Create translator"))
            app.processEvents()
            translator = self.application_admin.get_translator()
            self.show_splash_message(splash_window, _("Install translator"))
            if isinstance(translator, list):
                for t in translator:
                    app.installTranslator(t)
            else:
                app.installTranslator(translator)
            app.processEvents()

            # self.load_translations(app)
            # Set the style sheet
            self.show_splash_message(splash_window, _("Create main window"))
            app.processEvents()
            stylesheet = self.application_admin.get_stylesheet()
            if stylesheet:
                app.setStyleSheet(stylesheet)
            app.processEvents()
            self.initialization()
            app.processEvents()
            main_window = self.create_main_window()
            self.close_splashscreen(splash_window, main_window)
            return self.start_event_loop(app)
        except Exception, e:
            logger.error("exception in initialization", exc_info=e)
            import traceback, cStringIO

            sio = cStringIO.StringIO()
            traceback.print_exc(file=sio)
            traceback_print = sio.getvalue()
            sio.close()
            exception_info = (e, traceback_print)
            self.initialization_exception(exception_info)
Пример #29
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')
Пример #30
0
    def main(self):
        """the main function of the application, this will call all other
        functions before starting the event loop"""
        import logging
        logger = logging.getLogger('camelot.view.main')

        try:
            #
            # before anything else happens or is imported, the splash screen should be there
            #
            import sys
            from PyQt4 import QtGui, QtCore
            app = QtGui.QApplication([a for a in sys.argv if a])
            splash_window = self.show_splashscreen()

            self.show_splash_message(splash_window,
                                     _('Initialize application'))
            # regularly call processEvents to keep the splash alive
            app.processEvents()
            #  font = app.font()
            #  font.setStyleStrategy(QtGui.QFont.PreferAntialias)
            #  font.setPointSize(font.pointSize()+1)
            #  app.setFont(font)

            QT_MAJOR_VERSION = float('.'.join(
                str(QtCore.QT_VERSION_STR).split('.')[0:2]))
            logger.debug('qt version %s, pyqt version %s' %
                         (QtCore.QT_VERSION_STR, QtCore.PYQT_VERSION_STR))
            logger.debug('qt major version %f' % QT_MAJOR_VERSION)
            app.processEvents()
            import sqlalchemy, elixir
            logger.debug('sqlalchemy version %s' % sqlalchemy.__version__)
            logger.debug('elixir version %s' % elixir.__version__)
            app.processEvents()
            self.set_application_attributes(app)
            self.pre_initialization()
            app.processEvents()
            # regularly call processEvents to keep the splash alive
            self.show_splash_message(splash_window, _('Setup database'))
            app.processEvents()
            self.start_model_thread()
            app.processEvents()

            #
            # WEIRD, if we put this code in a method, the translations
            # don't work
            #
            from camelot.core.utils import load_translations
            from camelot.view.model_thread import get_model_thread
            self.show_splash_message(splash_window, _('Load translations'))
            app.processEvents()
            get_model_thread().post(load_translations)
            self.show_splash_message(splash_window, _('Create translator'))
            app.processEvents()
            translator = self.application_admin.get_translator()
            self.show_splash_message(splash_window, _('Install translator'))
            if isinstance(translator, list):
                for t in translator:
                    app.installTranslator(t)
            else:
                app.installTranslator(translator)
            app.processEvents()

            #self.load_translations(app)
            # Set the style sheet
            self.show_splash_message(splash_window, _('Create main window'))
            app.processEvents()
            stylesheet = self.application_admin.get_stylesheet()
            if stylesheet:
                app.setStyleSheet(stylesheet)
            app.processEvents()
            self.initialization()
            app.processEvents()
            main_window = self.create_main_window()
            self.close_splashscreen(splash_window, main_window)
            return self.start_event_loop(app)
        except Exception, e:
            logger.error('exception in initialization', exc_info=e)
            import traceback, cStringIO
            sio = cStringIO.StringIO()
            traceback.print_exc(file=sio)
            traceback_print = sio.getvalue()
            sio.close()
            exception_info = (e, traceback_print)
            self.initialization_exception(exception_info)