diff --git a/openlp/core/__init__.py b/openlp/core/__init__.py index d1112ab5c..9b5eef8a2 100644 --- a/openlp/core/__init__.py +++ b/openlp/core/__init__.py @@ -136,6 +136,8 @@ class OpenLP(QtGui.QApplication): self.processEvents() # start the main app window self.main_window = MainWindow() + Registry().execute(u'bootstrap_initialise') + Registry().execute(u'bootstrap_post_set_up') self.main_window.show() if show_splash: # now kill the splashscreen diff --git a/openlp/core/lib/pluginmanager.py b/openlp/core/lib/pluginmanager.py index 43410b4a7..e918d743a 100644 --- a/openlp/core/lib/pluginmanager.py +++ b/openlp/core/lib/pluginmanager.py @@ -54,11 +54,37 @@ class PluginManager(object): """ log.info(u'Plugin manager Initialising') Registry().register(u'plugin_manager', self) + Registry().register_function(u'bootstrap_initialise', self.bootstrap_initialise) self.base_path = os.path.abspath(AppLocation.get_directory(AppLocation.PluginsDir)) log.debug(u'Base path %s ', self.base_path) self.plugins = [] log.info(u'Plugin manager Initialised') + def bootstrap_initialise(self): + """ + Bootstrap all the plugin manager functions + """ + log.info(u'bootstrap_initialise') + self.find_plugins() + # hook methods have to happen after find_plugins. Find plugins needs + # the controllers hence the hooks have moved from setupUI() to here + # Find and insert settings tabs + log.info(u'hook settings') + self.hook_settings_tabs() + # Find and insert media manager items + log.info(u'hook media') + self.hook_media_manager() + # Call the hook method to pull in import menus. + log.info(u'hook menus') + self.hook_import_menu() + # Call the hook method to pull in export menus. + self.hook_export_menu() + # Call the hook method to pull in tools menus. + self.hook_tools_menu() + # Call the initialise method to setup plugins. + log.info(u'initialise plugins') + self.initialise_plugins() + def find_plugins(self): """ Scan a directory for objects inheriting from the ``Plugin`` class. @@ -118,56 +144,44 @@ class PluginManager(object): if plugin.status is not PluginStatus.Disabled: plugin.createMediaManagerItem() - def hook_settings_tabs(self, settings_form=None): + def hook_settings_tabs(self): """ Loop through all the plugins. If a plugin has a valid settings tab item, add it to the settings tab. Tabs are set for all plugins not just Active ones - ``settings_form`` - Defaults to *None*. The settings form to add tabs to. """ for plugin in self.plugins: if plugin.status is not PluginStatus.Disabled: - plugin.createSettingsTab(settings_form) - if settings_form: - settings_form.plugins = self.plugins + plugin.createSettingsTab(self.settings_form) - def hook_import_menu(self, import_menu): + def hook_import_menu(self): """ Loop through all the plugins and give them an opportunity to add an item to the import menu. - ``import_menu`` - The Import menu. """ for plugin in self.plugins: if plugin.status is not PluginStatus.Disabled: - plugin.addImportMenuItem(import_menu) + plugin.addImportMenuItem(self.main_window.file_import_menu) - def hook_export_menu(self, export_menu): + def hook_export_menu(self): """ Loop through all the plugins and give them an opportunity to add an item to the export menu. - - ``export_menu`` - The Export menu. """ for plugin in self.plugins: if plugin.status is not PluginStatus.Disabled: - plugin.addExportMenuItem(export_menu) + plugin.addExportMenuItem(self.main_window.file_export_menu) - def hook_tools_menu(self, tools_menu): + def hook_tools_menu(self): """ Loop through all the plugins and give them an opportunity to add an item to the tools menu. - - ``tools_menu`` - The Tools menu. """ for plugin in self.plugins: if plugin.status is not PluginStatus.Disabled: - plugin.addToolsMenuItem(tools_menu) + plugin.addToolsMenuItem(self.main_window.tools_menu) def initialise_plugins(self): """ @@ -211,3 +225,23 @@ class PluginManager(object): if plugin.isActive(): plugin.new_service_created() + def _get_settings_form(self): + """ + Adds the plugin manager to the class dynamically + """ + if not hasattr(self, u'_settings_form'): + self._settings_form = Registry().get(u'settings_form') + return self._settings_form + + settings_form = property(_get_settings_form) + + def _get_main_window(self): + """ + Adds the main window to the class dynamically + """ + if not hasattr(self, u'_main_window'): + self._main_window = Registry().get(u'main_window') + return self._main_window + + main_window = property(_get_main_window) + diff --git a/openlp/core/lib/renderer.py b/openlp/core/lib/renderer.py index c8066ddaa..076874e18 100644 --- a/openlp/core/lib/renderer.py +++ b/openlp/core/lib/renderer.py @@ -662,4 +662,3 @@ class Renderer(object): return self._theme_manager theme_manager = property(_get_theme_manager) - diff --git a/openlp/core/lib/settingstab.py b/openlp/core/lib/settingstab.py index f8839ce64..5b8a01fc6 100644 --- a/openlp/core/lib/settingstab.py +++ b/openlp/core/lib/settingstab.py @@ -123,7 +123,7 @@ class SettingsTab(QtGui.QWidget): """ self.load() - def postSetUp(self, postUpdate=False): + def post_set_up(self, postUpdate=False): """ Changes which need to be made after setup of application diff --git a/openlp/core/ui/generaltab.py b/openlp/core/ui/generaltab.py index a20206f9b..90e7da702 100644 --- a/openlp/core/ui/generaltab.py +++ b/openlp/core/ui/generaltab.py @@ -308,9 +308,9 @@ class GeneralTab(SettingsTab): settings.setValue(u'audio repeat list', self.repeatListCheckBox.isChecked()) settings.endGroup() # On save update the screens as well - self.postSetUp(True) + self.post_set_up(True) - def postSetUp(self, postUpdate=False): + def post_set_up(self, postUpdate=False): """ Apply settings after settings tab has loaded and most of the system so must be delayed diff --git a/openlp/core/ui/mainwindow.py b/openlp/core/ui/mainwindow.py index 1a9f00350..96f8efe18 100644 --- a/openlp/core/ui/mainwindow.py +++ b/openlp/core/ui/mainwindow.py @@ -105,13 +105,13 @@ class Ui_MainWindow(object): self.controlSplitter.setObjectName(u'controlSplitter') self.mainContentLayout.addWidget(self.controlSplitter) # Create slide controllers - self.previewController = SlideController(self) - self.liveController = SlideController(self, True) + self.preview_controller = SlideController(self) + self.live_controller = SlideController(self, True) previewVisible = Settings().value(u'user interface/preview panel') - self.previewController.panel.setVisible(previewVisible) + self.preview_controller.panel.setVisible(previewVisible) liveVisible = Settings().value(u'user interface/live panel') panelLocked = Settings().value(u'user interface/lock panel') - self.liveController.panel.setVisible(liveVisible) + self.live_controller.panel.setVisible(liveVisible) # Create menu self.menuBar = QtGui.QMenuBar(main_window) self.menuBar.setObjectName(u'menuBar') @@ -119,18 +119,18 @@ class Ui_MainWindow(object): self.fileMenu.setObjectName(u'fileMenu') self.recentFilesMenu = QtGui.QMenu(self.fileMenu) self.recentFilesMenu.setObjectName(u'recentFilesMenu') - self.fileImportMenu = QtGui.QMenu(self.fileMenu) - self.fileImportMenu.setObjectName(u'fileImportMenu') - self.fileExportMenu = QtGui.QMenu(self.fileMenu) - self.fileExportMenu.setObjectName(u'fileExportMenu') + self.file_import_menu = QtGui.QMenu(self.fileMenu) + self.file_import_menu.setObjectName(u'file_import_menu') + self.file_export_menu = QtGui.QMenu(self.fileMenu) + self.file_export_menu.setObjectName(u'file_export_menu') # View Menu self.viewMenu = QtGui.QMenu(self.menuBar) self.viewMenu.setObjectName(u'viewMenu') self.viewModeMenu = QtGui.QMenu(self.viewMenu) self.viewModeMenu.setObjectName(u'viewModeMenu') # Tools Menu - self.toolsMenu = QtGui.QMenu(self.menuBar) - self.toolsMenu.setObjectName(u'toolsMenu') + self.tools_menu = QtGui.QMenu(self.menuBar) + self.tools_menu.setObjectName(u'tools_menu') # Settings Menu self.settingsMenu = QtGui.QMenu(self.menuBar) self.settingsMenu.setObjectName(u'settingsMenu') @@ -308,11 +308,13 @@ class Ui_MainWindow(object): can_shortcuts=True, category=UiStrings().Help, triggers=self.onOnlineHelpClicked) self.webSiteItem = create_action(main_window, u'webSiteItem', can_shortcuts=True, category=UiStrings().Help) - add_actions(self.fileImportMenu, (self.settingsImportItem, None, self.importThemeItem, self.importLanguageItem)) - add_actions(self.fileExportMenu, (self.settingsExportItem, None, self.exportThemeItem, self.exportLanguageItem)) + add_actions(self.file_import_menu, (self.settingsImportItem, None, self.importThemeItem, + self.importLanguageItem)) + add_actions(self.file_export_menu, (self.settingsExportItem, None, self.exportThemeItem, + self.exportLanguageItem)) add_actions(self.fileMenu, (self.fileNewItem, self.fileOpenItem, self.fileSaveItem, self.fileSaveAsItem, self.recentFilesMenu.menuAction(), None, - self.fileImportMenu.menuAction(), self.fileExportMenu.menuAction(), None, self.printServiceOrderItem, + self.file_import_menu.menuAction(), self.file_export_menu.menuAction(), None, self.printServiceOrderItem, self.fileExitItem)) add_actions(self.viewModeMenu, (self.modeDefaultItem, self.modeSetupItem, self.modeLiveItem)) add_actions(self.viewMenu, (self.viewModeMenu.menuAction(), None, self.viewMediaManagerItem, @@ -329,16 +331,16 @@ class Ui_MainWindow(object): else: add_actions(self.settingsMenu, (self.settingsPluginListItem, self.settingsLanguageMenu.menuAction(), None, self.formattingTagItem, self.settingsShortcutsItem, self.settingsConfigureItem)) - add_actions(self.toolsMenu, (self.toolsAddToolItem, None)) - add_actions(self.toolsMenu, (self.toolsOpenDataFolder, None)) - add_actions(self.toolsMenu, (self.toolsFirstTimeWizard, None)) - add_actions(self.toolsMenu, [self.updateThemeImages]) + add_actions(self.tools_menu, (self.toolsAddToolItem, None)) + add_actions(self.tools_menu, (self.toolsOpenDataFolder, None)) + add_actions(self.tools_menu, (self.toolsFirstTimeWizard, None)) + add_actions(self.tools_menu, [self.updateThemeImages]) if os.name == u'nt': add_actions(self.helpMenu, (self.offlineHelpItem, self.onlineHelpItem, None, self.webSiteItem, self.aboutItem)) else: add_actions(self.helpMenu, (self.onlineHelpItem, None, self.webSiteItem, self.aboutItem)) - add_actions(self.menuBar, (self.fileMenu.menuAction(), self.viewMenu.menuAction(), self.toolsMenu.menuAction(), + add_actions(self.menuBar, (self.fileMenu.menuAction(), self.viewMenu.menuAction(), self.tools_menu.menuAction(), self.settingsMenu.menuAction(), self.helpMenu.menuAction())) # Initialise the translation self.retranslateUi(main_window) @@ -359,12 +361,12 @@ class Ui_MainWindow(object): mainWindow.mainTitle = UiStrings().OLPV2x mainWindow.setWindowTitle(mainWindow.mainTitle) self.fileMenu.setTitle(translate('OpenLP.MainWindow', '&File')) - self.fileImportMenu.setTitle(translate('OpenLP.MainWindow', '&Import')) - self.fileExportMenu.setTitle(translate('OpenLP.MainWindow', '&Export')) + self.file_import_menu.setTitle(translate('OpenLP.MainWindow', '&Import')) + self.file_export_menu.setTitle(translate('OpenLP.MainWindow', '&Export')) self.recentFilesMenu.setTitle(translate('OpenLP.MainWindow', '&Recent Files')) self.viewMenu.setTitle(translate('OpenLP.MainWindow', '&View')) self.viewModeMenu.setTitle(translate('OpenLP.MainWindow', 'M&ode')) - self.toolsMenu.setTitle(translate('OpenLP.MainWindow', '&Tools')) + self.tools_menu.setTitle(translate('OpenLP.MainWindow', '&Tools')) self.settingsMenu.setTitle(translate('OpenLP.MainWindow', '&Settings')) self.settingsLanguageMenu.setTitle(translate('OpenLP.MainWindow', '&Language')) self.helpMenu.setTitle(translate('OpenLP.MainWindow', '&Help')) @@ -478,102 +480,70 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): self.playersSettingsSection = u'players' self.displayTagsSection = u'displayTags' self.headerSection = u'SettingsImport' + self.recentFiles = [] + self.timer_id = 0 + self.timer_version_id = 0 + self.new_data_path = None + self.copy_data = False Settings().set_up_default_values() Settings().remove_obsolete_settings() self.serviceNotSaved = False self.aboutForm = AboutForm(self) - self.mediaController = MediaController() + self.media_controller = MediaController() self.settingsForm = SettingsForm(self) self.formattingTagForm = FormattingTagForm(self) self.shortcutForm = ShortcutListForm(self) - self.recentFiles = [] - self.timer_id = 0 - self.timer_version_id = 0 # Set up the path with plugins self.plugin_manager = PluginManager() - self.imageManager = ImageManager() + self.image_manager = ImageManager() # Set up the interface self.setupUi(self) - # Register the active media players and suffixes - self.mediaController.check_available_media_players() + # Define the media Dock Manager + self.mediaDockManager = MediaDockManager(self.mediaToolBox) # Load settings after setupUi so default UI sizes are overwritten self.loadSettings() # Once settings are loaded update the menu with the recent files. self.updateRecentFilesMenu() self.pluginForm = PluginForm(self) - self.new_data_path = None - self.copy_data = False # Set up signals and slots - QtCore.QObject.connect(self.importThemeItem, QtCore.SIGNAL(u'triggered()'), - self.themeManagerContents.on_import_theme) - QtCore.QObject.connect(self.exportThemeItem, QtCore.SIGNAL(u'triggered()'), - self.themeManagerContents.on_export_theme) QtCore.QObject.connect(self.mediaManagerDock, QtCore.SIGNAL(u'visibilityChanged(bool)'), - self.viewMediaManagerItem.setChecked) + self.viewMediaManagerItem.setChecked) QtCore.QObject.connect(self.serviceManagerDock, QtCore.SIGNAL(u'visibilityChanged(bool)'), - self.viewServiceManagerItem.setChecked) + self.viewServiceManagerItem.setChecked) QtCore.QObject.connect(self.themeManagerDock, QtCore.SIGNAL(u'visibilityChanged(bool)'), - self.viewThemeManagerItem.setChecked) - QtCore.QObject.connect(self.webSiteItem, QtCore.SIGNAL(u'triggered()'), self.onHelpWebSiteClicked) - QtCore.QObject.connect(self.toolsOpenDataFolder, QtCore.SIGNAL(u'triggered()'), - self.onToolsOpenDataFolderClicked) - QtCore.QObject.connect(self.toolsFirstTimeWizard, QtCore.SIGNAL(u'triggered()'), self.onFirstTimeWizardClicked) - QtCore.QObject.connect(self.updateThemeImages, QtCore.SIGNAL(u'triggered()'), self.onUpdateThemeImages) - QtCore.QObject.connect(self.formattingTagItem, QtCore.SIGNAL(u'triggered()'), self.onFormattingTagItemClicked) - QtCore.QObject.connect(self.settingsConfigureItem, QtCore.SIGNAL(u'triggered()'), - self.onSettingsConfigureItemClicked) - QtCore.QObject.connect(self.settingsShortcutsItem, QtCore.SIGNAL(u'triggered()'), - self.onSettingsShortcutsItemClicked) - QtCore.QObject.connect(self.settingsImportItem, QtCore.SIGNAL(u'triggered()'), - self.onSettingsImportItemClicked) - QtCore.QObject.connect(self.settingsExportItem, QtCore.SIGNAL(u'triggered()'), self.onSettingsExportItemClicked) + self.viewThemeManagerItem.setChecked) + self.importThemeItem.triggered.connect(self.themeManagerContents.on_import_theme) + self.exportThemeItem.triggered.connect(self.themeManagerContents.on_export_theme) + self.webSiteItem.triggered.connect(self.onHelpWebSiteClicked) + self.toolsOpenDataFolder.triggered.connect(self.onToolsOpenDataFolderClicked) + self.toolsFirstTimeWizard.triggered.connect(self.onFirstTimeWizardClicked) + self.updateThemeImages.triggered.connect(self.onUpdateThemeImages) + self.formattingTagItem.triggered.connect(self.onFormattingTagItemClicked) + self.settingsConfigureItem.triggered.connect(self.onSettingsConfigureItemClicked) + self.settingsShortcutsItem.triggered.connect(self.onSettingsShortcutsItemClicked) + self.settingsImportItem.triggered.connect(self.onSettingsImportItemClicked) + self.settingsExportItem.triggered.connect(self.onSettingsExportItemClicked) # i18n set signals for languages self.languageGroup.triggered.connect(LanguageManager.set_language) - QtCore.QObject.connect(self.modeDefaultItem, QtCore.SIGNAL(u'triggered()'), self.onModeDefaultItemClicked) - QtCore.QObject.connect(self.modeSetupItem, QtCore.SIGNAL(u'triggered()'), self.onModeSetupItemClicked) - QtCore.QObject.connect(self.modeLiveItem, QtCore.SIGNAL(u'triggered()'), self.onModeLiveItemClicked) + self.modeDefaultItem.triggered.connect(self.onModeDefaultItemClicked) + self.modeSetupItem.triggered.connect(self.onModeSetupItemClicked) + self.modeLiveItem.triggered.connect(self.onModeLiveItemClicked) # Media Manager - QtCore.QObject.connect(self.mediaToolBox, QtCore.SIGNAL(u'currentChanged(int)'), self.onMediaToolBoxChanged) + self.mediaToolBox.currentChanged.connect(self.onMediaToolBoxChanged) self.application.set_busy_cursor() # Simple message boxes Registry().register_function(u'theme_update_global', self.default_theme_changed) Registry().register_function(u'openlp_version_check', self.version_notice) Registry().register_function(u'config_screen_changed', self.screen_changed) self.renderer = Renderer() - # Define the media Dock Manager - self.mediaDockManager = MediaDockManager(self.mediaToolBox) - log.info(u'Load Plugins') - self.plugin_manager.find_plugins() - # hook methods have to happen after find_plugins. Find plugins needs - # the controllers hence the hooks have moved from setupUI() to here - # Find and insert settings tabs - log.info(u'hook settings') - self.plugin_manager.hook_settings_tabs(self.settingsForm) - # Find and insert media manager items - log.info(u'hook media') - self.plugin_manager.hook_media_manager() - # Call the hook method to pull in import menus. - log.info(u'hook menus') - self.plugin_manager.hook_import_menu(self.fileImportMenu) - # Call the hook method to pull in export menus. - self.plugin_manager.hook_export_menu(self.fileExportMenu) - # Call the hook method to pull in tools menus. - self.plugin_manager.hook_tools_menu(self.toolsMenu) - # Call the initialise method to setup plugins. - log.info(u'initialise plugins') - self.plugin_manager.initialise_plugins() # Create the displays as all necessary components are loaded. - self.previewController.screenSizeChanged() - self.liveController.screenSizeChanged() + self.preview_controller.screenSizeChanged() + self.live_controller.screenSizeChanged() log.info(u'Load data from Settings') if Settings().value(u'advanced/save current plugin'): savedPlugin = Settings().value(u'advanced/current media plugin') if savedPlugin != -1: self.mediaToolBox.setCurrentIndex(savedPlugin) - self.settingsForm.postSetUp() - # Once all components are initialised load the Themes - log.info(u'Load Themes') - self.themeManagerContents.load_themes(True) # Reset the cursor self.application.set_normal_cursor() @@ -608,8 +578,8 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): Show the main form, as well as the display form """ QtGui.QWidget.show(self) - if self.liveController.display.isVisible(): - self.liveController.display.setFocus() + if self.live_controller.display.isVisible(): + self.live_controller.display.setFocus() self.activateWindow() if self.arguments: args = [] @@ -702,7 +672,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): Check and display message if screen blank on setup. """ settings = Settings() - self.liveController.mainDisplaySetBackground() + self.live_controller.mainDisplaySetBackground() if settings.value(u'%s/screen blank' % self.generalSettingsSection): if settings.value(u'%s/blank warning' % self.generalSettingsSection): QtGui.QMessageBox.question(self, translate('OpenLP.MainWindow', 'OpenLP Main Display Blanked'), @@ -809,8 +779,8 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): """ We need to make sure, that the SlidePreview's size is correct. """ - self.previewController.previewSizeChanged() - self.liveController.previewSizeChanged() + self.preview_controller.previewSizeChanged() + self.live_controller.previewSizeChanged() def onSettingsShortcutsItemClicked(self): """ @@ -1018,10 +988,10 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): """ log.debug(u'screen_changed') self.application.set_busy_cursor() - self.imageManager.update_display() + self.image_manager.update_display() self.renderer.update_display() - self.previewController.screenSizeChanged() - self.liveController.screenSizeChanged() + self.preview_controller.screenSizeChanged() + self.live_controller.screenSizeChanged() self.setFocus() self.activateWindow() self.application.set_normal_cursor() @@ -1074,8 +1044,8 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): ``save_settings`` Switch to prevent saving settings. Defaults to **True**. """ - self.imageManager.stop_manager = True - while self.imageManager.image_thread.isRunning(): + self.image_manager.stop_manager = True + while self.image_manager.image_thread.isRunning(): time.sleep(0.1) # Clean temporary files used by services self.serviceManagerContents.clean_up() @@ -1092,9 +1062,9 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): if self.new_data_path: self.changeDataDirectory() # Close down the display - if self.liveController.display: - self.liveController.display.close() - self.liveController.display = None + if self.live_controller.display: + self.live_controller.display.close() + self.live_controller.display = None def serviceChanged(self, reset=False, serviceName=None): """ @@ -1175,7 +1145,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): True - Visible False - Hidden """ - self.previewController.panel.setVisible(visible) + self.preview_controller.panel.setVisible(visible) Settings().setValue(u'user interface/preview panel', visible) self.viewPreviewPanel.setChecked(visible) @@ -1213,7 +1183,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): True - Visible False - Hidden """ - self.liveController.panel.setVisible(visible) + self.live_controller.panel.setVisible(visible) Settings().setValue(u'user interface/live panel', visible) self.viewLivePanel.setChecked(visible) @@ -1233,8 +1203,8 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): self.move(settings.value(u'main window position')) self.restoreGeometry(settings.value(u'main window geometry')) self.restoreState(settings.value(u'main window state')) - self.liveController.splitter.restoreState(settings.value(u'live splitter geometry')) - self.previewController.splitter.restoreState(settings.value(u'preview splitter geometry')) + self.live_controller.splitter.restoreState(settings.value(u'live splitter geometry')) + self.preview_controller.splitter.restoreState(settings.value(u'preview splitter geometry')) self.controlSplitter.restoreState(settings.value(u'main window splitter geometry')) settings.endGroup() @@ -1254,8 +1224,8 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): settings.setValue(u'main window position', self.pos()) settings.setValue(u'main window state', self.saveState()) settings.setValue(u'main window geometry', self.saveGeometry()) - settings.setValue(u'live splitter geometry', self.liveController.splitter.saveState()) - settings.setValue(u'preview splitter geometry', self.previewController.splitter.saveState()) + settings.setValue(u'live splitter geometry', self.live_controller.splitter.saveState()) + settings.setValue(u'preview splitter geometry', self.preview_controller.splitter.saveState()) settings.setValue(u'main window splitter geometry', self.controlSplitter.saveState()) settings.endGroup() diff --git a/openlp/core/ui/media/mediacontroller.py b/openlp/core/ui/media/mediacontroller.py index e9a963553..09ad73b8f 100644 --- a/openlp/core/ui/media/mediacontroller.py +++ b/openlp/core/ui/media/mediacontroller.py @@ -98,6 +98,7 @@ class MediaController(object): Constructor """ Registry().register(u'media_controller', self) + Registry().register_function(u'bootstrap_initialise', self.check_available_media_players) self.mediaPlayers = {} self.displayControllers = {} self.currentMediaPlayer = {} @@ -161,10 +162,9 @@ class MediaController(object): """ Check to see if we have any media Player's available. """ + print "check" log.debug(u'_check_available_media_players') - controller_dir = os.path.join( - AppLocation.get_directory(AppLocation.AppDir), - u'core', u'ui', u'media') + controller_dir = os.path.join(AppLocation.get_directory(AppLocation.AppDir), u'core', u'ui', u'media') for filename in os.listdir(controller_dir): if filename.endswith(u'player.py') and not filename == 'mediaplayer.py': path = os.path.join(controller_dir, filename) @@ -397,7 +397,7 @@ class MediaController(object): else: controller.media_info.start_time = serviceItem.start_time controller.media_info.end_time = serviceItem.end_time - elif controller.previewDisplay: + elif controller.preview_display: isValid = self._check_file_type(controller, display, serviceItem) if not isValid: # Media could not be loaded correctly @@ -441,7 +441,7 @@ class MediaController(object): controller.media_info = MediaInfo() controller.media_info.volume = 0 controller.media_info.file_info = QtCore.QFileInfo(serviceItem.get_frame_path()) - display = controller.previewDisplay + display = controller._display if not self._check_file_type(controller, display, serviceItem): # Media could not be loaded correctly critical_error_message_box(translate('MediaPlugin.MediaItem', 'Unsupported File'), diff --git a/openlp/core/ui/media/playertab.py b/openlp/core/ui/media/playertab.py index d8b896864..920aef376 100644 --- a/openlp/core/ui/media/playertab.py +++ b/openlp/core/ui/media/playertab.py @@ -232,7 +232,7 @@ class PlayerTab(SettingsTab): Registry().execute(u'mediaitem_media_rebuild') Registry().execute(u'config_screen_changed') - def postSetUp(self, postUpdate=False): + def post_set_up(self): """ Late setup for players as the MediaController has to be initialised first. diff --git a/openlp/core/ui/settingsform.py b/openlp/core/ui/settingsform.py index 1b000f16b..166f7908a 100644 --- a/openlp/core/ui/settingsform.py +++ b/openlp/core/ui/settingsform.py @@ -50,6 +50,7 @@ class SettingsForm(QtGui.QDialog, Ui_SettingsDialog): Initialise the settings form """ Registry().register(u'settings_form', self) + Registry().register_function(u'bootstrap_post_set_up', self.post_set_up) QtGui.QDialog.__init__(self, parent) self.setupUi(self) # General tab @@ -75,7 +76,7 @@ class SettingsForm(QtGui.QDialog, Ui_SettingsDialog): self.insertTab(self.advancedTab, 2, PluginStatus.Active) self.insertTab(self.playerTab, 3, PluginStatus.Active) count = 4 - for plugin in self.plugins: + for plugin in self.plugin_manager.plugins: if plugin.settingsTab: self.insertTab(plugin.settingsTab, count, plugin.status) count += 1 @@ -118,17 +119,17 @@ class SettingsForm(QtGui.QDialog, Ui_SettingsDialog): self.stackedLayout.widget(tabIndex).cancel() return QtGui.QDialog.reject(self) - def postSetUp(self): + def post_set_up(self): """ Run any post-setup code for the tabs on the form """ - self.generalTab.postSetUp() - self.themesTab.postSetUp() - self.advancedTab.postSetUp() - self.playerTab.postSetUp() - for plugin in self.plugins: + self.generalTab.post_set_up() + self.themesTab.post_set_up() + self.advancedTab.post_set_up() + self.playerTab.post_set_up() + for plugin in self.plugin_manager.plugins: if plugin.settingsTab: - plugin.settingsTab.postSetUp() + plugin.settingsTab.post_set_up() def tabChanged(self, tabIndex): """ @@ -166,3 +167,13 @@ class SettingsForm(QtGui.QDialog, Ui_SettingsDialog): return self._service_manager service_manager = property(_get_service_manager) + + def _get_plugin_manager(self): + """ + Adds the plugin manager to the class dynamically + """ + if not hasattr(self, u'_plugin_manager'): + self._plugin_manager = Registry().get(u'plugin_manager') + return self._plugin_manager + + plugin_manager = property(_get_plugin_manager) diff --git a/openlp/core/ui/thememanager.py b/openlp/core/ui/thememanager.py index f172f8fe2..3f14f9921 100644 --- a/openlp/core/ui/thememanager.py +++ b/openlp/core/ui/thememanager.py @@ -59,6 +59,7 @@ class ThemeManager(QtGui.QWidget): """ QtGui.QWidget.__init__(self, parent) Registry().register(u'theme_manager', self) + Registry().register_function(u'bootstrap_initialise', self.load_first_time_themes) self.settingsSection = u'themes' self.themeForm = ThemeForm(self) self.fileRenameForm = FileRenameForm() @@ -144,18 +145,6 @@ class ThemeManager(QtGui.QWidget): # Last little bits of setting up self.config_updated() - def first_time(self): - """ - Import new themes downloaded by the first time wizard - """ - self.application.set_busy_cursor() - files = AppLocation.get_files(self.settingsSection, u'.otz') - for theme_file in files: - theme_file = os.path.join(self.path, theme_file) - self.unzip_theme(theme_file, self.path) - delete_file(theme_file) - self.application.set_normal_cursor() - def config_updated(self): """ Triggered when Config dialog is updated. @@ -388,7 +377,6 @@ class ThemeManager(QtGui.QWidget): theme_zip.close() self.application.set_normal_cursor() - def on_import_theme(self): """ Opens a file dialog to select the theme file(s) to import before @@ -409,9 +397,30 @@ class ThemeManager(QtGui.QWidget): self.load_themes() self.application.set_normal_cursor() - def load_themes(self, first_time=False): + def load_first_time_themes(self): """ - Loads the theme lists and triggers updates accross the whole system + Imports any themes on start up and makes sure there is at least one theme + """ + self.application.set_busy_cursor() + files = AppLocation.get_files(self.settingsSection, u'.otz') + for theme_file in files: + theme_file = os.path.join(self.path, theme_file) + self.unzip_theme(theme_file, self.path) + delete_file(theme_file) + files = AppLocation.get_files(self.settingsSection, u'.otz') + # No themes have been found so create one + if not files: + theme = ThemeXML() + theme.theme_name = UiStrings().Default + self._write_theme(theme, None, None) + Settings().setValue(self.settingsSection + u'/global theme', theme.theme_name) + self.config_updated() + self.application.set_normal_cursor() + self.load_themes() + + def load_themes(self): + """ + Loads the theme lists and triggers updates across the whole system using direct calls or core functions and events for the plugins. The plugins will call back in to get the real list if they want it. """ @@ -419,17 +428,6 @@ class ThemeManager(QtGui.QWidget): self.theme_list = [] self.theme_list_widget.clear() files = AppLocation.get_files(self.settingsSection, u'.png') - if first_time: - self.first_time() - files = AppLocation.get_files(self.settingsSection, u'.png') - # No themes have been found so create one - if not files: - theme = ThemeXML() - theme.theme_name = UiStrings().Default - self._write_theme(theme, None, None) - Settings().setValue(self.settingsSection + u'/global theme', theme.theme_name) - self.config_updated() - files = AppLocation.get_files(self.settingsSection, u'.png') # Sort the themes by its name considering language specific files.sort(key=lambda file_name: unicode(file_name), cmp=locale_compare) # now process the file list of png files diff --git a/openlp/core/ui/themestab.py b/openlp/core/ui/themestab.py index 1442ff4e9..2ae3d7cc7 100644 --- a/openlp/core/ui/themestab.py +++ b/openlp/core/ui/themestab.py @@ -155,7 +155,7 @@ class ThemesTab(SettingsTab): self.renderer.set_theme_level(self.theme_level) Registry().execute(u'theme_update_global', self.global_theme) - def postSetUp(self): + def post_set_up(self): """ After setting things up... """ diff --git a/openlp/core/utils/__init__.py b/openlp/core/utils/__init__.py index 6706750b5..d32729699 100644 --- a/openlp/core/utils/__init__.py +++ b/openlp/core/utils/__init__.py @@ -335,11 +335,11 @@ def get_uno_command(): Returns the UNO command to launch an openoffice.org instance. """ COMMAND = u'soffice' - OPTIONS = u'-nologo -norestore -minimized -nodefault -nofirststartwizard' + OPTIONS = u'--nologo --norestore --minimized --nodefault --nofirststartwizard' if UNO_CONNECTION_TYPE == u'pipe': - CONNECTION = u'"-accept=pipe,name=openlp_pipe;urp;"' + CONNECTION = u'"--accept=pipe,name=openlp_pipe;urp;"' else: - CONNECTION = u'"-accept=socket,host=localhost,port=2002;urp;"' + CONNECTION = u'"--accept=socket,host=localhost,port=2002;urp;"' return u'%s %s %s' % (COMMAND, OPTIONS, CONNECTION) diff --git a/openlp/plugins/alerts/alertsplugin.py b/openlp/plugins/alerts/alertsplugin.py index 46de8df98..3dfc32257 100644 --- a/openlp/plugins/alerts/alertsplugin.py +++ b/openlp/plugins/alerts/alertsplugin.py @@ -151,7 +151,8 @@ class AlertsPlugin(Plugin): text=translate('AlertsPlugin', '&Alert'), icon=u':/plugins/plugin_alerts.png', statustip=translate('AlertsPlugin', 'Show an alert message.'), visible=False, can_shortcuts=True, triggers=self.onAlertsTrigger) - self.main_window.toolsMenu.addAction(self.toolsAlertItem) + self.main_window.tools_menu.addAction(self.toolsAlertItem) + def initialise(self): log.info(u'Alerts Initialising') diff --git a/tests/functional/openlp_core_lib/test_pluginmanager.py b/tests/functional/openlp_core_lib/test_pluginmanager.py index fef9b54d6..7b2a0ba31 100644 --- a/tests/functional/openlp_core_lib/test_pluginmanager.py +++ b/tests/functional/openlp_core_lib/test_pluginmanager.py @@ -18,8 +18,15 @@ class TestPluginManager(TestCase): """ Some pre-test setup required. """ + self.mocked_main_window = MagicMock() + self.mocked_main_window.file_import_menu.return_value = None + self.mocked_main_window.file_export_menu.return_value = None + self.mocked_main_window.file_export_menu.return_value = None + self.mocked_settings_form = MagicMock() Registry.create() Registry().register(u'service_list', MagicMock()) + Registry().register(u'main_window', self.mocked_main_window) + Registry().register(u'settings_form', self.mocked_settings_form) def hook_media_manager_with_disabled_plugin_test(self): """ @@ -78,19 +85,43 @@ class TestPluginManager(TestCase): # GIVEN: A PluginManager instance and a list with a mocked up plugin whose status is set to Disabled mocked_plugin = MagicMock() mocked_plugin.status = PluginStatus.Disabled - mocked_settings_form = MagicMock() plugin_manager = PluginManager() plugin_manager.plugins = [mocked_plugin] + mocked_settings_form = MagicMock() + # Replace the autoloaded plugin with the version for testing in real code this would error + mocked_settings_form.plugin_manager = plugin_manager # WHEN: We run hook_settings_tabs() - plugin_manager.hook_settings_tabs(mocked_settings_form) + plugin_manager.hook_settings_tabs() # THEN: The createSettingsTab() method should not have been called, but the plugins lists should be the same assert mocked_plugin.createSettingsTab.call_count == 0, \ u'The createMediaManagerItem() method should not have been called.' - self.assertEqual(mocked_settings_form.plugins, plugin_manager.plugins, + self.assertEqual(mocked_settings_form.plugin_manager.plugins, plugin_manager.plugins, u'The plugins on the settings form should be the same as the plugins in the plugin manager') + def hook_settings_tabs_with_active_plugin_and_mocked_form_test(self): + """ + Test running the hook_settings_tabs() method with an active plugin and a mocked settings form + """ + # GIVEN: A PluginManager instance and a list with a mocked up plugin whose status is set to Active + mocked_plugin = MagicMock() + mocked_plugin.status = PluginStatus.Active + plugin_manager = PluginManager() + plugin_manager.plugins = [mocked_plugin] + mocked_settings_form = MagicMock() + # Replace the autoloaded plugin with the version for testing in real code this would error + mocked_settings_form.plugin_manager = plugin_manager + + # WHEN: We run hook_settings_tabs() + plugin_manager.hook_settings_tabs() + + # THEN: The createMediaManagerItem() method should have been called with the mocked settings form + assert mocked_plugin.createSettingsTab.call_count == 1, \ + u'The createMediaManagerItem() method should have been called once.' + self.assertEqual(mocked_settings_form.plugin_manager.plugins, plugin_manager.plugins, + u'The plugins on the settings form should be the same as the plugins in the plugin manager') + def hook_settings_tabs_with_active_plugin_and_no_form_test(self): """ Test running the hook_settings_tabs() method with an active plugin and no settings form @@ -105,26 +136,7 @@ class TestPluginManager(TestCase): plugin_manager.hook_settings_tabs() # THEN: The createSettingsTab() method should have been called - mocked_plugin.createSettingsTab.assert_called_with(None) - - def hook_settings_tabs_with_active_plugin_and_mocked_form_test(self): - """ - Test running the hook_settings_tabs() method with an active plugin and a mocked settings form - """ - # GIVEN: A PluginManager instance and a list with a mocked up plugin whose status is set to Active - mocked_plugin = MagicMock() - mocked_plugin.status = PluginStatus.Active - mocked_settings_form = MagicMock() - plugin_manager = PluginManager() - plugin_manager.plugins = [mocked_plugin] - - # WHEN: We run hook_settings_tabs() - plugin_manager.hook_settings_tabs(mocked_settings_form) - - # THEN: The createMediaManagerItem() method should have been called with the mocked settings form - mocked_plugin.createSettingsTab.assert_called_with(mocked_settings_form) - self.assertEqual(mocked_settings_form.plugins, plugin_manager.plugins, - u'The plugins on the settings form should be the same as the plugins in the plugin manager') + mocked_plugin.createSettingsTab.assert_called_with(self.mocked_settings_form) def hook_import_menu_with_disabled_plugin_test(self): """ @@ -133,12 +145,11 @@ class TestPluginManager(TestCase): # GIVEN: A PluginManager instance and a list with a mocked up plugin whose status is set to Disabled mocked_plugin = MagicMock() mocked_plugin.status = PluginStatus.Disabled - mocked_import_menu = MagicMock() plugin_manager = PluginManager() plugin_manager.plugins = [mocked_plugin] # WHEN: We run hook_import_menu() - plugin_manager.hook_import_menu(mocked_import_menu) + plugin_manager.hook_import_menu() # THEN: The createMediaManagerItem() method should have been called assert mocked_plugin.addImportMenuItem.call_count == 0, \ @@ -151,15 +162,14 @@ class TestPluginManager(TestCase): # GIVEN: A PluginManager instance and a list with a mocked up plugin whose status is set to Active mocked_plugin = MagicMock() mocked_plugin.status = PluginStatus.Active - mocked_import_menu = MagicMock() plugin_manager = PluginManager() plugin_manager.plugins = [mocked_plugin] # WHEN: We run hook_import_menu() - plugin_manager.hook_import_menu(mocked_import_menu) + plugin_manager.hook_import_menu() # THEN: The addImportMenuItem() method should have been called - mocked_plugin.addImportMenuItem.assert_called_with(mocked_import_menu) + mocked_plugin.addImportMenuItem.assert_called_with(self.mocked_main_window.file_import_menu) def hook_export_menu_with_disabled_plugin_test(self): """ @@ -168,12 +178,11 @@ class TestPluginManager(TestCase): # GIVEN: A PluginManager instance and a list with a mocked up plugin whose status is set to Disabled mocked_plugin = MagicMock() mocked_plugin.status = PluginStatus.Disabled - mocked_export_menu = MagicMock() plugin_manager = PluginManager() plugin_manager.plugins = [mocked_plugin] # WHEN: We run hook_export_menu() - plugin_manager.hook_export_menu(mocked_export_menu) + plugin_manager.hook_export_menu() # THEN: The addExportMenuItem() method should have been called assert mocked_plugin.addExportMenuItem.call_count == 0, \ @@ -186,15 +195,14 @@ class TestPluginManager(TestCase): # GIVEN: A PluginManager instance and a list with a mocked up plugin whose status is set to Active mocked_plugin = MagicMock() mocked_plugin.status = PluginStatus.Active - mocked_export_menu = MagicMock() plugin_manager = PluginManager() plugin_manager.plugins = [mocked_plugin] # WHEN: We run hook_export_menu() - plugin_manager.hook_export_menu(mocked_export_menu) + plugin_manager.hook_export_menu() # THEN: The addExportMenuItem() method should have been called - mocked_plugin.addExportMenuItem.assert_called_with(mocked_export_menu) + mocked_plugin.addExportMenuItem.assert_called_with(self.mocked_main_window.file_export_menu) def hook_tools_menu_with_disabled_plugin_test(self): """ @@ -203,12 +211,11 @@ class TestPluginManager(TestCase): # GIVEN: A PluginManager instance and a list with a mocked up plugin whose status is set to Disabled mocked_plugin = MagicMock() mocked_plugin.status = PluginStatus.Disabled - mocked_tools_menu = MagicMock() plugin_manager = PluginManager() plugin_manager.plugins = [mocked_plugin] # WHEN: We run hook_tools_menu() - plugin_manager.hook_tools_menu(mocked_tools_menu) + plugin_manager.hook_tools_menu() # THEN: The addToolsMenuItem() method should have been called assert mocked_plugin.addToolsMenuItem.call_count == 0, \ @@ -221,15 +228,14 @@ class TestPluginManager(TestCase): # GIVEN: A PluginManager instance and a list with a mocked up plugin whose status is set to Active mocked_plugin = MagicMock() mocked_plugin.status = PluginStatus.Active - mocked_tools_menu = MagicMock() plugin_manager = PluginManager() plugin_manager.plugins = [mocked_plugin] # WHEN: We run hook_tools_menu() - plugin_manager.hook_tools_menu(mocked_tools_menu) + plugin_manager.hook_tools_menu() # THEN: The addToolsMenuItem() method should have been called - mocked_plugin.addToolsMenuItem.assert_called_with(mocked_tools_menu) + mocked_plugin.addToolsMenuItem.assert_called_with(self.mocked_main_window.tools_menu) def initialise_plugins_with_disabled_plugin_test(self): """ diff --git a/tests/interfaces/openlp_core_ui/test_servicemanager.py b/tests/interfaces/openlp_core_ui/test_servicemanager.py index 97212f326..db161022b 100644 --- a/tests/interfaces/openlp_core_ui/test_servicemanager.py +++ b/tests/interfaces/openlp_core_ui/test_servicemanager.py @@ -21,15 +21,15 @@ class TestServiceManager(TestCase): self.app = QtGui.QApplication.instance() ScreenList.create(self.app.desktop()) Registry().register(u'application', MagicMock()) - #with patch(u'openlp.core.lib.PluginManager'): - # self.main_window = MainWindow() - #self.service_manager = Registry().get(u'service_manager') + with patch(u'openlp.core.lib.PluginManager'): + self.main_window = MainWindow() + self.service_manager = Registry().get(u'service_manager') def tearDown(self): """ Delete all the C++ objects at the end so that we don't have a segfault """ - #del self.main_window + del self.main_window del self.app def basic_service_manager_test(self): @@ -40,6 +40,5 @@ class TestServiceManager(TestCase): # WHEN I have an empty display # THEN the count of items should be zero - #self.assertEqual(self.service_manager.service_manager_list.topLevelItemCount(), 0, - # u'The service manager list should be empty ') - pass + self.assertEqual(self.service_manager.service_manager_list.topLevelItemCount(), 0, + u'The service manager list should be empty ')