def __init__(self, parent, projectordb, edit=False): """ Build the source select dialog using tabbed interface. :param projectordb: ProjectorDB session to use """ log.debug('Initializing SourceSelectTabs()') super(SourceSelectTabs, self).__init__(parent, QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.WindowTitleHint) self.setMinimumWidth(350) self.projectordb = projectordb self.edit = edit if self.edit: title = translate('OpenLP.SourceSelectForm', 'Edit Projector Source Text') else: title = translate('OpenLP.SourceSelectForm', 'Select Projector Source') self.setWindowTitle(title) self.setObjectName('source_select_tabs') self.setWindowIcon(build_icon(':/icon/openlp-log.svg')) self.setModal(True) self.layout = QtWidgets.QVBoxLayout() self.layout.setObjectName('source_select_tabs_layout') if is_macosx(): self.tabwidget = QtWidgets.QTabWidget(self) else: self.tabwidget = FingerTabWidget(self) self.tabwidget.setObjectName('source_select_tabs_tabwidget') self.tabwidget.setUsesScrollButtons(False) if is_macosx(): self.tabwidget.setTabPosition(QtWidgets.QTabWidget.North) else: self.tabwidget.setTabPosition(QtWidgets.QTabWidget.West) self.layout.addWidget(self.tabwidget) self.setLayout(self.layout)
def __init__(self, parent): """ Constructor """ super(MainDisplay, self).__init__(parent) self.screens = ScreenList() self.rebuild_css = False self.hide_mode = None self.override = {} self.retranslateUi() self.media_object = None if self.is_live: self.audio_player = AudioPlayer(self) else: self.audio_player = None self.first_time = True self.web_loaded = True self.setStyleSheet(OPAQUE_STYLESHEET) window_flags = QtCore.Qt.FramelessWindowHint | QtCore.Qt.Tool | QtCore.Qt.WindowStaysOnTopHint if Settings().value('advanced/x11 bypass wm'): window_flags |= QtCore.Qt.X11BypassWindowManagerHint # TODO: The following combination of window_flags works correctly # on Mac OS X. For next OpenLP version we should test it on other # platforms. For OpenLP 2.0 keep it only for OS X to not cause any # regressions on other platforms. if is_macosx(): window_flags = QtCore.Qt.FramelessWindowHint | QtCore.Qt.Window self.setWindowFlags(window_flags) self.setAttribute(QtCore.Qt.WA_DeleteOnClose) self.set_transparency(False) if is_macosx(): if self.is_live: # Get a pointer to the underlying NSView try: nsview_pointer = self.winId().ascapsule() except: nsview_pointer = voidptr(self.winId()).ascapsule() # Set PyCapsule name so pyobjc will accept it pythonapi.PyCapsule_SetName.restype = c_void_p pythonapi.PyCapsule_SetName.argtypes = [py_object, c_char_p] pythonapi.PyCapsule_SetName(nsview_pointer, c_char_p(b"objc.__object__")) # Covert the NSView pointer into a pyobjc NSView object self.pyobjc_nsview = objc_object(cobject=nsview_pointer) # Set the window level so that the MainDisplay is above the menu bar and dock self.pyobjc_nsview.window().setLevel_(NSMainMenuWindowLevel + 2) # Set the collection behavior so the window is visible when Mission Control is activated self.pyobjc_nsview.window().setCollectionBehavior_(NSWindowCollectionBehaviorManaged) if self.screens.current['primary']: # Connect focusWindowChanged signal so we can change the window level when the display is not in # focus on the primary screen self.application.focusWindowChanged.connect(self.change_window_level) if self.is_live: Registry().register_function('live_display_hide', self.hide_display) Registry().register_function('live_display_show', self.show_display) Registry().register_function('update_display_css', self.css_changed) self.close_display = False
def setup_vlc(self): """ Setup VLC instance and mediaplayer """ vlc = get_vlc() self.vlc_instance = vlc.Instance() # creating an empty vlc media player self.vlc_media_player = self.vlc_instance.media_player_new() # The media player has to be 'connected' to the QFrame. # (otherwise a video would be displayed in it's own window) # This is platform specific! # You have to give the id of the QFrame (or similar object) # to vlc, different platforms have different functions for this. win_id = int(self.preview_frame.winId()) if is_win(): self.vlc_media_player.set_hwnd(win_id) elif is_macosx(): # We have to use 'set_nsobject' since Qt5 on OSX uses Cocoa # framework and not the old Carbon. self.vlc_media_player.set_nsobject(win_id) else: # for Linux using the X Server self.vlc_media_player.set_xwindow(win_id) self.vlc_media = None # Setup timer every 100 ms to update position self.timer = QtCore.QTimer(self) self.timer.timeout.connect(self.update_position) self.timer.start(100) self.find_optical_devices() self.audio_cd = False self.audio_cd_tracks = None
def setup(self, display): """ Set up the media player """ vlc = get_vlc() display.vlc_widget = QtGui.QFrame(display) display.vlc_widget.setFrameStyle(QtGui.QFrame.NoFrame) # creating a basic vlc instance command_line_options = '--no-video-title-show' if not display.has_audio: command_line_options += ' --no-audio --no-video-title-show' if Settings().value('advanced/hide mouse') and display.controller.is_live: command_line_options += ' --mouse-hide-timeout=0' display.vlc_instance = vlc.Instance(command_line_options) # creating an empty vlc media player display.vlc_media_player = display.vlc_instance.media_player_new() display.vlc_widget.resize(display.size()) display.vlc_widget.raise_() display.vlc_widget.hide() # The media player has to be 'connected' to the QFrame. # (otherwise a video would be displayed in it's own window) # This is platform specific! # You have to give the id of the QFrame (or similar object) # to vlc, different platforms have different functions for this. win_id = int(display.vlc_widget.winId()) if is_win(): display.vlc_media_player.set_hwnd(win_id) elif is_macosx(): # We have to use 'set_nsobject' since Qt4 on OSX uses Cocoa # framework and not the old Carbon. display.vlc_media_player.set_nsobject(win_id) else: # for Linux/*BSD using the X Server display.vlc_media_player.set_xwindow(win_id) self.has_own_widget = True
def event(self, event): """ Enables platform specific event handling i.e. direct file opening on OS X :param event: The event """ if event.type() == QtCore.QEvent.FileOpen: file_name = event.file() log.debug('Got open file event for {name}!'.format(name=file_name)) self.args.insert(0, file_name) return True # Mac OS X should restore app window when user clicked on the OpenLP icon # in the Dock bar. However, OpenLP consists of multiple windows and this # does not work. This workaround fixes that. # The main OpenLP window is restored when it was previously minimized. elif event.type() == QtCore.QEvent.ApplicationActivate: if is_macosx() and hasattr(self, 'main_window'): if self.main_window.isMinimized(): # Copied from QWidget.setWindowState() docs on how to restore and activate a minimized window # while preserving its maximized and/or full-screen state. self.main_window.setWindowState( self.main_window.windowState() & ~QtCore.Qt.WindowMinimized | QtCore.Qt.WindowActive) return True return QtWidgets.QApplication.event(self, event)
def change_window_level(self, window): """ Changes the display window level on Mac OS X so that the main window can be brought into focus but still allow the main display to be above the menu bar and dock when it in focus. :param window: Window from our application that focus changed to or None if outside our application """ if is_macosx(): if window: # Get different window ids' as int's try: window_id = window.winId().__int__() main_window_id = self.main_window.winId().__int__() self_id = self.winId().__int__() except: return # If the passed window has the same id as our window make sure the display has the proper level and # collection behavior. if window_id == self_id: self.pyobjc_nsview.window().setLevel_(NSMainMenuWindowLevel + 2) self.pyobjc_nsview.window().setCollectionBehavior_(NSWindowCollectionBehaviorManaged) # Else set the displays window level back to normal since we are trying to focus a window other than # the display. else: self.pyobjc_nsview.window().setLevel_(0) self.pyobjc_nsview.window().setCollectionBehavior_(NSWindowCollectionBehaviorManaged) # If we are trying to focus the main window raise it now to complete the focus change. if window_id == main_window_id: self.main_window.raise_()
def setup_vlc(self): """ Setup VLC instance and mediaplayer """ self.vlc_instance = vlc.Instance() # creating an empty vlc media player self.vlc_media_player = self.vlc_instance.media_player_new() # The media player has to be 'connected' to the QFrame. # (otherwise a video would be displayed in it's own window) # This is platform specific! # You have to give the id of the QFrame (or similar object) # to vlc, different platforms have different functions for this. win_id = int(self.preview_frame.winId()) if is_win(): self.vlc_media_player.set_hwnd(win_id) elif is_macosx(): # We have to use 'set_nsobject' since Qt4 on OSX uses Cocoa # framework and not the old Carbon. self.vlc_media_player.set_nsobject(win_id) else: # for Linux using the X Server self.vlc_media_player.set_xwindow(win_id) self.vlc_media = None # Setup timer every 100 ms to update position self.timer = QtCore.QTimer(self) self.timer.timeout.connect(self.update_position) self.timer.start(100) self.find_optical_devices() self.audio_cd = False self.audio_cd_tracks = None
def change_window_level(self, window): """ Changes the display window level on Mac OS X so that the main window can be brought into focus but still allow the main display to be above the menu bar and dock when it in focus. :param window: Window from our application that focus changed to or None if outside our application """ if is_macosx(): if window: # Get different window ids' as int's try: window_id = window.winId().__int__() main_window_id = self.main_window.winId().__int__() self_id = self.winId().__int__() except: return # If the passed window has the same id as our window make sure the display has the proper level and # collection behavior. if window_id == self_id: self.pyobjc_nsview.window().setLevel_( NSMainMenuWindowLevel + 2) self.pyobjc_nsview.window().setCollectionBehavior_( NSWindowCollectionBehaviorManaged) # Else set the displays window level back to normal since we are trying to focus a window other than # the display. else: self.pyobjc_nsview.window().setLevel_(0) self.pyobjc_nsview.window().setCollectionBehavior_( NSWindowCollectionBehaviorManaged) # If we are trying to focus the main window raise it now to complete the focus change. if window_id == main_window_id: self.main_window.raise_()
def get_vlc(): """ In order to make this module more testable, we have to wrap the VLC import inside a method. We do this so that we can mock out the VLC module entirely. :return: The "vlc" module, or None """ if 'openlp.core.ui.media.vendor.vlc' in sys.modules: # If VLC has already been imported, no need to do all the stuff below again return sys.modules['openlp.core.ui.media.vendor.vlc'] is_vlc_available = False try: if is_macosx(): # Newer versions of VLC on OS X need this. See https://forum.videolan.org/viewtopic.php?t=124521 os.environ[ 'VLC_PLUGIN_PATH'] = '/Applications/VLC.app/Contents/MacOS/plugins' from openlp.core.ui.media.vendor import vlc is_vlc_available = bool(vlc.get_default_instance()) except (ImportError, NameError, NotImplementedError): pass except OSError as e: if is_win(): if not isinstance(e, WindowsError) and e.winerror != 126: raise elif is_macosx(): pass else: raise if is_vlc_available: try: VERSION = vlc.libvlc_get_version().decode('UTF-8') except: VERSION = '0.0.0' # LooseVersion does not work when a string contains letter and digits (e. g. 2.0.5 Twoflower). # http://bugs.python.org/issue14894 if LooseVersion(VERSION.split()[0]) < LooseVersion('1.1.0'): is_vlc_available = False log.debug( 'VLC could not be loaded, because the vlc version is too old: %s' % VERSION) if is_vlc_available: return vlc else: return None
def check_available(self): """ Check if the player is available """ # At the moment we don't have support for phononplayer on Mac OS X if is_macosx(): return False else: return True
def check_available(self): """ Check if the player is available """ # At the moment we don't have support for phononplayer on Mac OS X if is_macosx(): return False else: return True
def get_vlc(): """ In order to make this module more testable, we have to wrap the VLC import inside a method. We do this so that we can mock out the VLC module entirely. :return: The "vlc" module, or None """ if 'openlp.core.ui.media.vendor.vlc' in sys.modules: # If VLC has already been imported, no need to do all the stuff below again return sys.modules['openlp.core.ui.media.vendor.vlc'] is_vlc_available = False try: if is_macosx(): # Newer versions of VLC on OS X need this. See https://forum.videolan.org/viewtopic.php?t=124521 os.environ[ 'VLC_PLUGIN_PATH'] = '/Applications/VLC.app/Contents/MacOS/plugins' # On Windows when frozen in PyInstaller, we need to blank SetDllDirectoryW to allow loading of the VLC dll. # This is due to limitations (by desgin) in PyInstaller. SetDllDirectoryW original value is restored once # VLC has been imported. if is_win(): buffer_size = 1024 dll_directory = ctypes.create_unicode_buffer(buffer_size) new_buffer_size = ctypes.windll.kernel32.GetDllDirectoryW( buffer_size, dll_directory) dll_directory = ''.join(dll_directory[:new_buffer_size]).replace( '\0', '') log.debug('Original DllDirectory: %s' % dll_directory) ctypes.windll.kernel32.SetDllDirectoryW(None) from openlp.core.ui.media.vendor import vlc if is_win(): ctypes.windll.kernel32.SetDllDirectoryW(dll_directory) is_vlc_available = bool(vlc.get_default_instance()) except (ImportError, NameError, NotImplementedError): pass except OSError as e: if is_win(): if not isinstance(e, WindowsError) and e.winerror != 126: raise else: pass if is_vlc_available: try: VERSION = vlc.libvlc_get_version().decode('UTF-8') except: VERSION = '0.0.0' # LooseVersion does not work when a string contains letter and digits (e. g. 2.0.5 Twoflower). # http://bugs.python.org/issue14894 if LooseVersion(VERSION.split()[0]) < LooseVersion('1.1.0'): is_vlc_available = False log.debug( 'VLC could not be loaded, because the vlc version is too old: %s' % VERSION) if is_vlc_available: return vlc else: return None
def get_vlc(): """ In order to make this module more testable, we have to wrap the VLC import inside a method. We do this so that we can mock out the VLC module entirely. :return: The "vlc" module, or None """ if 'openlp.core.ui.media.vendor.vlc' in sys.modules: # If VLC has already been imported, no need to do all the stuff below again return sys.modules['openlp.core.ui.media.vendor.vlc'] is_vlc_available = False try: if is_macosx(): # Newer versions of VLC on OS X need this. See https://forum.videolan.org/viewtopic.php?t=124521 os.environ['VLC_PLUGIN_PATH'] = '/Applications/VLC.app/Contents/MacOS/plugins' from openlp.core.ui.media.vendor import vlc is_vlc_available = bool(vlc.get_default_instance()) except (ImportError, NameError, NotImplementedError): pass except OSError as e: if is_win(): if not isinstance(e, WindowsError) and e.winerror != 126: raise elif is_macosx(): pass else: raise if is_vlc_available: try: VERSION = vlc.libvlc_get_version().decode('UTF-8') except: VERSION = '0.0.0' # LooseVersion does not work when a string contains letter and digits (e. g. 2.0.5 Twoflower). # http://bugs.python.org/issue14894 if LooseVersion(VERSION.split()[0]) < LooseVersion('1.1.0'): is_vlc_available = False log.debug('VLC could not be loaded, because the vlc version is too old: %s' % VERSION) if is_vlc_available: return vlc else: return None
def get_vlc(): """ In order to make this module more testable, we have to wrap the VLC import inside a method. We do this so that we can mock out the VLC module entirely. :return: The "vlc" module, or None """ if 'openlp.core.ui.media.vendor.vlc' in sys.modules: # If VLC has already been imported, no need to do all the stuff below again return sys.modules['openlp.core.ui.media.vendor.vlc'] is_vlc_available = False try: if is_macosx(): # Newer versions of VLC on OS X need this. See https://forum.videolan.org/viewtopic.php?t=124521 os.environ['VLC_PLUGIN_PATH'] = '/Applications/VLC.app/Contents/MacOS/plugins' # On Windows when frozen in PyInstaller, we need to blank SetDllDirectoryW to allow loading of the VLC dll. # This is due to limitations (by desgin) in PyInstaller. SetDllDirectoryW original value is restored once # VLC has been imported. if is_win(): buffer_size = 1024 dll_directory = ctypes.create_unicode_buffer(buffer_size) new_buffer_size = ctypes.windll.kernel32.GetDllDirectoryW(buffer_size, dll_directory) dll_directory = ''.join(dll_directory[:new_buffer_size]).replace('\0', '') log.debug('Original DllDirectory: %s' % dll_directory) ctypes.windll.kernel32.SetDllDirectoryW(None) from openlp.core.ui.media.vendor import vlc if is_win(): ctypes.windll.kernel32.SetDllDirectoryW(dll_directory) is_vlc_available = bool(vlc.get_default_instance()) except (ImportError, NameError, NotImplementedError): pass except OSError as e: if is_win(): if not isinstance(e, WindowsError) and e.winerror != 126: raise else: pass if is_vlc_available: try: VERSION = vlc.libvlc_get_version().decode('UTF-8') except: VERSION = '0.0.0' # LooseVersion does not work when a string contains letter and digits (e. g. 2.0.5 Twoflower). # http://bugs.python.org/issue14894 if LooseVersion(VERSION.split()[0]) < LooseVersion('1.1.0'): is_vlc_available = False log.debug('VLC could not be loaded, because the vlc version is too old: %s' % VERSION) if is_vlc_available: return vlc else: return None
def __init__(self, parent, projectordb, edit=False): """ Build the source select dialog using tabbed interface. :param projectordb: ProjectorDB session to use """ log.debug('Initializing SourceSelectTabs()') super(SourceSelectTabs, self).__init__( parent, QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.WindowTitleHint | QtCore.Qt.WindowCloseButtonHint) self.setMinimumWidth(350) self.projectordb = projectordb self.edit = edit if self.edit: title = translate('OpenLP.SourceSelectForm', 'Edit Projector Source Text') else: title = translate('OpenLP.SourceSelectForm', 'Select Projector Source') self.setWindowTitle(title) self.setObjectName('source_select_tabs') self.setWindowIcon(build_icon(':/icon/openlp-log.svg')) self.setModal(True) self.layout = QtWidgets.QVBoxLayout() self.layout.setObjectName('source_select_tabs_layout') if is_macosx(): self.tabwidget = QtWidgets.QTabWidget(self) else: self.tabwidget = FingerTabWidget(self) self.tabwidget.setObjectName('source_select_tabs_tabwidget') self.tabwidget.setUsesScrollButtons(False) if is_macosx(): self.tabwidget.setTabPosition(QtWidgets.QTabWidget.North) else: self.tabwidget.setTabPosition(QtWidgets.QTabWidget.West) self.layout.addWidget(self.tabwidget) self.setLayout(self.layout)
def test_is_linux(self): """ Test the is_linux() function """ # GIVEN: Mocked out objects with patch('openlp.core.common.os') as mocked_os, patch('openlp.core.common.sys') as mocked_sys: # WHEN: The mocked os.name and sys.platform are set to 'posix' and 'linux3' repectivly mocked_os.name = 'posix' mocked_sys.platform = 'linux3' # THEN: The three platform functions should perform properly self.assertTrue(is_linux(), 'is_linux() should return True') self.assertFalse(is_win(), 'is_win() should return False') self.assertFalse(is_macosx(), 'is_macosx() should return False')
def close(self): """ Remove registered function on close. """ if self.is_live: if is_macosx(): # Block signals so signal we are disconnecting can't get called while we disconnect it self.blockSignals(True) if self.screens.current['primary']: self.application.focusWindowChanged.disconnect() self.blockSignals(False) Registry().remove_function('live_display_hide', self.hide_display) Registry().remove_function('live_display_show', self.show_display) Registry().remove_function('update_display_css', self.css_changed) self.close_display = True super().close()
def test_is_macosx(self): """ Test the is_macosx() function """ # GIVEN: Mocked out objects with patch('openlp.core.common.os') as mocked_os, patch( 'openlp.core.common.sys') as mocked_sys: # WHEN: The mocked os.name and sys.platform are set to 'posix' and 'darwin' repectivly mocked_os.name = 'posix' mocked_sys.platform = 'darwin' # THEN: The three platform functions should perform properly assert is_macosx() is True, 'is_macosx() should return True' assert is_win() is False, 'is_win() should return False' assert is_linux() is False, 'is_linux() should return False'
def is_linux_test(self): """ Test the is_linux() function """ # GIVEN: Mocked out objects with patch('openlp.core.common.os') as mocked_os, patch( 'openlp.core.common.sys') as mocked_sys: # WHEN: The mocked os.name and sys.platform are set to 'posix' and 'linux3' repectivly mocked_os.name = 'posix' mocked_sys.platform = 'linux3' # THEN: The three platform functions should perform properly self.assertTrue(is_linux(), 'is_linux() should return True') self.assertFalse(is_win(), 'is_win() should return False') self.assertFalse(is_macosx(), 'is_macosx() should return False')
def close(self): """ Remove registered function on close. """ if self.is_live: if is_macosx(): # Block signals so signal we are disconnecting can't get called while we disconnect it self.blockSignals(True) if self.screens.current['primary']: self.application.focusWindowChanged.disconnect() self.blockSignals(False) Registry().remove_function('live_display_hide', self.hide_display) Registry().remove_function('live_display_show', self.show_display) Registry().remove_function('update_display_css', self.css_changed) self.close_display = True super().close()
def get_translator(language): """ Set up a translator to use in this instance of OpenLP :param language: The language to load into the translator """ if LanguageManager.auto_language: language = QtCore.QLocale.system().name() lang_path = AppLocation.get_directory(AppLocation.LanguageDir) app_translator = QtCore.QTranslator() app_translator.load(language, lang_path) # A translator for buttons and other default strings provided by Qt. if not is_win() and not is_macosx(): lang_path = QtCore.QLibraryInfo.location(QtCore.QLibraryInfo.TranslationsPath) default_translator = QtCore.QTranslator() default_translator.load("qt_%s" % language, lang_path) return app_translator, default_translator
def setupUi(self, image): """ Set up the wizard UI. """ self.setWindowIcon(build_icon(u':/icon/openlp-logo.svg')) self.setModal(True) self.setOptions(QtGui.QWizard.IndependentPages | QtGui.QWizard.NoBackButtonOnStartPage | QtGui.QWizard.NoBackButtonOnLastPage) if is_macosx(): self.setPixmap(QtGui.QWizard.BackgroundPixmap, QtGui.QPixmap(':/wizards/openlp-osx-wizard.png')) else: self.setWizardStyle(QtGui.QWizard.ModernStyle) add_welcome_page(self, image) self.add_custom_pages() if self.with_progress_page: self.add_progress_page() self.retranslateUi()
def get_screen_resolution(): """ Get the screen resolution """ if is_macosx(): from AppKit import NSScreen screen_size = NSScreen.mainScreen().frame().size return screen_size.width, screen_size.height elif is_win(): from win32api import GetSystemMetrics return GetSystemMetrics(0), GetSystemMetrics(1) elif is_linux(): from Xlib.display import Display resolution = Display().screen().root.get_geometry() return resolution.width, resolution.height else: return 1024, 768
def setup(self, controller, display, live_display): """ Set up the media player :param controller: The display where the media is :param live_display: Is the display a live one. :return: """ vlc = get_vlc() if controller.is_live: controller.vlc_widget = QtWidgets.QFrame() controller.vlc_widget.setWindowFlags( QtCore.Qt.FramelessWindowHint | QtCore.Qt.Tool | QtCore.Qt.WindowStaysOnTopHint) else: controller.vlc_widget = QtWidgets.QFrame(display) controller.vlc_widget.setFrameStyle(QtWidgets.QFrame.NoFrame) # creating a basic vlc instance command_line_options = '--no-video-title-show ' if self.settings.value('advanced/hide mouse') and live_display: command_line_options += '--mouse-hide-timeout=0 ' if self.settings.value('media/vlc arguments'): command_line_options += self.settings.value('media/vlc arguments') controller.vlc_instance = vlc.Instance(command_line_options) # creating an empty vlc media player controller.vlc_media_player = controller.vlc_instance.media_player_new( ) controller.vlc_widget.resize(controller.size()) controller.vlc_widget.raise_() controller.vlc_widget.hide() # The media player has to be 'connected' to the QFrame. # (otherwise a video would be displayed in it's own window) # This is platform specific! # You have to give the id of the QFrame (or similar object) # to vlc, different platforms have different functions for this. win_id = int(controller.vlc_widget.winId()) if is_win(): controller.vlc_media_player.set_hwnd(win_id) elif is_macosx(): # We have to use 'set_nsobject' since Qt5 on OSX uses Cocoa # framework and not the old Carbon. controller.vlc_media_player.set_nsobject(win_id) else: # for Linux/*BSD using the X Server controller.vlc_media_player.set_xwindow(win_id) self.has_own_widget = True
def get_translator(language): """ Set up a translator to use in this instance of OpenLP :param language: The language to load into the translator """ if LanguageManager.auto_language: language = QtCore.QLocale.system().name() lang_path = AppLocation.get_directory(AppLocation.LanguageDir) app_translator = QtCore.QTranslator() app_translator.load(language, lang_path) # A translator for buttons and other default strings provided by Qt. if not is_win() and not is_macosx(): lang_path = QtCore.QLibraryInfo.location(QtCore.QLibraryInfo.TranslationsPath) default_translator = QtCore.QTranslator() default_translator.load('qt_%s' % language, lang_path) return app_translator, default_translator
def __init__(self, parent): """ Constructor """ self.is_live = False if hasattr(parent, 'is_live') and parent.is_live: self.is_live = True if self.is_live: self.parent = lambda: parent super(Display, self).__init__() self.controller = parent self.screen = {} # FIXME: On Mac OS X (tested on 10.7) the display screen is corrupt with # OpenGL. Only white blank screen is shown on the 2nd monitor all the # time. We need to investigate more how to use OpenGL properly on Mac OS # X. if not is_macosx(): self.setViewport(QtOpenGL.QGLWidget())
class TestPresentationManagerFileImport(SongImportTestHelper): def __init__(self, *args, **kwargs): self.importer_class_name = 'PresentationManagerImport' self.importer_module_name = 'presentationmanager' super(TestPresentationManagerFileImport, self).__init__(*args, **kwargs) @skipIf(is_macosx(), 'This test fails for an undetermined reason on macOS') def test_song_import(self): """ Test that loading a PresentationManager file works correctly """ self.file_import([TEST_PATH / 'Great Is Thy Faithfulness.sng'], self.load_external_result_data( TEST_PATH / 'Great Is Thy Faithfulness.json')) self.file_import([TEST_PATH / 'Amazing Grace.sng'], self.load_external_result_data(TEST_PATH / 'Amazing Grace.json'))
def __init__(self, parent): """ Constructor """ self.is_live = False if hasattr(parent, 'is_live') and parent.is_live: self.is_live = True if self.is_live: self.parent = lambda: parent super(Display, self).__init__() self.controller = parent self.screen = {} # FIXME: On Mac OS X (tested on 10.7) the display screen is corrupt with # OpenGL. Only white blank screen is shown on the 2nd monitor all the # time. We need to investigate more how to use OpenGL properly on Mac OS # X. if not is_macosx(): self.setViewport(QtOpenGL.QGLWidget())
def _get_os_dir_path(dir_type): """ Return a path based on which OS and environment we are running in. :param dir_type: AppLocation Enum of the requested path type :return: The requested path :rtype: Path """ # If running from source, return the language directory from the source directory if dir_type == AppLocation.LanguageDir: directory = Path(openlp.__file__, '..', '..').resolve() / 'resources' if directory.exists(): return directory if is_win(): openlp_folder_path = Path(os.getenv('APPDATA'), 'openlp') if dir_type == AppLocation.DataDir: return openlp_folder_path / 'data' elif dir_type == AppLocation.LanguageDir: return Path(openlp.__file__).parent return openlp_folder_path dirs = appdirs.AppDirs('openlp', multipath=True) if is_macosx(): openlp_folder_path = Path(dirs.user_data_dir) if dir_type == AppLocation.DataDir: return openlp_folder_path / 'Data' elif dir_type == AppLocation.LanguageDir: return Path(openlp.__file__).parent return openlp_folder_path else: if dir_type == AppLocation.LanguageDir: site_dirs = dirs.site_data_dir.split(os.pathsep) directory = Path(site_dirs[0]) if directory.exists(): return directory return Path(site_dirs[1]) if dir_type == AppLocation.DataDir: return Path(dirs.user_data_dir) elif dir_type == AppLocation.CacheDir: return Path(dirs.user_cache_dir) if dir_type == AppLocation.DataDir: return Path(os.getenv('HOME'), '.openlp', 'data') return Path(os.getenv('HOME'), '.openlp')
def _get_os_dir_path(dir_type): """ Return a path based on which OS and environment we are running in. :param dir_type: AppLocation Enum of the requested path type :return: The requested path :rtype: openlp.core.common.path.Path """ # If running from source, return the language directory from the source directory if dir_type == AppLocation.LanguageDir: directory = Path(openlp.__file__, '..', '..').resolve() / 'resources' if directory.exists(): return directory if is_win(): openlp_folder_path = Path(os.getenv('APPDATA'), 'openlp') if dir_type == AppLocation.DataDir: return openlp_folder_path / 'data' elif dir_type == AppLocation.LanguageDir: return Path(openlp.__file__).parent return openlp_folder_path elif is_macosx(): openlp_folder_path = Path(os.getenv('HOME'), 'Library', 'Application Support', 'openlp') if dir_type == AppLocation.DataDir: return openlp_folder_path / 'Data' elif dir_type == AppLocation.LanguageDir: return Path(openlp.__file__).parent return openlp_folder_path else: if dir_type == AppLocation.LanguageDir: directory = Path('/usr', 'local', 'share', 'openlp') if directory.exists(): return directory return Path('/usr', 'share', 'openlp') if XDG_BASE_AVAILABLE: if dir_type == AppLocation.DataDir: return Path(BaseDirectory.xdg_data_home, 'openlp') elif dir_type == AppLocation.CacheDir: return Path(BaseDirectory.xdg_cache_home, 'openlp') if dir_type == AppLocation.DataDir: return Path(os.getenv('HOME'), '.openlp', 'data') return Path(os.getenv('HOME'), '.openlp')
def _get_os_dir_path(dir_type): """ Return a path based on which OS and environment we are running in. """ # If running from source, return the language directory from the source directory if dir_type == AppLocation.LanguageDir: directory = os.path.abspath( os.path.join(os.path.dirname(openlp.__file__), '..', 'resources')) if os.path.exists(directory): return directory if is_win(): if dir_type == AppLocation.DataDir: return os.path.join(str(os.getenv('APPDATA')), 'openlp-paul', 'data') elif dir_type == AppLocation.LanguageDir: return os.path.dirname(openlp.__file__) return os.path.join(str(os.getenv('APPDATA')), 'openlp-paul') elif is_macosx(): if dir_type == AppLocation.DataDir: return os.path.join(str(os.getenv('HOME')), 'Library', 'Application Support', 'openlp-paul', 'Data') elif dir_type == AppLocation.LanguageDir: return os.path.dirname(openlp.__file__) return os.path.join(str(os.getenv('HOME')), 'Library', 'Application Support', 'openlp-paul') else: if dir_type == AppLocation.LanguageDir: for prefix in ['/usr/local', '/usr']: directory = os.path.join(prefix, 'share', 'openlp-paul') if os.path.exists(directory): return directory return os.path.join('/usr', 'share', 'openlp-paul') if XDG_BASE_AVAILABLE: if dir_type == AppLocation.DataDir: return os.path.join(str(BaseDirectory.xdg_data_home), 'openlp-paul') elif dir_type == AppLocation.CacheDir: return os.path.join(str(BaseDirectory.xdg_cache_home), 'openlp-paul') if dir_type == AppLocation.DataDir: return os.path.join(str(os.getenv('HOME')), '.openlp-paul', 'data') return os.path.join(str(os.getenv('HOME')), '.openlp-paul')
def setup_ui(self, image): """ Set up the wizard UI. :param image: path to start up image """ self.setWindowIcon(UiIcons().main_icon) self.setModal(True) self.setOptions(QtWidgets.QWizard.IndependentPages | QtWidgets.QWizard.NoBackButtonOnStartPage | QtWidgets.QWizard.NoBackButtonOnLastPage) if is_macosx(): self.setPixmap(QtWidgets.QWizard.BackgroundPixmap, QtGui.QPixmap(':/wizards/openlp-osx-wizard.png')) else: self.setWizardStyle(QtWidgets.QWizard.ModernStyle) add_welcome_page(self, image) self.add_custom_pages() if self.with_progress_page: self.add_progress_page() self.retranslate_ui()
def bootstrap_initialise(self): """ Check to see if we have any media Player's available. """ self.setup() self.vlc_player = VlcPlayer(self) State().add_service('mediacontroller', 0) State().add_service('media_live', 0) has_vlc = get_vlc() if has_vlc and pymediainfo_available: State().update_pre_conditions('mediacontroller', True) State().update_pre_conditions('media_live', True) else: if hasattr(self.main_window, 'splash') and self.main_window.splash.isVisible(): self.main_window.splash.hide() generic_message = translate( 'OpenLP.MediaController', 'OpenLP requires the following libraries in order to show videos and other ' 'media, but they are not installed. Please install these libraries to enable ' 'media playback in OpenLP.') fedora_rpmfusion = translate( 'OpenLP.MediaController', 'To install these libraries, you will need to enable the RPMFusion ' 'repository: https://rpmfusion.org/') if is_macosx(): message = translate( 'OpenLP.MediaController', 'macOS is missing VLC. Please download and install from the VLC web site: ' 'https://www.videolan.org/vlc/') else: packages = [] if not has_vlc: packages.append('python3-vlc') if not pymediainfo_available: packages.append('python3-pymediainfo') message = generic_message + '\n\n' + ', '.join(packages) if not has_vlc and is_linux(distro='fedora'): message += '\n\n' + fedora_rpmfusion State().missing_text('media_live', message) return True
def test_is_linux_distro(self): """ Test the is_linux() function for a particular Linux distribution """ # GIVEN: Mocked out objects with patch('openlp.core.common.os') as mocked_os, \ patch('openlp.core.common.sys') as mocked_sys, \ patch('openlp.core.common.distro_id') as mocked_distro_id: # WHEN: The mocked os.name and sys.platform are set to 'posix' and 'linux3' repectively # and the distro is Fedora mocked_os.name = 'posix' mocked_sys.platform = 'linux3' mocked_distro_id.return_value = 'fedora' # THEN: The three platform functions should perform properly assert is_linux( distro='fedora' ) is True, 'is_linux(distro="fedora") should return True' assert is_win() is False, 'is_win() should return False' assert is_macosx() is False, 'is_macosx() should return False'
def start(): """ Instantiate and run the application. """ set_up_fault_handling() # Add support for using multiprocessing from frozen Windows executable (built using PyInstaller), # see https://docs.python.org/3/library/multiprocessing.html#multiprocessing.freeze_support if is_win(): multiprocessing.freeze_support() # Mac OS X passes arguments like '-psn_XXXX' to the application. This argument is actually a process serial number. # However, this causes a conflict with other OpenLP arguments. Since we do not use this argument we can delete it # to avoid any potential conflicts. if is_macosx(): sys.argv = [x for x in sys.argv if not x.startswith('-psn')] if getattr(sys, 'frozen', False): os.environ['QTWEBENGINEPROCESS_PATH'] = os.path.normpath( os.path.join(sys._MEIPASS, '..', 'MacOS', 'PyQt5', 'Qt', 'lib', 'QtWebEngineCore.framework', 'Versions', '5', 'Helpers', 'QtWebEngineProcess.app', 'Contents', 'MacOS', 'QtWebEngineProcess')) main()
def parse_audio_file(self, audio_file_path): """ Parse audio file. The path is relative to the SongsBeamer Songs folder. :param audio_file_path: Path to the audio file """ # The path is relative to SongBeamers Song folder if is_win(): user_doc_path = Path(os.path.expandvars('$DOCUMENTS')) elif is_macosx(): user_doc_path = Path.home() / 'Documents' else: # SongBeamer only runs on mac and win... return audio_file_path = user_doc_path / 'SongBeamer' / 'Songs' / audio_file_path if audio_file_path.is_file(): self.add_media_file(audio_file_path) else: log.debug( 'Could not import mediafile "{audio_file_path}" since it does not exists!' .format(audio_file_path=audio_file_path))
def __init__(self, parent): """ Constructor """ super(MainDisplay, self).__init__(parent) self.screens = ScreenList() self.rebuild_css = False self.hide_mode = None self.override = {} self.retranslateUi() self.media_object = None if self.is_live and PHONON_AVAILABLE: self.audio_player = AudioPlayer(self) else: self.audio_player = None self.first_time = True self.web_loaded = True self.setStyleSheet(OPAQUE_STYLESHEET) window_flags = QtCore.Qt.FramelessWindowHint | QtCore.Qt.Tool | QtCore.Qt.WindowStaysOnTopHint if Settings().value('advanced/x11 bypass wm'): window_flags |= QtCore.Qt.X11BypassWindowManagerHint # TODO: The following combination of window_flags works correctly # on Mac OS X. For next OpenLP version we should test it on other # platforms. For OpenLP 2.0 keep it only for OS X to not cause any # regressions on other platforms. if is_macosx(): window_flags = QtCore.Qt.FramelessWindowHint | QtCore.Qt.Window # For primary screen ensure it stays above the OS X dock # and menu bar if self.screens.current['primary']: self.setWindowState(QtCore.Qt.WindowFullScreen) else: window_flags |= QtCore.Qt.WindowStaysOnTopHint self.setWindowFlags(window_flags) self.setAttribute(QtCore.Qt.WA_DeleteOnClose) self.set_transparency(False) if self.is_live: Registry().register_function('live_display_hide', self.hide_display) Registry().register_function('live_display_show', self.show_display) Registry().register_function('update_display_css', self.css_changed)
def __init__(self, parent): """ Constructor """ super(MainDisplay, self).__init__(parent) self.screens = ScreenList() self.rebuild_css = False self.hide_mode = None self.override = {} self.retranslateUi() self.media_object = None if self.is_live and PHONON_AVAILABLE: self.audio_player = AudioPlayer(self) else: self.audio_player = None self.first_time = True self.web_loaded = True self.setStyleSheet(OPAQUE_STYLESHEET) window_flags = QtCore.Qt.FramelessWindowHint | QtCore.Qt.Tool | QtCore.Qt.WindowStaysOnTopHint if Settings().value('advanced/x11 bypass wm'): window_flags |= QtCore.Qt.X11BypassWindowManagerHint # TODO: The following combination of window_flags works correctly # on Mac OS X. For next OpenLP version we should test it on other # platforms. For OpenLP 2.0 keep it only for OS X to not cause any # regressions on other platforms. if is_macosx(): window_flags = QtCore.Qt.FramelessWindowHint | QtCore.Qt.Window # For primary screen ensure it stays above the OS X dock # and menu bar if self.screens.current['primary']: self.setWindowState(QtCore.Qt.WindowFullScreen) else: window_flags |= QtCore.Qt.WindowStaysOnTopHint self.setWindowFlags(window_flags) self.setAttribute(QtCore.Qt.WA_DeleteOnClose) self.set_transparency(False) if self.is_live: Registry().register_function('live_display_hide', self.hide_display) Registry().register_function('live_display_show', self.show_display) Registry().register_function('update_display_css', self.css_changed)
def setup(self, display): """ Set up the media player :param display: The display where the media is :return: """ vlc = get_vlc() display.vlc_widget = QtWidgets.QFrame(display) display.vlc_widget.setFrameStyle(QtWidgets.QFrame.NoFrame) # creating a basic vlc instance command_line_options = '--no-video-title-show' if not display.has_audio: command_line_options += ' --no-audio --no-video-title-show' if Settings().value( 'advanced/hide mouse') and display.controller.is_live: command_line_options += ' --mouse-hide-timeout=0' display.vlc_instance = vlc.Instance(command_line_options) # creating an empty vlc media player display.vlc_media_player = display.vlc_instance.media_player_new() display.vlc_widget.resize(display.size()) display.vlc_widget.raise_() display.vlc_widget.hide() # The media player has to be 'connected' to the QFrame. # (otherwise a video would be displayed in it's own window) # This is platform specific! # You have to give the id of the QFrame (or similar object) # to vlc, different platforms have different functions for this. win_id = int(display.vlc_widget.winId()) if is_win(): display.vlc_media_player.set_hwnd(win_id) elif is_macosx(): # We have to use 'set_nsobject' since Qt5 on OSX uses Cocoa # framework and not the old Carbon. display.vlc_media_player.set_nsobject(win_id) else: # for Linux/*BSD using the X Server display.vlc_media_player.set_xwindow(win_id) self.has_own_widget = True
def _get_os_dir_path(dir_type): """ Return a path based on which OS and environment we are running in. """ # If running from source, return the language directory from the source directory if dir_type == AppLocation.LanguageDir: directory = os.path.abspath(os.path.join(os.path.dirname(openlp.__file__), '..', 'resources')) if os.path.exists(directory): return directory if is_win(): if dir_type == AppLocation.DataDir: return os.path.join(str(os.getenv('APPDATA')), 'openlp-paul', 'data') elif dir_type == AppLocation.LanguageDir: return os.path.dirname(openlp.__file__) return os.path.join(str(os.getenv('APPDATA')), 'openlp-paul') elif is_macosx(): if dir_type == AppLocation.DataDir: return os.path.join(str(os.getenv('HOME')), 'Library', 'Application Support', 'openlp-paul', 'Data') elif dir_type == AppLocation.LanguageDir: return os.path.dirname(openlp.__file__) return os.path.join(str(os.getenv('HOME')), 'Library', 'Application Support', 'openlp-paul') else: if dir_type == AppLocation.LanguageDir: for prefix in ['/usr/local', '/usr']: directory = os.path.join(prefix, 'share', 'openlp-paul') if os.path.exists(directory): return directory return os.path.join('/usr', 'share', 'openlp-paul') if XDG_BASE_AVAILABLE: if dir_type == AppLocation.DataDir: return os.path.join(str(BaseDirectory.xdg_data_home), 'openlp-paul') elif dir_type == AppLocation.CacheDir: return os.path.join(str(BaseDirectory.xdg_cache_home), 'openlp-paul') if dir_type == AppLocation.DataDir: return os.path.join(str(os.getenv('HOME')), '.openlp-paul', 'data') return os.path.join(str(os.getenv('HOME')), '.openlp-paul')
def event(self, event): """ Enables platform specific event handling i.e. direct file opening on OS X :param event: The event """ if event.type() == QtCore.QEvent.FileOpen: file_name = event.file() log.debug('Got open file event for %s!', file_name) self.args.insert(0, file_name) return True # Mac OS X should restore app window when user clicked on the OpenLP icon # in the Dock bar. However, OpenLP consists of multiple windows and this # does not work. This workaround fixes that. # The main OpenLP window is restored when it was previously minimized. elif event.type() == QtCore.QEvent.ApplicationActivate: if is_macosx() and hasattr(self, 'main_window'): if self.main_window.isMinimized(): # Copied from QWidget.setWindowState() docs on how to restore and activate a minimized window # while preserving its maximized and/or full-screen state. self.main_window.setWindowState(self.main_window.windowState() & ~QtCore.Qt.WindowMinimized | QtCore.Qt.WindowActive) return True return QtGui.QApplication.event(self, event)
def create_action(parent, name, **kwargs): """ Return an action with the object name set and the given parameters. :param parent: A QtCore.QObject for the actions parent (required). :param name: A string which is set as object name (required). :param kwargs: ``text`` A string for the action text. ``icon`` Either a QIcon, a resource string, or a file location string for the action icon. ``tooltip`` A string for the action tool tip. ``statustip`` A string for the action status tip. ``checked`` A bool for the state. If ``None`` the Action is not checkable. ``enabled`` False in case the action should be disabled. ``visible`` False in case the action should be hidden. ``separator`` True in case the action will be considered a separator. ``data`` The action's data. ``can_shortcuts`` Capability stating if this action can have shortcuts. If ``True`` the action is added to shortcut dialog otherwise it it not. Define your shortcut in the :class:`~openlp.core.lib.Settings` class. *Note*: When *not* ``True`` you *must not* set a shortcuts at all. ``context`` A context for the shortcut execution. ``category`` A category the action should be listed in the shortcut dialog. ``triggers`` A slot which is connected to the actions ``triggered()`` slot. """ action = QtWidgets.QAction(parent) action.setObjectName(name) if is_macosx(): action.setIconVisibleInMenu(False) if kwargs.get('text'): action.setText(kwargs.pop('text')) if kwargs.get('icon'): action.setIcon(build_icon(kwargs.pop('icon'))) if kwargs.get('tooltip'): action.setToolTip(kwargs.pop('tooltip')) if kwargs.get('statustip'): action.setStatusTip(kwargs.pop('statustip')) if kwargs.get('checked') is not None: action.setCheckable(True) action.setChecked(kwargs.pop('checked')) if not kwargs.pop('enabled', True): action.setEnabled(False) if not kwargs.pop('visible', True): action.setVisible(False) if kwargs.pop('separator', False): action.setSeparator(True) if 'data' in kwargs: action.setData(kwargs.pop('data')) if kwargs.pop('can_shortcuts', False): action_list = ActionList.get_instance() action_list.add_action(action, kwargs.pop('category', None)) if 'context' in kwargs: action.setShortcutContext(kwargs.pop('context')) if kwargs.get('triggers'): action.triggered.connect(kwargs.pop('triggers')) for key in list(kwargs.keys()): if key not in ['text', 'icon', 'tooltip', 'statustip', 'checked', 'can_shortcuts', 'category', 'triggers']: log.warning('Parameter {key} was not consumed in create_action().'.format(key=key)) return action
def setupUi(self, theme_wizard): """ Set up the UI """ theme_wizard.setObjectName('OpenLP.ThemeWizard') theme_wizard.setWindowIcon(build_icon(u':/icon/openlp-logo.svg')) theme_wizard.setModal(True) theme_wizard.setOptions(QtGui.QWizard.IndependentPages | QtGui.QWizard.NoBackButtonOnStartPage | QtGui.QWizard.HaveCustomButton1) if is_macosx(): theme_wizard.setPixmap(QtGui.QWizard.BackgroundPixmap, QtGui.QPixmap(':/wizards/openlp-osx-wizard.png')) theme_wizard.resize(646, 400) else: theme_wizard.setWizardStyle(QtGui.QWizard.ModernStyle) self.spacer = QtGui.QSpacerItem(10, 0, QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Minimum) # Welcome Page add_welcome_page(theme_wizard, ':/wizards/wizard_createtheme.bmp') # Background Page self.background_page = QtGui.QWizardPage() self.background_page.setObjectName('background_page') self.background_layout = QtGui.QVBoxLayout(self.background_page) self.background_layout.setObjectName('background_layout') self.background_type_layout = QtGui.QFormLayout() self.background_type_layout.setObjectName('background_type_layout') self.background_label = QtGui.QLabel(self.background_page) self.background_label.setObjectName('background_label') self.background_combo_box = QtGui.QComboBox(self.background_page) self.background_combo_box.addItems(['', '', '', '']) self.background_combo_box.setObjectName('background_combo_box') self.background_type_layout.addRow(self.background_label, self.background_combo_box) self.background_type_layout.setItem(1, QtGui.QFormLayout.LabelRole, self.spacer) self.background_layout.addLayout(self.background_type_layout) self.background_stack = QtGui.QStackedLayout() self.background_stack.setObjectName('background_stack') self.color_widget = QtGui.QWidget(self.background_page) self.color_widget.setObjectName('color_widget') self.color_layout = QtGui.QFormLayout(self.color_widget) self.color_layout.setMargin(0) self.color_layout.setObjectName('color_layout') self.color_label = QtGui.QLabel(self.color_widget) self.color_label.setObjectName('color_label') self.color_button = ColorButton(self.color_widget) self.color_button.setObjectName('color_button') self.color_layout.addRow(self.color_label, self.color_button) self.color_layout.setItem(1, QtGui.QFormLayout.LabelRole, self.spacer) self.background_stack.addWidget(self.color_widget) self.gradient_widget = QtGui.QWidget(self.background_page) self.gradient_widget.setObjectName('Gradient_widget') self.gradient_layout = QtGui.QFormLayout(self.gradient_widget) self.gradient_layout.setMargin(0) self.gradient_layout.setObjectName('gradient_layout') self.gradient_start_label = QtGui.QLabel(self.gradient_widget) self.gradient_start_label.setObjectName('gradient_start_label') self.gradient_start_button = ColorButton(self.gradient_widget) self.gradient_start_button.setObjectName('gradient_start_button') self.gradient_layout.addRow(self.gradient_start_label, self.gradient_start_button) self.gradient_end_label = QtGui.QLabel(self.gradient_widget) self.gradient_end_label.setObjectName('gradient_end_label') self.gradient_end_button = ColorButton(self.gradient_widget) self.gradient_end_button.setObjectName('gradient_end_button') self.gradient_layout.addRow(self.gradient_end_label, self.gradient_end_button) self.gradient_type_label = QtGui.QLabel(self.gradient_widget) self.gradient_type_label.setObjectName('Gradient_type_label') self.gradient_combo_box = QtGui.QComboBox(self.gradient_widget) self.gradient_combo_box.setObjectName('gradient_combo_box') self.gradient_combo_box.addItems(['', '', '', '', '']) self.gradient_layout.addRow(self.gradient_type_label, self.gradient_combo_box) self.gradient_layout.setItem(3, QtGui.QFormLayout.LabelRole, self.spacer) self.background_stack.addWidget(self.gradient_widget) self.image_widget = QtGui.QWidget(self.background_page) self.image_widget.setObjectName('image_widget') self.image_layout = QtGui.QFormLayout(self.image_widget) self.image_layout.setMargin(0) self.image_layout.setObjectName('image_layout') self.image_color_label = QtGui.QLabel(self.color_widget) self.image_color_label.setObjectName('image_color_label') self.image_color_button = ColorButton(self.color_widget) self.image_color_button.setObjectName('image_color_button') self.image_layout.addRow(self.image_color_label, self.image_color_button) self.image_label = QtGui.QLabel(self.image_widget) self.image_label.setObjectName('image_label') self.image_file_layout = QtGui.QHBoxLayout() self.image_file_layout.setObjectName('image_file_layout') self.image_file_edit = QtGui.QLineEdit(self.image_widget) self.image_file_edit.setObjectName('image_file_edit') self.image_file_layout.addWidget(self.image_file_edit) self.image_browse_button = QtGui.QToolButton(self.image_widget) self.image_browse_button.setObjectName('image_browse_button') self.image_browse_button.setIcon(build_icon(':/general/general_open.png')) self.image_file_layout.addWidget(self.image_browse_button) self.image_layout.addRow(self.image_label, self.image_file_layout) self.image_layout.setItem(2, QtGui.QFormLayout.LabelRole, self.spacer) self.background_stack.addWidget(self.image_widget) self.transparent_widget = QtGui.QWidget(self.background_page) self.transparent_widget.setObjectName('TransparentWidget') self.transparent_layout = QtGui.QFormLayout(self.transparent_widget) self.transparent_layout.setMargin(0) self.transparent_layout.setObjectName('Transparent_layout') self.background_stack.addWidget(self.transparent_widget) self.background_layout.addLayout(self.background_stack) theme_wizard.addPage(self.background_page) # Main Area Page self.main_area_page = QtGui.QWizardPage() self.main_area_page.setObjectName('main_area_page') self.main_area_layout = QtGui.QFormLayout(self.main_area_page) self.main_area_layout.setObjectName('main_area_layout') self.main_font_label = QtGui.QLabel(self.main_area_page) self.main_font_label.setObjectName('main_font_label') self.main_font_combo_box = QtGui.QFontComboBox(self.main_area_page) self.main_font_combo_box.setObjectName('main_font_combo_box') self.main_area_layout.addRow(self.main_font_label, self.main_font_combo_box) self.main_color_label = QtGui.QLabel(self.main_area_page) self.main_color_label.setObjectName('main_color_label') self.main_properties_layout = QtGui.QHBoxLayout() self.main_properties_layout.setObjectName('main_properties_layout') self.main_color_button = ColorButton(self.main_area_page) self.main_color_button.setObjectName('main_color_button') self.main_properties_layout.addWidget(self.main_color_button) self.main_properties_layout.addSpacing(20) self.main_bold_check_box = QtGui.QCheckBox(self.main_area_page) self.main_bold_check_box.setObjectName('main_bold_check_box') self.main_properties_layout.addWidget(self.main_bold_check_box) self.main_properties_layout.addSpacing(20) self.main_italics_check_box = QtGui.QCheckBox(self.main_area_page) self.main_italics_check_box.setObjectName('MainItalicsCheckBox') self.main_properties_layout.addWidget(self.main_italics_check_box) self.main_area_layout.addRow(self.main_color_label, self.main_properties_layout) self.main_size_label = QtGui.QLabel(self.main_area_page) self.main_size_label.setObjectName('main_size_label') self.main_size_layout = QtGui.QHBoxLayout() self.main_size_layout.setObjectName('main_size_layout') self.main_size_spin_box = QtGui.QSpinBox(self.main_area_page) self.main_size_spin_box.setMaximum(999) self.main_size_spin_box.setValue(16) self.main_size_spin_box.setObjectName('main_size_spin_box') self.main_size_layout.addWidget(self.main_size_spin_box) self.main_line_count_label = QtGui.QLabel(self.main_area_page) self.main_line_count_label.setObjectName('main_line_count_label') self.main_size_layout.addWidget(self.main_line_count_label) self.main_area_layout.addRow(self.main_size_label, self.main_size_layout) self.line_spacing_label = QtGui.QLabel(self.main_area_page) self.line_spacing_label.setObjectName('line_spacing_label') self.line_spacing_spin_box = QtGui.QSpinBox(self.main_area_page) self.line_spacing_spin_box.setMinimum(-250) self.line_spacing_spin_box.setMaximum(250) self.line_spacing_spin_box.setObjectName('line_spacing_spin_box') self.main_area_layout.addRow(self.line_spacing_label, self.line_spacing_spin_box) self.outline_check_box = QtGui.QCheckBox(self.main_area_page) self.outline_check_box.setObjectName('outline_check_box') self.outline_layout = QtGui.QHBoxLayout() self.outline_layout.setObjectName('outline_layout') self.outline_color_button = ColorButton(self.main_area_page) self.outline_color_button.setEnabled(False) self.outline_color_button.setObjectName('Outline_color_button') self.outline_layout.addWidget(self.outline_color_button) self.outline_layout.addSpacing(20) self.outline_size_label = QtGui.QLabel(self.main_area_page) self.outline_size_label.setObjectName('outline_size_label') self.outline_layout.addWidget(self.outline_size_label) self.outline_size_spin_box = QtGui.QSpinBox(self.main_area_page) self.outline_size_spin_box.setEnabled(False) self.outline_size_spin_box.setObjectName('outline_size_spin_box') self.outline_layout.addWidget(self.outline_size_spin_box) self.main_area_layout.addRow(self.outline_check_box, self.outline_layout) self.shadow_check_box = QtGui.QCheckBox(self.main_area_page) self.shadow_check_box.setObjectName('shadow_check_box') self.shadow_layout = QtGui.QHBoxLayout() self.shadow_layout.setObjectName('shadow_layout') self.shadow_color_button = ColorButton(self.main_area_page) self.shadow_color_button.setEnabled(False) self.shadow_color_button.setObjectName('shadow_color_button') self.shadow_layout.addWidget(self.shadow_color_button) self.shadow_layout.addSpacing(20) self.shadow_size_label = QtGui.QLabel(self.main_area_page) self.shadow_size_label.setObjectName('shadow_size_label') self.shadow_layout.addWidget(self.shadow_size_label) self.shadow_size_spin_box = QtGui.QSpinBox(self.main_area_page) self.shadow_size_spin_box.setEnabled(False) self.shadow_size_spin_box.setObjectName('shadow_size_spin_box') self.shadow_layout.addWidget(self.shadow_size_spin_box) self.main_area_layout.addRow(self.shadow_check_box, self.shadow_layout) theme_wizard.addPage(self.main_area_page) # Footer Area Page self.footer_area_page = QtGui.QWizardPage() self.footer_area_page.setObjectName('footer_area_page') self.footer_area_layout = QtGui.QFormLayout(self.footer_area_page) self.footer_area_layout.setObjectName('footer_area_layout') self.footer_font_label = QtGui.QLabel(self.footer_area_page) self.footer_font_label.setObjectName('FooterFontLabel') self.footer_font_combo_box = QtGui.QFontComboBox(self.footer_area_page) self.footer_font_combo_box.setObjectName('footer_font_combo_box') self.footer_area_layout.addRow(self.footer_font_label, self.footer_font_combo_box) self.footer_color_label = QtGui.QLabel(self.footer_area_page) self.footer_color_label.setObjectName('footer_color_label') self.footer_color_button = ColorButton(self.footer_area_page) self.footer_color_button.setObjectName('footer_color_button') self.footer_area_layout.addRow(self.footer_color_label, self.footer_color_button) self.footer_size_label = QtGui.QLabel(self.footer_area_page) self.footer_size_label.setObjectName('footer_size_label') self.footer_size_spin_box = QtGui.QSpinBox(self.footer_area_page) self.footer_size_spin_box.setMaximum(999) self.footer_size_spin_box.setValue(10) self.footer_size_spin_box.setObjectName('FooterSizeSpinBox') self.footer_area_layout.addRow(self.footer_size_label, self.footer_size_spin_box) self.footer_area_layout.setItem(3, QtGui.QFormLayout.LabelRole, self.spacer) theme_wizard.addPage(self.footer_area_page) # Alignment Page self.alignment_page = QtGui.QWizardPage() self.alignment_page.setObjectName('alignment_page') self.alignment_layout = QtGui.QFormLayout(self.alignment_page) self.alignment_layout.setObjectName('alignment_layout') self.horizontal_label = QtGui.QLabel(self.alignment_page) self.horizontal_label.setObjectName('horizontal_label') self.horizontal_combo_box = QtGui.QComboBox(self.alignment_page) self.horizontal_combo_box.addItems(['', '', '', '']) self.horizontal_combo_box.setObjectName('horizontal_combo_box') self.alignment_layout.addRow(self.horizontal_label, self.horizontal_combo_box) self.vertical_label, self.vertical_combo_box = create_valign_selection_widgets(self.alignment_page) self.vertical_label.setObjectName('vertical_label') self.vertical_combo_box.setObjectName('vertical_combo_box') self.alignment_layout.addRow(self.vertical_label, self.vertical_combo_box) self.transitions_label = QtGui.QLabel(self.alignment_page) self.transitions_label.setObjectName('transitions_label') self.transitions_check_box = QtGui.QCheckBox(self.alignment_page) self.transitions_check_box.setObjectName('transitions_check_box') self.alignment_layout.addRow(self.transitions_label, self.transitions_check_box) self.alignment_layout.setItem(3, QtGui.QFormLayout.LabelRole, self.spacer) theme_wizard.addPage(self.alignment_page) # Area Position Page self.area_position_page = QtGui.QWizardPage() self.area_position_page.setObjectName('area_position_page') self.area_position_layout = QtGui.QHBoxLayout(self.area_position_page) self.area_position_layout.setObjectName('area_position_layout') self.main_position_group_box = QtGui.QGroupBox(self.area_position_page) self.main_position_group_box.setObjectName('main_position_group_box') self.main_position_layout = QtGui.QFormLayout(self.main_position_group_box) self.main_position_layout.setObjectName('main_position_layout') self.main_position_check_box = QtGui.QCheckBox(self.main_position_group_box) self.main_position_check_box.setObjectName('main_position_check_box') self.main_position_layout.addRow(self.main_position_check_box) self.main_position_method_label = QtGui.QLabel(self.main_position_group_box) self.main_position_method_label.setObjectName('main_position_method_label') self.main_position_method = QtGui.QComboBox(self.main_position_group_box) self.main_position_method.addItems(['','','']) self.main_position_method.setObjectName('main_position_method') self.main_position_layout.addRow(self.main_position_method_label, self.main_position_method) self.main_x_label = QtGui.QLabel(self.main_position_group_box) self.main_x_label.setObjectName('main_x_label') self.main_x_spin_box = QtGui.QSpinBox(self.main_position_group_box) self.main_x_spin_box.setMaximum(9999) self.main_x_spin_box.setObjectName('main_x_spin_box') self.main_position_layout.addRow(self.main_x_label, self.main_x_spin_box) self.main_y_label = QtGui.QLabel(self.main_position_group_box) self.main_y_label.setObjectName('main_y_label') self.main_y_spin_box = QtGui.QSpinBox(self.main_position_group_box) self.main_y_spin_box.setMaximum(9999) self.main_y_spin_box.setObjectName('main_y_spin_box') self.main_position_layout.addRow(self.main_y_label, self.main_y_spin_box) self.main_width_label = QtGui.QLabel(self.main_position_group_box) self.main_width_label.setObjectName('main_width_label') self.main_width_spin_box = QtGui.QSpinBox(self.main_position_group_box) self.main_width_spin_box.setMaximum(9999) self.main_width_spin_box.setObjectName('main_width_spin_box') self.main_position_layout.addRow(self.main_width_label, self.main_width_spin_box) self.main_height_label = QtGui.QLabel(self.main_position_group_box) self.main_height_label.setObjectName('main_height_label') self.main_height_spin_box = QtGui.QSpinBox(self.main_position_group_box) self.main_height_spin_box.setMaximum(9999) self.main_height_spin_box.setObjectName('main_height_spin_box') self.main_position_layout.addRow(self.main_height_label, self.main_height_spin_box) self.area_position_layout.addWidget(self.main_position_group_box) self.footer_position_group_box = QtGui.QGroupBox(self.area_position_page) self.footer_position_group_box.setObjectName('footer_position_group_box') self.footer_position_layout = QtGui.QFormLayout(self.footer_position_group_box) self.footer_position_layout.setObjectName('footer_position_layout') self.footer_position_check_box = QtGui.QCheckBox(self.footer_position_group_box) self.footer_position_check_box.setObjectName('footer_position_check_box') self.footer_position_layout.addRow(self.footer_position_check_box) self.footer_x_label = QtGui.QLabel(self.footer_position_group_box) self.footer_x_label.setObjectName('footer_x_label') self.footer_x_spin_box = QtGui.QSpinBox(self.footer_position_group_box) self.footer_x_spin_box.setMaximum(9999) self.footer_x_spin_box.setObjectName('footer_x_spin_box') self.footer_position_layout.addRow(self.footer_x_label, self.footer_x_spin_box) self.footer_y_label = QtGui.QLabel(self.footer_position_group_box) self.footer_y_label.setObjectName('footer_y_label') self.footer_y_spin_box = QtGui.QSpinBox(self.footer_position_group_box) self.footer_y_spin_box.setMaximum(9999) self.footer_y_spin_box.setObjectName('footer_y_spin_box') self.footer_position_layout.addRow(self.footer_y_label, self.footer_y_spin_box) self.footer_width_label = QtGui.QLabel(self.footer_position_group_box) self.footer_width_label.setObjectName('footer_width_label') self.footer_width_spin_box = QtGui.QSpinBox(self.footer_position_group_box) self.footer_width_spin_box.setMaximum(9999) self.footer_width_spin_box.setObjectName('footer_width_spin_box') self.footer_position_layout.addRow(self.footer_width_label, self.footer_width_spin_box) self.footer_height_label = QtGui.QLabel(self.footer_position_group_box) self.footer_height_label.setObjectName('footer_height_label') self.footer_height_spin_box = QtGui.QSpinBox(self.footer_position_group_box) self.footer_height_spin_box.setMaximum(9999) self.footer_height_spin_box.setObjectName('footer_height_spin_box') self.footer_position_layout.addRow(self.footer_height_label, self.footer_height_spin_box) self.area_position_layout.addWidget(self.footer_position_group_box) theme_wizard.addPage(self.area_position_page) # Preview Page self.preview_page = QtGui.QWizardPage() self.preview_page.setObjectName('preview_page') self.preview_layout = QtGui.QVBoxLayout(self.preview_page) self.preview_layout.setObjectName('preview_layout') self.theme_name_layout = QtGui.QFormLayout() self.theme_name_layout.setObjectName('theme_name_layout') self.theme_name_label = QtGui.QLabel(self.preview_page) self.theme_name_label.setObjectName('theme_name_label') self.theme_name_edit = QtGui.QLineEdit(self.preview_page) self.theme_name_edit.setValidator(QtGui.QRegExpValidator(QtCore.QRegExp(r'[^/\\?*|<>\[\]":<>+%]+'), self)) self.theme_name_edit.setObjectName('ThemeNameEdit') self.theme_name_layout.addRow(self.theme_name_label, self.theme_name_edit) self.preview_layout.addLayout(self.theme_name_layout) self.preview_area = QtGui.QWidget(self.preview_page) self.preview_area.setObjectName('PreviewArea') self.preview_area_layout = QtGui.QGridLayout(self.preview_area) self.preview_area_layout.setMargin(0) self.preview_area_layout.setColumnStretch(0, 1) self.preview_area_layout.setRowStretch(0, 1) self.preview_area_layout.setObjectName('preview_area_layout') self.preview_box_label = QtGui.QLabel(self.preview_area) self.preview_box_label.setFrameShape(QtGui.QFrame.Box) self.preview_box_label.setScaledContents(True) self.preview_box_label.setObjectName('preview_box_label') self.preview_area_layout.addWidget(self.preview_box_label) self.preview_layout.addWidget(self.preview_area) theme_wizard.addPage(self.preview_page) self.retranslateUi(theme_wizard) QtCore.QObject.connect(self.background_combo_box, QtCore.SIGNAL('currentIndexChanged(int)'), self.background_stack, QtCore.SLOT('setCurrentIndex(int)')) QtCore.QObject.connect(self.outline_check_box, QtCore.SIGNAL('toggled(bool)'), self.outline_color_button, QtCore.SLOT('setEnabled(bool)')) QtCore.QObject.connect(self.outline_check_box, QtCore.SIGNAL('toggled(bool)'), self.outline_size_spin_box, QtCore.SLOT('setEnabled(bool)')) QtCore.QObject.connect(self.shadow_check_box, QtCore.SIGNAL('toggled(bool)'), self.shadow_color_button, QtCore.SLOT('setEnabled(bool)')) QtCore.QObject.connect(self.shadow_check_box, QtCore.SIGNAL('toggled(bool)'), self.shadow_size_spin_box, QtCore.SLOT('setEnabled(bool)')) QtCore.QObject.connect(self.main_position_check_box, QtCore.SIGNAL('toggled(bool)'), self.main_position_method, QtCore.SLOT('setDisabled(bool)')) QtCore.QObject.connect(self.main_position_check_box, QtCore.SIGNAL('toggled(bool)'), self.main_x_spin_box, QtCore.SLOT('setDisabled(bool)')) QtCore.QObject.connect(self.main_position_check_box, QtCore.SIGNAL('toggled(bool)'), self.main_y_spin_box, QtCore.SLOT('setDisabled(bool)')) QtCore.QObject.connect(self.main_position_check_box, QtCore.SIGNAL('toggled(bool)'), self.main_width_spin_box, QtCore.SLOT('setDisabled(bool)')) QtCore.QObject.connect(self.main_position_check_box, QtCore.SIGNAL('toggled(bool)'), self.main_height_spin_box, QtCore.SLOT('setDisabled(bool)')) QtCore.QObject.connect(self.footer_position_check_box, QtCore.SIGNAL('toggled(bool)'), self.footer_x_spin_box, QtCore.SLOT('setDisabled(bool)')) QtCore.QObject.connect(self.footer_position_check_box, QtCore.SIGNAL('toggled(bool)'), self.footer_y_spin_box, QtCore.SLOT('setDisabled(bool)')) QtCore.QObject.connect(self.footer_position_check_box, QtCore.SIGNAL('toggled(bool)'), self.footer_width_spin_box, QtCore.SLOT('setDisabled(bool)')) QtCore.QObject.connect(self.footer_position_check_box, QtCore.SIGNAL('toggled(bool)'), self.footer_height_spin_box, QtCore.SLOT('setDisabled(bool)'))
def main(args=None): """ The main function which parses command line options and then runs :param args: Some args """ args = parse_options(args) qt_args = [] if args and args.loglevel.lower() in ['d', 'debug']: log.setLevel(logging.DEBUG) elif args and args.loglevel.lower() in ['w', 'warning']: log.setLevel(logging.WARNING) else: log.setLevel(logging.INFO) # Throw the rest of the arguments at Qt, just in case. qt_args.extend(args.rargs) # Bug #1018855: Set the WM_CLASS property in X11 if not is_win() and not is_macosx(): qt_args.append('OpenLP') # Initialise the resources qInitResources() # Now create and actually run the application. application = OpenLP(qt_args) application.setOrganizationName('OpenLP') application.setOrganizationDomain('openlp.org') application.setAttribute(QtCore.Qt.AA_UseHighDpiPixmaps, True) application.setAttribute(QtCore.Qt.AA_DontCreateNativeWidgetSiblings, True) if args.portable: application.setApplicationName('OpenLPPortable') Settings.setDefaultFormat(Settings.IniFormat) # Get location OpenLPPortable.ini portable_path = (AppLocation.get_directory(AppLocation.AppDir) / '..' / '..').resolve() data_path = portable_path / 'Data' set_up_logging(portable_path / 'Other') log.info('Running portable') portable_settings_path = data_path / 'OpenLP.ini' # Make this our settings file log.info('INI file: {name}'.format(name=portable_settings_path)) Settings.set_filename(str(portable_settings_path)) portable_settings = Settings() # Set our data path log.info('Data path: {name}'.format(name=data_path)) # Point to our data path portable_settings.setValue('advanced/data path', data_path) portable_settings.setValue('advanced/is portable', True) portable_settings.sync() else: application.setApplicationName('OpenLP') set_up_logging(AppLocation.get_directory(AppLocation.CacheDir)) Registry.create() Registry().register('application', application) Registry().set_flag('no_web_server', args.no_web_server) application.setApplicationVersion(get_version()['version']) # Check if an instance of OpenLP is already running. Quit if there is a running instance and the user only wants one server = Server() if server.is_another_instance_running(): application.is_already_running() server.post_to_server(qt_args) sys.exit() else: server.start_server() application.server = server # If the custom data path is missing and the user wants to restore the data path, quit OpenLP. if application.is_data_path_missing(): server.close_server() sys.exit() # Upgrade settings. settings = Settings() if settings.can_upgrade(): now = datetime.now() # Only back up if OpenLP has previously run. if settings.value('core/has run wizard'): back_up_path = AppLocation.get_data_path() / ( now.strftime('%Y-%m-%d %H-%M') + '.conf') log.info( 'Settings about to be upgraded. Existing settings are being backed up to {back_up_path}' .format(back_up_path=back_up_path)) QtWidgets.QMessageBox.information( None, translate('OpenLP', 'Settings Upgrade'), translate( 'OpenLP', 'Your settings are about to be upgraded. A backup will be created at ' '{back_up_path}').format(back_up_path=back_up_path)) settings.export(back_up_path) settings.upgrade_settings() # First time checks in settings if not Settings().value('core/has run wizard'): if not FirstTimeLanguageForm().exec(): # if cancel then stop processing server.close_server() sys.exit() # i18n Set Language language = LanguageManager.get_language() translators = LanguageManager.get_translators(language) for translator in translators: if not translator.isEmpty(): application.installTranslator(translator) if not translators: log.debug('Could not find translators.') if args and not args.no_error_form: sys.excepthook = application.hook_exception sys.exit(application.run(qt_args))
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for # # more details. # # # # You should have received a copy of the GNU General Public License along # # with this program; if not, write to the Free Software Foundation, Inc., 59 # # Temple Place, Suite 330, Boston, MA 02111-1307 USA # ############################################################################### import sys import multiprocessing from openlp.core.common import is_win, is_macosx from openlp.core import main if __name__ == '__main__': """ Instantiate and run the application. """ # Add support for using multiprocessing from frozen Windows executable (built using PyInstaller), # see https://docs.python.org/3/library/multiprocessing.html#multiprocessing.freeze_support if is_win(): multiprocessing.freeze_support() # Mac OS X passes arguments like '-psn_XXXX' to the application. This argument is actually a process serial number. # However, this causes a conflict with other OpenLP arguments. Since we do not use this argument we can delete it # to avoid any potential conflicts. if is_macosx(): sys.argv = [x for x in sys.argv if not x.startswith('-psn')] main()
# # # You should have received a copy of the GNU General Public License along # # with this program; if not, write to the Free Software Foundation, Inc., 59 # # Temple Place, Suite 330, Boston, MA 02111-1307 USA # ############################################################################### """ The :mod:`openlp.core.common.applocation` module provides an utility for OpenLP receiving the data path etc. """ import logging import os import sys from openlp.core.common import Settings, is_win, is_macosx if not is_win() and not is_macosx(): try: from xdg import BaseDirectory XDG_BASE_AVAILABLE = True except ImportError: XDG_BASE_AVAILABLE = False import openlp from openlp.core.common import check_directory_exists, get_frozen_path log = logging.getLogger(__name__) class AppLocation(object): """
from tempfile import mkdtemp from unittest import TestCase, SkipTest from unittest.mock import MagicMock, patch, call from openlp.core.common import is_macosx from openlp.core.common.path import Path from openlp.plugins.presentations.lib.maclocontroller import MacLOController, MacLODocument from tests.helpers.testmixin import TestMixin from tests.utils.constants import TEST_RESOURCES_PATH try: import Pyro4 # noqa: F401 except ImportError: raise SkipTest('Pyro4 is not installed, skipping testing the Mac LibreOffice controller') if not is_macosx(): raise SkipTest('Not on macOS, skipping testing the Mac LibreOffice controller') class TestMacLOController(TestCase, TestMixin): """ Test the MacLOController Class """ def setUp(self): """ Set up the patches and mocks need for all tests. """ self.setup_application() self.build_settings() self.mock_plugin = MagicMock()
from subprocess import Popen from openlp.core.common import delete_file, is_macosx from openlp.core.common.applocation import AppLocation from openlp.core.common.mixins import LogMixin from openlp.core.common.path import Path from openlp.core.common.registry import Registry from openlp.core.display.screens import ScreenList from openlp.plugins.presentations.lib.presentationcontroller import PresentationController, PresentationDocument LIBREOFFICE_PATH = Path('/Applications/LibreOffice.app') LIBREOFFICE_PYTHON = LIBREOFFICE_PATH / 'Contents' / 'Resources' / 'python' try: from Pyro4 import Proxy if is_macosx() and LIBREOFFICE_PATH.exists(): macuno_available = True else: macuno_available = False except ImportError: macuno_available = False if macuno_available: # If this controller is good to go, register the serializer classes with Pyro4 from openlp.plugins.presentations.lib.serializers import register_classes register_classes() log = logging.getLogger(__name__) class MacLOController(PresentationController, LogMixin):
def setup_ui(self, first_time_wizard): """ Set up the UI. :param first_time_wizard: The wizard form """ first_time_wizard.setObjectName('first_time_wizard') first_time_wizard.setWindowIcon(build_icon(':/icon/openlp-logo.svg')) first_time_wizard.resize(550, 386) first_time_wizard.setModal(True) first_time_wizard.setOptions(QtWidgets.QWizard.IndependentPages | QtWidgets.QWizard.NoBackButtonOnStartPage | QtWidgets.QWizard.NoBackButtonOnLastPage | QtWidgets.QWizard.HaveCustomButton1 | QtWidgets.QWizard.HaveCustomButton2) if is_macosx(): first_time_wizard.setPixmap(QtWidgets.QWizard.BackgroundPixmap, QtGui.QPixmap(':/wizards/openlp-osx-wizard.png')) first_time_wizard.resize(634, 386) else: first_time_wizard.setWizardStyle(QtWidgets.QWizard.ModernStyle) self.finish_button = self.button(QtWidgets.QWizard.FinishButton) self.no_internet_finish_button = self.button(QtWidgets.QWizard.CustomButton1) self.cancel_button = self.button(QtWidgets.QWizard.CancelButton) self.no_internet_cancel_button = self.button(QtWidgets.QWizard.CustomButton2) self.next_button = self.button(QtWidgets.QWizard.NextButton) self.back_button = self.button(QtWidgets.QWizard.BackButton) add_welcome_page(first_time_wizard, ':/wizards/wizard_firsttime.bmp') # The download page self.download_page = QtWidgets.QWizardPage() self.download_page.setObjectName('download_page') self.download_layout = QtWidgets.QVBoxLayout(self.download_page) self.download_layout.setContentsMargins(48, 48, 48, 48) self.download_layout.setObjectName('download_layout') self.download_label = QtWidgets.QLabel(self.download_page) self.download_label.setObjectName('download_label') self.download_layout.addWidget(self.download_label) first_time_wizard.setPage(FirstTimePage.Download, self.download_page) # The "you don't have an internet connection" page. self.no_internet_page = QtWidgets.QWizardPage() self.no_internet_page.setObjectName('no_internet_page') self.no_internet_layout = QtWidgets.QVBoxLayout(self.no_internet_page) self.no_internet_layout.setContentsMargins(50, 30, 50, 40) self.no_internet_layout.setObjectName('no_internet_layout') self.no_internet_label = QtWidgets.QLabel(self.no_internet_page) self.no_internet_label.setWordWrap(True) self.no_internet_label.setObjectName('no_internet_label') self.no_internet_layout.addWidget(self.no_internet_label) first_time_wizard.setPage(FirstTimePage.NoInternet, self.no_internet_page) # The plugins page self.plugin_page = QtWidgets.QWizardPage() self.plugin_page.setObjectName('plugin_page') self.plugin_layout = QtWidgets.QVBoxLayout(self.plugin_page) self.plugin_layout.setContentsMargins(40, 15, 40, 0) self.plugin_layout.setObjectName('plugin_layout') self.songs_check_box = QtWidgets.QCheckBox(self.plugin_page) self.songs_check_box.setChecked(True) self.songs_check_box.setObjectName('songs_check_box') self.plugin_layout.addWidget(self.songs_check_box) self.custom_check_box = QtWidgets.QCheckBox(self.plugin_page) self.custom_check_box.setChecked(True) self.custom_check_box.setObjectName('custom_check_box') self.plugin_layout.addWidget(self.custom_check_box) self.bible_check_box = QtWidgets.QCheckBox(self.plugin_page) self.bible_check_box.setChecked(True) self.bible_check_box.setObjectName('bible_check_box') self.plugin_layout.addWidget(self.bible_check_box) self.image_check_box = QtWidgets.QCheckBox(self.plugin_page) self.image_check_box.setChecked(True) self.image_check_box.setObjectName('image_check_box') self.plugin_layout.addWidget(self.image_check_box) self.presentation_check_box = QtWidgets.QCheckBox(self.plugin_page) self.presentation_check_box.setChecked(True) self.presentation_check_box.setObjectName('presentation_check_box') self.plugin_layout.addWidget(self.presentation_check_box) self.media_check_box = QtWidgets.QCheckBox(self.plugin_page) self.media_check_box.setChecked(True) self.media_check_box.setObjectName('media_check_box') self.plugin_layout.addWidget(self.media_check_box) self.remote_check_box = QtWidgets.QCheckBox(self.plugin_page) self.remote_check_box.setObjectName('remote_check_box') self.plugin_layout.addWidget(self.remote_check_box) self.song_usage_check_box = QtWidgets.QCheckBox(self.plugin_page) self.song_usage_check_box.setChecked(True) self.song_usage_check_box.setObjectName('song_usage_check_box') self.plugin_layout.addWidget(self.song_usage_check_box) self.alert_check_box = QtWidgets.QCheckBox(self.plugin_page) self.alert_check_box.setChecked(True) self.alert_check_box.setObjectName('alert_check_box') self.plugin_layout.addWidget(self.alert_check_box) self.projectors_check_box = QtWidgets.QCheckBox(self.plugin_page) # If visibility setting for projector panel is True, check the box. if Settings().value('projector/show after wizard'): self.projectors_check_box.setChecked(True) self.projectors_check_box.setObjectName('projectors_check_box') self.projectors_check_box.clicked.connect(self.on_projectors_check_box_clicked) self.plugin_layout.addWidget(self.projectors_check_box) first_time_wizard.setPage(FirstTimePage.Plugins, self.plugin_page) # The song samples page self.songs_page = QtWidgets.QWizardPage() self.songs_page.setObjectName('songs_page') self.songs_layout = QtWidgets.QVBoxLayout(self.songs_page) self.songs_layout.setContentsMargins(50, 20, 50, 20) self.songs_layout.setObjectName('songs_layout') self.songs_list_widget = QtWidgets.QListWidget(self.songs_page) self.songs_list_widget.setAlternatingRowColors(True) self.songs_list_widget.setObjectName('songs_list_widget') self.songs_layout.addWidget(self.songs_list_widget) first_time_wizard.setPage(FirstTimePage.Songs, self.songs_page) # The Bible samples page self.bibles_page = QtWidgets.QWizardPage() self.bibles_page.setObjectName('bibles_page') self.bibles_layout = QtWidgets.QVBoxLayout(self.bibles_page) self.bibles_layout.setContentsMargins(50, 20, 50, 20) self.bibles_layout.setObjectName('bibles_layout') self.bibles_tree_widget = QtWidgets.QTreeWidget(self.bibles_page) self.bibles_tree_widget.setAlternatingRowColors(True) self.bibles_tree_widget.header().setVisible(False) self.bibles_tree_widget.setObjectName('bibles_tree_widget') self.bibles_layout.addWidget(self.bibles_tree_widget) first_time_wizard.setPage(FirstTimePage.Bibles, self.bibles_page) # The theme samples page self.themes_page = QtWidgets.QWizardPage() self.themes_page.setObjectName('themes_page') self.themes_layout = QtWidgets.QVBoxLayout(self.themes_page) self.themes_layout.setContentsMargins(20, 50, 20, 60) self.themes_layout.setObjectName('themes_layout') self.themes_list_widget = QtWidgets.QListWidget(self.themes_page) self.themes_list_widget.setViewMode(QtWidgets.QListView.IconMode) self.themes_list_widget.setMovement(QtWidgets.QListView.Static) self.themes_list_widget.setFlow(QtWidgets.QListView.LeftToRight) self.themes_list_widget.setSpacing(4) self.themes_list_widget.setUniformItemSizes(True) self.themes_list_widget.setIconSize(QtCore.QSize(133, 100)) self.themes_list_widget.setWrapping(False) self.themes_list_widget.setObjectName('themes_list_widget') self.themes_layout.addWidget(self.themes_list_widget) first_time_wizard.setPage(FirstTimePage.Themes, self.themes_page) # the default settings page self.defaults_page = QtWidgets.QWizardPage() self.defaults_page.setObjectName('defaults_page') self.defaults_layout = QtWidgets.QFormLayout(self.defaults_page) self.defaults_layout.setContentsMargins(50, 20, 50, 20) self.defaults_layout.setObjectName('defaults_layout') self.display_label = QtWidgets.QLabel(self.defaults_page) self.display_label.setObjectName('display_label') self.display_combo_box = QtWidgets.QComboBox(self.defaults_page) self.display_combo_box.setEditable(False) self.display_combo_box.setInsertPolicy(QtWidgets.QComboBox.NoInsert) self.display_combo_box.setObjectName('display_combo_box') self.defaults_layout.addRow(self.display_label, self.display_combo_box) self.theme_label = QtWidgets.QLabel(self.defaults_page) self.theme_label.setObjectName('theme_label') self.theme_combo_box = QtWidgets.QComboBox(self.defaults_page) self.theme_combo_box.setEditable(False) self.theme_combo_box.setInsertPolicy(QtWidgets.QComboBox.NoInsert) self.theme_combo_box.setSizeAdjustPolicy(QtWidgets.QComboBox.AdjustToContents) self.theme_combo_box.setObjectName('theme_combo_box') self.defaults_layout.addRow(self.theme_label, self.theme_combo_box) first_time_wizard.setPage(FirstTimePage.Defaults, self.defaults_page) # Progress page self.progress_page = QtWidgets.QWizardPage() self.progress_page.setObjectName('progress_page') self.progress_layout = QtWidgets.QVBoxLayout(self.progress_page) self.progress_layout.setContentsMargins(48, 48, 48, 48) self.progress_layout.setObjectName('progress_layout') self.progress_label = QtWidgets.QLabel(self.progress_page) self.progress_label.setObjectName('progress_label') self.progress_layout.addWidget(self.progress_label) self.progress_bar = QtWidgets.QProgressBar(self.progress_page) self.progress_bar.setObjectName('progress_bar') self.progress_layout.addWidget(self.progress_bar) first_time_wizard.setPage(FirstTimePage.Progress, self.progress_page) self.retranslate_ui(first_time_wizard)
Package to test the openlp.core.ui.mainwindow package. """ from unittest import TestCase, skipIf from unittest.mock import MagicMock, patch from PyQt5 import QtGui from openlp.core.state import State from openlp.core.common import is_macosx from openlp.core.common.registry import Registry from openlp.core.lib.plugin import PluginStatus from openlp.core.ui.mainwindow import MainWindow from tests.helpers.testmixin import TestMixin @skipIf(is_macosx( ), 'Skip on macOS until we can figure out what the problem is or the tests are refactored' ) class TestMainWindow(TestCase, TestMixin): def setUp(self): """ Create the UI """ Registry.create() self.registry = Registry() self.setup_application() # Mock cursor busy/normal methods. self.app.set_busy_cursor = MagicMock() self.app.set_normal_cursor = MagicMock() self.app.args = [] Registry().register('application', self.app) Registry().set_flag('no_web_server', True)
def find_optical_devices(self): """ Attempt to autodetect optical devices on the computer, and add them to the media-dropdown :return: """ # Clear list first self.media_path_combobox.clear() if is_win(): # use win api to find optical drives fso = Dispatch('scripting.filesystemobject') for drive in fso.Drives: log.debug('Drive %s has type %d' % (drive.DriveLetter, drive.DriveType)) # if type is 4, it is a cd-rom drive if drive.DriveType == 4: self.media_path_combobox.addItem('%s:\\' % drive.DriveLetter) elif is_linux(): # Get disc devices from dbus and find the ones that are optical bus = dbus.SystemBus() try: udev_manager_obj = bus.get_object('org.freedesktop.UDisks', '/org/freedesktop/UDisks') udev_manager = dbus.Interface(udev_manager_obj, 'org.freedesktop.UDisks') for dev in udev_manager.EnumerateDevices(): device_obj = bus.get_object("org.freedesktop.UDisks", dev) device_props = dbus.Interface(device_obj, dbus.PROPERTIES_IFACE) if device_props.Get('org.freedesktop.UDisks.Device', 'DeviceIsDrive'): drive_props = device_props.Get('org.freedesktop.UDisks.Device', 'DriveMediaCompatibility') if any('optical' in prop for prop in drive_props): self.media_path_combobox.addItem(device_props.Get('org.freedesktop.UDisks.Device', 'DeviceFile')) return except dbus.exceptions.DBusException: log.debug('could not use udisks, will try udisks2') udev_manager_obj = bus.get_object('org.freedesktop.UDisks2', '/org/freedesktop/UDisks2') udev_manager = dbus.Interface(udev_manager_obj, 'org.freedesktop.DBus.ObjectManager') for k, v in udev_manager.GetManagedObjects().items(): drive_info = v.get('org.freedesktop.UDisks2.Drive', {}) drive_props = drive_info.get('MediaCompatibility') if drive_props and any('optical' in prop for prop in drive_props): for device in udev_manager.GetManagedObjects().values(): if dbus.String('org.freedesktop.UDisks2.Block') in device: if device[dbus.String('org.freedesktop.UDisks2.Block')][dbus.String('Drive')] == k: block_file = '' for c in device[dbus.String('org.freedesktop.UDisks2.Block')][ dbus.String('PreferredDevice')]: if chr(c) != '\x00': block_file += chr(c) self.media_path_combobox.addItem(block_file) elif is_macosx(): # Look for DVD folders in devices to find optical devices volumes = os.listdir('/Volumes') candidates = list() for volume in volumes: if volume.startswith('.'): continue dirs = os.listdir('/Volumes/' + volume) # Detect DVD if 'VIDEO_TS' in dirs: self.media_path_combobox.addItem('/Volumes/' + volume) # Detect audio cd files = [f for f in dirs if os.path.isfile(f)] for file in files: if file.endswith('aiff'): self.media_path_combobox.addItem('/Volumes/' + volume) break
def main(args=None): """ The main function which parses command line options and then runs :param args: Some args """ (options, args) = parse_options(args) qt_args = [] if options.loglevel.lower() in ['d', 'debug']: log.setLevel(logging.DEBUG) elif options.loglevel.lower() in ['w', 'warning']: log.setLevel(logging.WARNING) else: log.setLevel(logging.INFO) if options.style: qt_args.extend(['-style', options.style]) # Throw the rest of the arguments at Qt, just in case. qt_args.extend(args) # Bug #1018855: Set the WM_CLASS property in X11 if not is_win() and not is_macosx(): qt_args.append('OpenLP') # Initialise the resources qInitResources() # Now create and actually run the application. application = OpenLP(qt_args) application.setOrganizationName('OpenLP') application.setOrganizationDomain('openlp.org') if options.portable: application.setApplicationName('OpenLPPortable') Settings.setDefaultFormat(Settings.IniFormat) # Get location OpenLPPortable.ini application_path = AppLocation.get_directory(AppLocation.AppDir) set_up_logging(os.path.abspath(os.path.join(application_path, '..', '..', 'Other'))) log.info('Running portable') portable_settings_file = os.path.abspath(os.path.join(application_path, '..', '..', 'Data', 'OpenLP.ini')) # Make this our settings file log.info('INI file: %s', portable_settings_file) Settings.set_filename(portable_settings_file) portable_settings = Settings() # Set our data path data_path = os.path.abspath(os.path.join(application_path, '..', '..', 'Data',)) log.info('Data path: %s', data_path) # Point to our data path portable_settings.setValue('advanced/data path', data_path) portable_settings.setValue('advanced/is portable', True) portable_settings.sync() else: application.setApplicationName('OpenLP') set_up_logging(AppLocation.get_directory(AppLocation.CacheDir)) Registry.create() Registry().register('application', application) application.setApplicationVersion(get_application_version()['version']) # Instance check if application.is_already_running(): sys.exit() # Remove/convert obsolete settings. Settings().remove_obsolete_settings() # First time checks in settings if not Settings().value('core/has run wizard'): if not FirstTimeLanguageForm().exec_(): # if cancel then stop processing sys.exit() # i18n Set Language language = LanguageManager.get_language() application_translator, default_translator = LanguageManager.get_translator(language) if not application_translator.isEmpty(): application.installTranslator(application_translator) if not default_translator.isEmpty(): application.installTranslator(default_translator) else: log.debug('Could not find default_translator.') if not options.no_error_form: sys.excepthook = application.hook_exception sys.exit(application.run(qt_args))