Exemplo n.º 1
0
    def __init__(self, gui_context, parent=None):
        from workspace import DesktopWorkspace
        logger.debug('initializing main window')
        QtGui.QMainWindow.__init__(self, parent)

        self.splash_screen = None
        self.toolbars = []
        self.nav_pane = None
        self.app_admin = gui_context.admin.get_application_admin()

        logger.debug('setting up workspace')
        self.workspace = DesktopWorkspace(self.app_admin, self)
        self.gui_context = gui_context
        self.gui_context.workspace = self.workspace

        logger.debug('setting child windows dictionary')

        logger.debug('setting central widget to our workspace')
        self.setCentralWidget(self.workspace)

        self.workspace.change_view_mode_signal.connect(self.change_view_mode)
        self.workspace.last_view_closed_signal.connect(self.unmaximize_view)
        self.workspace.view_activated_signal.connect(self.view_activated)

        logger.debug('creating navigation pane')
        post(self.app_admin.get_sections, self.set_sections)

        logger.debug('creating the menus')
        post(self.app_admin.get_main_menu, self.set_main_menu)

        logger.debug('creating the toolbars')
        post(self.app_admin.get_toolbar_actions,
             self.set_left_toolbar_actions,
             args=(Qt.LeftToolBarArea, ))
        post(self.app_admin.get_toolbar_actions,
             self.set_right_toolbar_actions,
             args=(Qt.RightToolBarArea, ))
        post(self.app_admin.get_toolbar_actions,
             self.set_top_toolbar_actions,
             args=(Qt.TopToolBarArea, ))
        post(self.app_admin.get_toolbar_actions,
             self.set_bottom_toolbar_actions,
             args=(Qt.BottomToolBarArea, ))
        post(self.app_admin.get_hidden_actions, self.set_hidden_actions)

        logger.debug('reading saved settings')
        self.read_settings()

        windowtitle = self.app_admin.get_name()
        logger.debug(u'setting up window title: %s' % windowtitle)
        self.setWindowTitle(windowtitle)
        self.app_admin.title_changed_signal.connect(self.setWindowTitle)

        logger.debug('initialization complete')
Exemplo n.º 2
0
    def __init__(self, app_admin, parent=None):
        from workspace import DesktopWorkspace
        logger.debug('initializing main window')
        QtGui.QMainWindow.__init__(self, parent)

        self.app_admin = app_admin

        logger.debug('setting up workspace')
        self.workspace = DesktopWorkspace(self)

        logger.debug('setting child windows dictionary')

        logger.debug('setting central widget to our workspace')
        self.setCentralWidget(self.workspace)

        self.workspace.view_activated_signal.connect(self.updateMenus)
        self.workspace.change_view_mode_signal.connect(self.change_view_mode)
        self.workspace.last_view_closed_signal.connect(self.unmaximize_view)

        logger.debug('creating navigation pane')
        self.createNavigationPane()

        logger.debug('creating all the required actions')
        self.createActions()

        logger.debug('creating the menus')
        self.createMenus()

        logger.debug('creating the toolbars')
        self.createToolBars()

        logger.debug('creating status bar')
        self.createStatusBar()

        logger.debug('updating menus')
        self.updateMenus()

        logger.debug('reading saved settings')
        self.readSettings()

        logger.debug('setting up printer object')
        self.printer = Printer()

        windowtitle = self.app_admin.get_name()
        logger.debug('setting up window title: %s' % windowtitle)
        self.setWindowTitle(windowtitle)
        self.app_admin.title_changed_signal.connect(self.setWindowTitle)

        #QtCore.QTimer.singleShot(0, self.doInitialization)
        logger.debug('initialization complete')
Exemplo n.º 3
0
    def __init__(self, gui_context, parent=None):
        from workspace import DesktopWorkspace
        logger.debug('initializing main window')
        QtGui.QMainWindow.__init__(self, parent)

        self.splash_screen = None
        self.toolbars = []
        self.nav_pane = None
        self.app_admin = gui_context.admin.get_application_admin()
        
        logger.debug('setting up workspace')
        self.workspace = DesktopWorkspace( self.app_admin, self )
        self.gui_context = gui_context
        self.gui_context.workspace = self.workspace

        logger.debug('setting child windows dictionary')

        logger.debug('setting central widget to our workspace')
        self.setCentralWidget( self.workspace )

        self.workspace.change_view_mode_signal.connect( self.change_view_mode )
        self.workspace.last_view_closed_signal.connect( self.unmaximize_view )
        self.workspace.view_activated_signal.connect( self.view_activated )

        logger.debug('creating navigation pane')
        post( self.app_admin.get_sections, self.set_sections )
        
        logger.debug('creating the menus')
        post( self.app_admin.get_main_menu, self.set_main_menu )

        logger.debug('creating the toolbars')
        post( self.app_admin.get_toolbar_actions, 
              self.set_left_toolbar_actions,
              args = (Qt.LeftToolBarArea,) )
        post( self.app_admin.get_toolbar_actions, 
              self.set_right_toolbar_actions,
              args = (Qt.RightToolBarArea,) )
        post( self.app_admin.get_toolbar_actions, 
              self.set_top_toolbar_actions,
              args = (Qt.TopToolBarArea,) )
        post( self.app_admin.get_toolbar_actions, 
              self.set_bottom_toolbar_actions,
              args = (Qt.BottomToolBarArea,) )
        post( self.app_admin.get_hidden_actions,
              self.set_hidden_actions )

        logger.debug('reading saved settings')
        self.read_settings()
        
        windowtitle = self.app_admin.get_name()
        logger.debug( u'setting up window title: %s'%windowtitle )
        self.setWindowTitle( windowtitle )
        self.app_admin.title_changed_signal.connect( self.setWindowTitle )

        logger.debug('initialization complete')
Exemplo n.º 4
0
    def __init__(self, app_admin, parent=None):
        from workspace import DesktopWorkspace
        logger.debug('initializing main window')
        QtGui.QMainWindow.__init__(self, parent)

        self.app_admin = app_admin

        logger.debug('setting up workspace')
        self.workspace = DesktopWorkspace(self)

        logger.debug('setting child windows dictionary')

        logger.debug('setting central widget to our workspace')
        self.setCentralWidget(self.workspace)

        self.workspace.view_activated_signal.connect(self.updateMenus)
        self.workspace.change_view_mode_signal.connect( self.change_view_mode )
        self.workspace.last_view_closed_signal.connect( self.unmaximize_view )

        logger.debug('creating navigation pane')
        self.createNavigationPane()

        logger.debug('creating all the required actions')
        self.createActions()

        logger.debug('creating the menus')
        self.createMenus()

        logger.debug('creating the toolbars')
        self.createToolBars()

        logger.debug('creating status bar')
        self.createStatusBar()

        logger.debug('updating menus')
        self.updateMenus()

        logger.debug('reading saved settings')
        self.readSettings()

        logger.debug('setting up printer object')
        self.printer = Printer()
        
        windowtitle = self.app_admin.get_name()
        logger.debug('setting up window title: %s' % windowtitle)
        self.setWindowTitle(windowtitle)
        self.app_admin.title_changed_signal.connect( self.setWindowTitle )

        #QtCore.QTimer.singleShot(0, self.doInitialization)
        logger.debug('initialization complete')
Exemplo n.º 5
0
class MainWindow(QtGui.QMainWindow):
    """Main window of a Desktop Camelot application
    
    :param gui_context: an :class:`camelot.admin.action.application_action.ApplicationActionGuiContext`
        object
    :param parent: a :class:`QtGui.QWidget` object or :class:`None` 
    
    .. attribute:: splash_screen 
        a :class:`QtGui.QWidget` that needs to be closed when
        the main window is shown.
    """

    def __init__(self, gui_context, parent=None):
        from workspace import DesktopWorkspace
        logger.debug('initializing main window')
        QtGui.QMainWindow.__init__(self, parent)

        self.splash_screen = None
        self.toolbars = []
        self.nav_pane = None
        self.app_admin = gui_context.admin.get_application_admin()
        
        logger.debug('setting up workspace')
        self.workspace = DesktopWorkspace( self.app_admin, self )
        self.gui_context = gui_context
        self.gui_context.workspace = self.workspace

        logger.debug('setting child windows dictionary')

        logger.debug('setting central widget to our workspace')
        self.setCentralWidget( self.workspace )

        self.workspace.change_view_mode_signal.connect( self.change_view_mode )
        self.workspace.last_view_closed_signal.connect( self.unmaximize_view )
        self.workspace.view_activated_signal.connect( self.view_activated )

        logger.debug('creating navigation pane')
        post( self.app_admin.get_sections, self.set_sections )
        
        logger.debug('creating the menus')
        post( self.app_admin.get_main_menu, self.set_main_menu )

        logger.debug('creating the toolbars')
        post( self.app_admin.get_toolbar_actions, 
              self.set_left_toolbar_actions,
              args = (Qt.LeftToolBarArea,) )
        post( self.app_admin.get_toolbar_actions, 
              self.set_right_toolbar_actions,
              args = (Qt.RightToolBarArea,) )
        post( self.app_admin.get_toolbar_actions, 
              self.set_top_toolbar_actions,
              args = (Qt.TopToolBarArea,) )
        post( self.app_admin.get_toolbar_actions, 
              self.set_bottom_toolbar_actions,
              args = (Qt.BottomToolBarArea,) )
        post( self.app_admin.get_hidden_actions,
              self.set_hidden_actions )

        logger.debug('reading saved settings')
        self.read_settings()
        
        windowtitle = self.app_admin.get_name()
        logger.debug( u'setting up window title: %s'%windowtitle )
        self.setWindowTitle( windowtitle )
        self.app_admin.title_changed_signal.connect( self.setWindowTitle )

        logger.debug('initialization complete')

    @QtCore.pyqtSlot()
    def show( self ):
        """This method wait until the main window is completely set up, and
        only then shows it.  This is a workaround for a bug in Qt on OS X
        
        https://bugreports.qt.nokia.com/browse/QTBUG-18567
        
        """
        post( lambda:None, self._delayed_show )
        
    @QtCore.pyqtSlot(object)
    def _delayed_show( self, _o ):
        """Call to the underlying :meth:`QMainWindow.show`, to be used in
        :meth:`MainWindow.show`
        """
        super( MainWindow, self ).show()
        if self.splash_screen:
            self.splash_screen.close()
        
    @QtCore.pyqtSlot()
    def unmaximize_view( self ):
        """Show the navigation pane and the menu bar if they exist """
        if self.navpane:
            self.navpane.show()
        if self.menuBar():
            self.menuBar().show()

    @QtCore.pyqtSlot()
    def change_view_mode( self ):
        """Switch between hidden or shown menubar and navigation pane"""
        if self.menuBar().isHidden():
            if self.navpane:
                self.navpane.show()
            self.menuBar().show()
        else:
            if self.navpane:
                self.navpane.hide()
            self.menuBar().hide()

    def read_settings( self ):
        """Restore the geometry of the main window to its last saved state"""
        settings = QtCore.QSettings()
        self.restoreGeometry(settings.value('geometry').toByteArray())

    def write_settings(self):
        """Store the current geometry of the main window"""
        logger.debug('writing application settings')
        settings = QtCore.QSettings()
        settings.setValue('geometry', QtCore.QVariant(self.saveGeometry()))
        logger.debug('settings written')

    @QtCore.pyqtSlot( object )
    def set_main_menu( self, main_menu ):
        """Set the main menu
        :param main_menu: a list of :class:`camelot.admin.menu.Menu` objects,
            as returned by the :meth:`camelot.admin.application_admin.ApplicationAdmin.get_main_menu`
            method.
        """
        from camelot.view.controls.action_widget import ActionAction
        if main_menu == None:
            return
        menu_bar = self.menuBar()
        for menu in main_menu:
            menu_bar.addMenu( menu.render( self.gui_context, menu_bar ) )
        for qaction in menu_bar.findChildren( ActionAction ):
            qaction.triggered.connect( self.action_triggered )

    def get_gui_context( self ):
        """Get the :class:`GuiContext` of the active view in the mainwindow,
        or the :class:`GuiContext` of the application.

        :return: a :class:`camelot.admin.action.base.GuiContext`
        """
        active_view = self.gui_context.workspace.active_view()
        if active_view:
            return active_view.gui_context
        return self.gui_context
        
    @QtCore.pyqtSlot( object, object )
    def set_toolbar_actions( self, toolbar_area, toolbar_actions ):
        """Set the toolbar for a specific area
        :param toolbar_area: the area on which to put the toolbar, from
            :class:`Qt.LeftToolBarArea` through :class:`Qt.BottomToolBarArea`
        :param toolbar_actions: a list of :class:`camelot.admin.action..base.Action` objects,
            as returned by the :meth:`camelot.admin.application_admin.ApplicationAdmin.get_toolbar_actions`
            method.
        """
        from camelot.view.controls.action_widget import ActionAction
        if toolbar_actions != None:
            #
            # gather menu bar actions to prevent duplication of QActions
            #
            qactions = dict()
            menu_bar = self.menuBar()
            if menu_bar:
                for qaction in menu_bar.findChildren( ActionAction ):
                    qactions[qaction.action] = qaction
            toolbar = QtGui.QToolBar( _('Toolbar') )
            self.addToolBar( toolbar_area, toolbar )
            toolbar.setObjectName( 'MainWindowToolBar_%i'%toolbar_area )
            toolbar.setMovable( False )
            toolbar.setFloatable( False )
            for action in toolbar_actions:
                qaction = qactions.get( action, None )
                if qaction == None:
                    qaction = action.render( self.gui_context, toolbar )
                    qaction.triggered.connect( self.action_triggered )
                toolbar.addAction( qaction )
            self.toolbars.append( toolbar )
            toolbar.addWidget( BusyWidget() )
                
    @QtCore.pyqtSlot( object )
    def set_left_toolbar_actions( self, toolbar_actions ):
        self.set_toolbar_actions( Qt.LeftToolBarArea, toolbar_actions )
    
    @QtCore.pyqtSlot( object )
    def set_right_toolbar_actions( self, toolbar_actions ):
        self.set_toolbar_actions( Qt.RightToolBarArea, toolbar_actions )
        
    @QtCore.pyqtSlot( object )
    def set_top_toolbar_actions( self, toolbar_actions ):
        self.set_toolbar_actions( Qt.TopToolBarArea, toolbar_actions )
        
    @QtCore.pyqtSlot( object )
    def set_bottom_toolbar_actions( self, toolbar_actions ):
        self.set_toolbar_actions( Qt.BottomToolBarArea, toolbar_actions )

    @QtCore.pyqtSlot( object )
    def set_hidden_actions( self, hidden_actions ):
        from camelot.view.controls.action_widget import ActionAction
        for action in hidden_actions:
            action_action = ActionAction( action, self.gui_context, self )
            action_action.triggered.connect( self.action_triggered )
            self.addAction( action_action )
        
    @QtCore.pyqtSlot()
    def view_activated( self ):
        """Update the state of the actions when the active tab in the
        desktop widget has changed"""
        from camelot.view.controls.action_widget import ActionAction
        gui_context = self.get_gui_context()
        model_context = gui_context.create_model_context()
        for toolbar in self.toolbars:
            for qaction in toolbar.actions():
                if isinstance( qaction, ActionAction ):
                    post( qaction.action.get_state,
                          qaction.set_state,
                          args = ( model_context, ) )
        menu_bar = self.menuBar()
        if menu_bar:
            for qaction in menu_bar.findChildren( ActionAction ):
                post( qaction.action.get_state,
                      qaction.set_state,
                      args = ( model_context, ) )
        
    @QtCore.pyqtSlot( bool )
    def action_triggered( self, _checked = False ):
        """Execute an action that was triggered somewhere in the main window,
        such as the toolbar or the main menu"""
        action_action = self.sender()
        gui_context = self.get_gui_context()
        action_action.action.gui_run( gui_context )
        
    @QtCore.pyqtSlot( object )
    def set_sections( self, sections ):
        """Set the sections of the navigation pane
        :param main_menu: a list of :class:`camelot.admin.section.Section` objects,
            as returned by the :meth:`camelot.admin.application_admin.ApplicationAdmin.get_sections`
            method.
        """
        if sections != None:
            self.navpane = NavigationPane(
                self.app_admin,
                workspace=self.workspace,
                parent=self
            )
            self.addDockWidget( Qt.LeftDockWidgetArea, self.navpane )
        else:
            self.navpane = None

    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)
Exemplo n.º 6
0
class MainWindow(QtGui.QMainWindow):
    """Main window GUI"""
    def __init__(self, app_admin, parent=None):
        from workspace import DesktopWorkspace
        logger.debug('initializing main window')
        QtGui.QMainWindow.__init__(self, parent)

        self.app_admin = app_admin

        logger.debug('setting up workspace')
        self.workspace = DesktopWorkspace(self)

        logger.debug('setting child windows dictionary')

        logger.debug('setting central widget to our workspace')
        self.setCentralWidget(self.workspace)

        self.workspace.view_activated_signal.connect(self.updateMenus)
        self.workspace.change_view_mode_signal.connect(self.change_view_mode)
        self.workspace.last_view_closed_signal.connect(self.unmaximize_view)

        logger.debug('creating navigation pane')
        self.createNavigationPane()

        logger.debug('creating all the required actions')
        self.createActions()

        logger.debug('creating the menus')
        self.createMenus()

        logger.debug('creating the toolbars')
        self.createToolBars()

        logger.debug('creating status bar')
        self.createStatusBar()

        logger.debug('updating menus')
        self.updateMenus()

        logger.debug('reading saved settings')
        self.readSettings()

        logger.debug('setting up printer object')
        self.printer = Printer()

        windowtitle = self.app_admin.get_name()
        logger.debug('setting up window title: %s' % windowtitle)
        self.setWindowTitle(windowtitle)
        self.app_admin.title_changed_signal.connect(self.setWindowTitle)

        #QtCore.QTimer.singleShot(0, self.doInitialization)
        logger.debug('initialization complete')

    # Application settings

    def about(self):
        logger.debug('showing about message box')
        abtmsg = self.app_admin.get_about()
        QtGui.QMessageBox.about(self, _('About'), _(abtmsg))
        logger.debug('about message closed')

    def whats_new(self):
        widget = self.app_admin.get_whats_new()
        if widget:
            widget.exec_()

    def affiliated_website(self):
        from PyQt4.QtGui import QDesktopServices
        url = self.app_admin.get_affiliated_url()
        if url:
            QDesktopServices.openUrl(url)

    def remote_support(self):
        from PyQt4.QtGui import QDesktopServices
        url = self.app_admin.get_remote_support_url()
        if url:
            QDesktopServices.openUrl(url)

    @QtCore.pyqtSlot()
    def unmaximize_view(self):
        self.navpane.show()
        self.menuBar().show()

    @QtCore.pyqtSlot()
    def change_view_mode(self):
        if self.menuBar().isHidden():
            self.navpane.show()
            self.menuBar().show()
        else:
            self.navpane.hide()
            self.menuBar().hide()

    def readSettings(self):
        settings = QtCore.QSettings()
        self.restoreGeometry(settings.value('geometry').toByteArray())
        # Don't restore state, since it messes up the toolbar if stuff was
        # added
        # self.restoreState(settings.value('state').toByteArray())

    def writeSettings(self):
        logger.debug('writing application settings')
        settings = QtCore.QSettings()
        settings.setValue('geometry', QtCore.QVariant(self.saveGeometry()))
        #settings.setValue('state', QtCore.QVariant(self.saveState()))
        logger.debug('settings written')

    def display_exception_message_box(self, exc_info):
        from controls.exception import model_thread_exception_message_box
        model_thread_exception_message_box(exc_info)

    def runAction(self, name, callable):
        progress = QtGui.QProgressDialog(_('Please wait'), QtCore.QString(), 0,
                                         0)
        progress.setWindowTitle(name)
        progress.show()
        post(callable,
             progress.close,
             exception=self.display_exception_message_box)

    def createActions(self):
        self.backupAct = ActionFactory.backup(self, self.backup)
        self.restoreAct = ActionFactory.restore(self, self.restore)
        self.pageSetupAct = ActionFactory.page_setup(self, self.pageSetup)
        self.printAct = ActionFactory.print_(self, self.printDoc)
        self.previewAct = ActionFactory.print_preview(self, self.previewDoc)
        self.exitAct = ActionFactory.exit(self, slot=self.close)
        self.copyAct = ActionFactory.copy(self, slot=self.copy)
        self.selectAllAct = ActionFactory.select_all(self,
                                                     slot=self.select_all)
        self.separatorAct = QtGui.QAction(self)
        self.separatorAct.setSeparator(True)
        self.aboutAct = ActionFactory.about(self, slot=self.about)
        self.whats_new_action = ActionFactory.whats_new(self,
                                                        slot=self.whats_new)
        self.affiliated_website_action = ActionFactory.affiliated_website(
            self, slot=self.affiliated_website)
        self.remote_support_action = ActionFactory.remote_support(
            self, slot=self.remote_support)
        self.helpAct = ActionFactory.help(self, slot=self.help)
        self.newAct = ActionFactory.new(self, slot=self.new)
        self.deleteAct = ActionFactory.delete(self, slot=self.delete)
        self.viewFirstAct = ActionFactory.view_first(self, self.viewFirst)
        self.viewLastAct = ActionFactory.view_last(self, self.viewLast)
        self.viewNextAct = ActionFactory.view_next(self, self.viewNext)
        self.viewPreviousAct = ActionFactory.view_previous(
            self, self.viewPrevious)
        self.viewFirstAct.setIconVisibleInMenu(False)
        self.viewLastAct.setIconVisibleInMenu(False)
        self.viewNextAct.setIconVisibleInMenu(False)
        self.viewPreviousAct.setIconVisibleInMenu(False)
        self.updateValueAct = ActionFactory.update_values(
            self, slot=self.updateValue)
        self.mergeDocumentAct = ActionFactory.merge_document(
            self, slot=self.merge_document)
        self.exportToExcelAct = ActionFactory.export_excel(
            self, slot=self.exportToExcel)
        self.exportToWordAct = ActionFactory.export_word(
            self, slot=self.exportToWord)
        self.exportToMailAct = ActionFactory.export_mail(
            self, slot=self.exportToMail)
        self.importFromFileAct = ActionFactory.import_file(
            self, slot=self.importFromFile)
        self.sessionRefreshAct = ActionFactory.refresh(
            self, slot=self.refresh_session)

        self.app_actions = []
        for action in self.app_admin.get_actions():

            def bind_action(parent, action):
                def slot(*args):
                    action.run(parent)

                return slot

            self.app_actions.append(
                ActionFactory.create_action(
                    parent=self,
                    text=unicode(action.get_verbose_name()),
                    slot=bind_action(self, action),
                    actionicon=action.get_icon(),
                    tip=unicode(action.get_verbose_name())))

    # QAction slots and methods implementations

    def refresh_session(self):
        from elixir import session
        from camelot.core.orm import refresh_session
        refresh_session(session)

    def help(self):
        #
        # Import WebKit as late as possible, since it's the largest
        # part of the QT Library (15 meg on Ubuntu linux)
        #
        from PyQt4 import QtWebKit
        TOP_LEVEL = None
        self.view = QtWebKit.QWebView(TOP_LEVEL)
        #print self.app_admin.get_help_url()
        #print self.app_admin.get_help_base()
        #index_file = open(self.app_admin.get_help_url(),'r')
        #self.view.setHtml (index_file.read(), self.app_admin.get_help_base())
        self.view.load(self.app_admin.get_help_url())
        self.view.setWindowTitle(_('Help Browser'))
        self.view.setWindowIcon(self.helpAct.icon())
        self.view.show()

    def backup(self):
        self.app_admin.backup(self)

    def restore(self):
        self.app_admin.restore(self)

    def saveAs(self):
        pass

    def copy(self):
        self.activeMdiChild().copy_selected_rows()

    def select_all(self):
        self.activeMdiChild().select_all_rows()

    def printDoc(self):
        self.previewDoc()

    def previewDoc(self):
        active = self.activeMdiChild()
        from camelot.admin.form_action import PrintHtmlFormAction

        class PrintPreview(PrintHtmlFormAction):
            def html(self, entity_getter):
                return active.to_html()

        action = PrintPreview(_('Print Preview'))
        action.run(lambda: None)

    def new(self):
        self.activeMdiChild().newRow()

    def delete(self):
        self.activeMdiChild().deleteSelectedRows()

    def pageSetup(self):
        pass

    def viewFirst(self):
        """selects view's first row"""
        active = self.activeMdiChild()
        active.viewFirst()

    def viewLast(self):
        """selects view's last row"""
        active = self.activeMdiChild()
        active.viewLast()

    def viewNext(self):
        """selects view's next row"""
        active = self.activeMdiChild()
        active.viewNext()

    def viewPrevious(self):
        """selects view's previous row"""
        active = self.activeMdiChild()
        active.viewPrevious()

    def updateValue(self):
        from camelot.view.wizard.update_value import UpdateValueWizard

        admin = self.activeMdiChild().get_admin()
        selection_getter = self.activeMdiChild().get_selection
        wizard = UpdateValueWizard(admin=admin,
                                   selection_getter=selection_getter)
        wizard.exec_()

    def merge_document(self):
        """Run the merge document wizard on the selection in the current
        table view"""
        from camelot.view.wizard.merge_document import MergeDocumentWizard

        selection_getter = self.activeMdiChild().get_selection
        wizard = MergeDocumentWizard(selection_getter=selection_getter)
        wizard.exec_()

    def exportToExcel(self):
        """creates an excel file from the view"""
        widget = self.activeMdiChild()
        post(widget.export_to_excel)

    def exportToWord(self):
        """Use windows COM to export the active child window to MS word,
        by using its to_html function"""
        widget = self.activeMdiChild()
        post(widget.export_to_word)

    def exportToMail(self):
        widget = self.activeMdiChild()
        post(widget.export_to_mail)

    def importFromFile(self):
        self.activeMdiChild().importFromFile()

    def createMenus(self):

        self.file_menu = self.menuBar().addMenu(_('&File'))
        addActions(
            self.file_menu,
            (
                #self.closeAct,
                None,
                self.backupAct,
                self.restoreAct,
                None,
                self.pageSetupAct,
                self.previewAct,
                self.printAct,
                None))

        self.exportMenu = QtGui.QMenu(_('Export To'))
        addActions(self.exportMenu, (
            self.exportToExcelAct,
            self.exportToWordAct,
            self.exportToMailAct,
        ))
        self.file_menu.addMenu(self.exportMenu)

        self.importMenu = QtGui.QMenu(_('Import From'))
        addActions(self.importMenu, (self.importFromFileAct, ))
        self.file_menu.addMenu(self.importMenu)

        addActions(self.file_menu, (None, self.exitAct))

        self.editMenu = self.menuBar().addMenu(_('&Edit'))

        addActions(self.editMenu, (self.copyAct, self.selectAllAct,
                                   self.updateValueAct, self.mergeDocumentAct))

        self.viewMenu = self.menuBar().addMenu(_('View'))
        addActions(self.viewMenu, (self.sessionRefreshAct, ))
        gotoMenu = self.viewMenu.addMenu(_('Go To'))
        addActions(gotoMenu, (self.viewFirstAct, self.viewPreviousAct,
                              self.viewNextAct, self.viewLastAct))

        self.menuBar().addSeparator()

        self.helpMenu = self.menuBar().addMenu(_('&Help'))

        help_menu_actions = [self.helpAct, self.aboutAct]
        if self.app_admin.get_whats_new():
            help_menu_actions.append(self.whats_new_action)
        if self.app_admin.get_affiliated_url():
            help_menu_actions.append(self.affiliated_website_action)
        if self.app_admin.get_remote_support_url():
            help_menu_actions.append(self.remote_support_action)
        addActions(self.helpMenu, help_menu_actions)

    def updateMenus(self):
        """Toggle the status of the menus, depending on the active view"""
        active_view = (self.workspace.active_view() is not None)
        self.backupAct.setEnabled(True)
        self.restoreAct.setEnabled(True)

        self.pageSetupAct.setEnabled(active_view)
        self.previewAct.setEnabled(active_view)
        self.printAct.setEnabled(active_view)

        self.newAct.setEnabled(active_view)
        self.deleteAct.setEnabled(active_view)
        self.copyAct.setEnabled(active_view)
        self.viewFirstAct.setEnabled(active_view)
        self.viewPreviousAct.setEnabled(active_view)
        self.viewNextAct.setEnabled(active_view)
        self.viewLastAct.setEnabled(active_view)

        self.exportToWordAct.setEnabled(active_view)
        self.exportToExcelAct.setEnabled(active_view)
        self.exportToMailAct.setEnabled(active_view)

        self.importFromFileAct.setEnabled(active_view)

        self.separatorAct.setVisible(active_view)

    def get_tool_bar(self):
        return self.tool_bar

    def createToolBars(self):
        #
        # All actions are put in one toolbar, to ease unit testing and
        # generation of screenshots
        #
        self.tool_bar = self.addToolBar(_('Toolbar'))
        self.tool_bar.setObjectName('ToolBar')
        self.tool_bar.setMovable(False)
        self.tool_bar.setFloatable(False)
        addActions(
            self.tool_bar,
            (self.newAct, self.copyAct, self.deleteAct, self.viewFirstAct,
             self.viewPreviousAct, self.viewNextAct, self.viewLastAct))

        addActions(self.tool_bar, (
            self.exportToExcelAct,
            self.exportToWordAct,
            self.exportToMailAct,
        ))

        addActions(self.tool_bar, (self.printAct, self.previewAct))

        addActions(self.tool_bar, (self.helpAct, ))

        if self.app_actions:
            addActions(self.tool_bar, self.app_actions)

    # Navigation Pane
    def createNavigationPane(self):
        self.navpane = NavigationPane(self.app_admin,
                                      workspace=self.workspace,
                                      parent=self)
        self.addDockWidget(Qt.LeftDockWidgetArea, self.navpane)

    def activeMdiChild(self):
        return self.workspace.active_view()

    # Statusbar
    def createStatusBar(self):
        from controls.statusbar import StatusBar
        statusbar = StatusBar(self)
        self.setStatusBar(statusbar)
        statusbar.showMessage(_('Ready'), 5000)

#    # Events
#
#    def closeEvent(self, event):
#        self.workspace.closeAllSubWindows()
#        if self.activeMdiChild():
#            event.ignore()
#        else:
#            self.writeSettings()
#            event.accept()

    def closeEvent(self, event):
        self.workspace.close_all_views()
        self.writeSettings()
        event.accept()
Exemplo n.º 7
0
class MainWindow(QtGui.QMainWindow):
    """Main window of a Desktop Camelot application
    
    :param gui_context: an :class:`camelot.admin.action.application_action.ApplicationActionGuiContext`
        object
    :param parent: a :class:`QtGui.QWidget` object or :class:`None` 
    
    .. attribute:: splash_screen 
        a :class:`QtGui.QWidget` that needs to be closed when
        the main window is shown.
    """
    def __init__(self, gui_context, parent=None):
        from workspace import DesktopWorkspace
        logger.debug('initializing main window')
        QtGui.QMainWindow.__init__(self, parent)

        self.splash_screen = None
        self.toolbars = []
        self.nav_pane = None
        self.app_admin = gui_context.admin.get_application_admin()

        logger.debug('setting up workspace')
        self.workspace = DesktopWorkspace(self.app_admin, self)
        self.gui_context = gui_context
        self.gui_context.workspace = self.workspace

        logger.debug('setting child windows dictionary')

        logger.debug('setting central widget to our workspace')
        self.setCentralWidget(self.workspace)

        self.workspace.change_view_mode_signal.connect(self.change_view_mode)
        self.workspace.last_view_closed_signal.connect(self.unmaximize_view)
        self.workspace.view_activated_signal.connect(self.view_activated)

        logger.debug('creating navigation pane')
        post(self.app_admin.get_sections, self.set_sections)

        logger.debug('creating the menus')
        post(self.app_admin.get_main_menu, self.set_main_menu)

        logger.debug('creating the toolbars')
        post(self.app_admin.get_toolbar_actions,
             self.set_left_toolbar_actions,
             args=(Qt.LeftToolBarArea, ))
        post(self.app_admin.get_toolbar_actions,
             self.set_right_toolbar_actions,
             args=(Qt.RightToolBarArea, ))
        post(self.app_admin.get_toolbar_actions,
             self.set_top_toolbar_actions,
             args=(Qt.TopToolBarArea, ))
        post(self.app_admin.get_toolbar_actions,
             self.set_bottom_toolbar_actions,
             args=(Qt.BottomToolBarArea, ))
        post(self.app_admin.get_hidden_actions, self.set_hidden_actions)

        logger.debug('reading saved settings')
        self.read_settings()

        windowtitle = self.app_admin.get_name()
        logger.debug(u'setting up window title: %s' % windowtitle)
        self.setWindowTitle(windowtitle)
        self.app_admin.title_changed_signal.connect(self.setWindowTitle)

        logger.debug('initialization complete')

    @QtCore.pyqtSlot()
    def show(self):
        """This method wait until the main window is completely set up, and
        only then shows it.  This is a workaround for a bug in Qt on OS X
        
        https://bugreports.qt.nokia.com/browse/QTBUG-18567
        
        """
        post(lambda: None, self._delayed_show)

    @QtCore.pyqtSlot(object)
    def _delayed_show(self, _o):
        """Call to the underlying :meth:`QMainWindow.show`, to be used in
        :meth:`MainWindow.show`
        """
        super(MainWindow, self).show()
        if self.splash_screen:
            self.splash_screen.close()

    @QtCore.pyqtSlot()
    def unmaximize_view(self):
        """Show the navigation pane and the menu bar if they exist """
        if self.navpane:
            self.navpane.show()
        if self.menuBar():
            self.menuBar().show()

    @QtCore.pyqtSlot()
    def change_view_mode(self):
        """Switch between hidden or shown menubar and navigation pane"""
        if self.menuBar().isHidden():
            if self.navpane:
                self.navpane.show()
            self.menuBar().show()
        else:
            if self.navpane:
                self.navpane.hide()
            self.menuBar().hide()

    def read_settings(self):
        """Restore the geometry of the main window to its last saved state"""
        settings = QtCore.QSettings()
        self.restoreGeometry(settings.value('geometry').toByteArray())

    def write_settings(self):
        """Store the current geometry of the main window"""
        logger.debug('writing application settings')
        settings = QtCore.QSettings()
        settings.setValue('geometry', QtCore.QVariant(self.saveGeometry()))
        logger.debug('settings written')

    @QtCore.pyqtSlot(object)
    def set_main_menu(self, main_menu):
        """Set the main menu
        :param main_menu: a list of :class:`camelot.admin.menu.Menu` objects,
            as returned by the :meth:`camelot.admin.application_admin.ApplicationAdmin.get_main_menu`
            method.
        """
        from camelot.view.controls.action_widget import ActionAction
        if main_menu == None:
            return
        menu_bar = self.menuBar()
        for menu in main_menu:
            menu_bar.addMenu(menu.render(self.gui_context, menu_bar))
        for qaction in menu_bar.findChildren(ActionAction):
            qaction.triggered.connect(self.action_triggered)

    def get_gui_context(self):
        """Get the :class:`GuiContext` of the active view in the mainwindow,
        or the :class:`GuiContext` of the application.

        :return: a :class:`camelot.admin.action.base.GuiContext`
        """
        active_view = self.gui_context.workspace.active_view()
        if active_view:
            return active_view.gui_context
        return self.gui_context

    @QtCore.pyqtSlot(object, object)
    def set_toolbar_actions(self, toolbar_area, toolbar_actions):
        """Set the toolbar for a specific area
        :param toolbar_area: the area on which to put the toolbar, from
            :class:`Qt.LeftToolBarArea` through :class:`Qt.BottomToolBarArea`
        :param toolbar_actions: a list of :class:`camelot.admin.action..base.Action` objects,
            as returned by the :meth:`camelot.admin.application_admin.ApplicationAdmin.get_toolbar_actions`
            method.
        """
        from camelot.view.controls.action_widget import ActionAction
        if toolbar_actions != None:
            #
            # gather menu bar actions to prevent duplication of QActions
            #
            qactions = dict()
            menu_bar = self.menuBar()
            if menu_bar:
                for qaction in menu_bar.findChildren(ActionAction):
                    qactions[qaction.action] = qaction
            toolbar = QtGui.QToolBar(_('Toolbar'))
            self.addToolBar(toolbar_area, toolbar)
            toolbar.setObjectName('MainWindowToolBar_%i' % toolbar_area)
            toolbar.setMovable(False)
            toolbar.setFloatable(False)
            for action in toolbar_actions:
                qaction = qactions.get(action, None)
                if qaction == None:
                    qaction = action.render(self.gui_context, toolbar)
                    qaction.triggered.connect(self.action_triggered)
                toolbar.addAction(qaction)
            self.toolbars.append(toolbar)
            toolbar.addWidget(BusyWidget())

    @QtCore.pyqtSlot(object)
    def set_left_toolbar_actions(self, toolbar_actions):
        self.set_toolbar_actions(Qt.LeftToolBarArea, toolbar_actions)

    @QtCore.pyqtSlot(object)
    def set_right_toolbar_actions(self, toolbar_actions):
        self.set_toolbar_actions(Qt.RightToolBarArea, toolbar_actions)

    @QtCore.pyqtSlot(object)
    def set_top_toolbar_actions(self, toolbar_actions):
        self.set_toolbar_actions(Qt.TopToolBarArea, toolbar_actions)

    @QtCore.pyqtSlot(object)
    def set_bottom_toolbar_actions(self, toolbar_actions):
        self.set_toolbar_actions(Qt.BottomToolBarArea, toolbar_actions)

    @QtCore.pyqtSlot(object)
    def set_hidden_actions(self, hidden_actions):
        from camelot.view.controls.action_widget import ActionAction
        for action in hidden_actions:
            action_action = ActionAction(action, self.gui_context, self)
            action_action.triggered.connect(self.action_triggered)
            self.addAction(action_action)

    @QtCore.pyqtSlot()
    def view_activated(self):
        """Update the state of the actions when the active tab in the
        desktop widget has changed"""
        from camelot.view.controls.action_widget import ActionAction
        gui_context = self.get_gui_context()
        model_context = gui_context.create_model_context()
        for toolbar in self.toolbars:
            for qaction in toolbar.actions():
                if isinstance(qaction, ActionAction):
                    post(qaction.action.get_state,
                         qaction.set_state,
                         args=(model_context, ))
        menu_bar = self.menuBar()
        if menu_bar:
            for qaction in menu_bar.findChildren(ActionAction):
                post(qaction.action.get_state,
                     qaction.set_state,
                     args=(model_context, ))

    @QtCore.pyqtSlot(bool)
    def action_triggered(self, _checked=False):
        """Execute an action that was triggered somewhere in the main window,
        such as the toolbar or the main menu"""
        action_action = self.sender()
        gui_context = self.get_gui_context()
        action_action.action.gui_run(gui_context)

    @QtCore.pyqtSlot(object)
    def set_sections(self, sections):
        """Set the sections of the navigation pane
        :param main_menu: a list of :class:`camelot.admin.section.Section` objects,
            as returned by the :meth:`camelot.admin.application_admin.ApplicationAdmin.get_sections`
            method.
        """
        if sections != None:
            self.navpane = NavigationPane(self.app_admin,
                                          workspace=self.workspace,
                                          parent=self)
            self.addDockWidget(Qt.LeftDockWidgetArea, self.navpane)
        else:
            self.navpane = None

    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)
Exemplo n.º 8
0
class MainWindow(QtGui.QMainWindow):
    """Main window GUI"""

    def __init__(self, app_admin, parent=None):
        from workspace import DesktopWorkspace
        logger.debug('initializing main window')
        QtGui.QMainWindow.__init__(self, parent)

        self.app_admin = app_admin

        logger.debug('setting up workspace')
        self.workspace = DesktopWorkspace(self)

        logger.debug('setting child windows dictionary')

        logger.debug('setting central widget to our workspace')
        self.setCentralWidget(self.workspace)

        self.workspace.view_activated_signal.connect(self.updateMenus)
        self.workspace.change_view_mode_signal.connect( self.change_view_mode )
        self.workspace.last_view_closed_signal.connect( self.unmaximize_view )

        logger.debug('creating navigation pane')
        self.createNavigationPane()

        logger.debug('creating all the required actions')
        self.createActions()

        logger.debug('creating the menus')
        self.createMenus()

        logger.debug('creating the toolbars')
        self.createToolBars()

        logger.debug('creating status bar')
        self.createStatusBar()

        logger.debug('updating menus')
        self.updateMenus()

        logger.debug('reading saved settings')
        self.readSettings()

        logger.debug('setting up printer object')
        self.printer = Printer()
        
        windowtitle = self.app_admin.get_name()
        logger.debug('setting up window title: %s' % windowtitle)
        self.setWindowTitle(windowtitle)
        self.app_admin.title_changed_signal.connect( self.setWindowTitle )

        #QtCore.QTimer.singleShot(0, self.doInitialization)
        logger.debug('initialization complete')

    # Application settings

    def about(self):
        logger.debug('showing about message box')
        abtmsg = self.app_admin.get_about()
        QtGui.QMessageBox.about(self, _('About'), _(abtmsg))
        logger.debug('about message closed')

    def whats_new(self):
        widget = self.app_admin.get_whats_new()
        if widget:
            widget.exec_()

    def affiliated_website(self):
        from PyQt4.QtGui import QDesktopServices
        url = self.app_admin.get_affiliated_url()
        if url:
            QDesktopServices.openUrl(url)

    def remote_support(self):
        from PyQt4.QtGui import QDesktopServices
        url = self.app_admin.get_remote_support_url()
        if url:
            QDesktopServices.openUrl(url)

    @QtCore.pyqtSlot()
    def unmaximize_view(self):
        self.navpane.show()
        self.menuBar().show()

    @QtCore.pyqtSlot()
    def change_view_mode(self):
        if self.menuBar().isHidden():
            self.navpane.show()
            self.menuBar().show()
        else:
            self.navpane.hide()
            self.menuBar().hide()

    def readSettings(self):
        settings = QtCore.QSettings()
        self.restoreGeometry(settings.value('geometry').toByteArray())
        # Don't restore state, since it messes up the toolbar if stuff was
        # added
        # self.restoreState(settings.value('state').toByteArray())

    def writeSettings(self):
        logger.debug('writing application settings')
        settings = QtCore.QSettings()
        settings.setValue('geometry', QtCore.QVariant(self.saveGeometry()))
        #settings.setValue('state', QtCore.QVariant(self.saveState()))
        logger.debug('settings written')

    def display_exception_message_box(self, exc_info):
        from controls.exception import model_thread_exception_message_box
        model_thread_exception_message_box(exc_info)

    def runAction(self, name, callable):
        progress = QtGui.QProgressDialog(_('Please wait'), QtCore.QString(), 0, 0)
        progress.setWindowTitle(name)
        progress.show()
        post(
            callable,
            progress.close,
            exception=self.display_exception_message_box
        )

    def createActions(self):
        self.backupAct = ActionFactory.backup(self, self.backup)
        self.restoreAct = ActionFactory.restore(self, self.restore)
        self.pageSetupAct = ActionFactory.page_setup(self, self.pageSetup)
        self.printAct = ActionFactory.print_(self, self.printDoc)
        self.previewAct = ActionFactory.print_preview(self, self.previewDoc)
        self.exitAct= ActionFactory.exit(self, slot=self.close)
        self.copyAct = ActionFactory.copy(self, slot=self.copy)
        self.selectAllAct = ActionFactory.select_all(self, slot=self.select_all)
        self.separatorAct = QtGui.QAction(self)
        self.separatorAct.setSeparator(True)
        self.aboutAct = ActionFactory.about(self, slot=self.about)
        self.whats_new_action = ActionFactory.whats_new(self, slot=self.whats_new)
        self.affiliated_website_action = ActionFactory.affiliated_website(self, slot=self.affiliated_website)
        self.remote_support_action =ActionFactory.remote_support(self, slot=self.remote_support)
        self.helpAct = ActionFactory.help(self, slot=self.help)
        self.newAct = ActionFactory.new(self, slot=self.new)
        self.deleteAct = ActionFactory.delete(self, slot=self.delete)
        self.viewFirstAct = ActionFactory.view_first(self, self.viewFirst)
        self.viewLastAct = ActionFactory.view_last(self, self.viewLast)
        self.viewNextAct = ActionFactory.view_next(self, self.viewNext)
        self.viewPreviousAct = ActionFactory.view_previous(self, self.viewPrevious)
        self.viewFirstAct.setIconVisibleInMenu(False)
        self.viewLastAct.setIconVisibleInMenu(False)
        self.viewNextAct.setIconVisibleInMenu(False)
        self.viewPreviousAct.setIconVisibleInMenu(False)
        self.updateValueAct = ActionFactory.update_values(self, slot = self.updateValue)
        self.mergeDocumentAct = ActionFactory.merge_document(self, slot = self.merge_document)
        self.exportToExcelAct = ActionFactory.export_excel(self, slot=self.exportToExcel)
        self.exportToWordAct = ActionFactory.export_word(self, slot=self.exportToWord)
        self.exportToMailAct = ActionFactory.export_mail(self, slot=self.exportToMail)
        self.importFromFileAct = ActionFactory.import_file(self, slot=self.importFromFile)
        self.sessionRefreshAct = ActionFactory.refresh(self, slot=self.refresh_session)

        self.app_actions = []
        for action in self.app_admin.get_actions():

            def bind_action(parent, action):

                def slot(*args):
                    action.run(parent)

                return slot

            self.app_actions.append(
                ActionFactory.create_action(
                    parent=self,
                    text=unicode(action.get_verbose_name()),
                    slot=bind_action(self, action),
                    actionicon=action.get_icon(),
                    tip=unicode(action.get_verbose_name())
                )
            )

    # QAction slots and methods implementations

    def refresh_session(self):
        from elixir import session
        from camelot.core.orm import refresh_session
        refresh_session( session )

    def help(self):
        #
        # Import WebKit as late as possible, since it's the largest
        # part of the QT Library (15 meg on Ubuntu linux)
        #
        from PyQt4 import QtWebKit
        TOP_LEVEL = None
        self.view = QtWebKit.QWebView(TOP_LEVEL)
        #print self.app_admin.get_help_url()
        #print self.app_admin.get_help_base()
        #index_file = open(self.app_admin.get_help_url(),'r')
        #self.view.setHtml (index_file.read(), self.app_admin.get_help_base())
        self.view.load(self.app_admin.get_help_url())
        self.view.setWindowTitle(_('Help Browser'))
        self.view.setWindowIcon(self.helpAct.icon())
        self.view.show()

    def backup(self):
        self.app_admin.backup(self)

    def restore(self):
        self.app_admin.restore(self)

    def saveAs(self):
        pass

    def copy(self):
        self.activeMdiChild().copy_selected_rows()

    def select_all(self):
        self.activeMdiChild().select_all_rows()

    def printDoc(self):
        self.previewDoc()

    def previewDoc(self):
        active = self.activeMdiChild()
        from camelot.admin.form_action import PrintHtmlFormAction

        class PrintPreview(PrintHtmlFormAction):

            def html(self, entity_getter):
                return active.to_html()

        action = PrintPreview(_('Print Preview'))
        action.run(lambda:None)

    def new(self):
        self.activeMdiChild().newRow()

    def delete(self):
        self.activeMdiChild().deleteSelectedRows()

    def pageSetup(self):
        pass

    def viewFirst(self):
        """selects view's first row"""
        active = self.activeMdiChild()
        active.viewFirst()

    def viewLast(self):
        """selects view's last row"""
        active = self.activeMdiChild()
        active.viewLast()

    def viewNext(self):
        """selects view's next row"""
        active = self.activeMdiChild()
        active.viewNext()

    def viewPrevious(self):
        """selects view's previous row"""
        active = self.activeMdiChild()
        active.viewPrevious()

    def updateValue(self):
        from camelot.view.wizard.update_value import UpdateValueWizard

        admin = self.activeMdiChild().get_admin()
        selection_getter = self.activeMdiChild().get_selection
        wizard = UpdateValueWizard(admin=admin, selection_getter=selection_getter)
        wizard.exec_()

    def merge_document(self):
        """Run the merge document wizard on the selection in the current
        table view"""
        from camelot.view.wizard.merge_document import MergeDocumentWizard

        selection_getter = self.activeMdiChild().get_selection
        wizard = MergeDocumentWizard(selection_getter=selection_getter)
        wizard.exec_()

    def exportToExcel(self):
        """creates an excel file from the view"""
        widget = self.activeMdiChild()
        post(widget.export_to_excel)

    def exportToWord(self):
        """Use windows COM to export the active child window to MS word,
        by using its to_html function"""
        widget = self.activeMdiChild()
        post(widget.export_to_word)

    def exportToMail(self):
        widget = self.activeMdiChild()
        post(widget.export_to_mail)

    def importFromFile(self):
        self.activeMdiChild().importFromFile()

    def createMenus(self):

        self.file_menu = self.menuBar().addMenu(_('&File'))
        addActions(self.file_menu, (
            #self.closeAct,
            None,
            self.backupAct,
            self.restoreAct,
            None,
            self.pageSetupAct,
            self.previewAct,
            self.printAct,
            None
        ))

        self.exportMenu = QtGui.QMenu(_('Export To'))
        addActions(self.exportMenu, (
            self.exportToExcelAct,
            self.exportToWordAct,
            self.exportToMailAct,
        ))
        self.file_menu.addMenu(self.exportMenu)

        self.importMenu = QtGui.QMenu(_('Import From'))
        addActions(self.importMenu, (self.importFromFileAct,))
        self.file_menu.addMenu(self.importMenu)

        addActions(self.file_menu, (None, self.exitAct))

        self.editMenu = self.menuBar().addMenu(_('&Edit'))

        addActions(self.editMenu, (self.copyAct,
                                   self.selectAllAct,
                                   self.updateValueAct,
                                   self.mergeDocumentAct))

        self.viewMenu = self.menuBar().addMenu(_('View'))
        addActions(self.viewMenu, (self.sessionRefreshAct,))
        gotoMenu = self.viewMenu.addMenu(_('Go To'))
        addActions(gotoMenu, (
            self.viewFirstAct,
            self.viewPreviousAct,
            self.viewNextAct,
            self.viewLastAct
        ))

        self.menuBar().addSeparator()

        self.helpMenu = self.menuBar().addMenu(_('&Help'))

        help_menu_actions = [self.helpAct, self.aboutAct]
        if self.app_admin.get_whats_new():
            help_menu_actions.append(self.whats_new_action)
        if self.app_admin.get_affiliated_url():
            help_menu_actions.append(self.affiliated_website_action)
        if self.app_admin.get_remote_support_url():
            help_menu_actions.append(self.remote_support_action)
        addActions(self.helpMenu, help_menu_actions )

    def updateMenus(self):
        """Toggle the status of the menus, depending on the active view"""
        active_view = (self.workspace.active_view() is not None)
        self.backupAct.setEnabled(True)
        self.restoreAct.setEnabled(True)

        self.pageSetupAct.setEnabled(active_view)
        self.previewAct.setEnabled(active_view)
        self.printAct.setEnabled(active_view)

        self.newAct.setEnabled(active_view)
        self.deleteAct.setEnabled(active_view)
        self.copyAct.setEnabled(active_view)
        self.viewFirstAct.setEnabled(active_view)
        self.viewPreviousAct.setEnabled(active_view)
        self.viewNextAct.setEnabled(active_view)
        self.viewLastAct.setEnabled(active_view)

        self.exportToWordAct.setEnabled(active_view)
        self.exportToExcelAct.setEnabled(active_view)
        self.exportToMailAct.setEnabled(active_view)

        self.importFromFileAct.setEnabled(active_view)

        self.separatorAct.setVisible(active_view)

    def get_tool_bar(self):
        return self.tool_bar

    def createToolBars(self):
        #
        # All actions are put in one toolbar, to ease unit testing and
        # generation of screenshots
        #
        self.tool_bar = self.addToolBar(_('Toolbar'))
        self.tool_bar.setObjectName('ToolBar')
        self.tool_bar.setMovable(False)
        self.tool_bar.setFloatable(False)
        addActions(self.tool_bar, (
            self.newAct,
            self.copyAct,
            self.deleteAct,
            self.viewFirstAct,
            self.viewPreviousAct,
            self.viewNextAct,
            self.viewLastAct
        ))

        addActions(self.tool_bar, (
            self.exportToExcelAct,
            self.exportToWordAct,
            self.exportToMailAct,
        ))

        addActions(self.tool_bar, (self.printAct, self.previewAct))

        addActions(self.tool_bar, (self.helpAct,))

        if self.app_actions:
            addActions(self.tool_bar, self.app_actions)

    # Navigation Pane
    def createNavigationPane(self):
        self.navpane = NavigationPane(
            self.app_admin,
            workspace=self.workspace,
            parent=self
        )
        self.addDockWidget(Qt.LeftDockWidgetArea, self.navpane)

    def activeMdiChild(self):
        return self.workspace.active_view()

    # Statusbar
    def createStatusBar(self):
        from controls.statusbar import StatusBar
        statusbar = StatusBar(self)
        self.setStatusBar(statusbar)
        statusbar.showMessage(_('Ready'), 5000)

#    # Events
#
#    def closeEvent(self, event):
#        self.workspace.closeAllSubWindows()
#        if self.activeMdiChild():
#            event.ignore()
#        else:
#            self.writeSettings()
#            event.accept()

    def closeEvent(self, event):
        self.workspace.close_all_views()
        self.writeSettings()
        event.accept()