Merge lp:~trb143/openlp/bugs-2_4b into lp:openlp

Proposed by Tim Bentley on 2015-11-04
Status: Merged
Merged at revision: 2566
Proposed branch: lp:~trb143/openlp/bugs-2_4b
Merge into: lp:openlp
Diff against target: 1230 lines (+351/-312)
31 files modified
openlp/core/__init__.py (+21/-20)
openlp/core/common/settings.py (+5/-42)
openlp/core/common/uistrings.py (+3/-2)
openlp/core/lib/plugin.py (+1/-7)
openlp/core/lib/serviceitem.py (+1/-6)
openlp/core/ui/advancedtab.py (+13/-0)
openlp/core/ui/mainwindow.py (+13/-17)
openlp/core/ui/plugindialog.py (+11/-11)
openlp/core/ui/printserviceform.py (+1/-1)
openlp/core/ui/thememanager.py (+13/-6)
openlp/plugins/bibles/bibleplugin.py (+5/-3)
openlp/plugins/bibles/lib/db.py (+0/-10)
openlp/plugins/bibles/lib/manager.py (+0/-5)
openlp/plugins/custom/customplugin.py (+2/-4)
openlp/plugins/custom/lib/mediaitem.py (+7/-5)
openlp/plugins/images/imageplugin.py (+1/-24)
openlp/plugins/images/lib/mediaitem.py (+8/-8)
openlp/plugins/presentations/presentationplugin.py (+0/-16)
openlp/plugins/remotes/html/openlp.js (+7/-1)
openlp/plugins/remotes/lib/httprouter.py (+6/-3)
openlp/plugins/songs/forms/editsongform.py (+1/-1)
openlp/plugins/songs/lib/mediaitem.py (+3/-3)
openlp/plugins/songs/lib/openlyricsxml.py (+1/-11)
openlp/plugins/songs/lib/songstab.py (+0/-8)
openlp/plugins/songs/songsplugin.py (+2/-5)
tests/functional/openlp_core/test_init.py (+144/-0)
tests/functional/openlp_core_ui/test_advancedtab.py (+69/-0)
tests/functional/openlp_core_ui/test_mainwindow.py (+2/-2)
tests/functional/openlp_core_utils/test_init.py (+1/-1)
tests/functional/test_init.py (+0/-58)
tests/utils/test_bzr_tags.py (+10/-32)
To merge this branch: bzr merge lp:~trb143/openlp/bugs-2_4b
Reviewer Review Type Date Requested Status
Raoul Snyman 2015-11-04 Approve on 2015-11-05
Review via email: mp+276686@code.launchpad.net

This proposal supersedes a proposal from 2015-11-02.

Description of the change

First merge for 2.4.

A Number of small bug fixes which could be done in 2.2.
Clean up all the 2.0 to 2.2 migrations stuff.
Create a 2.2 to 2.4 migration for settings.
Fix problems with the Tag test so you do not need to restart a branch each time we do a release.

lp:~trb143/openlp/bugs-2_4b (revision 2578)
[SUCCESS] https//ci.openlp.io/job/Branch-01-Pull/1164/
[SUCCESS] https//ci.openlp.io/job/Branch-02-Functional-Tests/1087/
[SUCCESS] https//ci.openlp.io/job/Branch-03-Interface-Tests/1028/
[SUCCESS] https//ci.openlp.io/job/Branch-04a-Windows_Functional_Tests/875/
[SUCCESS] https//ci.openlp.io/job/Branch-04b-Windows_Interface_Tests/471/
[SUCCESS] https//ci.openlp.io/job/Branch-05a-Code_Analysis/591/
[SUCCESS] https//ci.openlp.io/job/Branch-05b-Test_Coverage/462/

To post a comment you must log in.
Tim Bentley (trb143) wrote : Posted in a previous version of this proposal

lp:~trb143/openlp/bugs-2_4b (revision 2576)
[SUCCESS] https//ci.openlp.io/job/Branch-01-Pull/1148/
[SUCCESS] https//ci.openlp.io/job/Branch-02-Functional-Tests/1071/
[SUCCESS] https//ci.openlp.io/job/Branch-03-Interface-Tests/1012/
[SUCCESS] https//ci.openlp.io/job/Branch-04a-Windows_Functional_Tests/859/
[SUCCESS] https//ci.openlp.io/job/Branch-04b-Windows_Interface_Tests/456/
[SUCCESS] https//ci.openlp.io/job/Branch-05a-Code_Analysis/577/
[SUCCESS] https//ci.openlp.io/job/Branch-05b-Test_Coverage/448/

Raoul Snyman (raoul-snyman) : Posted in a previous version of this proposal
review: Needs Information
Raoul Snyman (raoul-snyman) wrote : Posted in a previous version of this proposal

Minor "nitpicking"

review: Needs Fixing
Raoul Snyman (raoul-snyman) : Posted in a previous version of this proposal
review: Needs Fixing
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'openlp/core/__init__.py'
--- openlp/core/__init__.py 2015-03-24 22:33:57 +0000
+++ openlp/core/__init__.py 2015-11-04 18:37:45 +0000
@@ -30,7 +30,7 @@
30import os30import os
31import sys31import sys
32import logging32import logging
33from optparse import OptionParser33import argparse
34from traceback import format_exception34from traceback import format_exception
35import shutil35import shutil
36import time36import time
@@ -282,17 +282,18 @@
282 :return: a tuple of parsed options of type optparse.Value and a list of remaining argsZ282 :return: a tuple of parsed options of type optparse.Value and a list of remaining argsZ
283 """283 """
284 # Set up command line options.284 # Set up command line options.
285 usage = 'Usage: %prog [options] [qt-options]'285 parser = argparse.ArgumentParser(prog='openlp.py')
286 parser = OptionParser(usage=usage)286 parser.add_argument('-e', '--no-error-form', dest='no_error_form', action='store_true',
287 parser.add_option('-e', '--no-error-form', dest='no_error_form', action='store_true',287 help='Disable the error notification form.')
288 help='Disable the error notification form.')288 parser.add_argument('-l', '--log-level', dest='loglevel', default='warning', metavar='LEVEL',
289 parser.add_option('-l', '--log-level', dest='loglevel', default='warning', metavar='LEVEL',289 help='Set logging to LEVEL level. Valid values are "debug", "info", "warning".')
290 help='Set logging to LEVEL level. Valid values are "debug", "info", "warning".')290 parser.add_argument('-p', '--portable', dest='portable', action='store_true',
291 parser.add_option('-p', '--portable', dest='portable', action='store_true',291 help='Specify if this should be run as a portable app, '
292 help='Specify if this should be run as a portable app, off a USB flash drive (not implemented).')292 'off a USB flash drive (not implemented).')
293 parser.add_option('-d', '--dev-version', dest='dev_version', action='store_true',293 parser.add_argument('-d', '--dev-version', dest='dev_version', action='store_true',
294 help='Ignore the version file and pull the version directly from Bazaar')294 help='Ignore the version file and pull the version directly from Bazaar')
295 parser.add_option('-s', '--style', dest='style', help='Set the Qt4 style (passed directly to Qt4).')295 parser.add_argument('-s', '--style', dest='style', help='Set the Qt4 style (passed directly to Qt4).')
296 parser.add_argument('rargs', nargs='?', default=[])
296 # Parse command line options and deal with them. Use args supplied pragmatically if possible.297 # Parse command line options and deal with them. Use args supplied pragmatically if possible.
297 return parser.parse_args(args) if args else parser.parse_args()298 return parser.parse_args(args) if args else parser.parse_args()
298299
@@ -318,18 +319,18 @@
318319
319 :param args: Some args320 :param args: Some args
320 """321 """
321 (options, args) = parse_options(args)322 args = parse_options(args)
322 qt_args = []323 qt_args = []
323 if options.loglevel.lower() in ['d', 'debug']:324 if args and args.loglevel.lower() in ['d', 'debug']:
324 log.setLevel(logging.DEBUG)325 log.setLevel(logging.DEBUG)
325 elif options.loglevel.lower() in ['w', 'warning']:326 elif args and args.loglevel.lower() in ['w', 'warning']:
326 log.setLevel(logging.WARNING)327 log.setLevel(logging.WARNING)
327 else:328 else:
328 log.setLevel(logging.INFO)329 log.setLevel(logging.INFO)
329 if options.style:330 if args and args.style:
330 qt_args.extend(['-style', options.style])331 qt_args.extend(['-style', args.style])
331 # Throw the rest of the arguments at Qt, just in case.332 # Throw the rest of the arguments at Qt, just in case.
332 qt_args.extend(args)333 qt_args.extend(args.rargs)
333 # Bug #1018855: Set the WM_CLASS property in X11334 # Bug #1018855: Set the WM_CLASS property in X11
334 if not is_win() and not is_macosx():335 if not is_win() and not is_macosx():
335 qt_args.append('OpenLP')336 qt_args.append('OpenLP')
@@ -339,7 +340,7 @@
339 application = OpenLP(qt_args)340 application = OpenLP(qt_args)
340 application.setOrganizationName('OpenLP')341 application.setOrganizationName('OpenLP')
341 application.setOrganizationDomain('openlp.org')342 application.setOrganizationDomain('openlp.org')
342 if options.portable:343 if args and args.portable:
343 application.setApplicationName('OpenLPPortable')344 application.setApplicationName('OpenLPPortable')
344 Settings.setDefaultFormat(Settings.IniFormat)345 Settings.setDefaultFormat(Settings.IniFormat)
345 # Get location OpenLPPortable.ini346 # Get location OpenLPPortable.ini
@@ -383,6 +384,6 @@
383 application.installTranslator(default_translator)384 application.installTranslator(default_translator)
384 else:385 else:
385 log.debug('Could not find default_translator.')386 log.debug('Could not find default_translator.')
386 if not options.no_error_form:387 if args and not args.no_error_form:
387 sys.excepthook = application.hook_exception388 sys.excepthook = application.hook_exception
388 sys.exit(application.run(qt_args))389 sys.exit(application.run(qt_args))
389390
=== modified file 'openlp/core/common/settings.py'
--- openlp/core/common/settings.py 2015-09-08 19:13:59 +0000
+++ openlp/core/common/settings.py 2015-11-04 18:37:45 +0000
@@ -118,6 +118,7 @@
118 'advanced/slide limits': SlideLimits.End,118 'advanced/slide limits': SlideLimits.End,
119 'advanced/single click preview': False,119 'advanced/single click preview': False,
120 'advanced/x11 bypass wm': X11_BYPASS_DEFAULT,120 'advanced/x11 bypass wm': X11_BYPASS_DEFAULT,
121 'advanced/search as type': True,
121 'crashreport/last directory': '',122 'crashreport/last directory': '',
122 'formattingTags/html_tags': '',123 'formattingTags/html_tags': '',
123 'core/audio repeat list': False,124 'core/audio repeat list': False,
@@ -321,48 +322,10 @@
321 }322 }
322 __file_path__ = ''323 __file_path__ = ''
323 __obsolete_settings__ = [324 __obsolete_settings__ = [
324 # Changed during 1.9.x development.325 # Changed during 2.2.x development.
325 ('bibles/bookname language', 'bibles/book name language', []),326 # ('advanced/stylesheet fix', '', []),
326 ('general/enable slide loop', 'advanced/slide limits', [(SlideLimits.Wrap, True), (SlideLimits.End, False)]),327 # ('general/recent files', 'core/recent files', [(recent_files_conv, None)]),
327 ('songs/ccli number', 'core/ccli number', []),328 ('songs/search as type', 'advanced/search as type', [])
328 ('media/use phonon', '', []),
329 # Changed during 2.1.x development.
330 ('advanced/stylesheet fix', '', []),
331 ('bibles/last directory 1', 'bibles/last directory import', []),
332 ('media/background color', 'players/background color', []),
333 ('themes/last directory', 'themes/last directory import', []),
334 ('themes/last directory 1', 'themes/last directory export', []),
335 ('songs/last directory 1', 'songs/last directory import', []),
336 ('songusage/last directory 1', 'songusage/last directory export', []),
337 ('user interface/mainwindow splitter geometry', 'user interface/main window splitter geometry', []),
338 ('shortcuts/makeLive', 'shortcuts/make_live', []),
339 ('general/audio repeat list', 'core/audio repeat list', []),
340 ('general/auto open', 'core/auto open', []),
341 ('general/auto preview', 'core/auto preview', []),
342 ('general/audio start paused', 'core/audio start paused', []),
343 ('general/auto unblank', 'core/auto unblank', []),
344 ('general/blank warning', 'core/blank warning', []),
345 ('general/ccli number', 'core/ccli number', []),
346 ('general/has run wizard', 'core/has run wizard', []),
347 ('general/language', 'core/language', []),
348 ('general/last version test', 'core/last version test', []),
349 ('general/loop delay', 'core/loop delay', []),
350 ('general/recent files', 'core/recent files', [(recent_files_conv, None)]),
351 ('general/save prompt', 'core/save prompt', []),
352 ('general/screen blank', 'core/screen blank', []),
353 ('general/show splash', 'core/show splash', []),
354 ('general/songselect password', 'core/songselect password', []),
355 ('general/songselect username', 'core/songselect username', []),
356 ('general/update check', 'core/update check', []),
357 ('general/view mode', 'core/view mode', []),
358 ('general/display on monitor', 'core/display on monitor', []),
359 ('general/override position', 'core/override position', []),
360 ('general/x position', 'core/x position', []),
361 ('general/y position', 'core/y position', []),
362 ('general/monitor', 'core/monitor', []),
363 ('general/height', 'core/height', []),
364 ('general/monitor', 'core/monitor', []),
365 ('general/width', 'core/width', [])
366 ]329 ]
367330
368 @staticmethod331 @staticmethod
369332
=== modified file 'openlp/core/common/uistrings.py'
--- openlp/core/common/uistrings.py 2015-04-21 21:49:22 +0000
+++ openlp/core/common/uistrings.py 2015-11-04 18:37:45 +0000
@@ -108,8 +108,9 @@
108 self.NFSp = translate('OpenLP.Ui', 'No Files Selected', 'Plural')108 self.NFSp = translate('OpenLP.Ui', 'No Files Selected', 'Plural')
109 self.NISs = translate('OpenLP.Ui', 'No Item Selected', 'Singular')109 self.NISs = translate('OpenLP.Ui', 'No Item Selected', 'Singular')
110 self.NISp = translate('OpenLP.Ui', 'No Items Selected', 'Plural')110 self.NISp = translate('OpenLP.Ui', 'No Items Selected', 'Plural')
111 self.OLPV2 = translate('OpenLP.Ui', 'OpenLP 2')111 self.OLP = translate('OpenLP.Ui', 'OpenLP')
112 self.OLPV2x = translate('OpenLP.Ui', 'OpenLP 2.2')112 self.OLPV2 = "%s %s" % (self.OLP, "2")
113 self.OLPV2x = "%s %s" % (self.OLP, "2.4")
113 self.OpenLPStart = translate('OpenLP.Ui', 'OpenLP is already running. Do you wish to continue?')114 self.OpenLPStart = translate('OpenLP.Ui', 'OpenLP is already running. Do you wish to continue?')
114 self.OpenService = translate('OpenLP.Ui', 'Open service.')115 self.OpenService = translate('OpenLP.Ui', 'Open service.')
115 self.PlaySlidesInLoop = translate('OpenLP.Ui', 'Play Slides in Loop')116 self.PlaySlidesInLoop = translate('OpenLP.Ui', 'Play Slides in Loop')
116117
=== modified file 'openlp/core/lib/plugin.py'
--- openlp/core/lib/plugin.py 2015-01-18 13:39:21 +0000
+++ openlp/core/lib/plugin.py 2015-11-04 18:37:45 +0000
@@ -288,13 +288,7 @@
288 """288 """
289 Perform tasks on application startup289 Perform tasks on application startup
290 """290 """
291 # FIXME: Remove after 2.2 release.291 pass
292 # This is needed to load the list of media/presentation from the config saved before the settings rewrite.
293 if self.media_item_class is not None and self.name != 'images':
294 loaded_list = Settings().get_files_from_config(self)
295 # Now save the list to the config using our Settings class.
296 if loaded_list:
297 Settings().setValue('%s/%s files' % (self.settings_section, self.name), loaded_list)
298292
299 def uses_theme(self, theme):293 def uses_theme(self, theme):
300 """294 """
301295
=== modified file 'openlp/core/lib/serviceitem.py'
--- openlp/core/lib/serviceitem.py 2015-09-08 19:13:59 +0000
+++ openlp/core/lib/serviceitem.py 2015-11-04 18:37:45 +0000
@@ -129,7 +129,7 @@
129 OnLoadUpdate = 8129 OnLoadUpdate = 8
130 AddIfNewItem = 9130 AddIfNewItem = 9
131 ProvidesOwnDisplay = 10131 ProvidesOwnDisplay = 10
132 HasDetailedTitleDisplay = 11132 # HasDetailedTitleDisplay = 11
133 HasVariableStartTime = 12133 HasVariableStartTime = 12
134 CanSoftBreak = 13134 CanSoftBreak = 13
135 CanWordSplit = 14135 CanWordSplit = 14
@@ -415,11 +415,6 @@
415 self.will_auto_start = header.get('will_auto_start', False)415 self.will_auto_start = header.get('will_auto_start', False)
416 self.processor = header.get('processor', None)416 self.processor = header.get('processor', None)
417 self.has_original_files = True417 self.has_original_files = True
418 # TODO: Remove me in 2,3 build phase
419 if self.is_capable(ItemCapabilities.HasDetailedTitleDisplay):
420 self.capabilities.remove(ItemCapabilities.HasDetailedTitleDisplay)
421 self.processor = self.title
422 self.title = None
423 if 'background_audio' in header:418 if 'background_audio' in header:
424 self.background_audio = []419 self.background_audio = []
425 for filename in header['background_audio']:420 for filename in header['background_audio']:
426421
=== modified file 'openlp/core/ui/advancedtab.py'
--- openlp/core/ui/advancedtab.py 2015-01-18 13:39:21 +0000
+++ openlp/core/ui/advancedtab.py 2015-11-04 18:37:45 +0000
@@ -80,6 +80,9 @@
80 self.expand_service_item_check_box = QtGui.QCheckBox(self.ui_group_box)80 self.expand_service_item_check_box = QtGui.QCheckBox(self.ui_group_box)
81 self.expand_service_item_check_box.setObjectName('expand_service_item_check_box')81 self.expand_service_item_check_box.setObjectName('expand_service_item_check_box')
82 self.ui_layout.addRow(self.expand_service_item_check_box)82 self.ui_layout.addRow(self.expand_service_item_check_box)
83 self.search_as_type_check_box = QtGui.QCheckBox(self.ui_group_box)
84 self.search_as_type_check_box.setObjectName('SearchAsType_check_box')
85 self.ui_layout.addRow(self.search_as_type_check_box)
83 self.enable_auto_close_check_box = QtGui.QCheckBox(self.ui_group_box)86 self.enable_auto_close_check_box = QtGui.QCheckBox(self.ui_group_box)
84 self.enable_auto_close_check_box.setObjectName('enable_auto_close_check_box')87 self.enable_auto_close_check_box.setObjectName('enable_auto_close_check_box')
85 self.ui_layout.addRow(self.enable_auto_close_check_box)88 self.ui_layout.addRow(self.enable_auto_close_check_box)
@@ -251,6 +254,7 @@
251 self.end_slide_radio_button.clicked.connect(self.on_end_slide_button_clicked)254 self.end_slide_radio_button.clicked.connect(self.on_end_slide_button_clicked)
252 self.wrap_slide_radio_button.clicked.connect(self.on_wrap_slide_button_clicked)255 self.wrap_slide_radio_button.clicked.connect(self.on_wrap_slide_button_clicked)
253 self.next_item_radio_button.clicked.connect(self.on_next_item_button_clicked)256 self.next_item_radio_button.clicked.connect(self.on_next_item_button_clicked)
257 self.search_as_type_check_box.stateChanged.connect(self.on_search_as_type_check_box_changed)
254258
255 def retranslateUi(self):259 def retranslateUi(self):
256 """260 """
@@ -319,6 +323,7 @@
319 self.end_slide_radio_button.setText(translate('OpenLP.GeneralTab', '&Remain on Slide'))323 self.end_slide_radio_button.setText(translate('OpenLP.GeneralTab', '&Remain on Slide'))
320 self.wrap_slide_radio_button.setText(translate('OpenLP.GeneralTab', '&Wrap around'))324 self.wrap_slide_radio_button.setText(translate('OpenLP.GeneralTab', '&Wrap around'))
321 self.next_item_radio_button.setText(translate('OpenLP.GeneralTab', '&Move to next/previous service item'))325 self.next_item_radio_button.setText(translate('OpenLP.GeneralTab', '&Move to next/previous service item'))
326 self.search_as_type_check_box.setText(translate('SongsPlugin.GeneralTab', 'Enable search as you type'))
322327
323 def load(self):328 def load(self):
324 """329 """
@@ -349,6 +354,8 @@
349 self.default_color = settings.value('default color')354 self.default_color = settings.value('default color')
350 self.default_file_edit.setText(settings.value('default image'))355 self.default_file_edit.setText(settings.value('default image'))
351 self.slide_limits = settings.value('slide limits')356 self.slide_limits = settings.value('slide limits')
357 self.is_search_as_you_type_enabled = settings.value('search as type')
358 self.search_as_type_check_box.setChecked(self.is_search_as_you_type_enabled)
352 # Prevent the dialog displayed by the alternate_rows_check_box to display.359 # Prevent the dialog displayed by the alternate_rows_check_box to display.
353 self.alternate_rows_check_box.blockSignals(True)360 self.alternate_rows_check_box.blockSignals(True)
354 self.alternate_rows_check_box.setChecked(settings.value('alternate rows'))361 self.alternate_rows_check_box.setChecked(settings.value('alternate rows'))
@@ -424,8 +431,14 @@
424 settings.setValue('x11 bypass wm', self.x11_bypass_check_box.isChecked())431 settings.setValue('x11 bypass wm', self.x11_bypass_check_box.isChecked())
425 self.settings_form.register_post_process('config_screen_changed')432 self.settings_form.register_post_process('config_screen_changed')
426 self.settings_form.register_post_process('slidecontroller_update_slide_limits')433 self.settings_form.register_post_process('slidecontroller_update_slide_limits')
434 settings.setValue('search as type', self.is_search_as_you_type_enabled)
427 settings.endGroup()435 settings.endGroup()
428436
437 def on_search_as_type_check_box_changed(self, check_state):
438 self.is_search_as_you_type_enabled = (check_state == QtCore.Qt.Checked)
439 self.settings_form.register_post_process('songs_config_updated')
440 self.settings_form.register_post_process('custom_config_updated')
441
429 def cancel(self):442 def cancel(self):
430 """443 """
431 Dialogue was cancelled, remove any pending data path change.444 Dialogue was cancelled, remove any pending data path change.
432445
=== modified file 'openlp/core/ui/mainwindow.py'
--- openlp/core/ui/mainwindow.py 2015-08-24 18:19:30 +0000
+++ openlp/core/ui/mainwindow.py 2015-11-04 18:37:45 +0000
@@ -389,7 +389,7 @@
389 self.file_menu.setTitle(translate('OpenLP.MainWindow', '&File'))389 self.file_menu.setTitle(translate('OpenLP.MainWindow', '&File'))
390 self.file_import_menu.setTitle(translate('OpenLP.MainWindow', '&Import'))390 self.file_import_menu.setTitle(translate('OpenLP.MainWindow', '&Import'))
391 self.file_export_menu.setTitle(translate('OpenLP.MainWindow', '&Export'))391 self.file_export_menu.setTitle(translate('OpenLP.MainWindow', '&Export'))
392 self.recent_files_menu.setTitle(translate('OpenLP.MainWindow', '&Recent Files'))392 self.recent_files_menu.setTitle(translate('OpenLP.MainWindow', '&Recent Services'))
393 self.view_menu.setTitle(translate('OpenLP.MainWindow', '&View'))393 self.view_menu.setTitle(translate('OpenLP.MainWindow', '&View'))
394 self.view_mode_menu.setTitle(translate('OpenLP.MainWindow', 'M&ode'))394 self.view_mode_menu.setTitle(translate('OpenLP.MainWindow', 'M&ode'))
395 self.tools_menu.setTitle(translate('OpenLP.MainWindow', '&Tools'))395 self.tools_menu.setTitle(translate('OpenLP.MainWindow', '&Tools'))
@@ -400,16 +400,16 @@
400 self.service_manager_dock.setWindowTitle(translate('OpenLP.MainWindow', 'Service Manager'))400 self.service_manager_dock.setWindowTitle(translate('OpenLP.MainWindow', 'Service Manager'))
401 self.theme_manager_dock.setWindowTitle(translate('OpenLP.MainWindow', 'Theme Manager'))401 self.theme_manager_dock.setWindowTitle(translate('OpenLP.MainWindow', 'Theme Manager'))
402 self.projector_manager_dock.setWindowTitle(translate('OpenLP.MainWindow', 'Projector Manager'))402 self.projector_manager_dock.setWindowTitle(translate('OpenLP.MainWindow', 'Projector Manager'))
403 self.file_new_item.setText(translate('OpenLP.MainWindow', '&New'))403 self.file_new_item.setText(translate('OpenLP.MainWindow', '&New Service'))
404 self.file_new_item.setToolTip(UiStrings().NewService)404 self.file_new_item.setToolTip(UiStrings().NewService)
405 self.file_new_item.setStatusTip(UiStrings().CreateService)405 self.file_new_item.setStatusTip(UiStrings().CreateService)
406 self.file_open_item.setText(translate('OpenLP.MainWindow', '&Open'))406 self.file_open_item.setText(translate('OpenLP.MainWindow', '&Open Service'))
407 self.file_open_item.setToolTip(UiStrings().OpenService)407 self.file_open_item.setToolTip(UiStrings().OpenService)
408 self.file_open_item.setStatusTip(translate('OpenLP.MainWindow', 'Open an existing service.'))408 self.file_open_item.setStatusTip(translate('OpenLP.MainWindow', 'Open an existing service.'))
409 self.file_save_item.setText(translate('OpenLP.MainWindow', '&Save'))409 self.file_save_item.setText(translate('OpenLP.MainWindow', '&Save Service'))
410 self.file_save_item.setToolTip(UiStrings().SaveService)410 self.file_save_item.setToolTip(UiStrings().SaveService)
411 self.file_save_item.setStatusTip(translate('OpenLP.MainWindow', 'Save the current service to disk.'))411 self.file_save_item.setStatusTip(translate('OpenLP.MainWindow', 'Save the current service to disk.'))
412 self.file_save_as_item.setText(translate('OpenLP.MainWindow', 'Save &As...'))412 self.file_save_as_item.setText(translate('OpenLP.MainWindow', 'Save Service &As...'))
413 self.file_save_as_item.setToolTip(translate('OpenLP.MainWindow', 'Save Service As'))413 self.file_save_as_item.setToolTip(translate('OpenLP.MainWindow', 'Save Service As'))
414 self.file_save_as_item.setStatusTip(translate('OpenLP.MainWindow',414 self.file_save_as_item.setStatusTip(translate('OpenLP.MainWindow',
415 'Save the current service under a new name.'))415 'Save the current service under a new name.'))
@@ -456,7 +456,7 @@
456 self.lock_panel.setText(translate('OpenLP.MainWindow', 'L&ock Panels'))456 self.lock_panel.setText(translate('OpenLP.MainWindow', 'L&ock Panels'))
457 self.lock_panel.setStatusTip(translate('OpenLP.MainWindow', 'Prevent the panels being moved.'))457 self.lock_panel.setStatusTip(translate('OpenLP.MainWindow', 'Prevent the panels being moved.'))
458 self.view_live_panel.setStatusTip(translate('OpenLP.MainWindow', 'Toggle the visibility of the live panel.'))458 self.view_live_panel.setStatusTip(translate('OpenLP.MainWindow', 'Toggle the visibility of the live panel.'))
459 self.settings_plugin_list_item.setText(translate('OpenLP.MainWindow', '&Plugin List'))459 self.settings_plugin_list_item.setText(translate('OpenLP.MainWindow', '&Manage Plugins'))
460 self.settings_plugin_list_item.setStatusTip(translate('OpenLP.MainWindow', 'List the Plugins'))460 self.settings_plugin_list_item.setStatusTip(translate('OpenLP.MainWindow', 'List the Plugins'))
461 self.about_item.setText(translate('OpenLP.MainWindow', '&About'))461 self.about_item.setText(translate('OpenLP.MainWindow', '&About'))
462 self.about_item.setStatusTip(translate('OpenLP.MainWindow', 'More information about OpenLP'))462 self.about_item.setStatusTip(translate('OpenLP.MainWindow', 'More information about OpenLP'))
@@ -505,7 +505,7 @@
505 super(MainWindow, self).__init__()505 super(MainWindow, self).__init__()
506 Registry().register('main_window', self)506 Registry().register('main_window', self)
507 self.clipboard = self.application.clipboard()507 self.clipboard = self.application.clipboard()
508 self.arguments = self.application.args508 self.arguments = ''.join(self.application.args)
509 # Set up settings sections for the main application (not for use by plugins).509 # Set up settings sections for the main application (not for use by plugins).
510 self.ui_settings_section = 'user interface'510 self.ui_settings_section = 'user interface'
511 self.general_settings_section = 'core'511 self.general_settings_section = 'core'
@@ -634,7 +634,7 @@
634 self.live_controller.display.setFocus()634 self.live_controller.display.setFocus()
635 self.activateWindow()635 self.activateWindow()
636 if self.arguments:636 if self.arguments:
637 self.open_cmd_line_files()637 self.open_cmd_line_files(self.arguments)
638 elif Settings().value(self.general_settings_section + '/auto open'):638 elif Settings().value(self.general_settings_section + '/auto open'):
639 self.service_manager_contents.load_last_file()639 self.service_manager_contents.load_last_file()
640 view_mode = Settings().value('%s/view mode' % self.general_settings_section)640 view_mode = Settings().value('%s/view mode' % self.general_settings_section)
@@ -1416,15 +1416,11 @@
1416 settings.remove('advanced/data path')1416 settings.remove('advanced/data path')
1417 self.application.set_normal_cursor()1417 self.application.set_normal_cursor()
14181418
1419 def open_cmd_line_files(self):1419 def open_cmd_line_files(self, filename):
1420 """1420 """
1421 Open files passed in through command line arguments1421 Open files passed in through command line arguments
1422 """1422 """
1423 args = []1423 if not isinstance(filename, str):
1424 for a in self.arguments:1424 filename = str(filename, sys.getfilesystemencoding())
1425 args.extend([a])1425 if filename.endswith(('.osz', '.oszl')):
1426 for filename in args:1426 self.service_manager_contents.load_file(filename)
1427 if not isinstance(filename, str):
1428 filename = str(filename, sys.getfilesystemencoding())
1429 if filename.endswith(('.osz', '.oszl')):
1430 self.service_manager_contents.load_file(filename)
14311427
=== modified file 'openlp/core/ui/plugindialog.py'
--- openlp/core/ui/plugindialog.py 2015-01-18 13:39:21 +0000
+++ openlp/core/ui/plugindialog.py 2015-11-04 18:37:45 +0000
@@ -33,21 +33,21 @@
33 """33 """
34 The UI of the plugin view dialog34 The UI of the plugin view dialog
35 """35 """
36 def setupUi(self, pluginViewDialog):36 def setupUi(self, plugin_view_dialog):
37 """37 """
38 Set up the UI38 Set up the UI
39 """39 """
40 pluginViewDialog.setObjectName('pluginViewDialog')40 plugin_view_dialog.setObjectName('plugin_view_dialog')
41 pluginViewDialog.setWindowIcon(build_icon(u':/icon/openlp-logo.svg'))41 plugin_view_dialog.setWindowIcon(build_icon(u':/icon/openlp-logo.svg'))
42 pluginViewDialog.setWindowModality(QtCore.Qt.ApplicationModal)42 plugin_view_dialog.setWindowModality(QtCore.Qt.ApplicationModal)
43 self.plugin_layout = QtGui.QVBoxLayout(pluginViewDialog)43 self.plugin_layout = QtGui.QVBoxLayout(plugin_view_dialog)
44 self.plugin_layout.setObjectName('plugin_layout')44 self.plugin_layout.setObjectName('plugin_layout')
45 self.list_layout = QtGui.QHBoxLayout()45 self.list_layout = QtGui.QHBoxLayout()
46 self.list_layout.setObjectName('list_layout')46 self.list_layout.setObjectName('list_layout')
47 self.plugin_list_widget = QtGui.QListWidget(pluginViewDialog)47 self.plugin_list_widget = QtGui.QListWidget(plugin_view_dialog)
48 self.plugin_list_widget.setObjectName('plugin_list_widget')48 self.plugin_list_widget.setObjectName('plugin_list_widget')
49 self.list_layout.addWidget(self.plugin_list_widget)49 self.list_layout.addWidget(self.plugin_list_widget)
50 self.plugin_info_group_box = QtGui.QGroupBox(pluginViewDialog)50 self.plugin_info_group_box = QtGui.QGroupBox(plugin_view_dialog)
51 self.plugin_info_group_box.setObjectName('plugin_info_group_box')51 self.plugin_info_group_box.setObjectName('plugin_info_group_box')
52 self.plugin_info_layout = QtGui.QFormLayout(self.plugin_info_group_box)52 self.plugin_info_layout = QtGui.QFormLayout(self.plugin_info_group_box)
53 self.plugin_info_layout.setObjectName('plugin_info_layout')53 self.plugin_info_layout.setObjectName('plugin_info_layout')
@@ -70,15 +70,15 @@
70 self.plugin_info_layout.addRow(self.about_label, self.about_text_browser)70 self.plugin_info_layout.addRow(self.about_label, self.about_text_browser)
71 self.list_layout.addWidget(self.plugin_info_group_box)71 self.list_layout.addWidget(self.plugin_info_group_box)
72 self.plugin_layout.addLayout(self.list_layout)72 self.plugin_layout.addLayout(self.list_layout)
73 self.button_box = create_button_box(pluginViewDialog, 'button_box', ['ok'])73 self.button_box = create_button_box(plugin_view_dialog, 'button_box', ['ok'])
74 self.plugin_layout.addWidget(self.button_box)74 self.plugin_layout.addWidget(self.button_box)
75 self.retranslateUi(pluginViewDialog)75 self.retranslateUi(plugin_view_dialog)
7676
77 def retranslateUi(self, pluginViewDialog):77 def retranslateUi(self, plugin_view_dialog):
78 """78 """
79 Translate the UI on the fly79 Translate the UI on the fly
80 """80 """
81 pluginViewDialog.setWindowTitle(translate('OpenLP.PluginForm', 'Plugin List'))81 plugin_view_dialog.setWindowTitle(translate('OpenLP.PluginForm', 'Manage Plugins'))
82 self.plugin_info_group_box.setTitle(translate('OpenLP.PluginForm', 'Plugin Details'))82 self.plugin_info_group_box.setTitle(translate('OpenLP.PluginForm', 'Plugin Details'))
83 self.version_label.setText('%s:' % UiStrings().Version)83 self.version_label.setText('%s:' % UiStrings().Version)
84 self.about_label.setText('%s:' % UiStrings().About)84 self.about_label.setText('%s:' % UiStrings().About)
8585
=== modified file 'openlp/core/ui/printserviceform.py'
--- openlp/core/ui/printserviceform.py 2015-04-11 22:13:30 +0000
+++ openlp/core/ui/printserviceform.py 2015-11-04 18:37:45 +0000
@@ -162,7 +162,7 @@
162 html_data = self._add_element('html')162 html_data = self._add_element('html')
163 self._add_element('head', parent=html_data)163 self._add_element('head', parent=html_data)
164 self._add_element('title', self.title_line_edit.text(), html_data.head)164 self._add_element('title', self.title_line_edit.text(), html_data.head)
165 css_path = os.path.join(AppLocation.get_data_path(), 'service_print.css')165 css_path = os.path.join(AppLocation.get_data_path(), 'serviceprint', 'service_print.css')
166 custom_css = get_text_file_string(css_path)166 custom_css = get_text_file_string(css_path)
167 if not custom_css:167 if not custom_css:
168 custom_css = DEFAULT_CSS168 custom_css = DEFAULT_CSS
169169
=== modified file 'openlp/core/ui/thememanager.py'
--- openlp/core/ui/thememanager.py 2015-09-08 19:13:59 +0000
+++ openlp/core/ui/thememanager.py 2015-11-04 18:37:45 +0000
@@ -755,12 +755,19 @@
755 return False755 return False
756 # check for use in the system else where.756 # check for use in the system else where.
757 if test_plugin:757 if test_plugin:
758 plugin_usage = ""
758 for plugin in self.plugin_manager.plugins:759 for plugin in self.plugin_manager.plugins:
759 if plugin.uses_theme(theme):760 used_count = plugin.uses_theme(theme)
760 critical_error_message_box(translate('OpenLP.ThemeManager', 'Validation Error'),761 if used_count:
761 translate('OpenLP.ThemeManager',762 plugin_usage = "%s%s" % (plugin_usage, (translate('OpenLP.ThemeManager',
762 'Theme %s is used in the %s plugin.')763 '%s time(s) by %s') %
763 % (theme, plugin.name))764 (used_count, plugin.name)))
764 return False765 plugin_usage = "%s\n" % plugin_usage
766 if plugin_usage:
767 critical_error_message_box(translate('OpenLP.ThemeManager', 'Unable to delete theme'),
768 translate('OpenLP.ThemeManager', 'Theme is currently used \n\n%s') %
769 plugin_usage)
770
771 return False
765 return True772 return True
766 return False773 return False
767774
=== modified file 'openlp/plugins/bibles/bibleplugin.py'
--- openlp/plugins/bibles/bibleplugin.py 2015-03-10 21:33:35 +0000
+++ openlp/plugins/bibles/bibleplugin.py 2015-11-04 18:37:45 +0000
@@ -178,12 +178,14 @@
178178
179 def uses_theme(self, theme):179 def uses_theme(self, theme):
180 """180 """
181 Called to find out if the bible plugin is currently using a theme. Returns ``True`` if the theme is being used,181 Called to find out if the bible plugin is currently using a theme. Returns ``1`` if the theme is being used,
182 otherwise returns ``False``.182 otherwise returns ``0``.
183183
184 :param theme: The theme184 :param theme: The theme
185 """185 """
186 return str(self.settings_tab.bible_theme) == theme186 if str(self.settings_tab.bible_theme) == theme:
187 return 1
188 return 0
187189
188 def rename_theme(self, old_theme, new_theme):190 def rename_theme(self, old_theme, new_theme):
189 """191 """
190192
=== modified file 'openlp/plugins/bibles/lib/db.py'
--- openlp/plugins/bibles/lib/db.py 2015-09-08 19:13:26 +0000
+++ openlp/plugins/bibles/lib/db.py 2015-11-04 18:37:45 +0000
@@ -476,16 +476,6 @@
476 self.save_meta('language_id', language_id)476 self.save_meta('language_id', language_id)
477 return language_id477 return language_id
478478
479 def is_old_database(self):
480 """
481 Returns ``True`` if it is a bible database, which has been created prior to 1.9.6.
482 """
483 try:
484 self.session.query(Book).all()
485 except:
486 return True
487 return False
488
489 def dump_bible(self):479 def dump_bible(self):
490 """480 """
491 Utility debugging method to dump the contents of a bible.481 Utility debugging method to dump the contents of a bible.
492482
=== modified file 'openlp/plugins/bibles/lib/manager.py'
--- openlp/plugins/bibles/lib/manager.py 2015-01-31 21:52:02 +0000
+++ openlp/plugins/bibles/lib/manager.py 2015-11-04 18:37:45 +0000
@@ -129,11 +129,6 @@
129 bible.session.close()129 bible.session.close()
130 delete_file(os.path.join(self.path, filename))130 delete_file(os.path.join(self.path, filename))
131 continue131 continue
132 # Find old database versions.
133 if bible.is_old_database():
134 self.old_bible_databases.append([filename, name])
135 bible.session.close()
136 continue
137 log.debug('Bible Name: "%s"', name)132 log.debug('Bible Name: "%s"', name)
138 self.db_cache[name] = bible133 self.db_cache[name] = bible
139 # Look to see if lazy load bible exists and get create getter.134 # Look to see if lazy load bible exists and get create getter.
140135
=== modified file 'openlp/plugins/custom/customplugin.py'
--- openlp/plugins/custom/customplugin.py 2015-02-11 20:56:13 +0000
+++ openlp/plugins/custom/customplugin.py 2015-11-04 18:37:45 +0000
@@ -72,11 +72,9 @@
72 """72 """
73 Called to find out if the custom plugin is currently using a theme.73 Called to find out if the custom plugin is currently using a theme.
7474
75 Returns True if the theme is being used, otherwise returns False.75 Returns count of the times the theme is used.
76 """76 """
77 if self.db_manager.get_all_objects(CustomSlide, CustomSlide.theme_name == theme):77 return len(self.db_manager.get_all_objects(CustomSlide, CustomSlide.theme_name == theme))
78 return True
79 return False
8078
81 def rename_theme(self, old_theme, new_theme):79 def rename_theme(self, old_theme, new_theme):
82 """80 """
8381
=== modified file 'openlp/plugins/custom/lib/mediaitem.py'
--- openlp/plugins/custom/lib/mediaitem.py 2015-04-02 20:49:19 +0000
+++ openlp/plugins/custom/lib/mediaitem.py 2015-11-04 18:37:45 +0000
@@ -85,6 +85,7 @@
85 """85 """
86 log.debug('Config loaded')86 log.debug('Config loaded')
87 self.add_custom_from_service = Settings().value(self.settings_section + '/add custom from service')87 self.add_custom_from_service = Settings().value(self.settings_section + '/add custom from service')
88 self.is_search_as_you_type_enabled = Settings().value('advanced/search as type')
8889
89 def retranslateUi(self):90 def retranslateUi(self):
90 """91 """
@@ -269,11 +270,12 @@
269270
270 :param text: The search text271 :param text: The search text
271 """272 """
272 search_length = 2273 if self.is_search_as_you_type_enabled:
273 if len(text) > search_length:274 search_length = 2
274 self.on_search_text_button_clicked()275 if len(text) > search_length:
275 elif not text:276 self.on_search_text_button_clicked()
276 self.on_clear_text_button_click()277 elif not text:
278 self.on_clear_text_button_click()
277279
278 def service_load(self, item):280 def service_load(self, item):
279 """281 """
280282
=== modified file 'openlp/plugins/images/imageplugin.py'
--- openlp/plugins/images/imageplugin.py 2015-02-11 22:15:46 +0000
+++ openlp/plugins/images/imageplugin.py 2015-11-04 18:37:45 +0000
@@ -67,36 +67,13 @@
67 'provided by the theme.')67 'provided by the theme.')
68 return about_text68 return about_text
6969
70 def app_startup(self):
71 """
72 Perform tasks on application startup.
73 """
74 # TODO: Can be removed when the upgrade path from 2.0.x to 2.2.x is no longer needed
75 Plugin.app_startup(self)
76 # Convert old settings-based image list to the database.
77 files_from_config = Settings().get_files_from_config(self)
78 if files_from_config:
79 for file in files_from_config:
80 filename = os.path.split(file)[1]
81 thumb = os.path.join(self.media_item.service_path, filename)
82 try:
83 os.remove(thumb)
84 except:
85 pass
86 log.debug('Importing images list from old config: %s' % files_from_config)
87 self.media_item.save_new_images_list(files_from_config)
88
89 def upgrade_settings(self, settings):70 def upgrade_settings(self, settings):
90 """71 """
91 Upgrade the settings of this plugin.72 Upgrade the settings of this plugin.
9273
93 :param settings: The Settings object containing the old settings.74 :param settings: The Settings object containing the old settings.
94 """75 """
95 # TODO: Can be removed when the upgrade path from 2.0.x to 2.2.x is no longer needed76 pass
96 files_from_config = settings.get_files_from_config(self)
97 if files_from_config:
98 log.debug('Importing images list from old config: %s' % files_from_config)
99 self.media_item.save_new_images_list(files_from_config)
10077
101 def set_plugin_text_strings(self):78 def set_plugin_text_strings(self):
102 """79 """
10380
=== modified file 'openlp/plugins/images/lib/mediaitem.py'
--- openlp/plugins/images/lib/mediaitem.py 2015-09-08 19:13:59 +0000
+++ openlp/plugins/images/lib/mediaitem.py 2015-11-04 18:37:45 +0000
@@ -119,14 +119,6 @@
119 icon=':/general/general_edit.png',119 icon=':/general/general_edit.png',
120 triggers=self.on_edit_click)120 triggers=self.on_edit_click)
121 create_widget_action(self.list_view, separator=True)121 create_widget_action(self.list_view, separator=True)
122 if self.has_delete_icon:
123 create_widget_action(
124 self.list_view,
125 'listView%s%sItem' % (self.plugin.name.title(), StringContent.Delete.title()),
126 text=self.plugin.get_string(StringContent.Delete)['title'],
127 icon=':/general/general_delete.png',
128 can_shortcuts=True, triggers=self.on_delete_click)
129 create_widget_action(self.list_view, separator=True)
130 create_widget_action(122 create_widget_action(
131 self.list_view,123 self.list_view,
132 'listView%s%sItem' % (self.plugin.name.title(), StringContent.Preview.title()),124 'listView%s%sItem' % (self.plugin.name.title(), StringContent.Preview.title()),
@@ -155,6 +147,14 @@
155 text=translate('OpenLP.MediaManagerItem', '&Add to selected Service Item'),147 text=translate('OpenLP.MediaManagerItem', '&Add to selected Service Item'),
156 icon=':/general/general_add.png',148 icon=':/general/general_add.png',
157 triggers=self.on_add_edit_click)149 triggers=self.on_add_edit_click)
150 create_widget_action(self.list_view, separator=True)
151 if self.has_delete_icon:
152 create_widget_action(
153 self.list_view,
154 'listView%s%sItem' % (self.plugin.name.title(), StringContent.Delete.title()),
155 text=self.plugin.get_string(StringContent.Delete)['title'],
156 icon=':/general/general_delete.png',
157 can_shortcuts=True, triggers=self.on_delete_click)
158 self.add_custom_context_actions()158 self.add_custom_context_actions()
159 # Create the context menu and add all actions from the list_view.159 # Create the context menu and add all actions from the list_view.
160 self.menu = QtGui.QMenu()160 self.menu = QtGui.QMenu()
161161
=== modified file 'openlp/plugins/presentations/presentationplugin.py'
--- openlp/plugins/presentations/presentationplugin.py 2015-05-26 21:26:59 +0000
+++ openlp/plugins/presentations/presentationplugin.py 2015-11-04 18:37:45 +0000
@@ -137,22 +137,6 @@
137 self.register_controllers(controller)137 self.register_controllers(controller)
138 return bool(self.controllers)138 return bool(self.controllers)
139139
140 def app_startup(self):
141 """
142 Perform tasks on application startup.
143 """
144 # TODO: Can be removed when the upgrade path from 2.0.x to 2.2.x is no longer needed
145 super().app_startup()
146 files_from_config = Settings().value('presentations/presentations files')
147 for file in files_from_config:
148 try:
149 self.media_item.clean_up_thumbnails(file, True)
150 except AttributeError:
151 pass
152 self.media_item.list_view.clear()
153 Settings().setValue('presentations/thumbnail_scheme', 'md5')
154 self.media_item.validate_and_load(files_from_config)
155
156 def about(self):140 def about(self):
157 """141 """
158 Return information about this plugin.142 Return information about this plugin.
159143
=== modified file 'openlp/plugins/remotes/html/openlp.js'
--- openlp/plugins/remotes/html/openlp.js 2015-01-18 13:39:21 +0000
+++ openlp/plugins/remotes/html/openlp.js 2015-11-04 18:37:45 +0000
@@ -271,9 +271,15 @@
271 if (typeof value[0] !== "number"){271 if (typeof value[0] !== "number"){
272 value[0] = OpenLP.escapeString(value[0])272 value[0] = OpenLP.escapeString(value[0])
273 }273 }
274 var txt = "";
275 if (value[2].length > 0) {
276 txt = value[1] + " ( " + value[2] + " )";
277 } else {
278 txt = value[1];
279 }
274 ul.append($("<li>").append($("<a>").attr("href", "#options")280 ul.append($("<li>").append($("<a>").attr("href", "#options")
275 .attr("data-rel", "dialog").attr("value", value[0])281 .attr("data-rel", "dialog").attr("value", value[0])
276 .click(OpenLP.showOptions).text(value[1])));282 .click(OpenLP.showOptions).text(txt)));
277 });283 });
278 }284 }
279 ul.listview("refresh");285 ul.listview("refresh");
280286
=== modified file 'openlp/plugins/remotes/lib/httprouter.py'
--- openlp/plugins/remotes/lib/httprouter.py 2015-02-14 09:12:35 +0000
+++ openlp/plugins/remotes/lib/httprouter.py 2015-11-04 18:37:45 +0000
@@ -309,10 +309,13 @@
309 """309 """
310 Translate various strings in the mobile app.310 Translate various strings in the mobile app.
311 """311 """
312 remote = translate('RemotePlugin.Mobile', 'Remote')
313 stage = translate('RemotePlugin.Mobile', 'Stage View')
314 live = translate('RemotePlugin.Mobile', 'Live View')
312 self.template_vars = {315 self.template_vars = {
313 'app_title': translate('RemotePlugin.Mobile', 'OpenLP 2.2 Remote'),316 'app_title': "%s %s" % (UiStrings().OLPV2x, remote),
314 'stage_title': translate('RemotePlugin.Mobile', 'OpenLP 2.2 Stage View'),317 'stage_title': "%s %s" % (UiStrings().OLPV2x, stage),
315 'live_title': translate('RemotePlugin.Mobile', 'OpenLP 2.2 Live View'),318 'live_title': "%s %s" % (UiStrings().OLPV2x, live),
316 'service_manager': translate('RemotePlugin.Mobile', 'Service Manager'),319 'service_manager': translate('RemotePlugin.Mobile', 'Service Manager'),
317 'slide_controller': translate('RemotePlugin.Mobile', 'Slide Controller'),320 'slide_controller': translate('RemotePlugin.Mobile', 'Slide Controller'),
318 'alerts': translate('RemotePlugin.Mobile', 'Alerts'),321 'alerts': translate('RemotePlugin.Mobile', 'Alerts'),
319322
=== modified file 'openlp/plugins/songs/forms/editsongform.py'
--- openlp/plugins/songs/forms/editsongform.py 2015-01-18 13:39:21 +0000
+++ openlp/plugins/songs/forms/editsongform.py 2015-11-04 18:37:45 +0000
@@ -178,7 +178,7 @@
178 if invalid_verses:178 if invalid_verses:
179 valid = create_separated_list(verse_names)179 valid = create_separated_list(verse_names)
180 if len(invalid_verses) > 1:180 if len(invalid_verses) > 1:
181 msg = translate('SongsPlugin.EditSongForm', 'There are no verses corresponding to "%(invalid)s".'181 msg = translate('SongsPlugin.EditSongForm', 'There are no verses corresponding to "%(invalid)s". '
182 'Valid entries are %(valid)s.\nPlease enter the verses separated by spaces.') % \182 'Valid entries are %(valid)s.\nPlease enter the verses separated by spaces.') % \
183 {'invalid': ', '.join(invalid_verses), 'valid': valid}183 {'invalid': ', '.join(invalid_verses), 'valid': valid}
184 else:184 else:
185185
=== modified file 'openlp/plugins/songs/lib/mediaitem.py'
--- openlp/plugins/songs/lib/mediaitem.py 2015-01-18 13:39:21 +0000
+++ openlp/plugins/songs/lib/mediaitem.py 2015-11-04 18:37:45 +0000
@@ -115,7 +115,7 @@
115 Is triggered when the songs config is updated115 Is triggered when the songs config is updated
116 """116 """
117 log.debug('config_updated')117 log.debug('config_updated')
118 self.search_as_you_type = Settings().value(self.settings_section + '/search as type')118 self.is_search_as_you_type_enabled = Settings().value('advanced/search as type')
119 self.update_service_on_edit = Settings().value(self.settings_section + '/update service on edit')119 self.update_service_on_edit = Settings().value(self.settings_section + '/update service on edit')
120 self.add_song_from_service = Settings().value(self.settings_section + '/add song from service')120 self.add_song_from_service = Settings().value(self.settings_section + '/add song from service')
121 self.display_songbook = Settings().value(self.settings_section + '/display songbook')121 self.display_songbook = Settings().value(self.settings_section + '/display songbook')
@@ -279,7 +279,7 @@
279 If search as type enabled invoke the search on each key press. If the Lyrics are being searched do not start279 If search as type enabled invoke the search on each key press. If the Lyrics are being searched do not start
280 till 7 characters have been entered.280 till 7 characters have been entered.
281 """281 """
282 if self.search_as_you_type:282 if self.is_search_as_you_type_enabled:
283 search_length = 1283 search_length = 1
284 if self.search_text_edit.current_search_type() == SongSearch.Entire:284 if self.search_text_edit.current_search_type() == SongSearch.Entire:
285 search_length = 4285 search_length = 4
@@ -590,4 +590,4 @@
590 :param show_error: Is this an error?590 :param show_error: Is this an error?
591 """591 """
592 search_results = self.search_entire(string)592 search_results = self.search_entire(string)
593 return [[song.id, song.title] for song in search_results]593 return [[song.id, song.title, song.alternate_title] for song in search_results]
594594
=== modified file 'openlp/plugins/songs/lib/openlyricsxml.py'
--- openlp/plugins/songs/lib/openlyricsxml.py 2015-09-08 19:13:59 +0000
+++ openlp/plugins/songs/lib/openlyricsxml.py 2015-11-04 18:37:45 +0000
@@ -121,17 +121,7 @@
121 """121 """
122 self.song_xml = None122 self.song_xml = None
123 verse_list = []123 verse_list = []
124 if not xml.startswith('<?xml') and not xml.startswith('<song'):124 if xml.startswith('<?xml'):
125 # This is an old style song, without XML. Let's handle it correctly by iterating through the verses, and
126 # then recreating the internal xml object as well.
127 self.song_xml = objectify.fromstring('<song version="1.0" />')
128 self.lyrics = etree.SubElement(self.song_xml, 'lyrics')
129 verses = xml.split('\n\n')
130 for count, verse in enumerate(verses):
131 verse_list.append([{'type': 'v', 'label': str(count)}, str(verse)])
132 self.add_verse_to_lyrics('v', str(count), verse)
133 return verse_list
134 elif xml.startswith('<?xml'):
135 xml = xml[38:]125 xml = xml[38:]
136 try:126 try:
137 self.song_xml = objectify.fromstring(xml)127 self.song_xml = objectify.fromstring(xml)
138128
=== modified file 'openlp/plugins/songs/lib/songstab.py'
--- openlp/plugins/songs/lib/songstab.py 2015-10-10 20:50:59 +0000
+++ openlp/plugins/songs/lib/songstab.py 2015-11-04 18:37:45 +0000
@@ -41,9 +41,6 @@
41 self.mode_group_box.setObjectName('mode_group_box')41 self.mode_group_box.setObjectName('mode_group_box')
42 self.mode_layout = QtGui.QVBoxLayout(self.mode_group_box)42 self.mode_layout = QtGui.QVBoxLayout(self.mode_group_box)
43 self.mode_layout.setObjectName('mode_layout')43 self.mode_layout.setObjectName('mode_layout')
44 self.search_as_type_check_box = QtGui.QCheckBox(self.mode_group_box)
45 self.search_as_type_check_box.setObjectName('SearchAsType_check_box')
46 self.mode_layout.addWidget(self.search_as_type_check_box)
47 self.tool_bar_active_check_box = QtGui.QCheckBox(self.mode_group_box)44 self.tool_bar_active_check_box = QtGui.QCheckBox(self.mode_group_box)
48 self.tool_bar_active_check_box.setObjectName('tool_bar_active_check_box')45 self.tool_bar_active_check_box.setObjectName('tool_bar_active_check_box')
49 self.mode_layout.addWidget(self.tool_bar_active_check_box)46 self.mode_layout.addWidget(self.tool_bar_active_check_box)
@@ -62,7 +59,6 @@
62 self.left_layout.addWidget(self.mode_group_box)59 self.left_layout.addWidget(self.mode_group_box)
63 self.left_layout.addStretch()60 self.left_layout.addStretch()
64 self.right_layout.addStretch()61 self.right_layout.addStretch()
65 self.search_as_type_check_box.stateChanged.connect(self.on_search_as_type_check_box_changed)
66 self.tool_bar_active_check_box.stateChanged.connect(self.on_tool_bar_active_check_box_changed)62 self.tool_bar_active_check_box.stateChanged.connect(self.on_tool_bar_active_check_box_changed)
67 self.update_on_edit_check_box.stateChanged.connect(self.on_update_on_edit_check_box_changed)63 self.update_on_edit_check_box.stateChanged.connect(self.on_update_on_edit_check_box_changed)
68 self.add_from_service_check_box.stateChanged.connect(self.on_add_from_service_check_box_changed)64 self.add_from_service_check_box.stateChanged.connect(self.on_add_from_service_check_box_changed)
@@ -71,7 +67,6 @@
7167
72 def retranslateUi(self):68 def retranslateUi(self):
73 self.mode_group_box.setTitle(translate('SongsPlugin.SongsTab', 'Songs Mode'))69 self.mode_group_box.setTitle(translate('SongsPlugin.SongsTab', 'Songs Mode'))
74 self.search_as_type_check_box.setText(translate('SongsPlugin.SongsTab', 'Enable search as you type'))
75 self.tool_bar_active_check_box.setText(translate('SongsPlugin.SongsTab',70 self.tool_bar_active_check_box.setText(translate('SongsPlugin.SongsTab',
76 'Display verses on live tool bar'))71 'Display verses on live tool bar'))
77 self.update_on_edit_check_box.setText(translate('SongsPlugin.SongsTab', 'Update service from song edit'))72 self.update_on_edit_check_box.setText(translate('SongsPlugin.SongsTab', 'Update service from song edit'))
@@ -103,13 +98,11 @@
103 def load(self):98 def load(self):
104 settings = Settings()99 settings = Settings()
105 settings.beginGroup(self.settings_section)100 settings.beginGroup(self.settings_section)
106 self.song_search = settings.value('search as type')
107 self.tool_bar = settings.value('display songbar')101 self.tool_bar = settings.value('display songbar')
108 self.update_edit = settings.value('update service on edit')102 self.update_edit = settings.value('update service on edit')
109 self.update_load = settings.value('add song from service')103 self.update_load = settings.value('add song from service')
110 self.display_songbook = settings.value('display songbook')104 self.display_songbook = settings.value('display songbook')
111 self.display_copyright_symbol = settings.value('display copyright symbol')105 self.display_copyright_symbol = settings.value('display copyright symbol')
112 self.search_as_type_check_box.setChecked(self.song_search)
113 self.tool_bar_active_check_box.setChecked(self.tool_bar)106 self.tool_bar_active_check_box.setChecked(self.tool_bar)
114 self.update_on_edit_check_box.setChecked(self.update_edit)107 self.update_on_edit_check_box.setChecked(self.update_edit)
115 self.add_from_service_check_box.setChecked(self.update_load)108 self.add_from_service_check_box.setChecked(self.update_load)
@@ -120,7 +113,6 @@
120 def save(self):113 def save(self):
121 settings = Settings()114 settings = Settings()
122 settings.beginGroup(self.settings_section)115 settings.beginGroup(self.settings_section)
123 settings.setValue('search as type', self.song_search)
124 settings.setValue('display songbar', self.tool_bar)116 settings.setValue('display songbar', self.tool_bar)
125 settings.setValue('update service on edit', self.update_edit)117 settings.setValue('update service on edit', self.update_edit)
126 settings.setValue('add song from service', self.update_load)118 settings.setValue('add song from service', self.update_load)
127119
=== modified file 'openlp/plugins/songs/songsplugin.py'
--- openlp/plugins/songs/songsplugin.py 2015-02-11 20:56:13 +0000
+++ openlp/plugins/songs/songsplugin.py 2015-11-04 18:37:45 +0000
@@ -57,7 +57,6 @@
57 'songs/last search type': SongSearch.Entire,57 'songs/last search type': SongSearch.Entire,
58 'songs/last import type': SongFormat.OpenLyrics,58 'songs/last import type': SongFormat.OpenLyrics,
59 'songs/update service on edit': False,59 'songs/update service on edit': False,
60 'songs/search as type': True,
61 'songs/add song from service': True,60 'songs/add song from service': True,
62 'songs/display songbar': True,61 'songs/display songbar': True,
63 'songs/display songbook': False,62 'songs/display songbook': False,
@@ -226,11 +225,9 @@
226 Called to find out if the song plugin is currently using a theme.225 Called to find out if the song plugin is currently using a theme.
227226
228 :param theme: The theme to check for usage227 :param theme: The theme to check for usage
229 :return: True if the theme is being used, otherwise returns False228 :return: count of the number of times the theme is used.
230 """229 """
231 if self.manager.get_all_objects(Song, Song.theme_name == theme):230 return len(self.manager.get_all_objects(Song, Song.theme_name == theme))
232 return True
233 return False
234231
235 def rename_theme(self, old_theme, new_theme):232 def rename_theme(self, old_theme, new_theme):
236 """233 """
237234
=== added directory 'tests/functional/openlp_core'
=== added file 'tests/functional/openlp_core/test_init.py'
--- tests/functional/openlp_core/test_init.py 1970-01-01 00:00:00 +0000
+++ tests/functional/openlp_core/test_init.py 2015-11-04 18:37:45 +0000
@@ -0,0 +1,144 @@
1# -*- coding: utf-8 -*-
2# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
3
4###############################################################################
5# OpenLP - Open Source Lyrics Projection #
6# --------------------------------------------------------------------------- #
7# Copyright (c) 2008-2015 OpenLP Developers #
8# --------------------------------------------------------------------------- #
9# This program is free software; you can redistribute it and/or modify it #
10# under the terms of the GNU General Public License as published by the Free #
11# Software Foundation; version 2 of the License. #
12# #
13# This program is distributed in the hope that it will be useful, but WITHOUT #
14# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
15# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
16# more details. #
17# #
18# You should have received a copy of the GNU General Public License along #
19# with this program; if not, write to the Free Software Foundation, Inc., 59 #
20# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
21###############################################################################
22
23import sys
24from unittest import TestCase
25
26from openlp.core import parse_options
27from tests.helpers.testmixin import TestMixin
28
29
30class TestInitFunctions(TestMixin, TestCase):
31
32 def parse_options_basic_test(self):
33 """
34 Test the parse options process works
35
36 """
37 # GIVEN: a a set of system arguments.
38 sys.argv[1:] = []
39 # WHEN: We we parse them to expand to options
40 args = parse_options()
41 # THEN: the following fields will have been extracted.
42 self.assertFalse(args.dev_version, 'The dev_version flag should be False')
43 self.assertEquals(args.loglevel, 'warning', 'The log level should be set to warning')
44 self.assertFalse(args.no_error_form, 'The no_error_form should be set to False')
45 self.assertFalse(args.portable, 'The portable flag should be set to false')
46 self.assertEquals(args.style, None, 'There are no style flags to be processed')
47 self.assertEquals(args.rargs, [], 'The service file should be blank')
48
49 def parse_options_debug_test(self):
50 """
51 Test the parse options process works for debug only
52
53 """
54 # GIVEN: a a set of system arguments.
55 sys.argv[1:] = ['-l debug']
56 # WHEN: We we parse them to expand to options
57 args = parse_options()
58 # THEN: the following fields will have been extracted.
59 self.assertFalse(args.dev_version, 'The dev_version flag should be False')
60 self.assertEquals(args.loglevel, ' debug', 'The log level should be set to debug')
61 self.assertFalse(args.no_error_form, 'The no_error_form should be set to False')
62 self.assertFalse(args.portable, 'The portable flag should be set to false')
63 self.assertEquals(args.style, None, 'There are no style flags to be processed')
64 self.assertEquals(args.rargs, [], 'The service file should be blank')
65
66 def parse_options_debug_and_portable_test(self):
67 """
68 Test the parse options process works for debug and portable
69
70 """
71 # GIVEN: a a set of system arguments.
72 sys.argv[1:] = ['--portable']
73 # WHEN: We we parse them to expand to options
74 args = parse_options()
75 # THEN: the following fields will have been extracted.
76 self.assertFalse(args.dev_version, 'The dev_version flag should be False')
77 self.assertEquals(args.loglevel, 'warning', 'The log level should be set to warning')
78 self.assertFalse(args.no_error_form, 'The no_error_form should be set to False')
79 self.assertTrue(args.portable, 'The portable flag should be set to true')
80 self.assertEquals(args.style, None, 'There are no style flags to be processed')
81 self.assertEquals(args.rargs, [], 'The service file should be blank')
82
83 def parse_options_all_no_file_test(self):
84 """
85 Test the parse options process works with two options
86
87 """
88 # GIVEN: a a set of system arguments.
89 sys.argv[1:] = ['-l debug', '-d']
90 # WHEN: We we parse them to expand to options
91 args = parse_options()
92 # THEN: the following fields will have been extracted.
93 self.assertTrue(args.dev_version, 'The dev_version flag should be True')
94 self.assertEquals(args.loglevel, ' debug', 'The log level should be set to debug')
95 self.assertFalse(args.no_error_form, 'The no_error_form should be set to False')
96 self.assertFalse(args.portable, 'The portable flag should be set to false')
97 self.assertEquals(args.style, None, 'There are no style flags to be processed')
98 self.assertEquals(args.rargs, [], 'The service file should be blank')
99
100 def parse_options_file_test(self):
101 """
102 Test the parse options process works with a file
103
104 """
105 # GIVEN: a a set of system arguments.
106 sys.argv[1:] = ['dummy_temp']
107 # WHEN: We we parse them to expand to options
108 args = parse_options()
109 # THEN: the following fields will have been extracted.
110 self.assertFalse(args.dev_version, 'The dev_version flag should be False')
111 self.assertEquals(args.loglevel, 'warning', 'The log level should be set to warning')
112 self.assertFalse(args.no_error_form, 'The no_error_form should be set to False')
113 self.assertFalse(args.portable, 'The portable flag should be set to false')
114 self.assertEquals(args.style, None, 'There are no style flags to be processed')
115 self.assertEquals(args.rargs, 'dummy_temp', 'The service file should not be blank')
116
117 def parse_options_file_and_debug_test(self):
118 """
119 Test the parse options process works with a file
120
121 """
122 # GIVEN: a a set of system arguments.
123 sys.argv[1:] = ['-l debug', 'dummy_temp']
124 # WHEN: We we parse them to expand to options
125 args = parse_options()
126 # THEN: the following fields will have been extracted.
127 self.assertFalse(args.dev_version, 'The dev_version flag should be False')
128 self.assertEquals(args.loglevel, ' debug', 'The log level should be set to debug')
129 self.assertFalse(args.no_error_form, 'The no_error_form should be set to False')
130 self.assertFalse(args.portable, 'The portable flag should be set to false')
131 self.assertEquals(args.style, None, 'There are no style flags to be processed')
132 self.assertEquals(args.rargs, 'dummy_temp', 'The service file should not be blank')
133
134 def parse_options_two_files_test(self):
135 """
136 Test the parse options process works with a file
137
138 """
139 # GIVEN: a a set of system arguments.
140 sys.argv[1:] = ['dummy_temp', 'dummy_temp2']
141 # WHEN: We we parse them to expand to options
142 args = parse_options()
143 # THEN: the following fields will have been extracted.
144 self.assertEquals(args, None, 'The args should be None')
0145
=== added file 'tests/functional/openlp_core_ui/test_advancedtab.py'
--- tests/functional/openlp_core_ui/test_advancedtab.py 1970-01-01 00:00:00 +0000
+++ tests/functional/openlp_core_ui/test_advancedtab.py 2015-11-04 18:37:45 +0000
@@ -0,0 +1,69 @@
1# -*- coding: utf-8 -*-
2# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
3
4###############################################################################
5# OpenLP - Open Source Lyrics Projection #
6# --------------------------------------------------------------------------- #
7# Copyright (c) 2008-2015 OpenLP Developers #
8# --------------------------------------------------------------------------- #
9# This program is free software; you can redistribute it and/or modify it #
10# under the terms of the GNU General Public License as published by the Free #
11# Software Foundation; version 2 of the License. #
12# #
13# This program is distributed in the hope that it will be useful, but WITHOUT #
14# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
15# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
16# more details. #
17# #
18# You should have received a copy of the GNU General Public License along #
19# with this program; if not, write to the Free Software Foundation, Inc., 59 #
20# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
21###############################################################################
22"""
23Package to test the openlp.core.ui.advancedtab package.
24"""
25from unittest import TestCase
26
27from openlp.core.common import Registry
28from openlp.core.ui.advancedtab import AdvancedTab
29from openlp.core.ui.settingsform import SettingsForm
30
31from tests.helpers.testmixin import TestMixin
32
33
34class TestAdvancedTab(TestCase, TestMixin):
35
36 def setUp(self):
37 """
38 Set up a few things for the tests
39 """
40 Registry.create()
41
42 def test_creation(self):
43 """
44 Test that Advanced Tab is created.
45 """
46 # GIVEN: A new Advanced Tab
47 settings_form = SettingsForm(None)
48
49 # WHEN: I create an advanced tab
50 advanced_tab = AdvancedTab(settings_form)
51
52 # THEN:
53 self.assertEqual("Advanced", advanced_tab.tab_title, 'The tab title should be Advanced')
54
55 def test_change_search_as_type(self):
56 """
57 Test that when search as type is changed custom and song configs are updated
58 """
59 # GIVEN: A new Advanced Tab
60 settings_form = SettingsForm(None)
61 advanced_tab = AdvancedTab(settings_form)
62
63 # WHEN: I change search as type check box
64 advanced_tab.on_search_as_type_check_box_changed(True)
65
66 # THEN: we should have two post save processed to run
67 self.assertEqual(2, len(settings_form.processes), 'Two post save processes should be created')
68 self.assertTrue("songs_config_updated" in settings_form.processes, 'The songs plugin should be called')
69 self.assertTrue("custom_config_updated" in settings_form.processes, 'The custom plugin should be called')
070
=== modified file 'tests/functional/openlp_core_ui/test_mainwindow.py'
--- tests/functional/openlp_core_ui/test_mainwindow.py 2015-01-30 21:15:03 +0000
+++ tests/functional/openlp_core_ui/test_mainwindow.py 2015-11-04 18:37:45 +0000
@@ -71,7 +71,7 @@
71 with patch('openlp.core.ui.servicemanager.ServiceManager.load_file') as mocked_load_path:71 with patch('openlp.core.ui.servicemanager.ServiceManager.load_file') as mocked_load_path:
7272
73 # WHEN the argument is processed73 # WHEN the argument is processed
74 self.main_window.open_cmd_line_files()74 self.main_window.open_cmd_line_files(service)
7575
76 # THEN the service from the arguments is loaded76 # THEN the service from the arguments is loaded
77 mocked_load_path.assert_called_with(service), 'load_path should have been called with the service\'s path'77 mocked_load_path.assert_called_with(service), 'load_path should have been called with the service\'s path'
@@ -86,7 +86,7 @@
86 with patch('openlp.core.ui.servicemanager.ServiceManager.load_file') as mocked_load_path:86 with patch('openlp.core.ui.servicemanager.ServiceManager.load_file') as mocked_load_path:
8787
88 # WHEN the argument is processed88 # WHEN the argument is processed
89 self.main_window.open_cmd_line_files()89 self.main_window.open_cmd_line_files("")
9090
91 # THEN the file should not be opened91 # THEN the file should not be opened
92 assert not mocked_load_path.called, 'load_path should not have been called'92 assert not mocked_load_path.called, 'load_path should not have been called'
9393
=== modified file 'tests/functional/openlp_core_utils/test_init.py'
--- tests/functional/openlp_core_utils/test_init.py 2015-01-19 08:34:29 +0000
+++ tests/functional/openlp_core_utils/test_init.py 2015-11-04 18:37:45 +0000
@@ -25,7 +25,7 @@
25from unittest import TestCase25from unittest import TestCase
2626
27from openlp.core.common.settings import Settings27from openlp.core.common.settings import Settings
28from openlp.core.utils import VersionThread, get_application_version, get_uno_command28from openlp.core.utils import VersionThread, get_uno_command
29from tests.functional import MagicMock, patch29from tests.functional import MagicMock, patch
30from tests.helpers.testmixin import TestMixin30from tests.helpers.testmixin import TestMixin
3131
3232
=== modified file 'tests/functional/test_init.py'
--- tests/functional/test_init.py 2015-04-25 19:29:39 +0000
+++ tests/functional/test_init.py 2015-11-04 18:37:45 +0000
@@ -33,7 +33,6 @@
33from tests.helpers.testmixin import TestMixin33from tests.helpers.testmixin import TestMixin
34from tests.functional import MagicMock, patch, call34from tests.functional import MagicMock, patch, call
3535
36
37TEST_PATH = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'resources'))36TEST_PATH = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'resources'))
3837
3938
@@ -132,60 +131,3 @@
132 # THEN: It should ask if we want to create a backup131 # THEN: It should ask if we want to create a backup
133 self.assertEqual(Settings().value('core/application version'), '2.2.0', 'Version should be upgraded!')132 self.assertEqual(Settings().value('core/application version'), '2.2.0', 'Version should be upgraded!')
134 self.assertEqual(mocked_question.call_count, 1, 'A question should have been asked!')133 self.assertEqual(mocked_question.call_count, 1, 'A question should have been asked!')
135
136 @patch(u'openlp.core.OptionParser')
137 def parse_options_test(self, MockedOptionParser):
138 """
139 Test that parse_options sets up OptionParser correctly and parses the options given
140 """
141 # GIVEN: A list of valid options and a mocked out OptionParser object
142 options = ['-e', '-l', 'debug', '-pd', '-s', 'style', 'extra', 'qt', 'args']
143 mocked_parser = MagicMock()
144 MockedOptionParser.return_value = mocked_parser
145 expected_calls = [
146 call('-e', '--no-error-form', dest='no_error_form', action='store_true',
147 help='Disable the error notification form.'),
148 call('-l', '--log-level', dest='loglevel', default='warning', metavar='LEVEL',
149 help='Set logging to LEVEL level. Valid values are "debug", "info", "warning".'),
150 call('-p', '--portable', dest='portable', action='store_true',
151 help='Specify if this should be run as a portable app, off a USB flash drive (not implemented).'),
152 call('-d', '--dev-version', dest='dev_version', action='store_true',
153 help='Ignore the version file and pull the version directly from Bazaar'),
154 call('-s', '--style', dest='style', help='Set the Qt4 style (passed directly to Qt4).')
155 ]
156
157 # WHEN: Calling parse_options
158 parse_options(options)
159
160 # THEN: A tuple should be returned with the parsed options and left over options
161 MockedOptionParser.assert_called_with(usage='Usage: %prog [options] [qt-options]')
162 self.assertEquals(expected_calls, mocked_parser.add_option.call_args_list)
163 mocked_parser.parse_args.assert_called_with(options)
164
165 @patch(u'openlp.core.OptionParser')
166 def parse_options_from_sys_argv_test(self, MockedOptionParser):
167 """
168 Test that parse_options sets up OptionParser correctly and parses sys.argv
169 """
170 # GIVEN: A list of valid options and a mocked out OptionParser object
171 mocked_parser = MagicMock()
172 MockedOptionParser.return_value = mocked_parser
173 expected_calls = [
174 call('-e', '--no-error-form', dest='no_error_form', action='store_true',
175 help='Disable the error notification form.'),
176 call('-l', '--log-level', dest='loglevel', default='warning', metavar='LEVEL',
177 help='Set logging to LEVEL level. Valid values are "debug", "info", "warning".'),
178 call('-p', '--portable', dest='portable', action='store_true',
179 help='Specify if this should be run as a portable app, off a USB flash drive (not implemented).'),
180 call('-d', '--dev-version', dest='dev_version', action='store_true',
181 help='Ignore the version file and pull the version directly from Bazaar'),
182 call('-s', '--style', dest='style', help='Set the Qt4 style (passed directly to Qt4).')
183 ]
184
185 # WHEN: Calling parse_options
186 parse_options([])
187
188 # THEN: A tuple should be returned with the parsed options and left over options
189 MockedOptionParser.assert_called_with(usage='Usage: %prog [options] [qt-options]')
190 self.assertEquals(expected_calls, mocked_parser.add_option.call_args_list)
191 mocked_parser.parse_args.assert_called_with()
192134
=== modified file 'tests/utils/test_bzr_tags.py'
--- tests/utils/test_bzr_tags.py 2015-10-17 11:18:23 +0000
+++ tests/utils/test_bzr_tags.py 2015-11-04 18:37:45 +0000
@@ -23,39 +23,13 @@
23Package to test for proper bzr tags.23Package to test for proper bzr tags.
24"""24"""
25import os25import os
26import re
27from unittest import TestCase26from unittest import TestCase
2827
29from subprocess import Popen, PIPE28from subprocess import Popen, PIPE
3029
31TAGS = [30TAGS1 = {'1.9.0', '1.9.1', '1.9.2', '1.9.3', '1.9.4', '1.9.5', '1.9.6', '1.9.7', '1.9.8', '1.9.9', '1.9.10',
32 ['1.9.0', '1'],31 '1.9.11', '1.9.12', '2.0', '2.1.0', '2.1.1', '2.1.2', '2.1.3', '2.1.4', '2.1.5', '2.1.6', '2.2'
33 ['1.9.1', '775'],32 }
34 ['1.9.2', '890'],
35 ['1.9.3', '1063'],
36 ['1.9.4', '1196'],
37 ['1.9.5', '1421'],
38 ['1.9.6', '1657'],
39 ['1.9.7', '1761'],
40 ['1.9.8', '1856'],
41 ['1.9.9', '1917'],
42 ['1.9.10', '2003'],
43 ['1.9.11', '2039'],
44 ['1.9.12', '2063'],
45 ['2.0', '2118'],
46 ['2.1.0', '2119'],
47 ['2.1.1', '2438'],
48 ['2.1.2', '2488'],
49 ['2.1.3', '2513'],
50 ['2.1.4', '2532'],
51 ['2.1.5', '2543'],
52 ['2.1.6', '2550'],
53 ['2.2', '2562']
54]
55# Depending on the repository, we sometimes have the 2.0.x tags in the repo too. They come up with a revision number of
56# "?", which I suspect is due to the fact that we're using shared repositories. This regular expression matches all
57# 2.0.x tags.
58TAG_SEARCH = re.compile('2\.0\.\d')
5933
6034
61class TestBzrTags(TestCase):35class TestBzrTags(TestCase):
@@ -70,8 +44,12 @@
70 # WHEN getting the branches tags44 # WHEN getting the branches tags
71 bzr = Popen(('bzr', 'tags', '--directory=' + path), stdout=PIPE)45 bzr = Popen(('bzr', 'tags', '--directory=' + path), stdout=PIPE)
72 std_out = bzr.communicate()[0]46 std_out = bzr.communicate()[0]
73 tags = [line.decode('utf-8').split() for line in std_out.splitlines()]47 count = len(TAGS1)
74 tags = [t_r for t_r in tags if t_r[1] != '?' or not (t_r[1] == '?' and TAG_SEARCH.search(t_r[0]))]48 tags = [line.decode('utf-8').split()[0] for line in std_out.splitlines()]
49 count1 = 0
50 for t in tags:
51 if t in TAGS1:
52 count1 += 1
7553
76 # THEN the tags should match the accepted tags54 # THEN the tags should match the accepted tags
77 self.assertEqual(TAGS, tags, 'List of tags should match')55 self.assertEqual(count, count1, 'List of tags should match')