forked from openlp/openlp
Compare commits
199 Commits
Author | SHA1 | Date |
---|---|---|
Raoul Snyman | f90bb9f14a | |
Tim Bentley | 6b37313288 | |
Tim Bentley | 54cba7bec7 | |
simon.hanna@serve-me.info | 991296d8e3 | |
Raoul Snyman | 950afd08e7 | |
Simon Hanna | 80bb6f713e | |
Raoul Snyman | ca53095d5a | |
Raoul Snyman | 594af69414 | |
Simon Hanna | b371e73acc | |
Raoul Snyman | bd9eb0058a | |
Raoul Snyman | 6ca65fd758 | |
Raoul Snyman | 12cfe103b7 | |
Raoul Snyman | a62d9c6a41 | |
Raoul Snyman | ddd9d4d865 | |
Raoul Snyman | 336ec0b54f | |
Raoul Snyman | a204d8a06d | |
Raoul Snyman | 867c718c89 | |
tim.bentley@gmail.com | 419b3e46d8 | |
Tim Bentley | 62ff38d989 | |
raoul@snyman.info | 28e0399856 | |
Raoul Snyman | d9d9b4f62c | |
Raoul Snyman | 296d9534a8 | |
Raoul Snyman | cfbe212a32 | |
Raoul Snyman | dc37dad251 | |
Raoul Snyman | f759bda9e7 | |
Raoul Snyman | e5c6938577 | |
Raoul Snyman | c4162fdf1e | |
Raoul Snyman | 91a32d33a7 | |
Raoul Snyman | 808875b683 | |
Raoul Snyman | 3635cc3603 | |
Raoul Snyman | c5835a7362 | |
Raoul Snyman | 8850ab2fe3 | |
Raoul Snyman | 3ff851b064 | |
Raoul Snyman | 1ec27e8b05 | |
Raoul Snyman | 090de0d987 | |
raoul@snyman.info | 1a442e7f3c | |
raoul@snyman.info | 0d6f015eec | |
Raoul Snyman | bef7c9df13 | |
Raoul Snyman | 678a42263d | |
Raoul Snyman | 35af0af211 | |
Raoul Snyman | 9e6ffe5d43 | |
Raoul Snyman | 77d36b607c | |
Raoul Snyman | 2748f1e6c5 | |
Raoul Snyman | 70532e444a | |
Raoul Snyman | c000ba4b4f | |
Raoul Snyman | 561f272e86 | |
Tim Bentley | 90e5e3c9ed | |
Tim Bentley | 408abb06ff | |
raoul@snyman.info | ea8aa7588c | |
tim.bentley@gmail.com | 4cb992fbd7 | |
Raoul Snyman | 3fd1f43536 | |
Raoul Snyman | e3ca228723 | |
Raoul Snyman | ed8304bfb6 | |
Tim Bentley | a5c9ded757 | |
Tim Bentley | bd5dfe920b | |
raoul@snyman.info | a0fb528ba7 | |
tim.bentley@gmail.com | 793d7460f2 | |
Tim Bentley | ef205e677a | |
second@tgc.dk | ab5b69eb0c | |
Tomas Groth | 3cb1dae0f0 | |
Tomas Groth | dc5de9a54d | |
Raoul Snyman | f13f473bec | |
tim.bentley@gmail.com | 93b10bb6e7 | |
Tim Bentley | b197e62818 | |
tim.bentley@gmail.com | 5f0273fbec | |
Tim Bentley | c5c98157ba | |
Tim Bentley | 93955495a7 | |
raoul@snyman.info | 21b8aaa1ac | |
Raoul Snyman | 36008338b2 | |
Raoul Snyman | 203ebde628 | |
Raoul Snyman | 5fbbb1ae9e | |
Raoul Snyman | d47c66f833 | |
Raoul Snyman | 5620e73c90 | |
Raoul Snyman | df900b3e9e | |
Raoul Snyman | e58669e769 | |
Raoul Snyman | f4f0b3d035 | |
Raoul Snyman | 1de246e00f | |
Raoul Snyman | cd90f5ca68 | |
Raoul Snyman | 432f813edb | |
Raoul Snyman | b06542c637 | |
Raoul Snyman | e1a87cf74d | |
Raoul Snyman | 7bfdc7deef | |
Raoul Snyman | bd5056fb09 | |
Raoul Snyman | 47f20598d5 | |
Raoul Snyman | a399517e3d | |
Raoul Snyman | 27400290ba | |
Raoul Snyman | e96281c1c0 | |
Raoul Snyman | 7931eb1d17 | |
Raoul Snyman | 41593f73ff | |
Raoul Snyman | 04fe94e533 | |
tim.bentley@gmail.com | ac3859c0b8 | |
Tim Bentley | 1c75c07e4c | |
Raoul Snyman | 18c3d99f29 | |
phill.ridout@gmail.com | d466fde45c | |
Philip Ridout | 73c441399f | |
Philip Ridout | 0d54103a7a | |
Raoul Snyman | c1d4d59471 | |
raoul@snyman.info | fb585d683a | |
raoul@snyman.info | 4f36d6e12a | |
Raoul Snyman | b789a7809d | |
Raoul Snyman | 358667356f | |
Raoul Snyman | 13eb461f5b | |
Raoul Snyman | 7c1c0475c6 | |
Raoul Snyman | 8526e8287f | |
Raoul Snyman | 577a27eb66 | |
second@tgc.dk | 92ccb1681c | |
Tomas Groth | 1e3bc35390 | |
Tomas Groth | 6fcfe1aecd | |
tim.bentley@gmail.com | c62c167d66 | |
Tim Bentley | 59cc42e666 | |
raoul@snyman.info | 0ba881b5e2 | |
Raoul Snyman | 4a7d06ca33 | |
Raoul Snyman | 33c5f7674e | |
Raoul Snyman | 7d5a640a16 | |
tim.bentley@gmail.com | cdf6a4cbff | |
Tim Bentley | 9c7dbecd45 | |
tim.bentley@gmail.com | 47dff51d00 | |
Tim Bentley | a7dd65245a | |
raoul@snyman.info | 585321376d | |
raoul@snyman.info | 120b299372 | |
Raoul Snyman | d2866a1e9c | |
Raoul Snyman | c4a257c9dd | |
Raoul Snyman | 912849b22c | |
Raoul Snyman | b3893c2c1b | |
Raoul Snyman | ae93a6e33d | |
Raoul Snyman | c3bb167b32 | |
Raoul Snyman | e4468573dc | |
raoul@snyman.info | 989356c24e | |
raoul@snyman.info | 01c6cb0f8b | |
Raoul Snyman | 66d7c8fca6 | |
second@tgc.dk | 7d52332074 | |
Tomas Groth | a3a113021b | |
Raoul Snyman | 00ede5aeae | |
Raoul Snyman | f3796fa3d2 | |
Raoul Snyman | 37e92d00a2 | |
Ken Roberts | 0e8ab10daf | |
Ken Roberts | 319870aa83 | |
tim.bentley@gmail.com | b19fe349d8 | |
Tim Bentley | 3cede5cc63 | |
second@tgc.dk | a0ac63c31c | |
Ken Roberts | ecdb379082 | |
Tomas Groth | 867c32165a | |
second@tgc.dk | 9d2da2307f | |
Tomas Groth | db0cdd372b | |
Ken Roberts | 7abbb2abb3 | |
Tomas Groth | cadc21b5c0 | |
Tomas Groth | 7265065906 | |
Tomas Groth | 8f04f587ec | |
Tomas Groth | 8057d13db6 | |
raoul@snyman.info | 7ad464d43e | |
Raoul Snyman | 19a5272e5a | |
Ken Roberts | 9ba66f29da | |
Ken Roberts | 2dd4c87dde | |
Tim Bentley | 2a1786ec00 | |
Tim Bentley | a050e41589 | |
second@tgc.dk | d8d6917b7d | |
tim.bentley@gmail.com | d6a433c2fc | |
Tomas Groth | 505e6de924 | |
Tomas Groth | 8a53e4a991 | |
Tomas Groth | d5c9fd33c5 | |
Tim Bentley | ff541f36ed | |
Tim Bentley | d78ed92c4e | |
Tomas Groth | a2b19858b9 | |
Tomas Groth | 935200731c | |
Tomas Groth | eb15f09a47 | |
Tomas Groth | 94a8057a6a | |
raoul@snyman.info | 8a6955fda1 | |
raoul@snyman.info | af54780de5 | |
Tomas Groth | df840d7705 | |
Tomas Groth | a34cbab35c | |
Tomas Groth | f843236059 | |
Tomas Groth | 2e41c5e6fa | |
Raoul Snyman | 150ced331b | |
Raoul Snyman | dcf78ae592 | |
Raoul Snyman | 4ee29b0e3d | |
raoul@snyman.info | 654241246d | |
Raoul Snyman | a75953c3d8 | |
Raoul Snyman | e505950d3f | |
s.mehrbrodt@gmail.com | f32d95c200 | |
Samuel Mehrbrodt | ef89796e33 | |
Samuel Mehrbrodt | 6e901e336c | |
Raoul Snyman | 79285ce759 | |
Tim Bentley | c744a9fa59 | |
raoul@snyman.info | 475ab2af3a | |
Raoul Snyman | 411953285d | |
ian@knightly.xyz | 76f8349e34 | |
Tim Bentley | 78e6ece7fe | |
Ian Knight | 8b893767f8 | |
Ian Knight | fea43c46b9 | |
second@tgc.dk | 07323e50a6 | |
Tomas Groth | 895b3bf9b5 | |
Tomas Groth | 2c640389f1 | |
Ian Knight | 61ffd29cad | |
Ian Knight | ff60d9c271 | |
tim.bentley@gmail.com | 7b1a61a0e6 | |
Tim Bentley | 82dae6b128 | |
Tim Bentley | f46f3e835c | |
Ken Roberts | 8a8695dc50 | |
Ken Roberts | 045744dc17 |
|
@ -45,3 +45,4 @@ cover
|
|||
*.kdev4
|
||||
coverage
|
||||
tags
|
||||
output
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
OpenLP 2.4.6
|
||||
============
|
||||
|
||||
* Fix a bug where the author type upgrade was being ignore because it was looking at the wrong table
|
||||
* Fix a bug where the songs_songbooks table was not being created because the if expression was the wrong way round
|
||||
* Change the songs_songbooks migration SQL slightly to take into account a bug that has (hopefully) been fixed
|
||||
* Sometimes the timer goes off as OpenLP is shutting down, and the application has already been deleted (reported via support system)
|
||||
* Fix opening the data folder (KDE thought the old way was an SMB share)
|
||||
* Fix a problem with the new QMediaPlayer not controlling the playlist anymore
|
||||
* Add importing of author types to the OpenLP 2 song importer
|
||||
* Fix a problem with loading Qt's translation files, bug #1676163
|
||||
* Disable the controls in the shortcut dialog unless a shortcut is actually selected
|
|
@ -4,7 +4,7 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# Copyright (c) 2008-2017 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# Copyright (c) 2008-2017 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
|
|
|
@ -1 +1 @@
|
|||
2.4
|
||||
2.4.6
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# Copyright (c) 2008-2017 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# Copyright (c) 2008-2017 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
|
@ -129,21 +129,21 @@ class OpenLP(OpenLPMixin, QtWidgets.QApplication):
|
|||
application_stylesheet += WIN_REPAIR_STYLESHEET
|
||||
if application_stylesheet:
|
||||
self.setStyleSheet(application_stylesheet)
|
||||
show_splash = Settings().value('core/show splash')
|
||||
if show_splash:
|
||||
can_show_splash = Settings().value('core/show splash')
|
||||
if can_show_splash:
|
||||
self.splash = SplashScreen()
|
||||
self.splash.show()
|
||||
# make sure Qt really display the splash screen
|
||||
self.processEvents()
|
||||
# Check if OpenLP has been upgrade and if a backup of data should be created
|
||||
self.backup_on_upgrade(has_run_wizard)
|
||||
self.backup_on_upgrade(has_run_wizard, can_show_splash)
|
||||
# start the main app window
|
||||
self.main_window = MainWindow()
|
||||
Registry().execute('bootstrap_initialise')
|
||||
Registry().execute('bootstrap_post_set_up')
|
||||
Registry().initialise = False
|
||||
self.main_window.show()
|
||||
if show_splash:
|
||||
if can_show_splash:
|
||||
# now kill the splashscreen
|
||||
self.splash.finish(self.main_window)
|
||||
log.debug('Splashscreen closed')
|
||||
|
@ -153,10 +153,10 @@ class OpenLP(OpenLPMixin, QtWidgets.QApplication):
|
|||
self.processEvents()
|
||||
if not has_run_wizard:
|
||||
self.main_window.first_time()
|
||||
# update_check = Settings().value('core/update check')
|
||||
# if update_check:
|
||||
# version = VersionThread(self.main_window)
|
||||
# version.start()
|
||||
update_check = Settings().value('core/update check')
|
||||
if update_check:
|
||||
version = VersionThread(self.main_window)
|
||||
version.start()
|
||||
self.main_window.is_display_blank()
|
||||
self.main_window.app_startup()
|
||||
return self.exec()
|
||||
|
@ -177,6 +177,38 @@ class OpenLP(OpenLPMixin, QtWidgets.QApplication):
|
|||
self.shared_memory.create(1)
|
||||
return False
|
||||
|
||||
def is_data_path_missing(self):
|
||||
"""
|
||||
Check if the data folder path exists.
|
||||
"""
|
||||
data_folder_path = AppLocation.get_data_path()
|
||||
if not os.path.exists(data_folder_path):
|
||||
log.critical('Database was not found in: ' + data_folder_path)
|
||||
status = QtWidgets.QMessageBox.critical(None, translate('OpenLP', 'Data Directory Error'),
|
||||
translate('OpenLP', 'OpenLP data folder was not found in:\n\n{path}'
|
||||
'\n\nThe location of the data folder was '
|
||||
'previously changed from the OpenLP\'s '
|
||||
'default location. If the data was stored on '
|
||||
'removable device, that device needs to be '
|
||||
'made available.\n\nYou may reset the data '
|
||||
'location back to the default location, '
|
||||
'or you can try to make the current location '
|
||||
'available.\n\nDo you want to reset to the '
|
||||
'default data location? If not, OpenLP will be '
|
||||
'closed so you can try to fix the the problem.')
|
||||
.format(path=data_folder_path),
|
||||
QtWidgets.QMessageBox.StandardButtons(QtWidgets.QMessageBox.Yes |
|
||||
QtWidgets.QMessageBox.No),
|
||||
QtWidgets.QMessageBox.No)
|
||||
if status == QtWidgets.QMessageBox.No:
|
||||
# If answer was "No", return "True", it will shutdown OpenLP in def main
|
||||
log.info('User requested termination')
|
||||
return True
|
||||
# If answer was "Yes", remove the custom data path thus resetting the default location.
|
||||
Settings().remove('advanced/data path')
|
||||
log.info('Database location has been reset to the default settings.')
|
||||
return False
|
||||
|
||||
def hook_exception(self, exc_type, value, traceback):
|
||||
"""
|
||||
Add an exception hook so that any uncaught exceptions are displayed in this window rather than somewhere where
|
||||
|
@ -192,9 +224,15 @@ class OpenLP(OpenLPMixin, QtWidgets.QApplication):
|
|||
self.exception_form = ExceptionForm()
|
||||
self.exception_form.exception_text_edit.setPlainText(''.join(format_exception(exc_type, value, traceback)))
|
||||
self.set_normal_cursor()
|
||||
is_splash_visible = False
|
||||
if hasattr(self, 'splash') and self.splash.isVisible():
|
||||
is_splash_visible = True
|
||||
self.splash.hide()
|
||||
self.exception_form.exec()
|
||||
if is_splash_visible:
|
||||
self.splash.show()
|
||||
|
||||
def backup_on_upgrade(self, has_run_wizard):
|
||||
def backup_on_upgrade(self, has_run_wizard, can_show_splash):
|
||||
"""
|
||||
Check if OpenLP has been upgraded, and ask if a backup of data should be made
|
||||
|
||||
|
@ -207,6 +245,8 @@ class OpenLP(OpenLPMixin, QtWidgets.QApplication):
|
|||
Settings().setValue('core/application version', openlp_version)
|
||||
# If data_version is different from the current version ask if we should backup the data folder
|
||||
elif data_version != openlp_version:
|
||||
if can_show_splash and self.splash.isVisible():
|
||||
self.splash.hide()
|
||||
if QtWidgets.QMessageBox.question(None, translate('OpenLP', 'Backup'),
|
||||
translate('OpenLP', 'OpenLP has been upgraded, do you want to create '
|
||||
'a backup of OpenLPs data folder?'),
|
||||
|
@ -228,6 +268,8 @@ class OpenLP(OpenLPMixin, QtWidgets.QApplication):
|
|||
% data_folder_backup_path)
|
||||
# Update the version in the settings
|
||||
Settings().setValue('core/application version', openlp_version)
|
||||
if can_show_splash:
|
||||
self.splash.show()
|
||||
|
||||
def process_events(self):
|
||||
"""
|
||||
|
@ -275,7 +317,7 @@ class OpenLP(OpenLPMixin, QtWidgets.QApplication):
|
|||
return QtWidgets.QApplication.event(self, event)
|
||||
|
||||
|
||||
def parse_options(args):
|
||||
def parse_options(args=None):
|
||||
"""
|
||||
Parse the command line arguments
|
||||
|
||||
|
@ -342,6 +384,7 @@ def main(args=None):
|
|||
application.setOrganizationName('OpenLP')
|
||||
application.setOrganizationDomain('openlp.org')
|
||||
application.setAttribute(QtCore.Qt.AA_UseHighDpiPixmaps, True)
|
||||
application.setAttribute(QtCore.Qt.AA_DontCreateNativeWidgetSiblings, True)
|
||||
if args and args.portable:
|
||||
application.setApplicationName('OpenLPPortable')
|
||||
Settings.setDefaultFormat(Settings.IniFormat)
|
||||
|
@ -367,9 +410,13 @@ def main(args=None):
|
|||
Registry.create()
|
||||
Registry().register('application', application)
|
||||
application.setApplicationVersion(get_application_version()['version'])
|
||||
# Instance check
|
||||
# Check if an instance of OpenLP is already running. Quit if there is a running instance and the user only wants one
|
||||
if application.is_already_running():
|
||||
sys.exit()
|
||||
# If the custom data path is missing and the user wants to restore the data path, quit OpenLP.
|
||||
if application.is_data_path_missing():
|
||||
application.shared_memory.detach()
|
||||
sys.exit()
|
||||
# Remove/convert obsolete settings.
|
||||
Settings().remove_obsolete_settings()
|
||||
# First time checks in settings
|
||||
|
@ -379,13 +426,12 @@ def main(args=None):
|
|||
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.')
|
||||
translators = LanguageManager.get_translator(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))
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# Copyright (c) 2008-2017 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
|
@ -219,7 +219,8 @@ def qmd5_hash(salt, data=None):
|
|||
log.debug('qmd5_hash(salt="%s"' % salt)
|
||||
hash_obj = QHash(QHash.Md5)
|
||||
hash_obj.addData(salt)
|
||||
hash_obj.addData(data)
|
||||
if data:
|
||||
hash_obj.addData(data)
|
||||
hash_value = hash_obj.result().toHex()
|
||||
log.debug('qmd5_hash() returning "%s"' % hash_value)
|
||||
return hash_value.data()
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# Copyright (c) 2008-2017 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# Copyright (c) 2008-2017 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# Copyright (c) 2008-2017 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# Copyright (c) 2008-2017 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# Copyright (c) 2008-2017 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# Copyright (c) 2008-2017 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# Copyright (c) 2008-2017 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# Copyright (c) 2008-2017 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# Copyright (c) 2008-2017 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# Copyright (c) 2008-2017 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# Copyright (c) 2008-2017 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# Copyright (c) 2008-2017 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# Copyright (c) 2008-2017 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# Copyright (c) 2008-2017 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# Copyright (c) 2008-2017 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# Copyright (c) 2008-2017 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# Copyright (c) 2008-2017 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# Copyright (c) 2008-2017 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# Copyright (c) 2008-2017 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# Copyright (c) 2008-2017 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# Copyright (c) 2008-2017 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# Copyright (c) 2008-2017 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# Copyright (c) 2008-2017 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
|
@ -297,7 +297,11 @@ PJLINK_ERST_STATUS = {'0': ERROR_STRING[E_OK],
|
|||
PJLINK_POWR_STATUS = {'0': S_STANDBY,
|
||||
'1': S_ON,
|
||||
'2': S_COOLDOWN,
|
||||
'3': S_WARMUP}
|
||||
'3': S_WARMUP,
|
||||
S_STANDBY: '0',
|
||||
S_ON: '1',
|
||||
S_COOLDOWN: '2',
|
||||
S_WARMUP: '3'}
|
||||
|
||||
PJLINK_DEFAULT_SOURCES = {'1': translate('OpenLP.DB', 'RGB'),
|
||||
'2': translate('OpenLP.DB', 'Video'),
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# Copyright (c) 2008-2017 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# Copyright (c) 2008-2017 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
|
@ -49,7 +49,7 @@ from codecs import decode
|
|||
from PyQt5.QtCore import pyqtSignal, pyqtSlot
|
||||
from PyQt5.QtNetwork import QAbstractSocket, QTcpSocket
|
||||
|
||||
from openlp.core.common import translate, qmd5_hash
|
||||
from openlp.core.common import translate, md5_hash
|
||||
from openlp.core.lib.projector.constants import *
|
||||
|
||||
# Shortcuts
|
||||
|
@ -58,7 +58,7 @@ SocketSTate = QAbstractSocket.SocketState
|
|||
|
||||
PJLINK_PREFIX = '%'
|
||||
PJLINK_CLASS = '1'
|
||||
PJLINK_HEADER = '%s%s' % (PJLINK_PREFIX, PJLINK_CLASS)
|
||||
PJLINK_HEADER = '{prefix}{linkclass}'.format(prefix=PJLINK_PREFIX, linkclass=PJLINK_CLASS)
|
||||
PJLINK_SUFFIX = CR
|
||||
|
||||
|
||||
|
@ -68,7 +68,7 @@ class PJLink1(QTcpSocket):
|
|||
"""
|
||||
# Signals sent by this module
|
||||
changeStatus = pyqtSignal(str, int, str)
|
||||
projectorNetwork = pyqtSignal(int) # Projector network activity
|
||||
projectorNetwork = pyqtSignal(str, int) # Projector network activity
|
||||
projectorStatus = pyqtSignal(int) # Status update
|
||||
projectorAuthentication = pyqtSignal(str) # Authentication error
|
||||
projectorNoAuthentication = pyqtSignal(str) # PIN set and no authentication needed
|
||||
|
@ -91,7 +91,7 @@ class PJLink1(QTcpSocket):
|
|||
:param poll_time: Time (in seconds) to poll connected projector
|
||||
:param socket_timeout: Time (in seconds) to abort the connection if no response
|
||||
"""
|
||||
log.debug('PJlink(args="%s" kwargs="%s")' % (args, kwargs))
|
||||
log.debug('PJlink(args={args} kwargs={kwargs})'.format(args=args, kwargs=kwargs))
|
||||
self.name = name
|
||||
self.ip = ip
|
||||
self.port = port
|
||||
|
@ -147,7 +147,7 @@ class PJLink1(QTcpSocket):
|
|||
"""
|
||||
Reset projector-specific information to default
|
||||
"""
|
||||
log.debug('(%s) reset_information() connect status is %s' % (self.ip, self.state()))
|
||||
log.debug('({ip}) reset_information() connect status is {state}'.format(ip=self.ip, state=self.state()))
|
||||
self.power = S_OFF
|
||||
self.pjlink_name = None
|
||||
self.manufacturer = None
|
||||
|
@ -160,8 +160,10 @@ class PJLink1(QTcpSocket):
|
|||
self.source = None
|
||||
self.other_info = None
|
||||
if hasattr(self, 'timer'):
|
||||
log.debug('({ip}): Calling timer.stop()'.format(ip=self.ip))
|
||||
self.timer.stop()
|
||||
if hasattr(self, 'socket_timer'):
|
||||
log.debug('({ip}): Calling socket_timer.stop()'.format(ip=self.ip))
|
||||
self.socket_timer.stop()
|
||||
self.send_queue = []
|
||||
self.send_busy = False
|
||||
|
@ -170,7 +172,7 @@ class PJLink1(QTcpSocket):
|
|||
"""
|
||||
Connects signals to methods when thread is started.
|
||||
"""
|
||||
log.debug('(%s) Thread starting' % self.ip)
|
||||
log.debug('({ip}) Thread starting'.format(ip=self.ip))
|
||||
self.i_am_running = True
|
||||
self.connected.connect(self.check_login)
|
||||
self.disconnected.connect(self.disconnect_from_host)
|
||||
|
@ -180,7 +182,7 @@ class PJLink1(QTcpSocket):
|
|||
"""
|
||||
Cleanups when thread is stopped.
|
||||
"""
|
||||
log.debug('(%s) Thread stopped' % self.ip)
|
||||
log.debug('({ip}) Thread stopped'.format(ip=self.ip))
|
||||
try:
|
||||
self.connected.disconnect(self.check_login)
|
||||
except TypeError:
|
||||
|
@ -206,7 +208,7 @@ class PJLink1(QTcpSocket):
|
|||
Aborts connection and closes socket in case of brain-dead projectors.
|
||||
Should normally be called by socket_timer().
|
||||
"""
|
||||
log.debug('(%s) socket_abort() - Killing connection' % self.ip)
|
||||
log.debug('({ip}) socket_abort() - Killing connection'.format(ip=self.ip))
|
||||
self.disconnect_from_host(abort=True)
|
||||
|
||||
def poll_loop(self):
|
||||
|
@ -216,7 +218,7 @@ class PJLink1(QTcpSocket):
|
|||
"""
|
||||
if self.state() != self.ConnectedState:
|
||||
return
|
||||
log.debug('(%s) Updating projector status' % self.ip)
|
||||
log.debug('({ip}) Updating projector status'.format(ip=self.ip))
|
||||
# Reset timer in case we were called from a set command
|
||||
if self.timer.interval() < self.poll_time:
|
||||
# Reset timer to 5 seconds
|
||||
|
@ -276,11 +278,17 @@ class PJLink1(QTcpSocket):
|
|||
self.status_connect = S_CONNECTED
|
||||
self.projector_status = status
|
||||
(status_code, status_message) = self._get_status(self.status_connect)
|
||||
log.debug('(%s) status_connect: %s: %s' % (self.ip, status_code, status_message if msg is None else msg))
|
||||
log.debug('({ip}) status_connect: {code}: "{message}"'.format(ip=self.ip,
|
||||
code=status_code,
|
||||
message=status_message if msg is None else msg))
|
||||
(status_code, status_message) = self._get_status(self.projector_status)
|
||||
log.debug('(%s) projector_status: %s: %s' % (self.ip, status_code, status_message if msg is None else msg))
|
||||
log.debug('({ip}) projector_status: {code}: "{message}"'.format(ip=self.ip,
|
||||
code=status_code,
|
||||
message=status_message if msg is None else msg))
|
||||
(status_code, status_message) = self._get_status(self.error_status)
|
||||
log.debug('(%s) error_status: %s: %s' % (self.ip, status_code, status_message if msg is None else msg))
|
||||
log.debug('({ip}) error_status: {code}: "{message}"'.format(ip=self.ip,
|
||||
code=status_code,
|
||||
message=status_message if msg is None else msg))
|
||||
self.changeStatus.emit(self.ip, status, message)
|
||||
|
||||
@pyqtSlot()
|
||||
|
@ -289,29 +297,31 @@ class PJLink1(QTcpSocket):
|
|||
Processes the initial connection and authentication (if needed).
|
||||
Starts poll timer if connection is established.
|
||||
|
||||
NOTE: Qt md5 hash function doesn't work with projector authentication. Use the python md5 hash function.
|
||||
|
||||
:param data: Optional data if called from another routine
|
||||
"""
|
||||
log.debug('(%s) check_login(data="%s")' % (self.ip, data))
|
||||
log.debug('({ip}) check_login(data="{data}")'.format(ip=self.ip, data=data))
|
||||
if data is None:
|
||||
# Reconnected setup?
|
||||
if not self.waitForReadyRead(2000):
|
||||
# Possible timeout issue
|
||||
log.error('(%s) Socket timeout waiting for login' % self.ip)
|
||||
log.error('({ip}) Socket timeout waiting for login'.format(ip=self.ip))
|
||||
self.change_status(E_SOCKET_TIMEOUT)
|
||||
return
|
||||
read = self.readLine(self.maxSize)
|
||||
dontcare = self.readLine(self.maxSize) # Clean out the trailing \r\n
|
||||
if read is None:
|
||||
log.warn('(%s) read is None - socket error?' % self.ip)
|
||||
log.warning('({ip}) read is None - socket error?'.format(ip=self.ip))
|
||||
return
|
||||
elif len(read) < 8:
|
||||
log.warn('(%s) Not enough data read)' % self.ip)
|
||||
log.warning('({ip}) Not enough data read)'.format(ip=self.ip))
|
||||
return
|
||||
data = decode(read, 'ascii')
|
||||
# Possibility of extraneous data on input when reading.
|
||||
# Clean out extraneous characters in buffer.
|
||||
dontcare = self.readLine(self.maxSize)
|
||||
log.debug('(%s) check_login() read "%s"' % (self.ip, data.strip()))
|
||||
log.debug('({ip}) check_login() read "{data}"'.format(ip=self.ip, data=data.strip()))
|
||||
# At this point, we should only have the initial login prompt with
|
||||
# possible authentication
|
||||
# PJLink initial login will be:
|
||||
|
@ -326,26 +336,35 @@ class PJLink1(QTcpSocket):
|
|||
else:
|
||||
# Process initial connection
|
||||
data_check = data.strip().split(' ')
|
||||
log.debug('(%s) data_check="%s"' % (self.ip, data_check))
|
||||
log.debug('({ip}) data_check="{data}"'.format(ip=self.ip, data=data_check))
|
||||
# Check for projector reporting an error
|
||||
if data_check[1].upper() == 'ERRA':
|
||||
# Authentication error
|
||||
self.disconnect_from_host()
|
||||
self.change_status(E_AUTHENTICATION)
|
||||
log.debug('(%s) emitting projectorAuthentication() signal' % self.name)
|
||||
log.debug('({ip}) emitting projectorAuthentication() signal'.format(ip=self.name))
|
||||
return
|
||||
elif data_check[1] == '0' and self.pin is not None:
|
||||
# Pin set and no authentication needed
|
||||
log.warning('({ip}) Regular connection but PIN set'.format(ip=self.name))
|
||||
self.disconnect_from_host()
|
||||
self.change_status(E_AUTHENTICATION)
|
||||
log.debug('(%s) emitting projectorNoAuthentication() signal' % self.name)
|
||||
log.debug('({ip}) Emitting projectorNoAuthentication() signal'.format(ip=self.name))
|
||||
self.projectorNoAuthentication.emit(self.name)
|
||||
return
|
||||
elif data_check[1] == '1':
|
||||
# Authenticated login with salt
|
||||
log.debug('(%s) Setting hash with salt="%s"' % (self.ip, data_check[2]))
|
||||
log.debug('(%s) pin="%s"' % (self.ip, self.pin))
|
||||
salt = qmd5_hash(salt=data_check[2].encode('ascii'), data=self.pin.encode('ascii'))
|
||||
if self.pin is None:
|
||||
log.warning('({ip}) Authenticated connection but no pin set'.format(ip=self.name))
|
||||
self.disconnect_from_host()
|
||||
self.change_status(E_AUTHENTICATION)
|
||||
log.debug('({ip}) Emitting projectorAuthentication() signal'.format(ip=self.name))
|
||||
self.projectorAuthentication.emit(self.name)
|
||||
return
|
||||
else:
|
||||
log.debug('({ip}) Setting hash with salt="{data}"'.format(ip=self.ip, data=data_check[2]))
|
||||
log.debug('({ip}) pin="{data}"'.format(ip=self.ip, data=self.pin))
|
||||
salt = md5_hash(salt=data_check[2].encode('ascii'), data=self.pin.encode('ascii'))
|
||||
else:
|
||||
salt = None
|
||||
# We're connected at this point, so go ahead and do regular I/O
|
||||
|
@ -355,7 +374,7 @@ class PJLink1(QTcpSocket):
|
|||
self.send_command(cmd='CLSS', salt=salt)
|
||||
self.waitForReadyRead()
|
||||
if (not self.no_poll) and (self.state() == self.ConnectedState):
|
||||
log.debug('(%s) Starting timer' % self.ip)
|
||||
log.debug('({ip}) Starting timer'.format(ip=self.ip))
|
||||
self.timer.setInterval(2000) # Set 2 seconds for initial information
|
||||
self.timer.start()
|
||||
|
||||
|
@ -364,29 +383,29 @@ class PJLink1(QTcpSocket):
|
|||
"""
|
||||
Socket interface to retrieve data.
|
||||
"""
|
||||
log.debug('(%s) get_data(): Reading data' % self.ip)
|
||||
log.debug('({ip}) get_data(): Reading data'.format(ip=self.ip))
|
||||
if self.state() != self.ConnectedState:
|
||||
log.debug('(%s) get_data(): Not connected - returning' % self.ip)
|
||||
log.debug('({ip}) get_data(): Not connected - returning'.format(ip=self.ip))
|
||||
self.send_busy = False
|
||||
return
|
||||
read = self.readLine(self.maxSize)
|
||||
if read == -1:
|
||||
# No data available
|
||||
log.debug('(%s) get_data(): No data available (-1)' % self.ip)
|
||||
log.debug('({ip}) get_data(): No data available (-1)'.format(ip=self.ip))
|
||||
self.send_busy = False
|
||||
self.projectorReceivedData.emit()
|
||||
return
|
||||
self.socket_timer.stop()
|
||||
self.projectorNetwork.emit(S_NETWORK_RECEIVED)
|
||||
self.projectorNetwork.emit(self.ip, S_NETWORK_RECEIVED)
|
||||
data_in = decode(read, 'ascii')
|
||||
data = data_in.strip()
|
||||
if len(data) < 7:
|
||||
# Not enough data for a packet
|
||||
log.debug('(%s) get_data(): Packet length < 7: "%s"' % (self.ip, data))
|
||||
log.debug('({ip}) get_data(): Packet length < 7: "{data}"'.format(ip=self.ip, data=data))
|
||||
self.send_busy = False
|
||||
self.projectorReceivedData.emit()
|
||||
return
|
||||
log.debug('(%s) get_data(): Checking new data "%s"' % (self.ip, data))
|
||||
log.debug('({ip}) get_data(): Checking new data "{data}"'.format(ip=self.ip, data=data))
|
||||
if data.upper().startswith('PJLINK'):
|
||||
# Reconnected from remote host disconnect ?
|
||||
self.check_login(data)
|
||||
|
@ -394,7 +413,7 @@ class PJLink1(QTcpSocket):
|
|||
self.projectorReceivedData.emit()
|
||||
return
|
||||
elif '=' not in data:
|
||||
log.warn('(%s) get_data(): Invalid packet received' % self.ip)
|
||||
log.warning('({ip}) get_data(): Invalid packet received'.format(ip=self.ip))
|
||||
self.send_busy = False
|
||||
self.projectorReceivedData.emit()
|
||||
return
|
||||
|
@ -402,21 +421,21 @@ class PJLink1(QTcpSocket):
|
|||
try:
|
||||
(prefix, class_, cmd, data) = (data_split[0][0], data_split[0][1], data_split[0][2:], data_split[1])
|
||||
except ValueError as e:
|
||||
log.warn('(%s) get_data(): Invalid packet - expected header + command + data' % self.ip)
|
||||
log.warn('(%s) get_data(): Received data: "%s"' % (self.ip, read))
|
||||
log.warning('({ip}) get_data(): Invalid packet - expected header + command + data'.format(ip=self.ip))
|
||||
log.warning('({ip}) get_data(): Received data: "{data}"'.format(ip=self.ip, data=data_in.strip()))
|
||||
self.change_status(E_INVALID_DATA)
|
||||
self.send_busy = False
|
||||
self.projectorReceivedData.emit()
|
||||
return
|
||||
|
||||
if not (self.pjlink_class in PJLINK_VALID_CMD and cmd in PJLINK_VALID_CMD[self.pjlink_class]):
|
||||
log.warn('(%s) get_data(): Invalid packet - unknown command "%s"' % (self.ip, cmd))
|
||||
log.warning('({ip}) get_data(): Invalid packet - unknown command "{data}"'.format(ip=self.ip, data=cmd))
|
||||
self.send_busy = False
|
||||
self.projectorReceivedData.emit()
|
||||
return
|
||||
return self.process_command(cmd, data)
|
||||
|
||||
@pyqtSlot(int)
|
||||
@pyqtSlot(QAbstractSocket.SocketError)
|
||||
def get_error(self, err):
|
||||
"""
|
||||
Process error from SocketError signal.
|
||||
|
@ -424,7 +443,7 @@ class PJLink1(QTcpSocket):
|
|||
|
||||
:param err: Error code
|
||||
"""
|
||||
log.debug('(%s) get_error(err=%s): %s' % (self.ip, err, self.errorString()))
|
||||
log.debug('({ip}) get_error(err={error}): {data}'.format(ip=self.ip, error=err, data=self.errorString()))
|
||||
if err <= 18:
|
||||
# QSocket errors. Redefined in projector.constants so we don't mistake
|
||||
# them for system errors
|
||||
|
@ -453,10 +472,10 @@ class PJLink1(QTcpSocket):
|
|||
:param queue: Option to force add to queue rather than sending directly
|
||||
"""
|
||||
if self.state() != self.ConnectedState:
|
||||
log.warn('(%s) send_command(): Not connected - returning' % self.ip)
|
||||
log.warning('({ip}) send_command(): Not connected - returning'.format(ip=self.ip))
|
||||
self.send_queue = []
|
||||
return
|
||||
self.projectorNetwork.emit(S_NETWORK_SENDING)
|
||||
self.projectorNetwork.emit(self.ip, S_NETWORK_SENDING)
|
||||
log.debug('(%s) send_command(): Building cmd="%s" opts="%s" %s' % (self.ip,
|
||||
cmd,
|
||||
opts,
|
||||
|
@ -467,18 +486,19 @@ class PJLink1(QTcpSocket):
|
|||
out = '%s%s%s %s%s' % (salt, PJLINK_HEADER, cmd, opts, CR)
|
||||
if out in self.send_queue:
|
||||
# Already there, so don't add
|
||||
log.debug('(%s) send_command(out="%s") Already in queue - skipping' % (self.ip, out.strip()))
|
||||
log.debug('({ip}) send_command(out="{data}") Already in queue - skipping'.format(ip=self.ip,
|
||||
data=out.strip()))
|
||||
elif not queue and len(self.send_queue) == 0:
|
||||
# Nothing waiting to send, so just send it
|
||||
log.debug('(%s) send_command(out="%s") Sending data' % (self.ip, out.strip()))
|
||||
log.debug('({ip}) send_command(out="{data}") Sending data'.format(ip=self.ip, data=out.strip()))
|
||||
return self._send_command(data=out)
|
||||
else:
|
||||
log.debug('(%s) send_command(out="%s") adding to queue' % (self.ip, out.strip()))
|
||||
log.debug('({ip}) send_command(out="{data}") adding to queue'.format(ip=self.ip, data=out.strip()))
|
||||
self.send_queue.append(out)
|
||||
self.projectorReceivedData.emit()
|
||||
log.debug('(%s) send_command(): send_busy is %s' % (self.ip, self.send_busy))
|
||||
log.debug('({ip}) send_command(): send_busy is {data}'.format(ip=self.ip, data=self.send_busy))
|
||||
if not self.send_busy:
|
||||
log.debug('(%s) send_command() calling _send_string()')
|
||||
log.debug('({ip}) send_command() calling _send_string()'.format(ip=self.ip))
|
||||
self._send_command()
|
||||
|
||||
@pyqtSlot()
|
||||
|
@ -488,10 +508,10 @@ class PJLink1(QTcpSocket):
|
|||
|
||||
:param data: Immediate data to send
|
||||
"""
|
||||
log.debug('(%s) _send_string()' % self.ip)
|
||||
log.debug('(%s) _send_string(): Connection status: %s' % (self.ip, self.state()))
|
||||
log.debug('({ip}) _send_string()'.format(ip=self.ip))
|
||||
log.debug('({ip}) _send_string(): Connection status: {data}'.format(ip=self.ip, data=self.state()))
|
||||
if self.state() != self.ConnectedState:
|
||||
log.debug('(%s) _send_string() Not connected - abort' % self.ip)
|
||||
log.debug('({ip}) _send_string() Not connected - abort'.format(ip=self.ip))
|
||||
self.send_queue = []
|
||||
self.send_busy = False
|
||||
return
|
||||
|
@ -500,22 +520,22 @@ class PJLink1(QTcpSocket):
|
|||
return
|
||||
if data is not None:
|
||||
out = data
|
||||
log.debug('(%s) _send_string(data=%s)' % (self.ip, out.strip()))
|
||||
log.debug('({ip}) _send_string(data="{data}")'.format(ip=self.ip, data=out.strip()))
|
||||
elif len(self.send_queue) != 0:
|
||||
out = self.send_queue.pop(0)
|
||||
log.debug('(%s) _send_string(queued data=%s)' % (self.ip, out.strip()))
|
||||
log.debug('({ip}) _send_string(queued data="{data}"%s)'.format(ip=self.ip, data=out.strip()))
|
||||
else:
|
||||
# No data to send
|
||||
log.debug('(%s) _send_string(): No data to send' % self.ip)
|
||||
log.debug('({ip}) _send_string(): No data to send'.format(ip=self.ip))
|
||||
self.send_busy = False
|
||||
return
|
||||
self.send_busy = True
|
||||
log.debug('(%s) _send_string(): Sending "%s"' % (self.ip, out.strip()))
|
||||
log.debug('(%s) _send_string(): Queue = %s' % (self.ip, self.send_queue))
|
||||
log.debug('({ip}) _send_string(): Sending "{data}"'.format(ip=self.ip, data=out.strip()))
|
||||
log.debug('({ip}) _send_string(): Queue = {data}'.format(ip=self.ip, data=self.send_queue))
|
||||
self.socket_timer.start()
|
||||
try:
|
||||
self.projectorNetwork.emit(S_NETWORK_SENDING)
|
||||
sent = self.write(out)
|
||||
self.projectorNetwork.emit(self.ip, S_NETWORK_SENDING)
|
||||
sent = self.write(out.encode('ascii'))
|
||||
self.waitForBytesWritten(2000) # 2 seconds should be enough
|
||||
if sent == -1:
|
||||
# Network error?
|
||||
|
@ -523,7 +543,9 @@ class PJLink1(QTcpSocket):
|
|||
translate('OpenLP.PJLink1', 'Error while sending data to projector'))
|
||||
except SocketError as e:
|
||||
self.disconnect_from_host(abort=True)
|
||||
self.changeStatus(E_NETWORK, '%s : %s' % (e.error(), e.errorString()))
|
||||
self.changeStatus(E_NETWORK,
|
||||
translate('OpenLP.PJLink1', '{code} : {string}').format(code=e.error(),
|
||||
string=e.errorString()))
|
||||
|
||||
def process_command(self, cmd, data):
|
||||
"""
|
||||
|
@ -532,19 +554,21 @@ class PJLink1(QTcpSocket):
|
|||
:param cmd: Command to process
|
||||
:param data: Data being processed
|
||||
"""
|
||||
log.debug('(%s) Processing command "%s"' % (self.ip, cmd))
|
||||
log.debug('({ip}) Processing command "{data}"'.format(ip=self.ip, data=cmd))
|
||||
if data in PJLINK_ERRORS:
|
||||
# Oops - projector error
|
||||
log.error('({ip}) Projector returned error "{data}"'.format(ip=self.ip, data=data))
|
||||
if data.upper() == 'ERRA':
|
||||
# Authentication error
|
||||
self.disconnect_from_host()
|
||||
self.change_status(E_AUTHENTICATION)
|
||||
log.debug('(%s) emitting projectorAuthentication() signal' % self.ip)
|
||||
log.debug('({ip}) emitting projectorAuthentication() signal'.format(ip=self.ip))
|
||||
self.projectorAuthentication.emit(self.name)
|
||||
elif data.upper() == 'ERR1':
|
||||
# Undefined command
|
||||
self.change_status(E_UNDEFINED, '%s "%s"' %
|
||||
(translate('OpenLP.PJLink1', 'Undefined command:'), cmd))
|
||||
self.change_status(E_UNDEFINED, '{error} "{data}"'.format(error=translate('OpenLP.PJLink1',
|
||||
'Undefined command:'),
|
||||
data=cmd))
|
||||
elif data.upper() == 'ERR2':
|
||||
# Invalid parameter
|
||||
self.change_status(E_PARAMETER)
|
||||
|
@ -559,7 +583,7 @@ class PJLink1(QTcpSocket):
|
|||
return
|
||||
# Command succeeded - no extra information
|
||||
elif data.upper() == 'OK':
|
||||
log.debug('(%s) Command returned OK' % self.ip)
|
||||
log.debug('({ip}) Command returned OK'.format(ip=self.ip))
|
||||
# A command returned successfully, recheck data
|
||||
self.send_busy = False
|
||||
self.projectorReceivedData.emit()
|
||||
|
@ -568,7 +592,7 @@ class PJLink1(QTcpSocket):
|
|||
if cmd in self.PJLINK1_FUNC:
|
||||
self.PJLINK1_FUNC[cmd](data)
|
||||
else:
|
||||
log.warn('(%s) Invalid command %s' % (self.ip, cmd))
|
||||
log.warning('({ip}) Invalid command {data}'.format(ip=self.ip, data=cmd))
|
||||
self.send_busy = False
|
||||
self.projectorReceivedData.emit()
|
||||
|
||||
|
@ -587,7 +611,7 @@ class PJLink1(QTcpSocket):
|
|||
fill = {'Hours': int(data_dict[0]), 'On': False if data_dict[1] == '0' else True}
|
||||
except ValueError:
|
||||
# In case of invalid entry
|
||||
log.warn('(%s) process_lamp(): Invalid data "%s"' % (self.ip, data))
|
||||
log.warning('({ip}) process_lamp(): Invalid data "{data}"'.format(ip=self.ip, data=data))
|
||||
return
|
||||
lamps.append(fill)
|
||||
data_dict.pop(0) # Remove lamp hours
|
||||
|
@ -614,7 +638,7 @@ class PJLink1(QTcpSocket):
|
|||
self.send_command('INST')
|
||||
else:
|
||||
# Log unknown status response
|
||||
log.warn('Unknown power response: %s' % data)
|
||||
log.warning('({ip}) Unknown power response: {data}'.format(ip=self.ip, data=data))
|
||||
return
|
||||
|
||||
def process_avmt(self, data):
|
||||
|
@ -639,7 +663,7 @@ class PJLink1(QTcpSocket):
|
|||
shutter = True
|
||||
mute = True
|
||||
else:
|
||||
log.warn('Unknown shutter response: %s' % data)
|
||||
log.warning('({ip}) Unknown shutter response: {data}'.format(ip=self.ip, data=data))
|
||||
update_icons = shutter != self.shutter
|
||||
update_icons = update_icons or mute != self.mute
|
||||
self.shutter = shutter
|
||||
|
@ -656,6 +680,7 @@ class PJLink1(QTcpSocket):
|
|||
:param data: Currently selected source
|
||||
"""
|
||||
self.source = data
|
||||
log.info('({ip}) Setting data source to "{data}"'.format(ip=self.ip, data=self.source))
|
||||
return
|
||||
|
||||
def process_clss(self, data):
|
||||
|
@ -665,8 +690,17 @@ class PJLink1(QTcpSocket):
|
|||
|
||||
:param data: Class that projector supports.
|
||||
"""
|
||||
self.pjlink_class = data
|
||||
log.debug('(%s) Setting pjlink_class for this projector to "%s"' % (self.ip, self.pjlink_class))
|
||||
# bug 1550891: Projector returns non-standard class response:
|
||||
# : Expected: %1CLSS=1
|
||||
# : Received: %1CLSS=Class 1
|
||||
if len(data) > 1:
|
||||
# Split non-standard information from response
|
||||
clss = data.split()[-1]
|
||||
else:
|
||||
clss = data
|
||||
self.pjlink_class = clss
|
||||
log.debug('({ip}) Setting pjlink_class for this projector to "{data}"'.format(ip=self.ip,
|
||||
data=self.pjlink_class))
|
||||
return
|
||||
|
||||
def process_name(self, data):
|
||||
|
@ -677,6 +711,7 @@ class PJLink1(QTcpSocket):
|
|||
:param data: Projector name
|
||||
"""
|
||||
self.pjlink_name = data
|
||||
log.debug('({ip}) Setting projector PJLink name to "{data}"'.format(ip=self.ip, data=self.pjlink_name))
|
||||
return
|
||||
|
||||
def process_inf1(self, data):
|
||||
|
@ -687,6 +722,7 @@ class PJLink1(QTcpSocket):
|
|||
:param data: Projector manufacturer
|
||||
"""
|
||||
self.manufacturer = data
|
||||
log.debug('({ip}) Setting projector manufacturer data to "{data}"'.format(ip=self.ip, data=self.manufacturer))
|
||||
return
|
||||
|
||||
def process_inf2(self, data):
|
||||
|
@ -697,6 +733,7 @@ class PJLink1(QTcpSocket):
|
|||
:param data: Model name
|
||||
"""
|
||||
self.model = data
|
||||
log.debug('({ip}) Setting projector model to "{data}"'.format(ip=self.ip, data=self.model))
|
||||
return
|
||||
|
||||
def process_info(self, data):
|
||||
|
@ -707,6 +744,7 @@ class PJLink1(QTcpSocket):
|
|||
:param data: Projector other info
|
||||
"""
|
||||
self.other_info = data
|
||||
log.debug('({ip}) Setting projector other_info to "{data}"'.format(ip=self.ip, data=self.other_info))
|
||||
return
|
||||
|
||||
def process_inst(self, data):
|
||||
|
@ -723,6 +761,8 @@ class PJLink1(QTcpSocket):
|
|||
sources.sort()
|
||||
self.source_available = sources
|
||||
self.projectorUpdateIcons.emit()
|
||||
log.debug('({ip}) Setting projector sources_available to "{data}"'.format(ip=self.ip,
|
||||
data=self.source_available))
|
||||
return
|
||||
|
||||
def process_erst(self, data):
|
||||
|
@ -772,7 +812,7 @@ class PJLink1(QTcpSocket):
|
|||
Initiate connection to projector.
|
||||
"""
|
||||
if self.state() == self.ConnectedState:
|
||||
log.warn('(%s) connect_to_host(): Already connected - returning' % self.ip)
|
||||
log.warning('({ip}) connect_to_host(): Already connected - returning'.format(ip=self.ip))
|
||||
return
|
||||
self.change_status(S_CONNECTING)
|
||||
self.connectToHost(self.ip, self.port if type(self.port) is int else int(self.port))
|
||||
|
@ -784,9 +824,9 @@ class PJLink1(QTcpSocket):
|
|||
"""
|
||||
if abort or self.state() != self.ConnectedState:
|
||||
if abort:
|
||||
log.warn('(%s) disconnect_from_host(): Aborting connection' % self.ip)
|
||||
log.warning('({ip}) disconnect_from_host(): Aborting connection'.format(ip=self.ip))
|
||||
else:
|
||||
log.warn('(%s) disconnect_from_host(): Not connected - returning' % self.ip)
|
||||
log.warning('({ip}) disconnect_from_host(): Not connected - returning'.format(ip=self.ip))
|
||||
self.reset_information()
|
||||
self.disconnectFromHost()
|
||||
try:
|
||||
|
@ -796,8 +836,8 @@ class PJLink1(QTcpSocket):
|
|||
if abort:
|
||||
self.change_status(E_NOT_CONNECTED)
|
||||
else:
|
||||
log.debug('(%s) disconnect_from_host() Current status %s' % (self.ip,
|
||||
self._get_status(self.status_connect)[0]))
|
||||
log.debug('({ip}) disconnect_from_host() '
|
||||
'Current status {data}'.format(ip=self.ip, data=self._get_status(self.status_connect)[0]))
|
||||
if self.status_connect != E_NOT_CONNECTED:
|
||||
self.change_status(S_NOT_CONNECTED)
|
||||
self.reset_information()
|
||||
|
@ -807,60 +847,70 @@ class PJLink1(QTcpSocket):
|
|||
"""
|
||||
Send command to retrieve available source inputs.
|
||||
"""
|
||||
log.debug('({ip}) Sending INST command'.format(ip=self.ip))
|
||||
return self.send_command(cmd='INST')
|
||||
|
||||
def get_error_status(self):
|
||||
"""
|
||||
Send command to retrieve currently known errors.
|
||||
"""
|
||||
log.debug('({ip}) Sending ERST command'.format(ip=self.ip))
|
||||
return self.send_command(cmd='ERST')
|
||||
|
||||
def get_input_source(self):
|
||||
"""
|
||||
Send command to retrieve currently selected source input.
|
||||
"""
|
||||
log.debug('({ip}) Sending INPT command'.format(ip=self.ip))
|
||||
return self.send_command(cmd='INPT')
|
||||
|
||||
def get_lamp_status(self):
|
||||
"""
|
||||
Send command to return the lap status.
|
||||
"""
|
||||
log.debug('({ip}) Sending LAMP command'.format(ip=self.ip))
|
||||
return self.send_command(cmd='LAMP')
|
||||
|
||||
def get_manufacturer(self):
|
||||
"""
|
||||
Send command to retrieve manufacturer name.
|
||||
"""
|
||||
log.debug('({ip}) Sending INF1 command'.format(ip=self.ip))
|
||||
return self.send_command(cmd='INF1')
|
||||
|
||||
def get_model(self):
|
||||
"""
|
||||
Send command to retrieve the model name.
|
||||
"""
|
||||
log.debug('({ip}) Sending INF2 command'.format(ip=self.ip))
|
||||
return self.send_command(cmd='INF2')
|
||||
|
||||
def get_name(self):
|
||||
"""
|
||||
Send command to retrieve name as set by end-user (if set).
|
||||
"""
|
||||
log.debug('({ip}) Sending NAME command'.format(ip=self.ip))
|
||||
return self.send_command(cmd='NAME')
|
||||
|
||||
def get_other_info(self):
|
||||
"""
|
||||
Send command to retrieve extra info set by manufacturer.
|
||||
"""
|
||||
log.debug('({ip}) Sending INFO command'.format(ip=self.ip))
|
||||
return self.send_command(cmd='INFO')
|
||||
|
||||
def get_power_status(self):
|
||||
"""
|
||||
Send command to retrieve power status.
|
||||
"""
|
||||
log.debug('({ip}) Sending POWR command'.format(ip=self.ip))
|
||||
return self.send_command(cmd='POWR')
|
||||
|
||||
def get_shutter_status(self):
|
||||
"""
|
||||
Send command to retrieve shutter status.
|
||||
"""
|
||||
log.debug('({ip}) Sending AVMT command'.format(ip=self.ip))
|
||||
return self.send_command(cmd='AVMT')
|
||||
|
||||
def set_input_source(self, src=None):
|
||||
|
@ -870,12 +920,12 @@ class PJLink1(QTcpSocket):
|
|||
|
||||
:param src: Video source to select in projector
|
||||
"""
|
||||
log.debug('(%s) set_input_source(src=%s)' % (self.ip, src))
|
||||
log.debug('({ip}) set_input_source(src="{data}")'.format(ip=self.ip, data=src))
|
||||
if self.source_available is None:
|
||||
return
|
||||
elif src not in self.source_available:
|
||||
return
|
||||
log.debug('(%s) Setting input source to %s' % (self.ip, src))
|
||||
log.debug('({ip}) Setting input source to "{data}"'.format(ip=self.ip, data=src))
|
||||
self.send_command(cmd='INPT', opts=src)
|
||||
self.poll_loop()
|
||||
|
||||
|
@ -883,6 +933,7 @@ class PJLink1(QTcpSocket):
|
|||
"""
|
||||
Send command to turn power to on.
|
||||
"""
|
||||
log.debug('({ip}) Setting POWR to 1 (on)'.format(ip=self.ip))
|
||||
self.send_command(cmd='POWR', opts='1')
|
||||
self.poll_loop()
|
||||
|
||||
|
@ -890,6 +941,7 @@ class PJLink1(QTcpSocket):
|
|||
"""
|
||||
Send command to turn power to standby.
|
||||
"""
|
||||
log.debug('({ip}) Setting POWR to 0 (standby)'.format(ip=self.ip))
|
||||
self.send_command(cmd='POWR', opts='0')
|
||||
self.poll_loop()
|
||||
|
||||
|
@ -897,6 +949,7 @@ class PJLink1(QTcpSocket):
|
|||
"""
|
||||
Send command to set shutter to closed position.
|
||||
"""
|
||||
log.debug('({ip}) Setting AVMT to 11 (shutter closed)'.format(ip=self.ip))
|
||||
self.send_command(cmd='AVMT', opts='11')
|
||||
self.poll_loop()
|
||||
|
||||
|
@ -904,5 +957,6 @@ class PJLink1(QTcpSocket):
|
|||
"""
|
||||
Send command to set shutter to open position.
|
||||
"""
|
||||
log.debug('({ip}) Setting AVMT to "10" (shutter open)'.format(ip=self.ip))
|
||||
self.send_command(cmd='AVMT', opts='10')
|
||||
self.poll_loop()
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# Copyright (c) 2008-2017 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# Copyright (c) 2008-2017 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# Copyright (c) 2008-2017 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# Copyright (c) 2008-2017 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# Copyright (c) 2008-2017 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# Copyright (c) 2008-2017 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
|
@ -142,6 +142,7 @@ class SpellTextEdit(QtWidgets.QPlainTextEdit):
|
|||
"""
|
||||
Replaces the selected text with word.
|
||||
"""
|
||||
tag = tag.replace('&', '')
|
||||
for html in FormattingTags.get_html_tags():
|
||||
if tag == html['desc']:
|
||||
cursor = self.textCursor()
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# Copyright (c) 2008-2017 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# Copyright (c) 2008-2017 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# Copyright (c) 2008-2017 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
|
@ -26,7 +26,7 @@ import os
|
|||
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
|
||||
from openlp.core.common import Registry
|
||||
from openlp.core.common import Registry, is_win
|
||||
|
||||
|
||||
class TreeWidgetWithDnD(QtWidgets.QTreeWidget):
|
||||
|
@ -108,6 +108,11 @@ class TreeWidgetWithDnD(QtWidgets.QTreeWidget):
|
|||
|
||||
:param event: Handle of the event pint passed
|
||||
"""
|
||||
# If we are on Windows, OpenLP window will not be set on top. For example, user can drag images to Library and
|
||||
# the folder stays on top of the group creation box. This piece of code fixes this issue.
|
||||
if is_win():
|
||||
self.setWindowState(self.windowState() & ~QtCore.Qt.WindowMinimized | QtCore.Qt.WindowActive)
|
||||
self.setWindowState(QtCore.Qt.WindowNoState)
|
||||
if event.mimeData().hasUrls():
|
||||
event.setDropAction(QtCore.Qt.CopyAction)
|
||||
event.accept()
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# Copyright (c) 2008-2017 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# Copyright (c) 2008-2017 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# Copyright (c) 2008-2017 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
|
@ -298,8 +298,8 @@ class UiAboutDialog(object):
|
|||
self.about_notebook.setTabText(self.about_notebook.indexOf(self.credits_tab),
|
||||
translate('OpenLP.AboutForm', 'Credits'))
|
||||
copyright_note = translate('OpenLP.AboutForm',
|
||||
'Copyright \xa9 2004-2016 %s\n'
|
||||
'Portions copyright \xa9 2004-2016 %s') % \
|
||||
'Copyright (c) 2004-2017 %s\n'
|
||||
'Portions copyright (c) 2004-2017 %s') % \
|
||||
('Raoul Snyman',
|
||||
'Tim Bentley, Gerald Britton, Jonathan Corwin, Samuel Findlay, '
|
||||
'Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, '
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# Copyright (c) 2008-2017 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# Copyright (c) 2008-2017 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# Copyright (c) 2008-2017 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# Copyright (c) 2008-2017 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
|
@ -180,11 +180,13 @@ class ExceptionForm(QtWidgets.QDialog, Ui_ExceptionDialog, RegistryProperties):
|
|||
if ':' in line:
|
||||
exception = line.split('\n')[-1].split(':')[0]
|
||||
subject = 'Bug report: %s in %s' % (exception, source)
|
||||
mail_to_url = QtCore.QUrlQuery('mailto:bugs@openlp.org')
|
||||
mail_to_url.addQueryItem('subject', subject)
|
||||
mail_to_url.addQueryItem('body', self.report_text % content)
|
||||
mail_urlquery = QtCore.QUrlQuery()
|
||||
mail_urlquery.addQueryItem('subject', subject)
|
||||
mail_urlquery.addQueryItem('body', self.report_text % content)
|
||||
if self.file_attachment:
|
||||
mail_to_url.addQueryItem('attach', self.file_attachment)
|
||||
mail_urlquery.addQueryItem('attach', self.file_attachment)
|
||||
mail_to_url = QtCore.QUrl('mailto:bugs@openlp.org')
|
||||
mail_to_url.setQuery(mail_urlquery)
|
||||
QtGui.QDesktopServices.openUrl(mail_to_url)
|
||||
|
||||
def on_description_updated(self):
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# Copyright (c) 2008-2017 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# Copyright (c) 2008-2017 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# Copyright (c) 2008-2017 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# Copyright (c) 2008-2017 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# Copyright (c) 2008-2017 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# Copyright (c) 2008-2017 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# Copyright (c) 2008-2017 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# Copyright (c) 2008-2017 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# Copyright (c) 2008-2017 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# Copyright (c) 2008-2017 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
|
@ -159,7 +159,6 @@ class GeneralTab(SettingsTab):
|
|||
self.startup_layout.addWidget(self.show_splash_check_box)
|
||||
self.check_for_updates_check_box = QtWidgets.QCheckBox(self.startup_group_box)
|
||||
self.check_for_updates_check_box.setObjectName('check_for_updates_check_box')
|
||||
self.check_for_updates_check_box.setVisible(False)
|
||||
self.startup_layout.addWidget(self.check_for_updates_check_box)
|
||||
self.right_layout.addWidget(self.startup_group_box)
|
||||
# Application Settings
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# Copyright (c) 2008-2017 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# Copyright (c) 2008-2017 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
|
@ -672,7 +672,7 @@ class AudioPlayer(OpenLPMixin, QtCore.QObject):
|
|||
"""
|
||||
Skip forward to the next track in the list
|
||||
"""
|
||||
self.player.next()
|
||||
self.playlist.next()
|
||||
|
||||
def go_to(self, index):
|
||||
"""
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# Copyright (c) 2008-2017 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
|
@ -52,21 +52,17 @@ from openlp.core.ui.printserviceform import PrintServiceForm
|
|||
log = logging.getLogger(__name__)
|
||||
|
||||
MEDIA_MANAGER_STYLE = """
|
||||
QToolBox {
|
||||
padding-bottom: 2px;
|
||||
}
|
||||
QToolBox::tab {
|
||||
::tab#media_tool_box {
|
||||
background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
|
||||
stop: 0 palette(button), stop: 1.0 palette(mid));
|
||||
border: 1px solid palette(mid);
|
||||
border-radius: 3px;
|
||||
}
|
||||
QToolBox::tab:selected {
|
||||
background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
|
||||
stop: 0 palette(light), stop: 1.0 palette(button));
|
||||
border: 1px solid palette(mid);
|
||||
font-weight: bold;
|
||||
border: 0;
|
||||
border-radius: 2px;
|
||||
margin-bottom: 0;
|
||||
margin-top: 0;
|
||||
text-align: left;
|
||||
}
|
||||
/* This is here to make the tabs on KDE with the Breeze theme work */
|
||||
::tab:selected {}
|
||||
"""
|
||||
|
||||
PROGRESSBAR_STYLE = """
|
||||
|
@ -180,6 +176,7 @@ class Ui_MainWindow(object):
|
|||
self.projector_manager_contents = ProjectorManager(self.projector_manager_dock)
|
||||
self.projector_manager_contents.setObjectName('projector_manager_contents')
|
||||
self.projector_manager_dock.setWidget(self.projector_manager_contents)
|
||||
self.projector_manager_dock.setVisible(False)
|
||||
main_window.addDockWidget(QtCore.Qt.RightDockWidgetArea, self.projector_manager_dock)
|
||||
# Create the menu items
|
||||
action_list = ActionList.get_instance()
|
||||
|
@ -192,7 +189,7 @@ class Ui_MainWindow(object):
|
|||
triggers=self.service_manager_contents.on_load_service_clicked)
|
||||
self.file_save_item = create_action(main_window, 'fileSaveItem', icon=':/general/general_save.png',
|
||||
can_shortcuts=True, category=UiStrings().File,
|
||||
triggers=self.service_manager_contents.save_file)
|
||||
triggers=self.service_manager_contents.decide_save_method)
|
||||
self.file_save_as_item = create_action(main_window, 'fileSaveAsItem', can_shortcuts=True,
|
||||
category=UiStrings().File,
|
||||
triggers=self.service_manager_contents.save_file_as)
|
||||
|
@ -799,7 +796,7 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow, RegistryProperties):
|
|||
Open data folder
|
||||
"""
|
||||
path = AppLocation.get_data_path()
|
||||
QtGui.QDesktopServices.openUrl(QtCore.QUrl("file:///" + path))
|
||||
QtGui.QDesktopServices.openUrl(QtCore.QUrl.fromLocalFile(path))
|
||||
|
||||
def on_update_theme_images(self):
|
||||
"""
|
||||
|
@ -1379,7 +1376,9 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow, RegistryProperties):
|
|||
if event.timerId() == self.timer_id:
|
||||
self.timer_id = 0
|
||||
self.load_progress_bar.hide()
|
||||
self.application.process_events()
|
||||
# Sometimes the timer goes off as OpenLP is shutting down, and the application has already been deleted
|
||||
if self.application:
|
||||
self.application.process_events()
|
||||
|
||||
def set_new_data_path(self, new_data_path):
|
||||
"""
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# Copyright (c) 2008-2017 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# Copyright (c) 2008-2017 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# Copyright (c) 2008-2017 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# Copyright (c) 2008-2017 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
|
|
|
@ -100,7 +100,7 @@ class SystemPlayer(MediaPlayer):
|
|||
ext = '*%s' % extension
|
||||
if ext not in mime_type_list:
|
||||
mime_type_list.append(ext)
|
||||
log.info('MediaPlugin: %s extensions: %s' % (mimetype, ' '.join(extensions)))
|
||||
log.info('MediaPlugin: %s extensions: %s', mimetype, ' '.join(extensions))
|
||||
|
||||
def setup(self, display):
|
||||
"""
|
||||
|
@ -160,6 +160,13 @@ class SystemPlayer(MediaPlayer):
|
|||
if start_time > 0:
|
||||
self.seek(display, controller.media_info.start_time * 1000)
|
||||
self.volume(display, controller.media_info.volume)
|
||||
display.media_player.blockSignals(True)
|
||||
try:
|
||||
display.media_player.durationChanged.disconnect()
|
||||
except TypeError:
|
||||
# We get a type error if there are no slots attached to this signal, so ignore it
|
||||
pass
|
||||
display.media_player.blockSignals(False)
|
||||
display.media_player.durationChanged.connect(functools.partial(self.set_duration, controller))
|
||||
self.state = MediaState.Playing
|
||||
display.video_widget.raise_()
|
||||
|
@ -178,7 +185,11 @@ class SystemPlayer(MediaPlayer):
|
|||
Stop the current media item
|
||||
"""
|
||||
display.media_player.blockSignals(True)
|
||||
display.media_player.durationChanged.disconnect()
|
||||
try:
|
||||
display.media_player.durationChanged.disconnect()
|
||||
except TypeError:
|
||||
# We get a type error if there are no slots attached to this signal, so ignore it
|
||||
pass
|
||||
display.media_player.blockSignals(False)
|
||||
display.media_player.stop()
|
||||
self.set_visible(display, False)
|
||||
|
@ -216,6 +227,9 @@ class SystemPlayer(MediaPlayer):
|
|||
|
||||
@staticmethod
|
||||
def set_duration(controller, duration):
|
||||
"""
|
||||
Set the length of the seek slider
|
||||
"""
|
||||
controller.media_info.length = int(duration / 1000)
|
||||
controller.seek_slider.setMaximum(controller.media_info.length * 1000)
|
||||
|
||||
|
@ -261,33 +275,34 @@ class SystemPlayer(MediaPlayer):
|
|||
:return: True if file can be played otherwise False
|
||||
"""
|
||||
thread = QtCore.QThread()
|
||||
check_media_player = CheckMedia(path)
|
||||
check_media_player.setVolume(0)
|
||||
check_media_player.moveToThread(thread)
|
||||
check_media_player.finished.connect(thread.quit)
|
||||
thread.started.connect(check_media_player.play)
|
||||
check_media_worker = CheckMediaWorker(path)
|
||||
check_media_worker.setVolume(0)
|
||||
check_media_worker.moveToThread(thread)
|
||||
check_media_worker.finished.connect(thread.quit)
|
||||
thread.started.connect(check_media_worker.play)
|
||||
thread.start()
|
||||
while thread.isRunning():
|
||||
self.application.processEvents()
|
||||
return check_media_player.result
|
||||
return check_media_worker.result
|
||||
|
||||
|
||||
class CheckMedia(QtMultimedia.QMediaPlayer):
|
||||
class CheckMediaWorker(QtMultimedia.QMediaPlayer):
|
||||
"""
|
||||
Class used to check if a media file is playable
|
||||
"""
|
||||
finished = QtCore.pyqtSignal()
|
||||
|
||||
def __init__(self, path):
|
||||
super(CheckMedia, self).__init__(None, QtMultimedia.QMediaPlayer.VideoSurface)
|
||||
super(CheckMediaWorker, self).__init__(None, QtMultimedia.QMediaPlayer.VideoSurface)
|
||||
self.result = None
|
||||
|
||||
self.error.connect(functools.partial(self.signals, 'error'))
|
||||
self.mediaStatusChanged.connect(functools.partial(self.signals, 'media'))
|
||||
|
||||
self.setMedia(QtMultimedia.QMediaContent(QtCore.QUrl.fromLocalFile(path)))
|
||||
|
||||
def signals(self, origin, status):
|
||||
"""
|
||||
Exit the worker and stop the thread when either an error or a media change is encountered
|
||||
"""
|
||||
if origin == 'media' and status == self.BufferedMedia:
|
||||
self.result = True
|
||||
self.stop()
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# Copyright (c) 2008-2017 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# Copyright (c) 2008-2017 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# Copyright (c) 2008-2017 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# Copyright (c) 2008-2017 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
|
@ -54,7 +54,7 @@ class MediaDockManager(object):
|
|||
match = True
|
||||
break
|
||||
if not match:
|
||||
self.media_dock.addItem(media_item, visible_title['title'])
|
||||
self.media_dock.addItem(media_item, media_item.plugin.icon, visible_title['title'])
|
||||
|
||||
def remove_dock(self, media_item):
|
||||
"""
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# Copyright (c) 2008-2017 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# Copyright (c) 2008-2017 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# Copyright (c) 2008-2017 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# Copyright (c) 2008-2017 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# Copyright (c) 2008-2017 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# Copyright (c) 2008-2017 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# Copyright (c) 2008-2017 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
|
@ -61,6 +61,9 @@ STATUS_ICONS = {S_NOT_CONNECTED: ':/projector/projector_item_disconnect.png',
|
|||
E_NOT_CONNECTED: ':/projector/projector_not_connected_error.png'
|
||||
}
|
||||
|
||||
STATUS_NETWORK_BUSY = [S_CONNECTING, S_NETWORK_SENDING]
|
||||
STATUS_NETWORK_FREE = [E_NETWORK, E_UNKNOWN_SOCKET_ERROR, E_NOT_CONNECTED, S_NETWORK_RECEIVED]
|
||||
|
||||
|
||||
class Ui_ProjectorManager(object):
|
||||
"""
|
||||
|
@ -288,6 +291,8 @@ class ProjectorManager(OpenLPMixin, RegistryMixin, QWidget, Ui_ProjectorManager,
|
|||
self.projectordb = projectordb
|
||||
self.projector_list = []
|
||||
self.source_select_form = None
|
||||
self.network_list = {} # Currently active network communications keyed on IP
|
||||
self.network_busy = False
|
||||
|
||||
def bootstrap_initialise(self):
|
||||
"""
|
||||
|
@ -482,7 +487,7 @@ class ProjectorManager(OpenLPMixin, RegistryMixin, QWidget, Ui_ProjectorManager,
|
|||
if ans == msg.Cancel:
|
||||
return
|
||||
try:
|
||||
projector.link.projectorNetwork.disconnect(self.update_status)
|
||||
projector.link.projectorNetwork.disconnect(self.update_network_status)
|
||||
except (AttributeError, TypeError):
|
||||
pass
|
||||
try:
|
||||
|
@ -720,7 +725,7 @@ class ProjectorManager(OpenLPMixin, RegistryMixin, QWidget, Ui_ProjectorManager,
|
|||
thread.started.connect(item.link.thread_started)
|
||||
thread.finished.connect(item.link.thread_stopped)
|
||||
thread.finished.connect(thread.deleteLater)
|
||||
item.link.projectorNetwork.connect(self.update_status)
|
||||
item.link.projectorNetwork.connect(self.update_network_status)
|
||||
item.link.changeStatus.connect(self.update_status)
|
||||
item.link.projectorAuthentication.connect(self.authentication_error)
|
||||
item.link.projectorNoAuthentication.connect(self.no_authentication_error)
|
||||
|
@ -790,6 +795,39 @@ class ProjectorManager(OpenLPMixin, RegistryMixin, QWidget, Ui_ProjectorManager,
|
|||
"""
|
||||
return self.projector_list
|
||||
|
||||
@pyqtSlot(str, int)
|
||||
def update_network_status(self, ip, status):
|
||||
"""
|
||||
Update network busy icon
|
||||
|
||||
NOTE: Placeholder for bugfix 1588369. Permanent fix will be in trunk for 2.6.
|
||||
|
||||
:param ip: IP of destination
|
||||
:param status: Status code
|
||||
"""
|
||||
log.debug('update_network_status(ip="%s" status=%d)' % (ip, status))
|
||||
# Keep track of what connections are currently being chatty
|
||||
if status in STATUS_NETWORK_BUSY:
|
||||
if ip not in self.network_list:
|
||||
log.debug('Adding %s to network list' % ip)
|
||||
self.network_list[ip] = status
|
||||
elif status in STATUS_NETWORK_FREE:
|
||||
if ip in self.network_list:
|
||||
log.debug('Removing %s from network list' % ip)
|
||||
self.network_list.pop(ip)
|
||||
else:
|
||||
log.warn('"%s" not in network list - something got dropped in setting?')
|
||||
else:
|
||||
log.warn('Unknown network status update: ip="%s" stutus: %s' % (ip, status))
|
||||
# Check for turnin on/off network busy icon
|
||||
if self.network_list:
|
||||
log.debug('network list: %s' % self.network_list)
|
||||
log.debug('Turning on network busy icon')
|
||||
self.network_busy = True
|
||||
else:
|
||||
log.debug('No network chatter - turning off network busy icon')
|
||||
self.network_busy = False
|
||||
|
||||
@pyqtSlot(str, int, str)
|
||||
def update_status(self, ip, status=None, msg=None):
|
||||
"""
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# Copyright (c) 2008-2017 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
|
@ -20,24 +20,21 @@
|
|||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||
###############################################################################
|
||||
"""
|
||||
:mod: `openlp.core.ui.projector.sourceselectform` module
|
||||
:mod: `openlp.core.ui.projector.sourceselectform` module
|
||||
|
||||
Provides the dialog window for selecting video source for projector.
|
||||
Provides the dialog window for selecting video source for projector.
|
||||
"""
|
||||
import logging
|
||||
log = logging.getLogger(__name__)
|
||||
log.debug('editform loaded')
|
||||
|
||||
from PyQt5 import QtCore, QtWidgets
|
||||
from PyQt5.QtCore import pyqtSlot, QSize
|
||||
from PyQt5.QtWidgets import QDialog, QButtonGroup, QDialogButtonBox, QFormLayout, QLineEdit, QRadioButton, \
|
||||
QStyle, QStylePainter, QStyleOptionTab, QTabBar, QTabWidget, QVBoxLayout, QWidget
|
||||
|
||||
from openlp.core.common import translate, is_macosx
|
||||
from openlp.core.lib import build_icon
|
||||
from openlp.core.lib.projector.db import ProjectorSource
|
||||
from openlp.core.lib.projector.constants import PJLINK_DEFAULT_SOURCES, PJLINK_DEFAULT_CODES
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def source_group(inputs, source_text):
|
||||
"""
|
||||
|
@ -64,9 +61,8 @@ def source_group(inputs, source_text):
|
|||
"""
|
||||
groupdict = {}
|
||||
keydict = {}
|
||||
checklist = inputs
|
||||
key = checklist[0][0]
|
||||
for item in checklist:
|
||||
key = inputs[0][0]
|
||||
for item in inputs:
|
||||
if item[0] == key:
|
||||
groupdict[item] = source_text[item]
|
||||
continue
|
||||
|
@ -78,7 +74,7 @@ def source_group(inputs, source_text):
|
|||
return keydict
|
||||
|
||||
|
||||
def Build_Tab(group, source_key, default, projector, projectordb, edit=False):
|
||||
def build_tab(group, source_key, default, projector, projectordb, edit=False):
|
||||
"""
|
||||
Create the radio button page for a tab.
|
||||
Dictionary will be a 1-key entry where key=tab to setup, val=list of inputs.
|
||||
|
@ -104,8 +100,8 @@ def Build_Tab(group, source_key, default, projector, projectordb, edit=False):
|
|||
:param edit: If we're editing the source text
|
||||
"""
|
||||
buttonchecked = False
|
||||
widget = QWidget()
|
||||
layout = QFormLayout() if edit else QVBoxLayout()
|
||||
widget = QtWidgets.QWidget()
|
||||
layout = QtWidgets.QFormLayout() if edit else QtWidgets.QVBoxLayout()
|
||||
layout.setSpacing(10)
|
||||
widget.setLayout(layout)
|
||||
tempkey = list(source_key.keys())[0] # Should only be 1 key
|
||||
|
@ -114,7 +110,7 @@ def Build_Tab(group, source_key, default, projector, projectordb, edit=False):
|
|||
button_count = len(sourcelist)
|
||||
if edit:
|
||||
for key in sourcelist:
|
||||
item = QLineEdit()
|
||||
item = QtWidgets.QLineEdit()
|
||||
item.setObjectName('source_key_%s' % key)
|
||||
source_item = projectordb.get_source_by_code(code=key, projector_id=projector.db_item.id)
|
||||
if source_item is None:
|
||||
|
@ -130,7 +126,7 @@ def Build_Tab(group, source_key, default, projector, projectordb, edit=False):
|
|||
text = source_key[tempkey][key]
|
||||
else:
|
||||
text = source_item.text
|
||||
itemwidget = QRadioButton(text)
|
||||
itemwidget = QtWidgets.QRadioButton(text)
|
||||
itemwidget.setAutoExclusive(True)
|
||||
if default == key:
|
||||
itemwidget.setChecked(True)
|
||||
|
@ -141,30 +137,30 @@ def Build_Tab(group, source_key, default, projector, projectordb, edit=False):
|
|||
return widget, button_count, buttonchecked
|
||||
|
||||
|
||||
def set_button_tooltip(bar):
|
||||
def set_button_tooltip(button_bar):
|
||||
"""
|
||||
Set the toolip for the standard buttons used
|
||||
|
||||
:param bar: QDialogButtonBar instance to update
|
||||
"""
|
||||
for button in bar.buttons():
|
||||
if bar.standardButton(button) == QDialogButtonBox.Cancel:
|
||||
for button in button_bar.buttons():
|
||||
if button_bar.standardButton(button) == QtWidgets.QDialogButtonBox.Cancel:
|
||||
button.setToolTip(translate('OpenLP.SourceSelectForm',
|
||||
'Ignoring current changes and return to OpenLP'))
|
||||
elif bar.standardButton(button) == QDialogButtonBox.Reset:
|
||||
elif button_bar.standardButton(button) == QtWidgets.QDialogButtonBox.Reset:
|
||||
button.setToolTip(translate('OpenLP.SourceSelectForm',
|
||||
'Delete all user-defined text and revert to PJLink default text'))
|
||||
elif bar.standardButton(button) == QDialogButtonBox.Discard:
|
||||
elif button_bar.standardButton(button) == QtWidgets.QDialogButtonBox.Discard:
|
||||
button.setToolTip(translate('OpenLP.SourceSelectForm',
|
||||
'Discard changes and reset to previous user-defined text'))
|
||||
elif bar.standardButton(button) == QDialogButtonBox.Ok:
|
||||
elif button_bar.standardButton(button) == QtWidgets.QDialogButtonBox.Ok:
|
||||
button.setToolTip(translate('OpenLP.SourceSelectForm',
|
||||
'Save changes and return to OpenLP'))
|
||||
else:
|
||||
log.debug('No tooltip for button {}'.format(button.text()))
|
||||
log.debug('No tooltip for button %s', button.text())
|
||||
|
||||
|
||||
class FingerTabBarWidget(QTabBar):
|
||||
class FingerTabBarWidget(QtWidgets.QTabBar):
|
||||
"""
|
||||
Realign west -orientation tabs to left-right text rather than south-north text
|
||||
Borrowed from
|
||||
|
@ -177,8 +173,8 @@ class FingerTabBarWidget(QTabBar):
|
|||
:param width: Remove default width parameter in kwargs
|
||||
:param height: Remove default height parameter in kwargs
|
||||
"""
|
||||
self.tabSize = QSize(kwargs.pop('width', 100), kwargs.pop('height', 25))
|
||||
QTabBar.__init__(self, parent, *args, **kwargs)
|
||||
self.tabSize = QtCore.QSize(kwargs.pop('width', 100), kwargs.pop('height', 25))
|
||||
QtWidgets.QTabBar.__init__(self, parent, *args, **kwargs)
|
||||
|
||||
def paintEvent(self, event):
|
||||
"""
|
||||
|
@ -186,14 +182,14 @@ class FingerTabBarWidget(QTabBar):
|
|||
|
||||
:param event: Repaint event signal
|
||||
"""
|
||||
painter = QStylePainter(self)
|
||||
option = QStyleOptionTab()
|
||||
painter = QtWidgets.QStylePainter(self)
|
||||
option = QtWidgets.QStyleOptionTab()
|
||||
|
||||
for index in range(self.count()):
|
||||
self.initStyleOption(option, index)
|
||||
tabRect = self.tabRect(index)
|
||||
tabRect.moveLeft(10)
|
||||
painter.drawControl(QStyle.CE_TabBarTabShape, option)
|
||||
painter.drawControl(QtWidgets.QStyle.CE_TabBarTabShape, option)
|
||||
painter.drawText(tabRect, QtCore.Qt.AlignVCenter |
|
||||
QtCore.Qt.TextDontClip,
|
||||
self.tabText(index))
|
||||
|
@ -209,7 +205,7 @@ class FingerTabBarWidget(QTabBar):
|
|||
return self.tabSize
|
||||
|
||||
|
||||
class FingerTabWidget(QTabWidget):
|
||||
class FingerTabWidget(QtWidgets.QTabWidget):
|
||||
"""
|
||||
A QTabWidget equivalent which uses our FingerTabBarWidget
|
||||
|
||||
|
@ -220,11 +216,11 @@ class FingerTabWidget(QTabWidget):
|
|||
"""
|
||||
Initialize FingerTabWidget instance
|
||||
"""
|
||||
QTabWidget.__init__(self, parent, *args)
|
||||
QtWidgets.QTabWidget.__init__(self, parent, *args)
|
||||
self.setTabBar(FingerTabBarWidget(self))
|
||||
|
||||
|
||||
class SourceSelectTabs(QDialog):
|
||||
class SourceSelectTabs(QtWidgets.QDialog):
|
||||
"""
|
||||
Class for handling selecting the source for the projector to use.
|
||||
Uses tabbed interface.
|
||||
|
@ -248,18 +244,18 @@ class SourceSelectTabs(QDialog):
|
|||
self.setObjectName('source_select_tabs')
|
||||
self.setWindowIcon(build_icon(':/icon/openlp-log-32x32.png'))
|
||||
self.setModal(True)
|
||||
self.layout = QVBoxLayout()
|
||||
self.layout = QtWidgets.QVBoxLayout()
|
||||
self.layout.setObjectName('source_select_tabs_layout')
|
||||
if is_macosx():
|
||||
self.tabwidget = QTabWidget(self)
|
||||
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(QTabWidget.North)
|
||||
self.tabwidget.setTabPosition(QtWidgets.QTabWidget.North)
|
||||
else:
|
||||
self.tabwidget.setTabPosition(QTabWidget.West)
|
||||
self.tabwidget.setTabPosition(QtWidgets.QTabWidget.West)
|
||||
self.layout.addWidget(self.tabwidget)
|
||||
self.setLayout(self.layout)
|
||||
|
||||
|
@ -273,12 +269,12 @@ class SourceSelectTabs(QDialog):
|
|||
self.source_text = self.projectordb.get_source_list(projector=projector)
|
||||
self.source_group = source_group(projector.source_available, self.source_text)
|
||||
# self.source_group = {'4': {'41': 'Storage 1'}, '5': {"51": 'Network 1'}}
|
||||
self.button_group = [] if self.edit else QButtonGroup()
|
||||
self.button_group = [] if self.edit else QtWidgets.QButtonGroup()
|
||||
keys = list(self.source_group.keys())
|
||||
keys.sort()
|
||||
if self.edit:
|
||||
for key in keys:
|
||||
(tab, button_count, buttonchecked) = Build_Tab(group=self.button_group,
|
||||
(tab, button_count, buttonchecked) = build_tab(group=self.button_group,
|
||||
source_key={key: self.source_group[key]},
|
||||
default=self.projector.source,
|
||||
projector=self.projector,
|
||||
|
@ -287,13 +283,13 @@ class SourceSelectTabs(QDialog):
|
|||
thistab = self.tabwidget.addTab(tab, PJLINK_DEFAULT_SOURCES[key])
|
||||
if buttonchecked:
|
||||
self.tabwidget.setCurrentIndex(thistab)
|
||||
self.button_box = QDialogButtonBox(QtWidgets.QDialogButtonBox.Reset |
|
||||
QtWidgets.QDialogButtonBox.Discard |
|
||||
QtWidgets.QDialogButtonBox.Ok |
|
||||
QtWidgets.QDialogButtonBox.Cancel)
|
||||
self.button_box = QtWidgets.QDialogButtonBox(QtWidgets.QDialogButtonBox.Reset |
|
||||
QtWidgets.QDialogButtonBox.Discard |
|
||||
QtWidgets.QDialogButtonBox.Ok |
|
||||
QtWidgets.QDialogButtonBox.Cancel)
|
||||
else:
|
||||
for key in keys:
|
||||
(tab, button_count, buttonchecked) = Build_Tab(group=self.button_group,
|
||||
(tab, button_count, buttonchecked) = build_tab(group=self.button_group,
|
||||
source_key={key: self.source_group[key]},
|
||||
default=self.projector.source,
|
||||
projector=self.projector,
|
||||
|
@ -302,15 +298,15 @@ class SourceSelectTabs(QDialog):
|
|||
thistab = self.tabwidget.addTab(tab, PJLINK_DEFAULT_SOURCES[key])
|
||||
if buttonchecked:
|
||||
self.tabwidget.setCurrentIndex(thistab)
|
||||
self.button_box = QDialogButtonBox(QtWidgets.QDialogButtonBox.Ok |
|
||||
QtWidgets.QDialogButtonBox.Cancel)
|
||||
self.button_box = QtWidgets.QDialogButtonBox(QtWidgets.QDialogButtonBox.Ok |
|
||||
QtWidgets.QDialogButtonBox.Cancel)
|
||||
self.button_box.clicked.connect(self.button_clicked)
|
||||
self.layout.addWidget(self.button_box)
|
||||
set_button_tooltip(self.button_box)
|
||||
selected = super(SourceSelectTabs, self).exec()
|
||||
return selected
|
||||
|
||||
@pyqtSlot(object)
|
||||
@QtCore.pyqtSlot(QtWidgets.QAbstractButton)
|
||||
def button_clicked(self, button):
|
||||
"""
|
||||
Checks which button was clicked
|
||||
|
@ -333,6 +329,9 @@ class SourceSelectTabs(QDialog):
|
|||
return 100
|
||||
|
||||
def delete_sources(self):
|
||||
"""
|
||||
Delete the source
|
||||
"""
|
||||
msg = QtWidgets.QMessageBox()
|
||||
msg.setText(translate('OpenLP.SourceSelectForm', 'Delete entries for this projector'))
|
||||
msg.setInformativeText(translate('OpenLP.SourceSelectForm',
|
||||
|
@ -359,20 +358,20 @@ class SourceSelectTabs(QDialog):
|
|||
continue
|
||||
item = self.projectordb.get_source_by_code(code=code, projector_id=projector.id)
|
||||
if item is None:
|
||||
log.debug("(%s) Adding new source text %s: %s" % (projector.ip, code, text))
|
||||
log.debug("(%s) Adding new source text %s: %s", projector.ip, code, text)
|
||||
item = ProjectorSource(projector_id=projector.id, code=code, text=text)
|
||||
else:
|
||||
item.text = text
|
||||
log.debug('(%s) Updating source code %s with text="%s"' % (projector.ip, item.code, item.text))
|
||||
log.debug('(%s) Updating source code %s with text="%s"', projector.ip, item.code, item.text)
|
||||
self.projectordb.add_source(item)
|
||||
selected = 0
|
||||
else:
|
||||
selected = self.button_group.checkedId()
|
||||
log.debug('SourceSelectTabs().accepted() Setting source to %s' % selected)
|
||||
log.debug('SourceSelectTabs().accepted() Setting source to %s', selected)
|
||||
self.done(selected)
|
||||
|
||||
|
||||
class SourceSelectSingle(QDialog):
|
||||
class SourceSelectSingle(QtWidgets.QDialog):
|
||||
"""
|
||||
Class for handling selecting the source for the projector to use.
|
||||
Uses single dialog interface.
|
||||
|
@ -393,6 +392,7 @@ class SourceSelectSingle(QDialog):
|
|||
title = translate('OpenLP.SourceSelectForm', 'Select Projector Source')
|
||||
self.setObjectName('source_select_single')
|
||||
self.setWindowIcon(build_icon(':/icon/openlp-log-32x32.png'))
|
||||
self.setWindowTitle(title)
|
||||
self.setModal(True)
|
||||
self.edit = edit
|
||||
|
||||
|
@ -403,12 +403,12 @@ class SourceSelectSingle(QDialog):
|
|||
:param projector: Projector instance to build source list from
|
||||
"""
|
||||
self.projector = projector
|
||||
self.layout = QFormLayout() if self.edit else QVBoxLayout()
|
||||
self.layout = QtWidgets.QFormLayout() if self.edit else QtWidgets.QVBoxLayout()
|
||||
self.layout.setObjectName('source_select_tabs_layout')
|
||||
self.layout.setSpacing(10)
|
||||
self.setLayout(self.layout)
|
||||
self.setMinimumWidth(350)
|
||||
self.button_group = [] if self.edit else QButtonGroup()
|
||||
self.button_group = [] if self.edit else QtWidgets.QButtonGroup()
|
||||
self.source_text = self.projectordb.get_source_list(projector=projector)
|
||||
keys = list(self.source_text.keys())
|
||||
keys.sort()
|
||||
|
@ -416,7 +416,7 @@ class SourceSelectSingle(QDialog):
|
|||
button_list = []
|
||||
if self.edit:
|
||||
for key in keys:
|
||||
item = QLineEdit()
|
||||
item = QtWidgets.QLineEdit()
|
||||
item.setObjectName('source_key_%s' % key)
|
||||
source_item = self.projectordb.get_source_by_code(code=key, projector_id=self.projector.db_item.id)
|
||||
if source_item is None:
|
||||
|
@ -426,10 +426,10 @@ class SourceSelectSingle(QDialog):
|
|||
item.setText(source_item.text)
|
||||
self.layout.addRow(PJLINK_DEFAULT_CODES[key], item)
|
||||
self.button_group.append(item)
|
||||
self.button_box = QDialogButtonBox(QtWidgets.QDialogButtonBox.Reset |
|
||||
QtWidgets.QDialogButtonBox.Discard |
|
||||
QtWidgets.QDialogButtonBox.Ok |
|
||||
QtWidgets.QDialogButtonBox.Cancel)
|
||||
self.button_box = QtWidgets.QDialogButtonBox(QtWidgets.QDialogButtonBox.Reset |
|
||||
QtWidgets.QDialogButtonBox.Discard |
|
||||
QtWidgets.QDialogButtonBox.Ok |
|
||||
QtWidgets.QDialogButtonBox.Cancel)
|
||||
else:
|
||||
for key in keys:
|
||||
source_text = self.projectordb.get_source_by_code(code=key, projector_id=self.projector.db_item.id)
|
||||
|
@ -439,8 +439,8 @@ class SourceSelectSingle(QDialog):
|
|||
self.layout.addWidget(button)
|
||||
self.button_group.addButton(button, int(key))
|
||||
button_list.append(key)
|
||||
self.button_box = QDialogButtonBox(QtWidgets.QDialogButtonBox.Ok |
|
||||
QtWidgets.QDialogButtonBox.Cancel)
|
||||
self.button_box = QtWidgets.QDialogButtonBox(QtWidgets.QDialogButtonBox.Ok |
|
||||
QtWidgets.QDialogButtonBox.Cancel)
|
||||
self.button_box.clicked.connect(self.button_clicked)
|
||||
self.layout.addWidget(self.button_box)
|
||||
self.setMinimumHeight(key_count * 25)
|
||||
|
@ -448,7 +448,7 @@ class SourceSelectSingle(QDialog):
|
|||
selected = super(SourceSelectSingle, self).exec()
|
||||
return selected
|
||||
|
||||
@pyqtSlot(object)
|
||||
@QtCore.pyqtSlot(QtWidgets.QAbstractButton)
|
||||
def button_clicked(self, button):
|
||||
"""
|
||||
Checks which button was clicked
|
||||
|
@ -471,6 +471,9 @@ class SourceSelectSingle(QDialog):
|
|||
return 100
|
||||
|
||||
def delete_sources(self):
|
||||
"""
|
||||
Delete all the entries for this projector
|
||||
"""
|
||||
msg = QtWidgets.QMessageBox()
|
||||
msg.setText(translate('OpenLP.SourceSelectForm', 'Delete entries for this projector'))
|
||||
msg.setInformativeText(translate('OpenLP.SourceSelectForm',
|
||||
|
@ -484,7 +487,7 @@ class SourceSelectSingle(QDialog):
|
|||
self.projectordb.delete_all_objects(ProjectorSource, ProjectorSource.projector_id == self.projector.db_item.id)
|
||||
self.done(100)
|
||||
|
||||
@pyqtSlot()
|
||||
@QtCore.pyqtSlot()
|
||||
def accept_me(self):
|
||||
"""
|
||||
Slot to accept 'OK' button
|
||||
|
@ -498,14 +501,14 @@ class SourceSelectSingle(QDialog):
|
|||
continue
|
||||
item = self.projectordb.get_source_by_code(code=code, projector_id=projector.id)
|
||||
if item is None:
|
||||
log.debug("(%s) Adding new source text %s: %s" % (projector.ip, code, text))
|
||||
log.debug('(%s) Adding new source text %s: %s', projector.ip, code, text)
|
||||
item = ProjectorSource(projector_id=projector.id, code=code, text=text)
|
||||
else:
|
||||
item.text = text
|
||||
log.debug('(%s) Updating source code %s with text="%s"' % (projector.ip, item.code, item.text))
|
||||
log.debug('(%s) Updating source code %s with text="%s"', projector.ip, item.code, item.text)
|
||||
self.projectordb.add_source(item)
|
||||
selected = 0
|
||||
else:
|
||||
selected = self.button_group.checkedId()
|
||||
log.debug('SourceSelectDialog().accepted() Setting source to %s' % selected)
|
||||
log.debug('SourceSelectDialog().accepted() Setting source to %s', selected)
|
||||
self.done(selected)
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# Copyright (c) 2008-2017 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# Copyright (c) 2008-2017 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# Copyright (c) 2008-2017 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# Copyright (c) 2008-2017 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
|
@ -594,7 +594,7 @@ class ServiceManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ServiceMa
|
|||
if success:
|
||||
try:
|
||||
shutil.copy(temp_file_name, path_file_name)
|
||||
except shutil.Error:
|
||||
except (shutil.Error, PermissionError):
|
||||
return self.save_file_as()
|
||||
except OSError as ose:
|
||||
QtWidgets.QMessageBox.critical(self, translate('OpenLP.ServiceManager', 'Error Saving File'),
|
||||
|
@ -655,7 +655,7 @@ class ServiceManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ServiceMa
|
|||
if success:
|
||||
try:
|
||||
shutil.copy(temp_file_name, path_file_name)
|
||||
except shutil.Error:
|
||||
except (shutil.Error, PermissionError):
|
||||
return self.save_file_as()
|
||||
self.main_window.add_recent_file(path_file_name)
|
||||
self.set_modified(False)
|
||||
|
@ -1321,9 +1321,10 @@ class ServiceManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ServiceMa
|
|||
"""
|
||||
The theme may have changed in the settings dialog so make sure the theme combo box is in the correct state.
|
||||
"""
|
||||
visible = self.renderer.theme_level == ThemeLevel.Global
|
||||
self.theme_label.setVisible(visible)
|
||||
self.theme_combo_box.setVisible(visible)
|
||||
visible = self.renderer.theme_level != ThemeLevel.Global
|
||||
self.toolbar.actions['theme_combo_box'].setVisible(visible)
|
||||
self.toolbar.actions['theme_label'].setVisible(visible)
|
||||
self.regenerate_service_items()
|
||||
|
||||
def regenerate_service_items(self, changed=False):
|
||||
"""
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# Copyright (c) 2008-2017 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# Copyright (c) 2008-2017 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
|
@ -39,7 +39,7 @@ class Ui_SettingsDialog(object):
|
|||
"""
|
||||
settings_dialog.setObjectName('settings_dialog')
|
||||
settings_dialog.setWindowIcon(build_icon(u':/icon/openlp-logo.svg'))
|
||||
settings_dialog.resize(800, 700)
|
||||
settings_dialog.resize(920, 625)
|
||||
self.dialog_layout = QtWidgets.QGridLayout(settings_dialog)
|
||||
self.dialog_layout.setObjectName('dialog_layout')
|
||||
self.dialog_layout.setContentsMargins(8, 8, 8, 8)
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# Copyright (c) 2008-2017 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# Copyright (c) 2008-2017 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# Copyright (c) 2008-2017 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
|
@ -49,6 +49,8 @@ class ShortcutListForm(QtWidgets.QDialog, Ui_ShortcutListDialog, RegistryPropert
|
|||
self.changed_actions = {}
|
||||
self.action_list = ActionList.get_instance()
|
||||
self.dialog_was_shown = False
|
||||
self.default_radio_button.setEnabled(False)
|
||||
self.custom_radio_button.setEnabled(False)
|
||||
self.primary_push_button.toggled.connect(self.on_primary_push_button_clicked)
|
||||
self.alternate_push_button.toggled.connect(self.on_alternate_push_button_clicked)
|
||||
self.tree_widget.currentItemChanged.connect(self.on_current_item_changed)
|
||||
|
@ -110,8 +112,89 @@ class ShortcutListForm(QtWidgets.QDialog, Ui_ShortcutListDialog, RegistryPropert
|
|||
self.reload_shortcut_list()
|
||||
self._adjust_button(self.primary_push_button, False, False, '')
|
||||
self._adjust_button(self.alternate_push_button, False, False, '')
|
||||
self._set_controls_enabled(False)
|
||||
return QtWidgets.QDialog.exec(self)
|
||||
|
||||
def _validiate_shortcut(self, changing_action, key_sequence):
|
||||
"""
|
||||
Checks if the given ``changing_action `` can use the given ``key_sequence``. Returns ``True`` if the
|
||||
``key_sequence`` can be used by the action, otherwise displays a dialog and returns ``False``.
|
||||
|
||||
:param changing_action: The action which wants to use the ``key_sequence``.
|
||||
:param key_sequence: The key sequence which the action want so use.
|
||||
"""
|
||||
is_valid = True
|
||||
for category in self.action_list.categories:
|
||||
for action in category.actions:
|
||||
shortcuts = self._action_shortcuts(action)
|
||||
if key_sequence not in shortcuts:
|
||||
continue
|
||||
if action is changing_action:
|
||||
if self.primary_push_button.isChecked() and shortcuts.index(key_sequence) == 0:
|
||||
continue
|
||||
if self.alternate_push_button.isChecked() and shortcuts.index(key_sequence) == 1:
|
||||
continue
|
||||
# Have the same parent, thus they cannot have the same shortcut.
|
||||
if action.parent() is changing_action.parent():
|
||||
is_valid = False
|
||||
# The new shortcut is already assigned, but if both shortcuts are only valid in a different widget the
|
||||
# new shortcut is valid, because they will not interfere.
|
||||
if action.shortcutContext() in [QtCore.Qt.WindowShortcut, QtCore.Qt.ApplicationShortcut]:
|
||||
is_valid = False
|
||||
if changing_action.shortcutContext() in [QtCore.Qt.WindowShortcut, QtCore.Qt.ApplicationShortcut]:
|
||||
is_valid = False
|
||||
if not is_valid:
|
||||
self.main_window.warning_message(translate('OpenLP.ShortcutListDialog', 'Duplicate Shortcut'),
|
||||
translate('OpenLP.ShortcutListDialog',
|
||||
'The shortcut "%s" is already assigned to another action, please'
|
||||
' use a different shortcut.') %
|
||||
self.get_shortcut_string(key_sequence, for_display=True))
|
||||
self.dialog_was_shown = True
|
||||
return is_valid
|
||||
|
||||
def _action_shortcuts(self, action):
|
||||
"""
|
||||
This returns the shortcuts for the given ``action``, which also includes those shortcuts which are not saved
|
||||
yet but already assigned (as changes are applied when closing the dialog).
|
||||
"""
|
||||
if action in self.changed_actions:
|
||||
return self.changed_actions[action]
|
||||
return action.shortcuts()
|
||||
|
||||
def _current_item_action(self, item=None):
|
||||
"""
|
||||
Returns the action of the given ``item``. If no item is given, we return the action of the current item of
|
||||
the ``tree_widget``.
|
||||
"""
|
||||
if item is None:
|
||||
item = self.tree_widget.currentItem()
|
||||
if item is None:
|
||||
return
|
||||
return item.data(0, QtCore.Qt.UserRole)
|
||||
|
||||
def _adjust_button(self, button, checked=None, enabled=None, text=None):
|
||||
"""
|
||||
Can be called to adjust more properties of the given ``button`` at once.
|
||||
"""
|
||||
# Set the text before checking the button, because this emits a signal.
|
||||
if text is not None:
|
||||
button.setText(text)
|
||||
if checked is not None:
|
||||
button.setChecked(checked)
|
||||
if enabled is not None:
|
||||
button.setEnabled(enabled)
|
||||
|
||||
def _set_controls_enabled(self, is_enabled=False):
|
||||
"""
|
||||
Enable or disable the shortcut controls
|
||||
"""
|
||||
self.default_radio_button.setEnabled(is_enabled)
|
||||
self.custom_radio_button.setEnabled(is_enabled)
|
||||
self.primary_push_button.setEnabled(is_enabled)
|
||||
self.alternate_push_button.setEnabled(is_enabled)
|
||||
self.clear_primary_button.setEnabled(is_enabled)
|
||||
self.clear_alternate_button.setEnabled(is_enabled)
|
||||
|
||||
def reload_shortcut_list(self):
|
||||
"""
|
||||
Reload the ``tree_widget`` list to add new and remove old actions.
|
||||
|
@ -229,8 +312,7 @@ class ShortcutListForm(QtWidgets.QDialog, Ui_ShortcutListDialog, RegistryPropert
|
|||
A item has been pressed. We adjust the button's text to the action's shortcut which is encapsulate in the item.
|
||||
"""
|
||||
action = self._current_item_action(item)
|
||||
self.primary_push_button.setEnabled(action is not None)
|
||||
self.alternate_push_button.setEnabled(action is not None)
|
||||
self._set_controls_enabled(action is not None)
|
||||
primary_text = ''
|
||||
alternate_text = ''
|
||||
primary_label_text = ''
|
||||
|
@ -244,7 +326,7 @@ class ShortcutListForm(QtWidgets.QDialog, Ui_ShortcutListDialog, RegistryPropert
|
|||
if len(action.default_shortcuts) == 2:
|
||||
alternate_label_text = self.get_shortcut_string(action.default_shortcuts[1], for_display=True)
|
||||
shortcuts = self._action_shortcuts(action)
|
||||
# We do not want to loose pending changes, that is why we have to keep the text when, this function has not
|
||||
# We do not want to loose pending changes, that is why we have to keep the text when this function has not
|
||||
# been triggered by a signal.
|
||||
if item is None:
|
||||
primary_text = self.primary_push_button.text()
|
||||
|
@ -254,7 +336,7 @@ class ShortcutListForm(QtWidgets.QDialog, Ui_ShortcutListDialog, RegistryPropert
|
|||
elif len(shortcuts) == 2:
|
||||
primary_text = self.get_shortcut_string(shortcuts[0], for_display=True)
|
||||
alternate_text = self.get_shortcut_string(shortcuts[1], for_display=True)
|
||||
# When we are capturing a new shortcut, we do not want, the buttons to display the current shortcut.
|
||||
# When we are capturing a new shortcut, we do not want the buttons to display the current shortcut.
|
||||
if self.primary_push_button.isChecked():
|
||||
primary_text = ''
|
||||
if self.alternate_push_button.isChecked():
|
||||
|
@ -396,75 +478,6 @@ class ShortcutListForm(QtWidgets.QDialog, Ui_ShortcutListDialog, RegistryPropert
|
|||
self.refresh_shortcut_list()
|
||||
self.on_current_item_changed(self.tree_widget.currentItem())
|
||||
|
||||
def _validiate_shortcut(self, changing_action, key_sequence):
|
||||
"""
|
||||
Checks if the given ``changing_action `` can use the given ``key_sequence``. Returns ``True`` if the
|
||||
``key_sequence`` can be used by the action, otherwise displays a dialog and returns ``False``.
|
||||
|
||||
:param changing_action: The action which wants to use the ``key_sequence``.
|
||||
:param key_sequence: The key sequence which the action want so use.
|
||||
"""
|
||||
is_valid = True
|
||||
for category in self.action_list.categories:
|
||||
for action in category.actions:
|
||||
shortcuts = self._action_shortcuts(action)
|
||||
if key_sequence not in shortcuts:
|
||||
continue
|
||||
if action is changing_action:
|
||||
if self.primary_push_button.isChecked() and shortcuts.index(key_sequence) == 0:
|
||||
continue
|
||||
if self.alternate_push_button.isChecked() and shortcuts.index(key_sequence) == 1:
|
||||
continue
|
||||
# Have the same parent, thus they cannot have the same shortcut.
|
||||
if action.parent() is changing_action.parent():
|
||||
is_valid = False
|
||||
# The new shortcut is already assigned, but if both shortcuts are only valid in a different widget the
|
||||
# new shortcut is valid, because they will not interfere.
|
||||
if action.shortcutContext() in [QtCore.Qt.WindowShortcut, QtCore.Qt.ApplicationShortcut]:
|
||||
is_valid = False
|
||||
if changing_action.shortcutContext() in [QtCore.Qt.WindowShortcut, QtCore.Qt.ApplicationShortcut]:
|
||||
is_valid = False
|
||||
if not is_valid:
|
||||
self.main_window.warning_message(translate('OpenLP.ShortcutListDialog', 'Duplicate Shortcut'),
|
||||
translate('OpenLP.ShortcutListDialog',
|
||||
'The shortcut "%s" is already assigned to another action, please'
|
||||
' use a different shortcut.') %
|
||||
self.get_shortcut_string(key_sequence, for_display=True))
|
||||
self.dialog_was_shown = True
|
||||
return is_valid
|
||||
|
||||
def _action_shortcuts(self, action):
|
||||
"""
|
||||
This returns the shortcuts for the given ``action``, which also includes those shortcuts which are not saved
|
||||
yet but already assigned (as changes are applied when closing the dialog).
|
||||
"""
|
||||
if action in self.changed_actions:
|
||||
return self.changed_actions[action]
|
||||
return action.shortcuts()
|
||||
|
||||
def _current_item_action(self, item=None):
|
||||
"""
|
||||
Returns the action of the given ``item``. If no item is given, we return the action of the current item of
|
||||
the ``tree_widget``.
|
||||
"""
|
||||
if item is None:
|
||||
item = self.tree_widget.currentItem()
|
||||
if item is None:
|
||||
return
|
||||
return item.data(0, QtCore.Qt.UserRole)
|
||||
|
||||
def _adjust_button(self, button, checked=None, enabled=None, text=None):
|
||||
"""
|
||||
Can be called to adjust more properties of the given ``button`` at once.
|
||||
"""
|
||||
# Set the text before checking the button, because this emits a signal.
|
||||
if text is not None:
|
||||
button.setText(text)
|
||||
if checked is not None:
|
||||
button.setChecked(checked)
|
||||
if enabled is not None:
|
||||
button.setEnabled(enabled)
|
||||
|
||||
@staticmethod
|
||||
def get_shortcut_string(shortcut, for_display=False):
|
||||
if for_display:
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# Copyright (c) 2008-2017 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
|
@ -714,8 +714,10 @@ class SlideController(DisplayController, RegistryProperties):
|
|||
# Reset the button
|
||||
self.play_slides_once.setChecked(False)
|
||||
self.play_slides_once.setIcon(build_icon(':/media/media_time.png'))
|
||||
self.play_slides_once.setText(UiStrings().PlaySlidesToEnd)
|
||||
self.play_slides_loop.setChecked(False)
|
||||
self.play_slides_loop.setIcon(build_icon(':/media/media_time.png'))
|
||||
self.play_slides_loop.setText(UiStrings().PlaySlidesInLoop)
|
||||
if item.is_text():
|
||||
if (Settings().value(self.main_window.songs_settings_section + '/display songbar') and
|
||||
not self.song_menu.menu().isEmpty()):
|
||||
|
@ -907,7 +909,9 @@ class SlideController(DisplayController, RegistryProperties):
|
|||
Registry().execute('%s_stop' % old_item.name.lower(), [old_item, self.is_live])
|
||||
if old_item.is_media() and not self.service_item.is_media():
|
||||
self.on_media_close()
|
||||
Registry().execute('slidecontroller_%s_started' % self.type_prefix, [self.service_item])
|
||||
if self.is_live:
|
||||
# This even is only registered for live
|
||||
Registry().execute('slidecontroller_%s_started' % self.type_prefix, [self.service_item])
|
||||
|
||||
def on_slide_selected_index(self, message):
|
||||
"""
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# Copyright (c) 2008-2017 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# Copyright (c) 2008-2017 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# Copyright (c) 2008-2017 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# Copyright (c) 2008-2017 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# Copyright (c) 2008-2017 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# Copyright (c) 2008-2017 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# Copyright (c) 2008-2017 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# Copyright (c) 2008-2017 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# Copyright (c) 2008-2017 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
|
@ -43,9 +43,9 @@ class Ui_ThemeWizard(object):
|
|||
theme_wizard.setModal(True)
|
||||
theme_wizard.setOptions(QtWidgets.QWizard.IndependentPages |
|
||||
QtWidgets.QWizard.NoBackButtonOnStartPage | QtWidgets.QWizard.HaveCustomButton1)
|
||||
theme_wizard.setFixedWidth(640)
|
||||
if is_macosx():
|
||||
theme_wizard.setPixmap(QtWidgets.QWizard.BackgroundPixmap, QtGui.QPixmap(':/wizards/openlp-osx-wizard.png'))
|
||||
theme_wizard.resize(646, 400)
|
||||
else:
|
||||
theme_wizard.setWizardStyle(QtWidgets.QWizard.ModernStyle)
|
||||
self.spacer = QtWidgets.QSpacerItem(10, 0, QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Minimum)
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# Copyright (c) 2008-2017 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# Copyright (c) 2008-2017 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
|
@ -529,7 +529,7 @@ def get_natural_key(string):
|
|||
key = [int(part) if part.isdigit() else get_locale_key(part) for part in key]
|
||||
# Python 3 does not support comparison of different types anymore. So make sure, that we do not compare str
|
||||
# and int.
|
||||
if string[0].isdigit():
|
||||
if string and string[0].isdigit():
|
||||
return [b''] + key
|
||||
return key
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue