forked from openlp/openlp
Merge trunk.
This commit is contained in:
commit
e16a3c6dea
@ -25,3 +25,5 @@ openlp.cfg
|
||||
openlp.pro
|
||||
.kdev4
|
||||
tests.kdev4
|
||||
*.nja
|
||||
*.orig
|
||||
|
@ -34,4 +34,3 @@ import core
|
||||
import plugins
|
||||
|
||||
__all__ = [u'core', u'plugins']
|
||||
|
||||
|
@ -43,7 +43,7 @@ from traceback import format_exception
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
from openlp.core.lib import Receiver, Settings, check_directory_exists, ScreenList, UiStrings, Registry
|
||||
from openlp.core.lib import Receiver, Settings, ScreenList, UiStrings, Registry, check_directory_exists
|
||||
from openlp.core.resources import qInitResources
|
||||
from openlp.core.ui.mainwindow import MainWindow
|
||||
from openlp.core.ui.firsttimelanguageform import FirstTimeLanguageForm
|
||||
@ -92,15 +92,16 @@ class OpenLP(QtGui.QApplication):
|
||||
"""
|
||||
Override exec method to allow the shared memory to be released on exit
|
||||
"""
|
||||
self.eventLoopIsActive = True
|
||||
QtGui.QApplication.exec_()
|
||||
self.sharedMemory.detach()
|
||||
self.is_event_loop_active = True
|
||||
result = QtGui.QApplication.exec_()
|
||||
self.shared_memory.detach()
|
||||
return result
|
||||
|
||||
def run(self, args, testing=False):
|
||||
def run(self, args):
|
||||
"""
|
||||
Run the OpenLP application.
|
||||
"""
|
||||
self.eventLoopIsActive = False
|
||||
self.is_event_loop_active = False
|
||||
# On Windows, the args passed into the constructor are ignored. Not
|
||||
# very handy, so set the ones we want to use. On Linux and FreeBSD, in
|
||||
# order to set the WM_CLASS property for X11, we pass "OpenLP" in as a
|
||||
@ -109,10 +110,6 @@ class OpenLP(QtGui.QApplication):
|
||||
if 'OpenLP' in args:
|
||||
args.remove('OpenLP')
|
||||
self.args.extend(args)
|
||||
# provide a listener for widgets to reqest a screen update.
|
||||
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'openlp_process_events'), self.processEvents)
|
||||
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'cursor_busy'), self.setBusyCursor)
|
||||
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'cursor_normal'), self.setNormalCursor)
|
||||
# Decide how many screens we have and their size
|
||||
screens = ScreenList.create(self.desktop())
|
||||
# First time checks in settings
|
||||
@ -121,11 +118,15 @@ class OpenLP(QtGui.QApplication):
|
||||
if FirstTimeForm(screens).exec_() == QtGui.QDialog.Accepted:
|
||||
Settings().setValue(u'general/has run wizard', True)
|
||||
# Correct stylesheet bugs
|
||||
if os.name == u'nt':
|
||||
application_stylesheet = u''
|
||||
if not Settings().value(u'advanced/alternate rows'):
|
||||
base_color = self.palette().color(QtGui.QPalette.Active, QtGui.QPalette.Base)
|
||||
application_stylesheet = \
|
||||
alternate_rows_repair_stylesheet = \
|
||||
u'QTableWidget, QListWidget, QTreeWidget {alternate-background-color: ' + base_color.name() + ';}\n'
|
||||
application_stylesheet += alternate_rows_repair_stylesheet
|
||||
if os.name == u'nt':
|
||||
application_stylesheet += nt_repair_stylesheet
|
||||
if application_stylesheet:
|
||||
self.setStyleSheet(application_stylesheet)
|
||||
show_splash = Settings().value(u'general/show splash')
|
||||
if show_splash:
|
||||
@ -134,65 +135,89 @@ class OpenLP(QtGui.QApplication):
|
||||
# make sure Qt really display the splash screen
|
||||
self.processEvents()
|
||||
# start the main app window
|
||||
self.mainWindow = MainWindow(self)
|
||||
self.mainWindow.show()
|
||||
self.main_window = MainWindow()
|
||||
self.main_window.show()
|
||||
if show_splash:
|
||||
# now kill the splashscreen
|
||||
self.splash.finish(self.mainWindow)
|
||||
self.splash.finish(self.main_window)
|
||||
log.debug(u'Splashscreen closed')
|
||||
# make sure Qt really display the splash screen
|
||||
self.processEvents()
|
||||
self.mainWindow.repaint()
|
||||
self.main_window.repaint()
|
||||
self.processEvents()
|
||||
if not has_run_wizard:
|
||||
self.mainWindow.firstTime()
|
||||
self.main_window.first_time()
|
||||
update_check = Settings().value(u'general/update check')
|
||||
if update_check:
|
||||
VersionThread(self.mainWindow).start()
|
||||
VersionThread(self.main_window).start()
|
||||
Receiver.send_message(u'live_display_blank_check')
|
||||
self.mainWindow.appStartup()
|
||||
# Skip exec_() for gui tests
|
||||
if not testing:
|
||||
return self.exec_()
|
||||
self.main_window.app_startup()
|
||||
return self.exec_()
|
||||
|
||||
def isAlreadyRunning(self):
|
||||
def close_splash_screen(self):
|
||||
"""
|
||||
Close the splash screen when requested.
|
||||
"""
|
||||
self.splash.close()
|
||||
|
||||
def is_already_running(self):
|
||||
"""
|
||||
Look to see if OpenLP is already running and ask if a 2nd copy
|
||||
is to be started.
|
||||
"""
|
||||
self.sharedMemory = QtCore.QSharedMemory('OpenLP')
|
||||
if self.sharedMemory.attach():
|
||||
self.shared_memory = QtCore.QSharedMemory('OpenLP')
|
||||
if self.shared_memory.attach():
|
||||
status = QtGui.QMessageBox.critical(None, UiStrings().Error, UiStrings().OpenLPStart,
|
||||
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Yes | QtGui.QMessageBox.No))
|
||||
if status == QtGui.QMessageBox.No:
|
||||
return True
|
||||
return False
|
||||
else:
|
||||
self.sharedMemory.create(1)
|
||||
self.shared_memory.create(1)
|
||||
return False
|
||||
|
||||
def hookException(self, exctype, value, traceback):
|
||||
def hook_exception(self, exctype, value, traceback):
|
||||
"""
|
||||
Add an exception hook so that any uncaught exceptions are displayed in this window rather than somewhere where
|
||||
users cannot see it and cannot report when we encounter these problems.
|
||||
|
||||
``exctype``
|
||||
The class of exception.
|
||||
|
||||
``value``
|
||||
The actual exception object.
|
||||
|
||||
``traceback``
|
||||
A traceback object with the details of where the exception occurred.
|
||||
"""
|
||||
if not hasattr(self, u'mainWindow'):
|
||||
log.exception(''.join(format_exception(exctype, value, traceback)))
|
||||
return
|
||||
if not hasattr(self, u'exceptionForm'):
|
||||
self.exceptionForm = ExceptionForm(self.mainWindow)
|
||||
self.exceptionForm.exceptionTextEdit.setPlainText(''.join(format_exception(exctype, value, traceback)))
|
||||
self.setNormalCursor()
|
||||
self.exceptionForm.exec_()
|
||||
self.exception_form = ExceptionForm(self.main_window)
|
||||
self.exception_form.exceptionTextEdit.setPlainText(''.join(format_exception(exctype, value, traceback)))
|
||||
self.set_normal_cursor()
|
||||
self.exception_form.exec_()
|
||||
|
||||
def setBusyCursor(self):
|
||||
def process_events(self):
|
||||
"""
|
||||
Wrapper to make ProcessEvents visible and named correctly
|
||||
"""
|
||||
self.processEvents()
|
||||
|
||||
def set_busy_cursor(self):
|
||||
"""
|
||||
Sets the Busy Cursor for the Application
|
||||
"""
|
||||
self.setOverrideCursor(QtCore.Qt.BusyCursor)
|
||||
self.processEvents()
|
||||
|
||||
def setNormalCursor(self):
|
||||
def set_normal_cursor(self):
|
||||
"""
|
||||
Sets the Normal Cursor for the Application
|
||||
"""
|
||||
self.restoreOverrideCursor()
|
||||
self.processEvents()
|
||||
|
||||
def event(self, event):
|
||||
"""
|
||||
@ -217,7 +242,7 @@ def set_up_logging(log_path):
|
||||
logfile.setFormatter(logging.Formatter(u'%(asctime)s %(name)-55s %(levelname)-8s %(message)s'))
|
||||
log.addHandler(logfile)
|
||||
if log.isEnabledFor(logging.DEBUG):
|
||||
print 'Logging to:', filename
|
||||
print('Logging to: %s' % filename)
|
||||
|
||||
|
||||
def main(args=None):
|
||||
@ -237,7 +262,6 @@ def main(args=None):
|
||||
parser.add_option('-d', '--dev-version', dest='dev_version', action='store_true',
|
||||
help='Ignore the version file and pull the version directly from Bazaar')
|
||||
parser.add_option('-s', '--style', dest='style', help='Set the Qt4 style (passed directly to Qt4).')
|
||||
parser.add_option('--testing', dest='testing', action='store_true', help='Run by testing framework')
|
||||
# Parse command line options and deal with them.
|
||||
# Use args supplied programatically if possible.
|
||||
(options, args) = parser.parse_args(args) if args else parser.parse_args()
|
||||
@ -258,38 +282,37 @@ def main(args=None):
|
||||
# Initialise the resources
|
||||
qInitResources()
|
||||
# Now create and actually run the application.
|
||||
app = OpenLP(qt_args)
|
||||
app.setOrganizationName(u'OpenLP')
|
||||
app.setOrganizationDomain(u'openlp.org')
|
||||
application = OpenLP(qt_args)
|
||||
application.setOrganizationName(u'OpenLP')
|
||||
application.setOrganizationDomain(u'openlp.org')
|
||||
if options.portable:
|
||||
app.setApplicationName(u'OpenLPPortable')
|
||||
application.setApplicationName(u'OpenLPPortable')
|
||||
Settings.setDefaultFormat(Settings.IniFormat)
|
||||
# Get location OpenLPPortable.ini
|
||||
app_path = AppLocation.get_directory(AppLocation.AppDir)
|
||||
set_up_logging(os.path.abspath(os.path.join(app_path, u'..', u'..', u'Other')))
|
||||
application_path = AppLocation.get_directory(AppLocation.AppDir)
|
||||
set_up_logging(os.path.abspath(os.path.join(application_path, u'..', u'..', u'Other')))
|
||||
log.info(u'Running portable')
|
||||
portable_settings_file = os.path.abspath(os.path.join(app_path, u'..', u'..', u'Data', u'OpenLP.ini'))
|
||||
portable_settings_file = os.path.abspath(os.path.join(application_path, u'..', u'..', u'Data', u'OpenLP.ini'))
|
||||
# Make this our settings file
|
||||
log.info(u'INI file: %s', portable_settings_file)
|
||||
Settings.set_filename(portable_settings_file)
|
||||
portable_settings = Settings()
|
||||
# Set our data path
|
||||
data_path = os.path.abspath(os.path.join(app_path, u'..', u'..', u'Data',))
|
||||
data_path = os.path.abspath(os.path.join(application_path, u'..', u'..', u'Data',))
|
||||
log.info(u'Data path: %s', data_path)
|
||||
# Point to our data path
|
||||
portable_settings.setValue(u'advanced/data path', data_path)
|
||||
portable_settings.setValue(u'advanced/is portable', True)
|
||||
portable_settings.sync()
|
||||
else:
|
||||
app.setApplicationName(u'OpenLP')
|
||||
application.setApplicationName(u'OpenLP')
|
||||
set_up_logging(AppLocation.get_directory(AppLocation.CacheDir))
|
||||
registry = Registry.create()
|
||||
app.setApplicationVersion(get_application_version()[u'version'])
|
||||
Registry.create()
|
||||
Registry().register(u'application', application)
|
||||
application.setApplicationVersion(get_application_version()[u'version'])
|
||||
# Instance check
|
||||
if not options.testing:
|
||||
# Instance check
|
||||
if app.isAlreadyRunning():
|
||||
sys.exit()
|
||||
if application.is_already_running():
|
||||
sys.exit()
|
||||
# First time checks in settings
|
||||
if not Settings().value(u'general/has run wizard'):
|
||||
if not FirstTimeLanguageForm().exec_():
|
||||
@ -297,19 +320,14 @@ def main(args=None):
|
||||
sys.exit()
|
||||
# i18n Set Language
|
||||
language = LanguageManager.get_language()
|
||||
app_translator, default_translator = LanguageManager.get_translator(language)
|
||||
if not app_translator.isEmpty():
|
||||
app.installTranslator(app_translator)
|
||||
application_translator, default_translator = LanguageManager.get_translator(language)
|
||||
if not application_translator.isEmpty():
|
||||
application.installTranslator(application_translator)
|
||||
if not default_translator.isEmpty():
|
||||
app.installTranslator(default_translator)
|
||||
application.installTranslator(default_translator)
|
||||
else:
|
||||
log.debug(u'Could not find default_translator.')
|
||||
if not options.no_error_form:
|
||||
sys.excepthook = app.hookException
|
||||
# Do not run method app.exec_() when running gui tests
|
||||
if options.testing:
|
||||
app.run(qt_args, testing=True)
|
||||
# For gui tests we need access to window instances and their components
|
||||
return app
|
||||
else:
|
||||
sys.exit(app.run(qt_args))
|
||||
sys.excepthook = application.hook_exception
|
||||
sys.exit(application.run(qt_args))
|
||||
|
||||
|
@ -90,9 +90,8 @@ class ServiceItemAction(object):
|
||||
Next = 3
|
||||
|
||||
|
||||
def translate(context, text, comment=None,
|
||||
encoding=QtCore.QCoreApplication.CodecForTr, n=-1,
|
||||
translate=QtCore.QCoreApplication.translate):
|
||||
def translate(context, text, comment=None, encoding=QtCore.QCoreApplication.CodecForTr, n=-1,
|
||||
translate=QtCore.QCoreApplication.translate):
|
||||
"""
|
||||
A special shortcut method to wrap around the Qt4 translation functions.
|
||||
This abstracts the translation procedure so that we can change it if at a
|
||||
|
@ -45,6 +45,7 @@ from openlp.core.utils import AppLocation, delete_file
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def init_db(url, auto_flush=True, auto_commit=False):
|
||||
"""
|
||||
Initialise and return the session and metadata for a database
|
||||
@ -60,8 +61,7 @@ def init_db(url, auto_flush=True, auto_commit=False):
|
||||
"""
|
||||
engine = create_engine(url, poolclass=NullPool)
|
||||
metadata = MetaData(bind=engine)
|
||||
session = scoped_session(sessionmaker(autoflush=auto_flush,
|
||||
autocommit=auto_commit, bind=engine))
|
||||
session = scoped_session(sessionmaker(autoflush=auto_flush, autocommit=auto_commit, bind=engine))
|
||||
return session, metadata
|
||||
|
||||
|
||||
@ -109,14 +109,17 @@ def upgrade_db(url, upgrade):
|
||||
while hasattr(upgrade, u'upgrade_%d' % version):
|
||||
log.debug(u'Running upgrade_%d', version)
|
||||
try:
|
||||
getattr(upgrade, u'upgrade_%d' % version) (session, metadata, tables)
|
||||
upgrade_func = getattr(upgrade, u'upgrade_%d' % version)
|
||||
upgrade_func(session, metadata, tables)
|
||||
session.commit()
|
||||
# Update the version number AFTER a commit so that we are sure the previous transaction happened
|
||||
version_meta.value = unicode(version)
|
||||
session.commit()
|
||||
version += 1
|
||||
except (SQLAlchemyError, DBAPIError):
|
||||
log.exception(u'Could not run database upgrade script '
|
||||
'"upgrade_%s", upgrade process has been halted.', version)
|
||||
break
|
||||
version_meta.value = unicode(version)
|
||||
session.commit()
|
||||
version += 1
|
||||
else:
|
||||
version_meta = Metadata.populate(key=u'version', value=int(upgrade.__version__))
|
||||
session.commit()
|
||||
@ -156,6 +159,7 @@ class BaseModel(object):
|
||||
instance.__setattr__(key, value)
|
||||
return instance
|
||||
|
||||
|
||||
class Manager(object):
|
||||
"""
|
||||
Provide generic object persistence management
|
||||
@ -205,19 +209,17 @@ class Manager(object):
|
||||
if db_ver > up_ver:
|
||||
critical_error_message_box(
|
||||
translate('OpenLP.Manager', 'Database Error'),
|
||||
translate('OpenLP.Manager', 'The database being '
|
||||
'loaded was created in a more recent version of '
|
||||
'OpenLP. The database is version %d, while OpenLP '
|
||||
'expects version %d. The database will not be loaded.'
|
||||
'\n\nDatabase: %s') % \
|
||||
(db_ver, up_ver, self.db_url)
|
||||
translate('OpenLP.Manager', 'The database being loaded was created in a more recent version of '
|
||||
'OpenLP. The database is version %d, while OpenLP expects version %d. The database will not '
|
||||
'be loaded.\n\nDatabase: %s') % (db_ver, up_ver, self.db_url)
|
||||
)
|
||||
return
|
||||
try:
|
||||
self.session = init_schema(self.db_url)
|
||||
except (SQLAlchemyError, DBAPIError):
|
||||
log.exception(u'Error loading database: %s', self.db_url)
|
||||
critical_error_message_box(translate('OpenLP.Manager', 'Database Error'),
|
||||
critical_error_message_box(
|
||||
translate('OpenLP.Manager', 'Database Error'),
|
||||
translate('OpenLP.Manager', 'OpenLP cannot load your database.\n\nDatabase: %s') % self.db_url
|
||||
)
|
||||
|
||||
|
@ -35,10 +35,11 @@ import logging
|
||||
|
||||
from PyQt4 import QtGui
|
||||
|
||||
from openlp.core.lib import build_icon, ScreenList
|
||||
from openlp.core.lib import ScreenList, build_icon
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class OpenLPDockWidget(QtGui.QDockWidget):
|
||||
"""
|
||||
Custom DockWidget class to handle events
|
||||
|
@ -35,6 +35,7 @@ from PyQt4 import QtCore
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class EventReceiver(QtCore.QObject):
|
||||
"""
|
||||
Class to allow events to be passed from different parts of the system. This
|
||||
@ -46,24 +47,12 @@ class EventReceiver(QtCore.QObject):
|
||||
``mainwindow_status_text``
|
||||
Changes the bottom status bar text on the mainwindow.
|
||||
|
||||
``openlp_warning_message``
|
||||
Displays a standalone Warning Message.
|
||||
|
||||
``openlp_error_message``
|
||||
Displays a standalone Error Message.
|
||||
|
||||
``openlp_information_message``
|
||||
Displays a standalone Information Message.
|
||||
|
||||
``cursor_busy``
|
||||
Makes the cursor got to a busy form.
|
||||
|
||||
``cursor_normal``
|
||||
Resets the cursor to default.
|
||||
|
||||
``openlp_process_events``
|
||||
Requests the Application to flush the events queue.
|
||||
|
||||
``openlp_version_check``
|
||||
Version has changed so pop up window.
|
||||
|
||||
@ -120,29 +109,6 @@ class EventReceiver(QtCore.QObject):
|
||||
``slidecontroller_live_stop_loop``
|
||||
Stop the loop on the main display.
|
||||
|
||||
|
||||
**Servicemanager related signals**
|
||||
|
||||
``servicemanager_new_service``
|
||||
A new service is being loaded or created.
|
||||
|
||||
``servicemanager_previous_item``
|
||||
Display the previous item in the service.
|
||||
|
||||
``servicemanager_preview_live``
|
||||
Requests a Preview item from the Service Manager to update live and add
|
||||
a new item to the preview panel.
|
||||
|
||||
``servicemanager_next_item``
|
||||
Display the next item in the service.
|
||||
|
||||
``servicemanager_set_item``
|
||||
Go live on a specific item, by index.
|
||||
|
||||
``service_item_update``
|
||||
Passes back to the service manager the service item after it has been
|
||||
processed by the plugin.
|
||||
|
||||
**Display signals**
|
||||
|
||||
``update_display_css``
|
||||
|
@ -31,7 +31,8 @@ Provide HTML Tag management and Formatting Tag access class
|
||||
"""
|
||||
import cPickle
|
||||
|
||||
from openlp.core.lib import translate, Settings
|
||||
from openlp.core.lib import Settings, translate
|
||||
|
||||
|
||||
class FormattingTags(object):
|
||||
"""
|
||||
|
@ -207,8 +207,8 @@ sup {
|
||||
</html>
|
||||
"""
|
||||
|
||||
def build_html(item, screen, islive, background, image=None,
|
||||
plugins=None):
|
||||
|
||||
def build_html(item, screen, is_live, background, image=None, plugins=None):
|
||||
"""
|
||||
Build the full web paged structure for display
|
||||
|
||||
@ -233,7 +233,7 @@ def build_html(item, screen, islive, background, image=None,
|
||||
width = screen[u'size'].width()
|
||||
height = screen[u'size'].height()
|
||||
theme = item.themedata
|
||||
webkitvers = webkit_version()
|
||||
webkit_ver = webkit_version()
|
||||
# Image generated and poked in
|
||||
if background:
|
||||
bgimage_src = u'src="data:image/png;base64,%s"' % background
|
||||
@ -253,28 +253,32 @@ def build_html(item, screen, islive, background, image=None,
|
||||
css_additions += plugin.getDisplayCss()
|
||||
js_additions += plugin.getDisplayJavaScript()
|
||||
html_additions += plugin.getDisplayHtml()
|
||||
html = HTMLSRC % (build_background_css(item, width, height),
|
||||
html = HTMLSRC % (
|
||||
build_background_css(item, width, height),
|
||||
css_additions,
|
||||
build_footer_css(item, height),
|
||||
build_lyrics_css(item, webkitvers),
|
||||
u'true' if theme and theme.display_slide_transition and islive else u'false',
|
||||
build_lyrics_css(item, webkit_ver),
|
||||
u'true' if theme and theme.display_slide_transition and is_live else u'false',
|
||||
js_additions,
|
||||
bgimage_src, image_src,
|
||||
html_additions,
|
||||
build_lyrics_html(item, webkitvers))
|
||||
build_lyrics_html(item, webkit_ver)
|
||||
)
|
||||
return html
|
||||
|
||||
|
||||
def webkit_version():
|
||||
"""
|
||||
Return the Webkit version in use.
|
||||
Note method added relatively recently, so return 0 if prior to this
|
||||
"""
|
||||
try:
|
||||
webkitvers = float(QtWebKit.qWebKitVersion())
|
||||
log.debug(u'Webkit version = %s' % webkitvers)
|
||||
webkit_ver = float(QtWebKit.qWebKitVersion())
|
||||
log.debug(u'Webkit version = %s' % webkit_ver)
|
||||
except AttributeError:
|
||||
webkitvers = 0
|
||||
return webkitvers
|
||||
webkit_ver = 0
|
||||
return webkit_ver
|
||||
|
||||
|
||||
def build_background_css(item, width, height):
|
||||
"""
|
||||
@ -310,7 +314,8 @@ def build_background_css(item, width, height):
|
||||
% (width, width, width, theme.background_start_color, theme.background_end_color)
|
||||
return background
|
||||
|
||||
def build_lyrics_css(item, webkitvers):
|
||||
|
||||
def build_lyrics_css(item, webkit_ver):
|
||||
"""
|
||||
Build the lyrics display css
|
||||
|
||||
@ -367,12 +372,12 @@ def build_lyrics_css(item, webkitvers):
|
||||
# Up to 534.3 the text-shadow didn't get displayed when
|
||||
# webkit-text-stroke was used. So use an offset text layer underneath.
|
||||
# https://bugs.webkit.org/show_bug.cgi?id=19728
|
||||
if webkitvers >= 533.3:
|
||||
if webkit_ver >= 533.3:
|
||||
lyricsmain += build_lyrics_outline_css(theme)
|
||||
else:
|
||||
outline = build_lyrics_outline_css(theme)
|
||||
if theme.font_main_shadow:
|
||||
if theme.font_main_outline and webkitvers <= 534.3:
|
||||
if theme.font_main_outline and webkit_ver <= 534.3:
|
||||
shadow = u'padding-left: %spx; padding-top: %spx;' % \
|
||||
(int(theme.font_main_shadow_size) + (int(theme.font_main_outline_size) * 2),
|
||||
theme.font_main_shadow_size)
|
||||
@ -384,6 +389,7 @@ def build_lyrics_css(item, webkitvers):
|
||||
lyrics_css = style % (lyricstable, lyrics, lyricsmain, outline, shadow)
|
||||
return lyrics_css
|
||||
|
||||
|
||||
def build_lyrics_outline_css(theme, is_shadow=False):
|
||||
"""
|
||||
Build the css which controls the theme outline
|
||||
@ -407,6 +413,7 @@ def build_lyrics_outline_css(theme, is_shadow=False):
|
||||
else:
|
||||
return u''
|
||||
|
||||
|
||||
def build_lyrics_format_css(theme, width, height):
|
||||
"""
|
||||
Build the css which controls the theme format
|
||||
@ -451,6 +458,7 @@ def build_lyrics_format_css(theme, width, height):
|
||||
lyrics += u' font-weight:bold; '
|
||||
return lyrics
|
||||
|
||||
|
||||
def build_lyrics_html(item, webkitvers):
|
||||
"""
|
||||
Build the HTML required to show the lyrics
|
||||
@ -480,6 +488,7 @@ def build_lyrics_html(item, webkitvers):
|
||||
u'class="lyricscell lyricsmain"></div></div>'
|
||||
return lyrics
|
||||
|
||||
|
||||
def build_footer_css(item, height):
|
||||
"""
|
||||
Build the display of the item footer
|
||||
|
@ -39,24 +39,31 @@ import Queue
|
||||
|
||||
from PyQt4 import QtCore
|
||||
|
||||
from openlp.core.lib import resize_image, image_to_byte, Receiver, Registry, ScreenList
|
||||
from openlp.core.lib import Receiver, Registry, ScreenList, resize_image, image_to_byte
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class ImageThread(QtCore.QThread):
|
||||
"""
|
||||
A special Qt thread class to speed up the display of images. This is
|
||||
threaded so it loads the frames and generates byte stream in background.
|
||||
"""
|
||||
def __init__(self, manager):
|
||||
"""
|
||||
Constructor for the thread class.
|
||||
|
||||
``manager``
|
||||
The image manager.
|
||||
"""
|
||||
QtCore.QThread.__init__(self, None)
|
||||
self.imageManager = manager
|
||||
self.image_manager = manager
|
||||
|
||||
def run(self):
|
||||
"""
|
||||
Run the thread.
|
||||
"""
|
||||
self.imageManager._process()
|
||||
self.image_manager._process()
|
||||
|
||||
|
||||
class Priority(object):
|
||||
@ -181,72 +188,75 @@ class ImageManager(QtCore.QObject):
|
||||
log.info(u'Image Manager loaded')
|
||||
|
||||
def __init__(self):
|
||||
"""
|
||||
Constructor for the image manager.
|
||||
"""
|
||||
QtCore.QObject.__init__(self)
|
||||
Registry().register(u'image_manager', self)
|
||||
currentScreen = ScreenList().current
|
||||
self.width = currentScreen[u'size'].width()
|
||||
self.height = currentScreen[u'size'].height()
|
||||
current_screen = ScreenList().current
|
||||
self.width = current_screen[u'size'].width()
|
||||
self.height = current_screen[u'size'].height()
|
||||
self._cache = {}
|
||||
self.imageThread = ImageThread(self)
|
||||
self._conversionQueue = PriorityQueue()
|
||||
self.stopManager = False
|
||||
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'config_updated'), self.processUpdates)
|
||||
self.image_thread = ImageThread(self)
|
||||
self._conversion_queue = PriorityQueue()
|
||||
self.stop_manager = False
|
||||
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'config_updated'), self.process_updates)
|
||||
|
||||
def updateDisplay(self):
|
||||
def update_display(self):
|
||||
"""
|
||||
Screen has changed size so rebuild the cache to new size.
|
||||
"""
|
||||
log.debug(u'updateDisplay')
|
||||
currentScreen = ScreenList().current
|
||||
self.width = currentScreen[u'size'].width()
|
||||
self.height = currentScreen[u'size'].height()
|
||||
log.debug(u'update_display')
|
||||
current_screen = ScreenList().current
|
||||
self.width = current_screen[u'size'].width()
|
||||
self.height = current_screen[u'size'].height()
|
||||
# Mark the images as dirty for a rebuild by setting the image and byte
|
||||
# stream to None.
|
||||
for image in self._cache.values():
|
||||
self._resetImage(image)
|
||||
self._reset_image(image)
|
||||
|
||||
def updateImagesBorder(self, source, background):
|
||||
def update_images_border(self, source, background):
|
||||
"""
|
||||
Border has changed so update all the images affected.
|
||||
"""
|
||||
log.debug(u'updateImages')
|
||||
log.debug(u'update_images_border')
|
||||
# Mark the images as dirty for a rebuild by setting the image and byte
|
||||
# stream to None.
|
||||
for image in self._cache.values():
|
||||
if image.source == source:
|
||||
image.background = background
|
||||
self._resetImage(image)
|
||||
self._reset_image(image)
|
||||
|
||||
def updateImageBorder(self, path, source, background):
|
||||
def update_image_border(self, path, source, background):
|
||||
"""
|
||||
Border has changed so update the image affected.
|
||||
"""
|
||||
log.debug(u'updateImage')
|
||||
log.debug(u'update_image_border')
|
||||
# Mark the image as dirty for a rebuild by setting the image and byte
|
||||
# stream to None.
|
||||
image = self._cache[(path, source)]
|
||||
if image.source == source:
|
||||
image.background = background
|
||||
self._resetImage(image)
|
||||
self._reset_image(image)
|
||||
|
||||
def _resetImage(self, image):
|
||||
def _reset_image(self, image):
|
||||
"""
|
||||
Mark the given :class:`Image` instance as dirty by setting its ``image``
|
||||
and ``image_bytes`` attributes to None.
|
||||
"""
|
||||
image.image = None
|
||||
image.image_bytes = None
|
||||
self._conversionQueue.modify_priority(image, Priority.Normal)
|
||||
self._conversion_queue.modify_priority(image, Priority.Normal)
|
||||
|
||||
def processUpdates(self):
|
||||
def process_updates(self):
|
||||
"""
|
||||
Flush the queue to updated any data to update
|
||||
"""
|
||||
# We want only one thread.
|
||||
if not self.imageThread.isRunning():
|
||||
self.imageThread.start()
|
||||
if not self.image_thread.isRunning():
|
||||
self.image_thread.start()
|
||||
|
||||
def getImage(self, path, source):
|
||||
def get_image(self, path, source):
|
||||
"""
|
||||
Return the ``QImage`` from the cache. If not present wait for the
|
||||
background thread to process it.
|
||||
@ -254,9 +264,9 @@ class ImageManager(QtCore.QObject):
|
||||
log.debug(u'getImage %s' % path)
|
||||
image = self._cache[(path, source)]
|
||||
if image.image is None:
|
||||
self._conversionQueue.modify_priority(image, Priority.High)
|
||||
self._conversion_queue.modify_priority(image, Priority.High)
|
||||
# make sure we are running and if not give it a kick
|
||||
self.processUpdates()
|
||||
self.process_updates()
|
||||
while image.image is None:
|
||||
log.debug(u'getImage - waiting')
|
||||
time.sleep(0.1)
|
||||
@ -265,74 +275,74 @@ class ImageManager(QtCore.QObject):
|
||||
# byte stream was not generated yet. However, we only need to do
|
||||
# this, when the image was generated before it was requested
|
||||
# (otherwise this is already taken care of).
|
||||
self._conversionQueue.modify_priority(image, Priority.Low)
|
||||
self._conversion_queue.modify_priority(image, Priority.Low)
|
||||
return image.image
|
||||
|
||||
def getImageBytes(self, path, source):
|
||||
def get_image_bytes(self, path, source):
|
||||
"""
|
||||
Returns the byte string for an image. If not present wait for the
|
||||
background thread to process it.
|
||||
"""
|
||||
log.debug(u'getImageBytes %s' % path)
|
||||
log.debug(u'get_image_bytes %s' % path)
|
||||
image = self._cache[(path, source)]
|
||||
if image.image_bytes is None:
|
||||
self._conversionQueue.modify_priority(image, Priority.Urgent)
|
||||
self._conversion_queue.modify_priority(image, Priority.Urgent)
|
||||
# make sure we are running and if not give it a kick
|
||||
self.processUpdates()
|
||||
self.process_updates()
|
||||
while image.image_bytes is None:
|
||||
log.debug(u'getImageBytes - waiting')
|
||||
time.sleep(0.1)
|
||||
return image.image_bytes
|
||||
|
||||
def addImage(self, path, source, background):
|
||||
def add_image(self, path, source, background):
|
||||
"""
|
||||
Add image to cache if it is not already there.
|
||||
"""
|
||||
log.debug(u'addImage %s' % path)
|
||||
log.debug(u'add_image %s' % path)
|
||||
if not (path, source) in self._cache:
|
||||
image = Image(path, source, background)
|
||||
self._cache[(path, source)] = image
|
||||
self._conversionQueue.put((image.priority, image.secondary_priority, image))
|
||||
self._conversion_queue.put((image.priority, image.secondary_priority, image))
|
||||
# Check if the there are any images with the same path and check if the
|
||||
# timestamp has changed.
|
||||
for image in self._cache.values():
|
||||
if os.path.exists(path):
|
||||
if image.path == path and image.timestamp != os.stat(path).st_mtime:
|
||||
image.timestamp = os.stat(path).st_mtime
|
||||
self._resetImage(image)
|
||||
self._reset_image(image)
|
||||
# We want only one thread.
|
||||
if not self.imageThread.isRunning():
|
||||
self.imageThread.start()
|
||||
if not self.image_thread.isRunning():
|
||||
self.image_thread.start()
|
||||
|
||||
def _process(self):
|
||||
"""
|
||||
Controls the processing called from a ``QtCore.QThread``.
|
||||
"""
|
||||
log.debug(u'_process - started')
|
||||
while not self._conversionQueue.empty() and not self.stopManager:
|
||||
self._processCache()
|
||||
while not self._conversion_queue.empty() and not self.stop_manager:
|
||||
self._process_cache()
|
||||
log.debug(u'_process - ended')
|
||||
|
||||
def _processCache(self):
|
||||
def _process_cache(self):
|
||||
"""
|
||||
Actually does the work.
|
||||
"""
|
||||
log.debug(u'_processCache')
|
||||
image = self._conversionQueue.get()[2]
|
||||
image = self._conversion_queue.get()[2]
|
||||
# Generate the QImage for the image.
|
||||
if image.image is None:
|
||||
image.image = resize_image(image.path, self.width, self.height, image.background)
|
||||
# Set the priority to Lowest and stop here as we need to process
|
||||
# more important images first.
|
||||
if image.priority == Priority.Normal:
|
||||
self._conversionQueue.modify_priority(image, Priority.Lowest)
|
||||
self._conversion_queue.modify_priority(image, Priority.Lowest)
|
||||
return
|
||||
# For image with high priority we set the priority to Low, as the
|
||||
# byte stream might be needed earlier the byte stream of image with
|
||||
# Normal priority. We stop here as we need to process more important
|
||||
# images first.
|
||||
elif image.priority == Priority.High:
|
||||
self._conversionQueue.modify_priority(image, Priority.Low)
|
||||
self._conversion_queue.modify_priority(image, Priority.Low)
|
||||
return
|
||||
# Generate the byte stream for the image.
|
||||
if image.image_bytes is None:
|
||||
|
@ -35,6 +35,7 @@ from PyQt4 import QtCore, QtGui
|
||||
|
||||
from openlp.core.lib import Receiver
|
||||
|
||||
|
||||
class ListWidgetWithDnD(QtGui.QListWidget):
|
||||
"""
|
||||
Provide a list widget to store objects and handle drag and drop events
|
||||
@ -58,9 +59,8 @@ class ListWidgetWithDnD(QtGui.QListWidget):
|
||||
|
||||
def mouseMoveEvent(self, event):
|
||||
"""
|
||||
Drag and drop event does not care what data is selected
|
||||
as the recipient will use events to request the data move
|
||||
just tell it what plugin to call
|
||||
Drag and drop event does not care what data is selected as the recipient will use events to request the data
|
||||
move just tell it what plugin to call
|
||||
"""
|
||||
if event.buttons() != QtCore.Qt.LeftButton:
|
||||
event.ignore()
|
||||
@ -75,12 +75,18 @@ class ListWidgetWithDnD(QtGui.QListWidget):
|
||||
drag.start(QtCore.Qt.CopyAction)
|
||||
|
||||
def dragEnterEvent(self, event):
|
||||
"""
|
||||
When something is dragged into this object, check if you should be able to drop it in here.
|
||||
"""
|
||||
if event.mimeData().hasUrls():
|
||||
event.accept()
|
||||
else:
|
||||
event.ignore()
|
||||
|
||||
def dragMoveEvent(self, event):
|
||||
"""
|
||||
Make an object droppable, and set it to copy the contents of the object, not move it.
|
||||
"""
|
||||
if event.mimeData().hasUrls():
|
||||
event.setDropAction(QtCore.Qt.CopyAction)
|
||||
event.accept()
|
||||
|
@ -35,14 +35,14 @@ import re
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
from openlp.core.lib import OpenLPToolbar, ServiceItem, StringContent, build_icon, translate, Receiver, \
|
||||
ListWidgetWithDnD, ServiceItemContext, Settings, Registry, UiStrings
|
||||
from openlp.core.lib import OpenLPToolbar, ServiceItem, StringContent, Receiver, ListWidgetWithDnD, \
|
||||
ServiceItemContext, Settings, Registry, UiStrings, build_icon, translate
|
||||
from openlp.core.lib.searchedit import SearchEdit
|
||||
from openlp.core.lib.ui import create_widget_action, critical_error_message_box
|
||||
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class MediaManagerItem(QtGui.QWidget):
|
||||
"""
|
||||
MediaManagerItem is a helper widget for plugins.
|
||||
@ -332,9 +332,9 @@ class MediaManagerItem(QtGui.QWidget):
|
||||
Settings().value(self.settingsSection + u'/last directory'), self.onNewFileMasks)
|
||||
log.info(u'New files(s) %s', files)
|
||||
if files:
|
||||
Receiver.send_message(u'cursor_busy')
|
||||
self.application.set_busy_cursor()
|
||||
self.validateAndLoad(files)
|
||||
Receiver.send_message(u'cursor_normal')
|
||||
self.application.set_normal_cursor()
|
||||
|
||||
def loadFile(self, files):
|
||||
"""
|
||||
@ -345,15 +345,15 @@ class MediaManagerItem(QtGui.QWidget):
|
||||
"""
|
||||
new_files = []
|
||||
error_shown = False
|
||||
for file in files:
|
||||
type = file.split(u'.')[-1]
|
||||
if type.lower() not in self.onNewFileMasks:
|
||||
for file_name in files:
|
||||
file_type = file_name.split(u'.')[-1]
|
||||
if file_type.lower() not in self.onNewFileMasks:
|
||||
if not error_shown:
|
||||
critical_error_message_box(translate('OpenLP.MediaManagerItem', 'Invalid File Type'),
|
||||
translate('OpenLP.MediaManagerItem', 'Invalid File %s.\nSuffix not supported') % file)
|
||||
translate('OpenLP.MediaManagerItem', 'Invalid File %s.\nSuffix not supported') % file_name)
|
||||
error_shown = True
|
||||
else:
|
||||
new_files.append(file)
|
||||
new_files.append(file_name)
|
||||
if new_files:
|
||||
self.validateAndLoad(new_files)
|
||||
|
||||
@ -390,6 +390,9 @@ class MediaManagerItem(QtGui.QWidget):
|
||||
translate('OpenLP.MediaManagerItem', 'Duplicate files were found on import and were ignored.'))
|
||||
|
||||
def contextMenu(self, point):
|
||||
"""
|
||||
Display a context menu
|
||||
"""
|
||||
item = self.listView.itemAt(point)
|
||||
# Decide if we have to show the context menu or not.
|
||||
if item is None:
|
||||
@ -412,6 +415,9 @@ class MediaManagerItem(QtGui.QWidget):
|
||||
return file_list
|
||||
|
||||
def loadList(self, list):
|
||||
"""
|
||||
Load a list. Needs to be implemented by the plugin.
|
||||
"""
|
||||
raise NotImplementedError(u'MediaManagerItem.loadList needs to be defined by the plugin')
|
||||
|
||||
def onNewClick(self):
|
||||
@ -427,6 +433,9 @@ class MediaManagerItem(QtGui.QWidget):
|
||||
pass
|
||||
|
||||
def onDeleteClick(self):
|
||||
"""
|
||||
Delete an item. Needs to be implemented by the plugin.
|
||||
"""
|
||||
raise NotImplementedError(u'MediaManagerItem.onDeleteClick needs to be defined by the plugin')
|
||||
|
||||
def onFocus(self):
|
||||
@ -438,6 +447,9 @@ class MediaManagerItem(QtGui.QWidget):
|
||||
|
||||
def generateSlideData(self, serviceItem, item=None, xmlVersion=False, remote=False,
|
||||
context=ServiceItemContext.Live):
|
||||
"""
|
||||
Generate the slide data. Needs to be implemented by the plugin.
|
||||
"""
|
||||
raise NotImplementedError(u'MediaManagerItem.generateSlideData needs to be defined by the plugin')
|
||||
|
||||
def onDoubleClicked(self):
|
||||
@ -486,6 +498,9 @@ class MediaManagerItem(QtGui.QWidget):
|
||||
self.goLive()
|
||||
|
||||
def goLive(self, item_id=None, remote=False):
|
||||
"""
|
||||
Make the currently selected item go live.
|
||||
"""
|
||||
log.debug(u'%s Live requested', self.plugin.name)
|
||||
item = None
|
||||
if item_id:
|
||||
@ -499,6 +514,9 @@ class MediaManagerItem(QtGui.QWidget):
|
||||
self.live_controller.add_service_item(serviceItem)
|
||||
|
||||
def createItemFromId(self, item_id):
|
||||
"""
|
||||
Create a media item from an item id.
|
||||
"""
|
||||
item = QtGui.QListWidgetItem()
|
||||
item.setData(QtCore.Qt.UserRole, item_id)
|
||||
return item
|
||||
@ -522,6 +540,9 @@ class MediaManagerItem(QtGui.QWidget):
|
||||
self.addToService(item)
|
||||
|
||||
def addToService(self, item=None, replace=None, remote=False):
|
||||
"""
|
||||
Add this item to the current service.
|
||||
"""
|
||||
serviceItem = self.buildServiceItem(item, True, remote=remote, context=ServiceItemContext.Service)
|
||||
if serviceItem:
|
||||
serviceItem.from_plugin = False
|
||||
@ -688,3 +709,22 @@ class MediaManagerItem(QtGui.QWidget):
|
||||
|
||||
service_manager = property(_get_service_manager)
|
||||
|
||||
def _get_theme_manager(self):
|
||||
"""
|
||||
Adds the theme manager to the class dynamically
|
||||
"""
|
||||
if not hasattr(self, u'_theme_manager'):
|
||||
self._theme_manager = Registry().get(u'theme_manager')
|
||||
return self._theme_manager
|
||||
|
||||
theme_manager = property(_get_theme_manager)
|
||||
|
||||
def _get_application(self):
|
||||
"""
|
||||
Adds the openlp to the class dynamically
|
||||
"""
|
||||
if not hasattr(self, u'_application'):
|
||||
self._application = Registry().get(u'application')
|
||||
return self._application
|
||||
|
||||
application = property(_get_application)
|
||||
|
@ -38,6 +38,7 @@ from openlp.core.utils import get_application_version
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class PluginStatus(object):
|
||||
"""
|
||||
Defines the status of the plugin
|
||||
@ -294,7 +295,7 @@ class Plugin(QtCore.QObject):
|
||||
if self.mediaItem:
|
||||
self.main_window.mediaDockManager.remove_dock(self.mediaItem)
|
||||
|
||||
def appStartup(self):
|
||||
def app_startup(self):
|
||||
"""
|
||||
Perform tasks on application startup
|
||||
"""
|
||||
@ -320,7 +321,6 @@ class Plugin(QtCore.QObject):
|
||||
Settings().setValue(u'%s/%s files' % (self.settingsSection, self.name), loaded_list)
|
||||
settings.endGroup()
|
||||
|
||||
|
||||
def usesTheme(self, theme):
|
||||
"""
|
||||
Called to find out if a plugin is currently using a theme.
|
||||
@ -409,6 +409,12 @@ class Plugin(QtCore.QObject):
|
||||
"""
|
||||
pass
|
||||
|
||||
def new_service_created(self):
|
||||
"""
|
||||
The plugin's needs to handle a new song creation
|
||||
"""
|
||||
pass
|
||||
|
||||
def _get_main_window(self):
|
||||
"""
|
||||
Adds the main window to the class dynamically
|
||||
@ -419,3 +425,12 @@ class Plugin(QtCore.QObject):
|
||||
|
||||
main_window = property(_get_main_window)
|
||||
|
||||
def _get_application(self):
|
||||
"""
|
||||
Adds the openlp to the class dynamically
|
||||
"""
|
||||
if not hasattr(self, u'_application'):
|
||||
self._application = Registry().get(u'application')
|
||||
return self._application
|
||||
|
||||
application = property(_get_application)
|
||||
|
@ -37,6 +37,7 @@ from openlp.core.lib import Plugin, PluginStatus, Registry
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class PluginManager(object):
|
||||
"""
|
||||
This is the Plugin manager, which loads all the plugins,
|
||||
@ -211,3 +212,13 @@ class PluginManager(object):
|
||||
if plugin.name == name:
|
||||
return plugin
|
||||
return None
|
||||
|
||||
def new_service_created(self):
|
||||
"""
|
||||
Loop through all the plugins and give them an opportunity to handle a new service
|
||||
"""
|
||||
log.info(u'plugins - new service created')
|
||||
for plugin in self.plugins:
|
||||
if plugin.isActive():
|
||||
plugin.new_service_created()
|
||||
|
||||
|
@ -34,6 +34,7 @@ import sys
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class Registry(object):
|
||||
"""
|
||||
This is the Component Registry. It is a singleton object and is used to provide a
|
||||
@ -43,6 +44,9 @@ class Registry(object):
|
||||
__instance__ = None
|
||||
|
||||
def __new__(cls):
|
||||
"""
|
||||
Re-implement the __new__ method to make sure we create a true singleton.
|
||||
"""
|
||||
if not cls.__instance__:
|
||||
cls.__instance__ = object.__new__(cls)
|
||||
return cls.__instance__
|
||||
@ -61,7 +65,6 @@ class Registry(object):
|
||||
registry.running_under_test = True
|
||||
return registry
|
||||
|
||||
|
||||
def get(self, key):
|
||||
"""
|
||||
Extracts the registry value from the list based on the key passed in
|
||||
@ -87,10 +90,9 @@ class Registry(object):
|
||||
Removes the registry value from the list based on the key passed in
|
||||
(Only valid and active for testing framework)
|
||||
"""
|
||||
if self.running_under_test == False:
|
||||
if self.running_under_test is False:
|
||||
log.error(u'Invalid Method call for key %s' % key)
|
||||
raise KeyError(u'Invalid Method call for key %s' % key)
|
||||
return
|
||||
if key in self.service_list:
|
||||
del self.service_list[key]
|
||||
|
||||
del self.service_list[key]
|
||||
|
@ -31,8 +31,8 @@ import logging
|
||||
|
||||
from PyQt4 import QtGui, QtCore, QtWebKit
|
||||
|
||||
from openlp.core.lib import ServiceItem, expand_tags, build_lyrics_format_css, build_lyrics_outline_css, Receiver, \
|
||||
ItemCapabilities, FormattingTags, ImageSource, Registry, ScreenList
|
||||
from openlp.core.lib import FormattingTags, ImageSource, ItemCapabilities, Receiver, Registry, ScreenList, \
|
||||
ServiceItem, expand_tags, build_lyrics_format_css, build_lyrics_outline_css
|
||||
from openlp.core.lib.theme import ThemeLevel
|
||||
from openlp.core.ui import MainDisplay
|
||||
|
||||
@ -128,7 +128,7 @@ class Renderer(object):
|
||||
The theme name.
|
||||
"""
|
||||
if theme_name not in self._theme_dimensions:
|
||||
theme_data = self.theme_manager.getThemeData(theme_name)
|
||||
theme_data = self.theme_manager.get_theme_data(theme_name)
|
||||
main_rect = self.get_main_rectangle(theme_data)
|
||||
footer_rect = self.get_footer_rectangle(theme_data)
|
||||
self._theme_dimensions[theme_name] = [theme_data, main_rect, footer_rect]
|
||||
@ -136,7 +136,7 @@ class Renderer(object):
|
||||
theme_data, main_rect, footer_rect = self._theme_dimensions[theme_name]
|
||||
# if No file do not update cache
|
||||
if theme_data.background_filename:
|
||||
self.image_manager.addImage(theme_data.background_filename,
|
||||
self.image_manager.add_image(theme_data.background_filename,
|
||||
ImageSource.Theme, QtGui.QColor(theme_data.background_border_color))
|
||||
|
||||
def pre_render(self, override_theme_data=None):
|
||||
@ -238,7 +238,7 @@ class Renderer(object):
|
||||
serviceItem.raw_footer = FOOTER
|
||||
# if No file do not update cache
|
||||
if theme_data.background_filename:
|
||||
self.image_manager.addImage(theme_data.background_filename,
|
||||
self.image_manager.add_image(theme_data.background_filename,
|
||||
ImageSource.Theme,
|
||||
QtGui.QColor(theme_data.background_border_color))
|
||||
theme_data, main, footer = self.pre_render(theme_data)
|
||||
@ -315,7 +315,7 @@ class Renderer(object):
|
||||
if text_contains_split:
|
||||
text = slides[-1] + u'\n[---]\n' + text
|
||||
else:
|
||||
text = slides[-1] + u'\n'+ text
|
||||
text = slides[-1] + u'\n' + text
|
||||
text = text.replace(u'<br>', u'\n')
|
||||
else:
|
||||
pages.extend(slides)
|
||||
@ -543,7 +543,7 @@ class Renderer(object):
|
||||
end_tags.reverse()
|
||||
# Remove the indexes.
|
||||
html_tags = [tag[1] for tag in html_tags]
|
||||
return raw_text + u''.join(end_tags), u''.join(start_tags), u''.join(html_tags)
|
||||
return raw_text + u''.join(end_tags), u''.join(start_tags), u''.join(html_tags)
|
||||
|
||||
def _binary_chop(self, formatted, previous_html, previous_raw, html_list, raw_list, separator, line_end):
|
||||
"""
|
||||
@ -661,4 +661,5 @@ class Renderer(object):
|
||||
self._theme_manager = Registry().get(u'theme_manager')
|
||||
return self._theme_manager
|
||||
|
||||
theme_manager = property(_get_theme_manager)
|
||||
theme_manager = property(_get_theme_manager)
|
||||
|
||||
|
@ -37,7 +37,6 @@ from PyQt4 import QtCore
|
||||
|
||||
from openlp.core.lib import Receiver, translate
|
||||
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@ -51,6 +50,9 @@ class ScreenList(object):
|
||||
__instance__ = None
|
||||
|
||||
def __new__(cls):
|
||||
"""
|
||||
Re-implement __new__ to create a true singleton.
|
||||
"""
|
||||
if not cls.__instance__:
|
||||
cls.__instance__ = object.__new__(cls)
|
||||
return cls.__instance__
|
||||
@ -137,8 +139,7 @@ class ScreenList(object):
|
||||
"""
|
||||
screen_list = []
|
||||
for screen in self.screen_list:
|
||||
screen_name = u'%s %d' % (translate('OpenLP.ScreenList', 'Screen'),
|
||||
screen[u'number'] + 1)
|
||||
screen_name = u'%s %d' % (translate('OpenLP.ScreenList', 'Screen'), screen[u'number'] + 1)
|
||||
if screen[u'primary']:
|
||||
screen_name = u'%s (%s)' % (screen_name, translate('OpenLP.ScreenList', 'primary'))
|
||||
screen_list.append(screen_name)
|
||||
@ -235,8 +236,7 @@ class ScreenList(object):
|
||||
y = window.y() + (window.height() / 2)
|
||||
for screen in self.screen_list:
|
||||
size = screen[u'size']
|
||||
if x >= size.x() and x <= (size.x() + size.width()) and \
|
||||
y >= size.y() and y <= (size.y() + size.height()):
|
||||
if x >= size.x() and x <= (size.x() + size.width()) and y >= size.y() and y <= (size.y() + size.height()):
|
||||
return screen[u'number']
|
||||
|
||||
def load_screen_settings(self):
|
||||
|
@ -36,6 +36,7 @@ from openlp.core.lib.ui import create_widget_action
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class SearchEdit(QtGui.QLineEdit):
|
||||
"""
|
||||
This is a specialised QLineEdit with a "clear" button inside for searches.
|
||||
|
@ -39,10 +39,11 @@ import uuid
|
||||
|
||||
from PyQt4 import QtGui
|
||||
|
||||
from openlp.core.lib import build_icon, clean_tags, expand_tags, translate, ImageSource, Settings, Registry
|
||||
from openlp.core.lib import ImageSource, Settings, Registry, build_icon, clean_tags, expand_tags, translate
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class ServiceItemType(object):
|
||||
"""
|
||||
Defines the type of service item
|
||||
@ -292,7 +293,7 @@ class ServiceItem(object):
|
||||
self.image_border = background
|
||||
self.service_item_type = ServiceItemType.Image
|
||||
self._raw_frames.append({u'title': title, u'path': path})
|
||||
self.image_manager.addImage(path, ImageSource.ImagePlugin, self.image_border)
|
||||
self.image_manager.add_image(path, ImageSource.ImagePlugin, self.image_border)
|
||||
self._new_item()
|
||||
|
||||
def add_from_text(self, raw_slide, verse_tag=None):
|
||||
@ -607,7 +608,7 @@ class ServiceItem(object):
|
||||
``theme``
|
||||
The new theme to be replaced in the service item
|
||||
"""
|
||||
self.theme_overwritten = (theme == None)
|
||||
self.theme_overwritten = (theme is None)
|
||||
self.theme = theme
|
||||
self._new_item()
|
||||
self.render()
|
||||
@ -662,4 +663,4 @@ class ServiceItem(object):
|
||||
self._image_manager = Registry().get(u'image_manager')
|
||||
return self._image_manager
|
||||
|
||||
image_manager = property(_get_image_manager)
|
||||
image_manager = property(_get_image_manager)
|
||||
|
@ -74,7 +74,8 @@ class Settings(QtCore.QSettings):
|
||||
|
||||
The first entry is the *old key*; it will be removed.
|
||||
|
||||
The second entry is the *new key*; we will add it to the config.
|
||||
The second entry is the *new key*; we will add it to the config. If this is just an empty string, we just remove
|
||||
the old key.
|
||||
|
||||
The last entry is a list containing two-pair tuples. If the list is empty, no conversion is made. Otherwise each
|
||||
pair describes how to convert the old setting's value::
|
||||
@ -86,65 +87,68 @@ class Settings(QtCore.QSettings):
|
||||
So, if the type of the old value is bool, then there must be two rules.
|
||||
"""
|
||||
__default_settings__ = {
|
||||
u'advanced/x11 bypass wm': X11_BYPASS_DEFAULT,
|
||||
u'advanced/default service enabled': True,
|
||||
u'advanced/enable exit confirmation': True,
|
||||
u'advanced/save current plugin': False,
|
||||
u'advanced/single click preview': False,
|
||||
# 7 stands for now, 0 to 6 is Monday to Sunday.
|
||||
u'advanced/default service day': 7,
|
||||
u'advanced/max recent files': 20,
|
||||
u'advanced/is portable': False,
|
||||
u'advanced/hide mouse': True,
|
||||
u'advanced/add page break': False,
|
||||
u'advanced/alternate rows': not sys.platform.startswith(u'win'),
|
||||
u'advanced/current media plugin': -1,
|
||||
u'advanced/double click live': False,
|
||||
u'advanced/data path': u'',
|
||||
u'advanced/default service hour': 11,
|
||||
u'advanced/default color': u'#ffffff',
|
||||
u'advanced/default image': u':/graphics/openlp-splash-screen.png',
|
||||
u'advanced/expand service item': False,
|
||||
u'advanced/recent file count': 4,
|
||||
u'advanced/default service name': UiStrings().DefaultServiceName,
|
||||
# 7 stands for now, 0 to 6 is Monday to Sunday.
|
||||
u'advanced/default service day': 7,
|
||||
u'advanced/default service enabled': True,
|
||||
u'advanced/default service hour': 11,
|
||||
u'advanced/default service minute': 0,
|
||||
u'advanced/slide limits': SlideLimits.End,
|
||||
u'advanced/print slide text': False,
|
||||
u'advanced/add page break': False,
|
||||
u'advanced/default service name': UiStrings().DefaultServiceName,
|
||||
u'advanced/display size': 0,
|
||||
u'advanced/double click live': False,
|
||||
u'advanced/enable exit confirmation': True,
|
||||
u'advanced/expand service item': False,
|
||||
u'advanced/hide mouse': True,
|
||||
u'advanced/is portable': False,
|
||||
u'advanced/max recent files': 20,
|
||||
u'advanced/print file meta data': False,
|
||||
u'advanced/print notes': False,
|
||||
u'advanced/display size': 0,
|
||||
u'advanced/print slide text': False,
|
||||
u'advanced/recent file count': 4,
|
||||
u'advanced/save current plugin': False,
|
||||
u'advanced/slide limits': SlideLimits.End,
|
||||
u'advanced/single click preview': False,
|
||||
u'advanced/x11 bypass wm': X11_BYPASS_DEFAULT,
|
||||
u'crashreport/last directory': u'',
|
||||
u'displayTags/html_tags': u'',
|
||||
u'general/audio repeat list': False,
|
||||
u'general/auto open': False,
|
||||
u'general/auto preview': False,
|
||||
u'general/audio start paused': True,
|
||||
u'general/auto unblank': False,
|
||||
u'general/blank warning': False,
|
||||
u'general/ccli number': u'',
|
||||
u'general/has run wizard': False,
|
||||
u'general/update check': True,
|
||||
u'general/language': u'[en]',
|
||||
u'general/songselect password': u'',
|
||||
u'general/recent files': [],
|
||||
u'general/save prompt': False,
|
||||
u'general/auto preview': False,
|
||||
u'general/view mode': u'default',
|
||||
u'general/auto open': False,
|
||||
u'general/enable slide loop': True,
|
||||
u'general/show splash': True,
|
||||
u'general/screen blank': False,
|
||||
# The oder display settings (display position and dimensions) are defined in the ScreenList class due to crycle
|
||||
# dependency.
|
||||
u'general/override position': False,
|
||||
u'general/loop delay': 5,
|
||||
u'general/songselect username': u'',
|
||||
u'general/audio repeat list': False,
|
||||
u'general/auto unblank': False,
|
||||
u'general/display on monitor': True,
|
||||
u'general/audio start paused': True,
|
||||
# This defaults to yesterday in order to force the update check to run when you've never run it before.
|
||||
u'general/last version test': datetime.datetime.now().date() - datetime.timedelta(days=1),
|
||||
u'general/blank warning': False,
|
||||
u'general/loop delay': 5,
|
||||
u'general/recent files': [],
|
||||
u'general/save prompt': False,
|
||||
u'general/screen blank': False,
|
||||
u'general/show splash': True,
|
||||
u'general/songselect password': u'',
|
||||
u'general/songselect username': u'',
|
||||
u'general/update check': True,
|
||||
u'general/view mode': u'default',
|
||||
# The other display settings (display position and dimensions) are defined in the ScreenList class due to a
|
||||
# circular dependency.
|
||||
u'general/display on monitor': True,
|
||||
u'general/override position': False,
|
||||
u'media/players': u'webkit',
|
||||
u'media/override player': QtCore.Qt.Unchecked,
|
||||
u'players/background color': u'#000000',
|
||||
u'servicemanager/service theme': u'',
|
||||
u'servicemanager/last directory': u'',
|
||||
u'servicemanager/last file': u'',
|
||||
u'servicemanager/service theme': u'',
|
||||
u'SettingsImport/file_date_created': datetime.datetime.now().strftime("%Y-%m-%d %H:%M"),
|
||||
u'SettingsImport/Make_Changes': u'At_Own_RISK',
|
||||
u'SettingsImport/type': u'OpenLP_settings_export',
|
||||
u'SettingsImport/file_date_created': datetime.datetime.now().strftime("%Y-%m-%d %H:%M"),
|
||||
u'SettingsImport/version': u'',
|
||||
u'shortcuts/aboutItem': [QtGui.QKeySequence(u'Ctrl+F1')],
|
||||
u'shortcuts/audioPauseItem': [],
|
||||
@ -213,39 +217,37 @@ class Settings(QtCore.QSettings):
|
||||
u'shortcuts/viewLivePanel': [QtGui.QKeySequence(u'F12')],
|
||||
u'shortcuts/viewServiceManagerItem': [QtGui.QKeySequence(u'F9')],
|
||||
u'shortcuts/webSiteItem': [],
|
||||
u'themes/theme level': ThemeLevel.Song,
|
||||
u'themes/global theme': u'',
|
||||
u'themes/last directory': u'',
|
||||
u'themes/last directory export': u'',
|
||||
u'themes/last directory import': u'',
|
||||
u'user interface/main window position': QtCore.QPoint(0, 0),
|
||||
u'user interface/preview panel': True,
|
||||
u'themes/theme level': ThemeLevel.Song,
|
||||
u'user interface/live panel': True,
|
||||
u'user interface/main window geometry': QtCore.QByteArray(),
|
||||
u'user interface/preview splitter geometry': QtCore.QByteArray(),
|
||||
u'user interface/lock panel': False,
|
||||
u'user interface/mainwindow splitter geometry': QtCore.QByteArray(),
|
||||
u'user interface/live splitter geometry': QtCore.QByteArray(),
|
||||
u'user interface/lock panel': False,
|
||||
u'user interface/main window geometry': QtCore.QByteArray(),
|
||||
u'user interface/main window position': QtCore.QPoint(0, 0),
|
||||
u'user interface/main window splitter geometry': QtCore.QByteArray(),
|
||||
u'user interface/main window state': QtCore.QByteArray(),
|
||||
u'media/players': u'webkit',
|
||||
u'media/override player': QtCore.Qt.Unchecked,
|
||||
# Old settings (not used anymore). Have to be here, so that old setting.config backups can be imported.
|
||||
u'advanced/stylesheet fix': u'',
|
||||
u'servicemanager/last directory': u''
|
||||
u'user interface/preview panel': True,
|
||||
u'user interface/preview splitter geometry': QtCore.QByteArray()
|
||||
}
|
||||
__file_path__ = u''
|
||||
__obsolete_settings__ = [
|
||||
# Changed during 1.9.x development.
|
||||
(u'bibles/bookname language', u'bibles/book name language', []),
|
||||
(u'general/enable slide loop', u'advanced/slide limits', [(SlideLimits.Wrap, True), (SlideLimits.End, False)]),
|
||||
(u'songs/ccli number', u'general/ccli number', []),
|
||||
# Changed during 2.1.x development.
|
||||
(u'advanced/stylesheet fix', u'', []),
|
||||
(u'bibles/last directory 1', u'bibles/last directory import', []),
|
||||
(u'media/background color', u'players/background color', []),
|
||||
(u'themes/last directory', u'themes/last directory import', []),
|
||||
(u'themes/last directory 1', u'themes/last directory export', []),
|
||||
(u'servicemanager/last directory', u'', []),
|
||||
(u'songs/last directory 1', u'songs/last directory import', []),
|
||||
(u'bibles/last directory 1', u'bibles/last directory import', []),
|
||||
(u'songusage/last directory 1', u'songusage/last directory export', []),
|
||||
(u'shortcuts/makeLive', u'shortcuts/make_live', []),
|
||||
(u'advanced/stylesheet fix', u'', []),
|
||||
(u'media/background color', u'players/background color', [])
|
||||
(u'user interface/mainwindow splitter geometry', u'user interface/main window splitter geometry', []),
|
||||
(u'shortcuts/makeLive', u'shortcuts/make_live', [])
|
||||
]
|
||||
|
||||
@staticmethod
|
||||
@ -277,6 +279,9 @@ class Settings(QtCore.QSettings):
|
||||
Settings.__default_settings__[u'advanced/default service name'] = UiStrings().DefaultServiceName
|
||||
|
||||
def __init__(self, *args):
|
||||
"""
|
||||
Constructor which checks if this should be a native settings object, or an INI file.
|
||||
"""
|
||||
if not args and Settings.__file_path__ and Settings.defaultFormat() == Settings.IniFormat:
|
||||
QtCore.QSettings.__init__(self, Settings.__file_path__, Settings.IniFormat)
|
||||
else:
|
||||
@ -293,6 +298,11 @@ class Settings(QtCore.QSettings):
|
||||
if new_key:
|
||||
# Get the value of the old_key.
|
||||
old_value = super(Settings, self).value(old_key)
|
||||
# When we want to convert the value, we have to figure out the default value (because we cannot get
|
||||
# the default value from the central settings dict.
|
||||
if rules:
|
||||
default_value = rules[0][1]
|
||||
old_value = self._convert_value(old_value, default_value)
|
||||
# Iterate over our rules and check what the old_value should be "converted" to.
|
||||
for new, old in rules:
|
||||
# If the value matches with the condition (rule), then use the provided value. This is used to
|
||||
@ -308,8 +318,6 @@ class Settings(QtCore.QSettings):
|
||||
Returns the value for the given ``key``. The returned ``value`` is of the same type as the default value in the
|
||||
*Settings.__default_settings__* dict.
|
||||
|
||||
**Note**, this method only converts a few types and might need to be extended if a certain type is missing!
|
||||
|
||||
``key``
|
||||
The key to return the value from.
|
||||
"""
|
||||
@ -319,6 +327,21 @@ class Settings(QtCore.QSettings):
|
||||
else:
|
||||
default_value = Settings.__default_settings__[key]
|
||||
setting = super(Settings, self).value(key, default_value)
|
||||
return self._convert_value(setting, default_value)
|
||||
|
||||
def _convert_value(self, setting, default_value):
|
||||
"""
|
||||
This converts the given ``setting`` to the type of the given ``default_value``.
|
||||
|
||||
``setting``
|
||||
The setting to convert. This could be ``true`` for example.Settings()
|
||||
|
||||
``default_value``
|
||||
Indication the type the setting should be converted to. For example ``True`` (type is boolean), meaning that
|
||||
we convert the string ``true`` to a python boolean.
|
||||
|
||||
**Note**, this method only converts a few types and might need to be extended if a certain type is missing!
|
||||
"""
|
||||
# On OS X (and probably on other platforms too) empty value from QSettings is represented as type
|
||||
# PyQt4.QtCore.QPyNullVariant. This type has to be converted to proper 'None' Python type.
|
||||
if isinstance(setting, QtCore.QPyNullVariant) and setting.isNull():
|
||||
@ -341,4 +364,3 @@ class Settings(QtCore.QSettings):
|
||||
if isinstance(default_value, int):
|
||||
return int(setting)
|
||||
return setting
|
||||
|
||||
|
@ -33,9 +33,6 @@ format.
|
||||
"""
|
||||
import os
|
||||
|
||||
from PyQt4 import QtCore
|
||||
|
||||
from openlp.core.lib import Settings
|
||||
from openlp.core.utils import AppLocation
|
||||
|
||||
|
||||
|
@ -26,9 +26,16 @@
|
||||
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||
###############################################################################
|
||||
"""
|
||||
The :mod:`~openlp.core.lib.settingstab` module contains the base SettingsTab class which plugins use for adding their
|
||||
own tab to the settings dialog.
|
||||
"""
|
||||
|
||||
from PyQt4 import QtGui
|
||||
|
||||
|
||||
from openlp.core.lib import Registry
|
||||
|
||||
class SettingsTab(QtGui.QWidget):
|
||||
"""
|
||||
SettingsTab is a helper widget for plugins to define Tabs for the settings
|
||||
@ -131,3 +138,54 @@ class SettingsTab(QtGui.QWidget):
|
||||
Tab has just been made visible to the user
|
||||
"""
|
||||
pass
|
||||
|
||||
def _get_service_manager(self):
|
||||
"""
|
||||
Adds the service manager to the class dynamically
|
||||
"""
|
||||
if not hasattr(self, u'_service_manager'):
|
||||
self._service_manager = Registry().get(u'service_manager')
|
||||
return self._service_manager
|
||||
|
||||
service_manager = property(_get_service_manager)
|
||||
|
||||
def _get_main_window(self):
|
||||
"""
|
||||
Adds the main window to the class dynamically
|
||||
"""
|
||||
if not hasattr(self, u'_main_window'):
|
||||
self._main_window = Registry().get(u'main_window')
|
||||
return self._main_window
|
||||
|
||||
main_window = property(_get_main_window)
|
||||
|
||||
def _get_renderer(self):
|
||||
"""
|
||||
Adds the Renderer to the class dynamically
|
||||
"""
|
||||
if not hasattr(self, u'_renderer'):
|
||||
self._renderer = Registry().get(u'renderer')
|
||||
return self._renderer
|
||||
|
||||
renderer = property(_get_renderer)
|
||||
|
||||
def _get_theme_manager(self):
|
||||
"""
|
||||
Adds the theme manager to the class dynamically
|
||||
"""
|
||||
if not hasattr(self, u'_theme_manager'):
|
||||
self._theme_manager = Registry().get(u'theme_manager')
|
||||
return self._theme_manager
|
||||
|
||||
theme_manager = property(_get_theme_manager)
|
||||
|
||||
def _get_media_controller(self):
|
||||
"""
|
||||
Adds the media controller to the class dynamically
|
||||
"""
|
||||
if not hasattr(self, u'_media_controller'):
|
||||
self._media_controller = Registry().get(u'media_controller')
|
||||
return self._media_controller
|
||||
|
||||
media_controller = property(_get_media_controller)
|
||||
|
||||
|
@ -26,6 +26,10 @@
|
||||
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||
###############################################################################
|
||||
"""
|
||||
The :mod:`~openlp.core.lib.spelltextedit` module contains a classes to add spell checking to an edit widget.
|
||||
"""
|
||||
|
||||
import logging
|
||||
import re
|
||||
|
||||
@ -47,11 +51,15 @@ from openlp.core.lib.ui import create_action
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class SpellTextEdit(QtGui.QPlainTextEdit):
|
||||
"""
|
||||
Spell checking widget based on QPlanTextEdit.
|
||||
"""
|
||||
def __init__(self, parent=None, formattingTagsAllowed=True):
|
||||
"""
|
||||
Constructor.
|
||||
"""
|
||||
global ENCHANT_AVAILABLE
|
||||
QtGui.QPlainTextEdit.__init__(self, parent)
|
||||
self.formattingTagsAllowed = formattingTagsAllowed
|
||||
@ -171,6 +179,9 @@ class Highlighter(QtGui.QSyntaxHighlighter):
|
||||
WORDS = u'(?iu)[\w\']+'
|
||||
|
||||
def __init__(self, *args):
|
||||
"""
|
||||
Constructor
|
||||
"""
|
||||
QtGui.QSyntaxHighlighter.__init__(self, *args)
|
||||
self.spellingDictionary = None
|
||||
|
||||
@ -197,5 +208,8 @@ class SpellAction(QtGui.QAction):
|
||||
correct = QtCore.pyqtSignal(unicode)
|
||||
|
||||
def __init__(self, *args):
|
||||
"""
|
||||
Constructor
|
||||
"""
|
||||
QtGui.QAction.__init__(self, *args)
|
||||
self.triggered.connect(lambda x: self.correct.emit(self.text()))
|
||||
|
@ -86,6 +86,7 @@ BLANK_THEME_XML = \
|
||||
</theme>
|
||||
'''
|
||||
|
||||
|
||||
class ThemeLevel(object):
|
||||
"""
|
||||
Provides an enumeration for the level a theme applies to
|
||||
@ -213,6 +214,7 @@ class ThemeXML(object):
|
||||
"""
|
||||
FIRST_CAMEL_REGEX = re.compile(u'(.)([A-Z][a-z]+)')
|
||||
SECOND_CAMEL_REGEX = re.compile(u'([a-z0-9])([A-Z])')
|
||||
|
||||
def __init__(self):
|
||||
"""
|
||||
Initialise the theme object.
|
||||
@ -608,13 +610,15 @@ class ThemeXML(object):
|
||||
self.add_background_gradient(
|
||||
self.background_start_color,
|
||||
self.background_end_color,
|
||||
self.background_direction)
|
||||
self.background_direction
|
||||
)
|
||||
elif self.background_type == BackgroundType.to_string(BackgroundType.Image):
|
||||
filename = os.path.split(self.background_filename)[1]
|
||||
self.add_background_image(filename, self.background_border_color)
|
||||
elif self.background_type == BackgroundType.to_string(BackgroundType.Transparent):
|
||||
self.add_background_transparent()
|
||||
self.add_font(self.font_main_name,
|
||||
self.add_font(
|
||||
self.font_main_name,
|
||||
self.font_main_color,
|
||||
self.font_main_size,
|
||||
self.font_main_override, u'main',
|
||||
@ -630,14 +634,16 @@ class ThemeXML(object):
|
||||
self.font_main_outline_size,
|
||||
self.font_main_shadow,
|
||||
self.font_main_shadow_color,
|
||||
self.font_main_shadow_size)
|
||||
self.add_font(self.font_footer_name,
|
||||
self.font_main_shadow_size
|
||||
)
|
||||
self.add_font(
|
||||
self.font_footer_name,
|
||||
self.font_footer_color,
|
||||
self.font_footer_size,
|
||||
self.font_footer_override, u'footer',
|
||||
self.font_footer_bold,
|
||||
self.font_footer_italics,
|
||||
0, # line adjustment
|
||||
0, # line adjustment
|
||||
self.font_footer_x,
|
||||
self.font_footer_y,
|
||||
self.font_footer_width,
|
||||
@ -647,7 +653,10 @@ class ThemeXML(object):
|
||||
self.font_footer_outline_size,
|
||||
self.font_footer_shadow,
|
||||
self.font_footer_shadow_color,
|
||||
self.font_footer_shadow_size)
|
||||
self.add_display(self.display_horizontal_align,
|
||||
self.font_footer_shadow_size
|
||||
)
|
||||
self.add_display(
|
||||
self.display_horizontal_align,
|
||||
self.display_vertical_align,
|
||||
self.display_slide_transition)
|
||||
self.display_slide_transition
|
||||
)
|
||||
|
@ -37,6 +37,7 @@ from openlp.core.lib.ui import create_widget_action
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class OpenLPToolbar(QtGui.QToolBar):
|
||||
"""
|
||||
Lots of toolbars around the place, so it makes sense to have a common way
|
||||
@ -85,4 +86,3 @@ class OpenLPToolbar(QtGui.QToolBar):
|
||||
self.actions[handle].setVisible(visible)
|
||||
else:
|
||||
log.warn(u'No handle "%s" in actions list.', unicode(handle))
|
||||
|
||||
|
@ -33,7 +33,7 @@ import logging
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
from openlp.core.lib import build_icon, translate, Receiver, UiStrings
|
||||
from openlp.core.lib import Receiver, UiStrings, build_icon, translate
|
||||
from openlp.core.utils.actions import ActionList
|
||||
|
||||
|
||||
@ -67,7 +67,7 @@ def add_welcome_page(parent, image):
|
||||
parent.addPage(parent.welcomePage)
|
||||
|
||||
|
||||
def create_button_box(dialog, name, standard_buttons, custom_buttons=[]):
|
||||
def create_button_box(dialog, name, standard_buttons, custom_buttons=None):
|
||||
"""
|
||||
Creates a QDialogButtonBox with the given buttons. The ``accepted()`` and
|
||||
``rejected()`` signals of the button box are connected with the dialogs
|
||||
@ -88,6 +88,8 @@ def create_button_box(dialog, name, standard_buttons, custom_buttons=[]):
|
||||
QtGui.QAbstractButton it is added with QDialogButtonBox.ActionRole.
|
||||
Otherwhise the item has to be a tuple of a button and a ButtonRole.
|
||||
"""
|
||||
if custom_buttons is None:
|
||||
custom_buttons = []
|
||||
buttons = QtGui.QDialogButtonBox.NoButton
|
||||
if u'ok' in standard_buttons:
|
||||
buttons |= QtGui.QDialogButtonBox.Ok
|
||||
|
@ -111,8 +111,8 @@ class UiStrings(object):
|
||||
self.OLPV2x = translate('OpenLP.Ui', 'OpenLP 2.1')
|
||||
self.OpenLPStart = translate('OpenLP.Ui', 'OpenLP is already running. Do you wish to continue?')
|
||||
self.OpenService = translate('OpenLP.Ui', 'Open service.')
|
||||
self.PlaySlidesInLoop = translate('OpenLP.Ui','Play Slides in Loop')
|
||||
self.PlaySlidesToEnd = translate('OpenLP.Ui','Play Slides to End')
|
||||
self.PlaySlidesInLoop = translate('OpenLP.Ui', 'Play Slides in Loop')
|
||||
self.PlaySlidesToEnd = translate('OpenLP.Ui', 'Play Slides to End')
|
||||
self.Preview = translate('OpenLP.Ui', 'Preview')
|
||||
self.PrintService = translate('OpenLP.Ui', 'Print Service')
|
||||
self.ReplaceBG = translate('OpenLP.Ui', 'Replace Background')
|
||||
@ -144,4 +144,3 @@ class UiStrings(object):
|
||||
self.Version = translate('OpenLP.Ui', 'Version')
|
||||
self.View = translate('OpenLP.Ui', 'View')
|
||||
self.ViewMode = translate('OpenLP.Ui', 'View Mode')
|
||||
|
||||
|
@ -32,3 +32,5 @@ OpenLP when displaying a song or a scripture.
|
||||
"""
|
||||
|
||||
from openlp.core.theme.theme import Theme
|
||||
|
||||
__all__ = ['Theme']
|
||||
|
@ -37,11 +37,21 @@ from xml.etree.ElementTree import ElementTree, XML
|
||||
from PyQt4 import QtGui
|
||||
|
||||
DELPHI_COLORS = {
|
||||
u'clAqua': 0x00FFFF, u'clBlack': 0x000000, u'clBlue': 0x0000FF,
|
||||
u'clFuchsia': 0xFF00FF, u'clGray': 0x808080, u'clGreen': 0x008000,
|
||||
u'clLime': 0x00FF00, u'clMaroon': 0x800000, u'clNavy': 0x000080,
|
||||
u'clOlive': 0x808000, u'clPurple': 0x800080, u'clRed': 0xFF0000,
|
||||
u'clSilver': 0xC0C0C0, u'clTeal': 0x008080, u'clWhite': 0xFFFFFF,
|
||||
u'clAqua': 0x00FFFF,
|
||||
u'clBlack': 0x000000,
|
||||
u'clBlue': 0x0000FF,
|
||||
u'clFuchsia': 0xFF00FF,
|
||||
u'clGray': 0x808080,
|
||||
u'clGreen': 0x008000,
|
||||
u'clLime': 0x00FF00,
|
||||
u'clMaroon': 0x800000,
|
||||
u'clNavy': 0x000080,
|
||||
u'clOlive': 0x808000,
|
||||
u'clPurple': 0x800080,
|
||||
u'clRed': 0xFF0000,
|
||||
u'clSilver': 0xC0C0C0,
|
||||
u'clTeal': 0x008080,
|
||||
u'clWhite': 0xFFFFFF,
|
||||
u'clYellow': 0xFFFF00
|
||||
}
|
||||
|
||||
@ -66,6 +76,7 @@ BLANK_STYLE_XML = \
|
||||
</Theme>
|
||||
'''
|
||||
|
||||
|
||||
class Theme(object):
|
||||
"""
|
||||
Provide a class wrapper storing data from an XML theme
|
||||
@ -164,6 +175,7 @@ class Theme(object):
|
||||
* ``0`` - normal
|
||||
* ``1`` - lyrics
|
||||
"""
|
||||
|
||||
def __init__(self, xml):
|
||||
"""
|
||||
Initialise a theme with data from xml
|
||||
@ -205,10 +217,12 @@ class Theme(object):
|
||||
val = element_text
|
||||
# strings need special handling to sort the colours out
|
||||
if isinstance(element_text, basestring):
|
||||
if element_text[0] == u'$': # might be a hex number
|
||||
if element_text[0] == u'$':
|
||||
# might be a hex number
|
||||
try:
|
||||
val = int(element_text[1:], 16)
|
||||
except ValueError: # nope
|
||||
except ValueError:
|
||||
# nope
|
||||
pass
|
||||
elif element_text in DELPHI_COLORS:
|
||||
val = DELPHI_COLORS[element_text]
|
||||
@ -222,9 +236,9 @@ class Theme(object):
|
||||
isinstance(val, int))):
|
||||
# convert to a wx.Colour
|
||||
if not delphi_color_change:
|
||||
val = QtGui.QColor(val&0xFF, (val>>8)&0xFF, (val>>16)&0xFF)
|
||||
val = QtGui.QColor(val & 0xFF, (val >> 8) & 0xFF, (val >> 16) & 0xFF)
|
||||
else:
|
||||
val = QtGui.QColor((val>>16)&0xFF, (val>>8)&0xFF, val&0xFF)
|
||||
val = QtGui.QColor((val >> 16) & 0xFF, (val >> 8) & 0xFF, val & 0xFF)
|
||||
setattr(self, element.tag, val)
|
||||
|
||||
def __str__(self):
|
||||
|
@ -31,7 +31,6 @@ The :mod:`ui` module provides the core user interface for OpenLP
|
||||
"""
|
||||
|
||||
|
||||
|
||||
class HideMode(object):
|
||||
"""
|
||||
This is an enumeration class which specifies the different modes of hiding the display.
|
||||
@ -101,6 +100,8 @@ from mediadockmanager import MediaDockManager
|
||||
from servicemanager import ServiceManager
|
||||
from thememanager import ThemeManager
|
||||
|
||||
__all__ = ['SplashScreen', 'AboutForm', 'SettingsForm', 'MainDisplay',
|
||||
'SlideController', 'ServiceManager', 'ThemeManager', 'MediaDockManager',
|
||||
'ServiceItemEditForm', 'FirstTimeForm']
|
||||
__all__ = ['SplashScreen', 'AboutForm', 'SettingsForm', 'MainDisplay', 'SlideController', 'ServiceManager',
|
||||
'ThemeManager', 'MediaDockManager', 'ServiceItemEditForm', 'FirstTimeForm', 'FirstTimeLanguageForm', 'ThemeForm',
|
||||
'ThemeLayoutForm', 'FileRenameForm', 'StartTimeForm', 'MainDisplay', 'Display', 'ServiceNoteForm',
|
||||
'SlideController', 'DisplayController', 'GeneralTab', 'ThemesTab', 'AdvancedTab', 'PluginForm',
|
||||
'FormattingTagForm', 'ShortcutListForm']
|
||||
|
@ -29,12 +29,19 @@
|
||||
|
||||
from PyQt4 import QtGui
|
||||
|
||||
from openlp.core.lib import build_icon, translate, UiStrings
|
||||
from openlp.core.lib import UiStrings, build_icon, translate
|
||||
from openlp.core.lib.ui import create_button, create_button_box
|
||||
|
||||
|
||||
class Ui_AboutDialog(object):
|
||||
"""
|
||||
The actual GUI widgets for the About form.
|
||||
"""
|
||||
|
||||
def setupUi(self, aboutDialog):
|
||||
"""
|
||||
Set up the UI for the dialog.
|
||||
"""
|
||||
aboutDialog.setObjectName(u'aboutDialog')
|
||||
aboutDialog.setWindowIcon(build_icon(u':/icon/openlp-logo-16x16.png'))
|
||||
self.aboutDialogLayout = QtGui.QVBoxLayout(aboutDialog)
|
||||
@ -80,6 +87,9 @@ class Ui_AboutDialog(object):
|
||||
self.aboutNotebook.setCurrentIndex(0)
|
||||
|
||||
def retranslateUi(self, aboutDialog):
|
||||
"""
|
||||
Dynamically translate the UI.
|
||||
"""
|
||||
aboutDialog.setWindowTitle(u'%s OpenLP' % UiStrings().About)
|
||||
self.aboutTextEdit.setPlainText(translate('OpenLP.AboutForm',
|
||||
'OpenLP <version><revision> - Open Source Lyrics '
|
||||
@ -134,17 +144,17 @@ class Ui_AboutDialog(object):
|
||||
u'en_ZA': [u'Raoul "superfly" Snyman',
|
||||
u'Johan "nuvolari" Mynhardt'],
|
||||
u'el': [u'Alexander Siozos'],
|
||||
u'es': [u'Josu\xe9 Z\xfa\xf1iga',u'Christian Gonzalez'],
|
||||
u'es': [u'Josu\xe9 Z\xfa\xf1iga', u'Christian Gonzalez'],
|
||||
u'et': [u'Mattias "mahfiaz" P\xf5ldaru'],
|
||||
u'fi': [u'Jori "joribu" Brander', u'Tobbe "tobbeb" Bildo'],
|
||||
u'fr': [u'Stephan\xe9 "stbrunner" Brunner', u'Jeremie "jnau05"',
|
||||
u'Carl "carl.fischer" Fischer'],
|
||||
u'hu': [u'Gyuris Gell\xe9rt'],
|
||||
u'id': [u'Mico "bangmico" Siahaan' ,u' ign_christian'],
|
||||
u'id': [u'Mico "bangmico" Siahaan', u' ign_christian'],
|
||||
u'ja': [u'Kunio "Kunio" Nakamaru', u'Chris Haris'],
|
||||
u'nb': [u'Atle "pendlaren" Weibell', u'Frode "frodus" Woldsund'],
|
||||
u'nl': [u'Arjen "typovar" van Voorst'],
|
||||
u'pt_BR': [u'David Mederiros',u'Rafael "rafaellerm" Lerm',
|
||||
u'pt_BR': [u'David Mederiros', u'Rafael "rafaellerm" Lerm',
|
||||
u'Eduardo Levi Chaves',
|
||||
u'Gustavo Bim', u'Rog\xeanio Bel\xe9m', u'Samuel'
|
||||
u'Simon "samscudder" Scudder', u'Van Der Fran'],
|
||||
@ -260,7 +270,7 @@ class Ui_AboutDialog(object):
|
||||
u'\n '.join(documentors)))
|
||||
self.aboutNotebook.setTabText(self.aboutNotebook.indexOf(self.creditsTab),
|
||||
translate('OpenLP.AboutForm', 'Credits'))
|
||||
copyright = translate('OpenLP.AboutForm',
|
||||
copyright_note = translate('OpenLP.AboutForm',
|
||||
'Copyright \xa9 2004-2013 %s\n'
|
||||
'Portions copyright \xa9 2004-2013 %s') % (u'Raoul Snyman',
|
||||
u'Tim Bentley, Gerald Britton, Jonathan Corwin, Samuel Findlay, '
|
||||
@ -652,7 +662,7 @@ class Ui_AboutDialog(object):
|
||||
'linking proprietary applications with the library. If this is '
|
||||
'what you want to do, use the GNU Lesser General Public License '
|
||||
'instead of this License.')
|
||||
self.licenseTextEdit.setPlainText(u'%s\n\n%s\n\n%s\n\n\n%s' % (copyright, licence, disclaimer, gpltext))
|
||||
self.licenseTextEdit.setPlainText(u'%s\n\n%s\n\n%s\n\n\n%s' % (copyright_note, licence, disclaimer, gpltext))
|
||||
self.aboutNotebook.setTabText(self.aboutNotebook.indexOf(self.licenseTab),
|
||||
translate('OpenLP.AboutForm', 'License'))
|
||||
self.volunteerButton.setText(translate('OpenLP.AboutForm', 'Volunteer'))
|
||||
|
@ -26,6 +26,9 @@
|
||||
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||
###############################################################################
|
||||
"""
|
||||
The About dialog.
|
||||
"""
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
@ -33,6 +36,7 @@ from aboutdialog import Ui_AboutDialog
|
||||
from openlp.core.lib import translate
|
||||
from openlp.core.utils import get_application_version
|
||||
|
||||
|
||||
class AboutForm(QtGui.QDialog, Ui_AboutDialog):
|
||||
"""
|
||||
The About dialog
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -26,14 +26,24 @@
|
||||
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||
###############################################################################
|
||||
"""
|
||||
The GUI widgets of the exception dialog.
|
||||
"""
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
from openlp.core.lib import translate
|
||||
from openlp.core.lib.ui import create_button, create_button_box
|
||||
|
||||
|
||||
class Ui_ExceptionDialog(object):
|
||||
"""
|
||||
The GUI widgets of the exception dialog.
|
||||
"""
|
||||
def setupUi(self, exceptionDialog):
|
||||
"""
|
||||
Set up the UI.
|
||||
"""
|
||||
exceptionDialog.setObjectName(u'exceptionDialog')
|
||||
self.exceptionLayout = QtGui.QVBoxLayout(exceptionDialog)
|
||||
self.exceptionLayout.setObjectName(u'exceptionLayout')
|
||||
@ -66,7 +76,7 @@ class Ui_ExceptionDialog(object):
|
||||
self.exceptionLayout.addWidget(self.exceptionTextEdit)
|
||||
self.sendReportButton = create_button(exceptionDialog, u'sendReportButton',
|
||||
icon=u':/general/general_email.png', click=self.onSendReportButtonClicked)
|
||||
self.saveReportButton = create_button(exceptionDialog,u'saveReportButton',
|
||||
self.saveReportButton = create_button(exceptionDialog, u'saveReportButton',
|
||||
icon=u':/general/general_save.png', click=self.onSaveReportButtonClicked)
|
||||
self.attachFileButton = create_button(exceptionDialog, u'attachFileButton',
|
||||
icon=u':/general/general_open.png', click=self.onAttachFileButtonClicked)
|
||||
@ -79,6 +89,9 @@ class Ui_ExceptionDialog(object):
|
||||
QtCore.SIGNAL(u'textChanged()'), self.onDescriptionUpdated)
|
||||
|
||||
def retranslateUi(self, exceptionDialog):
|
||||
"""
|
||||
Translate the widgets on the fly.
|
||||
"""
|
||||
exceptionDialog.setWindowTitle(translate('OpenLP.ExceptionDialog', 'Error Occurred'))
|
||||
self.descriptionExplanation.setText(translate('OpenLP.ExceptionDialog',
|
||||
'Please enter a description of what you were doing to cause this '
|
||||
|
@ -26,6 +26,9 @@
|
||||
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||
###############################################################################
|
||||
"""
|
||||
The actual exception dialog form.
|
||||
"""
|
||||
import logging
|
||||
import re
|
||||
import os
|
||||
@ -85,29 +88,39 @@ except AttributeError:
|
||||
WEBKIT_VERSION = u'-'
|
||||
|
||||
|
||||
from openlp.core.lib import translate, UiStrings, Settings
|
||||
from openlp.core.lib import UiStrings, Settings, translate
|
||||
from openlp.core.utils import get_application_version
|
||||
|
||||
from exceptiondialog import Ui_ExceptionDialog
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class ExceptionForm(QtGui.QDialog, Ui_ExceptionDialog):
|
||||
"""
|
||||
The exception dialog
|
||||
"""
|
||||
def __init__(self, parent):
|
||||
"""
|
||||
Constructor.
|
||||
"""
|
||||
QtGui.QDialog.__init__(self, parent)
|
||||
self.setupUi(self)
|
||||
self.settingsSection = u'crashreport'
|
||||
|
||||
def exec_(self):
|
||||
"""
|
||||
Show the dialog.
|
||||
"""
|
||||
self.descriptionTextEdit.setPlainText(u'')
|
||||
self.onDescriptionUpdated()
|
||||
self.fileAttachment = None
|
||||
return QtGui.QDialog.exec_(self)
|
||||
|
||||
def _createReport(self):
|
||||
"""
|
||||
Create an exception report.
|
||||
"""
|
||||
openlp_version = get_application_version()
|
||||
description = self.descriptionTextEdit.toPlainText()
|
||||
traceback = self.exceptionTextEdit.toPlainText()
|
||||
@ -128,9 +141,9 @@ class ExceptionForm(QtGui.QDialog, Ui_ExceptionDialog):
|
||||
u'pyUNO bridge: %s\n' % UNO_VERSION
|
||||
if platform.system() == u'Linux':
|
||||
if os.environ.get(u'KDE_FULL_SESSION') == u'true':
|
||||
system = system + u'Desktop: KDE SC\n'
|
||||
system += u'Desktop: KDE SC\n'
|
||||
elif os.environ.get(u'GNOME_DESKTOP_SESSION_ID'):
|
||||
system = system + u'Desktop: GNOME\n'
|
||||
system += u'Desktop: GNOME\n'
|
||||
return (openlp_version, description, traceback, system, libraries)
|
||||
|
||||
def onSaveReportButtonClicked(self):
|
||||
@ -199,6 +212,9 @@ class ExceptionForm(QtGui.QDialog, Ui_ExceptionDialog):
|
||||
QtGui.QDesktopServices.openUrl(mailto_url)
|
||||
|
||||
def onDescriptionUpdated(self):
|
||||
"""
|
||||
Update the minimum number of characters needed in the description.
|
||||
"""
|
||||
count = int(20 - len(self.descriptionTextEdit.toPlainText()))
|
||||
if count < 0:
|
||||
count = 0
|
||||
@ -209,6 +225,9 @@ class ExceptionForm(QtGui.QDialog, Ui_ExceptionDialog):
|
||||
translate('OpenLP.ExceptionDialog', 'Description characters to enter : %s') % count)
|
||||
|
||||
def onAttachFileButtonClicked(self):
|
||||
"""
|
||||
Attache files to the bug report e-mail.
|
||||
"""
|
||||
files = QtGui.QFileDialog.getOpenFileName(
|
||||
self, translate('ImagePlugin.ExceptionDialog', 'Select Attachment'),
|
||||
Settings().value(self.settingsSection + u'/last directory'), u'%s (*.*) (*)' % UiStrings().AllFiles)
|
||||
@ -217,6 +236,8 @@ class ExceptionForm(QtGui.QDialog, Ui_ExceptionDialog):
|
||||
self.fileAttachment = unicode(files)
|
||||
|
||||
def __buttonState(self, state):
|
||||
"""
|
||||
Toggle the button state.
|
||||
"""
|
||||
self.saveReportButton.setEnabled(state)
|
||||
self.sendReportButton.setEnabled(state)
|
||||
|
||||
|
@ -26,14 +26,23 @@
|
||||
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||
###############################################################################
|
||||
|
||||
"""
|
||||
The UI widgets for the rename dialog
|
||||
"""
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
from openlp.core.lib import translate
|
||||
from openlp.core.lib.ui import create_button_box
|
||||
|
||||
|
||||
class Ui_FileRenameDialog(object):
|
||||
"""
|
||||
The UI widgets for the rename dialog
|
||||
"""
|
||||
def setupUi(self, fileRenameDialog):
|
||||
"""
|
||||
Set up the UI
|
||||
"""
|
||||
fileRenameDialog.setObjectName(u'fileRenameDialog')
|
||||
fileRenameDialog.resize(300, 10)
|
||||
self.dialogLayout = QtGui.QGridLayout(fileRenameDialog)
|
||||
@ -51,4 +60,7 @@ class Ui_FileRenameDialog(object):
|
||||
self.setMaximumHeight(self.sizeHint().height())
|
||||
|
||||
def retranslateUi(self, fileRenameDialog):
|
||||
"""
|
||||
Translate the UI on the fly.
|
||||
"""
|
||||
self.fileNameLabel.setText(translate('OpenLP.FileRenameForm', 'New File Name:'))
|
||||
|
@ -26,6 +26,9 @@
|
||||
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||
###############################################################################
|
||||
"""
|
||||
The file rename dialog.
|
||||
"""
|
||||
|
||||
from PyQt4 import QtGui
|
||||
|
||||
@ -33,11 +36,15 @@ from filerenamedialog import Ui_FileRenameDialog
|
||||
|
||||
from openlp.core.lib import translate
|
||||
|
||||
|
||||
class FileRenameForm(QtGui.QDialog, Ui_FileRenameDialog):
|
||||
"""
|
||||
The exception dialog
|
||||
The file rename dialog
|
||||
"""
|
||||
def __init__(self, parent):
|
||||
"""
|
||||
Constructor
|
||||
"""
|
||||
QtGui.QDialog.__init__(self, parent)
|
||||
self.setupUi(self)
|
||||
|
||||
|
@ -26,7 +26,9 @@
|
||||
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||
###############################################################################
|
||||
|
||||
"""
|
||||
This module contains the first time wizard.
|
||||
"""
|
||||
import io
|
||||
import logging
|
||||
import os
|
||||
@ -39,26 +41,27 @@ from ConfigParser import SafeConfigParser
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
from openlp.core.lib import translate, PluginStatus, Receiver, build_icon, check_directory_exists, Settings
|
||||
from openlp.core.utils import get_web_page, AppLocation, get_filesystem_encoding
|
||||
from openlp.core.lib import PluginStatus, Receiver, Settings, Registry, build_icon, check_directory_exists, translate
|
||||
from openlp.core.utils import AppLocation, get_web_page, get_filesystem_encoding
|
||||
from firsttimewizard import Ui_FirstTimeWizard, FirstTimePage
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class ThemeScreenshotThread(QtCore.QThread):
|
||||
"""
|
||||
This thread downloads the theme screenshots.
|
||||
"""
|
||||
def __init__(self, parent):
|
||||
QtCore.QThread.__init__(self, parent)
|
||||
|
||||
def run(self):
|
||||
"""
|
||||
Overridden method to run the thread.
|
||||
"""
|
||||
themes = self.parent().config.get(u'themes', u'files')
|
||||
themes = themes.split(u',')
|
||||
config = self.parent().config
|
||||
for theme in themes:
|
||||
# Stop if the wizard has been cancelled.
|
||||
if self.parent().downloadCancelled:
|
||||
if self.parent().was_download_cancelled:
|
||||
return
|
||||
title = config.get(u'theme_%s' % theme, u'title')
|
||||
filename = config.get(u'theme_%s' % theme, u'filename')
|
||||
@ -79,18 +82,21 @@ class FirstTimeForm(QtGui.QWizard, Ui_FirstTimeWizard):
|
||||
log.info(u'ThemeWizardForm loaded')
|
||||
|
||||
def __init__(self, screens, parent=None):
|
||||
QtGui.QWizard.__init__(self, parent)
|
||||
"""
|
||||
Create and set up the first time wizard.
|
||||
"""
|
||||
super(FirstTimeForm, self).__init__(parent)
|
||||
self.setupUi(self)
|
||||
self.screens = screens
|
||||
# check to see if we have web access
|
||||
self.web = u'http://openlp.org/files/frw/'
|
||||
self.config = SafeConfigParser()
|
||||
self.webAccess = get_web_page(u'%s%s' % (self.web, u'download.cfg'))
|
||||
if self.webAccess:
|
||||
files = self.webAccess.read()
|
||||
self.web_access = get_web_page(u'%s%s' % (self.web, u'download.cfg'))
|
||||
if self.web_access:
|
||||
files = self.web_access.read()
|
||||
self.config.readfp(io.BytesIO(files))
|
||||
self.updateScreenListCombo()
|
||||
self.downloadCancelled = False
|
||||
self.was_download_cancelled = False
|
||||
self.downloading = translate('OpenLP.FirstTimeWizard', 'Downloading %s...')
|
||||
QtCore.QObject.connect(self.cancelButton, QtCore.SIGNAL('clicked()'),
|
||||
self.onCancelButtonClicked)
|
||||
@ -112,13 +118,12 @@ class FirstTimeForm(QtGui.QWizard, Ui_FirstTimeWizard):
|
||||
Set up display at start of theme edit.
|
||||
"""
|
||||
self.restart()
|
||||
check_directory_exists(os.path.join(
|
||||
unicode(gettempdir(), get_filesystem_encoding()), u'openlp'))
|
||||
check_directory_exists(os.path.join(unicode(gettempdir(), get_filesystem_encoding()), u'openlp'))
|
||||
self.noInternetFinishButton.setVisible(False)
|
||||
# Check if this is a re-run of the wizard.
|
||||
self.hasRunWizard = Settings().value(u'general/has run wizard')
|
||||
# Sort out internet access for downloads
|
||||
if self.webAccess:
|
||||
if self.web_access:
|
||||
songs = self.config.get(u'songs', u'languages')
|
||||
songs = songs.split(u',')
|
||||
for song in songs:
|
||||
@ -146,15 +151,15 @@ class FirstTimeForm(QtGui.QWizard, Ui_FirstTimeWizard):
|
||||
# Download the theme screenshots.
|
||||
self.themeScreenshotThread = ThemeScreenshotThread(self)
|
||||
self.themeScreenshotThread.start()
|
||||
Receiver.send_message(u'cursor_normal')
|
||||
self.application.set_normal_cursor()
|
||||
|
||||
def nextId(self):
|
||||
"""
|
||||
Determine the next page in the Wizard to go to.
|
||||
"""
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
self.application.process_events()
|
||||
if self.currentId() == FirstTimePage.Plugins:
|
||||
if not self.webAccess:
|
||||
if not self.web_access:
|
||||
return FirstTimePage.NoInternet
|
||||
else:
|
||||
return FirstTimePage.Songs
|
||||
@ -163,14 +168,13 @@ class FirstTimeForm(QtGui.QWizard, Ui_FirstTimeWizard):
|
||||
elif self.currentId() == FirstTimePage.NoInternet:
|
||||
return FirstTimePage.Progress
|
||||
elif self.currentId() == FirstTimePage.Themes:
|
||||
Receiver.send_message(u'cursor_busy')
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
self.application.set_busy_cursor()
|
||||
while not self.themeScreenshotThread.isFinished():
|
||||
time.sleep(0.1)
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
self.application.process_events()
|
||||
# Build the screenshot icons, as this can not be done in the thread.
|
||||
self._buildThemeScreenshots()
|
||||
Receiver.send_message(u'cursor_normal')
|
||||
self.application.set_normal_cursor()
|
||||
return FirstTimePage.Defaults
|
||||
else:
|
||||
return self.currentId() + 1
|
||||
@ -181,7 +185,7 @@ class FirstTimeForm(QtGui.QWizard, Ui_FirstTimeWizard):
|
||||
"""
|
||||
# Keep track of the page we are at. Triggering "Cancel" causes pageId
|
||||
# to be a -1.
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
self.application.process_events()
|
||||
if pageId != -1:
|
||||
self.lastId = pageId
|
||||
if pageId == FirstTimePage.Plugins:
|
||||
@ -198,7 +202,7 @@ class FirstTimeForm(QtGui.QWizard, Ui_FirstTimeWizard):
|
||||
self.themeComboBox.addItem(item.text())
|
||||
if self.hasRunWizard:
|
||||
# Add any existing themes to list.
|
||||
for theme in self.parent().themeManagerContents.getThemes():
|
||||
for theme in self.theme_manager.get_themes():
|
||||
index = self.themeComboBox.findText(theme)
|
||||
if index == -1:
|
||||
self.themeComboBox.addItem(theme)
|
||||
@ -213,16 +217,15 @@ class FirstTimeForm(QtGui.QWizard, Ui_FirstTimeWizard):
|
||||
if self.hasRunWizard:
|
||||
self.cancelButton.setVisible(False)
|
||||
elif pageId == FirstTimePage.Progress:
|
||||
Receiver.send_message(u'cursor_busy')
|
||||
self.application.set_busy_cursor()
|
||||
self.repaint()
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
self.application.process_events()
|
||||
# Try to give the wizard a chance to redraw itself
|
||||
time.sleep(0.2)
|
||||
self._preWizard()
|
||||
self._performWizard()
|
||||
self._postWizard()
|
||||
Receiver.send_message(u'cursor_normal')
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
self.application.set_normal_cursor()
|
||||
|
||||
def updateScreenListCombo(self):
|
||||
"""
|
||||
@ -237,23 +240,21 @@ class FirstTimeForm(QtGui.QWizard, Ui_FirstTimeWizard):
|
||||
"""
|
||||
Process the triggering of the cancel button.
|
||||
"""
|
||||
if self.lastId == FirstTimePage.NoInternet or \
|
||||
(self.lastId <= FirstTimePage.Plugins and not self.hasRunWizard):
|
||||
if self.lastId == FirstTimePage.NoInternet or (self.lastId <= FirstTimePage.Plugins and not self.hasRunWizard):
|
||||
QtCore.QCoreApplication.exit()
|
||||
sys.exit()
|
||||
self.downloadCancelled = True
|
||||
self.was_download_cancelled = True
|
||||
while self.themeScreenshotThread.isRunning():
|
||||
time.sleep(0.1)
|
||||
Receiver.send_message(u'cursor_normal')
|
||||
self.application.set_normal_cursor()
|
||||
|
||||
def onNoInternetFinishButtonClicked(self):
|
||||
"""
|
||||
Process the triggering of the "Finish" button on the No Internet page.
|
||||
"""
|
||||
Receiver.send_message(u'cursor_busy')
|
||||
self.application.set_busy_cursor()
|
||||
self._performWizard()
|
||||
Receiver.send_message(u'cursor_normal')
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
self.application.set_normal_cursor()
|
||||
Settings().setValue(u'general/has run wizard', True)
|
||||
self.close()
|
||||
|
||||
@ -267,7 +268,7 @@ class FirstTimeForm(QtGui.QWizard, Ui_FirstTimeWizard):
|
||||
urlfile = urllib2.urlopen(url)
|
||||
filename = open(fpath, "wb")
|
||||
# Download until finished or canceled.
|
||||
while not self.downloadCancelled:
|
||||
while not self.was_download_cancelled:
|
||||
data = urlfile.read(block_size)
|
||||
if not data:
|
||||
break
|
||||
@ -276,7 +277,7 @@ class FirstTimeForm(QtGui.QWizard, Ui_FirstTimeWizard):
|
||||
self._downloadProgress(block_count, block_size)
|
||||
filename.close()
|
||||
# Delete file if cancelled, it may be a partial file.
|
||||
if self.downloadCancelled:
|
||||
if self.was_download_cancelled:
|
||||
os.remove(fpath)
|
||||
|
||||
def _buildThemeScreenshots(self):
|
||||
@ -297,11 +298,20 @@ class FirstTimeForm(QtGui.QWizard, Ui_FirstTimeWizard):
|
||||
screenshot)))
|
||||
|
||||
def _getFileSize(self, url):
|
||||
"""
|
||||
Get the size of a file.
|
||||
|
||||
``url``
|
||||
The URL of the file we want to download.
|
||||
"""
|
||||
site = urllib.urlopen(url)
|
||||
meta = site.info()
|
||||
return int(meta.getheaders("Content-Length")[0])
|
||||
|
||||
def _downloadProgress(self, count, block_size):
|
||||
"""
|
||||
Calculate and display the download progress.
|
||||
"""
|
||||
increment = (count * block_size) - self.previous_size
|
||||
self._incrementProgressBar(None, increment)
|
||||
self.previous_size = count * block_size
|
||||
@ -320,7 +330,7 @@ class FirstTimeForm(QtGui.QWizard, Ui_FirstTimeWizard):
|
||||
self.progressLabel.setText(status_text)
|
||||
if increment > 0:
|
||||
self.progressBar.setValue(self.progressBar.value() + increment)
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
self.application.process_events()
|
||||
|
||||
def _preWizard(self):
|
||||
"""
|
||||
@ -328,10 +338,10 @@ class FirstTimeForm(QtGui.QWizard, Ui_FirstTimeWizard):
|
||||
"""
|
||||
self.max_progress = 0
|
||||
self.finishButton.setVisible(False)
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
self.application.process_events()
|
||||
# Loop through the songs list and increase for each selected item
|
||||
for i in xrange(self.songsListWidget.count()):
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
self.application.process_events()
|
||||
item = self.songsListWidget.item(i)
|
||||
if item.checkState() == QtCore.Qt.Checked:
|
||||
filename = item.data(QtCore.Qt.UserRole)
|
||||
@ -340,7 +350,7 @@ class FirstTimeForm(QtGui.QWizard, Ui_FirstTimeWizard):
|
||||
# Loop through the Bibles list and increase for each selected item
|
||||
iterator = QtGui.QTreeWidgetItemIterator(self.biblesTreeWidget)
|
||||
while iterator.value():
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
self.application.process_events()
|
||||
item = iterator.value()
|
||||
if item.parent() and item.checkState(0) == QtCore.Qt.Checked:
|
||||
filename = item.data(0, QtCore.Qt.UserRole)
|
||||
@ -349,7 +359,7 @@ class FirstTimeForm(QtGui.QWizard, Ui_FirstTimeWizard):
|
||||
iterator += 1
|
||||
# Loop through the themes list and increase for each selected item
|
||||
for i in xrange(self.themesListWidget.count()):
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
self.application.process_events()
|
||||
item = self.themesListWidget.item(i)
|
||||
if item.checkState() == QtCore.Qt.Checked:
|
||||
filename = item.data(QtCore.Qt.UserRole)
|
||||
@ -357,7 +367,7 @@ class FirstTimeForm(QtGui.QWizard, Ui_FirstTimeWizard):
|
||||
self.max_progress += size
|
||||
if self.max_progress:
|
||||
# Add on 2 for plugins status setting plus a "finished" point.
|
||||
self.max_progress = self.max_progress + 2
|
||||
self.max_progress += 2
|
||||
self.progressBar.setValue(0)
|
||||
self.progressBar.setMinimum(0)
|
||||
self.progressBar.setMaximum(self.max_progress)
|
||||
@ -369,7 +379,7 @@ class FirstTimeForm(QtGui.QWizard, Ui_FirstTimeWizard):
|
||||
self.progressPage.setTitle(translate('OpenLP.FirstTimeWizard', 'Setting Up'))
|
||||
self.progressPage.setSubTitle(u'Setup complete.')
|
||||
self.repaint()
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
self.application.process_events()
|
||||
# Try to give the wizard a chance to repaint itself
|
||||
time.sleep(0.1)
|
||||
|
||||
@ -396,7 +406,7 @@ class FirstTimeForm(QtGui.QWizard, Ui_FirstTimeWizard):
|
||||
self.finishButton.setEnabled(True)
|
||||
self.cancelButton.setVisible(False)
|
||||
self.nextButton.setVisible(False)
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
self.application.process_events()
|
||||
|
||||
def _performWizard(self):
|
||||
"""
|
||||
@ -416,7 +426,7 @@ class FirstTimeForm(QtGui.QWizard, Ui_FirstTimeWizard):
|
||||
self._setPluginStatus(self.customCheckBox, u'custom/status')
|
||||
self._setPluginStatus(self.songUsageCheckBox, u'songusage/status')
|
||||
self._setPluginStatus(self.alertCheckBox, u'alerts/status')
|
||||
if self.webAccess:
|
||||
if self.web_access:
|
||||
# Build directories for downloads
|
||||
songs_destination = os.path.join(
|
||||
unicode(gettempdir(), get_filesystem_encoding()), u'openlp')
|
||||
@ -459,5 +469,28 @@ class FirstTimeForm(QtGui.QWizard, Ui_FirstTimeWizard):
|
||||
Settings().setValue(u'themes/global theme', self.themeComboBox.currentText())
|
||||
|
||||
def _setPluginStatus(self, field, tag):
|
||||
"""
|
||||
Set the status of a plugin.
|
||||
"""
|
||||
status = PluginStatus.Active if field.checkState() == QtCore.Qt.Checked else PluginStatus.Inactive
|
||||
Settings().setValue(tag, status)
|
||||
|
||||
def _get_theme_manager(self):
|
||||
"""
|
||||
Adds the theme manager to the class dynamically
|
||||
"""
|
||||
if not hasattr(self, u'_theme_manager'):
|
||||
self._theme_manager = Registry().get(u'theme_manager')
|
||||
return self._theme_manager
|
||||
|
||||
theme_manager = property(_get_theme_manager)
|
||||
|
||||
def _get_application(self):
|
||||
"""
|
||||
Adds the openlp to the class dynamically
|
||||
"""
|
||||
if not hasattr(self, u'_application'):
|
||||
self._application = Registry().get(u'application')
|
||||
return self._application
|
||||
|
||||
application = property(_get_application)
|
||||
|
@ -26,14 +26,23 @@
|
||||
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||
###############################################################################
|
||||
|
||||
"""
|
||||
The UI widgets of the language selection dialog.
|
||||
"""
|
||||
from PyQt4 import QtGui
|
||||
|
||||
from openlp.core.lib import translate
|
||||
from openlp.core.lib.ui import create_button_box
|
||||
|
||||
|
||||
class Ui_FirstTimeLanguageDialog(object):
|
||||
"""
|
||||
The UI widgets of the language selection dialog.
|
||||
"""
|
||||
def setupUi(self, languageDialog):
|
||||
"""
|
||||
Set up the UI.
|
||||
"""
|
||||
languageDialog.setObjectName(u'languageDialog')
|
||||
languageDialog.resize(300, 50)
|
||||
self.dialogLayout = QtGui.QVBoxLayout(languageDialog)
|
||||
@ -59,6 +68,9 @@ class Ui_FirstTimeLanguageDialog(object):
|
||||
self.setMaximumHeight(self.sizeHint().height())
|
||||
|
||||
def retranslateUi(self, languageDialog):
|
||||
"""
|
||||
Translate the UI on the fly.
|
||||
"""
|
||||
self.setWindowTitle(translate('OpenLP.FirstTimeLanguageForm', 'Select Translation'))
|
||||
self.infoLabel.setText(
|
||||
translate('OpenLP.FirstTimeLanguageForm', 'Choose the translation you\'d like to use in OpenLP.'))
|
||||
|
@ -26,18 +26,24 @@
|
||||
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||
###############################################################################
|
||||
|
||||
"""
|
||||
The language selection dialog.
|
||||
"""
|
||||
from PyQt4 import QtGui
|
||||
|
||||
from openlp.core.lib.ui import create_action
|
||||
from openlp.core.utils import LanguageManager
|
||||
from firsttimelanguagedialog import Ui_FirstTimeLanguageDialog
|
||||
|
||||
|
||||
class FirstTimeLanguageForm(QtGui.QDialog, Ui_FirstTimeLanguageDialog):
|
||||
"""
|
||||
The exception dialog
|
||||
The language selection dialog.
|
||||
"""
|
||||
def __init__(self, parent=None):
|
||||
"""
|
||||
Constructor
|
||||
"""
|
||||
QtGui.QDialog.__init__(self, parent)
|
||||
self.setupUi(self)
|
||||
self.qmList = LanguageManager.get_qm_list()
|
||||
@ -52,6 +58,9 @@ class FirstTimeLanguageForm(QtGui.QDialog, Ui_FirstTimeLanguageDialog):
|
||||
return QtGui.QDialog.exec_(self)
|
||||
|
||||
def accept(self):
|
||||
"""
|
||||
Run when the dialog is OKed.
|
||||
"""
|
||||
# It's the first row so must be Automatic
|
||||
if self.languageComboBox.currentIndex() == 0:
|
||||
LanguageManager.auto_language = True
|
||||
@ -63,6 +72,9 @@ class FirstTimeLanguageForm(QtGui.QDialog, Ui_FirstTimeLanguageDialog):
|
||||
return QtGui.QDialog.accept(self)
|
||||
|
||||
def reject(self):
|
||||
"""
|
||||
Run when the dialog is canceled.
|
||||
"""
|
||||
LanguageManager.auto_language = True
|
||||
LanguageManager.set_language(False, False)
|
||||
return QtGui.QDialog.reject(self)
|
||||
|
@ -26,7 +26,9 @@
|
||||
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||
###############################################################################
|
||||
|
||||
"""
|
||||
The UI widgets for the first time wizard.
|
||||
"""
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
import sys
|
||||
@ -34,7 +36,11 @@ import sys
|
||||
from openlp.core.lib import translate
|
||||
from openlp.core.lib.ui import add_welcome_page
|
||||
|
||||
|
||||
class FirstTimePage(object):
|
||||
"""
|
||||
An enumeration class with each of the pages of the wizard.
|
||||
"""
|
||||
Welcome = 0
|
||||
Plugins = 1
|
||||
NoInternet = 2
|
||||
@ -46,13 +52,19 @@ class FirstTimePage(object):
|
||||
|
||||
|
||||
class Ui_FirstTimeWizard(object):
|
||||
"""
|
||||
The UI widgets for the first time wizard.
|
||||
"""
|
||||
def setupUi(self, FirstTimeWizard):
|
||||
"""
|
||||
Set up the UI.
|
||||
"""
|
||||
FirstTimeWizard.setObjectName(u'FirstTimeWizard')
|
||||
FirstTimeWizard.resize(550, 386)
|
||||
FirstTimeWizard.setModal(True)
|
||||
FirstTimeWizard.setWizardStyle(QtGui.QWizard.ModernStyle)
|
||||
FirstTimeWizard.setOptions(QtGui.QWizard.IndependentPages | QtGui.QWizard.NoBackButtonOnStartPage |
|
||||
QtGui.QWizard.NoBackButtonOnLastPage |QtGui.QWizard.HaveCustomButton1)
|
||||
QtGui.QWizard.NoBackButtonOnLastPage | QtGui.QWizard.HaveCustomButton1)
|
||||
self.finishButton = self.button(QtGui.QWizard.FinishButton)
|
||||
self.noInternetFinishButton = self.button(QtGui.QWizard.CustomButton1)
|
||||
self.cancelButton = self.button(QtGui.QWizard.CancelButton)
|
||||
@ -193,17 +205,20 @@ class Ui_FirstTimeWizard(object):
|
||||
self.retranslateUi(FirstTimeWizard)
|
||||
|
||||
def retranslateUi(self, FirstTimeWizard):
|
||||
"""
|
||||
Translate the UI on the fly
|
||||
"""
|
||||
FirstTimeWizard.setWindowTitle(translate(
|
||||
'OpenLP.FirstTimeWizard', 'First Time Wizard'))
|
||||
self.titleLabel.setText(u'<span style="font-size:14pt; font-weight:600;">%s</span>' % \
|
||||
self.titleLabel.setText(u'<span style="font-size:14pt; font-weight:600;">%s</span>' %
|
||||
translate('OpenLP.FirstTimeWizard', 'Welcome to the First Time Wizard'))
|
||||
self.informationLabel.setText(translate('OpenLP.FirstTimeWizard',
|
||||
'This wizard will help you to configure OpenLP for initial use.'
|
||||
' Click the next button below to start.'))
|
||||
self.pluginPage.setTitle(translate('OpenLP.FirstTimeWizard', 'Activate required Plugins'))
|
||||
self.pluginPage.setSubTitle(translate('OpenLP.FirstTimeWizard','Select the Plugins you wish to use. '))
|
||||
self.pluginPage.setSubTitle(translate('OpenLP.FirstTimeWizard', 'Select the Plugins you wish to use. '))
|
||||
self.songsCheckBox.setText(translate('OpenLP.FirstTimeWizard', 'Songs'))
|
||||
self.customCheckBox.setText(translate('OpenLP.FirstTimeWizard','Custom Slides'))
|
||||
self.customCheckBox.setText(translate('OpenLP.FirstTimeWizard', 'Custom Slides'))
|
||||
self.bibleCheckBox.setText(translate('OpenLP.FirstTimeWizard', 'Bible'))
|
||||
self.imageCheckBox.setText(translate('OpenLP.FirstTimeWizard', 'Images'))
|
||||
# TODO Presentation plugin is not yet working on Mac OS X.
|
||||
|
@ -26,16 +26,23 @@
|
||||
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||
###############################################################################
|
||||
|
||||
"""
|
||||
The UI widgets for the formatting tags window.
|
||||
"""
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
from openlp.core.lib import translate, UiStrings
|
||||
from openlp.core.lib import UiStrings, translate
|
||||
from openlp.core.lib.ui import create_button_box
|
||||
|
||||
|
||||
class Ui_FormattingTagDialog(object):
|
||||
|
||||
"""
|
||||
The UI widgets for the formatting tags window.
|
||||
"""
|
||||
def setupUi(self, formattingTagDialog):
|
||||
"""
|
||||
Set up the UI
|
||||
"""
|
||||
formattingTagDialog.setObjectName(u'formattingTagDialog')
|
||||
formattingTagDialog.resize(725, 548)
|
||||
self.listdataGridLayout = QtGui.QGridLayout(formattingTagDialog)
|
||||
@ -116,6 +123,9 @@ class Ui_FormattingTagDialog(object):
|
||||
self.retranslateUi(formattingTagDialog)
|
||||
|
||||
def retranslateUi(self, formattingTagDialog):
|
||||
"""
|
||||
Translate the UI on the fly
|
||||
"""
|
||||
formattingTagDialog.setWindowTitle(translate('OpenLP.FormattingTagDialog', 'Configure Formatting Tags'))
|
||||
self.editGroupBox.setTitle(translate('OpenLP.FormattingTagDialog', 'Edit Selection'))
|
||||
self.savePushButton.setText(translate('OpenLP.FormattingTagDialog', 'Save'))
|
||||
|
@ -27,14 +27,13 @@
|
||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||
###############################################################################
|
||||
"""
|
||||
The :mod:`formattingtagform` provides an Tag Edit facility. The Base set are
|
||||
protected and included each time loaded. Custom tags can be defined and saved.
|
||||
The Custom Tag arrays are saved in a pickle so QSettings works on them. Base
|
||||
Tags cannot be changed.
|
||||
The :mod:`formattingtagform` provides an Tag Edit facility. The Base set are protected and included each time loaded.
|
||||
Custom tags can be defined and saved. The Custom Tag arrays are saved in a pickle so QSettings works on them. Base Tags
|
||||
cannot be changed.
|
||||
"""
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
from openlp.core.lib import translate, FormattingTags
|
||||
from openlp.core.lib import FormattingTags, translate
|
||||
from openlp.core.lib.ui import critical_error_message_box
|
||||
from openlp.core.ui.formattingtagdialog import Ui_FormattingTagDialog
|
||||
|
||||
@ -49,7 +48,7 @@ class FormattingTagForm(QtGui.QDialog, Ui_FormattingTagDialog):
|
||||
"""
|
||||
QtGui.QDialog.__init__(self, parent)
|
||||
self.setupUi(self)
|
||||
QtCore.QObject.connect(self.tagTableWidget, QtCore.SIGNAL(u'itemSelectionChanged()'),self.onRowSelected)
|
||||
QtCore.QObject.connect(self.tagTableWidget, QtCore.SIGNAL(u'itemSelectionChanged()'), self.onRowSelected)
|
||||
QtCore.QObject.connect(self.newPushButton, QtCore.SIGNAL(u'clicked()'), self.onNewClicked)
|
||||
QtCore.QObject.connect(self.savePushButton, QtCore.SIGNAL(u'clicked()'), self.onSavedClicked)
|
||||
QtCore.QObject.connect(self.deletePushButton, QtCore.SIGNAL(u'clicked()'), self.onDeleteClicked)
|
||||
|
@ -26,14 +26,18 @@
|
||||
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||
###############################################################################
|
||||
"""
|
||||
The general tab of the configuration dialog.
|
||||
"""
|
||||
import logging
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
from openlp.core.lib import Receiver, Settings, SettingsTab, translate, ScreenList, UiStrings
|
||||
from openlp.core.lib import Receiver, Settings, SettingsTab, ScreenList, UiStrings, translate
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class GeneralTab(SettingsTab):
|
||||
"""
|
||||
GeneralTab is the general settings tab in the settings dialog.
|
||||
|
@ -27,19 +27,23 @@
|
||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||
###############################################################################
|
||||
"""
|
||||
The :mod:`maindisplay` module provides the functionality to display screens
|
||||
and play multimedia within OpenLP.
|
||||
The :mod:`maindisplay` module provides the functionality to display screens and play multimedia within OpenLP.
|
||||
|
||||
Some of the code for this form is based on the examples at:
|
||||
|
||||
* `http://www.steveheffernan.com/html5-video-player/demo-video-player.html`_
|
||||
* `http://html5demos.com/two-videos`_
|
||||
|
||||
"""
|
||||
import cgi
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
|
||||
from PyQt4 import QtCore, QtGui, QtWebKit, QtOpenGL
|
||||
from PyQt4.phonon import Phonon
|
||||
|
||||
from openlp.core.lib import Receiver, build_html, ServiceItem, image_to_byte, translate, expand_tags,\
|
||||
Settings, ImageSource, Registry
|
||||
from openlp.core.lib import Receiver, ServiceItem, Settings, ImageSource, Registry, build_html, expand_tags, \
|
||||
image_to_byte, translate
|
||||
from openlp.core.lib.theme import BackgroundType
|
||||
|
||||
from openlp.core.lib import ScreenList
|
||||
@ -47,8 +51,6 @@ from openlp.core.ui import HideMode, AlertLocation
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
#http://www.steveheffernan.com/html5-video-player/demo-video-player.html
|
||||
#http://html5demos.com/two-videos
|
||||
|
||||
class Display(QtGui.QGraphicsView):
|
||||
"""
|
||||
@ -57,6 +59,9 @@ class Display(QtGui.QGraphicsView):
|
||||
Preview display.
|
||||
"""
|
||||
def __init__(self, parent, live, controller):
|
||||
"""
|
||||
Constructor
|
||||
"""
|
||||
if live:
|
||||
QtGui.QGraphicsView.__init__(self)
|
||||
# Overwrite the parent() method.
|
||||
@ -101,6 +106,9 @@ class Display(QtGui.QGraphicsView):
|
||||
QtCore.Qt.ScrollBarAlwaysOff)
|
||||
|
||||
def resizeEvent(self, event):
|
||||
"""
|
||||
React to resizing of this display
|
||||
"""
|
||||
self.webView.setGeometry(0, 0, self.width(), self.height())
|
||||
|
||||
def isWebLoaded(self):
|
||||
@ -116,6 +124,9 @@ class MainDisplay(Display):
|
||||
This is the display screen as a specialized class from the Display class
|
||||
"""
|
||||
def __init__(self, parent, live, controller):
|
||||
"""
|
||||
Constructor
|
||||
"""
|
||||
Display.__init__(self, parent, live, controller)
|
||||
self.screens = ScreenList()
|
||||
self.rebuildCSS = False
|
||||
@ -153,6 +164,9 @@ class MainDisplay(Display):
|
||||
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'config_updated'), self.configChanged)
|
||||
|
||||
def setTransparency(self, enabled):
|
||||
"""
|
||||
Set the transparency of the window
|
||||
"""
|
||||
if enabled:
|
||||
self.setAutoFillBackground(False)
|
||||
else:
|
||||
@ -229,7 +243,7 @@ class MainDisplay(Display):
|
||||
log.debug(u'text to display')
|
||||
# Wait for the webview to update before displaying text.
|
||||
while not self.webLoaded:
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
self.application.process_events()
|
||||
self.setGeometry(self.screen[u'size'])
|
||||
if animate:
|
||||
self.frame.evaluateJavaScript(u'show_text("%s")' % slide.replace(u'\\', u'\\\\').replace(u'\"', u'\\\"'))
|
||||
@ -278,7 +292,7 @@ class MainDisplay(Display):
|
||||
"""
|
||||
API for replacement backgrounds so Images are added directly to cache.
|
||||
"""
|
||||
self.image_manager.addImage(path, ImageSource.ImagePlugin, background)
|
||||
self.image_manager.add_image(path, ImageSource.ImagePlugin, background)
|
||||
if not hasattr(self, u'serviceItem'):
|
||||
return False
|
||||
self.override[u'image'] = path
|
||||
@ -300,7 +314,7 @@ class MainDisplay(Display):
|
||||
re-added to the image manager.
|
||||
"""
|
||||
log.debug(u'image to display')
|
||||
image = self.image_manager.getImageBytes(path, ImageSource.ImagePlugin)
|
||||
image = self.image_manager.get_image_bytes(path, ImageSource.ImagePlugin)
|
||||
self.controller.media_controller.media_reset(self.controller)
|
||||
self.displayImage(image)
|
||||
|
||||
@ -333,18 +347,18 @@ class MainDisplay(Display):
|
||||
Generates a preview of the image displayed.
|
||||
"""
|
||||
log.debug(u'preview for %s', self.isLive)
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
self.application.process_events()
|
||||
# We must have a service item to preview.
|
||||
if self.isLive and hasattr(self, u'serviceItem'):
|
||||
# Wait for the fade to finish before geting the preview.
|
||||
# Important otherwise preview will have incorrect text if at all!
|
||||
if self.serviceItem.themedata and self.serviceItem.themedata.display_slide_transition:
|
||||
while self.frame.evaluateJavaScript(u'show_text_complete()') == u'false':
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
self.application.process_events()
|
||||
# Wait for the webview to update before getting the preview.
|
||||
# Important otherwise first preview will miss the background !
|
||||
while not self.webLoaded:
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
self.application.process_events()
|
||||
# if was hidden keep it hidden
|
||||
if self.isLive:
|
||||
if self.hideMode:
|
||||
@ -381,14 +395,16 @@ class MainDisplay(Display):
|
||||
self.override = {}
|
||||
else:
|
||||
# replace the background
|
||||
background = self.image_manager.getImageBytes(self.override[u'image'], ImageSource.ImagePlugin)
|
||||
background = self.image_manager.get_image_bytes(self.override[u'image'], ImageSource.ImagePlugin)
|
||||
self.setTransparency(self.serviceItem.themedata.background_type ==
|
||||
BackgroundType.to_string(BackgroundType.Transparent))
|
||||
if self.serviceItem.themedata.background_filename:
|
||||
self.serviceItem.bg_image_bytes = self.image_manager.getImageBytes(
|
||||
self.serviceItem.themedata.background_filename,ImageSource.Theme)
|
||||
self.serviceItem.bg_image_bytes = self.image_manager.get_image_bytes(
|
||||
self.serviceItem.themedata.background_filename,
|
||||
ImageSource.Theme
|
||||
)
|
||||
if image_path:
|
||||
image_bytes = self.image_manager.getImageBytes(image_path, ImageSource.ImagePlugin)
|
||||
image_bytes = self.image_manager.get_image_bytes(image_path, ImageSource.ImagePlugin)
|
||||
else:
|
||||
image_bytes = None
|
||||
html = build_html(self.serviceItem, self.screen, self.isLive, background, image_bytes,
|
||||
@ -487,6 +503,16 @@ class MainDisplay(Display):
|
||||
|
||||
image_manager = property(_get_image_manager)
|
||||
|
||||
def _get_application(self):
|
||||
"""
|
||||
Adds the openlp to the class dynamically
|
||||
"""
|
||||
if not hasattr(self, u'_application'):
|
||||
self._application = Registry().get(u'application')
|
||||
return self._application
|
||||
|
||||
application = property(_get_application)
|
||||
|
||||
|
||||
class AudioPlayer(QtCore.QObject):
|
||||
"""
|
||||
@ -532,6 +558,9 @@ class AudioPlayer(QtCore.QObject):
|
||||
self.mediaObject.enqueue(self.playlist[self.currentIndex])
|
||||
|
||||
def onFinished(self):
|
||||
"""
|
||||
When the audio track finishes.
|
||||
"""
|
||||
if self.repeat:
|
||||
log.debug(u'Repeat is enabled... here we go again!')
|
||||
self.mediaObject.clearQueue()
|
||||
@ -540,6 +569,9 @@ class AudioPlayer(QtCore.QObject):
|
||||
self.play()
|
||||
|
||||
def connectVolumeSlider(self, slider):
|
||||
"""
|
||||
Connect the volume slider to the output channel.
|
||||
"""
|
||||
slider.setAudioOutput(self.audioObject)
|
||||
|
||||
def reset(self):
|
||||
@ -586,6 +618,9 @@ class AudioPlayer(QtCore.QObject):
|
||||
self.playlist.extend(map(Phonon.MediaSource, filenames))
|
||||
|
||||
def next(self):
|
||||
"""
|
||||
Skip forward to the next track in the list
|
||||
"""
|
||||
if not self.repeat and self.currentIndex + 1 >= len(self.playlist):
|
||||
return
|
||||
isPlaying = self.mediaObject.state() == Phonon.PlayingState
|
||||
@ -599,6 +634,9 @@ class AudioPlayer(QtCore.QObject):
|
||||
self.mediaObject.play()
|
||||
|
||||
def goTo(self, index):
|
||||
"""
|
||||
Go to a particular track in the list
|
||||
"""
|
||||
isPlaying = self.mediaObject.state() == Phonon.PlayingState
|
||||
self.mediaObject.clearQueue()
|
||||
self.mediaObject.clear()
|
||||
@ -609,5 +647,7 @@ class AudioPlayer(QtCore.QObject):
|
||||
|
||||
#@todo is this used?
|
||||
def connectSlot(self, signal, slot):
|
||||
"""
|
||||
Connect a slot to a signal on the media object
|
||||
"""
|
||||
QtCore.QObject.connect(self.mediaObject, signal, slot)
|
||||
|
||||
|
@ -26,7 +26,9 @@
|
||||
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||
###############################################################################
|
||||
|
||||
"""
|
||||
This is the main window, where all the action happens.
|
||||
"""
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
@ -39,13 +41,13 @@ from datetime import datetime
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
from openlp.core.lib import Renderer, build_icon, OpenLPDockWidget, PluginManager, Receiver, translate, ImageManager, \
|
||||
PluginStatus, Registry, Settings, ScreenList
|
||||
from openlp.core.lib import Renderer, OpenLPDockWidget, PluginManager, Receiver, ImageManager, PluginStatus, Registry, \
|
||||
Settings, ScreenList, build_icon, check_directory_exists, translate
|
||||
from openlp.core.lib.ui import UiStrings, create_action
|
||||
from openlp.core.ui import AboutForm, SettingsForm, ServiceManager, ThemeManager, SlideController, PluginForm, \
|
||||
MediaDockManager, ShortcutListForm, FormattingTagForm
|
||||
from openlp.core.ui.media import MediaController
|
||||
from openlp.core.utils import AppLocation, add_actions, LanguageManager, get_application_version, \
|
||||
from openlp.core.utils import AppLocation, LanguageManager, add_actions, get_application_version, \
|
||||
get_filesystem_encoding
|
||||
from openlp.core.utils.actions import ActionList, CategoryOrder
|
||||
from openlp.core.ui.firsttimeform import FirstTimeForm
|
||||
@ -80,21 +82,24 @@ PROGRESSBAR_STYLE = """
|
||||
|
||||
|
||||
class Ui_MainWindow(object):
|
||||
def setupUi(self, mainWindow):
|
||||
"""
|
||||
This is the UI part of the main window.
|
||||
"""
|
||||
def setupUi(self, main_window):
|
||||
"""
|
||||
Set up the user interface
|
||||
"""
|
||||
mainWindow.setObjectName(u'MainWindow')
|
||||
mainWindow.setWindowIcon(build_icon(u':/icon/openlp-logo-64x64.png'))
|
||||
mainWindow.setDockNestingEnabled(True)
|
||||
main_window.setObjectName(u'MainWindow')
|
||||
main_window.setWindowIcon(build_icon(u':/icon/openlp-logo-64x64.png'))
|
||||
main_window.setDockNestingEnabled(True)
|
||||
# Set up the main container, which contains all the other form widgets.
|
||||
self.mainContent = QtGui.QWidget(mainWindow)
|
||||
self.mainContent = QtGui.QWidget(main_window)
|
||||
self.mainContent.setObjectName(u'mainContent')
|
||||
self.mainContentLayout = QtGui.QHBoxLayout(self.mainContent)
|
||||
self.mainContentLayout.setSpacing(0)
|
||||
self.mainContentLayout.setMargin(0)
|
||||
self.mainContentLayout.setObjectName(u'mainContentLayout')
|
||||
mainWindow.setCentralWidget(self.mainContent)
|
||||
main_window.setCentralWidget(self.mainContent)
|
||||
self.controlSplitter = QtGui.QSplitter(self.mainContent)
|
||||
self.controlSplitter.setOrientation(QtCore.Qt.Horizontal)
|
||||
self.controlSplitter.setObjectName(u'controlSplitter')
|
||||
@ -108,7 +113,7 @@ class Ui_MainWindow(object):
|
||||
panelLocked = Settings().value(u'user interface/lock panel')
|
||||
self.liveController.panel.setVisible(liveVisible)
|
||||
# Create menu
|
||||
self.menuBar = QtGui.QMenuBar(mainWindow)
|
||||
self.menuBar = QtGui.QMenuBar(main_window)
|
||||
self.menuBar.setObjectName(u'menuBar')
|
||||
self.fileMenu = QtGui.QMenu(self.menuBar)
|
||||
self.fileMenu.setObjectName(u'fileMenu')
|
||||
@ -134,10 +139,10 @@ class Ui_MainWindow(object):
|
||||
# Help Menu
|
||||
self.helpMenu = QtGui.QMenu(self.menuBar)
|
||||
self.helpMenu.setObjectName(u'helpMenu')
|
||||
mainWindow.setMenuBar(self.menuBar)
|
||||
self.statusBar = QtGui.QStatusBar(mainWindow)
|
||||
main_window.setMenuBar(self.menuBar)
|
||||
self.statusBar = QtGui.QStatusBar(main_window)
|
||||
self.statusBar.setObjectName(u'statusBar')
|
||||
mainWindow.setStatusBar(self.statusBar)
|
||||
main_window.setStatusBar(self.statusBar)
|
||||
self.loadProgressBar = QtGui.QProgressBar(self.statusBar)
|
||||
self.loadProgressBar.setObjectName(u'loadProgressBar')
|
||||
self.statusBar.addPermanentWidget(self.loadProgressBar)
|
||||
@ -148,142 +153,142 @@ class Ui_MainWindow(object):
|
||||
self.defaultThemeLabel.setObjectName(u'defaultThemeLabel')
|
||||
self.statusBar.addPermanentWidget(self.defaultThemeLabel)
|
||||
# Create the MediaManager
|
||||
self.mediaManagerDock = OpenLPDockWidget(mainWindow,u'mediaManagerDock', u':/system/system_mediamanager.png')
|
||||
self.mediaManagerDock = OpenLPDockWidget(main_window, u'mediaManagerDock', u':/system/system_mediamanager.png')
|
||||
self.mediaManagerDock.setStyleSheet(MEDIA_MANAGER_STYLE)
|
||||
# Create the media toolbox
|
||||
self.mediaToolBox = QtGui.QToolBox(self.mediaManagerDock)
|
||||
self.mediaToolBox.setObjectName(u'mediaToolBox')
|
||||
self.mediaManagerDock.setWidget(self.mediaToolBox)
|
||||
mainWindow.addDockWidget(QtCore.Qt.LeftDockWidgetArea, self.mediaManagerDock)
|
||||
main_window.addDockWidget(QtCore.Qt.LeftDockWidgetArea, self.mediaManagerDock)
|
||||
# Create the service manager
|
||||
self.serviceManagerDock = OpenLPDockWidget(mainWindow, u'serviceManagerDock',
|
||||
self.serviceManagerDock = OpenLPDockWidget(main_window, u'serviceManagerDock',
|
||||
u':/system/system_servicemanager.png')
|
||||
self.serviceManagerContents = ServiceManager(self.serviceManagerDock)
|
||||
self.serviceManagerDock.setWidget(self.serviceManagerContents)
|
||||
mainWindow.addDockWidget(QtCore.Qt.RightDockWidgetArea, self.serviceManagerDock)
|
||||
main_window.addDockWidget(QtCore.Qt.RightDockWidgetArea, self.serviceManagerDock)
|
||||
# Create the theme manager
|
||||
self.themeManagerDock = OpenLPDockWidget(mainWindow, u'themeManagerDock', u':/system/system_thememanager.png')
|
||||
self.themeManagerDock = OpenLPDockWidget(main_window, u'themeManagerDock', u':/system/system_thememanager.png')
|
||||
self.themeManagerContents = ThemeManager(self.themeManagerDock)
|
||||
self.themeManagerContents.setObjectName(u'themeManagerContents')
|
||||
self.themeManagerDock.setWidget(self.themeManagerContents)
|
||||
mainWindow.addDockWidget(QtCore.Qt.RightDockWidgetArea, self.themeManagerDock)
|
||||
main_window.addDockWidget(QtCore.Qt.RightDockWidgetArea, self.themeManagerDock)
|
||||
# Create the menu items
|
||||
action_list = ActionList.get_instance()
|
||||
action_list.add_category(UiStrings().File, CategoryOrder.standardMenu)
|
||||
self.fileNewItem = create_action(mainWindow, u'fileNewItem',
|
||||
self.fileNewItem = create_action(main_window, u'fileNewItem',
|
||||
icon=u':/general/general_new.png',
|
||||
shortcuts=[QtGui.QKeySequence(u'Ctrl+N')],
|
||||
category=UiStrings().File,
|
||||
triggers=self.serviceManagerContents.on_new_service_clicked)
|
||||
self.fileOpenItem = create_action(mainWindow, u'fileOpenItem',
|
||||
self.fileOpenItem = create_action(main_window, u'fileOpenItem',
|
||||
icon=u':/general/general_open.png',
|
||||
shortcuts=[QtGui.QKeySequence(u'Ctrl+O')],
|
||||
category=UiStrings().File,
|
||||
triggers=self.serviceManagerContents.on_load_service_clicked)
|
||||
self.fileSaveItem = create_action(mainWindow, u'fileSaveItem',
|
||||
self.fileSaveItem = create_action(main_window, u'fileSaveItem',
|
||||
icon=u':/general/general_save.png',
|
||||
shortcuts=[QtGui.QKeySequence(u'Ctrl+S')],
|
||||
category=UiStrings().File,
|
||||
triggers=self.serviceManagerContents.save_file)
|
||||
self.fileSaveAsItem = create_action(mainWindow, u'fileSaveAsItem',
|
||||
self.fileSaveAsItem = create_action(main_window, u'fileSaveAsItem',
|
||||
shortcuts=[QtGui.QKeySequence(u'Ctrl+Shift+S')],
|
||||
category=UiStrings().File,
|
||||
triggers=self.serviceManagerContents.save_file_as)
|
||||
self.printServiceOrderItem = create_action(mainWindow,
|
||||
self.printServiceOrderItem = create_action(main_window,
|
||||
u'printServiceItem', shortcuts=[QtGui.QKeySequence(u'Ctrl+P')],
|
||||
category=UiStrings().File,
|
||||
triggers=self.serviceManagerContents.print_service_order)
|
||||
self.fileExitItem = create_action(mainWindow, u'fileExitItem',
|
||||
self.fileExitItem = create_action(main_window, u'fileExitItem',
|
||||
icon=u':/system/system_exit.png',
|
||||
shortcuts=[QtGui.QKeySequence(u'Alt+F4')],
|
||||
category=UiStrings().File, triggers=mainWindow.close)
|
||||
category=UiStrings().File, triggers=main_window.close)
|
||||
# Give QT Extra Hint that this is the Exit Menu Item
|
||||
self.fileExitItem.setMenuRole(QtGui.QAction.QuitRole)
|
||||
action_list.add_category(UiStrings().Import, CategoryOrder.standardMenu)
|
||||
self.importThemeItem = create_action(mainWindow, u'importThemeItem', category=UiStrings().Import)
|
||||
self.importLanguageItem = create_action(mainWindow, u'importLanguageItem')
|
||||
self.importThemeItem = create_action(main_window, u'importThemeItem', category=UiStrings().Import)
|
||||
self.importLanguageItem = create_action(main_window, u'importLanguageItem')
|
||||
action_list.add_category(UiStrings().Export, CategoryOrder.standardMenu)
|
||||
self.exportThemeItem = create_action(mainWindow, u'exportThemeItem', category=UiStrings().Export)
|
||||
self.exportLanguageItem = create_action(mainWindow, u'exportLanguageItem')
|
||||
self.exportThemeItem = create_action(main_window, u'exportThemeItem', category=UiStrings().Export)
|
||||
self.exportLanguageItem = create_action(main_window, u'exportLanguageItem')
|
||||
action_list.add_category(UiStrings().View, CategoryOrder.standardMenu)
|
||||
self.viewMediaManagerItem = create_action(mainWindow,
|
||||
self.viewMediaManagerItem = create_action(main_window,
|
||||
u'viewMediaManagerItem', shortcuts=[QtGui.QKeySequence(u'F8')],
|
||||
icon=u':/system/system_mediamanager.png',
|
||||
checked=self.mediaManagerDock.isVisible(),
|
||||
category=UiStrings().View, triggers=self.toggleMediaManager)
|
||||
self.viewThemeManagerItem = create_action(mainWindow,
|
||||
self.viewThemeManagerItem = create_action(main_window,
|
||||
u'viewThemeManagerItem', shortcuts=[QtGui.QKeySequence(u'F10')],
|
||||
icon=u':/system/system_thememanager.png',
|
||||
checked=self.themeManagerDock.isVisible(),
|
||||
category=UiStrings().View, triggers=self.toggleThemeManager)
|
||||
self.viewServiceManagerItem = create_action(mainWindow,
|
||||
self.viewServiceManagerItem = create_action(main_window,
|
||||
u'viewServiceManagerItem', shortcuts=[QtGui.QKeySequence(u'F9')],
|
||||
icon=u':/system/system_servicemanager.png',
|
||||
checked=self.serviceManagerDock.isVisible(),
|
||||
category=UiStrings().View, triggers=self.toggleServiceManager)
|
||||
self.viewPreviewPanel = create_action(mainWindow, u'viewPreviewPanel',
|
||||
self.viewPreviewPanel = create_action(main_window, u'viewPreviewPanel',
|
||||
shortcuts=[QtGui.QKeySequence(u'F11')], checked=previewVisible,
|
||||
category=UiStrings().View, triggers=self.setPreviewPanelVisibility)
|
||||
self.viewLivePanel = create_action(mainWindow, u'viewLivePanel',
|
||||
self.viewLivePanel = create_action(main_window, u'viewLivePanel',
|
||||
shortcuts=[QtGui.QKeySequence(u'F12')], checked=liveVisible,
|
||||
category=UiStrings().View, triggers=self.setLivePanelVisibility)
|
||||
self.lockPanel = create_action(mainWindow, u'lockPanel',
|
||||
self.lockPanel = create_action(main_window, u'lockPanel',
|
||||
checked=panelLocked, triggers=self.setLockPanel)
|
||||
action_list.add_category(UiStrings().ViewMode,
|
||||
CategoryOrder.standardMenu)
|
||||
self.modeDefaultItem = create_action(mainWindow, u'modeDefaultItem', checked=False,
|
||||
self.modeDefaultItem = create_action(main_window, u'modeDefaultItem', checked=False,
|
||||
category=UiStrings().ViewMode)
|
||||
self.modeSetupItem = create_action(mainWindow, u'modeSetupItem', checked=False, category=UiStrings().ViewMode)
|
||||
self.modeLiveItem = create_action(mainWindow, u'modeLiveItem', checked=True, category=UiStrings().ViewMode)
|
||||
self.modeGroup = QtGui.QActionGroup(mainWindow)
|
||||
self.modeSetupItem = create_action(main_window, u'modeSetupItem', checked=False, category=UiStrings().ViewMode)
|
||||
self.modeLiveItem = create_action(main_window, u'modeLiveItem', checked=True, category=UiStrings().ViewMode)
|
||||
self.modeGroup = QtGui.QActionGroup(main_window)
|
||||
self.modeGroup.addAction(self.modeDefaultItem)
|
||||
self.modeGroup.addAction(self.modeSetupItem)
|
||||
self.modeGroup.addAction(self.modeLiveItem)
|
||||
self.modeDefaultItem.setChecked(True)
|
||||
action_list.add_category(UiStrings().Tools, CategoryOrder.standardMenu)
|
||||
self.toolsAddToolItem = create_action(mainWindow,
|
||||
self.toolsAddToolItem = create_action(main_window,
|
||||
u'toolsAddToolItem', icon=u':/tools/tools_add.png',
|
||||
category=UiStrings().Tools)
|
||||
self.toolsOpenDataFolder = create_action(mainWindow,
|
||||
self.toolsOpenDataFolder = create_action(main_window,
|
||||
u'toolsOpenDataFolder', icon=u':/general/general_open.png',
|
||||
category=UiStrings().Tools)
|
||||
self.toolsFirstTimeWizard = create_action(mainWindow,
|
||||
self.toolsFirstTimeWizard = create_action(main_window,
|
||||
u'toolsFirstTimeWizard', icon=u':/general/general_revert.png',
|
||||
category=UiStrings().Tools)
|
||||
self.updateThemeImages = create_action(mainWindow,
|
||||
self.updateThemeImages = create_action(main_window,
|
||||
u'updateThemeImages', category=UiStrings().Tools)
|
||||
action_list.add_category(UiStrings().Settings,
|
||||
CategoryOrder.standardMenu)
|
||||
self.settingsPluginListItem = create_action(mainWindow,
|
||||
self.settingsPluginListItem = create_action(main_window,
|
||||
u'settingsPluginListItem',
|
||||
icon=u':/system/settings_plugin_list.png',
|
||||
shortcuts=[QtGui.QKeySequence(u'Alt+F7')],
|
||||
category=UiStrings().Settings, triggers=self.onPluginItemClicked)
|
||||
# i18n Language Items
|
||||
self.autoLanguageItem = create_action(mainWindow, u'autoLanguageItem',
|
||||
self.autoLanguageItem = create_action(main_window, u'autoLanguageItem',
|
||||
checked=LanguageManager.auto_language)
|
||||
self.languageGroup = QtGui.QActionGroup(mainWindow)
|
||||
self.languageGroup = QtGui.QActionGroup(main_window)
|
||||
self.languageGroup.setExclusive(True)
|
||||
self.languageGroup.setObjectName(u'languageGroup')
|
||||
add_actions(self.languageGroup, [self.autoLanguageItem])
|
||||
qmList = LanguageManager.get_qm_list()
|
||||
savedLanguage = LanguageManager.get_language()
|
||||
for key in sorted(qmList.keys()):
|
||||
languageItem = create_action(mainWindow, key, checked=qmList[key] == savedLanguage)
|
||||
languageItem = create_action(main_window, key, checked=qmList[key] == savedLanguage)
|
||||
add_actions(self.languageGroup, [languageItem])
|
||||
self.settingsShortcutsItem = create_action(mainWindow, u'settingsShortcutsItem',
|
||||
self.settingsShortcutsItem = create_action(main_window, u'settingsShortcutsItem',
|
||||
icon=u':/system/system_configure_shortcuts.png', category=UiStrings().Settings)
|
||||
# Formatting Tags were also known as display tags.
|
||||
self.formattingTagItem = create_action(mainWindow, u'displayTagItem',
|
||||
self.formattingTagItem = create_action(main_window, u'displayTagItem',
|
||||
icon=u':/system/tag_editor.png', category=UiStrings().Settings)
|
||||
self.settingsConfigureItem = create_action(mainWindow, u'settingsConfigureItem',
|
||||
self.settingsConfigureItem = create_action(main_window, u'settingsConfigureItem',
|
||||
icon=u':/system/system_settings.png', category=UiStrings().Settings)
|
||||
# Give QT Extra Hint that this is the Preferences Menu Item
|
||||
self.settingsConfigureItem.setMenuRole(QtGui.QAction.PreferencesRole)
|
||||
self.settingsImportItem = create_action(mainWindow, u'settingsImportItem', category=UiStrings().Settings)
|
||||
self.settingsExportItem = create_action(mainWindow, u'settingsExportItem', category=UiStrings().Settings)
|
||||
self.settingsImportItem = create_action(main_window, u'settingsImportItem', category=UiStrings().Settings)
|
||||
self.settingsExportItem = create_action(main_window, u'settingsExportItem', category=UiStrings().Settings)
|
||||
action_list.add_category(UiStrings().Help, CategoryOrder.standardMenu)
|
||||
self.aboutItem = create_action(mainWindow, u'aboutItem', icon=u':/system/system_about.png',
|
||||
self.aboutItem = create_action(main_window, u'aboutItem', icon=u':/system/system_about.png',
|
||||
shortcuts=[QtGui.QKeySequence(u'Ctrl+F1')],
|
||||
category=UiStrings().Help, triggers=self.onAboutItemClicked)
|
||||
# Give QT Extra Hint that this is an About Menu Item
|
||||
@ -291,15 +296,15 @@ class Ui_MainWindow(object):
|
||||
if os.name == u'nt':
|
||||
self.localHelpFile = os.path.join(
|
||||
AppLocation.get_directory(AppLocation.AppDir), 'OpenLP.chm')
|
||||
self.offlineHelpItem = create_action(mainWindow, u'offlineHelpItem',
|
||||
self.offlineHelpItem = create_action(main_window, u'offlineHelpItem',
|
||||
icon=u':/system/system_help_contents.png',
|
||||
shortcuts=[QtGui.QKeySequence(u'F1')],
|
||||
category=UiStrings().Help, triggers=self.onOfflineHelpClicked)
|
||||
self.onlineHelpItem = create_action(mainWindow, u'onlineHelpItem',
|
||||
self.onlineHelpItem = create_action(main_window, u'onlineHelpItem',
|
||||
icon=u':/system/system_online_help.png',
|
||||
shortcuts=[QtGui.QKeySequence(u'Alt+F1')],
|
||||
category=UiStrings().Help, triggers=self.onOnlineHelpClicked)
|
||||
self.webSiteItem = create_action(mainWindow, u'webSiteItem', category=UiStrings().Help)
|
||||
self.webSiteItem = create_action(main_window, u'webSiteItem', category=UiStrings().Help)
|
||||
add_actions(self.fileImportMenu, (self.settingsImportItem, None, self.importThemeItem, self.importLanguageItem))
|
||||
add_actions(self.fileExportMenu, (self.settingsExportItem, None, self.exportThemeItem, self.exportLanguageItem))
|
||||
add_actions(self.fileMenu, (self.fileNewItem, self.fileOpenItem,
|
||||
@ -333,7 +338,7 @@ class Ui_MainWindow(object):
|
||||
add_actions(self.menuBar, (self.fileMenu.menuAction(), self.viewMenu.menuAction(), self.toolsMenu.menuAction(),
|
||||
self.settingsMenu.menuAction(), self.helpMenu.menuAction()))
|
||||
# Initialise the translation
|
||||
self.retranslateUi(mainWindow)
|
||||
self.retranslateUi(main_window)
|
||||
self.mediaToolBox.setCurrentIndex(0)
|
||||
# Connect up some signals and slots
|
||||
QtCore.QObject.connect(self.fileMenu, QtCore.SIGNAL(u'aboutToShow()'), self.updateRecentFilesMenu)
|
||||
@ -406,7 +411,8 @@ class Ui_MainWindow(object):
|
||||
'Toggle the visibility of the service manager.'))
|
||||
self.viewPreviewPanel.setText(translate('OpenLP.MainWindow', '&Preview Panel'))
|
||||
self.viewPreviewPanel.setToolTip(translate('OpenLP.MainWindow', 'Toggle Preview Panel'))
|
||||
self.viewPreviewPanel.setStatusTip(translate('OpenLP.MainWindow', 'Toggle the visibility of the preview panel.'))
|
||||
self.viewPreviewPanel.setStatusTip(
|
||||
translate('OpenLP.MainWindow', 'Toggle the visibility of the preview panel.'))
|
||||
self.viewLivePanel.setText(translate('OpenLP.MainWindow', '&Live Panel'))
|
||||
self.viewLivePanel.setToolTip(translate('OpenLP.MainWindow', 'Toggle Live Panel'))
|
||||
self.lockPanel.setText(translate('OpenLP.MainWindow', 'L&ock Panels'))
|
||||
@ -449,14 +455,13 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
||||
"""
|
||||
log.info(u'MainWindow loaded')
|
||||
|
||||
def __init__(self, application):
|
||||
def __init__(self):
|
||||
"""
|
||||
This constructor sets up the interface, the various managers, and the
|
||||
plugins.
|
||||
"""
|
||||
QtGui.QMainWindow.__init__(self)
|
||||
Registry().register(u'main_window', self)
|
||||
self.application = application
|
||||
self.clipboard = self.application.clipboard()
|
||||
self.arguments = self.application.args
|
||||
# Set up settings sections for the main application (not for use by plugins).
|
||||
@ -481,7 +486,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
||||
self.recentFiles = []
|
||||
# Set up the path with plugins
|
||||
plugin_path = AppLocation.get_directory(AppLocation.PluginsDir)
|
||||
self.pluginManager = PluginManager(plugin_path)
|
||||
self.plugin_manager = PluginManager(plugin_path)
|
||||
self.imageManager = ImageManager()
|
||||
# Set up the interface
|
||||
self.setupUi(self)
|
||||
@ -496,9 +501,9 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
||||
self.copyData = False
|
||||
# Set up signals and slots
|
||||
QtCore.QObject.connect(self.importThemeItem, QtCore.SIGNAL(u'triggered()'),
|
||||
self.themeManagerContents.onImportTheme)
|
||||
self.themeManagerContents.on_import_theme)
|
||||
QtCore.QObject.connect(self.exportThemeItem, QtCore.SIGNAL(u'triggered()'),
|
||||
self.themeManagerContents.onExportTheme)
|
||||
self.themeManagerContents.on_export_theme)
|
||||
QtCore.QObject.connect(self.mediaManagerDock, QtCore.SIGNAL(u'visibilityChanged(bool)'),
|
||||
self.viewMediaManagerItem.setChecked)
|
||||
QtCore.QObject.connect(self.serviceManagerDock, QtCore.SIGNAL(u'visibilityChanged(bool)'),
|
||||
@ -517,7 +522,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
||||
self.onSettingsShortcutsItemClicked)
|
||||
QtCore.QObject.connect(self.settingsImportItem, QtCore.SIGNAL(u'triggered()'),
|
||||
self.onSettingsImportItemClicked)
|
||||
QtCore.QObject.connect(self.settingsExportItem,QtCore.SIGNAL(u'triggered()'), self.onSettingsExportItemClicked)
|
||||
QtCore.QObject.connect(self.settingsExportItem, QtCore.SIGNAL(u'triggered()'), self.onSettingsExportItemClicked)
|
||||
# i18n set signals for languages
|
||||
self.languageGroup.triggered.connect(LanguageManager.set_language)
|
||||
QtCore.QObject.connect(self.modeDefaultItem, QtCore.SIGNAL(u'triggered()'), self.onModeDefaultItemClicked)
|
||||
@ -527,14 +532,14 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
||||
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'openlp_version_check'), self.versionNotice)
|
||||
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'live_display_blank_check'), self.blankCheck)
|
||||
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'config_screen_changed'), self.screenChanged)
|
||||
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'mainwindow_status_text'), self.showStatusMessage)
|
||||
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'mainwindow_status_text'),
|
||||
self.showStatusMessage)
|
||||
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'cleanup'), self.clean_up)
|
||||
# Media Manager
|
||||
QtCore.QObject.connect(self.mediaToolBox, QtCore.SIGNAL(u'currentChanged(int)'), self.onMediaToolBoxChanged)
|
||||
Receiver.send_message(u'cursor_busy')
|
||||
self.application.set_busy_cursor()
|
||||
# Simple message boxes
|
||||
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'openlp_error_message'), self.onErrorMessage)
|
||||
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'openlp_warning_message'), self.onWarningMessage)
|
||||
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'openlp_information_message'),
|
||||
self.onInformationMessage)
|
||||
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'set_new_data_path'), self.setNewDataPath)
|
||||
@ -546,25 +551,25 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
||||
# Define the media Dock Manager
|
||||
self.mediaDockManager = MediaDockManager(self.mediaToolBox)
|
||||
log.info(u'Load Plugins')
|
||||
self.pluginManager.find_plugins(plugin_path)
|
||||
self.plugin_manager.find_plugins(plugin_path)
|
||||
# hook methods have to happen after find_plugins. Find plugins needs
|
||||
# the controllers hence the hooks have moved from setupUI() to here
|
||||
# Find and insert settings tabs
|
||||
log.info(u'hook settings')
|
||||
self.pluginManager.hook_settings_tabs(self.settingsForm)
|
||||
self.plugin_manager.hook_settings_tabs(self.settingsForm)
|
||||
# Find and insert media manager items
|
||||
log.info(u'hook media')
|
||||
self.pluginManager.hook_media_manager()
|
||||
self.plugin_manager.hook_media_manager()
|
||||
# Call the hook method to pull in import menus.
|
||||
log.info(u'hook menus')
|
||||
self.pluginManager.hook_import_menu(self.fileImportMenu)
|
||||
self.plugin_manager.hook_import_menu(self.fileImportMenu)
|
||||
# Call the hook method to pull in export menus.
|
||||
self.pluginManager.hook_export_menu(self.fileExportMenu)
|
||||
self.plugin_manager.hook_export_menu(self.fileExportMenu)
|
||||
# Call the hook method to pull in tools menus.
|
||||
self.pluginManager.hook_tools_menu(self.toolsMenu)
|
||||
self.plugin_manager.hook_tools_menu(self.toolsMenu)
|
||||
# Call the initialise method to setup plugins.
|
||||
log.info(u'initialise plugins')
|
||||
self.pluginManager.initialise_plugins()
|
||||
self.plugin_manager.initialise_plugins()
|
||||
# Create the displays as all necessary components are loaded.
|
||||
self.previewController.screenSizeChanged()
|
||||
self.liveController.screenSizeChanged()
|
||||
@ -576,18 +581,24 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
||||
self.settingsForm.postSetUp()
|
||||
# Once all components are initialised load the Themes
|
||||
log.info(u'Load Themes')
|
||||
self.themeManagerContents.loadThemes(True)
|
||||
self.themeManagerContents.load_themes(True)
|
||||
# Hide/show the theme combobox on the service manager
|
||||
self.serviceManagerContents.themeChange()
|
||||
self.serviceManagerContents.theme_change()
|
||||
# Reset the cursor
|
||||
Receiver.send_message(u'cursor_normal')
|
||||
self.application.set_normal_cursor()
|
||||
|
||||
def setAutoLanguage(self, value):
|
||||
"""
|
||||
Set the language to automatic.
|
||||
"""
|
||||
self.languageGroup.setDisabled(value)
|
||||
LanguageManager.auto_language = value
|
||||
LanguageManager.set_language(self.languageGroup.checkedAction())
|
||||
|
||||
def onMediaToolBoxChanged(self, index):
|
||||
"""
|
||||
Focus a widget when the media toolbox changes.
|
||||
"""
|
||||
widget = self.mediaToolBox.widget(index)
|
||||
if widget:
|
||||
widget.onFocus()
|
||||
@ -631,24 +642,26 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
||||
self.setViewMode(False, True, False, False, True)
|
||||
self.modeLiveItem.setChecked(True)
|
||||
|
||||
def appStartup(self):
|
||||
def app_startup(self):
|
||||
"""
|
||||
Give all the plugins a chance to perform some tasks at startup
|
||||
"""
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
for plugin in self.pluginManager.plugins:
|
||||
self.application.process_events()
|
||||
for plugin in self.plugin_manager.plugins:
|
||||
if plugin.isActive():
|
||||
plugin.appStartup()
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
plugin.app_startup()
|
||||
self.application.process_events()
|
||||
|
||||
def firstTime(self):
|
||||
# Import themes if first time
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
for plugin in self.pluginManager.plugins:
|
||||
if hasattr(plugin, u'firstTime'):
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
plugin.firstTime()
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
def first_time(self):
|
||||
"""
|
||||
Import themes if first time
|
||||
"""
|
||||
self.application.process_events()
|
||||
for plugin in self.plugin_manager.plugins:
|
||||
if hasattr(plugin, u'first_time'):
|
||||
self.application.process_events()
|
||||
plugin.first_time()
|
||||
self.application.process_events()
|
||||
temp_dir = os.path.join(unicode(gettempdir()), u'openlp')
|
||||
shutil.rmtree(temp_dir, True)
|
||||
|
||||
@ -669,29 +682,30 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
||||
QtGui.QMessageBox.No)
|
||||
if answer == QtGui.QMessageBox.No:
|
||||
return
|
||||
Receiver.send_message(u'cursor_busy')
|
||||
screens = ScreenList()
|
||||
firstTime = FirstTimeForm(screens, self)
|
||||
firstTime.exec_()
|
||||
if firstTime.downloadCancelled:
|
||||
first_run_wizard = FirstTimeForm(screens, self)
|
||||
first_run_wizard.exec_()
|
||||
if first_run_wizard.was_download_cancelled:
|
||||
return
|
||||
self.firstTime()
|
||||
for plugin in self.pluginManager.plugins:
|
||||
self.application.set_busy_cursor()
|
||||
self.first_time()
|
||||
for plugin in self.plugin_manager.plugins:
|
||||
self.activePlugin = plugin
|
||||
oldStatus = self.activePlugin.status
|
||||
self.activePlugin.setStatus()
|
||||
if oldStatus != self.activePlugin.status:
|
||||
if self.activePlugin.status == PluginStatus.Active:
|
||||
self.activePlugin.toggleStatus(PluginStatus.Active)
|
||||
self.activePlugin.appStartup()
|
||||
self.activePlugin.app_startup()
|
||||
else:
|
||||
self.activePlugin.toggleStatus(PluginStatus.Inactive)
|
||||
self.themeManagerContents.configUpdated()
|
||||
self.themeManagerContents.loadThemes(True)
|
||||
self.themeManagerContents.config_updated()
|
||||
self.themeManagerContents.load_themes(True)
|
||||
Receiver.send_message(u'theme_update_global', self.themeManagerContents.global_theme)
|
||||
# Check if any Bibles downloaded. If there are, they will be
|
||||
# processed.
|
||||
Receiver.send_message(u'bibles_load_list', True)
|
||||
self.application.set_normal_cursor()
|
||||
|
||||
def blankCheck(self):
|
||||
"""
|
||||
@ -705,15 +719,24 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
||||
translate('OpenLP.MainWindow', 'The Main Display has been blanked out'))
|
||||
|
||||
def onErrorMessage(self, data):
|
||||
Receiver.send_message(u'close_splash')
|
||||
"""
|
||||
Display an error message
|
||||
"""
|
||||
self.application.close_splash_screen()
|
||||
QtGui.QMessageBox.critical(self, data[u'title'], data[u'message'])
|
||||
|
||||
def onWarningMessage(self, data):
|
||||
Receiver.send_message(u'close_splash')
|
||||
QtGui.QMessageBox.warning(self, data[u'title'], data[u'message'])
|
||||
def warning_message(self, message):
|
||||
"""
|
||||
Display a warning message
|
||||
"""
|
||||
self.application.close_splash_screen()
|
||||
QtGui.QMessageBox.warning(self, message[u'title'], message[u'message'])
|
||||
|
||||
def onInformationMessage(self, data):
|
||||
Receiver.send_message(u'close_splash')
|
||||
"""
|
||||
Display an informational message
|
||||
"""
|
||||
self.application.close_splash_screen()
|
||||
QtGui.QMessageBox.information(self, data[u'title'], data[u'message'])
|
||||
|
||||
def onHelpWebSiteClicked(self):
|
||||
@ -760,7 +783,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
||||
"""
|
||||
Updates the new theme preview images.
|
||||
"""
|
||||
self.themeManagerContents.updatePreviewImages()
|
||||
self.themeManagerContents.update_preview_images()
|
||||
|
||||
def onFormattingTagItemClicked(self):
|
||||
"""
|
||||
@ -800,8 +823,8 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
||||
QtGui.QMessageBox.No)
|
||||
if answer == QtGui.QMessageBox.No:
|
||||
return
|
||||
import_file_name = QtGui.QFileDialog.getOpenFileName(self,translate('OpenLP.MainWindow', 'Open File'), '',
|
||||
translate('OpenLP.MainWindow', 'OpenLP Export Settings Files (*.conf)'))
|
||||
import_file_name = QtGui.QFileDialog.getOpenFileName(self, translate('OpenLP.MainWindow', 'Open File'), '',
|
||||
translate('OpenLP.MainWindow', 'OpenLP Export Settings Files (*.conf)'))
|
||||
if not import_file_name:
|
||||
return
|
||||
setting_sections = []
|
||||
@ -817,10 +840,17 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
||||
setting_sections.extend([self.headerSection])
|
||||
setting_sections.extend([u'crashreport'])
|
||||
# Add plugin sections.
|
||||
for plugin in self.pluginManager.plugins:
|
||||
for plugin in self.plugin_manager.plugins:
|
||||
setting_sections.extend([plugin.name])
|
||||
# Copy the settings file to the tmp dir, because we do not want to change the original one.
|
||||
temp_directory = os.path.join(unicode(gettempdir()), u'openlp')
|
||||
check_directory_exists(temp_directory)
|
||||
temp_config = os.path.join(temp_directory, os.path.basename(import_file_name))
|
||||
shutil.copyfile(import_file_name, temp_config)
|
||||
settings = Settings()
|
||||
import_settings = Settings(import_file_name, Settings.IniFormat)
|
||||
import_settings = Settings(temp_config, Settings.IniFormat)
|
||||
# Remove/rename old settings to prepare the import.
|
||||
import_settings.remove_obsolete_settings()
|
||||
# Lets do a basic sanity check. If it contains this string we can
|
||||
# assume it was created by OpenLP and so we'll load what we can
|
||||
# from it, and just silently ignore anything we don't recognise
|
||||
@ -880,7 +910,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
||||
return
|
||||
# Make sure it's a .conf file.
|
||||
if not export_file_name.endswith(u'conf'):
|
||||
export_file_name = export_file_name + u'.conf'
|
||||
export_file_name += u'.conf'
|
||||
temp_file = os.path.join(unicode(gettempdir(),
|
||||
get_filesystem_encoding()), u'openlp', u'exportConf.tmp')
|
||||
self.saveSettings()
|
||||
@ -894,7 +924,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
||||
setting_sections.extend([self.themesSettingsSection])
|
||||
setting_sections.extend([self.displayTagsSection])
|
||||
# Add plugin sections.
|
||||
for plugin in self.pluginManager.plugins:
|
||||
for plugin in self.plugin_manager.plugins:
|
||||
setting_sections.extend([plugin.name])
|
||||
# Delete old files if found.
|
||||
if os.path.exists(temp_file):
|
||||
@ -979,14 +1009,14 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
||||
renderer.
|
||||
"""
|
||||
log.debug(u'screenChanged')
|
||||
Receiver.send_message(u'cursor_busy')
|
||||
self.imageManager.updateDisplay()
|
||||
self.application.set_busy_cursor()
|
||||
self.imageManager.update_display()
|
||||
self.renderer.update_display()
|
||||
self.previewController.screenSizeChanged()
|
||||
self.liveController.screenSizeChanged()
|
||||
self.setFocus()
|
||||
self.activateWindow()
|
||||
Receiver.send_message(u'cursor_normal')
|
||||
self.application.set_normal_cursor()
|
||||
|
||||
def closeEvent(self, event):
|
||||
"""
|
||||
@ -994,7 +1024,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
||||
"""
|
||||
# The MainApplication did not even enter the event loop (this happens
|
||||
# when OpenLP is not fully loaded). Just ignore the event.
|
||||
if not self.application.eventLoopIsActive:
|
||||
if not self.application.is_event_loop_active:
|
||||
event.ignore()
|
||||
return
|
||||
# If we just did a settings import, close without saving changes.
|
||||
@ -1036,17 +1066,17 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
||||
``save_settings``
|
||||
Switch to prevent saving settings. Defaults to **True**.
|
||||
"""
|
||||
self.imageManager.stopManager = True
|
||||
while self.imageManager.imageThread.isRunning():
|
||||
self.imageManager.stop_manager = True
|
||||
while self.imageManager.image_thread.isRunning():
|
||||
time.sleep(0.1)
|
||||
# Clean temporary files used by services
|
||||
self.serviceManagerContents.cleanUp()
|
||||
self.serviceManagerContents.clean_up()
|
||||
if save_settings:
|
||||
if Settings().value(u'advanced/save current plugin'):
|
||||
Settings().setValue(u'advanced/current media plugin', self.mediaToolBox.currentIndex())
|
||||
# Call the cleanup method to shutdown plugins.
|
||||
log.info(u'cleanup plugins')
|
||||
self.pluginManager.finalise_plugins()
|
||||
self.plugin_manager.finalise_plugins()
|
||||
if save_settings:
|
||||
# Save settings
|
||||
self.saveSettings()
|
||||
@ -1100,18 +1130,33 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
||||
self.setWindowTitle(title)
|
||||
|
||||
def showStatusMessage(self, message):
|
||||
"""
|
||||
Show a message in the status bar
|
||||
"""
|
||||
self.statusBar.showMessage(message)
|
||||
|
||||
def defaultThemeChanged(self, theme):
|
||||
"""
|
||||
Update the default theme indicator in the status bar
|
||||
"""
|
||||
self.defaultThemeLabel.setText(translate('OpenLP.MainWindow', 'Default Theme: %s') % theme)
|
||||
|
||||
def toggleMediaManager(self):
|
||||
"""
|
||||
Toggle the visibility of the media manager
|
||||
"""
|
||||
self.mediaManagerDock.setVisible(not self.mediaManagerDock.isVisible())
|
||||
|
||||
def toggleServiceManager(self):
|
||||
"""
|
||||
Toggle the visibility of the service manager
|
||||
"""
|
||||
self.serviceManagerDock.setVisible(not self.serviceManagerDock.isVisible())
|
||||
|
||||
def toggleThemeManager(self):
|
||||
"""
|
||||
Toggle the visibility of the theme manager
|
||||
"""
|
||||
self.themeManagerDock.setVisible(not self.themeManagerDock.isVisible())
|
||||
|
||||
def setPreviewPanelVisibility(self, visible):
|
||||
@ -1184,7 +1229,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
||||
self.restoreState(settings.value(u'main window state'))
|
||||
self.liveController.splitter.restoreState(settings.value(u'live splitter geometry'))
|
||||
self.previewController.splitter.restoreState(settings.value(u'preview splitter geometry'))
|
||||
self.controlSplitter.restoreState(settings.value(u'mainwindow splitter geometry'))
|
||||
self.controlSplitter.restoreState(settings.value(u'main window splitter geometry'))
|
||||
settings.endGroup()
|
||||
|
||||
def saveSettings(self):
|
||||
@ -1205,7 +1250,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
||||
settings.setValue(u'main window geometry', self.saveGeometry())
|
||||
settings.setValue(u'live splitter geometry', self.liveController.splitter.saveState())
|
||||
settings.setValue(u'preview splitter geometry', self.previewController.splitter.saveState())
|
||||
settings.setValue(u'mainwindow splitter geometry', self.controlSplitter.saveState())
|
||||
settings.setValue(u'main window splitter geometry', self.controlSplitter.saveState())
|
||||
settings.endGroup()
|
||||
|
||||
def updateRecentFilesMenu(self):
|
||||
@ -1270,14 +1315,14 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
||||
self.loadProgressBar.show()
|
||||
self.loadProgressBar.setMaximum(size)
|
||||
self.loadProgressBar.setValue(0)
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
self.application.process_events()
|
||||
|
||||
def incrementProgressBar(self):
|
||||
"""
|
||||
Increase the Progress Bar value by 1
|
||||
"""
|
||||
self.loadProgressBar.setValue(self.loadProgressBar.value() + 1)
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
self.application.process_events()
|
||||
|
||||
def finishedProgressBar(self):
|
||||
"""
|
||||
@ -1292,35 +1337,43 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
||||
if event.timerId() == self.timer_id:
|
||||
self.timer_id = 0
|
||||
self.loadProgressBar.hide()
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
self.application.process_events()
|
||||
|
||||
def setNewDataPath(self, new_data_path):
|
||||
"""
|
||||
Set the new data path
|
||||
"""
|
||||
self.newDataPath = new_data_path
|
||||
|
||||
def setCopyData(self, copy_data):
|
||||
"""
|
||||
Set the flag to copy the data
|
||||
"""
|
||||
self.copyData = copy_data
|
||||
|
||||
def changeDataDirectory(self):
|
||||
log.info(u'Changing data path to %s' % self.newDataPath )
|
||||
"""
|
||||
Change the data directory.
|
||||
"""
|
||||
log.info(u'Changing data path to %s' % self.newDataPath)
|
||||
old_data_path = unicode(AppLocation.get_data_path())
|
||||
# Copy OpenLP data to new location if requested.
|
||||
self.application.set_busy_cursor()
|
||||
if self.copyData:
|
||||
log.info(u'Copying data to new path')
|
||||
try:
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
Receiver.send_message(u'cursor_busy')
|
||||
self.showStatusMessage(
|
||||
translate('OpenLP.MainWindow', 'Copying OpenLP data to new data directory location - %s '
|
||||
'- Please wait for copy to finish').replace('%s', self.newDataPath))
|
||||
dir_util.copy_tree(old_data_path, self.newDataPath)
|
||||
log.info(u'Copy sucessful')
|
||||
except (IOError, os.error, DistutilsFileError), why:
|
||||
Receiver.send_message(u'cursor_normal')
|
||||
self.application.set_normal_cursor()
|
||||
log.exception(u'Data copy failed %s' % unicode(why))
|
||||
QtGui.QMessageBox.critical(self, translate('OpenLP.MainWindow', 'New Data Directory Error'),
|
||||
translate('OpenLP.MainWindow',
|
||||
'OpenLP Data directory copy failed\n\n%s').replace('%s', unicode(why)),
|
||||
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok))
|
||||
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok))
|
||||
return False
|
||||
else:
|
||||
log.info(u'No data copy requested')
|
||||
@ -1330,4 +1383,14 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
||||
# Check if the new data path is our default.
|
||||
if self.newDataPath == AppLocation.get_directory(AppLocation.DataDir):
|
||||
settings.remove(u'advanced/data path')
|
||||
self.application.set_normal_cursor()
|
||||
|
||||
def _get_application(self):
|
||||
"""
|
||||
Adds the openlp to the class dynamically
|
||||
"""
|
||||
if not hasattr(self, u'_application'):
|
||||
self._application = Registry().get(u'application')
|
||||
return self._application
|
||||
|
||||
application = property(_get_application)
|
||||
|
@ -26,6 +26,9 @@
|
||||
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||
###############################################################################
|
||||
"""
|
||||
The :mod:`~openlp.core.ui.media` module contains classes and objects for media player integration.
|
||||
"""
|
||||
import logging
|
||||
|
||||
from openlp.core.lib import Settings
|
||||
@ -34,6 +37,7 @@ from PyQt4 import QtCore
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class MediaState(object):
|
||||
"""
|
||||
An enumeration for possible States of the Media Player
|
||||
@ -70,6 +74,7 @@ class MediaInfo(object):
|
||||
end_time = 0
|
||||
media_type = MediaType()
|
||||
|
||||
|
||||
def get_media_players():
|
||||
"""
|
||||
This method extracts the configured media players and overridden player
|
||||
@ -85,7 +90,7 @@ def get_media_players():
|
||||
overridden_player = u'auto'
|
||||
else:
|
||||
overridden_player = u''
|
||||
saved_players_list = saved_players.replace(u'[', u'').replace(u']',u'').split(u',')
|
||||
saved_players_list = saved_players.replace(u'[', u'').replace(u']', u'').split(u',')
|
||||
return saved_players_list, overridden_player
|
||||
|
||||
|
||||
@ -108,3 +113,5 @@ def set_media_players(players_list, overridden_player=u'auto'):
|
||||
|
||||
from mediacontroller import MediaController
|
||||
from playertab import PlayerTab
|
||||
|
||||
__all__ = [u'MediaController', u'PlayerTab']
|
||||
|
@ -26,13 +26,16 @@
|
||||
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||
###############################################################################
|
||||
|
||||
"""
|
||||
The :mod:`~openlp.core.ui.media.mediacontroller` module contains a base class for media components and other widgets
|
||||
related to playing media, such as sliders.
|
||||
"""
|
||||
import logging
|
||||
import os
|
||||
import datetime
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
from openlp.core.lib import OpenLPToolbar, Receiver, translate, Settings, Registry, UiStrings
|
||||
from openlp.core.lib import OpenLPToolbar, Receiver, Settings, Registry, UiStrings, translate
|
||||
from openlp.core.lib.ui import critical_error_message_box
|
||||
from openlp.core.ui.media import MediaState, MediaInfo, MediaType, get_media_players, set_media_players
|
||||
from openlp.core.ui.media.mediaplayer import MediaPlayer
|
||||
@ -41,11 +44,15 @@ from openlp.core.ui import DisplayControllerType
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class MediaSlider(QtGui.QSlider):
|
||||
"""
|
||||
Allows the mouse events of a slider to be overridden and extra functionality added
|
||||
"""
|
||||
def __init__(self, direction, manager, controller, parent=None):
|
||||
"""
|
||||
Constructor
|
||||
"""
|
||||
QtGui.QSlider.__init__(self, direction)
|
||||
self.manager = manager
|
||||
self.controller = controller
|
||||
@ -55,7 +62,7 @@ class MediaSlider(QtGui.QSlider):
|
||||
Override event to allow hover time to be displayed.
|
||||
"""
|
||||
timevalue = QtGui.QStyle.sliderValueFromPosition(self.minimum(), self.maximum(), event.x(), self.width())
|
||||
self.setToolTip(u'%s' % datetime.timedelta(seconds=int(timevalue/1000)))
|
||||
self.setToolTip(u'%s' % datetime.timedelta(seconds=int(timevalue / 1000)))
|
||||
QtGui.QSlider.mouseMoveEvent(self, event)
|
||||
|
||||
def mousePressEvent(self, event):
|
||||
@ -87,6 +94,9 @@ class MediaController(object):
|
||||
|
||||
"""
|
||||
def __init__(self, parent):
|
||||
"""
|
||||
Constructor
|
||||
"""
|
||||
self.mainWindow = parent
|
||||
Registry().register(u'media_controller', self)
|
||||
self.mediaPlayers = {}
|
||||
@ -96,7 +106,7 @@ class MediaController(object):
|
||||
self.timer = QtCore.QTimer()
|
||||
self.timer.setInterval(200)
|
||||
# Signals
|
||||
QtCore.QObject.connect(self.timer, QtCore.SIGNAL("timeout()"), self.media_state)
|
||||
self.timer.timeout.connect(self.media_state)
|
||||
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'playbackPlay'), self.media_play_msg)
|
||||
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'playbackPause'), self.media_pause_msg)
|
||||
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'playbackStop'), self.media_stop_msg)
|
||||
@ -298,7 +308,6 @@ class MediaController(object):
|
||||
QtCore.QObject.connect(controller.seekSlider, QtCore.SIGNAL(u'valueChanged(int)'), controller.sendToPlugins)
|
||||
QtCore.QObject.connect(controller.volumeSlider, QtCore.SIGNAL(u'valueChanged(int)'), controller.sendToPlugins)
|
||||
|
||||
|
||||
def setup_display(self, display, preview):
|
||||
"""
|
||||
After a new display is configured, all media related widget will be
|
||||
@ -428,7 +437,7 @@ class MediaController(object):
|
||||
``serviceItem``
|
||||
The ServiceItem containing the details to be played.
|
||||
"""
|
||||
controller = self.displayControllers[DisplayControllerType.Plugin]
|
||||
controller = self.displayControllers[DisplayControllerType.Plugin]
|
||||
log.debug(u'media_length')
|
||||
# stop running videos
|
||||
self.media_reset(controller)
|
||||
@ -500,8 +509,7 @@ class MediaController(object):
|
||||
First element is the controller which should be used
|
||||
"""
|
||||
log.debug(u'media_play_msg')
|
||||
self.media_play(msg[0],status)
|
||||
|
||||
self.media_play(msg[0], status)
|
||||
|
||||
def media_play(self, controller, status=True):
|
||||
"""
|
||||
@ -551,7 +559,7 @@ class MediaController(object):
|
||||
First element is the controller which should be used
|
||||
"""
|
||||
log.debug(u'media_pause_msg')
|
||||
self.media_pause( msg[0])
|
||||
self.media_pause(msg[0])
|
||||
|
||||
def media_pause(self, controller):
|
||||
"""
|
||||
@ -716,6 +724,9 @@ class MediaController(object):
|
||||
self.timer.start()
|
||||
|
||||
def finalise(self):
|
||||
"""
|
||||
Reset all the media controllers when OpenLP shuts down
|
||||
"""
|
||||
self.timer.stop()
|
||||
for controller in self.displayControllers:
|
||||
self.media_reset(self.displayControllers[controller])
|
||||
@ -739,4 +750,4 @@ class MediaController(object):
|
||||
self._service_manager = Registry().get(u'service_manager')
|
||||
return self._service_manager
|
||||
|
||||
service_manager = property(_get_service_manager)
|
||||
service_manager = property(_get_service_manager)
|
||||
|
@ -26,9 +26,13 @@
|
||||
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||
###############################################################################
|
||||
|
||||
"""
|
||||
The :mod:`~openlp.core.ui.media.mediaplayer` module contains the MediaPlayer class.
|
||||
"""
|
||||
from openlp.core.lib import Registry
|
||||
from openlp.core.ui.media import MediaState
|
||||
|
||||
|
||||
class MediaPlayer(object):
|
||||
"""
|
||||
This is the base class media Player class to provide OpenLP with a
|
||||
@ -36,6 +40,9 @@ class MediaPlayer(object):
|
||||
"""
|
||||
|
||||
def __init__(self, parent, name=u'media_player'):
|
||||
"""
|
||||
Constructor
|
||||
"""
|
||||
self.parent = parent
|
||||
self.name = name
|
||||
self.available = self.check_available()
|
||||
@ -143,3 +150,13 @@ class MediaPlayer(object):
|
||||
Returns Information about the player
|
||||
"""
|
||||
return u''
|
||||
|
||||
def _get_application(self):
|
||||
"""
|
||||
Adds the openlp to the class dynamically
|
||||
"""
|
||||
if not hasattr(self, u'_application'):
|
||||
self._application = Registry().get(u'application')
|
||||
return self._application
|
||||
|
||||
application = property(_get_application)
|
@ -26,7 +26,9 @@
|
||||
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||
###############################################################################
|
||||
|
||||
"""
|
||||
The :mod:`~openlp.core.ui.media.phononplayer` contains the Phonon player component.
|
||||
"""
|
||||
import logging
|
||||
import mimetypes
|
||||
from datetime import datetime
|
||||
@ -34,7 +36,7 @@ from datetime import datetime
|
||||
from PyQt4 import QtGui
|
||||
from PyQt4.phonon import Phonon
|
||||
|
||||
from openlp.core.lib import Receiver, translate, Settings
|
||||
from openlp.core.lib import Settings, translate
|
||||
|
||||
from openlp.core.ui.media import MediaState
|
||||
from openlp.core.ui.media.mediaplayer import MediaPlayer
|
||||
@ -56,24 +58,25 @@ ADDITIONAL_EXT = {
|
||||
u'video/x-matroska': [u'.mpv', u'.mkv'],
|
||||
u'video/x-wmv': [u'.wmv'],
|
||||
u'video/x-mpg': [u'.mpg'],
|
||||
u'video/mpeg' : [u'.mp4', u'.mts', u'.mov'],
|
||||
u'video/mpeg': [u'.mp4', u'.mts', u'.mov'],
|
||||
u'video/x-ms-wmv': [u'.wmv']}
|
||||
|
||||
VIDEO_CSS = u"""
|
||||
#videobackboard {
|
||||
z-index:3;
|
||||
background-color: %s;
|
||||
background-color: %(bgcolor)s;
|
||||
}
|
||||
#video1 {
|
||||
background-color: %s;
|
||||
background-color: %(bgcolor)s;
|
||||
z-index:4;
|
||||
}
|
||||
#video2 {
|
||||
background-color: %s;
|
||||
background-color: %(bgcolor)s;
|
||||
z-index:4;
|
||||
}
|
||||
"""
|
||||
|
||||
|
||||
class PhononPlayer(MediaPlayer):
|
||||
"""
|
||||
A specialised version of the MediaPlayer class, which provides a Phonon
|
||||
@ -81,6 +84,9 @@ class PhononPlayer(MediaPlayer):
|
||||
"""
|
||||
|
||||
def __init__(self, parent):
|
||||
"""
|
||||
Constructor
|
||||
"""
|
||||
MediaPlayer.__init__(self, parent, u'phonon')
|
||||
self.original_name = u'Phonon'
|
||||
self.display_name = u'&Phonon'
|
||||
@ -94,13 +100,16 @@ class PhononPlayer(MediaPlayer):
|
||||
elif mimetype.startswith(u'video/'):
|
||||
self._addToList(self.video_extensions_list, mimetype)
|
||||
|
||||
def _addToList(self, list, mimetype):
|
||||
def _addToList(self, mimetype_list, mimetype):
|
||||
"""
|
||||
Add mimetypes to the provided list
|
||||
"""
|
||||
# Add all extensions which mimetypes provides us for supported types.
|
||||
extensions = mimetypes.guess_all_extensions(unicode(mimetype))
|
||||
for extension in extensions:
|
||||
ext = u'*%s' % extension
|
||||
if ext not in list:
|
||||
list.append(ext)
|
||||
if ext not in mimetype_list:
|
||||
mimetype_list.append(ext)
|
||||
log.info(u'MediaPlugin: %s extensions: %s' % (mimetype, u' '.join(extensions)))
|
||||
# Add extensions for this mimetype from self.additional_extensions.
|
||||
# This hack clears mimetypes' and operating system's shortcomings
|
||||
@ -108,12 +117,15 @@ class PhononPlayer(MediaPlayer):
|
||||
if mimetype in self.additional_extensions.keys():
|
||||
for extension in self.additional_extensions[mimetype]:
|
||||
ext = u'*%s' % extension
|
||||
if ext not in list:
|
||||
list.append(ext)
|
||||
if ext not in mimetype_list:
|
||||
mimetype_list.append(ext)
|
||||
log.info(u'MediaPlugin: %s additional extensions: %s' %
|
||||
(mimetype, u' '.join(self.additional_extensions[mimetype])))
|
||||
|
||||
def setup(self, display):
|
||||
"""
|
||||
Set up the player widgets
|
||||
"""
|
||||
display.phononWidget = Phonon.VideoWidget(display)
|
||||
display.phononWidget.resize(display.size())
|
||||
display.mediaObject = Phonon.MediaObject(display)
|
||||
@ -126,9 +138,15 @@ class PhononPlayer(MediaPlayer):
|
||||
self.hasOwnWidget = True
|
||||
|
||||
def check_available(self):
|
||||
"""
|
||||
Check if the player is available
|
||||
"""
|
||||
return True
|
||||
|
||||
def load(self, display):
|
||||
"""
|
||||
Load a video into the display
|
||||
"""
|
||||
log.debug(u'load vid in Phonon Controller')
|
||||
controller = display.controller
|
||||
volume = controller.media_info.volume
|
||||
@ -150,15 +168,21 @@ class PhononPlayer(MediaPlayer):
|
||||
current_state = display.mediaObject.state()
|
||||
if current_state == Phonon.ErrorState:
|
||||
return False
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
self.application.process_events()
|
||||
if (datetime.now() - start).seconds > 5:
|
||||
return False
|
||||
return True
|
||||
|
||||
def resize(self, display):
|
||||
"""
|
||||
Resize the display
|
||||
"""
|
||||
display.phononWidget.resize(display.size())
|
||||
|
||||
def play(self, display):
|
||||
"""
|
||||
Play the current media item
|
||||
"""
|
||||
controller = display.controller
|
||||
start_time = 0
|
||||
if display.mediaObject.state() != Phonon.PausedState and \
|
||||
@ -177,25 +201,40 @@ class PhononPlayer(MediaPlayer):
|
||||
return True
|
||||
|
||||
def pause(self, display):
|
||||
"""
|
||||
Pause the current media item
|
||||
"""
|
||||
display.mediaObject.pause()
|
||||
if self.media_state_wait(display, Phonon.PausedState):
|
||||
self.state = MediaState.Paused
|
||||
|
||||
def stop(self, display):
|
||||
"""
|
||||
Stop the current media item
|
||||
"""
|
||||
display.mediaObject.stop()
|
||||
self.set_visible(display, False)
|
||||
self.state = MediaState.Stopped
|
||||
|
||||
def volume(self, display, vol):
|
||||
"""
|
||||
Set the volume
|
||||
"""
|
||||
# 1.0 is the highest value
|
||||
if display.hasAudio:
|
||||
vol = float(vol) / float(100)
|
||||
display.audio.setVolume(vol)
|
||||
|
||||
def seek(self, display, seekVal):
|
||||
"""
|
||||
Go to a particular point in the current media item
|
||||
"""
|
||||
display.mediaObject.seek(seekVal)
|
||||
|
||||
def reset(self, display):
|
||||
"""
|
||||
Reset the media player
|
||||
"""
|
||||
display.mediaObject.stop()
|
||||
display.mediaObject.clearQueue()
|
||||
self.set_visible(display, False)
|
||||
@ -203,10 +242,16 @@ class PhononPlayer(MediaPlayer):
|
||||
self.state = MediaState.Off
|
||||
|
||||
def set_visible(self, display, status):
|
||||
"""
|
||||
Set the visibility of the widget
|
||||
"""
|
||||
if self.hasOwnWidget:
|
||||
display.phononWidget.setVisible(status)
|
||||
|
||||
def update_ui(self, display):
|
||||
"""
|
||||
Update the UI
|
||||
"""
|
||||
if display.mediaObject.state() == Phonon.PausedState and self.state != MediaState.Paused:
|
||||
self.stop(display)
|
||||
controller = display.controller
|
||||
@ -224,9 +269,12 @@ class PhononPlayer(MediaPlayer):
|
||||
Add css style sheets to htmlbuilder
|
||||
"""
|
||||
background = QtGui.QColor(Settings().value(u'players/background color')).name()
|
||||
return VIDEO_CSS % (background,background,background)
|
||||
return VIDEO_CSS % {u'bgcolor': background}
|
||||
|
||||
def get_info(self):
|
||||
"""
|
||||
Return some info about this player
|
||||
"""
|
||||
return(translate('Media.player', 'Phonon is a media player which '
|
||||
'interacts with the operating system to provide media capabilities.') +
|
||||
u'<br/> <strong>' + translate('Media.player', 'Audio') +
|
||||
|
@ -26,18 +26,24 @@
|
||||
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||
###############################################################################
|
||||
|
||||
"""
|
||||
The :mod:`~openlp.core.ui.media.playertab` module holds the configuration tab for the media stuff.
|
||||
"""
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
from openlp.core.lib import SettingsTab, translate, Receiver, Settings, UiStrings
|
||||
from openlp.core.lib import SettingsTab, Receiver, Settings, UiStrings, translate
|
||||
from openlp.core.lib.ui import create_button
|
||||
from openlp.core.ui.media import get_media_players, set_media_players
|
||||
|
||||
|
||||
class MediaQCheckBox(QtGui.QCheckBox):
|
||||
"""
|
||||
MediaQCheckBox adds an extra property, playerName to the QCheckBox class.
|
||||
"""
|
||||
def setPlayerName(self, name):
|
||||
"""
|
||||
Set the player name
|
||||
"""
|
||||
self.playerName = name
|
||||
|
||||
|
||||
@ -45,16 +51,20 @@ class PlayerTab(SettingsTab):
|
||||
"""
|
||||
MediaTab is the Media settings tab in the settings dialog.
|
||||
"""
|
||||
def __init__(self, parent, mainWindow):
|
||||
self.parent = parent
|
||||
self.mainWindow = mainWindow
|
||||
self.mediaPlayers = mainWindow.mediaController.mediaPlayers
|
||||
def __init__(self, parent):
|
||||
"""
|
||||
Constructor
|
||||
"""
|
||||
self.mediaPlayers = self.media_controller.mediaPlayers
|
||||
self.savedUsedPlayers = None
|
||||
self.iconPath = u':/media/multimedia-player.png'
|
||||
player_translated = translate('OpenLP.PlayerTab', 'Players')
|
||||
SettingsTab.__init__(self, parent, u'Players', player_translated)
|
||||
|
||||
def setupUi(self):
|
||||
"""
|
||||
Set up the UI
|
||||
"""
|
||||
self.setObjectName(u'MediaTab')
|
||||
SettingsTab.setupUi(self)
|
||||
self.bgColorGroupBox = QtGui.QGroupBox(self.leftColumn)
|
||||
@ -116,6 +126,9 @@ class PlayerTab(SettingsTab):
|
||||
self.onbackgroundColorButtonClicked)
|
||||
|
||||
def retranslateUi(self):
|
||||
"""
|
||||
Translate the UI on the fly
|
||||
"""
|
||||
self.mediaPlayerGroupBox.setTitle(translate('OpenLP.PlayerTab', 'Available Media Players'))
|
||||
self.playerOrderGroupBox.setTitle(translate('OpenLP.PlayerTab', 'Player Search Order'))
|
||||
self.bgColorGroupBox.setTitle(UiStrings().BackgroundColor)
|
||||
@ -125,12 +138,18 @@ class PlayerTab(SettingsTab):
|
||||
self.retranslatePlayers()
|
||||
|
||||
def onbackgroundColorButtonClicked(self):
|
||||
"""
|
||||
Set the background color
|
||||
"""
|
||||
new_color = QtGui.QColorDialog.getColor(QtGui.QColor(self.bg_color), self)
|
||||
if new_color.isValid():
|
||||
self.bg_color = new_color.name()
|
||||
self.backgroundColorButton.setStyleSheet(u'background-color: %s' % self.bg_color)
|
||||
|
||||
def onPlayerCheckBoxChanged(self, check_state):
|
||||
"""
|
||||
Add or remove players depending on their status
|
||||
"""
|
||||
player = self.sender().playerName
|
||||
if check_state == QtCore.Qt.Checked:
|
||||
if player not in self.usedPlayers:
|
||||
@ -141,6 +160,9 @@ class PlayerTab(SettingsTab):
|
||||
self.updatePlayerList()
|
||||
|
||||
def updatePlayerList(self):
|
||||
"""
|
||||
Update the list of media players
|
||||
"""
|
||||
self.playerOrderlistWidget.clear()
|
||||
for player in self.usedPlayers:
|
||||
if player in self.playerCheckBoxes.keys():
|
||||
@ -152,6 +174,9 @@ class PlayerTab(SettingsTab):
|
||||
self.playerOrderlistWidget.addItem(self.mediaPlayers[unicode(player)].original_name)
|
||||
|
||||
def onUpButtonClicked(self):
|
||||
"""
|
||||
Move a media player up in the order
|
||||
"""
|
||||
row = self.playerOrderlistWidget.currentRow()
|
||||
if row <= 0:
|
||||
return
|
||||
@ -161,6 +186,9 @@ class PlayerTab(SettingsTab):
|
||||
self.usedPlayers.insert(row - 1, self.usedPlayers.pop(row))
|
||||
|
||||
def onDownButtonClicked(self):
|
||||
"""
|
||||
Move a media player down in the order
|
||||
"""
|
||||
row = self.playerOrderlistWidget.currentRow()
|
||||
if row == -1 or row > self.playerOrderlistWidget.count() - 1:
|
||||
return
|
||||
@ -170,6 +198,9 @@ class PlayerTab(SettingsTab):
|
||||
self.usedPlayers.insert(row + 1, self.usedPlayers.pop(row))
|
||||
|
||||
def load(self):
|
||||
"""
|
||||
Load the settings
|
||||
"""
|
||||
if self.savedUsedPlayers:
|
||||
self.usedPlayers = self.savedUsedPlayers
|
||||
self.usedPlayers = get_media_players()[0]
|
||||
@ -183,6 +214,9 @@ class PlayerTab(SettingsTab):
|
||||
self.backgroundColorButton.setStyleSheet(u'background-color: %s' % self.bg_color)
|
||||
|
||||
def save(self):
|
||||
"""
|
||||
Save the settings
|
||||
"""
|
||||
player_string_changed = False
|
||||
settings = Settings()
|
||||
settings.beginGroup(self.settingsSection)
|
||||
@ -194,7 +228,7 @@ class PlayerTab(SettingsTab):
|
||||
set_media_players(self.usedPlayers, override_player)
|
||||
player_string_changed = True
|
||||
if player_string_changed:
|
||||
self.parent.reset_supported_suffixes()
|
||||
self.service_manager.reset_supported_suffixes()
|
||||
Receiver.send_message(u'mediaitem_media_rebuild')
|
||||
Receiver.send_message(u'config_screen_changed')
|
||||
|
||||
@ -211,7 +245,7 @@ class PlayerTab(SettingsTab):
|
||||
checkbox.setToolTip(player.get_info())
|
||||
checkbox.setPlayerName(player.name)
|
||||
self.playerCheckBoxes[player.name] = checkbox
|
||||
QtCore.QObject.connect(checkbox,QtCore.SIGNAL(u'stateChanged(int)'), self.onPlayerCheckBoxChanged)
|
||||
QtCore.QObject.connect(checkbox, QtCore.SIGNAL(u'stateChanged(int)'), self.onPlayerCheckBoxChanged)
|
||||
self.mediaPlayerLayout.addWidget(checkbox)
|
||||
if player.available and player.name in self.usedPlayers:
|
||||
checkbox.setChecked(True)
|
||||
|
@ -26,7 +26,9 @@
|
||||
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||
###############################################################################
|
||||
|
||||
"""
|
||||
The :mod:`~openlp.core.ui.media.vlcplayer` module contains our VLC component wrapper
|
||||
"""
|
||||
from datetime import datetime
|
||||
from distutils.version import LooseVersion
|
||||
import logging
|
||||
@ -35,7 +37,7 @@ import sys
|
||||
|
||||
from PyQt4 import QtGui
|
||||
|
||||
from openlp.core.lib import Receiver, translate, Settings
|
||||
from openlp.core.lib import Settings, translate
|
||||
from openlp.core.ui.media import MediaState
|
||||
from openlp.core.ui.media.mediaplayer import MediaPlayer
|
||||
|
||||
@ -80,8 +82,8 @@ VIDEO_EXT = [
|
||||
u'*.nsc',
|
||||
u'*.nsv',
|
||||
u'*.nut',
|
||||
u'*.ra', u'*.ram', u'*.rm', u'*.rv' ,u'*.rmbv',
|
||||
u'*.a52', u'*.dts', u'*.aac', u'*.flac' ,u'*.dv', u'*.vid',
|
||||
u'*.ra', u'*.ram', u'*.rm', u'*.rv', u'*.rmbv',
|
||||
u'*.a52', u'*.dts', u'*.aac', u'*.flac', u'*.dv', u'*.vid',
|
||||
u'*.tta', u'*.tac',
|
||||
u'*.ty',
|
||||
u'*.dts',
|
||||
@ -99,6 +101,9 @@ class VlcPlayer(MediaPlayer):
|
||||
"""
|
||||
|
||||
def __init__(self, parent):
|
||||
"""
|
||||
Constructor
|
||||
"""
|
||||
MediaPlayer.__init__(self, parent, u'vlc')
|
||||
self.original_name = u'VLC'
|
||||
self.display_name = u'&VLC'
|
||||
@ -108,6 +113,9 @@ class VlcPlayer(MediaPlayer):
|
||||
self.video_extensions_list = VIDEO_EXT
|
||||
|
||||
def setup(self, display):
|
||||
"""
|
||||
Set up the media player
|
||||
"""
|
||||
display.vlcWidget = QtGui.QFrame(display)
|
||||
display.vlcWidget.setFrameStyle(QtGui.QFrame.NoFrame)
|
||||
# creating a basic vlc instance
|
||||
@ -141,9 +149,15 @@ class VlcPlayer(MediaPlayer):
|
||||
self.hasOwnWidget = True
|
||||
|
||||
def check_available(self):
|
||||
"""
|
||||
Return the availability of VLC
|
||||
"""
|
||||
return VLC_AVAILABLE
|
||||
|
||||
def load(self, display):
|
||||
"""
|
||||
Load a video into VLC
|
||||
"""
|
||||
log.debug(u'load vid in Vlc Controller')
|
||||
controller = display.controller
|
||||
volume = controller.media_info.volume
|
||||
@ -173,15 +187,21 @@ class VlcPlayer(MediaPlayer):
|
||||
while not mediaState == display.vlcMedia.get_state():
|
||||
if display.vlcMedia.get_state() == vlc.State.Error:
|
||||
return False
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
self.application.process_events()
|
||||
if (datetime.now() - start).seconds > 60:
|
||||
return False
|
||||
return True
|
||||
|
||||
def resize(self, display):
|
||||
"""
|
||||
Resize the player
|
||||
"""
|
||||
display.vlcWidget.resize(display.size())
|
||||
|
||||
def play(self, display):
|
||||
"""
|
||||
Play the current item
|
||||
"""
|
||||
controller = display.controller
|
||||
start_time = 0
|
||||
if self.state != MediaState.Paused and controller.media_info.start_time > 0:
|
||||
@ -199,6 +219,9 @@ class VlcPlayer(MediaPlayer):
|
||||
return True
|
||||
|
||||
def pause(self, display):
|
||||
"""
|
||||
Pause the current item
|
||||
"""
|
||||
if display.vlcMedia.get_state() != vlc.State.Playing:
|
||||
return
|
||||
display.vlcMediaPlayer.pause()
|
||||
@ -206,27 +229,45 @@ class VlcPlayer(MediaPlayer):
|
||||
self.state = MediaState.Paused
|
||||
|
||||
def stop(self, display):
|
||||
"""
|
||||
Stop the current item
|
||||
"""
|
||||
display.vlcMediaPlayer.stop()
|
||||
self.state = MediaState.Stopped
|
||||
|
||||
def volume(self, display, vol):
|
||||
"""
|
||||
Set the volume
|
||||
"""
|
||||
if display.hasAudio:
|
||||
display.vlcMediaPlayer.audio_set_volume(vol)
|
||||
|
||||
def seek(self, display, seekVal):
|
||||
"""
|
||||
Go to a particular position
|
||||
"""
|
||||
if display.vlcMediaPlayer.is_seekable():
|
||||
display.vlcMediaPlayer.set_time(seekVal)
|
||||
|
||||
def reset(self, display):
|
||||
"""
|
||||
Reset the player
|
||||
"""
|
||||
display.vlcMediaPlayer.stop()
|
||||
display.vlcWidget.setVisible(False)
|
||||
self.state = MediaState.Off
|
||||
|
||||
def set_visible(self, display, status):
|
||||
"""
|
||||
Set the visibility
|
||||
"""
|
||||
if self.hasOwnWidget:
|
||||
display.vlcWidget.setVisible(status)
|
||||
|
||||
def update_ui(self, display):
|
||||
"""
|
||||
Update the UI
|
||||
"""
|
||||
# Stop video if playback is finished.
|
||||
if display.vlcMedia.get_state() == vlc.State.Ended:
|
||||
self.stop(display)
|
||||
@ -241,6 +282,9 @@ class VlcPlayer(MediaPlayer):
|
||||
controller.seekSlider.blockSignals(False)
|
||||
|
||||
def get_info(self):
|
||||
"""
|
||||
Return some information about this player
|
||||
"""
|
||||
return(translate('Media.player', 'VLC is an external player which '
|
||||
'supports a number of different formats.') +
|
||||
u'<br/> <strong>' + translate('Media.player', 'Audio') +
|
||||
|
@ -26,12 +26,14 @@
|
||||
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||
###############################################################################
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
"""
|
||||
The :mod:`~openlp.core.ui.media.webkit` module contains our WebKit video player
|
||||
"""
|
||||
from PyQt4 import QtGui
|
||||
|
||||
import logging
|
||||
|
||||
from openlp.core.lib import translate, Settings
|
||||
from openlp.core.lib import Settings, translate
|
||||
from openlp.core.ui.media import MediaState
|
||||
from openlp.core.ui.media.mediaplayer import MediaPlayer
|
||||
|
||||
@ -40,14 +42,14 @@ log = logging.getLogger(__name__)
|
||||
VIDEO_CSS = u"""
|
||||
#videobackboard {
|
||||
z-index:3;
|
||||
background-color: %s;
|
||||
background-color: %(bgcolor)s;
|
||||
}
|
||||
#video1 {
|
||||
background-color: %s;
|
||||
background-color: %(bgcolor)s;
|
||||
z-index:4;
|
||||
}
|
||||
#video2 {
|
||||
background-color: %s;
|
||||
background-color: %(bgcolor)s;
|
||||
z-index:4;
|
||||
}
|
||||
"""
|
||||
@ -234,33 +236,33 @@ FLASH_HTML = u"""
|
||||
"""
|
||||
|
||||
VIDEO_EXT = [
|
||||
u'*.3gp'
|
||||
, u'*.3gpp'
|
||||
, u'*.3g2'
|
||||
, u'*.3gpp2'
|
||||
, u'*.aac'
|
||||
, u'*.flv'
|
||||
, u'*.f4a'
|
||||
, u'*.f4b'
|
||||
, u'*.f4p'
|
||||
, u'*.f4v'
|
||||
, u'*.mov'
|
||||
, u'*.m4a'
|
||||
, u'*.m4b'
|
||||
, u'*.m4p'
|
||||
, u'*.m4v'
|
||||
, u'*.mkv'
|
||||
, u'*.mp4'
|
||||
, u'*.ogv'
|
||||
, u'*.webm'
|
||||
, u'*.mpg', u'*.wmv', u'*.mpeg', u'*.avi'
|
||||
, u'*.swf'
|
||||
]
|
||||
u'*.3gp',
|
||||
u'*.3gpp',
|
||||
u'*.3g2',
|
||||
u'*.3gpp2',
|
||||
u'*.aac',
|
||||
u'*.flv',
|
||||
u'*.f4a',
|
||||
u'*.f4b',
|
||||
u'*.f4p',
|
||||
u'*.f4v',
|
||||
u'*.mov',
|
||||
u'*.m4a',
|
||||
u'*.m4b',
|
||||
u'*.m4p',
|
||||
u'*.m4v',
|
||||
u'*.mkv',
|
||||
u'*.mp4',
|
||||
u'*.ogv',
|
||||
u'*.webm',
|
||||
u'*.mpg', u'*.wmv', u'*.mpeg', u'*.avi',
|
||||
u'*.swf'
|
||||
]
|
||||
|
||||
AUDIO_EXT = [
|
||||
u'*.mp3'
|
||||
, u'*.ogg'
|
||||
]
|
||||
u'*.mp3',
|
||||
u'*.ogg'
|
||||
]
|
||||
|
||||
|
||||
class WebkitPlayer(MediaPlayer):
|
||||
@ -270,6 +272,9 @@ class WebkitPlayer(MediaPlayer):
|
||||
"""
|
||||
|
||||
def __init__(self, parent):
|
||||
"""
|
||||
Constructor
|
||||
"""
|
||||
MediaPlayer.__init__(self, parent, u'webkit')
|
||||
self.original_name = u'WebKit'
|
||||
self.display_name = u'&WebKit'
|
||||
@ -283,7 +288,7 @@ class WebkitPlayer(MediaPlayer):
|
||||
Add css style sheets to htmlbuilder
|
||||
"""
|
||||
background = QtGui.QColor(Settings().value(u'players/background color')).name()
|
||||
css = VIDEO_CSS % (background,background,background)
|
||||
css = VIDEO_CSS % {u'bgcolor': background}
|
||||
return css + FLASH_CSS
|
||||
|
||||
def get_media_display_javascript(self):
|
||||
@ -299,14 +304,23 @@ class WebkitPlayer(MediaPlayer):
|
||||
return VIDEO_HTML + FLASH_HTML
|
||||
|
||||
def setup(self, display):
|
||||
"""
|
||||
Set up the player
|
||||
"""
|
||||
display.webView.resize(display.size())
|
||||
display.webView.raise_()
|
||||
self.hasOwnWidget = False
|
||||
|
||||
def check_available(self):
|
||||
"""
|
||||
Check the availability of the media player
|
||||
"""
|
||||
return True
|
||||
|
||||
def load(self, display):
|
||||
"""
|
||||
Load a video
|
||||
"""
|
||||
log.debug(u'load vid in Webkit Controller')
|
||||
controller = display.controller
|
||||
if display.hasAudio and not controller.media_info.is_background:
|
||||
@ -329,9 +343,15 @@ class WebkitPlayer(MediaPlayer):
|
||||
return True
|
||||
|
||||
def resize(self, display):
|
||||
"""
|
||||
Resize the player
|
||||
"""
|
||||
display.webView.resize(display.size())
|
||||
|
||||
def play(self, display):
|
||||
"""
|
||||
Play a video
|
||||
"""
|
||||
controller = display.controller
|
||||
display.webLoaded = True
|
||||
length = 0
|
||||
@ -352,6 +372,9 @@ class WebkitPlayer(MediaPlayer):
|
||||
return True
|
||||
|
||||
def pause(self, display):
|
||||
"""
|
||||
Pause a video
|
||||
"""
|
||||
controller = display.controller
|
||||
if controller.media_info.is_flash:
|
||||
display.frame.evaluateJavaScript(u'show_flash("pause");')
|
||||
@ -360,6 +383,9 @@ class WebkitPlayer(MediaPlayer):
|
||||
self.state = MediaState.Paused
|
||||
|
||||
def stop(self, display):
|
||||
"""
|
||||
Stop a video
|
||||
"""
|
||||
controller = display.controller
|
||||
if controller.media_info.is_flash:
|
||||
display.frame.evaluateJavaScript(u'show_flash("stop");')
|
||||
@ -368,6 +394,9 @@ class WebkitPlayer(MediaPlayer):
|
||||
self.state = MediaState.Stopped
|
||||
|
||||
def volume(self, display, vol):
|
||||
"""
|
||||
Set the volume
|
||||
"""
|
||||
controller = display.controller
|
||||
# 1.0 is the highest value
|
||||
if display.hasAudio:
|
||||
@ -376,6 +405,9 @@ class WebkitPlayer(MediaPlayer):
|
||||
display.frame.evaluateJavaScript(u'show_video(null, null, %s);' % str(vol))
|
||||
|
||||
def seek(self, display, seekVal):
|
||||
"""
|
||||
Go to a position in the video
|
||||
"""
|
||||
controller = display.controller
|
||||
if controller.media_info.is_flash:
|
||||
seek = seekVal
|
||||
@ -385,6 +417,9 @@ class WebkitPlayer(MediaPlayer):
|
||||
display.frame.evaluateJavaScript(u'show_video("seek", null, null, null, "%f");' % (seek))
|
||||
|
||||
def reset(self, display):
|
||||
"""
|
||||
Reset the player
|
||||
"""
|
||||
controller = display.controller
|
||||
if controller.media_info.is_flash:
|
||||
display.frame.evaluateJavaScript(u'show_flash("close");')
|
||||
@ -393,6 +428,9 @@ class WebkitPlayer(MediaPlayer):
|
||||
self.state = MediaState.Off
|
||||
|
||||
def set_visible(self, display, status):
|
||||
"""
|
||||
Set the visibility
|
||||
"""
|
||||
controller = display.controller
|
||||
if status:
|
||||
is_visible = "visible"
|
||||
@ -404,6 +442,9 @@ class WebkitPlayer(MediaPlayer):
|
||||
display.frame.evaluateJavaScript(u'show_video("setVisible", null, null, null, "%s");' % (is_visible))
|
||||
|
||||
def update_ui(self, display):
|
||||
"""
|
||||
Update the UI
|
||||
"""
|
||||
controller = display.controller
|
||||
if controller.media_info.is_flash:
|
||||
currentTime = display.frame.evaluateJavaScript(u'show_flash("currentTime");')
|
||||
@ -428,6 +469,9 @@ class WebkitPlayer(MediaPlayer):
|
||||
controller.seekSlider.blockSignals(False)
|
||||
|
||||
def get_info(self):
|
||||
"""
|
||||
Return some information about this player
|
||||
"""
|
||||
return(translate('Media.player', 'Webkit is a media player which runs '
|
||||
'inside a web browser. This player allows text over video to be '
|
||||
'rendered.') +
|
||||
|
@ -26,13 +26,16 @@
|
||||
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||
###############################################################################
|
||||
|
||||
"""
|
||||
The media manager dock.
|
||||
"""
|
||||
import logging
|
||||
|
||||
from openlp.core.lib import StringContent
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class MediaDockManager(object):
|
||||
"""
|
||||
Provide a repository for MediaManagerItems
|
||||
|
@ -26,15 +26,23 @@
|
||||
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||
###############################################################################
|
||||
|
||||
"""
|
||||
The UI widgets of the plugin view dialog
|
||||
#"""
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
from openlp.core.lib import translate, UiStrings
|
||||
from openlp.core.lib import UiStrings, translate
|
||||
from openlp.core.lib.ui import create_button_box
|
||||
|
||||
|
||||
class Ui_PluginViewDialog(object):
|
||||
"""
|
||||
The UI of the plugin view dialog
|
||||
"""
|
||||
def setupUi(self, pluginViewDialog):
|
||||
"""
|
||||
Set up the UI
|
||||
"""
|
||||
pluginViewDialog.setObjectName(u'pluginViewDialog')
|
||||
pluginViewDialog.setWindowModality(QtCore.Qt.ApplicationModal)
|
||||
self.pluginLayout = QtGui.QVBoxLayout(pluginViewDialog)
|
||||
@ -72,6 +80,9 @@ class Ui_PluginViewDialog(object):
|
||||
self.retranslateUi(pluginViewDialog)
|
||||
|
||||
def retranslateUi(self, pluginViewDialog):
|
||||
"""
|
||||
Translate the UI on the fly
|
||||
"""
|
||||
pluginViewDialog.setWindowTitle(translate('OpenLP.PluginForm', 'Plugin List'))
|
||||
self.pluginInfoGroupBox.setTitle(translate('OpenLP.PluginForm', 'Plugin Details'))
|
||||
self.versionLabel.setText(u'%s:' % UiStrings().Version)
|
||||
|
@ -26,21 +26,27 @@
|
||||
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||
###############################################################################
|
||||
|
||||
"""
|
||||
The actual plugin view form
|
||||
"""
|
||||
import logging
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
from openlp.core.lib import PluginStatus, Receiver, translate
|
||||
from openlp.core.lib import PluginStatus, Registry, translate
|
||||
from plugindialog import Ui_PluginViewDialog
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class PluginForm(QtGui.QDialog, Ui_PluginViewDialog):
|
||||
"""
|
||||
The plugin form provides user control over the plugins OpenLP uses.
|
||||
"""
|
||||
def __init__(self, parent=None):
|
||||
"""
|
||||
Constructor
|
||||
"""
|
||||
QtGui.QDialog.__init__(self, parent)
|
||||
self.activePlugin = None
|
||||
self.programaticChange = False
|
||||
@ -62,7 +68,7 @@ class PluginForm(QtGui.QDialog, Ui_PluginViewDialog):
|
||||
self._clearDetails()
|
||||
self.programaticChange = True
|
||||
pluginListWidth = 0
|
||||
for plugin in self.parent().pluginManager.plugins:
|
||||
for plugin in self.plugin_manager.plugins:
|
||||
item = QtGui.QListWidgetItem(self.pluginListWidget)
|
||||
# We do this just to make 100% sure the status is an integer as
|
||||
# sometimes when it's loaded from the config, it isn't cast to int.
|
||||
@ -85,12 +91,18 @@ class PluginForm(QtGui.QDialog, Ui_PluginViewDialog):
|
||||
self.pluginListWidget.setFixedWidth(pluginListWidth + self.pluginListWidget.iconSize().width() + 48)
|
||||
|
||||
def _clearDetails(self):
|
||||
"""
|
||||
Clear the plugin details widgets
|
||||
"""
|
||||
self.statusComboBox.setCurrentIndex(-1)
|
||||
self.versionNumberLabel.setText(u'')
|
||||
self.aboutTextBrowser.setHtml(u'')
|
||||
self.statusComboBox.setEnabled(False)
|
||||
|
||||
def _setDetails(self):
|
||||
"""
|
||||
Set the details of the currently selected plugin
|
||||
"""
|
||||
log.debug(u'PluginStatus: %s', str(self.activePlugin.status))
|
||||
self.versionNumberLabel.setText(self.activePlugin.version)
|
||||
self.aboutTextBrowser.setHtml(self.activePlugin.about())
|
||||
@ -103,13 +115,15 @@ class PluginForm(QtGui.QDialog, Ui_PluginViewDialog):
|
||||
self.programaticChange = False
|
||||
|
||||
def onPluginListWidgetSelectionChanged(self):
|
||||
"""
|
||||
If the selected plugin changes, update the form
|
||||
"""
|
||||
if self.pluginListWidget.currentItem() is None:
|
||||
self._clearDetails()
|
||||
return
|
||||
plugin_name_singular = \
|
||||
self.pluginListWidget.currentItem().text().split(u'(')[0][:-1]
|
||||
plugin_name_singular = self.pluginListWidget.currentItem().text().split(u'(')[0][:-1]
|
||||
self.activePlugin = None
|
||||
for plugin in self.parent().pluginManager.plugins:
|
||||
for plugin in self.plugin_manager.plugins:
|
||||
if plugin.status != PluginStatus.Disabled:
|
||||
if plugin.nameStrings[u'singular'] == plugin_name_singular:
|
||||
self.activePlugin = plugin
|
||||
@ -120,13 +134,16 @@ class PluginForm(QtGui.QDialog, Ui_PluginViewDialog):
|
||||
self._clearDetails()
|
||||
|
||||
def onStatusComboBoxChanged(self, status):
|
||||
"""
|
||||
If the status of a plugin is altered, apply the change
|
||||
"""
|
||||
if self.programaticChange or status == PluginStatus.Disabled:
|
||||
return
|
||||
if status == PluginStatus.Inactive:
|
||||
Receiver.send_message(u'cursor_busy')
|
||||
self.application.set_busy_cursor()
|
||||
self.activePlugin.toggleStatus(PluginStatus.Active)
|
||||
Receiver.send_message(u'cursor_normal')
|
||||
self.activePlugin.appStartup()
|
||||
self.application.set_normal_cursor()
|
||||
self.activePlugin.app_startup()
|
||||
else:
|
||||
self.activePlugin.toggleStatus(PluginStatus.Inactive)
|
||||
status_text = translate('OpenLP.PluginForm', '%s (Inactive)')
|
||||
@ -138,3 +155,23 @@ class PluginForm(QtGui.QDialog, Ui_PluginViewDialog):
|
||||
status_text = translate('OpenLP.PluginForm', '%s (Disabled)')
|
||||
self.pluginListWidget.currentItem().setText(
|
||||
status_text % self.activePlugin.nameStrings[u'singular'])
|
||||
|
||||
def _get_plugin_manager(self):
|
||||
"""
|
||||
Adds the plugin manager to the class dynamically
|
||||
"""
|
||||
if not hasattr(self, u'_plugin_manager'):
|
||||
self._plugin_manager = Registry().get(u'plugin_manager')
|
||||
return self._plugin_manager
|
||||
|
||||
plugin_manager = property(_get_plugin_manager)
|
||||
|
||||
def _get_application(self):
|
||||
"""
|
||||
Adds the openlp to the class dynamically
|
||||
"""
|
||||
if not hasattr(self, u'_application'):
|
||||
self._application = Registry().get(u'application')
|
||||
return self._application
|
||||
|
||||
application = property(_get_application)
|
||||
|
@ -26,10 +26,13 @@
|
||||
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||
###############################################################################
|
||||
|
||||
"""
|
||||
The UI widgets of the print service dialog.
|
||||
"""
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
from openlp.core.lib import build_icon, translate, SpellTextEdit, UiStrings
|
||||
from openlp.core.lib import SpellTextEdit, UiStrings, build_icon, translate
|
||||
|
||||
|
||||
class ZoomSize(object):
|
||||
"""
|
||||
@ -44,7 +47,13 @@ class ZoomSize(object):
|
||||
|
||||
|
||||
class Ui_PrintServiceDialog(object):
|
||||
"""
|
||||
The UI of the print service dialog
|
||||
"""
|
||||
def setupUi(self, printServiceDialog):
|
||||
"""
|
||||
Set up the UI
|
||||
"""
|
||||
printServiceDialog.setObjectName(u'printServiceDialog')
|
||||
printServiceDialog.resize(664, 594)
|
||||
self.mainLayout = QtGui.QVBoxLayout(printServiceDialog)
|
||||
@ -121,9 +130,12 @@ class Ui_PrintServiceDialog(object):
|
||||
self.optionsLayout.addWidget(self.optionsGroupBox)
|
||||
|
||||
self.retranslateUi(printServiceDialog)
|
||||
QtCore.QObject.connect(self.optionsButton,QtCore.SIGNAL(u'toggled(bool)'), self.toggleOptions)
|
||||
QtCore.QObject.connect(self.optionsButton, QtCore.SIGNAL(u'toggled(bool)'), self.toggleOptions)
|
||||
|
||||
def retranslateUi(self, printServiceDialog):
|
||||
"""
|
||||
Translate the UI on the fly
|
||||
"""
|
||||
printServiceDialog.setWindowTitle(UiStrings().PrintService)
|
||||
self.zoomOutButton.setToolTip(translate('OpenLP.PrintServiceForm', 'Zoom Out'))
|
||||
self.zoomOriginalButton.setToolTip(translate('OpenLP.PrintServiceForm', 'Zoom Original'))
|
||||
@ -131,7 +143,7 @@ class Ui_PrintServiceDialog(object):
|
||||
self.optionsButton.setText(translate('OpenLP.PrintServiceForm', 'Options'))
|
||||
self.titleLabel.setText(translate('OpenLP.PrintServiceForm', 'Title:'))
|
||||
self.footerLabel.setText(translate('OpenLP.PrintServiceForm', 'Custom Footer Text:'))
|
||||
self.optionsGroupBox.setTitle(translate('OpenLP.PrintServiceForm','Other Options'))
|
||||
self.optionsGroupBox.setTitle(translate('OpenLP.PrintServiceForm', 'Other Options'))
|
||||
self.slideTextCheckBox.setText(translate('OpenLP.PrintServiceForm', 'Include slide text if available'))
|
||||
self.pageBreakAfterText.setText(translate('OpenLP.PrintServiceForm', 'Add page break before each text item'))
|
||||
self.notesCheckBox.setText(translate('OpenLP.PrintServiceForm', 'Include service item notes'))
|
||||
@ -144,6 +156,5 @@ class Ui_PrintServiceDialog(object):
|
||||
u'100%',
|
||||
u'75%',
|
||||
u'50%',
|
||||
u'25%']
|
||||
)
|
||||
|
||||
u'25%'
|
||||
])
|
||||
|
@ -26,6 +26,9 @@
|
||||
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||
###############################################################################
|
||||
"""
|
||||
The actual print service dialog
|
||||
"""
|
||||
import cgi
|
||||
import datetime
|
||||
import os
|
||||
@ -33,7 +36,7 @@ import os
|
||||
from PyQt4 import QtCore, QtGui
|
||||
from lxml import html
|
||||
|
||||
from openlp.core.lib import translate, get_text_file_string, Receiver, Settings, UiStrings, Registry
|
||||
from openlp.core.lib import Receiver, Settings, UiStrings, Registry, translate, get_text_file_string
|
||||
from openlp.core.ui.printservicedialog import Ui_PrintServiceDialog, ZoomSize
|
||||
from openlp.core.utils import AppLocation
|
||||
|
||||
@ -106,8 +109,11 @@ http://doc.trolltech.com/4.7/richtext-html-subset.html#css-properties
|
||||
}
|
||||
"""
|
||||
|
||||
class PrintServiceForm(QtGui.QDialog, Ui_PrintServiceDialog):
|
||||
|
||||
class PrintServiceForm(QtGui.QDialog, Ui_PrintServiceDialog):
|
||||
"""
|
||||
The :class:`~openlp.core.ui.printserviceform.PrintServiceForm` class displays a dialog for printing the service.
|
||||
"""
|
||||
def __init__(self):
|
||||
"""
|
||||
Constructor
|
||||
@ -143,6 +149,9 @@ class PrintServiceForm(QtGui.QDialog, Ui_PrintServiceDialog):
|
||||
self.updatePreviewText()
|
||||
|
||||
def toggleOptions(self, checked):
|
||||
"""
|
||||
Toggle various options
|
||||
"""
|
||||
self.optionsWidget.setVisible(checked)
|
||||
if checked:
|
||||
left = self.optionsButton.pos().x()
|
||||
@ -169,7 +178,7 @@ class PrintServiceForm(QtGui.QDialog, Ui_PrintServiceDialog):
|
||||
self._addElement(u'body', parent=html_data)
|
||||
self._addElement(u'h1', cgi.escape(self.titleLineEdit.text()),
|
||||
html_data.body, classId=u'serviceTitle')
|
||||
for index, item in enumerate(self.service_manager.serviceItems):
|
||||
for index, item in enumerate(self.service_manager.service_items):
|
||||
self._addPreviewItem(html_data.body, item[u'service_item'], index)
|
||||
# Add the custom service notes:
|
||||
if self.footerTextEdit.toPlainText():
|
||||
@ -181,6 +190,9 @@ class PrintServiceForm(QtGui.QDialog, Ui_PrintServiceDialog):
|
||||
self.previewWidget.updatePreview()
|
||||
|
||||
def _addPreviewItem(self, body, item, index):
|
||||
"""
|
||||
Add a preview item
|
||||
"""
|
||||
div = self._addElement(u'div', classId=u'item', parent=body)
|
||||
# Add the title of the service item.
|
||||
item_title = self._addElement(u'h2', parent=div, classId=u'itemTitle')
|
||||
@ -388,6 +400,9 @@ class PrintServiceForm(QtGui.QDialog, Ui_PrintServiceDialog):
|
||||
settings.endGroup()
|
||||
|
||||
def update_song_usage(self):
|
||||
"""
|
||||
Update the song usage
|
||||
"""
|
||||
# Only continue when we include the song's text.
|
||||
if not self.slideTextCheckBox.isChecked():
|
||||
return
|
||||
@ -413,4 +428,4 @@ class PrintServiceForm(QtGui.QDialog, Ui_PrintServiceDialog):
|
||||
self._main_window = Registry().get(u'main_window')
|
||||
return self._main_window
|
||||
|
||||
main_window = property(_get_main_window)
|
||||
main_window = property(_get_main_window)
|
||||
|
@ -26,14 +26,23 @@
|
||||
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||
###############################################################################
|
||||
|
||||
"""
|
||||
The UI widgets for the service item edit dialog
|
||||
"""
|
||||
from PyQt4 import QtGui
|
||||
|
||||
from openlp.core.lib import translate
|
||||
from openlp.core.lib.ui import create_button_box, create_button
|
||||
|
||||
|
||||
class Ui_ServiceItemEditDialog(object):
|
||||
"""
|
||||
The UI widgets for the service item edit dialog
|
||||
"""
|
||||
def setupUi(self, serviceItemEditDialog):
|
||||
"""
|
||||
Set up the UI
|
||||
"""
|
||||
serviceItemEditDialog.setObjectName(u'serviceItemEditDialog')
|
||||
self.dialog_layout = QtGui.QGridLayout(serviceItemEditDialog)
|
||||
self.dialog_layout.setContentsMargins(8, 8, 8, 8)
|
||||
@ -61,4 +70,7 @@ class Ui_ServiceItemEditDialog(object):
|
||||
self.retranslateUi(serviceItemEditDialog)
|
||||
|
||||
def retranslateUi(self, serviceItemEditDialog):
|
||||
"""
|
||||
Translate the UI on the fly
|
||||
"""
|
||||
serviceItemEditDialog.setWindowTitle(translate('OpenLP.ServiceItemEditForm', 'Reorder Service Item'))
|
||||
|
@ -26,12 +26,15 @@
|
||||
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||
###############################################################################
|
||||
|
||||
"""
|
||||
The service item edit dialog
|
||||
"""
|
||||
from PyQt4 import QtCore, QtGui
|
||||
from openlp.core.lib import Registry
|
||||
|
||||
from serviceitemeditdialog import Ui_ServiceItemEditDialog
|
||||
|
||||
|
||||
class ServiceItemEditForm(QtGui.QDialog, Ui_ServiceItemEditDialog):
|
||||
"""
|
||||
This is the form that is used to edit the verses of the song.
|
||||
@ -47,6 +50,9 @@ class ServiceItemEditForm(QtGui.QDialog, Ui_ServiceItemEditDialog):
|
||||
self.on_current_row_changed)
|
||||
|
||||
def set_service_item(self, item):
|
||||
"""
|
||||
Set the service item to be edited.
|
||||
"""
|
||||
self.item = item
|
||||
self.item_list = []
|
||||
if self.item.is_image():
|
||||
@ -57,6 +63,9 @@ class ServiceItemEditForm(QtGui.QDialog, Ui_ServiceItemEditDialog):
|
||||
self.list_widget.setCurrentItem(self.list_widget.currentItem())
|
||||
|
||||
def get_service_item(self):
|
||||
"""
|
||||
Get the modified service item.
|
||||
"""
|
||||
if self.data:
|
||||
self.item._raw_frames = []
|
||||
if self.item.is_image():
|
||||
|
@ -26,6 +26,9 @@
|
||||
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||
###############################################################################
|
||||
"""
|
||||
The service manager sets up, loads, saves and manages services.
|
||||
"""
|
||||
import cgi
|
||||
import cPickle
|
||||
import logging
|
||||
@ -39,8 +42,8 @@ log = logging.getLogger(__name__)
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
from openlp.core.lib import OpenLPToolbar, ServiceItem, Receiver, build_icon, ItemCapabilities, SettingsManager, \
|
||||
translate, str_to_bool, check_directory_exists, Settings, PluginStatus, Registry, UiStrings
|
||||
from openlp.core.lib import OpenLPToolbar, ServiceItem, Receiver, ItemCapabilities, Settings, PluginStatus, Registry, \
|
||||
UiStrings, build_icon, translate, str_to_bool, check_directory_exists
|
||||
from openlp.core.lib.theme import ThemeLevel
|
||||
from openlp.core.lib.ui import critical_error_message_box, create_widget_action, find_and_set_in_combo_box
|
||||
from openlp.core.ui import ServiceNoteForm, ServiceItemEditForm, StartTimeForm
|
||||
@ -48,11 +51,15 @@ from openlp.core.ui.printserviceform import PrintServiceForm
|
||||
from openlp.core.utils import AppLocation, delete_file, split_filename, format_time
|
||||
from openlp.core.utils.actions import ActionList, CategoryOrder
|
||||
|
||||
|
||||
class ServiceManagerList(QtGui.QTreeWidget):
|
||||
"""
|
||||
Set up key bindings and mouse behaviour for the service list
|
||||
"""
|
||||
def __init__(self, serviceManager, parent=None):
|
||||
"""
|
||||
Constructor
|
||||
"""
|
||||
QtGui.QTreeWidget.__init__(self, parent)
|
||||
self.serviceManager = serviceManager
|
||||
|
||||
@ -93,16 +100,22 @@ class ServiceManagerList(QtGui.QTreeWidget):
|
||||
mime_data.setText(u'ServiceManager')
|
||||
drag.start(QtCore.Qt.CopyAction)
|
||||
|
||||
|
||||
class ServiceManagerDialog(object):
|
||||
"""
|
||||
UI part of the Service Manager
|
||||
"""
|
||||
def setup_ui(self,widget):
|
||||
def setup_ui(self, widget):
|
||||
"""
|
||||
Define the UI
|
||||
"""
|
||||
# Create the top toolbar
|
||||
self.toolbar = OpenLPToolbar(self)
|
||||
self.toolbar.addToolbarAction(u'newService', text=UiStrings().NewService, icon=u':/general/general_new.png',
|
||||
tooltip=UiStrings().CreateService, triggers=self.on_new_service_clicked)
|
||||
self.toolbar.addToolbarAction(u'openService', text=UiStrings().OpenService, icon=u':/general/general_open.png',
|
||||
tooltip=translate('OpenLP.ServiceManager', 'Load an existing service.'), triggers=self.on_load_service_clicked)
|
||||
tooltip=translate('OpenLP.ServiceManager', 'Load an existing service.'),
|
||||
triggers=self.on_load_service_clicked)
|
||||
self.toolbar.addToolbarAction(u'saveService', text=UiStrings().SaveService, icon=u':/general/general_save.png',
|
||||
tooltip=translate('OpenLP.ServiceManager', 'Save this service.'), triggers=self.decide_save_method)
|
||||
self.toolbar.addSeparator()
|
||||
@ -185,7 +198,8 @@ class ServiceManagerDialog(object):
|
||||
self.service_manager_list.make_live = self.order_toolbar.addToolbarAction(u'make_live',
|
||||
text=translate('OpenLP.ServiceManager', 'Go Live'), icon=u':/general/general_live.png',
|
||||
tooltip=translate('OpenLP.ServiceManager', 'Send the selected item to Live.'),
|
||||
shortcuts=[QtCore.Qt.Key_Enter, QtCore.Qt.Key_Return], category=UiStrings().Service, triggers=self.make_live)
|
||||
shortcuts=[QtCore.Qt.Key_Enter, QtCore.Qt.Key_Return], category=UiStrings().Service,
|
||||
triggers=self.make_live)
|
||||
self.layout.addWidget(self.order_toolbar)
|
||||
# Connect up our signals and slots
|
||||
QtCore.QObject.connect(self.theme_combo_box, QtCore.SIGNAL(u'activated(int)'),
|
||||
@ -197,17 +211,10 @@ class ServiceManagerDialog(object):
|
||||
QtCore.QObject.connect(self.service_manager_list, QtCore.SIGNAL(u'itemExpanded(QTreeWidgetItem*)'),
|
||||
self.expanded)
|
||||
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'theme_update_list'), self.update_theme_list)
|
||||
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'servicemanager_preview_live'),
|
||||
self.preview_live)
|
||||
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'servicemanager_next_item'), self.next_item)
|
||||
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'servicemanager_previous_item'),
|
||||
self.previous_item)
|
||||
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'servicemanager_set_item'), self.on_set_item)
|
||||
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'config_updated'), self.config_updated)
|
||||
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'config_screen_changed'),
|
||||
self.regenerate_service_Items)
|
||||
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'theme_update_global'), self.themeChange)
|
||||
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'service_item_update'), self.serviceItemUpdate)
|
||||
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'theme_update_global'), self.theme_change)
|
||||
# Last little bits of setting up
|
||||
self.service_theme = Settings().value(self.main_window.serviceManagerSettingsSection + u'/service theme')
|
||||
self.servicePath = AppLocation.get_section_data_path(u'servicemanager')
|
||||
@ -402,10 +409,12 @@ class ServiceManager(QtGui.QWidget, ServiceManagerDialog):
|
||||
elif result == QtGui.QMessageBox.Save:
|
||||
self.decide_save_method()
|
||||
if not load_file:
|
||||
file_name = QtGui.QFileDialog.getOpenfile_name(self.main_window,
|
||||
file_name = QtGui.QFileDialog.getOpenFileName(
|
||||
self.main_window,
|
||||
translate('OpenLP.ServiceManager', 'Open File'),
|
||||
SettingsManager.get_last_dir(self.main_window.serviceManagerSettingsSection),
|
||||
translate('OpenLP.ServiceManager', 'OpenLP Service Files (*.osz *.oszl)'))
|
||||
Settings().value(self.main_window.serviceManagerSettingsSection + u'/last directory'),
|
||||
translate('OpenLP.ServiceManager', 'OpenLP Service Files (*.osz *.oszl)')
|
||||
)
|
||||
if not file_name:
|
||||
return False
|
||||
else:
|
||||
@ -441,7 +450,7 @@ class ServiceManager(QtGui.QWidget, ServiceManagerDialog):
|
||||
self.service_id += 1
|
||||
self.set_modified(False)
|
||||
Settings().setValue(u'servicemanager/last file', u'')
|
||||
Receiver.send_message(u'servicemanager_new_service')
|
||||
self.plugin_manager.new_service_created()
|
||||
|
||||
def save_file(self):
|
||||
"""
|
||||
@ -469,7 +478,7 @@ class ServiceManager(QtGui.QWidget, ServiceManagerDialog):
|
||||
missing_list = []
|
||||
audio_files = []
|
||||
total_size = 0
|
||||
Receiver.send_message(u'cursor_busy')
|
||||
self.application.set_busy_cursor()
|
||||
# Number of items + 1 to zip it
|
||||
self.main_window.displayProgressBar(len(self.service_items) + 1)
|
||||
# Get list of missing files, and list of files to write
|
||||
@ -485,7 +494,7 @@ class ServiceManager(QtGui.QWidget, ServiceManagerDialog):
|
||||
else:
|
||||
write_list.append(path_from)
|
||||
if missing_list:
|
||||
Receiver.send_message(u'cursor_normal')
|
||||
self.application.set_normal_cursor()
|
||||
title = translate('OpenLP.ServiceManager', 'Service File(s) Missing')
|
||||
message = translate('OpenLP.ServiceManager',
|
||||
'The following file(s) in the service are missing:\n\t%s\n\n'
|
||||
@ -495,7 +504,6 @@ class ServiceManager(QtGui.QWidget, ServiceManagerDialog):
|
||||
if answer == QtGui.QMessageBox.Cancel:
|
||||
self.main_window.finishedProgressBar()
|
||||
return False
|
||||
Receiver.send_message(u'cursor_busy')
|
||||
# Check if item contains a missing file.
|
||||
for item in list(self.service_items):
|
||||
self.main_window.incrementProgressBar()
|
||||
@ -556,11 +564,11 @@ class ServiceManager(QtGui.QWidget, ServiceManagerDialog):
|
||||
if zip_file:
|
||||
zip_file.close()
|
||||
self.main_window.finishedProgressBar()
|
||||
Receiver.send_message(u'cursor_normal')
|
||||
self.application.set_normal_cursor()
|
||||
if success:
|
||||
try:
|
||||
shutil.copy(temp_file_name, path_file_name)
|
||||
except:
|
||||
except shutil.Error:
|
||||
return self.save_file_as()
|
||||
self.main_window.addRecentFile(path_file_name)
|
||||
self.set_modified(False)
|
||||
@ -585,7 +593,7 @@ class ServiceManager(QtGui.QWidget, ServiceManagerDialog):
|
||||
log.debug(u'ServiceManager.save_file - %s', path_file_name)
|
||||
Settings().setValue(self.main_window.serviceManagerSettingsSection + u'/last directory', path)
|
||||
service = []
|
||||
Receiver.send_message(u'cursor_busy')
|
||||
self.application.set_busy_cursor()
|
||||
# Number of items + 1 to zip it
|
||||
self.main_window.displayProgressBar(len(self.service_items) + 1)
|
||||
for item in self.service_items:
|
||||
@ -614,11 +622,11 @@ class ServiceManager(QtGui.QWidget, ServiceManagerDialog):
|
||||
if zip_file:
|
||||
zip_file.close()
|
||||
self.main_window.finishedProgressBar()
|
||||
Receiver.send_message(u'cursor_normal')
|
||||
self.application.set_normal_cursor()
|
||||
if success:
|
||||
try:
|
||||
shutil.copy(temp_file_name, path_file_name)
|
||||
except:
|
||||
except shutil.Error:
|
||||
return self.save_file_as()
|
||||
self.main_window.addRecentFile(path_file_name)
|
||||
self.set_modified(False)
|
||||
@ -653,11 +661,11 @@ class ServiceManager(QtGui.QWidget, ServiceManagerDialog):
|
||||
# SaveAs from osz to oszl is not valid as the files will be deleted
|
||||
# on exit which is not sensible or usable in the long term.
|
||||
if self._file_name.endswith(u'oszl') or self.service_has_all_original_files:
|
||||
file_name = QtGui.QFileDialog.getSavefile_name(self.main_window, UiStrings().SaveService, path,
|
||||
file_name = QtGui.QFileDialog.getSaveFileName(self.main_window, UiStrings().SaveService, path,
|
||||
translate('OpenLP.ServiceManager',
|
||||
'OpenLP Service Files (*.osz);; OpenLP Service Files - lite (*.oszl)'))
|
||||
else:
|
||||
file_name = QtGui.QFileDialog.getSavefile_name(self.main_window, UiStrings().SaveService, path,
|
||||
file_name = QtGui.QFileDialog.getSaveFileName(self.main_window, UiStrings().SaveService, path,
|
||||
translate('OpenLP.ServiceManager', 'OpenLP Service Files (*.osz);;'))
|
||||
if not file_name:
|
||||
return False
|
||||
@ -691,13 +699,15 @@ class ServiceManager(QtGui.QWidget, ServiceManagerDialog):
|
||||
return False
|
||||
zip_file = None
|
||||
file_to = None
|
||||
self.application.set_busy_cursor()
|
||||
try:
|
||||
zip_file = zipfile.ZipFile(file_name)
|
||||
for zip_info in zip_file.infolist():
|
||||
try:
|
||||
ucsfile = zip_info.filename.decode(u'utf-8')
|
||||
except UnicodeDecodeError:
|
||||
log.exception(u'file_name "%s" is not valid UTF-8' % zip_info.file_name.decode(u'utf-8', u'replace'))
|
||||
log.exception(u'file_name "%s" is not valid UTF-8' %
|
||||
zip_info.file_name.decode(u'utf-8', u'replace'))
|
||||
critical_error_message_box(message=translate('OpenLP.ServiceManager',
|
||||
'File is not a valid service.\n The content encoding is not UTF-8.'))
|
||||
continue
|
||||
@ -710,7 +720,6 @@ class ServiceManager(QtGui.QWidget, ServiceManagerDialog):
|
||||
if osfile.endswith(u'osd'):
|
||||
p_file = os.path.join(self.servicePath, osfile)
|
||||
if 'p_file' in locals():
|
||||
Receiver.send_message(u'cursor_busy')
|
||||
file_to = open(p_file, u'r')
|
||||
items = cPickle.load(file_to)
|
||||
file_to.close()
|
||||
@ -755,6 +764,7 @@ class ServiceManager(QtGui.QWidget, ServiceManagerDialog):
|
||||
QtGui.QMessageBox.information(self, translate('OpenLP.ServiceManager', 'Corrupt File'),
|
||||
translate('OpenLP.ServiceManager',
|
||||
'This file is either corrupt or it is not an OpenLP 2 service file.'))
|
||||
self.application.set_normal_cursor()
|
||||
return
|
||||
finally:
|
||||
if file_to:
|
||||
@ -762,7 +772,7 @@ class ServiceManager(QtGui.QWidget, ServiceManagerDialog):
|
||||
if zip_file:
|
||||
zip_file.close()
|
||||
self.main_window.finishedProgressBar()
|
||||
Receiver.send_message(u'cursor_normal')
|
||||
self.application.set_normal_cursor()
|
||||
self.repaint_service_list(-1, -1)
|
||||
|
||||
def load_Last_file(self):
|
||||
@ -809,7 +819,8 @@ class ServiceManager(QtGui.QWidget, ServiceManagerDialog):
|
||||
delay_suffix = u' %s s' % unicode(service_item[u'service_item'].timed_slide_interval)
|
||||
else:
|
||||
delay_suffix = u' ...'
|
||||
self.timed_slide_interval.setText(translate('OpenLP.ServiceManager', '&Delay between slides') + delay_suffix)
|
||||
self.timed_slide_interval.setText(
|
||||
translate('OpenLP.ServiceManager', '&Delay between slides') + delay_suffix)
|
||||
# TODO for future: make group explains itself more visually
|
||||
else:
|
||||
self.auto_play_slides_group.menuAction().setVisible(False)
|
||||
@ -818,7 +829,7 @@ class ServiceManager(QtGui.QWidget, ServiceManagerDialog):
|
||||
if service_item[u'service_item'].is_capable(ItemCapabilities.CanAutoStartForLive):
|
||||
self.auto_start_action.setVisible(True)
|
||||
self.auto_start_action.setIcon(self.inactive)
|
||||
self.auto_start_action.setText(translate('OpenLP.ServiceManager','&Auto Start - inactive'))
|
||||
self.auto_start_action.setText(translate('OpenLP.ServiceManager', '&Auto Start - inactive'))
|
||||
if service_item[u'service_item'].will_auto_start:
|
||||
self.auto_start_action.setText(translate('OpenLP.ServiceManager', '&Auto Start - active'))
|
||||
self.auto_start_action.setIcon(self.active)
|
||||
@ -876,7 +887,6 @@ class ServiceManager(QtGui.QWidget, ServiceManagerDialog):
|
||||
self.main_window.generalSettingsSection + u'/loop delay')
|
||||
self.set_modified()
|
||||
|
||||
|
||||
def toggle_auto_play_slides_loop(self):
|
||||
"""
|
||||
Toggle Auto play slide loop.
|
||||
@ -892,7 +902,6 @@ class ServiceManager(QtGui.QWidget, ServiceManagerDialog):
|
||||
self.main_window.generalSettingsSection + u'/loop delay')
|
||||
self.set_modified()
|
||||
|
||||
|
||||
def on_timed_slide_interval(self):
|
||||
"""
|
||||
Shows input dialog for enter interval in seconds for delay
|
||||
@ -935,12 +944,20 @@ class ServiceManager(QtGui.QWidget, ServiceManagerDialog):
|
||||
self.add_service_item(self.serviceItemEditForm.get_service_item(),
|
||||
replace=True, expand=self.service_items[item][u'expanded'])
|
||||
|
||||
def preview_live(self, message):
|
||||
def preview_live(self, unique_identifier, row):
|
||||
"""
|
||||
Called by the SlideController to request a preview item be made live
|
||||
and allows the next preview to be updated if relevant.
|
||||
|
||||
|
||||
``unique_identifier``
|
||||
Reference to the service_item
|
||||
|
||||
|
||||
``row``
|
||||
individual row number
|
||||
|
||||
"""
|
||||
unique_identifier, row = message.split(u':')
|
||||
for sitem in self.service_items:
|
||||
if sitem[u'service_item'].unique_identifier == unique_identifier:
|
||||
item = self.service_manager_list.topLevelItem(sitem[u'order'] - 1)
|
||||
@ -966,9 +983,13 @@ class ServiceManager(QtGui.QWidget, ServiceManagerDialog):
|
||||
lookFor = 1
|
||||
serviceIterator += 1
|
||||
|
||||
def previous_item(self, message):
|
||||
def previous_item(self, last_slide=False):
|
||||
"""
|
||||
Called by the SlideController to select the previous service item.
|
||||
|
||||
``last_slide``
|
||||
Is this the last slide in the service_item
|
||||
|
||||
"""
|
||||
if not self.service_manager_list.selectedItems():
|
||||
return
|
||||
@ -978,7 +999,7 @@ class ServiceManager(QtGui.QWidget, ServiceManagerDialog):
|
||||
serviceIterator = QtGui.QTreeWidgetItemIterator(self.service_manager_list)
|
||||
while serviceIterator.value():
|
||||
if serviceIterator.value() == selected:
|
||||
if message == u'last slide' and prevItemLastSlide:
|
||||
if last_slide and prevItemLastSlide:
|
||||
pos = prevItem.data(0, QtCore.Qt.UserRole)
|
||||
check_expanded = self.service_items[pos - 1][u'expanded']
|
||||
self.service_manager_list.setCurrentItem(prevItemLastSlide)
|
||||
@ -1201,13 +1222,13 @@ class ServiceManager(QtGui.QWidget, ServiceManagerDialog):
|
||||
self.service_manager_list.setCurrentItem(treewidgetitem)
|
||||
treewidgetitem.setExpanded(item[u'expanded'])
|
||||
|
||||
def cleanUp(self):
|
||||
def clean_up(self):
|
||||
"""
|
||||
Empties the servicePath of temporary files on system exit.
|
||||
"""
|
||||
log.debug(u'Cleaning up servicePath')
|
||||
for file in os.listdir(self.servicePath):
|
||||
file_path = os.path.join(self.servicePath, file)
|
||||
for file_name in os.listdir(self.servicePath):
|
||||
file_path = os.path.join(self.servicePath, file_name)
|
||||
delete_file(file_path)
|
||||
if os.path.exists(os.path.join(self.servicePath, u'audio')):
|
||||
shutil.rmtree(os.path.join(self.servicePath, u'audio'), True)
|
||||
@ -1222,12 +1243,12 @@ class ServiceManager(QtGui.QWidget, ServiceManagerDialog):
|
||||
Settings().setValue(self.main_window.serviceManagerSettingsSection + u'/service theme', self.service_theme)
|
||||
self.regenerate_service_Items(True)
|
||||
|
||||
def themeChange(self):
|
||||
def theme_change(self):
|
||||
"""
|
||||
The theme may have changed in the settings dialog so make
|
||||
sure the theme combo box is in the correct state.
|
||||
"""
|
||||
log.debug(u'themeChange')
|
||||
log.debug(u'theme_change')
|
||||
visible = self.renderer.theme_level == ThemeLevel.Global
|
||||
self.theme_label.setVisible(visible)
|
||||
self.theme_combo_box.setVisible(visible)
|
||||
@ -1237,7 +1258,7 @@ class ServiceManager(QtGui.QWidget, ServiceManagerDialog):
|
||||
Rebuild the service list as things have changed and a
|
||||
repaint is the easiest way to do this.
|
||||
"""
|
||||
Receiver.send_message(u'cursor_busy')
|
||||
self.application.set_busy_cursor()
|
||||
log.debug(u'regenerate_service_Items')
|
||||
# force reset of renderer as theme data has changed
|
||||
self.service_has_all_original_files = True
|
||||
@ -1269,14 +1290,14 @@ class ServiceManager(QtGui.QWidget, ServiceManagerDialog):
|
||||
self.set_modified()
|
||||
# Repaint it once only at the end
|
||||
self.repaint_service_list(-1, -1)
|
||||
Receiver.send_message(u'cursor_normal')
|
||||
self.application.set_normal_cursor()
|
||||
|
||||
def serviceItemUpdate(self, message):
|
||||
def service_item_update(self, edit_id, unique_identifier, temporary=False):
|
||||
"""
|
||||
Triggered from plugins to update service items.
|
||||
Save the values as they will be used as part of the service load
|
||||
"""
|
||||
edit_id, self.load_item_unique_identifier, temporary = message.split(u':')
|
||||
self.load_item_unique_identifier = unique_identifier
|
||||
self.load_item_edit_id = int(edit_id)
|
||||
self.load_item_temporary = str_to_bool(temporary)
|
||||
|
||||
@ -1344,7 +1365,7 @@ class ServiceManager(QtGui.QWidget, ServiceManagerDialog):
|
||||
"""
|
||||
Send the current item to the Preview slide controller
|
||||
"""
|
||||
Receiver.send_message(u'cursor_busy')
|
||||
self.application.set_busy_cursor()
|
||||
item, child = self.find_service_item()
|
||||
if self.service_items[item][u'service_item'].is_valid:
|
||||
self.preview_controller.addServiceManagerItem(self.service_items[item][u'service_item'], child)
|
||||
@ -1352,7 +1373,7 @@ class ServiceManager(QtGui.QWidget, ServiceManagerDialog):
|
||||
critical_error_message_box(translate('OpenLP.ServiceManager', 'Missing Display Handler'),
|
||||
translate('OpenLP.ServiceManager',
|
||||
'Your item cannot be displayed as there is no handler to display it'))
|
||||
Receiver.send_message(u'cursor_normal')
|
||||
self.application.set_normal_cursor()
|
||||
|
||||
def get_service_item(self):
|
||||
"""
|
||||
@ -1385,7 +1406,7 @@ class ServiceManager(QtGui.QWidget, ServiceManagerDialog):
|
||||
return
|
||||
if row != -1:
|
||||
child = row
|
||||
Receiver.send_message(u'cursor_busy')
|
||||
self.application.set_busy_cursor()
|
||||
if self.service_items[item][u'service_item'].is_valid:
|
||||
self.live_controller.addServiceManagerItem(self.service_items[item][u'service_item'], child)
|
||||
if Settings().value(self.main_window.generalSettingsSection + u'/auto preview'):
|
||||
@ -1400,13 +1421,13 @@ class ServiceManager(QtGui.QWidget, ServiceManagerDialog):
|
||||
critical_error_message_box(translate('OpenLP.ServiceManager', 'Missing Display Handler'),
|
||||
translate('OpenLP.ServiceManager',
|
||||
'Your item cannot be displayed as the plugin required to display it is missing or inactive'))
|
||||
Receiver.send_message(u'cursor_normal')
|
||||
self.application.set_normal_cursor()
|
||||
|
||||
def remote_edit(self):
|
||||
"""
|
||||
Triggers a remote edit to a plugin to allow item to be edited.
|
||||
"""
|
||||
item, child = self.find_service_item()
|
||||
item = self.find_service_item()[0]
|
||||
if self.service_items[item][u'service_item'].is_capable(ItemCapabilities.CanEdit):
|
||||
new_item = Registry().get(self.service_items[item][u'service_item'].name). \
|
||||
onRemoteEdit(self.service_items[item][u'service_item'].edit_id)
|
||||
@ -1612,4 +1633,14 @@ class ServiceManager(QtGui.QWidget, ServiceManagerDialog):
|
||||
self._main_window = Registry().get(u'main_window')
|
||||
return self._main_window
|
||||
|
||||
main_window = property(_get_main_window)
|
||||
main_window = property(_get_main_window)
|
||||
|
||||
def _get_application(self):
|
||||
"""
|
||||
Adds the openlp to the class dynamically
|
||||
"""
|
||||
if not hasattr(self, u'_application'):
|
||||
self._application = Registry().get(u'application')
|
||||
return self._application
|
||||
|
||||
application = property(_get_application)
|
||||
|
@ -26,12 +26,15 @@
|
||||
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||
###############################################################################
|
||||
|
||||
"""
|
||||
The :mod:`~openlp.core.ui.servicenoteform` module contains the `ServiceNoteForm` class.
|
||||
"""
|
||||
from PyQt4 import QtGui
|
||||
|
||||
from openlp.core.lib import translate, SpellTextEdit, Registry
|
||||
from openlp.core.lib import SpellTextEdit, Registry, translate
|
||||
from openlp.core.lib.ui import create_button_box
|
||||
|
||||
|
||||
class ServiceNoteForm(QtGui.QDialog):
|
||||
"""
|
||||
This is the form that is used to edit the verses of the song.
|
||||
@ -45,10 +48,16 @@ class ServiceNoteForm(QtGui.QDialog):
|
||||
self.retranslateUi()
|
||||
|
||||
def exec_(self):
|
||||
"""
|
||||
Execute the form and return the result.
|
||||
"""
|
||||
self.text_edit.setFocus()
|
||||
return QtGui.QDialog.exec_(self)
|
||||
|
||||
def setupUi(self):
|
||||
"""
|
||||
Set up the UI of the dialog
|
||||
"""
|
||||
self.setObjectName(u'serviceNoteEdit')
|
||||
self.dialog_layout = QtGui.QVBoxLayout(self)
|
||||
self.dialog_layout.setContentsMargins(8, 8, 8, 8)
|
||||
@ -61,6 +70,9 @@ class ServiceNoteForm(QtGui.QDialog):
|
||||
self.dialog_layout.addWidget(self.button_box)
|
||||
|
||||
def retranslateUi(self):
|
||||
"""
|
||||
Translate the UI on the fly
|
||||
"""
|
||||
self.setWindowTitle(translate('OpenLP.ServiceNoteForm', 'Service Item Notes'))
|
||||
|
||||
def _get_main_window(self):
|
||||
@ -71,4 +83,4 @@ class ServiceNoteForm(QtGui.QDialog):
|
||||
self._main_window = Registry().get(u'main_window')
|
||||
return self._main_window
|
||||
|
||||
main_window = property(_get_main_window)
|
||||
main_window = property(_get_main_window)
|
||||
|
@ -26,14 +26,23 @@
|
||||
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||
###############################################################################
|
||||
|
||||
"""
|
||||
The UI widgets of the settings dialog.
|
||||
"""
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
from openlp.core.lib import translate, build_icon
|
||||
from openlp.core.lib.ui import create_button_box
|
||||
|
||||
|
||||
class Ui_SettingsDialog(object):
|
||||
"""
|
||||
The UI widgets of the settings dialog.
|
||||
"""
|
||||
def setupUi(self, settingsDialog):
|
||||
"""
|
||||
Set up the UI
|
||||
"""
|
||||
settingsDialog.setObjectName(u'settingsDialog')
|
||||
settingsDialog.resize(800, 500)
|
||||
settingsDialog.setWindowIcon(build_icon(u':/system/system_settings.png'))
|
||||
@ -55,4 +64,7 @@ class Ui_SettingsDialog(object):
|
||||
QtCore.QObject.connect(self.settingListWidget, QtCore.SIGNAL(u'currentRowChanged(int)'), self.tabChanged)
|
||||
|
||||
def retranslateUi(self, settingsDialog):
|
||||
"""
|
||||
Translate the UI on the fly
|
||||
"""
|
||||
settingsDialog.setWindowTitle(translate('OpenLP.SettingsForm', 'Configure OpenLP'))
|
||||
|
@ -33,13 +33,14 @@ import logging
|
||||
|
||||
from PyQt4 import QtGui
|
||||
|
||||
from openlp.core.lib import Receiver, build_icon, PluginStatus, Registry
|
||||
from openlp.core.lib import Receiver, PluginStatus, Registry, build_icon
|
||||
from openlp.core.ui import AdvancedTab, GeneralTab, ThemesTab
|
||||
from openlp.core.ui.media import PlayerTab
|
||||
from settingsdialog import Ui_SettingsDialog
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class SettingsForm(QtGui.QDialog, Ui_SettingsDialog):
|
||||
"""
|
||||
Provide the form to manipulate the settings for OpenLP
|
||||
@ -54,13 +55,16 @@ class SettingsForm(QtGui.QDialog, Ui_SettingsDialog):
|
||||
# General tab
|
||||
self.generalTab = GeneralTab(self)
|
||||
# Themes tab
|
||||
self.themesTab = ThemesTab(self, self.main_window)
|
||||
self.themesTab = ThemesTab(self)
|
||||
# Advanced tab
|
||||
self.advancedTab = AdvancedTab(self)
|
||||
# Advanced tab
|
||||
self.playerTab = PlayerTab(self, self.main_window)
|
||||
self.playerTab = PlayerTab(self)
|
||||
|
||||
def exec_(self):
|
||||
"""
|
||||
Execute the form
|
||||
"""
|
||||
# load all the settings
|
||||
self.settingListWidget.clear()
|
||||
while self.stackedLayout.count():
|
||||
@ -161,4 +165,4 @@ class SettingsForm(QtGui.QDialog, Ui_SettingsDialog):
|
||||
self._service_manager = Registry().get(u'service_manager')
|
||||
return self._service_manager
|
||||
|
||||
service_manager = property(_get_service_manager)
|
||||
service_manager = property(_get_service_manager)
|
||||
|
@ -26,17 +26,23 @@
|
||||
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||
###############################################################################
|
||||
|
||||
"""
|
||||
The list of shortcuts within a dialog.
|
||||
"""
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
from openlp.core.lib import translate, build_icon
|
||||
from openlp.core.lib.ui import create_button_box
|
||||
|
||||
|
||||
class CaptureShortcutButton(QtGui.QPushButton):
|
||||
"""
|
||||
A class to encapsulate a ``QPushButton``.
|
||||
"""
|
||||
def __init__(self, *args):
|
||||
"""
|
||||
Constructor
|
||||
"""
|
||||
QtGui.QPushButton.__init__(self, *args)
|
||||
self.setCheckable(True)
|
||||
|
||||
@ -51,7 +57,13 @@ class CaptureShortcutButton(QtGui.QPushButton):
|
||||
|
||||
|
||||
class Ui_ShortcutListDialog(object):
|
||||
"""
|
||||
The UI widgets for the shortcut dialog.
|
||||
"""
|
||||
def setupUi(self, shortcutListDialog):
|
||||
"""
|
||||
Set up the UI
|
||||
"""
|
||||
shortcutListDialog.setObjectName(u'shortcutListDialog')
|
||||
shortcutListDialog.resize(500, 438)
|
||||
self.shortcutListLayout = QtGui.QVBoxLayout(shortcutListDialog)
|
||||
@ -113,6 +125,9 @@ class Ui_ShortcutListDialog(object):
|
||||
self.retranslateUi(shortcutListDialog)
|
||||
|
||||
def retranslateUi(self, shortcutListDialog):
|
||||
"""
|
||||
Translate the UI on the fly
|
||||
"""
|
||||
shortcutListDialog.setWindowTitle(translate('OpenLP.ShortcutListDialog', 'Configure Shortcuts'))
|
||||
self.descriptionLabel.setText(
|
||||
translate('OpenLP.ShortcutListDialog', 'Select an action and click one of the buttons below to start '
|
||||
|
@ -26,13 +26,14 @@
|
||||
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||
###############################################################################
|
||||
|
||||
"""
|
||||
The :mod:`~openlp.core.ui.shortcutlistform` module contains the form class"""
|
||||
import logging
|
||||
import re
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
from openlp.core.lib import Receiver, Settings
|
||||
from openlp.core.lib import Registry, Settings
|
||||
from openlp.core.utils import translate
|
||||
from openlp.core.utils.actions import ActionList
|
||||
from shortcutlistdialog import Ui_ShortcutListDialog
|
||||
@ -48,6 +49,9 @@ class ShortcutListForm(QtGui.QDialog, Ui_ShortcutListDialog):
|
||||
"""
|
||||
|
||||
def __init__(self, parent=None):
|
||||
"""
|
||||
Constructor
|
||||
"""
|
||||
QtGui.QDialog.__init__(self, parent)
|
||||
self.setupUi(self)
|
||||
self.changedActions = {}
|
||||
@ -72,6 +76,9 @@ class ShortcutListForm(QtGui.QDialog, Ui_ShortcutListDialog):
|
||||
self.onCustomRadioButtonClicked)
|
||||
|
||||
def keyPressEvent(self, event):
|
||||
"""
|
||||
Respond to certain key presses
|
||||
"""
|
||||
if event.key() == QtCore.Qt.Key_Space:
|
||||
self.keyReleaseEvent(event)
|
||||
elif self.primaryPushButton.isChecked() or self.alternatePushButton.isChecked():
|
||||
@ -81,6 +88,9 @@ class ShortcutListForm(QtGui.QDialog, Ui_ShortcutListDialog):
|
||||
self.close()
|
||||
|
||||
def keyReleaseEvent(self, event):
|
||||
"""
|
||||
Respond to certain key presses
|
||||
"""
|
||||
if not self.primaryPushButton.isChecked() and not self.alternatePushButton.isChecked():
|
||||
return
|
||||
key = event.key()
|
||||
@ -106,6 +116,9 @@ class ShortcutListForm(QtGui.QDialog, Ui_ShortcutListDialog):
|
||||
False, text=key_sequence.toString())
|
||||
|
||||
def exec_(self):
|
||||
"""
|
||||
Execute the dialog
|
||||
"""
|
||||
self.changedActions = {}
|
||||
self.reloadShortcutList()
|
||||
self._adjustButton(self.primaryPushButton, False, False, u'')
|
||||
@ -422,10 +435,10 @@ class ShortcutListForm(QtGui.QDialog, Ui_ShortcutListDialog):
|
||||
if action.shortcutContext() in [QtCore.Qt.WindowShortcut,
|
||||
QtCore.Qt.ApplicationShortcut]:
|
||||
is_valid = False
|
||||
if changing_action.shortcutContext() in [QtCore.Qt.WindowShortcut, QtCore.Qt.ApplicationShortcut]:
|
||||
if changing_action.shortcutContext() in [QtCore.Qt.WindowShortcut, QtCore.Qt.ApplicationShortcut]:
|
||||
is_valid = False
|
||||
if not is_valid:
|
||||
Receiver.send_message(u'openlp_warning_message', {
|
||||
self.main_window.warning_message( {
|
||||
u'title': translate('OpenLP.ShortcutListDialog', 'Duplicate Shortcut'),
|
||||
u'message': translate('OpenLP.ShortcutListDialog',
|
||||
'The shortcut "%s" is already assigned to another action, '
|
||||
@ -465,3 +478,13 @@ class ShortcutListForm(QtGui.QDialog, Ui_ShortcutListDialog):
|
||||
button.setChecked(checked)
|
||||
if enabled is not None:
|
||||
button.setEnabled(enabled)
|
||||
|
||||
def _get_main_window(self):
|
||||
"""
|
||||
Adds the main window to the class dynamically
|
||||
"""
|
||||
if not hasattr(self, u'_main_window'):
|
||||
self._main_window = Registry().get(u'main_window')
|
||||
return self._main_window
|
||||
|
||||
main_window = property(_get_main_window)
|
@ -26,7 +26,9 @@
|
||||
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||
###############################################################################
|
||||
|
||||
"""
|
||||
The :mod:`slidecontroller` module contains argubly the most important part of OpenLP - the slide controller
|
||||
"""
|
||||
import os
|
||||
import logging
|
||||
import copy
|
||||
@ -34,8 +36,8 @@ from collections import deque
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
from openlp.core.lib import OpenLPToolbar, Receiver, ItemCapabilities, translate, build_icon, build_html, \
|
||||
ServiceItem, ImageSource, SlideLimits, ServiceItemAction, Settings, Registry, UiStrings, ScreenList
|
||||
from openlp.core.lib import OpenLPToolbar, Receiver, ItemCapabilities, ServiceItem, ImageSource, SlideLimits, \
|
||||
ServiceItemAction, Settings, Registry, UiStrings, ScreenList, build_icon, build_html, translate
|
||||
from openlp.core.ui import HideMode, MainDisplay, Display, DisplayControllerType
|
||||
from openlp.core.lib.ui import create_action
|
||||
from openlp.core.utils.actions import ActionList, CategoryOrder
|
||||
@ -92,6 +94,14 @@ class SlideController(DisplayController):
|
||||
u'audioPauseItem',
|
||||
u'audioTimeLabel'
|
||||
]
|
||||
self.wideMenu = [
|
||||
u'blankScreenButton',
|
||||
u'themeScreenButton',
|
||||
u'desktopScreenButton'
|
||||
]
|
||||
self.hideMenuList = [
|
||||
u'hideMenu'
|
||||
]
|
||||
self.timer_id = 0
|
||||
self.songEdit = False
|
||||
self.selectedRow = 0
|
||||
@ -193,6 +203,19 @@ class SlideController(DisplayController):
|
||||
self.hideMenu.menu().addAction(self.blankScreen)
|
||||
self.hideMenu.menu().addAction(self.themeScreen)
|
||||
self.hideMenu.menu().addAction(self.desktopScreen)
|
||||
# Wide menu of display control buttons.
|
||||
self.blankScreenButton = QtGui.QToolButton(self.toolbar)
|
||||
self.blankScreenButton.setObjectName(u'blankScreenButton')
|
||||
self.toolbar.addToolbarWidget(self.blankScreenButton)
|
||||
self.blankScreenButton.setDefaultAction(self.blankScreen)
|
||||
self.themeScreenButton = QtGui.QToolButton(self.toolbar)
|
||||
self.themeScreenButton.setObjectName(u'themeScreenButton')
|
||||
self.toolbar.addToolbarWidget(self.themeScreenButton)
|
||||
self.themeScreenButton.setDefaultAction(self.themeScreen)
|
||||
self.desktopScreenButton = QtGui.QToolButton(self.toolbar)
|
||||
self.desktopScreenButton.setObjectName(u'desktopScreenButton')
|
||||
self.toolbar.addToolbarWidget(self.desktopScreenButton)
|
||||
self.desktopScreenButton.setDefaultAction(self.desktopScreen)
|
||||
self.toolbar.addToolbarAction(u'loopSeparator', separator=True)
|
||||
# Play Slides Menu
|
||||
self.playSlidesMenu = QtGui.QToolButton(self.toolbar)
|
||||
@ -207,7 +230,7 @@ class SlideController(DisplayController):
|
||||
self.playSlidesOnce = create_action(self, u'playSlidesOnce', text=UiStrings().PlaySlidesToEnd,
|
||||
icon=u':/media/media_time.png', checked=False, shortcuts=[],
|
||||
category=self.category, triggers=self.onPlaySlidesOnce)
|
||||
if Settings().value(self.parent().generalSettingsSection + u'/enable slide loop'):
|
||||
if Settings().value(self.parent().advancedSettingsSection + u'/slide limits') == SlideLimits.Wrap:
|
||||
self.playSlidesMenu.setDefaultAction(self.playSlidesLoop)
|
||||
else:
|
||||
self.playSlidesMenu.setDefaultAction(self.playSlidesOnce)
|
||||
@ -257,7 +280,7 @@ class SlideController(DisplayController):
|
||||
self.audioMenu.addAction(self.nextTrackItem)
|
||||
self.trackMenu = self.audioMenu.addMenu(translate('OpenLP.SlideController', 'Tracks'))
|
||||
self.audioTimeLabel = QtGui.QLabel(u' 00:00 ', self.toolbar)
|
||||
self.audioTimeLabel.setAlignment(QtCore.Qt.AlignCenter|QtCore.Qt.AlignHCenter)
|
||||
self.audioTimeLabel.setAlignment(QtCore.Qt.AlignCenter | QtCore.Qt.AlignHCenter)
|
||||
self.audioTimeLabel.setStyleSheet(
|
||||
u'background-color: palette(background); '
|
||||
u'border-top-color: palette(shadow); '
|
||||
@ -288,7 +311,7 @@ class SlideController(DisplayController):
|
||||
self.slideLayout.setObjectName(u'SlideLayout')
|
||||
self.previewDisplay = Display(self, self.isLive, self)
|
||||
self.previewDisplay.setGeometry(QtCore.QRect(0, 0, 300, 300))
|
||||
self.previewDisplay.screen = {u'size':self.previewDisplay.geometry()}
|
||||
self.previewDisplay.screen = {u'size': self.previewDisplay.geometry()}
|
||||
self.previewDisplay.setup()
|
||||
self.slideLayout.insertWidget(0, self.previewDisplay)
|
||||
self.previewDisplay.hide()
|
||||
@ -344,6 +367,7 @@ class SlideController(DisplayController):
|
||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||
QtCore.SIGNAL(u'slidecontroller_toggle_display'), self.toggleDisplay)
|
||||
self.toolbar.setWidgetVisible(self.loopList, False)
|
||||
self.toolbar.setWidgetVisible(self.wideMenu, False)
|
||||
else:
|
||||
QtCore.QObject.connect(self.previewListWidget,
|
||||
QtCore.SIGNAL(u'doubleClicked(QModelIndex)'), self.onGoLiveClick)
|
||||
@ -432,6 +456,9 @@ class SlideController(DisplayController):
|
||||
self.current_shortcut = u''
|
||||
|
||||
def setLiveHotkeys(self, parent=None):
|
||||
"""
|
||||
Set the live hotkeys
|
||||
"""
|
||||
self.previousService = create_action(parent, u'previousService',
|
||||
text=translate('OpenLP.SlideController', 'Previous Service'),
|
||||
shortcuts=[QtCore.Qt.Key_Left], context=QtCore.Qt.WidgetWithChildrenShortcut, category=self.category,
|
||||
@ -442,10 +469,13 @@ class SlideController(DisplayController):
|
||||
triggers=self.serviceNext)
|
||||
self.escapeItem = create_action(parent, 'escapeItem',
|
||||
text=translate('OpenLP.SlideController', 'Escape Item'),
|
||||
shortcuts=[QtCore.Qt.Key_Escape],context=QtCore.Qt.WidgetWithChildrenShortcut, category=self.category,
|
||||
shortcuts=[QtCore.Qt.Key_Escape], context=QtCore.Qt.WidgetWithChildrenShortcut, category=self.category,
|
||||
triggers=self.liveEscape)
|
||||
|
||||
def liveEscape(self):
|
||||
"""
|
||||
If you press ESC on the live screen it should close the display temporarily.
|
||||
"""
|
||||
self.display.setVisible(False)
|
||||
self.media_controller.media_stop(self)
|
||||
|
||||
@ -488,12 +518,12 @@ class SlideController(DisplayController):
|
||||
self.keypress_loop = True
|
||||
keypressCommand = self.keypress_queue.popleft()
|
||||
if keypressCommand == ServiceItemAction.Previous:
|
||||
Receiver.send_message('servicemanager_previous_item')
|
||||
self.service_manager.previous_item()
|
||||
elif keypressCommand == ServiceItemAction.PreviousLastSlide:
|
||||
# Go to the last slide of the previous item
|
||||
Receiver.send_message('servicemanager_previous_item', u'last slide')
|
||||
self.service_manager.previous_item(last_slide=True)
|
||||
else:
|
||||
Receiver.send_message('servicemanager_next_item')
|
||||
self.service_manager.next_item()
|
||||
self.keypress_loop = False
|
||||
|
||||
def screenSizeChanged(self):
|
||||
@ -520,11 +550,14 @@ class SlideController(DisplayController):
|
||||
serviceItem = ServiceItem()
|
||||
self.previewDisplay.webView.setHtml(build_html(serviceItem, self.previewDisplay.screen, None, self.isLive,
|
||||
plugins=self.plugin_manager.plugins))
|
||||
self.media_controller.setup_display(self.previewDisplay,True)
|
||||
self.media_controller.setup_display(self.previewDisplay, True)
|
||||
if self.serviceItem:
|
||||
self.refreshServiceItem()
|
||||
|
||||
def __addActionsToWidget(self, widget):
|
||||
"""
|
||||
Add actions to the widget specified by `widget`
|
||||
"""
|
||||
widget.addActions([
|
||||
self.previousItem, self.nextItem,
|
||||
self.previousService, self.nextService,
|
||||
@ -562,8 +595,24 @@ class SlideController(DisplayController):
|
||||
width = self.parent().controlSplitter.sizes()[self.split]
|
||||
for framenumber in range(len(self.serviceItem.get_frames())):
|
||||
self.previewListWidget.setRowHeight(framenumber, width / self.ratio)
|
||||
self.onControllerSizeChanged(self.controller.width(), self.controller.height())
|
||||
|
||||
def onControllerSizeChanged(self, width, height):
|
||||
"""
|
||||
Change layout of display control buttons on controller size change
|
||||
"""
|
||||
if self.isLive:
|
||||
if width > 300 and self.hideMenu.isVisible():
|
||||
self.toolbar.setWidgetVisible(self.hideMenuList, False)
|
||||
self.toolbar.setWidgetVisible(self.wideMenu)
|
||||
elif width < 300 and not self.hideMenu.isVisible():
|
||||
self.toolbar.setWidgetVisible(self.wideMenu, False)
|
||||
self.toolbar.setWidgetVisible(self.hideMenuList)
|
||||
|
||||
def onSongBarHandler(self):
|
||||
"""
|
||||
Some song handler
|
||||
"""
|
||||
request = self.sender().text()
|
||||
slide_no = self.slideList[request]
|
||||
self.__updatePreviewSelection(slide_no)
|
||||
@ -690,7 +739,7 @@ class SlideController(DisplayController):
|
||||
self.playSlidesLoop.setChecked(item.auto_play_slides_loop)
|
||||
self.delaySpinBox.setValue(int(item.timed_slide_interval))
|
||||
self.onPlaySlidesLoop()
|
||||
elif self.isLive and item.auto_play_slides_once and item.timed_slide_interval > 0:
|
||||
elif self.isLive and item.auto_play_slides_once and item.timed_slide_interval > 0:
|
||||
self.playSlidesOnce.setChecked(item.auto_play_slides_once)
|
||||
self.delaySpinBox.setValue(int(item.timed_slide_interval))
|
||||
self.onPlaySlidesOnce()
|
||||
@ -770,9 +819,9 @@ class SlideController(DisplayController):
|
||||
else:
|
||||
# If current slide set background to image
|
||||
if framenumber == slideno:
|
||||
self.serviceItem.bg_image_bytes = self.image_manager.getImageBytes(frame[u'path'],
|
||||
self.serviceItem.bg_image_bytes = self.image_manager.get_image_bytes(frame[u'path'],
|
||||
ImageSource.ImagePlugin)
|
||||
image = self.image_manager.getImage(frame[u'path'], ImageSource.ImagePlugin)
|
||||
image = self.image_manager.get_image(frame[u'path'], ImageSource.ImagePlugin)
|
||||
label.setPixmap(QtGui.QPixmap.fromImage(image))
|
||||
self.previewListWidget.setCellWidget(framenumber, 0, label)
|
||||
slideHeight = width * (1 / self.ratio)
|
||||
@ -1088,6 +1137,9 @@ class SlideController(DisplayController):
|
||||
self.slideSelected()
|
||||
|
||||
def __checkUpdateSelectedSlide(self, row):
|
||||
"""
|
||||
Check if this slide has been updated
|
||||
"""
|
||||
if row + 1 < self.previewListWidget.rowCount():
|
||||
self.previewListWidget.scrollToItem(self.previewListWidget.item(row + 1, 0))
|
||||
self.previewListWidget.selectRow(row)
|
||||
@ -1160,9 +1212,15 @@ class SlideController(DisplayController):
|
||||
self.onToggleLoop()
|
||||
|
||||
def setAudioItemsVisibility(self, visible):
|
||||
"""
|
||||
Set the visibility of the audio stuff
|
||||
"""
|
||||
self.toolbar.setWidgetVisible(self.audioList, visible)
|
||||
|
||||
def onAudioPauseClicked(self, checked):
|
||||
"""
|
||||
Pause the audio player
|
||||
"""
|
||||
if not self.audioPauseItem.isVisible():
|
||||
return
|
||||
if checked:
|
||||
@ -1213,8 +1271,7 @@ class SlideController(DisplayController):
|
||||
row = self.previewListWidget.currentRow()
|
||||
if -1 < row < self.previewListWidget.rowCount():
|
||||
if self.serviceItem.from_service:
|
||||
Receiver.send_message('servicemanager_preview_live', u'%s:%s' %
|
||||
(self.serviceItem.unique_identifier, row))
|
||||
self.service_manager.preview_live(self.serviceItem.unique_identifier, row)
|
||||
else:
|
||||
self.live_controller.addServiceManagerItem(self.serviceItem, row)
|
||||
|
||||
@ -1268,15 +1325,24 @@ class SlideController(DisplayController):
|
||||
return None
|
||||
|
||||
def onNextTrackClicked(self):
|
||||
"""
|
||||
Go to the next track when next is clicked
|
||||
"""
|
||||
self.display.audioPlayer.next()
|
||||
|
||||
def onAudioTimeRemaining(self, time):
|
||||
"""
|
||||
Update how much time is remaining
|
||||
"""
|
||||
seconds = self.display.audioPlayer.mediaObject.remainingTime() // 1000
|
||||
minutes = seconds // 60
|
||||
seconds %= 60
|
||||
self.audioTimeLabel.setText(u' %02d:%02d ' % (minutes, seconds))
|
||||
|
||||
def onTrackTriggered(self):
|
||||
"""
|
||||
Start playing a track
|
||||
"""
|
||||
action = self.sender()
|
||||
self.display.audioPlayer.goTo(action.data())
|
||||
|
||||
@ -1328,4 +1394,4 @@ class SlideController(DisplayController):
|
||||
self._live_controller = Registry().get(u'live_controller')
|
||||
return self._live_controller
|
||||
|
||||
live_controller = property(_get_live_controller)
|
||||
live_controller = property(_get_live_controller)
|
||||
|
@ -26,17 +26,28 @@
|
||||
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||
###############################################################################
|
||||
from openlp.core.lib import Receiver
|
||||
"""
|
||||
The splash screen
|
||||
"""
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
|
||||
class SplashScreen(QtGui.QSplashScreen):
|
||||
"""
|
||||
The splash screen
|
||||
"""
|
||||
def __init__(self):
|
||||
"""
|
||||
Constructor
|
||||
"""
|
||||
QtGui.QSplashScreen.__init__(self)
|
||||
self.setupUi()
|
||||
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'close_splash'), self.close)
|
||||
|
||||
def setupUi(self):
|
||||
"""
|
||||
Set up the UI
|
||||
"""
|
||||
self.setObjectName(u'splashScreen')
|
||||
self.setContextMenuPolicy(QtCore.Qt.PreventContextMenu)
|
||||
splash_image = QtGui.QPixmap(u':/graphics/openlp-splash-screen.png')
|
||||
|
@ -26,15 +26,23 @@
|
||||
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||
###############################################################################
|
||||
|
||||
"""
|
||||
The UI widgets for the time dialog
|
||||
"""
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
from openlp.core.lib import translate, UiStrings
|
||||
from openlp.core.lib import UiStrings, translate
|
||||
from openlp.core.lib.ui import create_button_box
|
||||
|
||||
|
||||
class Ui_StartTimeDialog(object):
|
||||
"""
|
||||
The UI widgets for the time dialog
|
||||
"""
|
||||
def setupUi(self, StartTimeDialog):
|
||||
"""
|
||||
Set up the UI
|
||||
"""
|
||||
StartTimeDialog.setObjectName(u'StartTimeDialog')
|
||||
StartTimeDialog.resize(350, 10)
|
||||
self.dialogLayout = QtGui.QGridLayout(StartTimeDialog)
|
||||
@ -108,6 +116,9 @@ class Ui_StartTimeDialog(object):
|
||||
self.setMaximumHeight(self.sizeHint().height())
|
||||
|
||||
def retranslateUi(self, StartTimeDialog):
|
||||
"""
|
||||
Update the translations on the fly
|
||||
"""
|
||||
self.setWindowTitle(translate('OpenLP.StartTimeForm', 'Item Start and Finish Time'))
|
||||
self.hourSpinBox.setSuffix(UiStrings().Hours)
|
||||
self.minuteSpinBox.setSuffix(UiStrings().Minutes)
|
||||
|
@ -26,19 +26,25 @@
|
||||
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||
###############################################################################
|
||||
|
||||
"""
|
||||
The actual start time form.
|
||||
"""
|
||||
from PyQt4 import QtGui
|
||||
|
||||
from starttimedialog import Ui_StartTimeDialog
|
||||
|
||||
from openlp.core.lib import translate, UiStrings, Registry
|
||||
from openlp.core.lib import UiStrings, Registry, translate
|
||||
from openlp.core.lib.ui import critical_error_message_box
|
||||
|
||||
|
||||
class StartTimeForm(QtGui.QDialog, Ui_StartTimeDialog):
|
||||
"""
|
||||
The exception dialog
|
||||
The start time dialog
|
||||
"""
|
||||
def __init__(self):
|
||||
"""
|
||||
Constructor
|
||||
"""
|
||||
QtGui.QDialog.__init__(self, self.main_window)
|
||||
self.setupUi(self)
|
||||
|
||||
@ -60,6 +66,9 @@ class StartTimeForm(QtGui.QDialog, Ui_StartTimeDialog):
|
||||
return QtGui.QDialog.exec_(self)
|
||||
|
||||
def accept(self):
|
||||
"""
|
||||
When the dialog succeeds, this is run
|
||||
"""
|
||||
start = self.hourSpinBox.value() * 3600 + \
|
||||
self.minuteSpinBox.value() * 60 + \
|
||||
self.secondSpinBox.value()
|
||||
@ -79,6 +88,9 @@ class StartTimeForm(QtGui.QDialog, Ui_StartTimeDialog):
|
||||
return QtGui.QDialog.accept(self)
|
||||
|
||||
def _time_split(self, seconds):
|
||||
"""
|
||||
Split time up into hours minutes and seconds from secongs
|
||||
"""
|
||||
hours = seconds / 3600
|
||||
seconds -= 3600 * hours
|
||||
minutes = seconds / 60
|
||||
@ -93,4 +105,4 @@ class StartTimeForm(QtGui.QDialog, Ui_StartTimeDialog):
|
||||
self._main_window = Registry().get(u'main_window')
|
||||
return self._main_window
|
||||
|
||||
main_window = property(_get_main_window)
|
||||
main_window = property(_get_main_window)
|
||||
|
@ -26,13 +26,15 @@
|
||||
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||
###############################################################################
|
||||
|
||||
"""
|
||||
The Theme wizard
|
||||
"""
|
||||
import logging
|
||||
import os
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
from openlp.core.lib import Receiver, translate, UiStrings
|
||||
from openlp.core.lib import Receiver, UiStrings, Registry, translate
|
||||
from openlp.core.lib.theme import BackgroundType, BackgroundGradientType
|
||||
from openlp.core.lib.ui import critical_error_message_box
|
||||
from openlp.core.ui import ThemeLayoutForm
|
||||
@ -41,6 +43,7 @@ from themewizard import Ui_ThemeWizard
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class ThemeForm(QtGui.QWizard, Ui_ThemeWizard):
|
||||
"""
|
||||
This is the Theme Import Wizard, which allows easy creation and editing of
|
||||
@ -56,7 +59,6 @@ class ThemeForm(QtGui.QWizard, Ui_ThemeWizard):
|
||||
The QWidget-derived parent of the wizard.
|
||||
"""
|
||||
QtGui.QWizard.__init__(self, parent)
|
||||
self.thememanager = parent
|
||||
self.setupUi(self)
|
||||
self.registerFields()
|
||||
self.updateThemeAllowed = True
|
||||
@ -72,14 +74,14 @@ class ThemeForm(QtGui.QWizard, Ui_ThemeWizard):
|
||||
self.onGradientStartButtonClicked)
|
||||
QtCore.QObject.connect(self.gradientEndButton, QtCore.SIGNAL(u'clicked()'), self.onGradientEndButtonClicked)
|
||||
QtCore.QObject.connect(self.imageBrowseButton, QtCore.SIGNAL(u'clicked()'), self.onImageBrowseButtonClicked)
|
||||
QtCore.QObject.connect(self.mainColorButton, QtCore.SIGNAL(u'clicked()'), self.onMainColorButtonClicked)
|
||||
QtCore.QObject.connect(self.mainColorButton, QtCore.SIGNAL(u'clicked()'), self.onMainColorButtonClicked)
|
||||
QtCore.QObject.connect(self.outlineColorButton, QtCore.SIGNAL(u'clicked()'), self.onOutlineColorButtonClicked)
|
||||
QtCore.QObject.connect(self.shadowColorButton, QtCore.SIGNAL(u'clicked()'), self.onShadowColorButtonClicked)
|
||||
QtCore.QObject.connect(self.outlineCheckBox, QtCore.SIGNAL(u'stateChanged(int)'),
|
||||
self.onOutlineCheckCheckBoxStateChanged)
|
||||
QtCore.QObject.connect(self.shadowCheckBox, QtCore.SIGNAL(u'stateChanged(int)'),
|
||||
self.onShadowCheckCheckBoxStateChanged)
|
||||
QtCore.QObject.connect(self.footerColorButton,QtCore.SIGNAL(u'clicked()'), self.onFooterColorButtonClicked)
|
||||
QtCore.QObject.connect(self.footerColorButton, QtCore.SIGNAL(u'clicked()'), self.onFooterColorButtonClicked)
|
||||
QtCore.QObject.connect(self, QtCore.SIGNAL(u'customButtonClicked(int)'), self.onCustom1ButtonClicked)
|
||||
QtCore.QObject.connect(self.mainPositionCheckBox, QtCore.SIGNAL(u'stateChanged(int)'),
|
||||
self.onMainPositionCheckBoxStateChanged)
|
||||
@ -149,7 +151,7 @@ class ThemeForm(QtGui.QWizard, Ui_ThemeWizard):
|
||||
# Do not trigger on start up
|
||||
if self.currentPage != self.welcomePage:
|
||||
self.updateTheme()
|
||||
self.thememanager.generateImage(self.theme, True)
|
||||
self.theme_manager.generate_image(self.theme, True)
|
||||
|
||||
def updateLinesText(self, lines):
|
||||
"""
|
||||
@ -178,6 +180,9 @@ class ThemeForm(QtGui.QWizard, Ui_ThemeWizard):
|
||||
pixmapHeight + 2 * frameWidth)
|
||||
|
||||
def validateCurrentPage(self):
|
||||
"""
|
||||
Validate the current page
|
||||
"""
|
||||
background_image = BackgroundType.to_string(BackgroundType.Image)
|
||||
if self.page(self.currentId()) == self.backgroundPage and \
|
||||
self.theme.background_type == background_image and not self.imageFileEdit.text():
|
||||
@ -196,7 +201,7 @@ class ThemeForm(QtGui.QWizard, Ui_ThemeWizard):
|
||||
self.setOption(QtGui.QWizard.HaveCustomButton1, enabled)
|
||||
if self.page(pageId) == self.previewPage:
|
||||
self.updateTheme()
|
||||
frame = self.thememanager.generateImage(self.theme)
|
||||
frame = self.theme_manager.generate_image(self.theme)
|
||||
self.previewBoxLabel.setPixmap(frame)
|
||||
self.displayAspectRatio = float(frame.width()) / frame.height()
|
||||
self.resizeEvent()
|
||||
@ -206,15 +211,15 @@ class ThemeForm(QtGui.QWizard, Ui_ThemeWizard):
|
||||
Generate layout preview and display the form.
|
||||
"""
|
||||
self.updateTheme()
|
||||
width = self.thememanager.mainwindow.renderer.width
|
||||
height = self.thememanager.mainwindow.renderer.height
|
||||
width = self.renderer.width
|
||||
height = self.renderer.height
|
||||
pixmap = QtGui.QPixmap(width, height)
|
||||
pixmap.fill(QtCore.Qt.white)
|
||||
paint = QtGui.QPainter(pixmap)
|
||||
paint.setPen(QtGui.QPen(QtCore.Qt.blue, 2))
|
||||
paint.drawRect(self.thememanager.mainwindow.renderer.get_main_rectangle(self.theme))
|
||||
paint.drawRect(self.renderer.get_main_rectangle(self.theme))
|
||||
paint.setPen(QtGui.QPen(QtCore.Qt.red, 2))
|
||||
paint.drawRect(self.thememanager.mainwindow.renderer.get_footer_rectangle(self.theme))
|
||||
paint.drawRect(self.renderer.get_footer_rectangle(self.theme))
|
||||
paint.end()
|
||||
self.themeLayoutForm.exec_(pixmap)
|
||||
|
||||
@ -444,18 +449,30 @@ class ThemeForm(QtGui.QWizard, Ui_ThemeWizard):
|
||||
self.setBackgroundPageValues()
|
||||
|
||||
def onMainColorButtonClicked(self):
|
||||
"""
|
||||
Set the main colour value
|
||||
"""
|
||||
self.theme.font_main_color = self._colorButton(self.theme.font_main_color)
|
||||
self.setMainAreaPageValues()
|
||||
|
||||
def onOutlineColorButtonClicked(self):
|
||||
"""
|
||||
Set the outline colour value
|
||||
"""
|
||||
self.theme.font_main_outline_color = self._colorButton(self.theme.font_main_outline_color)
|
||||
self.setMainAreaPageValues()
|
||||
|
||||
def onShadowColorButtonClicked(self):
|
||||
"""
|
||||
Set the shadow colour value
|
||||
"""
|
||||
self.theme.font_main_shadow_color = self._colorButton(self.theme.font_main_shadow_color)
|
||||
self.setMainAreaPageValues()
|
||||
|
||||
def onFooterColorButtonClicked(self):
|
||||
"""
|
||||
Set the footer colour value
|
||||
"""
|
||||
self.theme.font_footer_color = self._colorButton(self.theme.font_footer_color)
|
||||
self.setFooterAreaPageValues()
|
||||
|
||||
@ -514,9 +531,9 @@ class ThemeForm(QtGui.QWizard, Ui_ThemeWizard):
|
||||
filename = os.path.split(unicode(self.theme.background_filename))[1]
|
||||
saveTo = os.path.join(self.path, self.theme.theme_name, filename)
|
||||
saveFrom = self.theme.background_filename
|
||||
if not self.edit_mode and not self.thememanager.checkIfThemeExists(self.theme.theme_name):
|
||||
if not self.edit_mode and not self.theme_manager.check_if_theme_exists(self.theme.theme_name):
|
||||
return
|
||||
self.thememanager.saveTheme(self.theme, saveFrom, saveTo)
|
||||
self.theme_manager.save_theme(self.theme, saveFrom, saveTo)
|
||||
return QtGui.QDialog.accept(self)
|
||||
|
||||
def _colorButton(self, field):
|
||||
@ -527,3 +544,23 @@ class ThemeForm(QtGui.QWizard, Ui_ThemeWizard):
|
||||
if new_color.isValid():
|
||||
field = new_color.name()
|
||||
return field
|
||||
|
||||
def _get_renderer(self):
|
||||
"""
|
||||
Adds the Renderer to the class dynamically
|
||||
"""
|
||||
if not hasattr(self, u'_renderer'):
|
||||
self._renderer = Registry().get(u'renderer')
|
||||
return self._renderer
|
||||
|
||||
renderer = property(_get_renderer)
|
||||
|
||||
def _get_theme_manager(self):
|
||||
"""
|
||||
Adds the theme manager to the class dynamically
|
||||
"""
|
||||
if not hasattr(self, u'_theme_manager'):
|
||||
self._theme_manager = Registry().get(u'theme_manager')
|
||||
return self._theme_manager
|
||||
|
||||
theme_manager = property(_get_theme_manager)
|
||||
|
@ -26,7 +26,9 @@
|
||||
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||
###############################################################################
|
||||
|
||||
"""
|
||||
The layout of the theme
|
||||
"""
|
||||
from PyQt4 import QtGui
|
||||
|
||||
from openlp.core.lib import translate
|
||||
@ -34,7 +36,13 @@ from openlp.core.lib.ui import create_button_box
|
||||
|
||||
|
||||
class Ui_ThemeLayoutDialog(object):
|
||||
"""
|
||||
The layout of the theme
|
||||
"""
|
||||
def setupUi(self, themeLayoutDialog):
|
||||
"""
|
||||
Set up the UI
|
||||
"""
|
||||
themeLayoutDialog.setObjectName(u'themeLayoutDialogDialog')
|
||||
#themeLayoutDialog.resize(300, 200)
|
||||
self.previewLayout = QtGui.QVBoxLayout(themeLayoutDialog)
|
||||
@ -63,7 +71,9 @@ class Ui_ThemeLayoutDialog(object):
|
||||
self.retranslateUi(themeLayoutDialog)
|
||||
|
||||
def retranslateUi(self, themeLayoutDialog):
|
||||
"""
|
||||
Translate the UI on the fly
|
||||
"""
|
||||
themeLayoutDialog.setWindowTitle(translate('OpenLP.StartTimeForm', 'Theme Layout'))
|
||||
self.mainColourLabel.setText(translate('OpenLP.StartTimeForm', 'The blue box shows the main area.'))
|
||||
self.footerColourLabel.setText(translate('OpenLP.StartTimeForm', 'The red box shows the footer.'))
|
||||
|
||||
|
@ -26,16 +26,22 @@
|
||||
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||
###############################################################################
|
||||
|
||||
"""
|
||||
The form layout
|
||||
"""
|
||||
from PyQt4 import QtGui, QtCore
|
||||
|
||||
from themelayoutdialog import Ui_ThemeLayoutDialog
|
||||
|
||||
|
||||
class ThemeLayoutForm(QtGui.QDialog, Ui_ThemeLayoutDialog):
|
||||
"""
|
||||
The exception dialog
|
||||
"""
|
||||
def __init__(self, parent):
|
||||
"""
|
||||
Constructor
|
||||
"""
|
||||
QtGui.QDialog.__init__(self, parent)
|
||||
self.setupUi(self)
|
||||
|
||||
@ -44,11 +50,7 @@ class ThemeLayoutForm(QtGui.QDialog, Ui_ThemeLayoutDialog):
|
||||
Run the Dialog with correct heading.
|
||||
"""
|
||||
pixmap = image.scaledToHeight(400, QtCore.Qt.SmoothTransformation)
|
||||
self.themeDisplayLabel.setPixmap(image)
|
||||
self.themeDisplayLabel.setPixmap(pixmap)
|
||||
displayAspectRatio = float(image.width()) / image.height()
|
||||
self.themeDisplayLabel.setFixedSize(400, 400 / displayAspectRatio )
|
||||
self.themeDisplayLabel.setFixedSize(400, 400 / displayAspectRatio)
|
||||
return QtGui.QDialog.exec_(self)
|
||||
|
||||
def accept(self):
|
||||
return QtGui.QDialog.accept(self)
|
||||
|
||||
|
@ -26,7 +26,9 @@
|
||||
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||
###############################################################################
|
||||
|
||||
"""
|
||||
The Theme Manager manages adding, deleteing and modifying of themes.
|
||||
"""
|
||||
import os
|
||||
import zipfile
|
||||
import shutil
|
||||
@ -36,9 +38,9 @@ import re
|
||||
from xml.etree.ElementTree import ElementTree, XML
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
from openlp.core.lib import OpenLPToolbar, get_text_file_string, build_icon, Receiver, SettingsManager, translate, \
|
||||
check_item_selected, check_directory_exists, create_thumb, validate_thumb, ImageSource, Settings, Registry, \
|
||||
UiStrings
|
||||
from openlp.core.lib import ImageSource, OpenLPToolbar, Receiver, Registry, SettingsManager, Settings, UiStrings, \
|
||||
get_text_file_string, build_icon, translate, check_item_selected, check_directory_exists, create_thumb, \
|
||||
validate_thumb
|
||||
from openlp.core.lib.theme import ThemeXML, BackgroundType, VerticalType, BackgroundGradientType
|
||||
from openlp.core.lib.ui import critical_error_message_box, create_widget_action
|
||||
from openlp.core.theme import Theme
|
||||
@ -47,11 +49,15 @@ from openlp.core.utils import AppLocation, delete_file, locale_compare, get_file
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class ThemeManager(QtGui.QWidget):
|
||||
"""
|
||||
Manages the orders of Theme.
|
||||
"""
|
||||
def __init__(self, parent=None):
|
||||
"""
|
||||
Constructor
|
||||
"""
|
||||
QtGui.QWidget.__init__(self, parent)
|
||||
Registry().register(u'theme_manager', self)
|
||||
self.settingsSection = u'themes'
|
||||
@ -72,67 +78,67 @@ class ThemeManager(QtGui.QWidget):
|
||||
text=translate('OpenLP.ThemeManager', 'Edit Theme'),
|
||||
icon=u':/themes/theme_edit.png',
|
||||
tooltip=translate('OpenLP.ThemeManager', 'Edit a theme.'),
|
||||
triggers=self.onEditTheme)
|
||||
self.deleteToolbarAction = self.toolbar.addToolbarAction(u'deleteTheme',
|
||||
triggers=self.on_edit_theme)
|
||||
self.deleteToolbarAction = self.toolbar.addToolbarAction(u'delete_theme',
|
||||
text=translate('OpenLP.ThemeManager', 'Delete Theme'),
|
||||
icon=u':/general/general_delete.png',
|
||||
tooltip=translate('OpenLP.ThemeManager', 'Delete a theme.'),
|
||||
triggers=self.onDeleteTheme)
|
||||
triggers=self.on_delete_theme)
|
||||
self.toolbar.addSeparator()
|
||||
self.toolbar.addToolbarAction(u'importTheme',
|
||||
text=translate('OpenLP.ThemeManager', 'Import Theme'),
|
||||
icon=u':/general/general_import.png',
|
||||
tooltip=translate('OpenLP.ThemeManager', 'Import a theme.'),
|
||||
triggers=self.onImportTheme)
|
||||
triggers=self.on_import_theme)
|
||||
self.toolbar.addToolbarAction(u'exportTheme',
|
||||
text=translate('OpenLP.ThemeManager', 'Export Theme'),
|
||||
icon=u':/general/general_export.png',
|
||||
tooltip=translate('OpenLP.ThemeManager', 'Export a theme.'),
|
||||
triggers=self.onExportTheme)
|
||||
triggers=self.on_export_theme)
|
||||
self.layout.addWidget(self.toolbar)
|
||||
self.themeWidget = QtGui.QWidgetAction(self.toolbar)
|
||||
self.themeWidget.setObjectName(u'themeWidget')
|
||||
self.theme_widget = QtGui.QWidgetAction(self.toolbar)
|
||||
self.theme_widget.setObjectName(u'theme_widget')
|
||||
# create theme manager list
|
||||
self.themeListWidget = QtGui.QListWidget(self)
|
||||
self.themeListWidget.setAlternatingRowColors(True)
|
||||
self.themeListWidget.setIconSize(QtCore.QSize(88, 50))
|
||||
self.themeListWidget.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
|
||||
self.themeListWidget.setObjectName(u'themeListWidget')
|
||||
self.layout.addWidget(self.themeListWidget)
|
||||
QtCore.QObject.connect(self.themeListWidget, QtCore.SIGNAL('customContextMenuRequested(QPoint)'),
|
||||
self.contextMenu)
|
||||
self.theme_list_widget = QtGui.QListWidget(self)
|
||||
self.theme_list_widget.setAlternatingRowColors(True)
|
||||
self.theme_list_widget.setIconSize(QtCore.QSize(88, 50))
|
||||
self.theme_list_widget.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
|
||||
self.theme_list_widget.setObjectName(u'theme_list_widget')
|
||||
self.layout.addWidget(self.theme_list_widget)
|
||||
QtCore.QObject.connect(self.theme_list_widget, QtCore.SIGNAL('customContextMenuRequested(QPoint)'),
|
||||
self.context_menu)
|
||||
# build the context menu
|
||||
self.menu = QtGui.QMenu()
|
||||
self.editAction = create_widget_action(self.menu,
|
||||
self.edit_action = create_widget_action(self.menu,
|
||||
text=translate('OpenLP.ThemeManager', '&Edit Theme'),
|
||||
icon=u':/themes/theme_edit.png', triggers=self.onEditTheme)
|
||||
self.copyAction = create_widget_action(self.menu,
|
||||
icon=u':/themes/theme_edit.png', triggers=self.on_edit_theme)
|
||||
self.copy_action = create_widget_action(self.menu,
|
||||
text=translate('OpenLP.ThemeManager', '&Copy Theme'),
|
||||
icon=u':/themes/theme_edit.png', triggers=self.onCopyTheme)
|
||||
self.renameAction = create_widget_action(self.menu,
|
||||
icon=u':/themes/theme_edit.png', triggers=self.on_copy_theme)
|
||||
self.rename_action = create_widget_action(self.menu,
|
||||
text=translate('OpenLP.ThemeManager', '&Rename Theme'),
|
||||
icon=u':/themes/theme_edit.png', triggers=self.onRenameTheme)
|
||||
self.deleteAction = create_widget_action(self.menu,
|
||||
icon=u':/themes/theme_edit.png', triggers=self.on_rename_theme)
|
||||
self.delete_action = create_widget_action(self.menu,
|
||||
text=translate('OpenLP.ThemeManager', '&Delete Theme'),
|
||||
icon=u':/general/general_delete.png', triggers=self.onDeleteTheme)
|
||||
icon=u':/general/general_delete.png', triggers=self.on_delete_theme)
|
||||
self.menu.addSeparator()
|
||||
self.globalAction = create_widget_action(self.menu,
|
||||
self.global_action = create_widget_action(self.menu,
|
||||
text=translate('OpenLP.ThemeManager', 'Set As &Global Default'),
|
||||
icon=u':/general/general_export.png',
|
||||
triggers=self.changeGlobalFromScreen)
|
||||
self.exportAction = create_widget_action(self.menu,
|
||||
text=translate('OpenLP.ThemeManager', '&Export Theme'),
|
||||
icon=u':/general/general_export.png', triggers=self.onExportTheme)
|
||||
icon=u':/general/general_export.png', triggers=self.on_export_theme)
|
||||
# Signals
|
||||
QtCore.QObject.connect(self.themeListWidget,
|
||||
QtCore.QObject.connect(self.theme_list_widget,
|
||||
QtCore.SIGNAL(u'doubleClicked(QModelIndex)'), self.changeGlobalFromScreen)
|
||||
QtCore.QObject.connect(self.themeListWidget,
|
||||
QtCore.SIGNAL(u'currentItemChanged(QListWidgetItem *, QListWidgetItem *)'), self.checkListState)
|
||||
QtCore.QObject.connect(self.theme_list_widget,
|
||||
QtCore.SIGNAL(u'currentItemChanged(QListWidgetItem *, QListWidgetItem *)'), self.check_list_state)
|
||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||
QtCore.SIGNAL(u'theme_update_global'), self.changeGlobalFromTab)
|
||||
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'config_updated'), self.configUpdated)
|
||||
QtCore.SIGNAL(u'theme_update_global'), self.change_global_from_tab)
|
||||
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'config_updated'), self.config_updated)
|
||||
# Variables
|
||||
self.themeList = []
|
||||
self.theme_list = []
|
||||
self.path = AppLocation.get_section_data_path(self.settingsSection)
|
||||
check_directory_exists(self.path)
|
||||
self.thumbPath = os.path.join(self.path, u'thumbnails')
|
||||
@ -141,27 +147,28 @@ class ThemeManager(QtGui.QWidget):
|
||||
self.oldBackgroundImage = None
|
||||
self.badV1NameChars = re.compile(r'[%+\[\]]')
|
||||
# Last little bits of setting up
|
||||
self.configUpdated()
|
||||
self.config_updated()
|
||||
|
||||
def firstTime(self):
|
||||
def first_time(self):
|
||||
"""
|
||||
Import new themes downloaded by the first time wizard
|
||||
"""
|
||||
Receiver.send_message(u'cursor_busy')
|
||||
self.application.set_busy_cursor()
|
||||
files = SettingsManager.get_files(self.settingsSection, u'.otz')
|
||||
for file in files:
|
||||
file = os.path.join(self.path, file)
|
||||
self.unzipTheme(file, self.path)
|
||||
delete_file(file)
|
||||
Receiver.send_message(u'cursor_normal')
|
||||
for theme_file in files:
|
||||
theme_file = os.path.join(self.path, theme_file)
|
||||
self.unzip_theme(theme_file, self.path)
|
||||
delete_file(theme_file)
|
||||
self.application.set_normal_cursor()
|
||||
|
||||
def configUpdated(self):
|
||||
|
||||
def config_updated(self):
|
||||
"""
|
||||
Triggered when Config dialog is updated.
|
||||
"""
|
||||
self.global_theme = Settings().value(self.settingsSection + u'/global theme')
|
||||
|
||||
def checkListState(self, item):
|
||||
def check_list_state(self, item):
|
||||
"""
|
||||
If Default theme selected remove delete button.
|
||||
"""
|
||||
@ -175,41 +182,41 @@ class ThemeManager(QtGui.QWidget):
|
||||
else:
|
||||
self.deleteToolbarAction.setVisible(False)
|
||||
|
||||
def contextMenu(self, point):
|
||||
def context_menu(self, point):
|
||||
"""
|
||||
Build the Right Click Context menu and set state depending on
|
||||
the type of theme.
|
||||
"""
|
||||
item = self.themeListWidget.itemAt(point)
|
||||
item = self.theme_list_widget.itemAt(point)
|
||||
if item is None:
|
||||
return
|
||||
real_theme_name = item.data(QtCore.Qt.UserRole)
|
||||
theme_name = unicode(item.text())
|
||||
visible = real_theme_name == theme_name
|
||||
self.deleteAction.setVisible(visible)
|
||||
self.renameAction.setVisible(visible)
|
||||
self.globalAction.setVisible(visible)
|
||||
self.menu.exec_(self.themeListWidget.mapToGlobal(point))
|
||||
self.delete_action.setVisible(visible)
|
||||
self.rename_action.setVisible(visible)
|
||||
self.global_action.setVisible(visible)
|
||||
self.menu.exec_(self.theme_list_widget.mapToGlobal(point))
|
||||
|
||||
def changeGlobalFromTab(self, theme_name):
|
||||
def change_global_from_tab(self, theme_name):
|
||||
"""
|
||||
Change the global theme when it is changed through the Themes settings
|
||||
tab
|
||||
"""
|
||||
log.debug(u'changeGlobalFromTab %s', theme_name)
|
||||
for count in range (0, self.themeListWidget.count()):
|
||||
log.debug(u'change_global_from_tab %s', theme_name)
|
||||
for count in range(0, self.theme_list_widget.count()):
|
||||
# reset the old name
|
||||
item = self.themeListWidget.item(count)
|
||||
item = self.theme_list_widget.item(count)
|
||||
old_name = item.text()
|
||||
new_name = item.data(QtCore.Qt.UserRole)
|
||||
if old_name != new_name:
|
||||
self.themeListWidget.item(count).setText(new_name)
|
||||
self.theme_list_widget.item(count).setText(new_name)
|
||||
# Set the new name
|
||||
if theme_name == new_name:
|
||||
name = translate('OpenLP.ThemeManager', '%s (default)') % new_name
|
||||
self.themeListWidget.item(count).setText(name)
|
||||
self.theme_list_widget.item(count).setText(name)
|
||||
self.deleteToolbarAction.setVisible(
|
||||
item not in self.themeListWidget.selectedItems())
|
||||
item not in self.theme_list_widget.selectedItems())
|
||||
|
||||
def changeGlobalFromScreen(self, index=-1):
|
||||
"""
|
||||
@ -217,21 +224,21 @@ class ThemeManager(QtGui.QWidget):
|
||||
Theme Manager list
|
||||
"""
|
||||
log.debug(u'changeGlobalFromScreen %s', index)
|
||||
selected_row = self.themeListWidget.currentRow()
|
||||
for count in range (0, self.themeListWidget.count()):
|
||||
item = self.themeListWidget.item(count)
|
||||
selected_row = self.theme_list_widget.currentRow()
|
||||
for count in range(0, self.theme_list_widget.count()):
|
||||
item = self.theme_list_widget.item(count)
|
||||
old_name = item.text()
|
||||
# reset the old name
|
||||
if old_name != item.data(QtCore.Qt.UserRole):
|
||||
self.themeListWidget.item(count).setText(item.data(QtCore.Qt.UserRole))
|
||||
self.theme_list_widget.item(count).setText(item.data(QtCore.Qt.UserRole))
|
||||
# Set the new name
|
||||
if count == selected_row:
|
||||
self.global_theme = self.themeListWidget.item(count).text()
|
||||
self.global_theme = self.theme_list_widget.item(count).text()
|
||||
name = translate('OpenLP.ThemeManager', '%s (default)') % self.global_theme
|
||||
self.themeListWidget.item(count).setText(name)
|
||||
self.theme_list_widget.item(count).setText(name)
|
||||
Settings().setValue(self.settingsSection + u'/global theme', self.global_theme)
|
||||
Receiver.send_message(u'theme_update_global', self.global_theme)
|
||||
self._pushThemes()
|
||||
self._push_themes()
|
||||
|
||||
def onAddTheme(self):
|
||||
"""
|
||||
@ -242,44 +249,44 @@ class ThemeManager(QtGui.QWidget):
|
||||
theme.set_default_header_footer()
|
||||
self.themeForm.theme = theme
|
||||
self.themeForm.exec_()
|
||||
self.loadThemes()
|
||||
self.load_themes()
|
||||
|
||||
def onRenameTheme(self):
|
||||
def on_rename_theme(self):
|
||||
"""
|
||||
Renames an existing theme to a new name
|
||||
"""
|
||||
if self._validate_theme_action(translate('OpenLP.ThemeManager', 'You must select a theme to rename.'),
|
||||
translate('OpenLP.ThemeManager', 'Rename Confirmation'),
|
||||
translate('OpenLP.ThemeManager', 'Rename %s theme?'), False, False):
|
||||
item = self.themeListWidget.currentItem()
|
||||
item = self.theme_list_widget.currentItem()
|
||||
old_theme_name = item.data(QtCore.Qt.UserRole)
|
||||
self.fileRenameForm.fileNameEdit.setText(old_theme_name)
|
||||
if self.fileRenameForm.exec_():
|
||||
new_theme_name = self.fileRenameForm.fileNameEdit.text()
|
||||
if old_theme_name == new_theme_name:
|
||||
return
|
||||
if self.checkIfThemeExists(new_theme_name):
|
||||
old_theme_data = self.getThemeData(old_theme_name)
|
||||
if self.check_if_theme_exists(new_theme_name):
|
||||
old_theme_data = self.get_theme_data(old_theme_name)
|
||||
self.cloneThemeData(old_theme_data, new_theme_name)
|
||||
self.deleteTheme(old_theme_name)
|
||||
self.delete_theme(old_theme_name)
|
||||
for plugin in self.plugin_manager.plugins:
|
||||
if plugin.usesTheme(old_theme_name):
|
||||
plugin.renameTheme(old_theme_name, new_theme_name)
|
||||
self.renderer.update_theme(new_theme_name, old_theme_name)
|
||||
self.loadThemes()
|
||||
self.load_themes()
|
||||
|
||||
def onCopyTheme(self):
|
||||
def on_copy_theme(self):
|
||||
"""
|
||||
Copies an existing theme to a new name
|
||||
"""
|
||||
item = self.themeListWidget.currentItem()
|
||||
item = self.theme_list_widget.currentItem()
|
||||
old_theme_name = item.data(QtCore.Qt.UserRole)
|
||||
self.fileRenameForm.fileNameEdit.setText(translate('OpenLP.ThemeManager',
|
||||
'Copy of %s', 'Copy of <theme name>') % old_theme_name)
|
||||
if self.fileRenameForm.exec_(True):
|
||||
new_theme_name = self.fileRenameForm.fileNameEdit.text()
|
||||
if self.checkIfThemeExists(new_theme_name):
|
||||
theme_data = self.getThemeData(old_theme_name)
|
||||
if self.check_if_theme_exists(new_theme_name):
|
||||
theme_data = self.get_theme_data(old_theme_name)
|
||||
self.cloneThemeData(theme_data, new_theme_name)
|
||||
|
||||
def cloneThemeData(self, theme_data, new_theme_name):
|
||||
@ -295,65 +302,65 @@ class ThemeManager(QtGui.QWidget):
|
||||
save_from = theme_data.background_filename
|
||||
theme_data.theme_name = new_theme_name
|
||||
theme_data.extend_image_filename(self.path)
|
||||
self.saveTheme(theme_data, save_from, save_to)
|
||||
self.loadThemes()
|
||||
self.save_theme(theme_data, save_from, save_to)
|
||||
self.load_themes()
|
||||
|
||||
def onEditTheme(self):
|
||||
def on_edit_theme(self):
|
||||
"""
|
||||
Loads the settings for the theme that is to be edited and launches the
|
||||
theme editing form so the user can make their changes.
|
||||
"""
|
||||
if check_item_selected(self.themeListWidget,
|
||||
if check_item_selected(self.theme_list_widget,
|
||||
translate('OpenLP.ThemeManager', 'You must select a theme to edit.')):
|
||||
item = self.themeListWidget.currentItem()
|
||||
theme = self.getThemeData(item.data(QtCore.Qt.UserRole))
|
||||
item = self.theme_list_widget.currentItem()
|
||||
theme = self.get_theme_data(item.data(QtCore.Qt.UserRole))
|
||||
if theme.background_type == u'image':
|
||||
self.oldBackgroundImage = theme.background_filename
|
||||
self.themeForm.theme = theme
|
||||
self.themeForm.exec_(True)
|
||||
self.oldBackgroundImage = None
|
||||
self.renderer.update_theme(theme.theme_name)
|
||||
self.loadThemes()
|
||||
self.load_themes()
|
||||
|
||||
def onDeleteTheme(self):
|
||||
def on_delete_theme(self):
|
||||
"""
|
||||
Delete a theme
|
||||
"""
|
||||
if self._validate_theme_action(translate('OpenLP.ThemeManager', 'You must select a theme to delete.'),
|
||||
translate('OpenLP.ThemeManager', 'Delete Confirmation'),
|
||||
translate('OpenLP.ThemeManager', 'Delete %s theme?')):
|
||||
item = self.themeListWidget.currentItem()
|
||||
item = self.theme_list_widget.currentItem()
|
||||
theme = item.text()
|
||||
row = self.themeListWidget.row(item)
|
||||
self.themeListWidget.takeItem(row)
|
||||
self.deleteTheme(theme)
|
||||
row = self.theme_list_widget.row(item)
|
||||
self.theme_list_widget.takeItem(row)
|
||||
self.delete_theme(theme)
|
||||
self.renderer.update_theme(theme, only_delete=True)
|
||||
# As we do not reload the themes, push out the change. Reload the
|
||||
# list as the internal lists and events need to be triggered.
|
||||
self._pushThemes()
|
||||
self._push_themes()
|
||||
|
||||
def deleteTheme(self, theme):
|
||||
def delete_theme(self, theme):
|
||||
"""
|
||||
Delete a theme.
|
||||
|
||||
``theme``
|
||||
The theme to delete.
|
||||
"""
|
||||
self.themeList.remove(theme)
|
||||
self.theme_list.remove(theme)
|
||||
thumb = u'%s.png' % theme
|
||||
delete_file(os.path.join(self.path, thumb))
|
||||
delete_file(os.path.join(self.thumbPath, thumb))
|
||||
try:
|
||||
encoding = get_filesystem_encoding()
|
||||
shutil.rmtree(os.path.join(self.path, theme).encode(encoding))
|
||||
except OSError:
|
||||
except OSError, shutil.Error:
|
||||
log.exception(u'Error deleting theme %s', theme)
|
||||
|
||||
def onExportTheme(self):
|
||||
def on_export_theme(self):
|
||||
"""
|
||||
Export the theme in a zip file
|
||||
"""
|
||||
item = self.themeListWidget.currentItem()
|
||||
item = self.theme_list_widget.currentItem()
|
||||
if item is None:
|
||||
critical_error_message_box(message=translate('OpenLP.ThemeManager', 'You have not selected a theme.'))
|
||||
return
|
||||
@ -361,34 +368,34 @@ class ThemeManager(QtGui.QWidget):
|
||||
path = QtGui.QFileDialog.getExistingDirectory(self,
|
||||
translate('OpenLP.ThemeManager', 'Save Theme - (%s)') % theme,
|
||||
Settings().value(self.settingsSection + u'/last directory export'))
|
||||
Receiver.send_message(u'cursor_busy')
|
||||
self.application.set_busy_cursor()
|
||||
if path:
|
||||
Settings().setValue(self.settingsSection + u'/last directory export', path)
|
||||
theme_path = os.path.join(path, theme + u'.otz')
|
||||
# FIXME: Do not overwrite build-in.
|
||||
zip = None
|
||||
theme_zip = None
|
||||
try:
|
||||
zip = zipfile.ZipFile(theme_path, u'w')
|
||||
theme_zip = zipfile.ZipFile(theme_path, u'w')
|
||||
source = os.path.join(self.path, theme)
|
||||
for files in os.walk(source):
|
||||
for name in files[2]:
|
||||
zip.write(
|
||||
theme_zip.write(
|
||||
os.path.join(source, name).encode(u'utf-8'),
|
||||
os.path.join(theme, name).encode(u'utf-8'))
|
||||
os.path.join(theme, name).encode(u'utf-8')
|
||||
)
|
||||
QtGui.QMessageBox.information(self,
|
||||
translate('OpenLP.ThemeManager', 'Theme Exported'),
|
||||
translate('OpenLP.ThemeManager', 'Your theme has been successfully exported.'))
|
||||
except (IOError, OSError):
|
||||
log.exception(u'Export Theme Failed')
|
||||
critical_error_message_box(
|
||||
translate('OpenLP.ThemeManager', 'Theme Export Failed'),
|
||||
critical_error_message_box(translate('OpenLP.ThemeManager', 'Theme Export Failed'),
|
||||
translate('OpenLP.ThemeManager', 'Your theme could not be exported due to an error.'))
|
||||
finally:
|
||||
if zip:
|
||||
zip.close()
|
||||
Receiver.send_message(u'cursor_normal')
|
||||
if theme_zip:
|
||||
theme_zip.close()
|
||||
self.application.set_normal_cursor()
|
||||
|
||||
def onImportTheme(self):
|
||||
|
||||
def on_import_theme(self):
|
||||
"""
|
||||
Opens a file dialog to select the theme file(s) to import before
|
||||
attempting to extract OpenLP themes from those files. This process
|
||||
@ -401,37 +408,36 @@ class ThemeManager(QtGui.QWidget):
|
||||
log.info(u'New Themes %s', unicode(files))
|
||||
if not files:
|
||||
return
|
||||
Receiver.send_message(u'cursor_busy')
|
||||
for file in files:
|
||||
Settings().setValue(self.settingsSection + u'/last directory import', unicode(file))
|
||||
self.unzipTheme(file, self.path)
|
||||
self.loadThemes()
|
||||
Receiver.send_message(u'cursor_normal')
|
||||
self.application.set_busy_cursor()
|
||||
for file_name in files:
|
||||
Settings().setValue(self.settingsSection + u'/last directory import', unicode(file_name))
|
||||
self.unzip_theme(file_name, self.path)
|
||||
self.load_themes()
|
||||
self.application.set_normal_cursor()
|
||||
|
||||
def loadThemes(self, firstTime=False):
|
||||
def load_themes(self, first_time=False):
|
||||
"""
|
||||
Loads the theme lists and triggers updates accross the whole system
|
||||
using direct calls or core functions and events for the plugins.
|
||||
The plugins will call back in to get the real list if they want it.
|
||||
"""
|
||||
log.debug(u'Load themes from dir')
|
||||
self.themeList = []
|
||||
self.themeListWidget.clear()
|
||||
self.theme_list = []
|
||||
self.theme_list_widget.clear()
|
||||
files = SettingsManager.get_files(self.settingsSection, u'.png')
|
||||
if firstTime:
|
||||
self.firstTime()
|
||||
if first_time:
|
||||
self.first_time()
|
||||
files = SettingsManager.get_files(self.settingsSection, u'.png')
|
||||
# No themes have been found so create one
|
||||
if not files:
|
||||
theme = ThemeXML()
|
||||
theme.theme_name = UiStrings().Default
|
||||
self._writeTheme(theme, None, None)
|
||||
self._write_theme(theme, None, None)
|
||||
Settings().setValue(self.settingsSection + u'/global theme', theme.theme_name)
|
||||
self.configUpdated()
|
||||
self.config_updated()
|
||||
files = SettingsManager.get_files(self.settingsSection, u'.png')
|
||||
# Sort the themes by its name considering language specific
|
||||
files.sort(key=lambda file_name: unicode(file_name),
|
||||
cmp=locale_compare)
|
||||
files.sort(key=lambda file_name: unicode(file_name), cmp=locale_compare)
|
||||
# now process the file list of png files
|
||||
for name in files:
|
||||
# check to see file is in theme root directory
|
||||
@ -450,23 +456,23 @@ class ThemeManager(QtGui.QWidget):
|
||||
icon = create_thumb(theme, thumb)
|
||||
item_name.setIcon(icon)
|
||||
item_name.setData(QtCore.Qt.UserRole, text_name)
|
||||
self.themeListWidget.addItem(item_name)
|
||||
self.themeList.append(text_name)
|
||||
self._pushThemes()
|
||||
self.theme_list_widget.addItem(item_name)
|
||||
self.theme_list.append(text_name)
|
||||
self._push_themes()
|
||||
|
||||
def _pushThemes(self):
|
||||
def _push_themes(self):
|
||||
"""
|
||||
Notify listeners that the theme list has been updated
|
||||
"""
|
||||
Receiver.send_message(u'theme_update_list', self.getThemes())
|
||||
Receiver.send_message(u'theme_update_list', self.get_themes())
|
||||
|
||||
def getThemes(self):
|
||||
def get_themes(self):
|
||||
"""
|
||||
Return the list of loaded themes
|
||||
"""
|
||||
return self.themeList
|
||||
return self.theme_list
|
||||
|
||||
def getThemeData(self, theme_name):
|
||||
def get_theme_data(self, theme_name):
|
||||
"""
|
||||
Returns a theme object from an XML file
|
||||
|
||||
@ -480,18 +486,20 @@ class ThemeManager(QtGui.QWidget):
|
||||
log.debug(u'No theme data - using default theme')
|
||||
return ThemeXML()
|
||||
else:
|
||||
return self._createThemeFromXml(xml, self.path)
|
||||
return self._create_theme_fom_Xml(xml, self.path)
|
||||
|
||||
def overWriteMessageBox(self, theme_name):
|
||||
ret = QtGui.QMessageBox.question(self,
|
||||
translate('OpenLP.ThemeManager', 'Theme Already Exists'),
|
||||
def over_write_message_box(self, theme_name):
|
||||
"""
|
||||
Display a warning box to the user that a theme already exists
|
||||
"""
|
||||
ret = QtGui.QMessageBox.question(self, translate('OpenLP.ThemeManager', 'Theme Already Exists'),
|
||||
translate('OpenLP.ThemeManager',
|
||||
'Theme %s already exists. Do you want to replace it?').replace('%s', theme_name),
|
||||
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Yes | QtGui.QMessageBox.No),
|
||||
QtGui.QMessageBox.No)
|
||||
return ret == QtGui.QMessageBox.Yes
|
||||
|
||||
def unzipTheme(self, file_name, dir):
|
||||
def unzip_theme(self, file_name, directory):
|
||||
"""
|
||||
Unzip the theme, remove the preview file if stored
|
||||
Generate a new preview file. Check the XML theme version and upgrade if
|
||||
@ -499,32 +507,31 @@ class ThemeManager(QtGui.QWidget):
|
||||
"""
|
||||
log.debug(u'Unzipping theme %s', file_name)
|
||||
file_name = unicode(file_name)
|
||||
zip = None
|
||||
theme_zip = None
|
||||
out_file = None
|
||||
file_xml = None
|
||||
abort_import = True
|
||||
try:
|
||||
zip = zipfile.ZipFile(file_name)
|
||||
xml_file = filter(lambda name:
|
||||
os.path.splitext(name)[1].lower() == u'.xml', zip.namelist())
|
||||
theme_zip = zipfile.ZipFile(file_name)
|
||||
xml_file = filter(lambda name: os.path.splitext(name)[1].lower() == u'.xml', theme_zip.namelist())
|
||||
if len(xml_file) != 1:
|
||||
log.exception(u'Theme contains "%s" XML files' % len(xml_file))
|
||||
raise Exception(u'validation')
|
||||
xml_tree = ElementTree(element=XML(zip.read(xml_file[0]))).getroot()
|
||||
raise Exception('validation')
|
||||
xml_tree = ElementTree(element=XML(theme_zip.read(xml_file[0]))).getroot()
|
||||
v1_background = xml_tree.find(u'BackgroundType')
|
||||
if v1_background is not None:
|
||||
theme_name, file_xml, out_file, abort_import = self.unzipVersion122(
|
||||
dir, zip, xml_file[0], xml_tree, v1_background, out_file)
|
||||
theme_name, file_xml, out_file, abort_import = self.unzip_version_122(
|
||||
directory, theme_zip, xml_file[0], xml_tree, v1_background, out_file)
|
||||
else:
|
||||
theme_name = xml_tree.find(u'name').text.strip()
|
||||
theme_folder = os.path.join(dir, theme_name)
|
||||
theme_folder = os.path.join(directory, theme_name)
|
||||
theme_exists = os.path.exists(theme_folder)
|
||||
if theme_exists and not self.overWriteMessageBox(theme_name):
|
||||
if theme_exists and not self.over_write_message_box(theme_name):
|
||||
abort_import = True
|
||||
return
|
||||
else:
|
||||
abort_import = False
|
||||
for name in zip.namelist():
|
||||
for name in theme_zip.namelist():
|
||||
try:
|
||||
uname = unicode(name, u'utf-8')
|
||||
except UnicodeDecodeError:
|
||||
@ -536,15 +543,15 @@ class ThemeManager(QtGui.QWidget):
|
||||
if split_name[-1] == u'' or len(split_name) == 1:
|
||||
# is directory or preview file
|
||||
continue
|
||||
full_name = os.path.join(dir, uname)
|
||||
full_name = os.path.join(directory, uname)
|
||||
check_directory_exists(os.path.dirname(full_name))
|
||||
if os.path.splitext(uname)[1].lower() == u'.xml':
|
||||
file_xml = unicode(zip.read(name), u'utf-8')
|
||||
file_xml = unicode(theme_zip.read(name), u'utf-8')
|
||||
out_file = open(full_name, u'w')
|
||||
out_file.write(file_xml.encode(u'utf-8'))
|
||||
else:
|
||||
out_file = open(full_name, u'wb')
|
||||
out_file.write(zip.read(name))
|
||||
out_file.write(theme_zip.read(name))
|
||||
out_file.close()
|
||||
except (IOError, zipfile.BadZipfile):
|
||||
log.exception(u'Importing theme from zip failed %s' % file_name)
|
||||
@ -557,39 +564,38 @@ class ThemeManager(QtGui.QWidget):
|
||||
raise
|
||||
finally:
|
||||
# Close the files, to be able to continue creating the theme.
|
||||
if zip:
|
||||
zip.close()
|
||||
if theme_zip:
|
||||
theme_zip.close()
|
||||
if out_file:
|
||||
out_file.close()
|
||||
if not abort_import:
|
||||
# As all files are closed, we can create the Theme.
|
||||
if file_xml:
|
||||
theme = self._createThemeFromXml(file_xml, self.path)
|
||||
self.generateAndSaveImage(dir, theme_name, theme)
|
||||
theme = self._create_theme_fom_Xml(file_xml, self.path)
|
||||
self.generate_and_save_image(directory, theme_name, theme)
|
||||
# Only show the error message, when IOError was not raised (in
|
||||
# this case the error message has already been shown).
|
||||
elif zip is not None:
|
||||
elif theme_zip is not None:
|
||||
critical_error_message_box(
|
||||
translate('OpenLP.ThemeManager', 'Validation Error'),
|
||||
translate('OpenLP.ThemeManager', 'File is not a valid theme.'))
|
||||
log.exception(u'Theme file does not contain XML data %s' % file_name)
|
||||
|
||||
def unzipVersion122(self, dir, zip, xml_file, xml_tree, background,
|
||||
out_file):
|
||||
def unzip_version_122(self, dir_name, zip_file, xml_file, xml_tree, background, out_file):
|
||||
"""
|
||||
Unzip openlp.org 1.2x theme file and upgrade the theme xml. When calling
|
||||
this method, please keep in mind, that some parameters are redundant.
|
||||
"""
|
||||
theme_name = xml_tree.find(u'Name').text.strip()
|
||||
theme_name = self.badV1NameChars.sub(u'', theme_name)
|
||||
theme_folder = os.path.join(dir, theme_name)
|
||||
theme_folder = os.path.join(dir_name, theme_name)
|
||||
theme_exists = os.path.exists(theme_folder)
|
||||
if theme_exists and not self.overWriteMessageBox(theme_name):
|
||||
if theme_exists and not self.over_write_message_box(theme_name):
|
||||
return '', '', '', True
|
||||
themedir = os.path.join(dir, theme_name)
|
||||
themedir = os.path.join(dir_name, theme_name)
|
||||
check_directory_exists(themedir)
|
||||
file_xml = unicode(zip.read(xml_file), u'utf-8')
|
||||
file_xml = self._migrateVersion122(file_xml)
|
||||
file_xml = unicode(zip_file.read(xml_file), u'utf-8')
|
||||
file_xml = self._migrate_version_122(file_xml)
|
||||
out_file = open(os.path.join(themedir, theme_name + u'.xml'), u'w')
|
||||
out_file.write(file_xml.encode(u'utf-8'))
|
||||
out_file.close()
|
||||
@ -597,18 +603,17 @@ class ThemeManager(QtGui.QWidget):
|
||||
image_name = xml_tree.find(u'BackgroundParameter1').text.strip()
|
||||
# image file has same extension and is in subfolder
|
||||
image_file = filter(lambda name: os.path.splitext(name)[1].lower()
|
||||
== os.path.splitext(image_name)[1].lower() and name.find(r'/'),
|
||||
zip.namelist())
|
||||
== os.path.splitext(image_name)[1].lower() and name.find(r'/'), zip_file.namelist())
|
||||
if len(image_file) >= 1:
|
||||
out_file = open(os.path.join(themedir, image_name), u'wb')
|
||||
out_file.write(zip.read(image_file[0]))
|
||||
out_file.write(zip_file.read(image_file[0]))
|
||||
out_file.close()
|
||||
else:
|
||||
log.exception(u'Theme file does not contain image file "%s"' % image_name.decode(u'utf-8', u'replace'))
|
||||
raise Exception(u'validation')
|
||||
return theme_name, file_xml, out_file, False
|
||||
|
||||
def checkIfThemeExists(self, theme_name):
|
||||
def check_if_theme_exists(self, theme_name):
|
||||
"""
|
||||
Check if theme already exists and displays error message
|
||||
|
||||
@ -623,25 +628,25 @@ class ThemeManager(QtGui.QWidget):
|
||||
return False
|
||||
return True
|
||||
|
||||
def saveTheme(self, theme, image_from, image_to):
|
||||
def save_theme(self, theme, image_from, image_to):
|
||||
"""
|
||||
Called by thememaintenance Dialog to save the theme
|
||||
and to trigger the reload of the theme list
|
||||
"""
|
||||
self._writeTheme(theme, image_from, image_to)
|
||||
self._write_theme(theme, image_from, image_to)
|
||||
if theme.background_type == BackgroundType.to_string(BackgroundType.Image):
|
||||
self.image_manager.updateImageBorder(theme.background_filename,
|
||||
self.image_manager.update_image_border(theme.background_filename,
|
||||
ImageSource.Theme, QtGui.QColor(theme.background_border_color))
|
||||
self.image_manager.processUpdates()
|
||||
self.image_manager.process_updates()
|
||||
|
||||
def _writeTheme(self, theme, image_from, image_to):
|
||||
def _write_theme(self, theme, image_from, image_to):
|
||||
"""
|
||||
Writes the theme to the disk and handles the background image if
|
||||
necessary
|
||||
"""
|
||||
name = theme.theme_name
|
||||
theme_pretty_xml = theme.extract_formatted_xml()
|
||||
log.debug(u'saveTheme %s %s', name, theme_pretty_xml.decode(u'utf-8'))
|
||||
log.debug(u'save_theme %s %s', name, theme_pretty_xml.decode(u'utf-8'))
|
||||
theme_dir = os.path.join(self.path, name)
|
||||
check_directory_exists(theme_dir)
|
||||
theme_file = os.path.join(theme_dir, name + u'.xml')
|
||||
@ -660,13 +665,16 @@ class ThemeManager(QtGui.QWidget):
|
||||
try:
|
||||
encoding = get_filesystem_encoding()
|
||||
shutil.copyfile(unicode(image_from).encode(encoding), unicode(image_to).encode(encoding))
|
||||
except IOError:
|
||||
except IOError, shutil.Error:
|
||||
log.exception(u'Failed to save theme image')
|
||||
self.generateAndSaveImage(self.path, name, theme)
|
||||
self.generate_and_save_image(self.path, name, theme)
|
||||
|
||||
def generateAndSaveImage(self, dir, name, theme):
|
||||
log.debug(u'generateAndSaveImage %s %s', dir, name)
|
||||
frame = self.generateImage(theme)
|
||||
def generate_and_save_image(self, directory, name, theme):
|
||||
"""
|
||||
Generate and save a preview image
|
||||
"""
|
||||
log.debug(u'generate_and_save_image %s %s', directory, name)
|
||||
frame = self.generate_image(theme)
|
||||
sample_path_name = os.path.join(self.path, name + u'.png')
|
||||
if os.path.exists(sample_path_name):
|
||||
os.unlink(sample_path_name)
|
||||
@ -675,18 +683,18 @@ class ThemeManager(QtGui.QWidget):
|
||||
create_thumb(sample_path_name, thumb, False)
|
||||
log.debug(u'Theme image written to %s', sample_path_name)
|
||||
|
||||
def updatePreviewImages(self):
|
||||
def update_preview_images(self):
|
||||
"""
|
||||
Called to update the themes' preview images.
|
||||
"""
|
||||
self.main_window.displayProgressBar(len(self.themeList))
|
||||
for theme in self.themeList:
|
||||
self.main_window.displayProgressBar(len(self.theme_list))
|
||||
for theme in self.theme_list:
|
||||
self.main_window.incrementProgressBar()
|
||||
self.generateAndSaveImage(self.path, theme, self.getThemeData(theme))
|
||||
self.generate_and_save_image(self.path, theme, self.get_theme_data(theme))
|
||||
self.main_window.finishedProgressBar()
|
||||
self.loadThemes()
|
||||
self.load_themes()
|
||||
|
||||
def generateImage(self, theme_data, forcePage=False):
|
||||
def generate_image(self, theme_data, forcePage=False):
|
||||
"""
|
||||
Call the renderer to build a Sample Image
|
||||
|
||||
@ -696,21 +704,21 @@ class ThemeManager(QtGui.QWidget):
|
||||
``forcePage``
|
||||
Flag to tell message lines per page need to be generated.
|
||||
"""
|
||||
log.debug(u'generateImage \n%s ', theme_data)
|
||||
log.debug(u'generate_image \n%s ', theme_data)
|
||||
return self.renderer.generate_preview(theme_data, forcePage)
|
||||
|
||||
def getPreviewImage(self, theme):
|
||||
def get_preview_image(self, theme):
|
||||
"""
|
||||
Return an image representing the look of the theme
|
||||
|
||||
``theme``
|
||||
The theme to return the image for
|
||||
"""
|
||||
log.debug(u'getPreviewImage %s ', theme)
|
||||
log.debug(u'get_preview_image %s ', theme)
|
||||
image = os.path.join(self.path, theme + u'.png')
|
||||
return image
|
||||
|
||||
def _createThemeFromXml(self, theme_xml, path):
|
||||
def _create_theme_fom_Xml(self, theme_xml, path):
|
||||
"""
|
||||
Return a theme object using information parsed from XML
|
||||
|
||||
@ -722,15 +730,14 @@ class ThemeManager(QtGui.QWidget):
|
||||
theme.extend_image_filename(path)
|
||||
return theme
|
||||
|
||||
def _validate_theme_action(self, select_text, confirm_title, confirm_text,
|
||||
testPlugin=True, confirm=True):
|
||||
def _validate_theme_action(self, select_text, confirm_title, confirm_text, testPlugin=True, confirm=True):
|
||||
"""
|
||||
Check to see if theme has been selected and the destructive action
|
||||
is allowed.
|
||||
"""
|
||||
self.global_theme = Settings().value(self.settingsSection + u'/global theme')
|
||||
if check_item_selected(self.themeListWidget, select_text):
|
||||
item = self.themeListWidget.currentItem()
|
||||
if check_item_selected(self.theme_list_widget, select_text):
|
||||
item = self.theme_list_widget.currentItem()
|
||||
theme = item.text()
|
||||
# confirm deletion
|
||||
if confirm:
|
||||
@ -755,7 +762,7 @@ class ThemeManager(QtGui.QWidget):
|
||||
return True
|
||||
return False
|
||||
|
||||
def _migrateVersion122(self, xml_data):
|
||||
def _migrate_version_122(self, xml_data):
|
||||
"""
|
||||
Convert the xml data from version 1 format to the current format.
|
||||
|
||||
@ -843,3 +850,13 @@ class ThemeManager(QtGui.QWidget):
|
||||
return self._main_window
|
||||
|
||||
main_window = property(_get_main_window)
|
||||
|
||||
def _get_application(self):
|
||||
"""
|
||||
Adds the openlp to the class dynamically
|
||||
"""
|
||||
if not hasattr(self, u'_application'):
|
||||
self._application = Registry().get(u'application')
|
||||
return self._application
|
||||
|
||||
application = property(_get_application)
|
||||
|
@ -26,10 +26,12 @@
|
||||
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||
###############################################################################
|
||||
|
||||
"""
|
||||
The Themes configuration tab
|
||||
"""
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
from openlp.core.lib import Receiver, Settings, SettingsTab, translate, UiStrings
|
||||
from openlp.core.lib import Receiver, Settings, SettingsTab, UiStrings, translate
|
||||
from openlp.core.lib.theme import ThemeLevel
|
||||
from openlp.core.lib.ui import find_and_set_in_combo_box
|
||||
|
||||
@ -38,13 +40,18 @@ class ThemesTab(SettingsTab):
|
||||
"""
|
||||
ThemesTab is the theme settings tab in the settings dialog.
|
||||
"""
|
||||
def __init__(self, parent, mainwindow):
|
||||
self.mainwindow = mainwindow
|
||||
def __init__(self, parent):
|
||||
"""
|
||||
Constructor
|
||||
"""
|
||||
generalTranslated = translate('OpenLP.ThemesTab', 'Themes')
|
||||
SettingsTab.__init__(self, parent, u'Themes', generalTranslated)
|
||||
self.iconPath = u':/themes/theme_new.png'
|
||||
|
||||
def setupUi(self):
|
||||
"""
|
||||
Set up the UI
|
||||
"""
|
||||
self.setObjectName(u'ThemesTab')
|
||||
SettingsTab.setupUi(self)
|
||||
self.GlobalGroupBox = QtGui.QGroupBox(self.leftColumn)
|
||||
@ -100,6 +107,9 @@ class ThemesTab(SettingsTab):
|
||||
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'theme_update_list'), self.updateThemeList)
|
||||
|
||||
def retranslateUi(self):
|
||||
"""
|
||||
Translate the UI on the fly
|
||||
"""
|
||||
self.tabTitleVisible = UiStrings().Themes
|
||||
self.GlobalGroupBox.setTitle(translate('OpenLP.ThemesTab', 'Global Theme'))
|
||||
self.LevelGroupBox.setTitle(translate('OpenLP.ThemesTab', 'Theme Level'))
|
||||
@ -117,6 +127,9 @@ class ThemesTab(SettingsTab):
|
||||
'any themes associated with either the service or the songs.'))
|
||||
|
||||
def load(self):
|
||||
"""
|
||||
Load the theme settings into the tab
|
||||
"""
|
||||
settings = Settings()
|
||||
settings.beginGroup(self.settingsSection)
|
||||
self.theme_level = settings.value(u'theme level')
|
||||
@ -130,30 +143,48 @@ class ThemesTab(SettingsTab):
|
||||
self.SongLevelRadioButton.setChecked(True)
|
||||
|
||||
def save(self):
|
||||
"""
|
||||
Save the settings
|
||||
"""
|
||||
settings = Settings()
|
||||
settings.beginGroup(self.settingsSection)
|
||||
settings.setValue(u'theme level', self.theme_level)
|
||||
settings.setValue(u'global theme', self.global_theme)
|
||||
settings.endGroup()
|
||||
self.mainwindow.renderer.set_global_theme(self.global_theme)
|
||||
self.mainwindow.renderer.set_theme_level(self.theme_level)
|
||||
self.renderer.set_global_theme(self.global_theme)
|
||||
self.renderer.set_theme_level(self.theme_level)
|
||||
Receiver.send_message(u'theme_update_global', self.global_theme)
|
||||
|
||||
def postSetUp(self):
|
||||
"""
|
||||
After setting things up...
|
||||
"""
|
||||
Receiver.send_message(u'theme_update_global', self.global_theme)
|
||||
|
||||
def onSongLevelButtonClicked(self):
|
||||
"""
|
||||
Set the theme level
|
||||
"""
|
||||
self.theme_level = ThemeLevel.Song
|
||||
|
||||
def onServiceLevelButtonClicked(self):
|
||||
"""
|
||||
Set the theme level
|
||||
"""
|
||||
self.theme_level = ThemeLevel.Service
|
||||
|
||||
def onGlobalLevelButtonClicked(self):
|
||||
"""
|
||||
Set the theme level
|
||||
"""
|
||||
self.theme_level = ThemeLevel.Global
|
||||
|
||||
def onDefaultComboBoxChanged(self, value):
|
||||
"""
|
||||
Set the global default theme
|
||||
"""
|
||||
self.global_theme = self.DefaultComboBox.currentText()
|
||||
self.mainwindow.renderer.set_global_theme(self.global_theme)
|
||||
self.renderer.set_global_theme(self.global_theme)
|
||||
self.__previewGlobalTheme()
|
||||
|
||||
def updateThemeList(self, theme_list):
|
||||
@ -170,8 +201,8 @@ class ThemesTab(SettingsTab):
|
||||
self.DefaultComboBox.clear()
|
||||
self.DefaultComboBox.addItems(theme_list)
|
||||
find_and_set_in_combo_box(self.DefaultComboBox, self.global_theme)
|
||||
self.mainwindow.renderer.set_global_theme(self.global_theme)
|
||||
self.mainwindow.renderer.set_theme_level(self.theme_level)
|
||||
self.renderer.set_global_theme(self.global_theme)
|
||||
self.renderer.set_theme_level(self.theme_level)
|
||||
if self.global_theme is not u'':
|
||||
self.__previewGlobalTheme()
|
||||
|
||||
@ -179,7 +210,7 @@ class ThemesTab(SettingsTab):
|
||||
"""
|
||||
Utility method to update the global theme preview image.
|
||||
"""
|
||||
image = self.mainwindow.themeManagerContents.getPreviewImage(self.global_theme)
|
||||
image = self.theme_manager.get_preview_image(self.global_theme)
|
||||
preview = QtGui.QPixmap(unicode(image))
|
||||
if not preview.isNull():
|
||||
preview = preview.scaled(300, 255, QtCore.Qt.KeepAspectRatio, QtCore.Qt.SmoothTransformation)
|
||||
|
@ -26,15 +26,24 @@
|
||||
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||
###############################################################################
|
||||
|
||||
"""
|
||||
The Create/Edit theme wizard
|
||||
"""
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
from openlp.core.lib import translate, build_icon, UiStrings
|
||||
from openlp.core.lib import UiStrings, build_icon, translate
|
||||
from openlp.core.lib.theme import HorizontalType, BackgroundType, BackgroundGradientType
|
||||
from openlp.core.lib.ui import add_welcome_page, create_valign_selection_widgets
|
||||
|
||||
|
||||
class Ui_ThemeWizard(object):
|
||||
"""
|
||||
The Create/Edit theme wizard
|
||||
"""
|
||||
def setupUi(self, themeWizard):
|
||||
"""
|
||||
Set up the UI
|
||||
"""
|
||||
themeWizard.setObjectName(u'OpenLP.ThemeWizard')
|
||||
themeWizard.setModal(True)
|
||||
themeWizard.setWizardStyle(QtGui.QWizard.ModernStyle)
|
||||
@ -372,7 +381,7 @@ class Ui_ThemeWizard(object):
|
||||
QtCore.SLOT(u'setDisabled(bool)'))
|
||||
QtCore.QObject.connect(self.mainPositionCheckBox, QtCore.SIGNAL(u'toggled(bool)'), self.mainHeightSpinBox,
|
||||
QtCore.SLOT(u'setDisabled(bool)'))
|
||||
QtCore.QObject.connect(self.footerPositionCheckBox,QtCore.SIGNAL(u'toggled(bool)'), self.footerXSpinBox,
|
||||
QtCore.QObject.connect(self.footerPositionCheckBox, QtCore.SIGNAL(u'toggled(bool)'), self.footerXSpinBox,
|
||||
QtCore.SLOT(u'setDisabled(bool)'))
|
||||
QtCore.QObject.connect(self.footerPositionCheckBox, QtCore.SIGNAL(u'toggled(bool)'), self.footerYSpinBox,
|
||||
QtCore.SLOT(u'setDisabled(bool)'))
|
||||
@ -382,8 +391,11 @@ class Ui_ThemeWizard(object):
|
||||
QtCore.SLOT(u'setDisabled(bool)'))
|
||||
|
||||
def retranslateUi(self, themeWizard):
|
||||
"""
|
||||
Translate the UI on the fly
|
||||
"""
|
||||
themeWizard.setWindowTitle(translate('OpenLP.ThemeWizard', 'Theme Wizard'))
|
||||
self.titleLabel.setText(u'<span style="font-size:14pt; font-weight:600;">%s</span>' % \
|
||||
self.titleLabel.setText(u'<span style="font-size:14pt; font-weight:600;">%s</span>' %
|
||||
translate('OpenLP.ThemeWizard', 'Welcome to the Theme Wizard'))
|
||||
self.informationLabel.setText(
|
||||
translate('OpenLP.ThemeWizard', 'This wizard will help you to '
|
||||
|
@ -34,11 +34,12 @@ import os
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
from openlp.core.lib import build_icon, Receiver, Settings, translate, UiStrings
|
||||
from openlp.core.lib import Receiver, Registry, Settings, UiStrings, build_icon, translate
|
||||
from openlp.core.lib.ui import add_welcome_page
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class WizardStrings(object):
|
||||
"""
|
||||
Provide standard strings for wizards to use.
|
||||
@ -96,6 +97,9 @@ class OpenLPWizard(QtGui.QWizard):
|
||||
Whether to add a progress page with a progressbar at the end of the wizard.
|
||||
"""
|
||||
def __init__(self, parent, plugin, name, image, addProgressPage=True):
|
||||
"""
|
||||
Constructor
|
||||
"""
|
||||
QtGui.QWizard.__init__(self, parent)
|
||||
self.plugin = plugin
|
||||
self.withProgressPage = addProgressPage
|
||||
@ -234,7 +238,7 @@ class OpenLPWizard(QtGui.QWizard):
|
||||
self.progressLabel.setText(status_text)
|
||||
if increment > 0:
|
||||
self.progressBar.setValue(self.progressBar.value() + increment)
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
self.application.process_events()
|
||||
|
||||
def preWizard(self):
|
||||
"""
|
||||
@ -252,7 +256,7 @@ class OpenLPWizard(QtGui.QWizard):
|
||||
self.progressBar.setValue(self.progressBar.maximum())
|
||||
self.finishButton.setVisible(True)
|
||||
self.cancelButton.setVisible(False)
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
self.application.process_events()
|
||||
|
||||
def getFileName(self, title, editbox, setting_name, filters=u''):
|
||||
"""
|
||||
@ -301,3 +305,13 @@ class OpenLPWizard(QtGui.QWizard):
|
||||
if folder:
|
||||
editbox.setText(folder)
|
||||
Settings().setValue(self.plugin.settingsSection + u'/' + setting_name, folder)
|
||||
|
||||
def _get_application(self):
|
||||
"""
|
||||
Adds the openlp to the class dynamically
|
||||
"""
|
||||
if not hasattr(self, u'_application'):
|
||||
self._application = Registry().get(u'application')
|
||||
return self._application
|
||||
|
||||
application = property(_get_application)
|
||||
|
@ -29,7 +29,7 @@
|
||||
"""
|
||||
The :mod:`openlp.core.utils` module provides the utility libraries for OpenLP.
|
||||
"""
|
||||
from datetime import datetime, timedelta
|
||||
from datetime import datetime
|
||||
from distutils.version import LooseVersion
|
||||
import logging
|
||||
import locale
|
||||
@ -39,7 +39,7 @@ from subprocess import Popen, PIPE
|
||||
import sys
|
||||
import urllib2
|
||||
|
||||
from openlp.core.lib import Settings
|
||||
from openlp.core.lib import Registry, Settings
|
||||
|
||||
from PyQt4 import QtGui, QtCore
|
||||
|
||||
@ -61,14 +61,12 @@ UNO_CONNECTION_TYPE = u'pipe'
|
||||
CONTROL_CHARS = re.compile(r'[\x00-\x1F\x7F-\x9F]', re.UNICODE)
|
||||
INVALID_FILE_CHARS = re.compile(r'[\\/:\*\?"<>\|\+\[\]%]', re.UNICODE)
|
||||
|
||||
|
||||
class VersionThread(QtCore.QThread):
|
||||
"""
|
||||
A special Qt thread class to fetch the version of OpenLP from the website.
|
||||
This is threaded so that it doesn't affect the loading time of OpenLP.
|
||||
"""
|
||||
def __init__(self, parent):
|
||||
QtCore.QThread.__init__(self, parent)
|
||||
|
||||
def run(self):
|
||||
"""
|
||||
Run the thread.
|
||||
@ -157,7 +155,8 @@ def _get_os_dir_path(dir_type):
|
||||
return os.path.join(unicode(os.getenv(u'APPDATA'), encoding), u'openlp')
|
||||
elif sys.platform == u'darwin':
|
||||
if dir_type == AppLocation.DataDir:
|
||||
return os.path.join(unicode(os.getenv(u'HOME'), encoding), u'Library', u'Application Support', u'openlp', u'Data')
|
||||
return os.path.join(unicode(os.getenv(u'HOME'), encoding),
|
||||
u'Library', u'Application Support', u'openlp', u'Data')
|
||||
elif dir_type == AppLocation.LanguageDir:
|
||||
return os.path.split(openlp.__file__)[0]
|
||||
return os.path.join(unicode(os.getenv(u'HOME'), encoding), u'Library', u'Application Support', u'openlp')
|
||||
@ -425,7 +424,7 @@ def get_web_page(url, header=None, update_openlp=False):
|
||||
if not page:
|
||||
return None
|
||||
if update_openlp:
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
Registry().get(u'application').process_events()
|
||||
log.debug(page)
|
||||
return page
|
||||
|
||||
@ -472,6 +471,9 @@ def format_time(text, local_time):
|
||||
The time to be used to add to the string. This is a time object
|
||||
"""
|
||||
def match_formatting(match):
|
||||
"""
|
||||
Format the match
|
||||
"""
|
||||
return local_time.strftime(match.group())
|
||||
return re.sub('\%[a-zA-Z]', match_formatting, text)
|
||||
|
||||
@ -488,17 +490,14 @@ def locale_compare(string1, string2):
|
||||
return locale.strcoll(string1.lower(), string2.lower())
|
||||
|
||||
|
||||
# For performance reasons provide direct reference to compare function
|
||||
# without wrapping it in another function making te string lowercase.
|
||||
# This is needed for sorting songs.
|
||||
# For performance reasons provide direct reference to compare function without wrapping it in another function making
|
||||
# the string lowercase. This is needed for sorting songs.
|
||||
locale_direct_compare = locale.strcoll
|
||||
|
||||
|
||||
from languagemanager import LanguageManager
|
||||
from actions import ActionList
|
||||
|
||||
__all__ = [u'AppLocation', u'get_application_version', u'check_latest_version',
|
||||
u'add_actions', u'get_filesystem_encoding', u'LanguageManager',
|
||||
u'ActionList', u'get_web_page', u'get_uno_command', u'get_uno_instance',
|
||||
u'delete_file', u'clean_filename', u'format_time', u'locale_compare',
|
||||
u'locale_direct_compare']
|
||||
__all__ = [u'AppLocation', u'ActionList', u'LanguageManager', u'get_application_version', u'check_latest_version',
|
||||
u'add_actions', u'get_filesystem_encoding', u'get_web_page', u'get_uno_command', u'get_uno_instance',
|
||||
u'delete_file', u'clean_filename', u'format_time', u'locale_compare', u'locale_direct_compare']
|
||||
|
@ -41,6 +41,9 @@ class ActionCategory(object):
|
||||
category for the :class:`~openlp.core.utils.CategoryList` class.
|
||||
"""
|
||||
def __init__(self, name, weight=0):
|
||||
"""
|
||||
Constructor
|
||||
"""
|
||||
self.name = name
|
||||
self.weight = weight
|
||||
self.actions = CategoryActionList()
|
||||
@ -52,22 +55,37 @@ class CategoryActionList(object):
|
||||
list of actions within a category.
|
||||
"""
|
||||
def __init__(self):
|
||||
"""
|
||||
Constructor
|
||||
"""
|
||||
self.index = 0
|
||||
self.actions = []
|
||||
|
||||
def __getitem__(self, key):
|
||||
"""
|
||||
Implement the __getitem__() method to make this class a dictionary type
|
||||
"""
|
||||
for weight, action in self.actions:
|
||||
if action.text() == key:
|
||||
return action
|
||||
raise KeyError(u'Action "%s" does not exist.' % key)
|
||||
|
||||
def __contains__(self, item):
|
||||
"""
|
||||
Implement the __contains__() method to make this class a dictionary type
|
||||
"""
|
||||
return self.has_key(item)
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
Implement the __len__() method to make this class a dictionary type
|
||||
"""
|
||||
return len(self.actions)
|
||||
|
||||
def __iter__(self):
|
||||
"""
|
||||
Implement the __getitem__() method to make this class iterable
|
||||
"""
|
||||
return self
|
||||
|
||||
def __next__(self):
|
||||
@ -88,22 +106,34 @@ class CategoryActionList(object):
|
||||
return self.__next__()
|
||||
|
||||
def has_key(self, key):
|
||||
"""
|
||||
Implement the has_key() method to make this class a dictionary type
|
||||
"""
|
||||
for weight, action in self.actions:
|
||||
if action.text() == key:
|
||||
return True
|
||||
return False
|
||||
|
||||
def append(self, name):
|
||||
"""
|
||||
Append an action
|
||||
"""
|
||||
weight = 0
|
||||
if self.actions:
|
||||
weight = self.actions[-1][0] + 1
|
||||
self.add(name, weight)
|
||||
|
||||
def add(self, action, weight=0):
|
||||
"""
|
||||
Add an action.
|
||||
"""
|
||||
self.actions.append((weight, action))
|
||||
self.actions.sort(key=lambda act: act[0])
|
||||
|
||||
def remove(self, remove_action):
|
||||
"""
|
||||
Remove an action
|
||||
"""
|
||||
for action in self.actions:
|
||||
if action[1] == remove_action:
|
||||
self.actions.remove(action)
|
||||
@ -118,22 +148,37 @@ class CategoryList(object):
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
"""
|
||||
Constructor
|
||||
"""
|
||||
self.index = 0
|
||||
self.categories = []
|
||||
|
||||
def __getitem__(self, key):
|
||||
"""
|
||||
Implement the __getitem__() method to make this class like a dictionary
|
||||
"""
|
||||
for category in self.categories:
|
||||
if category.name == key:
|
||||
return category
|
||||
raise KeyError(u'Category "%s" does not exist.' % key)
|
||||
|
||||
def __contains__(self, item):
|
||||
"""
|
||||
Implement the __contains__() method to make this class like a dictionary
|
||||
"""
|
||||
return self.has_key(item)
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
Implement the __len__() method to make this class like a dictionary
|
||||
"""
|
||||
return len(self.categories)
|
||||
|
||||
def __iter__(self):
|
||||
"""
|
||||
Implement the __iter__() method to make this class like a dictionary
|
||||
"""
|
||||
return self
|
||||
|
||||
def __next__(self):
|
||||
@ -154,12 +199,18 @@ class CategoryList(object):
|
||||
return self.__next__()
|
||||
|
||||
def has_key(self, key):
|
||||
"""
|
||||
Implement the has_key() method to make this class like a dictionary
|
||||
"""
|
||||
for category in self.categories:
|
||||
if category.name == key:
|
||||
return True
|
||||
return False
|
||||
|
||||
def append(self, name, actions=None):
|
||||
"""
|
||||
Append a category
|
||||
"""
|
||||
weight = 0
|
||||
if self.categories:
|
||||
weight = self.categories[-1].weight + 1
|
||||
@ -169,6 +220,9 @@ class CategoryList(object):
|
||||
self.add(name, weight)
|
||||
|
||||
def add(self, name, weight=0, actions=None):
|
||||
"""
|
||||
Add a category
|
||||
"""
|
||||
category = ActionCategory(name, weight)
|
||||
if actions:
|
||||
for action in actions:
|
||||
@ -180,6 +234,9 @@ class CategoryList(object):
|
||||
self.categories.sort(key=lambda cat: cat.weight)
|
||||
|
||||
def remove(self, name):
|
||||
"""
|
||||
Remove a category
|
||||
"""
|
||||
for category in self.categories:
|
||||
if category.name == name:
|
||||
self.categories.remove(category)
|
||||
@ -196,10 +253,16 @@ class ActionList(object):
|
||||
shortcut_map = {}
|
||||
|
||||
def __init__(self):
|
||||
"""
|
||||
Constructor
|
||||
"""
|
||||
self.categories = CategoryList()
|
||||
|
||||
@staticmethod
|
||||
def get_instance():
|
||||
"""
|
||||
Get the instance of this class.
|
||||
"""
|
||||
if ActionList.instance is None:
|
||||
ActionList.instance = ActionList()
|
||||
return ActionList.instance
|
||||
|
@ -27,8 +27,7 @@
|
||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||
###############################################################################
|
||||
"""
|
||||
The :mod:`languagemanager` module provides all the translation settings and
|
||||
language file loading for OpenLP.
|
||||
The :mod:`languagemanager` module provides all the translation settings and language file loading for OpenLP.
|
||||
"""
|
||||
import logging
|
||||
import re
|
||||
@ -37,10 +36,11 @@ import sys
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
from openlp.core.utils import AppLocation
|
||||
from openlp.core.lib import translate, Settings
|
||||
from openlp.core.lib import Settings, translate
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class LanguageManager(object):
|
||||
"""
|
||||
Helper for Language selection
|
||||
|
@ -29,9 +29,9 @@
|
||||
|
||||
import logging
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
from PyQt4 import QtGui
|
||||
|
||||
from openlp.core.lib import Plugin, StringContent, build_icon, translate, Settings
|
||||
from openlp.core.lib import Plugin, Settings, StringContent, build_icon, translate
|
||||
from openlp.core.lib.db import Manager
|
||||
from openlp.core.lib.ui import create_action, UiStrings
|
||||
from openlp.core.lib.theme import VerticalType
|
||||
|
@ -34,6 +34,7 @@ from openlp.plugins.alerts.lib.db import AlertItem
|
||||
|
||||
from alertdialog import Ui_AlertDialog
|
||||
|
||||
|
||||
class AlertForm(QtGui.QDialog, Ui_AlertDialog):
|
||||
"""
|
||||
Provide UI for the alert system
|
||||
@ -45,7 +46,7 @@ class AlertForm(QtGui.QDialog, Ui_AlertDialog):
|
||||
self.manager = plugin.manager
|
||||
self.plugin = plugin
|
||||
self.item_id = None
|
||||
QtGui.QDialog.__init__(self, self.plugin.main_window)
|
||||
super(AlertForm, self).__init__(self.plugin.main_window)
|
||||
self.setupUi(self)
|
||||
QtCore.QObject.connect(self.displayButton, QtCore.SIGNAL(u'clicked()'), self.onDisplayClicked)
|
||||
QtCore.QObject.connect(self.displayCloseButton, QtCore.SIGNAL(u'clicked()'), self.onDisplayCloseClicked)
|
||||
@ -57,6 +58,9 @@ class AlertForm(QtGui.QDialog, Ui_AlertDialog):
|
||||
QtCore.QObject.connect(self.alertListWidget, QtCore.SIGNAL(u'currentRowChanged(int)'), self.onCurrentRowChanged)
|
||||
|
||||
def exec_(self):
|
||||
"""
|
||||
Execute the dialog and return the exit code.
|
||||
"""
|
||||
self.displayButton.setEnabled(False)
|
||||
self.displayCloseButton.setEnabled(False)
|
||||
self.alertTextEdit.setText(u'')
|
||||
@ -77,9 +81,15 @@ class AlertForm(QtGui.QDialog, Ui_AlertDialog):
|
||||
self.alertListWidget.setCurrentRow(self.alertListWidget.row(item_name))
|
||||
|
||||
def onDisplayClicked(self):
|
||||
"""
|
||||
Display the current alert text.
|
||||
"""
|
||||
self.triggerAlert(self.alertTextEdit.text())
|
||||
|
||||
def onDisplayCloseClicked(self):
|
||||
"""
|
||||
Close the alert preview.
|
||||
"""
|
||||
if self.triggerAlert(self.alertTextEdit.text()):
|
||||
self.close()
|
||||
|
||||
@ -97,6 +107,9 @@ class AlertForm(QtGui.QDialog, Ui_AlertDialog):
|
||||
self.alertTextEdit.setText(u'')
|
||||
|
||||
def onNewClick(self):
|
||||
"""
|
||||
Create a new alert.
|
||||
"""
|
||||
if not self.alertTextEdit.text():
|
||||
QtGui.QMessageBox.information(self,
|
||||
translate('AlertsPlugin.AlertForm', 'New Alert'),
|
||||
|
@ -29,8 +29,7 @@
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
from openlp.core.lib import SettingsTab, translate, Receiver, Settings, UiStrings
|
||||
from openlp.core.ui import AlertLocation
|
||||
from openlp.core.lib import SettingsTab, Receiver, Settings, UiStrings, translate
|
||||
from openlp.core.lib.ui import create_valign_selection_widgets
|
||||
|
||||
class AlertsTab(SettingsTab):
|
||||
|
@ -31,8 +31,8 @@ import logging
|
||||
|
||||
from PyQt4 import QtGui
|
||||
|
||||
from openlp.core.lib import Plugin, StringContent, build_icon, translate, Settings
|
||||
from openlp.core.lib.ui import create_action, UiStrings
|
||||
from openlp.core.lib import Plugin, StringContent, build_icon, translate
|
||||
from openlp.core.lib.ui import UiStrings, create_action
|
||||
from openlp.core.utils.actions import ActionList
|
||||
from openlp.plugins.bibles.lib import BibleManager, BiblesTab, BibleMediaItem, LayoutStyle, DisplayStyle, \
|
||||
LanguageSelection
|
||||
@ -102,11 +102,11 @@ class BiblePlugin(Plugin):
|
||||
#action_list.remove_action(self.exportBibleItem, UiStrings().Export)
|
||||
self.exportBibleItem.setVisible(False)
|
||||
|
||||
def appStartup(self):
|
||||
def app_startup(self):
|
||||
"""
|
||||
Perform tasks on application startup
|
||||
"""
|
||||
Plugin.appStartup(self)
|
||||
Plugin.app_startup(self)
|
||||
if self.manager.old_bible_databases:
|
||||
if QtGui.QMessageBox.information(self.main_window,
|
||||
translate('OpenLP', 'Information'),
|
||||
|
@ -34,7 +34,7 @@ import os
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
from openlp.core.lib import Receiver, translate, Settings, UiStrings
|
||||
from openlp.core.lib import Settings, UiStrings, translate
|
||||
from openlp.core.lib.db import delete_database
|
||||
from openlp.core.lib.ui import critical_error_message_box
|
||||
from openlp.core.ui.wizard import OpenLPWizard, WizardStrings
|
||||
@ -578,7 +578,7 @@ class BibleImportForm(OpenLPWizard):
|
||||
self.progressLabel.setText(translate('BiblesPlugin.ImportWizardForm', 'Registering Bible...'))
|
||||
else:
|
||||
self.progressLabel.setText(WizardStrings.StartingImport)
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
self.application.process_events()
|
||||
|
||||
def performWizard(self):
|
||||
"""
|
||||
|
@ -36,7 +36,7 @@ from tempfile import gettempdir
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
from openlp.core.lib import Receiver, translate, check_directory_exists, Settings, UiStrings
|
||||
from openlp.core.lib import Receiver, Settings, UiStrings, translate, check_directory_exists
|
||||
from openlp.core.lib.ui import critical_error_message_box
|
||||
from openlp.core.ui.wizard import OpenLPWizard, WizardStrings
|
||||
from openlp.core.utils import AppLocation, delete_file, get_filesystem_encoding
|
||||
@ -335,7 +335,7 @@ class BibleUpgradeForm(OpenLPWizard):
|
||||
"""
|
||||
OpenLPWizard.preWizard(self)
|
||||
self.progressLabel.setText(translate('BiblesPlugin.UpgradeWizardForm', 'Starting upgrade...'))
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
self.application.process_events()
|
||||
|
||||
def performWizard(self):
|
||||
"""
|
||||
@ -465,7 +465,7 @@ class BibleUpgradeForm(OpenLPWizard):
|
||||
self.newbibles[number].create_verse(db_book.id,
|
||||
int(verse[u'chapter']),
|
||||
int(verse[u'verse']), unicode(verse[u'text']))
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
self.application.process_events()
|
||||
self.newbibles[number].session.commit()
|
||||
else:
|
||||
language_id = self.newbibles[number].get_object(BibleMeta, u'language_id')
|
||||
@ -511,7 +511,7 @@ class BibleUpgradeForm(OpenLPWizard):
|
||||
self.newbibles[number].create_verse(db_book.id,
|
||||
int(verse[u'chapter']),
|
||||
int(verse[u'verse']), unicode(verse[u'text']))
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
self.application.process_events()
|
||||
self.newbibles[number].session.commit()
|
||||
if not self.success.get(number, True):
|
||||
self.incrementProgressBar(translate('BiblesPlugin.UpgradeWizardForm',
|
||||
|
@ -32,7 +32,7 @@ import re
|
||||
|
||||
from PyQt4 import QtGui
|
||||
|
||||
from openlp.core.lib import Receiver, translate, UiStrings
|
||||
from openlp.core.lib import Registry, UiStrings, translate
|
||||
from openlp.core.lib.ui import critical_error_message_box
|
||||
from editbibledialog import Ui_EditBibleDialog
|
||||
from openlp.plugins.bibles.lib import BibleStrings
|
||||
@ -122,8 +122,7 @@ class EditBibleForm(QtGui.QDialog, Ui_EditBibleDialog):
|
||||
if book.name != custom_names[abbr]:
|
||||
if not self.validateBook(custom_names[abbr], abbr):
|
||||
return
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
Receiver.send_message(u'cursor_busy')
|
||||
self.application.set_busy_cursor()
|
||||
self.manager.save_meta_data(self.bible, version, copyright, permissions, book_name_language)
|
||||
if not self.webbible:
|
||||
for abbr, book in self.books.iteritems():
|
||||
@ -132,7 +131,7 @@ class EditBibleForm(QtGui.QDialog, Ui_EditBibleDialog):
|
||||
book.name = custom_names[abbr]
|
||||
self.manager.update_book(self.bible, book)
|
||||
self.bible = None
|
||||
Receiver.send_message(u'cursor_normal')
|
||||
self.application.set_normal_cursor()
|
||||
QtGui.QDialog.accept(self)
|
||||
|
||||
def validateMeta(self, name, copyright):
|
||||
@ -189,3 +188,13 @@ class EditBibleForm(QtGui.QDialog, Ui_EditBibleDialog):
|
||||
% new_book_name)
|
||||
return False
|
||||
return True
|
||||
|
||||
def _get_application(self):
|
||||
"""
|
||||
Adds the openlp to the class dynamically
|
||||
"""
|
||||
if not hasattr(self, u'_application'):
|
||||
self._application = Registry().get(u'application')
|
||||
return self._application
|
||||
|
||||
application = property(_get_application)
|
||||
|
@ -33,7 +33,7 @@ plugin.
|
||||
import logging
|
||||
import re
|
||||
|
||||
from openlp.core.lib import translate, Settings
|
||||
from openlp.core.lib import Settings, translate
|
||||
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
@ -31,7 +31,7 @@ import logging
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
from openlp.core.lib import Receiver, SettingsTab, translate, Settings, UiStrings
|
||||
from openlp.core.lib import Receiver, SettingsTab, Settings, UiStrings, translate
|
||||
from openlp.core.lib.ui import find_and_set_in_combo_box
|
||||
from openlp.plugins.bibles.lib import LayoutStyle, DisplayStyle, update_reference_separators, \
|
||||
get_reference_separator, LanguageSelection
|
||||
|
@ -62,7 +62,7 @@ import logging
|
||||
import chardet
|
||||
import csv
|
||||
|
||||
from openlp.core.lib import Receiver, translate
|
||||
from openlp.core.lib import translate
|
||||
from openlp.plugins.bibles.lib.db import BibleDB, BiblesResourcesDB
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
@ -118,7 +118,7 @@ class CSVBible(BibleDB):
|
||||
book_details = BiblesResourcesDB.get_book_by_id(book_ref_id)
|
||||
self.create_book(unicode(line[2], details['encoding']), book_ref_id, book_details[u'testament_id'])
|
||||
book_list[int(line[0])] = unicode(line[2], details['encoding'])
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
self.application.process_events()
|
||||
except (IOError, IndexError):
|
||||
log.exception(u'Loading books from file failed')
|
||||
success = False
|
||||
@ -157,7 +157,7 @@ class CSVBible(BibleDB):
|
||||
verse_text = unicode(line[3], u'cp1252')
|
||||
self.create_verse(book.id, line[1], line[2], verse_text)
|
||||
self.wizard.incrementProgressBar(translate('BiblesPlugin.CSVBible', 'Importing verses... done.'))
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
self.application.process_events()
|
||||
self.session.commit()
|
||||
except IOError:
|
||||
log.exception(u'Loading verses from file failed')
|
||||
|
@ -34,11 +34,11 @@ import re
|
||||
import sqlite3
|
||||
|
||||
from PyQt4 import QtCore
|
||||
from sqlalchemy import Column, ForeignKey, or_, Table, types, func
|
||||
from sqlalchemy import Column, ForeignKey, Table, or_, types, func
|
||||
from sqlalchemy.orm import class_mapper, mapper, relation
|
||||
from sqlalchemy.orm.exc import UnmappedClassError
|
||||
|
||||
from openlp.core.lib import Receiver, translate
|
||||
from openlp.core.lib import Receiver, Registry, translate
|
||||
from openlp.core.lib.db import BaseModel, init_db, Manager
|
||||
from openlp.core.lib.ui import critical_error_message_box
|
||||
from openlp.core.utils import AppLocation, clean_filename
|
||||
@ -360,7 +360,7 @@ class BibleDB(QtCore.QObject, Manager):
|
||||
|
||||
``book``
|
||||
The name of the book, according to the selected language.
|
||||
|
||||
|
||||
``language_selection``
|
||||
The language selection the user has chosen in the settings
|
||||
section of the Bible.
|
||||
@ -549,6 +549,16 @@ class BibleDB(QtCore.QObject, Manager):
|
||||
verses = self.session.query(Verse).all()
|
||||
log.debug(verses)
|
||||
|
||||
def _get_application(self):
|
||||
"""
|
||||
Adds the openlp to the class dynamically
|
||||
"""
|
||||
if not hasattr(self, u'_application'):
|
||||
self._application = Registry().get(u'application')
|
||||
return self._application
|
||||
|
||||
application = property(_get_application)
|
||||
|
||||
|
||||
class BiblesResourcesDB(QtCore.QObject, Manager):
|
||||
"""
|
||||
|
@ -38,7 +38,7 @@ from HTMLParser import HTMLParseError
|
||||
|
||||
from BeautifulSoup import BeautifulSoup, NavigableString, Tag
|
||||
|
||||
from openlp.core.lib import Receiver, translate
|
||||
from openlp.core.lib import Registry, translate
|
||||
from openlp.core.lib.ui import critical_error_message_box
|
||||
from openlp.core.utils import get_web_page
|
||||
from openlp.plugins.bibles.lib import SearchResults
|
||||
@ -164,7 +164,7 @@ class BGExtract(object):
|
||||
if len(verse_parts) > 1:
|
||||
verse = int(verse_parts[0])
|
||||
except TypeError:
|
||||
log.warn(u'Illegal verse number: %s', unicode(raw_verse_num))
|
||||
log.warn(u'Illegal verse number: %s', unicode(verse))
|
||||
verses.append((verse, text))
|
||||
verse_list = {}
|
||||
for verse, text in verses[::-1]:
|
||||
@ -203,8 +203,7 @@ class BGExtract(object):
|
||||
if clean_verse_num:
|
||||
verse_text = raw_verse_num.next
|
||||
part = raw_verse_num.next.next
|
||||
while not (isinstance(part, Tag) and
|
||||
part.get(u'class') == u'versenum'):
|
||||
while not (isinstance(part, Tag) and part.get(u'class') == u'versenum'):
|
||||
# While we are still in the same verse grab all the text.
|
||||
if isinstance(part, NavigableString):
|
||||
verse_text += part
|
||||
@ -235,9 +234,10 @@ class BGExtract(object):
|
||||
soup = get_soup_for_bible_ref(
|
||||
u'http://www.biblegateway.com/passage/?%s' % url_params,
|
||||
pre_parse_regex=r'<meta name.*?/>', pre_parse_substitute='', cleaner=cleaner)
|
||||
self.application.process_events()
|
||||
if not soup:
|
||||
return None
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
self.application.process_events()
|
||||
div = soup.find('div', 'result-text-style-normal')
|
||||
self._clean_soup(div)
|
||||
span_list = div.findAll('span', 'text')
|
||||
@ -281,7 +281,7 @@ class BGExtract(object):
|
||||
if not soup:
|
||||
send_error_message(u'parse')
|
||||
return None
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
self.application.process_events()
|
||||
content = soup.find(u'table', u'infotable')
|
||||
if content:
|
||||
content = content.findAll(u'tr')
|
||||
@ -319,17 +319,15 @@ class BSExtract(object):
|
||||
``chapter``
|
||||
Chapter number
|
||||
"""
|
||||
log.debug(u'BSExtract.get_bible_chapter("%s", "%s", "%s")', version,
|
||||
book_name, chapter)
|
||||
log.debug(u'BSExtract.get_bible_chapter("%s", "%s", "%s")', version, book_name, chapter)
|
||||
url_version = urllib.quote(version.encode("utf-8"))
|
||||
url_book_name = urllib.quote(book_name.encode("utf-8"))
|
||||
chapter_url = u'http://m.bibleserver.com/text/%s/%s%d' % \
|
||||
(url_version, url_book_name, chapter)
|
||||
chapter_url = u'http://m.bibleserver.com/text/%s/%s%d' % (url_version, url_book_name, chapter)
|
||||
header = (u'Accept-Language', u'en')
|
||||
soup = get_soup_for_bible_ref(chapter_url, header)
|
||||
if not soup:
|
||||
return None
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
self.application.process_events()
|
||||
content = soup.find(u'div', u'content')
|
||||
if not content:
|
||||
log.error(u'No verses found in the Bibleserver response.')
|
||||
@ -339,7 +337,7 @@ class BSExtract(object):
|
||||
verse_number = re.compile(r'v(\d{1,2})(\d{3})(\d{3}) verse.*')
|
||||
verses = {}
|
||||
for verse in content:
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
self.application.process_events()
|
||||
versenumber = int(verse_number.sub(r'\3', verse[u'class']))
|
||||
verses[versenumber] = verse.contents[1].rstrip(u'\n')
|
||||
return SearchResults(book_name, chapter, verses)
|
||||
@ -354,8 +352,7 @@ class BSExtract(object):
|
||||
"""
|
||||
log.debug(u'BSExtract.get_books_from_http("%s")', version)
|
||||
urlversion = urllib.quote(version.encode("utf-8"))
|
||||
chapter_url = u'http://m.bibleserver.com/overlay/selectBook?'\
|
||||
'translation=%s' % (urlversion)
|
||||
chapter_url = u'http://m.bibleserver.com/overlay/selectBook?translation=%s' % (urlversion)
|
||||
soup = get_soup_for_bible_ref(chapter_url)
|
||||
if not soup:
|
||||
return None
|
||||
@ -365,9 +362,7 @@ class BSExtract(object):
|
||||
send_error_message(u'parse')
|
||||
return None
|
||||
content = content.findAll(u'li')
|
||||
return [
|
||||
book.contents[0].contents[0] for book in content
|
||||
]
|
||||
return [book.contents[0].contents[0] for book in content]
|
||||
|
||||
|
||||
class CWExtract(object):
|
||||
@ -392,17 +387,15 @@ class CWExtract(object):
|
||||
``chapter``
|
||||
Chapter number
|
||||
"""
|
||||
log.debug(u'CWExtract.get_bible_chapter("%s", "%s", "%s")', version,
|
||||
book_name, chapter)
|
||||
log.debug(u'CWExtract.get_bible_chapter("%s", "%s", "%s")', version, book_name, chapter)
|
||||
url_book_name = book_name.replace(u' ', u'-')
|
||||
url_book_name = url_book_name.lower()
|
||||
url_book_name = urllib.quote(url_book_name.encode("utf-8"))
|
||||
chapter_url = u'http://www.biblestudytools.com/%s/%s/%s.html' % \
|
||||
(version, url_book_name, chapter)
|
||||
chapter_url = u'http://www.biblestudytools.com/%s/%s/%s.html' % (version, url_book_name, chapter)
|
||||
soup = get_soup_for_bible_ref(chapter_url)
|
||||
if not soup:
|
||||
return None
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
self.application.process_events()
|
||||
html_verses = soup.findAll(u'span', u'versetext')
|
||||
if not html_verses:
|
||||
log.error(u'No verses found in the CrossWalk response.')
|
||||
@ -412,27 +405,25 @@ class CWExtract(object):
|
||||
reduce_spaces = re.compile(r'[ ]{2,}')
|
||||
fix_punctuation = re.compile(r'[ ]+([.,;])')
|
||||
for verse in html_verses:
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
self.application.process_events()
|
||||
verse_number = int(verse.contents[0].contents[0])
|
||||
verse_text = u''
|
||||
for part in verse.contents:
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
self.application.process_events()
|
||||
if isinstance(part, NavigableString):
|
||||
verse_text = verse_text + part
|
||||
verse_text += part
|
||||
elif part and part.attrMap and \
|
||||
(part.attrMap[u'class'] == u'WordsOfChrist' or \
|
||||
part.attrMap[u'class'] == u'strongs'):
|
||||
(part.attrMap[u'class'] == u'WordsOfChrist' or part.attrMap[u'class'] == u'strongs'):
|
||||
for subpart in part.contents:
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
self.application.process_events()
|
||||
if isinstance(subpart, NavigableString):
|
||||
verse_text = verse_text + subpart
|
||||
elif subpart and subpart.attrMap and \
|
||||
subpart.attrMap[u'class'] == u'strongs':
|
||||
verse_text += subpart
|
||||
elif subpart and subpart.attrMap and subpart.attrMap[u'class'] == u'strongs':
|
||||
for subsub in subpart.contents:
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
self.application.process_events()
|
||||
if isinstance(subsub, NavigableString):
|
||||
verse_text = verse_text + subsub
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
verse_text += subsub
|
||||
self.application.process_events()
|
||||
# Fix up leading and trailing spaces, multiple spaces, and spaces
|
||||
# between text and , and .
|
||||
verse_text = verse_text.strip(u'\n\r\t ')
|
||||
@ -449,8 +440,7 @@ class CWExtract(object):
|
||||
The version of the bible like NIV for New International Version
|
||||
"""
|
||||
log.debug(u'CWExtract.get_books_from_http("%s")', version)
|
||||
chapter_url = u'http://www.biblestudytools.com/%s/'\
|
||||
% (version)
|
||||
chapter_url = u'http://www.biblestudytools.com/%s/' % (version)
|
||||
soup = get_soup_for_bible_ref(chapter_url)
|
||||
if not soup:
|
||||
return None
|
||||
@ -504,9 +494,7 @@ class HTTPBible(BibleDB):
|
||||
``True`` on success, ``False`` on failure.
|
||||
"""
|
||||
self.wizard.progressBar.setMaximum(68)
|
||||
self.wizard.incrementProgressBar(translate(
|
||||
'BiblesPlugin.HTTPBible',
|
||||
'Registering Bible and loading books...'))
|
||||
self.wizard.incrementProgressBar(translate('BiblesPlugin.HTTPBible', 'Registering Bible and loading books...'))
|
||||
self.save_meta(u'download_source', self.download_source)
|
||||
self.save_meta(u'download_name', self.download_name)
|
||||
if self.proxy_server:
|
||||
@ -528,19 +516,16 @@ class HTTPBible(BibleDB):
|
||||
log.exception(u'Importing books from %s - download name: "%s" '\
|
||||
'failed' % (self.download_source, self.download_name))
|
||||
return False
|
||||
self.wizard.progressBar.setMaximum(len(books)+2)
|
||||
self.wizard.incrementProgressBar(translate(
|
||||
'BiblesPlugin.HTTPBible', 'Registering Language...'))
|
||||
bible = BiblesResourcesDB.get_webbible(self.download_name,
|
||||
self.download_source.lower())
|
||||
self.wizard.progressBar.setMaximum(len(books) + 2)
|
||||
self.wizard.incrementProgressBar(translate( 'BiblesPlugin.HTTPBible', 'Registering Language...'))
|
||||
bible = BiblesResourcesDB.get_webbible(self.download_name, self.download_source.lower())
|
||||
if bible[u'language_id']:
|
||||
language_id = bible[u'language_id']
|
||||
self.save_meta(u'language_id', language_id)
|
||||
else:
|
||||
language_id = self.get_language(bible_name)
|
||||
if not language_id:
|
||||
log.exception(u'Importing books from %s " '\
|
||||
'failed' % self.filename)
|
||||
log.exception(u'Importing books from %s failed' % self.filename)
|
||||
return False
|
||||
for book in books:
|
||||
if self.stop_import_flag:
|
||||
@ -548,8 +533,7 @@ class HTTPBible(BibleDB):
|
||||
self.wizard.incrementProgressBar(translate(
|
||||
'BiblesPlugin.HTTPBible', 'Importing %s...',
|
||||
'Importing <book name>...') % book)
|
||||
book_ref_id = self.get_book_ref_id_by_name(book, len(books),
|
||||
language_id)
|
||||
book_ref_id = self.get_book_ref_id_by_name(book, len(books), language_id)
|
||||
if not book_ref_id:
|
||||
log.exception(u'Importing books from %s - download name: "%s" '\
|
||||
'failed' % (self.download_source, self.download_name))
|
||||
@ -598,7 +582,7 @@ class HTTPBible(BibleDB):
|
||||
return []
|
||||
book = db_book.name
|
||||
if BibleDB.get_verse_count(self, book_id, reference[1]) == 0:
|
||||
Receiver.send_message(u'cursor_busy')
|
||||
self.application.set_busy_cursor()
|
||||
search_results = self.get_chapter(book, reference[1])
|
||||
if search_results and search_results.has_verselist():
|
||||
## We have found a book of the bible lets check to see
|
||||
@ -606,14 +590,13 @@ class HTTPBible(BibleDB):
|
||||
## we get a correct book. For example it is possible
|
||||
## to request ac and get Acts back.
|
||||
book_name = search_results.book
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
self.application.process_events()
|
||||
# Check to see if book/chapter exists.
|
||||
db_book = self.get_book(book_name)
|
||||
self.create_chapter(db_book.id, search_results.chapter,
|
||||
search_results.verselist)
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
Receiver.send_message(u'cursor_normal')
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
self.create_chapter(db_book.id, search_results.chapter, search_results.verselist)
|
||||
self.application.process_events()
|
||||
self.application.set_normal_cursor()
|
||||
self.application.process_events()
|
||||
return BibleDB.get_verses(self, reference_list, show_error)
|
||||
|
||||
def get_chapter(self, book, chapter):
|
||||
@ -660,6 +643,16 @@ class HTTPBible(BibleDB):
|
||||
log.debug(u'HTTPBible.get_verse_count("%s", %s)', book_id, chapter)
|
||||
return BiblesResourcesDB.get_verse_count(book_id, chapter)
|
||||
|
||||
def _get_application(self):
|
||||
"""
|
||||
Adds the openlp to the class dynamically
|
||||
"""
|
||||
if not hasattr(self, u'_application'):
|
||||
self._application = Registry().get(u'application')
|
||||
return self._application
|
||||
|
||||
application = property(_get_application)
|
||||
|
||||
def get_soup_for_bible_ref(reference_url, header=None, pre_parse_regex=None,
|
||||
pre_parse_substitute=None, cleaner=None):
|
||||
"""
|
||||
@ -701,7 +694,7 @@ def get_soup_for_bible_ref(reference_url, header=None, pre_parse_regex=None,
|
||||
if not soup:
|
||||
send_error_message(u'parse')
|
||||
return None
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
Registry().get(u'application').process_events()
|
||||
return soup
|
||||
|
||||
def send_error_message(error_type):
|
||||
|
@ -30,7 +30,7 @@
|
||||
import logging
|
||||
import os
|
||||
|
||||
from openlp.core.lib import Receiver, SettingsManager, translate, Settings
|
||||
from openlp.core.lib import Receiver, SettingsManager, Settings, translate
|
||||
from openlp.core.utils import AppLocation, delete_file
|
||||
from openlp.plugins.bibles.lib import parse_reference, get_reference_separator, LanguageSelection
|
||||
from openlp.plugins.bibles.lib.db import BibleDB, BibleMeta
|
||||
|
@ -31,8 +31,8 @@ import logging
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
from openlp.core.lib import MediaManagerItem, Receiver, ItemCapabilities, translate, create_separated_list, \
|
||||
ServiceItemContext, Settings, UiStrings
|
||||
from openlp.core.lib import MediaManagerItem, Receiver, ItemCapabilities, ServiceItemContext, Settings, UiStrings, \
|
||||
create_separated_list, translate
|
||||
from openlp.core.lib.searchedit import SearchEdit
|
||||
from openlp.core.lib.ui import set_case_insensitive_completer, create_horizontal_adjusting_combo_box, \
|
||||
critical_error_message_box, find_and_set_in_combo_box, build_icon
|
||||
@ -349,7 +349,7 @@ class BibleMediaItem(MediaManagerItem):
|
||||
self.loadBibles()
|
||||
# If called from first time wizard re-run, process any new bibles.
|
||||
if process:
|
||||
self.plugin.appStartup()
|
||||
self.plugin.app_startup()
|
||||
self.updateAutoCompleter()
|
||||
|
||||
def initialiseAdvancedBible(self, bible, last_book_id=None):
|
||||
@ -614,7 +614,7 @@ class BibleMediaItem(MediaManagerItem):
|
||||
"""
|
||||
log.debug(u'Advanced Search Button clicked')
|
||||
self.advancedSearchButton.setEnabled(False)
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
self.application.process_events()
|
||||
bible = self.advancedVersionComboBox.currentText()
|
||||
second_bible = self.advancedSecondComboBox.currentText()
|
||||
book = self.advancedBookComboBox.currentText()
|
||||
@ -628,7 +628,7 @@ class BibleMediaItem(MediaManagerItem):
|
||||
verse_range = chapter_from + verse_separator + verse_from + range_separator + chapter_to + \
|
||||
verse_separator + verse_to
|
||||
versetext = u'%s %s' % (book, verse_range)
|
||||
Receiver.send_message(u'cursor_busy')
|
||||
self.application.set_busy_cursor()
|
||||
self.search_results = self.plugin.manager.get_verses(bible, versetext, book_ref_id)
|
||||
if second_bible:
|
||||
self.second_search_results = self.plugin.manager.get_verses(second_bible, versetext, book_ref_id)
|
||||
@ -640,8 +640,7 @@ class BibleMediaItem(MediaManagerItem):
|
||||
self.displayResults(bible, second_bible)
|
||||
self.advancedSearchButton.setEnabled(True)
|
||||
self.checkSearchResult()
|
||||
Receiver.send_message(u'cursor_normal')
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
self.application.set_normal_cursor()
|
||||
|
||||
def onQuickSearchButton(self):
|
||||
"""
|
||||
@ -650,7 +649,7 @@ class BibleMediaItem(MediaManagerItem):
|
||||
"""
|
||||
log.debug(u'Quick Search Button clicked')
|
||||
self.quickSearchButton.setEnabled(False)
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
self.application.process_events()
|
||||
bible = self.quickVersionComboBox.currentText()
|
||||
second_bible = self.quickSecondComboBox.currentText()
|
||||
text = self.quickSearchEdit.text()
|
||||
@ -662,7 +661,7 @@ class BibleMediaItem(MediaManagerItem):
|
||||
self.search_results[0].book.book_reference_id)
|
||||
else:
|
||||
# We are doing a 'Text Search'.
|
||||
Receiver.send_message(u'cursor_busy')
|
||||
self.application.set_busy_cursor()
|
||||
bibles = self.plugin.manager.get_bibles()
|
||||
self.search_results = self.plugin.manager.verse_search(bible, second_bible, text)
|
||||
if second_bible and self.search_results:
|
||||
@ -697,8 +696,7 @@ class BibleMediaItem(MediaManagerItem):
|
||||
self.displayResults(bible, second_bible)
|
||||
self.quickSearchButton.setEnabled(True)
|
||||
self.checkSearchResult()
|
||||
Receiver.send_message(u'cursor_normal')
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
self.application.set_normal_cursor()
|
||||
|
||||
def displayResults(self, bible, second_bible=u''):
|
||||
"""
|
||||
|
@ -31,7 +31,6 @@ import logging
|
||||
import sqlite
|
||||
import sys
|
||||
|
||||
from openlp.core.lib import Receiver
|
||||
from openlp.core.ui.wizard import WizardStrings
|
||||
from openlp.plugins.bibles.lib.db import BibleDB, BiblesResourcesDB
|
||||
|
||||
@ -108,7 +107,7 @@ class OpenLP1Bible(BibleDB):
|
||||
verse_number = int(verse[1])
|
||||
text = unicode(verse[2], u'cp1252')
|
||||
self.create_verse(db_book.id, chapter, verse_number, text)
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
self.application.process_events()
|
||||
self.session.commit()
|
||||
connection.close()
|
||||
return True
|
||||
|
@ -30,7 +30,7 @@
|
||||
import logging
|
||||
from lxml import etree, objectify
|
||||
|
||||
from openlp.core.lib import Receiver, translate
|
||||
from openlp.core.lib import translate
|
||||
from openlp.core.lib.ui import critical_error_message_box
|
||||
from openlp.plugins.bibles.lib.db import BibleDB, BiblesResourcesDB
|
||||
|
||||
@ -129,7 +129,7 @@ class OpenSongBible(BibleDB):
|
||||
self.wizard.incrementProgressBar(translate('BiblesPlugin.Opensong', 'Importing %s %s...',
|
||||
'Importing <book name> <chapter>...')) % (db_book.name, chapter_number)
|
||||
self.session.commit()
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
self.application.process_events()
|
||||
except etree.XMLSyntaxError as inst:
|
||||
critical_error_message_box(message=translate('BiblesPlugin.OpenSongImport',
|
||||
'Incorrect Bible file type supplied. OpenSong Bibles may be '
|
||||
|
@ -33,7 +33,7 @@ import chardet
|
||||
import codecs
|
||||
import re
|
||||
|
||||
from openlp.core.lib import Receiver, translate
|
||||
from openlp.core.lib import translate
|
||||
from openlp.core.utils import AppLocation
|
||||
from openlp.plugins.bibles.lib.db import BibleDB, BiblesResourcesDB
|
||||
|
||||
@ -182,7 +182,7 @@ class OSISBible(BibleDB):
|
||||
.replace(u'</div>', u'').replace(u'</w>', u'')
|
||||
verse_text = self.spaces_regex.sub(u' ', verse_text)
|
||||
self.create_verse(db_book.id, chapter, verse, verse_text)
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
self.application.process_events()
|
||||
self.session.commit()
|
||||
if match_count == 0:
|
||||
success = False
|
||||
|
@ -72,12 +72,12 @@ class VerseReferenceList(object):
|
||||
prev = index - 1
|
||||
if self.verse_list[prev][u'version'] != verse[u'version']:
|
||||
result = u'%s (%s)' % (result, self.verse_list[prev][u'version'])
|
||||
result = result + u', '
|
||||
result += u', '
|
||||
if self.verse_list[prev][u'book'] != verse[u'book']:
|
||||
result = u'%s%s %s:' % (result, verse[u'book'], verse[u'chapter'])
|
||||
elif self.verse_list[prev][u'chapter'] != verse[u'chapter']:
|
||||
result = u'%s%s:' % (result, verse[u'chapter'])
|
||||
result = result + str(verse[u'start'])
|
||||
result += str(verse[u'start'])
|
||||
if verse[u'start'] != verse[u'end']:
|
||||
result = u'%s-%s' % (result, verse[u'end'])
|
||||
if len(self.version_list) > 1:
|
||||
@ -89,8 +89,8 @@ class VerseReferenceList(object):
|
||||
for index, version in enumerate(self.version_list):
|
||||
if index > 0:
|
||||
if result[-1] not in [u';', u',', u'.']:
|
||||
result = result + u';'
|
||||
result = result + u' '
|
||||
result += u';'
|
||||
result += u' '
|
||||
result = u'%s%s, %s' % (result, version[u'version'], version[u'copyright'])
|
||||
if version[u'permission'].strip():
|
||||
result = result + u', ' + version[u'permission']
|
||||
|
@ -29,7 +29,7 @@
|
||||
|
||||
from PyQt4 import QtGui
|
||||
|
||||
from openlp.core.lib import build_icon, translate, UiStrings
|
||||
from openlp.core.lib import UiStrings, build_icon, translate
|
||||
from openlp.core.lib.ui import create_button_box, create_button
|
||||
|
||||
class Ui_CustomEditDialog(object):
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user