forked from openlp/openlp
Head and merge failures
This commit is contained in:
commit
b83b6eccd1
@ -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):
|
||||
"""
|
||||
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
|
||||
@ -134,50 +135,63 @@ 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)
|
||||
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.app_startup()
|
||||
self.main_window.app_startup()
|
||||
return self.exec_()
|
||||
|
||||
def isAlreadyRunning(self):
|
||||
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.exception_form = ExceptionForm(self.main_window)
|
||||
self.exception_form.exceptionTextEdit.setPlainText(''.join(format_exception(exctype, value, traceback)))
|
||||
self.set_normal_cursor()
|
||||
self.exceptionForm.exec_()
|
||||
self.exception_form.exec_()
|
||||
|
||||
def process_events(self):
|
||||
"""
|
||||
@ -287,7 +301,7 @@ def main(args=None):
|
||||
else:
|
||||
app.setApplicationName(u'OpenLP')
|
||||
set_up_logging(AppLocation.get_directory(AppLocation.CacheDir))
|
||||
registry = Registry.create()
|
||||
Registry.create()
|
||||
Registry().register(u'openlp_core', app)
|
||||
app.setApplicationVersion(get_application_version()[u'version'])
|
||||
# Instance check
|
||||
@ -310,3 +324,4 @@ def main(args=None):
|
||||
if not options.no_error_form:
|
||||
sys.excepthook = app.hookException
|
||||
sys.exit(app.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
|
||||
@ -109,14 +110,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 +160,7 @@ class BaseModel(object):
|
||||
instance.__setattr__(key, value)
|
||||
return instance
|
||||
|
||||
|
||||
class Manager(object):
|
||||
"""
|
||||
Provide generic object persistence management
|
||||
@ -205,19 +210,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
|
||||
)
|
||||
|
||||
|
@ -39,6 +39,7 @@ from openlp.core.lib import build_icon, ScreenList
|
||||
|
||||
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
|
||||
|
@ -33,6 +33,7 @@ import cPickle
|
||||
|
||||
from openlp.core.lib import translate, Settings
|
||||
|
||||
|
||||
class FormattingTags(object):
|
||||
"""
|
||||
Static Class to HTML Tags to be access around the code the list is managed
|
||||
|
@ -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
|
||||
|
@ -43,20 +43,27 @@ from openlp.core.lib import resize_image, image_to_byte, Receiver, Registry, Scr
|
||||
|
||||
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.
|
||||
@ -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
|
||||
@ -707,4 +728,3 @@ class MediaManagerItem(QtGui.QWidget):
|
||||
return self._openlp_core
|
||||
|
||||
openlp_core = property(_get_openlp_core)
|
||||
|
||||
|
@ -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.
|
||||
@ -434,5 +434,3 @@ class Plugin(QtCore.QObject):
|
||||
return self._openlp_core
|
||||
|
||||
openlp_core = property(_get_openlp_core)
|
||||
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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]
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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__
|
||||
|
@ -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.
|
||||
|
@ -43,6 +43,7 @@ from openlp.core.lib import build_icon, clean_tags, expand_tags, translate, Imag
|
||||
|
||||
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)
|
||||
|
@ -128,8 +128,8 @@ class Settings(QtCore.QSettings):
|
||||
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.
|
||||
# The other display settings (display position and dimensions) are defined in the ScreenList class due to a
|
||||
# circular dependency.
|
||||
u'general/override position': False,
|
||||
u'general/loop delay': 5,
|
||||
u'general/songselect username': u'',
|
||||
@ -277,6 +277,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:
|
||||
@ -341,4 +344,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,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.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):
|
||||
|
@ -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
|
||||
@ -609,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',
|
||||
@ -631,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,
|
||||
@ -648,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))
|
||||
|
||||
|
@ -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
|
||||
@ -206,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]
|
||||
@ -223,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']
|
||||
|
@ -34,7 +34,14 @@ 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
|
||||
|
@ -36,7 +36,7 @@ import sys
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
from openlp.core.lib import SettingsTab, translate, build_icon, Receiver, Settings, UiStrings
|
||||
from openlp.core.lib import SettingsTab, Receiver, Settings, UiStrings, translate, build_icon
|
||||
from openlp.core.utils import get_images_filter, AppLocation, format_time
|
||||
from openlp.core.lib import SlideLimits
|
||||
|
||||
@ -137,7 +137,7 @@ class AdvancedTab(SettingsTab):
|
||||
self.data_directory_layout = QtGui.QFormLayout(self.data_directory_group_box)
|
||||
self.data_directory_layout.setObjectName(u'data_directory_layout')
|
||||
self.data_directory_current_label = QtGui.QLabel(self.data_directory_group_box)
|
||||
self.data_directory_current_label.setObjectName( u'data_directory_current_label')
|
||||
self.data_directory_current_label.setObjectName(u'data_directory_current_label')
|
||||
self.data_directory_label = QtGui.QLabel(self.data_directory_group_box)
|
||||
self.data_directory_label.setObjectName(u'data_directory_label')
|
||||
self.data_directory_new_label = QtGui.QLabel(self.data_directory_group_box)
|
||||
@ -314,7 +314,7 @@ class AdvancedTab(SettingsTab):
|
||||
self.service_name_edit.setToolTip(translate('OpenLP.AdvancedTab', 'Consult the OpenLP manual for usage.'))
|
||||
self.service_name_revert_button.setToolTip(
|
||||
translate('OpenLP.AdvancedTab', 'Revert to the default service name "%s".') %
|
||||
UiStrings().DefaultServiceName)
|
||||
UiStrings().DefaultServiceName)
|
||||
self.service_name_example_label.setText(translate('OpenLP.AdvancedTab', 'Example:'))
|
||||
self.hide_mouse_group_box.setTitle(translate('OpenLP.AdvancedTab', 'Mouse Cursor'))
|
||||
self.hide_mouse_check_box.setText(translate('OpenLP.AdvancedTab', 'Hide mouse cursor when over display window'))
|
||||
@ -461,9 +461,8 @@ class AdvancedTab(SettingsTab):
|
||||
|
||||
def cancel(self):
|
||||
"""
|
||||
Cancel Pressed.
|
||||
Dialogue was cancelled, remove any pending data path change.
|
||||
"""
|
||||
# Dialogue was cancelled, remove any pending data path change.
|
||||
self.on_data_directory_cancel_button_clicked()
|
||||
SettingsTab.cancel(self)
|
||||
|
||||
@ -490,8 +489,10 @@ class AdvancedTab(SettingsTab):
|
||||
if day_delta < 0:
|
||||
day_delta += 7
|
||||
time = now + timedelta(days=day_delta)
|
||||
local_time = time.replace(hour = self.service_name_time.time().hour(),
|
||||
minute = self.service_name_time.time().minute())
|
||||
local_time = time.replace(
|
||||
hour=self.service_name_time.time().hour(),
|
||||
minute=self.service_name_time.time().minute()
|
||||
)
|
||||
try:
|
||||
service_name_example = format_time(unicode(self.service_name_edit.text()), local_time)
|
||||
except ValueError:
|
||||
@ -501,7 +502,7 @@ class AdvancedTab(SettingsTab):
|
||||
|
||||
def update_service_name_example(self, returned_value):
|
||||
"""
|
||||
Example Updated
|
||||
Update the example service name.
|
||||
"""
|
||||
if not self.should_update_service_name_example:
|
||||
return
|
||||
@ -510,21 +511,21 @@ class AdvancedTab(SettingsTab):
|
||||
|
||||
def on_service_name_day_changed(self, service_day):
|
||||
"""
|
||||
Service Name day changed
|
||||
React to the day of the service name changing.
|
||||
"""
|
||||
self.service_name_time.setEnabled(service_day is not 7)
|
||||
self.update_service_name_example(None)
|
||||
|
||||
def on_service_name_revert_button_clicked(self):
|
||||
"""
|
||||
Service Name reverted
|
||||
Revert to the default service name.
|
||||
"""
|
||||
self.service_name_edit.setText(UiStrings().DefaultServiceName)
|
||||
self.service_name_edit.setFocus()
|
||||
|
||||
def on_default_color_button_clicked(self):
|
||||
"""
|
||||
Changed the default color
|
||||
Select the background colour of the default display screen.
|
||||
"""
|
||||
new_color = QtGui.QColorDialog.getColor(
|
||||
QtGui.QColor(self.default_color), self)
|
||||
@ -534,7 +535,7 @@ class AdvancedTab(SettingsTab):
|
||||
|
||||
def on_default_browse_button_clicked(self):
|
||||
"""
|
||||
Service Name options changed
|
||||
Select an image for the default display screen.
|
||||
"""
|
||||
file_filters = u'%s;;%s (*.*) (*)' % (get_images_filter(), UiStrings().AllFiles)
|
||||
filename = QtGui.QFileDialog.getOpenFileName(self,
|
||||
@ -549,9 +550,9 @@ class AdvancedTab(SettingsTab):
|
||||
"""
|
||||
old_root_path = unicode(self.data_directory_label.text())
|
||||
# Get the new directory location.
|
||||
new_data_path = QtGui.QFileDialog.getExistingDirectory(self,
|
||||
translate('OpenLP.AdvancedTab', 'Select Data Directory Location'), old_root_path,
|
||||
options = QtGui.QFileDialog.ShowDirsOnly)
|
||||
new_data_path = QtGui.QFileDialog.getExistingDirectory(
|
||||
self, translate('OpenLP.AdvancedTab', 'Select Data Directory Location'), old_root_path,
|
||||
options=QtGui.QFileDialog.ShowDirsOnly)
|
||||
# Set the new data path.
|
||||
if new_data_path:
|
||||
new_data_path = os.path.normpath(new_data_path)
|
||||
@ -602,8 +603,8 @@ class AdvancedTab(SettingsTab):
|
||||
|
||||
def on_data_directory_copy_check_box_toggled(self):
|
||||
"""
|
||||
Service Name options changed
|
||||
"""
|
||||
Copy existing data when you change your data directory.
|
||||
"""
|
||||
Receiver.send_message(u'set_copy_data',
|
||||
self.data_directory_copy_check_box.isChecked())
|
||||
if self.data_exists:
|
||||
@ -614,8 +615,8 @@ class AdvancedTab(SettingsTab):
|
||||
|
||||
def check_data_overwrite(self, data_path ):
|
||||
"""
|
||||
Service Name options changed
|
||||
"""
|
||||
Check if there's already data in the target directory.
|
||||
"""
|
||||
test_path = os.path.join(data_path, u'songs')
|
||||
self.data_directory_copy_check_box.show()
|
||||
if os.path.exists(test_path):
|
||||
@ -652,8 +653,8 @@ class AdvancedTab(SettingsTab):
|
||||
|
||||
def on_default_revert_button_clicked(self):
|
||||
"""
|
||||
Service Name options changed
|
||||
"""
|
||||
Revert the default screen back to the default settings.
|
||||
"""
|
||||
self.default_file_edit.setText(u':/graphics/openlp-splash-screen.png')
|
||||
self.default_file_edit.setFocus()
|
||||
|
||||
|
@ -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
|
||||
@ -92,22 +95,32 @@ 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()
|
||||
@ -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
|
||||
@ -45,14 +47,15 @@ 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
|
||||
@ -79,7 +82,10 @@ 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
|
||||
@ -90,7 +96,7 @@ class FirstTimeForm(QtGui.QWizard, Ui_FirstTimeWizard):
|
||||
files = self.webAccess.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)
|
||||
@ -239,7 +245,7 @@ class FirstTimeForm(QtGui.QWizard, Ui_FirstTimeWizard):
|
||||
(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)
|
||||
self.openlp_core.set_normal_cursor()
|
||||
@ -264,7 +270,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
|
||||
@ -273,7 +279,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):
|
||||
@ -294,11 +300,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
|
||||
@ -456,6 +471,9 @@ 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)
|
||||
|
||||
|
@ -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,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 formatting tags window.
|
||||
"""
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
from openlp.core.lib import translate, UiStrings
|
||||
@ -34,8 +36,13 @@ 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,10 +27,9 @@
|
||||
# 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
|
||||
|
||||
@ -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,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 general tab of the configuration dialog.
|
||||
"""
|
||||
import logging
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
@ -34,6 +37,7 @@ from openlp.core.lib import Receiver, Settings, SettingsTab, translate, ScreenLi
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class GeneralTab(SettingsTab):
|
||||
"""
|
||||
GeneralTab is the general settings tab in the settings dialog.
|
||||
|
@ -27,12 +27,16 @@
|
||||
# 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
|
||||
@ -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:
|
||||
@ -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)
|
||||
|
||||
@ -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,
|
||||
@ -542,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()
|
||||
@ -550,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):
|
||||
@ -596,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
|
||||
@ -609,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()
|
||||
@ -619,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
|
||||
@ -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'))
|
||||
@ -517,7 +523,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,7 +533,8 @@ 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)
|
||||
@ -583,11 +590,17 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
||||
self.openlp_core.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()
|
||||
@ -638,16 +651,18 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
||||
self.openlp_core.process_events()
|
||||
for plugin in self.plugin_manager.plugins:
|
||||
if plugin.isActive():
|
||||
plugin.appStartup()
|
||||
plugin.app_startup()
|
||||
self.openlp_core.process_events()
|
||||
|
||||
def firstTime(self):
|
||||
# Import themes if first time
|
||||
def first_time(self):
|
||||
"""
|
||||
Import themes if first time
|
||||
"""
|
||||
self.openlp_core.process_events()
|
||||
for plugin in self.plugin_manager.plugins:
|
||||
if hasattr(plugin, u'firstTime'):
|
||||
if hasattr(plugin, u'first_time'):
|
||||
self.openlp_core.process_events()
|
||||
plugin.firstTime()
|
||||
plugin.first_time()
|
||||
self.openlp_core.process_events()
|
||||
temp_dir = os.path.join(unicode(gettempdir()), u'openlp')
|
||||
shutil.rmtree(temp_dir, True)
|
||||
@ -670,9 +685,9 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
||||
if answer == QtGui.QMessageBox.No:
|
||||
return
|
||||
screens = ScreenList()
|
||||
first_time = FirstTimeForm(screens, self)
|
||||
first_time.exec_()
|
||||
if first_time.downloadCancelled:
|
||||
first_run_wizard = FirstTimeForm(screens, self)
|
||||
first_run_wizard.exec_()
|
||||
if first_run_wizard.was_download_cancelled:
|
||||
return
|
||||
self.openlp_core.set_busy_cursor()
|
||||
self.first_time()
|
||||
@ -683,7 +698,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
||||
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()
|
||||
@ -706,14 +721,23 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
||||
translate('OpenLP.MainWindow', 'The Main Display has been blanked out'))
|
||||
|
||||
def onErrorMessage(self, data):
|
||||
"""
|
||||
Display an error message
|
||||
"""
|
||||
Receiver.send_message(u'close_splash')
|
||||
QtGui.QMessageBox.critical(self, data[u'title'], data[u'message'])
|
||||
|
||||
def onWarningMessage(self, data):
|
||||
"""
|
||||
Display a warning message
|
||||
"""
|
||||
Receiver.send_message(u'close_splash')
|
||||
QtGui.QMessageBox.warning(self, data[u'title'], data[u'message'])
|
||||
|
||||
def onInformationMessage(self, data):
|
||||
"""
|
||||
Display an informational message
|
||||
"""
|
||||
Receiver.send_message(u'close_splash')
|
||||
QtGui.QMessageBox.information(self, data[u'title'], data[u'message'])
|
||||
|
||||
@ -801,8 +825,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 = []
|
||||
@ -981,7 +1005,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
||||
"""
|
||||
log.debug(u'screenChanged')
|
||||
self.openlp_core.set_busy_cursor()
|
||||
self.imageManager.updateDisplay()
|
||||
self.imageManager.update_display()
|
||||
self.renderer.update_display()
|
||||
self.previewController.screenSizeChanged()
|
||||
self.liveController.screenSizeChanged()
|
||||
@ -995,7 +1019,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.
|
||||
@ -1037,8 +1061,8 @@ 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.clean_up()
|
||||
@ -1101,18 +1125,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):
|
||||
@ -1296,13 +1335,22 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
||||
self.openlp_core.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.openlp_core.set_busy_cursor()
|
||||
@ -1341,4 +1389,4 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
||||
self._openlp_core = Registry().get(u'openlp_core')
|
||||
return self._openlp_core
|
||||
|
||||
openlp_core = property(_get_openlp_core)
|
||||
openlp_core = property(_get_openlp_core)
|
||||
|
@ -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,7 +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.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
|
||||
@ -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])
|
||||
|
@ -26,10 +26,17 @@
|
||||
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||
###############################################################################
|
||||
<<<<<<< TREE
|
||||
|
||||
from openlp.core.lib import Registry
|
||||
=======
|
||||
"""
|
||||
The :mod:`~openlp.core.ui.media.mediaplayer` module contains the MediaPlayer class.
|
||||
"""
|
||||
>>>>>>> MERGE-SOURCE
|
||||
from openlp.core.ui.media import MediaState
|
||||
|
||||
|
||||
class MediaPlayer(object):
|
||||
"""
|
||||
This is the base class media Player class to provide OpenLP with a
|
||||
@ -37,6 +44,9 @@ class MediaPlayer(object):
|
||||
"""
|
||||
|
||||
def __init__(self, parent, name=u'media_player'):
|
||||
"""
|
||||
Constructor
|
||||
"""
|
||||
self.parent = parent
|
||||
self.name = name
|
||||
self.available = self.check_available()
|
||||
|
@ -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
|
||||
@ -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
|
||||
@ -156,9 +174,15 @@ class PhononPlayer(MediaPlayer):
|
||||
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.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
|
||||
|
||||
|
||||
@ -46,6 +52,9 @@ class PlayerTab(SettingsTab):
|
||||
MediaTab is the Media settings tab in the settings dialog.
|
||||
"""
|
||||
def __init__(self, parent):
|
||||
"""
|
||||
Constructor
|
||||
"""
|
||||
self.mediaPlayers = self.media_controller.mediaPlayers
|
||||
self.savedUsedPlayers = None
|
||||
self.iconPath = u':/media/multimedia-player.png'
|
||||
@ -53,6 +62,9 @@ class PlayerTab(SettingsTab):
|
||||
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)
|
||||
@ -114,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)
|
||||
@ -123,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:
|
||||
@ -139,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():
|
||||
@ -150,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
|
||||
@ -159,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
|
||||
@ -168,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]
|
||||
@ -181,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)
|
||||
@ -209,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
|
||||
@ -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
|
||||
@ -179,9 +193,15 @@ class VlcPlayer(MediaPlayer):
|
||||
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,8 +26,10 @@
|
||||
# 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
|
||||
|
||||
@ -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,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 of the plugin view dialog
|
||||
#"""
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
from openlp.core.lib import translate, UiStrings
|
||||
@ -34,7 +36,13 @@ 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,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 actual plugin view form
|
||||
"""
|
||||
import logging
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
@ -36,11 +38,15 @@ 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
|
||||
@ -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,6 +115,9 @@ 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
|
||||
@ -119,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:
|
||||
self.openlp_core.set_busy_cursor()
|
||||
self.activePlugin.toggleStatus(PluginStatus.Active)
|
||||
self.openlp_core.set_normal_cursor()
|
||||
self.activePlugin.appStartup()
|
||||
self.activePlugin.app_startup()
|
||||
else:
|
||||
self.activePlugin.toggleStatus(PluginStatus.Inactive)
|
||||
status_text = translate('OpenLP.PluginForm', '%s (Inactive)')
|
||||
|
@ -26,11 +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 UI widgets of the print service dialog.
|
||||
"""
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
from openlp.core.lib import build_icon, translate, SpellTextEdit, UiStrings
|
||||
|
||||
|
||||
class ZoomSize(object):
|
||||
"""
|
||||
Type enumeration for Combo Box sizes
|
||||
@ -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
|
||||
@ -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()
|
||||
@ -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
|
||||
|
@ -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,7 +42,7 @@ log = logging.getLogger(__name__)
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
from openlp.core.lib import OpenLPToolbar, ServiceItem, Receiver, build_icon, ItemCapabilities, SettingsManager, \
|
||||
from openlp.core.lib import OpenLPToolbar, ServiceItem, Receiver, build_icon, ItemCapabilities, \
|
||||
translate, str_to_bool, check_directory_exists, Settings, PluginStatus, Registry, UiStrings
|
||||
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
|
||||
@ -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,6 +100,7 @@ class ServiceManagerList(QtGui.QTreeWidget):
|
||||
mime_data.setText(u'ServiceManager')
|
||||
drag.start(QtCore.Qt.CopyAction)
|
||||
|
||||
|
||||
class ServiceManagerDialog(object):
|
||||
"""
|
||||
UI part of the Service Manager
|
||||
@ -401,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.getOpenFileName(self.main_window,
|
||||
file_name = QtGui.QFileDialog.getOpenFileName(
|
||||
self.main_window,
|
||||
translate('OpenLP.ServiceManager', 'Open File'),
|
||||
Settings().value(self.main_window.serviceManagerSettingsSection + u'/last directory'),
|
||||
translate('OpenLP.ServiceManager', 'OpenLP Service Files (*.osz *.oszl)'))
|
||||
translate('OpenLP.ServiceManager', 'OpenLP Service Files (*.osz *.oszl)')
|
||||
)
|
||||
if not file_name:
|
||||
return False
|
||||
else:
|
||||
@ -809,8 +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)
|
||||
@ -819,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)
|
||||
@ -877,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.
|
||||
@ -893,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
|
||||
|
@ -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.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):
|
||||
|
@ -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'))
|
||||
|
@ -40,6 +40,7 @@ from settingsdialog import Ui_SettingsDialog
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class SettingsForm(QtGui.QDialog, Ui_SettingsDialog):
|
||||
"""
|
||||
Provide the form to manipulate the settings for OpenLP
|
||||
@ -61,6 +62,9 @@ class SettingsForm(QtGui.QDialog, Ui_SettingsDialog):
|
||||
self.playerTab = PlayerTab(self)
|
||||
|
||||
def exec_(self):
|
||||
"""
|
||||
Execute the form
|
||||
"""
|
||||
# load all the settings
|
||||
self.settingListWidget.clear()
|
||||
while self.stackedLayout.count():
|
||||
|
@ -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,7 +26,8 @@
|
||||
# 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
|
||||
|
||||
@ -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,7 +435,7 @@ 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', {
|
||||
|
@ -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
|
||||
@ -278,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); '
|
||||
@ -309,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()
|
||||
@ -454,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,
|
||||
@ -464,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)
|
||||
|
||||
@ -542,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,
|
||||
@ -599,6 +610,9 @@ class SlideController(DisplayController):
|
||||
self.toolbar.setWidgetVisible(self.hideMenuList)
|
||||
|
||||
def onSongBarHandler(self):
|
||||
"""
|
||||
Some song handler
|
||||
"""
|
||||
request = self.sender().text()
|
||||
slide_no = self.slideList[request]
|
||||
self.__updatePreviewSelection(slide_no)
|
||||
@ -725,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()
|
||||
@ -805,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)
|
||||
@ -1123,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)
|
||||
@ -1195,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:
|
||||
@ -1302,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())
|
||||
|
||||
@ -1362,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,30 @@
|
||||
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||
###############################################################################
|
||||
"""
|
||||
The splash screen
|
||||
"""
|
||||
from openlp.core.lib import Receiver
|
||||
|
||||
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,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 time dialog
|
||||
"""
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
from openlp.core.lib import translate, UiStrings
|
||||
@ -34,7 +36,13 @@ 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,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 actual start time form.
|
||||
"""
|
||||
from PyQt4 import QtGui
|
||||
|
||||
from starttimedialog import Ui_StartTimeDialog
|
||||
@ -34,11 +36,15 @@ from starttimedialog import Ui_StartTimeDialog
|
||||
from openlp.core.lib import translate, UiStrings, Registry
|
||||
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
|
||||
|
@ -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 wizard
|
||||
"""
|
||||
import logging
|
||||
import os
|
||||
|
||||
@ -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
|
||||
@ -71,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)
|
||||
@ -177,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():
|
||||
@ -443,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()
|
||||
|
||||
|
@ -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
|
||||
@ -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'
|
||||
@ -149,12 +155,13 @@ class ThemeManager(QtGui.QWidget):
|
||||
"""
|
||||
self.openlp_core.set_busy_cursor()
|
||||
files = SettingsManager.get_files(self.settingsSection, u'.otz')
|
||||
for file_name in files:
|
||||
file_name = os.path.join(self.path, file_name)
|
||||
self.unzip_theme(file_name, self.path)
|
||||
delete_file(file)
|
||||
for theme_file in files:
|
||||
theme_file = os.path.join(self.path, theme_file)
|
||||
self.unzipTheme(theme_file, self.path)
|
||||
delete_file(theme_file)
|
||||
self.openlp_core.set_normal_cursor()
|
||||
|
||||
|
||||
def config_updated(self):
|
||||
"""
|
||||
Triggered when Config dialog is updated.
|
||||
@ -197,7 +204,7 @@ class ThemeManager(QtGui.QWidget):
|
||||
tab
|
||||
"""
|
||||
log.debug(u'change_global_from_tab %s', theme_name)
|
||||
for count in range (0, self.theme_list_widget.count()):
|
||||
for count in range(0, self.theme_list_widget.count()):
|
||||
# reset the old name
|
||||
item = self.theme_list_widget.item(count)
|
||||
old_name = item.text()
|
||||
@ -218,7 +225,7 @@ class ThemeManager(QtGui.QWidget):
|
||||
"""
|
||||
log.debug(u'changeGlobalFromScreen %s', index)
|
||||
selected_row = self.theme_list_widget.currentRow()
|
||||
for count in range (0, self.theme_list_widget.count()):
|
||||
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
|
||||
@ -365,26 +372,29 @@ class ThemeManager(QtGui.QWidget):
|
||||
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_file = None
|
||||
theme_zip = None
|
||||
try:
|
||||
zip_file = 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_file.write(os.path.join(source, name).encode(u'utf-8'),
|
||||
os.path.join(theme, name).encode(u'utf-8'))
|
||||
QtGui.QMessageBox.information(self, translate('OpenLP.ThemeManager', 'Theme Exported'),
|
||||
theme_zip.write(
|
||||
os.path.join(source, 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'),
|
||||
translate('OpenLP.ThemeManager', 'Your theme could not be exported due to an error.'))
|
||||
finally:
|
||||
if zip_file:
|
||||
zip_file.close()
|
||||
if theme_zip:
|
||||
theme_zip.close()
|
||||
self.openlp_core.set_normal_cursor()
|
||||
|
||||
|
||||
def on_import_theme(self):
|
||||
"""
|
||||
Opens a file dialog to select the theme file(s) to import before
|
||||
@ -480,7 +490,7 @@ class ThemeManager(QtGui.QWidget):
|
||||
|
||||
def over_write_message_box(self, theme_name):
|
||||
"""
|
||||
Check before overwriting the theme
|
||||
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',
|
||||
@ -489,7 +499,7 @@ class ThemeManager(QtGui.QWidget):
|
||||
QtGui.QMessageBox.No)
|
||||
return ret == QtGui.QMessageBox.Yes
|
||||
|
||||
def unzip_theme(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
|
||||
@ -497,32 +507,31 @@ class ThemeManager(QtGui.QWidget):
|
||||
"""
|
||||
log.debug(u'Unzipping theme %s', file_name)
|
||||
file_name = unicode(file_name)
|
||||
zip_file = None
|
||||
theme_zip = None
|
||||
out_file = None
|
||||
file_xml = None
|
||||
abort_import = True
|
||||
try:
|
||||
zip_file = zipfile.ZipFile(file_name)
|
||||
xml_file = filter(lambda name:
|
||||
os.path.splitext(name)[1].lower() == u'.xml', zip_file.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('validation')
|
||||
xml_tree = ElementTree(element=XML(zip_file.read(xml_file[0]))).getroot()
|
||||
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.unzip_version_122(
|
||||
dir, zip_file, xml_file[0], xml_tree, v1_background, out_file)
|
||||
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.over_write_message_box(theme_name):
|
||||
abort_import = True
|
||||
return
|
||||
else:
|
||||
abort_import = False
|
||||
for name in zip_file.namelist():
|
||||
for name in theme_zip.namelist():
|
||||
try:
|
||||
uname = unicode(name, u'utf-8')
|
||||
except UnicodeDecodeError:
|
||||
@ -534,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_file.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_file.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)
|
||||
@ -555,18 +564,18 @@ class ThemeManager(QtGui.QWidget):
|
||||
raise
|
||||
finally:
|
||||
# Close the files, to be able to continue creating the theme.
|
||||
if zip_file:
|
||||
zip_file.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._create_theme_fom_Xml(file_xml, self.path)
|
||||
self.generate_and_save_image(dir, theme_name, theme)
|
||||
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.'))
|
||||
@ -626,9 +635,9 @@ class ThemeManager(QtGui.QWidget):
|
||||
"""
|
||||
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 _write_theme(self, theme, image_from, image_to):
|
||||
"""
|
||||
@ -660,11 +669,11 @@ class ThemeManager(QtGui.QWidget):
|
||||
log.exception(u'Failed to save theme image')
|
||||
self.generate_and_save_image(self.path, name, theme)
|
||||
|
||||
def generate_and_save_image(self, dir, name, theme):
|
||||
def generate_and_save_image(self, directory, name, theme):
|
||||
"""
|
||||
Generate and Save the theme image.
|
||||
Generate and save a preview image
|
||||
"""
|
||||
log.debug(u'generate_and_save_image %s %s', dir, name)
|
||||
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):
|
||||
|
@ -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 Themes configuration tab
|
||||
"""
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
from openlp.core.lib import Receiver, Settings, SettingsTab, translate, UiStrings
|
||||
@ -39,11 +41,17 @@ class ThemesTab(SettingsTab):
|
||||
ThemesTab is the theme settings tab in the settings dialog.
|
||||
"""
|
||||
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)
|
||||
@ -99,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'))
|
||||
@ -116,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')
|
||||
@ -129,6 +143,9 @@ 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)
|
||||
@ -139,18 +156,33 @@ class ThemesTab(SettingsTab):
|
||||
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.renderer.set_global_theme(self.global_theme)
|
||||
self.__previewGlobalTheme()
|
||||
|
@ -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.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 '
|
||||
|
@ -39,6 +39,7 @@ from openlp.core.lib.ui import add_welcome_page
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class WizardStrings(object):
|
||||
"""
|
||||
Provide standard strings for wizards to use.
|
||||
@ -80,6 +81,9 @@ class OpenLPWizard(QtGui.QWizard):
|
||||
and feel.
|
||||
"""
|
||||
def __init__(self, parent, plugin, name, image):
|
||||
"""
|
||||
Constructor
|
||||
"""
|
||||
QtGui.QWizard.__init__(self, parent)
|
||||
self.plugin = plugin
|
||||
self.setObjectName(name)
|
||||
|
@ -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
|
||||
@ -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')
|
||||
@ -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
|
||||
@ -41,6 +40,7 @@ from openlp.core.lib import translate, Settings
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class LanguageManager(object):
|
||||
"""
|
||||
Helper for Language selection
|
||||
|
@ -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'),
|
||||
|
@ -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'),
|
||||
|
@ -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):
|
||||
|
@ -41,35 +41,42 @@ from editcustomslideform import EditCustomSlideForm
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog):
|
||||
"""
|
||||
Class documentation goes here.
|
||||
"""
|
||||
log.info(u'Custom Editor loaded')
|
||||
|
||||
def __init__(self, mediaitem, parent, manager):
|
||||
"""
|
||||
Constructor
|
||||
"""
|
||||
QtGui.QDialog.__init__(self, parent)
|
||||
super(EditCustomForm, self).__init__(parent)
|
||||
self.manager = manager
|
||||
self.mediaitem = mediaitem
|
||||
self.setupUi(self)
|
||||
# Create other objects and forms.
|
||||
self.editSlideForm = EditCustomSlideForm(self)
|
||||
# Connecting signals and slots
|
||||
QtCore.QObject.connect(self.previewButton, QtCore.SIGNAL(u'clicked()'), self.onPreviewButtonClicked)
|
||||
QtCore.QObject.connect(self.addButton, QtCore.SIGNAL(u'clicked()'), self.onAddButtonClicked)
|
||||
QtCore.QObject.connect(self.editButton, QtCore.SIGNAL(u'clicked()'), self.onEditButtonClicked)
|
||||
QtCore.QObject.connect(self.editAllButton, QtCore.SIGNAL(u'clicked()'), self.onEditAllButtonClicked)
|
||||
self.previewButton.clicked.connect(self.on_preview_button_clicked)
|
||||
self.addButton.clicked.connect(self.on_add_button_clicked)
|
||||
self.editButton.clicked.connect(self.on_edit_button_clicked)
|
||||
self.editAllButton.clicked.connect(self.on_edit_all_button_clicked)
|
||||
self.slideListView.currentRowChanged.connect(self.on_current_row_changed)
|
||||
self.slideListView.doubleClicked.connect(self.on_edit_button_clicked)
|
||||
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'theme_update_list'), self.loadThemes)
|
||||
QtCore.QObject.connect(self.slideListView, QtCore.SIGNAL(u'currentRowChanged(int)'), self.onCurrentRowChanged)
|
||||
QtCore.QObject.connect(self.slideListView, QtCore.SIGNAL(u'doubleClicked(QModelIndex)'),
|
||||
self.onEditButtonClicked)
|
||||
|
||||
def loadThemes(self, themelist):
|
||||
def loadThemes(self, theme_list):
|
||||
"""
|
||||
Load a list of themes into the themes combo box.
|
||||
|
||||
``theme_list``
|
||||
The list of themes to load.
|
||||
"""
|
||||
self.themeComboBox.clear()
|
||||
self.themeComboBox.addItem(u'')
|
||||
self.themeComboBox.addItems(themelist)
|
||||
self.themeComboBox.addItems(theme_list)
|
||||
|
||||
def loadCustom(self, id, preview=False):
|
||||
"""
|
||||
@ -103,6 +110,9 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog):
|
||||
self.previewButton.setVisible(preview)
|
||||
|
||||
def accept(self):
|
||||
"""
|
||||
Override the QDialog method to check if the custom slide has been saved before closing the dialog.
|
||||
"""
|
||||
log.debug(u'accept')
|
||||
if self.saveCustom():
|
||||
QtGui.QDialog.accept(self)
|
||||
@ -125,6 +135,9 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog):
|
||||
return success
|
||||
|
||||
def onUpButtonClicked(self):
|
||||
"""
|
||||
Move a slide up in the list when the "Up" button is clicked.
|
||||
"""
|
||||
selectedRow = self.slideListView.currentRow()
|
||||
if selectedRow != 0:
|
||||
qw = self.slideListView.takeItem(selectedRow)
|
||||
@ -132,6 +145,9 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog):
|
||||
self.slideListView.setCurrentRow(selectedRow - 1)
|
||||
|
||||
def onDownButtonClicked(self):
|
||||
"""
|
||||
Move a slide down in the list when the "Down" button is clicked.
|
||||
"""
|
||||
selectedRow = self.slideListView.currentRow()
|
||||
# zero base arrays
|
||||
if selectedRow != self.slideListView.count() - 1:
|
||||
@ -139,17 +155,23 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog):
|
||||
self.slideListView.insertItem(selectedRow + 1, qw)
|
||||
self.slideListView.setCurrentRow(selectedRow + 1)
|
||||
|
||||
def onAddButtonClicked(self):
|
||||
def on_add_button_clicked(self):
|
||||
"""
|
||||
Add a new blank slide.
|
||||
"""
|
||||
self.editSlideForm.setText(u'')
|
||||
if self.editSlideForm.exec_():
|
||||
self.slideListView.addItems(self.editSlideForm.getText())
|
||||
|
||||
def onEditButtonClicked(self):
|
||||
def on_edit_button_clicked(self):
|
||||
"""
|
||||
Edit the currently selected slide.
|
||||
"""
|
||||
self.editSlideForm.setText(self.slideListView.currentItem().text())
|
||||
if self.editSlideForm.exec_():
|
||||
self.updateSlideList(self.editSlideForm.getText())
|
||||
|
||||
def onEditAllButtonClicked(self):
|
||||
def on_edit_all_button_clicked(self):
|
||||
"""
|
||||
Edits all slides.
|
||||
"""
|
||||
@ -163,7 +185,7 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog):
|
||||
if self.editSlideForm.exec_():
|
||||
self.updateSlideList(self.editSlideForm.getText(), True)
|
||||
|
||||
def onPreviewButtonClicked(self):
|
||||
def on_preview_button_clicked(self):
|
||||
"""
|
||||
Save the custom item and preview it.
|
||||
"""
|
||||
@ -203,9 +225,9 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog):
|
||||
Removes the current row from the list.
|
||||
"""
|
||||
self.slideListView.takeItem(self.slideListView.currentRow())
|
||||
self.onCurrentRowChanged(self.slideListView.currentRow())
|
||||
self.on_current_row_changed(self.slideListView.currentRow())
|
||||
|
||||
def onCurrentRowChanged(self, row):
|
||||
def on_current_row_changed(self, row):
|
||||
"""
|
||||
Called when the *slideListView*'s current row has been changed. This
|
||||
enables or disables buttons which require an slide to act on.
|
||||
|
@ -1,3 +1,4 @@
|
||||
#lint:disable
|
||||
# -*- coding: utf-8 -*-
|
||||
# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
|
||||
|
||||
@ -35,16 +36,18 @@ from editcustomslidedialog import Ui_CustomSlideEditDialog
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class EditCustomSlideForm(QtGui.QDialog, Ui_CustomSlideEditDialog):
|
||||
"""
|
||||
Class documentation goes here.
|
||||
"""
|
||||
log.info(u'Custom Verse Editor loaded')
|
||||
|
||||
def __init__(self, parent=None):
|
||||
"""
|
||||
Constructor
|
||||
"""
|
||||
QtGui.QDialog.__init__(self, parent)
|
||||
super(EditCustomSlideForm, self).__init__(parent)
|
||||
self.setupUi(self)
|
||||
# Connecting signals and slots
|
||||
QtCore.QObject.connect(self.insertButton, QtCore.SIGNAL(u'clicked()'), self.onInsertButtonClicked)
|
||||
@ -88,9 +91,10 @@ class EditCustomSlideForm(QtGui.QDialog, Ui_CustomSlideEditDialog):
|
||||
"""
|
||||
full_text = self.slideTextEdit.toPlainText()
|
||||
position = self.slideTextEdit.textCursor().position()
|
||||
if position and full_text[position-1] != u'\n':
|
||||
text = u'\n' + text
|
||||
if position == len(full_text) or full_text[position] != u'\n':
|
||||
text += u'\n'
|
||||
if position and full_text[position - 1] != u'\n':
|
||||
text = u'\n' + text
|
||||
if position == len(full_text) or full_text[position] != u'\n':
|
||||
text += u'\n'
|
||||
self.slideTextEdit.insertPlainText(text)
|
||||
|
||||
#lint:enable
|
||||
|
@ -98,4 +98,4 @@ class ImagePlugin(Plugin):
|
||||
last part of saving the config.
|
||||
"""
|
||||
background = QtGui.QColor(Settings().value(self.settingsSection + u'/background color'))
|
||||
self.liveController.imageManager.updateImagesBorder(ImageSource.ImagePlugin, background)
|
||||
self.liveController.imageManager.update_images_border(ImageSource.ImagePlugin, background)
|
||||
|
@ -118,13 +118,13 @@ class MediaPlugin(Plugin):
|
||||
"""
|
||||
return self.media_controller.get_media_display_html()
|
||||
|
||||
def appStartup(self):
|
||||
def app_startup(self):
|
||||
"""
|
||||
Do a couple of things when the app starts up. In this particular case
|
||||
we want to check if we have the old "Use Phonon" setting, and convert
|
||||
it to "enable Phonon" and "make it the first one in the list".
|
||||
"""
|
||||
Plugin.appStartup(self)
|
||||
Plugin.app_startup(self)
|
||||
settings = Settings()
|
||||
settings.beginGroup(self.settingsSection)
|
||||
if settings.contains(u'use phonon'):
|
||||
|
@ -33,6 +33,7 @@ from openlp.core.lib import translate
|
||||
from openlp.core.lib.ui import critical_error_message_box
|
||||
from openlp.plugins.songs.forms.songbookdialog import Ui_SongBookDialog
|
||||
|
||||
|
||||
class SongBookForm(QtGui.QDialog, Ui_SongBookDialog):
|
||||
"""
|
||||
Class documentation goes here.
|
||||
@ -41,10 +42,16 @@ class SongBookForm(QtGui.QDialog, Ui_SongBookDialog):
|
||||
"""
|
||||
Constructor
|
||||
"""
|
||||
QtGui.QDialog.__init__(self, parent)
|
||||
super(SongBookForm, self).__init__(parent)
|
||||
self.setupUi(self)
|
||||
|
||||
def exec_(self, clear=True):
|
||||
"""
|
||||
Execute the song book form.
|
||||
|
||||
``clear``
|
||||
Clear the fields on the form before displaying it.
|
||||
"""
|
||||
if clear:
|
||||
self.nameEdit.clear()
|
||||
self.publisherEdit.clear()
|
||||
@ -52,6 +59,9 @@ class SongBookForm(QtGui.QDialog, Ui_SongBookDialog):
|
||||
return QtGui.QDialog.exec_(self)
|
||||
|
||||
def accept(self):
|
||||
"""
|
||||
Override the inherited method to check that the name of the book has been typed in.
|
||||
"""
|
||||
if not self.nameEdit.text():
|
||||
critical_error_message_box(
|
||||
message=translate('SongsPlugin.SongBookForm', 'You need to type in a name for the book.'))
|
||||
|
@ -35,13 +35,14 @@ import os
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
from openlp.core.lib import Settings, SettingsManager, translate, UiStrings
|
||||
from openlp.core.lib import Settings, translate, UiStrings
|
||||
from openlp.core.lib.ui import critical_error_message_box
|
||||
from openlp.core.ui.wizard import OpenLPWizard, WizardStrings
|
||||
from openlp.plugins.songs.lib.importer import SongFormat, SongFormatSelect
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class SongImportForm(OpenLPWizard):
|
||||
"""
|
||||
This is the Song Import Wizard, which allows easy importing of Songs
|
||||
@ -211,17 +212,17 @@ class SongImportForm(OpenLPWizard):
|
||||
if self.currentPage() == self.welcomePage:
|
||||
return True
|
||||
elif self.currentPage() == self.sourcePage:
|
||||
format = self.currentFormat
|
||||
Settings().setValue(u'songs/last import type', format)
|
||||
select_mode, class_, error_msg = SongFormat.get(format, u'selectMode', u'class', u'invalidSourceMsg')
|
||||
this_format = self.currentFormat
|
||||
Settings().setValue(u'songs/last import type', this_format)
|
||||
select_mode, class_, error_msg = SongFormat.get(this_format, u'selectMode', u'class', u'invalidSourceMsg')
|
||||
if select_mode == SongFormatSelect.MultipleFiles:
|
||||
import_source = self.getListOfFiles(self.formatWidgets[format][u'fileListWidget'])
|
||||
import_source = self.getListOfFiles(self.formatWidgets[this_format][u'fileListWidget'])
|
||||
error_title = UiStrings().IFSp
|
||||
focus_button = self.formatWidgets[format][u'addButton']
|
||||
focus_button = self.formatWidgets[this_format][u'addButton']
|
||||
else:
|
||||
import_source = self.formatWidgets[format][u'filepathEdit'].text()
|
||||
import_source = self.formatWidgets[this_format][u'filepathEdit'].text()
|
||||
error_title = (UiStrings().IFSs if select_mode == SongFormatSelect.SingleFile else UiStrings().IFdSs)
|
||||
focus_button = self.formatWidgets[format][u'browseButton']
|
||||
focus_button = self.formatWidgets[this_format][u'browseButton']
|
||||
if not class_.isValidSource(import_source):
|
||||
critical_error_message_box(error_title, error_msg)
|
||||
focus_button.setFocus()
|
||||
@ -271,25 +272,35 @@ class SongImportForm(OpenLPWizard):
|
||||
del item
|
||||
|
||||
def onBrowseButtonClicked(self):
|
||||
format = self.currentFormat
|
||||
select_mode, format_name, filter = SongFormat.get(format, u'selectMode',
|
||||
"""
|
||||
Browse for files or a directory.
|
||||
"""
|
||||
this_format = self.currentFormat
|
||||
select_mode, format_name, ext_filter = SongFormat.get(this_format, u'selectMode',
|
||||
u'name', u'filter')
|
||||
filepathEdit = self.formatWidgets[format][u'filepathEdit']
|
||||
filepathEdit = self.formatWidgets[this_format][u'filepathEdit']
|
||||
if select_mode == SongFormatSelect.SingleFile:
|
||||
self.getFileName(WizardStrings.OpenTypeFile % format_name, filepathEdit, u'last directory import', filter)
|
||||
self.getFileName(WizardStrings.OpenTypeFile % format_name, filepathEdit,
|
||||
u'last directory import', ext_filter)
|
||||
elif select_mode == SongFormatSelect.SingleFolder:
|
||||
self.getFolder(WizardStrings.OpenTypeFolder % format_name, filepathEdit, u'last directory import')
|
||||
|
||||
def onAddButtonClicked(self):
|
||||
format = self.currentFormat
|
||||
select_mode, format_name, filter, custom_title = \
|
||||
SongFormat.get(format, u'selectMode', u'name', u'filter', u'getFilesTitle')
|
||||
"""
|
||||
Add a file or directory.
|
||||
"""
|
||||
this_format = self.currentFormat
|
||||
select_mode, format_name, ext_filter, custom_title = \
|
||||
SongFormat.get(this_format, u'selectMode', u'name', u'filter', u'getFilesTitle')
|
||||
title = custom_title if custom_title else WizardStrings.OpenTypeFile % format_name
|
||||
if select_mode == SongFormatSelect.MultipleFiles:
|
||||
self.getFiles(title, self.formatWidgets[format][u'fileListWidget'], filter)
|
||||
self.getFiles(title, self.formatWidgets[this_format][u'fileListWidget'], ext_filter)
|
||||
self.sourcePage.emit(QtCore.SIGNAL(u'completeChanged()'))
|
||||
|
||||
def onRemoveButtonClicked(self):
|
||||
"""
|
||||
Remove a file from the list.
|
||||
"""
|
||||
self.removeSelectedItems(
|
||||
self.formatWidgets[self.currentFormat][u'fileListWidget'])
|
||||
self.sourcePage.emit(QtCore.SIGNAL(u'completeChanged()'))
|
||||
@ -340,10 +351,10 @@ class SongImportForm(OpenLPWizard):
|
||||
select_mode = SongFormat.get(source_format, u'selectMode')
|
||||
if select_mode == SongFormatSelect.SingleFile:
|
||||
importer = self.plugin.importSongs(source_format,
|
||||
filename = self.formatWidgets[source_format][u'filepathEdit'].text())
|
||||
filename=self.formatWidgets[source_format][u'filepathEdit'].text())
|
||||
elif select_mode == SongFormatSelect.SingleFolder:
|
||||
importer = self.plugin.importSongs(source_format,
|
||||
folder = self.formatWidgets[source_format][u'filepathEdit'].text())
|
||||
folder=self.formatWidgets[source_format][u'filepathEdit'].text())
|
||||
else:
|
||||
importer = self.plugin.importSongs(source_format,
|
||||
filenames=self.getListOfFiles(self.formatWidgets[source_format][u'fileListWidget']))
|
||||
@ -369,9 +380,12 @@ class SongImportForm(OpenLPWizard):
|
||||
report_file.close()
|
||||
|
||||
def addFileSelectItem(self):
|
||||
format = self.currentFormat
|
||||
"""
|
||||
Add a file selection page.
|
||||
"""
|
||||
this_format = self.currentFormat
|
||||
prefix, can_disable, description_text, select_mode = \
|
||||
SongFormat.get(format, u'prefix', u'canDisable', u'descriptionText', u'selectMode')
|
||||
SongFormat.get(this_format, u'prefix', u'canDisable', u'descriptionText', u'selectMode')
|
||||
page = QtGui.QWidget()
|
||||
page.setObjectName(prefix + u'Page')
|
||||
if can_disable:
|
||||
@ -392,8 +406,8 @@ class SongImportForm(OpenLPWizard):
|
||||
descriptionLabel.setObjectName(prefix + u'DescriptionLabel')
|
||||
descriptionLayout.addWidget(descriptionLabel)
|
||||
importLayout.addLayout(descriptionLayout)
|
||||
self.formatWidgets[format][u'descriptionLabel'] = descriptionLabel
|
||||
self.formatWidgets[format][u'descriptionSpacer'] = descriptionSpacer
|
||||
self.formatWidgets[this_format][u'descriptionLabel'] = descriptionLabel
|
||||
self.formatWidgets[this_format][u'descriptionSpacer'] = descriptionSpacer
|
||||
if select_mode == SongFormatSelect.SingleFile or select_mode == SongFormatSelect.SingleFolder:
|
||||
filepathLayout = QtGui.QHBoxLayout()
|
||||
filepathLayout.setObjectName(prefix + u'FilepathLayout')
|
||||
@ -412,11 +426,11 @@ class SongImportForm(OpenLPWizard):
|
||||
filepathLayout.addWidget(browseButton)
|
||||
importLayout.addLayout(filepathLayout)
|
||||
importLayout.addSpacerItem(self.stackSpacer)
|
||||
self.formatWidgets[format][u'filepathLabel'] = filepathLabel
|
||||
self.formatWidgets[format][u'filepathSpacer'] = filepathSpacer
|
||||
self.formatWidgets[format][u'filepathLayout'] = filepathLayout
|
||||
self.formatWidgets[format][u'filepathEdit'] = filepathEdit
|
||||
self.formatWidgets[format][u'browseButton'] = browseButton
|
||||
self.formatWidgets[this_format][u'filepathLabel'] = filepathLabel
|
||||
self.formatWidgets[this_format][u'filepathSpacer'] = filepathSpacer
|
||||
self.formatWidgets[this_format][u'filepathLayout'] = filepathLayout
|
||||
self.formatWidgets[this_format][u'filepathEdit'] = filepathEdit
|
||||
self.formatWidgets[this_format][u'browseButton'] = browseButton
|
||||
elif select_mode == SongFormatSelect.MultipleFiles:
|
||||
fileListWidget = QtGui.QListWidget(importWidget)
|
||||
fileListWidget.setSelectionMode(QtGui.QAbstractItemView.ExtendedSelection)
|
||||
@ -434,18 +448,21 @@ class SongImportForm(OpenLPWizard):
|
||||
removeButton.setObjectName(prefix + u'RemoveButton')
|
||||
buttonLayout.addWidget(removeButton)
|
||||
importLayout.addLayout(buttonLayout)
|
||||
self.formatWidgets[format][u'fileListWidget'] = fileListWidget
|
||||
self.formatWidgets[format][u'buttonLayout'] = buttonLayout
|
||||
self.formatWidgets[format][u'addButton'] = addButton
|
||||
self.formatWidgets[format][u'removeButton'] = removeButton
|
||||
self.formatWidgets[this_format][u'fileListWidget'] = fileListWidget
|
||||
self.formatWidgets[this_format][u'buttonLayout'] = buttonLayout
|
||||
self.formatWidgets[this_format][u'addButton'] = addButton
|
||||
self.formatWidgets[this_format][u'removeButton'] = removeButton
|
||||
self.formatStack.addWidget(page)
|
||||
self.formatWidgets[format][u'page'] = page
|
||||
self.formatWidgets[format][u'importLayout'] = importLayout
|
||||
self.formatWidgets[this_format][u'page'] = page
|
||||
self.formatWidgets[this_format][u'importLayout'] = importLayout
|
||||
self.formatComboBox.addItem(u'')
|
||||
|
||||
def disablableWidget(self, page, prefix):
|
||||
format = self.currentFormat
|
||||
self.disablableFormats.append(format)
|
||||
"""
|
||||
Disable a widget.
|
||||
"""
|
||||
this_format = self.currentFormat
|
||||
self.disablableFormats.append(this_format)
|
||||
layout = QtGui.QVBoxLayout(page)
|
||||
layout.setMargin(0)
|
||||
layout.setSpacing(0)
|
||||
@ -465,11 +482,11 @@ class SongImportForm(OpenLPWizard):
|
||||
importWidget = QtGui.QWidget(page)
|
||||
importWidget.setObjectName(prefix + u'ImportWidget')
|
||||
layout.addWidget(importWidget)
|
||||
self.formatWidgets[format][u'layout'] = layout
|
||||
self.formatWidgets[format][u'disabledWidget'] = disabledWidget
|
||||
self.formatWidgets[format][u'disabledLayout'] = disabledLayout
|
||||
self.formatWidgets[format][u'disabledLabel'] = disabledLabel
|
||||
self.formatWidgets[format][u'importWidget'] = importWidget
|
||||
self.formatWidgets[this_format][u'layout'] = layout
|
||||
self.formatWidgets[this_format][u'disabledWidget'] = disabledWidget
|
||||
self.formatWidgets[this_format][u'disabledLayout'] = disabledLayout
|
||||
self.formatWidgets[this_format][u'disabledLabel'] = disabledLabel
|
||||
self.formatWidgets[this_format][u'importWidget'] = importWidget
|
||||
return importWidget
|
||||
|
||||
|
||||
@ -489,14 +506,14 @@ class SongImportSourcePage(QtGui.QWizardPage):
|
||||
When this method returns True, the wizard's Next button is enabled.
|
||||
"""
|
||||
wizard = self.wizard()
|
||||
format = wizard.currentFormat
|
||||
select_mode, format_available = SongFormat.get(format, u'selectMode', u'availability')
|
||||
this_format = wizard.currentFormat
|
||||
select_mode, format_available = SongFormat.get(this_format, u'selectMode', u'availability')
|
||||
if format_available:
|
||||
if select_mode == SongFormatSelect.MultipleFiles:
|
||||
if wizard.formatWidgets[format][u'fileListWidget'].count() > 0:
|
||||
if wizard.formatWidgets[this_format][u'fileListWidget'].count() > 0:
|
||||
return True
|
||||
else:
|
||||
filepath = unicode(wizard.formatWidgets[format][u'filepathEdit'].text())
|
||||
filepath = unicode(wizard.formatWidgets[this_format][u'filepathEdit'].text())
|
||||
if filepath:
|
||||
if select_mode == SongFormatSelect.SingleFile and os.path.isfile(filepath):
|
||||
return True
|
||||
|
@ -39,6 +39,7 @@ from songmaintenancedialog import Ui_SongMaintenanceDialog
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
|
||||
"""
|
||||
Class documentation goes here.
|
||||
@ -47,7 +48,7 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
|
||||
"""
|
||||
Constructor
|
||||
"""
|
||||
QtGui.QDialog.__init__(self, parent)
|
||||
super(SongMaintenanceForm, self).__init__(parent)
|
||||
self.setupUi(self)
|
||||
self.manager = manager
|
||||
self.authorform = AuthorsForm(self)
|
||||
@ -93,8 +94,14 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
|
||||
self.typeListWidget.setFocus()
|
||||
return QtGui.QDialog.exec_(self)
|
||||
|
||||
def _getCurrentItemId(self, listWidget):
|
||||
item = listWidget.currentItem()
|
||||
def _getCurrentItemId(self, list_widget):
|
||||
"""
|
||||
Get the ID of the currently selected item.
|
||||
|
||||
``list_widget``
|
||||
The list widget to examine.
|
||||
"""
|
||||
item = list_widget.currentItem()
|
||||
if item:
|
||||
item_id = (item.data(QtCore.Qt.UserRole))
|
||||
return item_id
|
||||
@ -102,6 +109,9 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
|
||||
return -1
|
||||
|
||||
def _deleteItem(self, itemClass, listWidget, resetFunc, dlgTitle, del_text, err_text):
|
||||
"""
|
||||
Delete an item.
|
||||
"""
|
||||
item_id = self._getCurrentItemId(listWidget)
|
||||
if item_id != -1:
|
||||
item = self.manager.get_object(itemClass, item_id)
|
||||
@ -196,6 +206,9 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
|
||||
return True
|
||||
|
||||
def onAuthorAddButtonClicked(self):
|
||||
"""
|
||||
Add an author to the list.
|
||||
"""
|
||||
self.authorform.setAutoDisplayName(True)
|
||||
if self.authorform.exec_():
|
||||
author = Author.populate(
|
||||
@ -213,6 +226,9 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
|
||||
message=translate('SongsPlugin.SongMaintenanceForm', 'This author already exists.'))
|
||||
|
||||
def onTopicAddButtonClicked(self):
|
||||
"""
|
||||
Add a topic to the list.
|
||||
"""
|
||||
if self.topicform.exec_():
|
||||
topic = Topic.populate(name=self.topicform.nameEdit.text())
|
||||
if self.checkTopic(topic):
|
||||
@ -226,6 +242,9 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
|
||||
message=translate('SongsPlugin.SongMaintenanceForm', 'This topic already exists.'))
|
||||
|
||||
def onBookAddButtonClicked(self):
|
||||
"""
|
||||
Add a book to the list.
|
||||
"""
|
||||
if self.bookform.exec_():
|
||||
book = Book.populate(name=self.bookform.nameEdit.text(),
|
||||
publisher=self.bookform.publisherEdit.text())
|
||||
@ -240,6 +259,9 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
|
||||
message=translate('SongsPlugin.SongMaintenanceForm', 'This book already exists.'))
|
||||
|
||||
def onAuthorEditButtonClicked(self):
|
||||
"""
|
||||
Edit an author.
|
||||
"""
|
||||
author_id = self._getCurrentItemId(self.authorsListWidget)
|
||||
if author_id == -1:
|
||||
return
|
||||
@ -283,6 +305,9 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
|
||||
'Could not save your modified author, because the author already exists.'))
|
||||
|
||||
def onTopicEditButtonClicked(self):
|
||||
"""
|
||||
Edit a topic.
|
||||
"""
|
||||
topic_id = self._getCurrentItemId(self.topicsListWidget)
|
||||
if topic_id == -1:
|
||||
return
|
||||
@ -311,6 +336,9 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
|
||||
'Could not save your modified topic, because it already exists.'))
|
||||
|
||||
def onBookEditButtonClicked(self):
|
||||
"""
|
||||
Edit a book.
|
||||
"""
|
||||
book_id = self._getCurrentItemId(self.booksListWidget)
|
||||
if book_id == -1:
|
||||
return
|
||||
|
@ -33,6 +33,7 @@ from openlp.core.lib import translate
|
||||
from openlp.core.lib.ui import critical_error_message_box
|
||||
from openlp.plugins.songs.forms.topicsdialog import Ui_TopicsDialog
|
||||
|
||||
|
||||
class TopicsForm(QtGui.QDialog, Ui_TopicsDialog):
|
||||
"""
|
||||
Class documentation goes here.
|
||||
@ -41,16 +42,22 @@ class TopicsForm(QtGui.QDialog, Ui_TopicsDialog):
|
||||
"""
|
||||
Constructor
|
||||
"""
|
||||
QtGui.QDialog.__init__(self, parent)
|
||||
super(TopicsForm, self).__init__(parent)
|
||||
self.setupUi(self)
|
||||
|
||||
def exec_(self, clear=True):
|
||||
"""
|
||||
Execute the dialog.
|
||||
"""
|
||||
if clear:
|
||||
self.nameEdit.clear()
|
||||
self.nameEdit.setFocus()
|
||||
return QtGui.QDialog.exec_(self)
|
||||
|
||||
def accept(self):
|
||||
"""
|
||||
Override the inherited method to check before we close.
|
||||
"""
|
||||
if not self.nameEdit.text():
|
||||
critical_error_message_box(message=translate('SongsPlugin.TopicsForm',
|
||||
'You need to type in a topic name.'))
|
||||
|
@ -236,7 +236,7 @@ class SongsPlugin(Plugin):
|
||||
}
|
||||
self.setPluginUiTextStrings(tooltips)
|
||||
|
||||
def firstTime(self):
|
||||
def first_time(self):
|
||||
"""
|
||||
If the first time wizard has run, this function is run to import all the
|
||||
new songs into the database.
|
||||
|
2
setup.py
2
setup.py
@ -152,7 +152,7 @@ OpenLP (previously openlp.org) is free church presentation software, or lyrics p
|
||||
url='http://openlp.org/',
|
||||
license='GNU General Public License',
|
||||
packages=find_packages(exclude=['ez_setup', 'examples', 'tests']),
|
||||
scripts=['openlp.pyw'],
|
||||
scripts=['openlp.py'],
|
||||
include_package_data=True,
|
||||
zip_safe=False,
|
||||
install_requires=[
|
||||
|
Loading…
Reference in New Issue
Block a user