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

Proposed by Tim Bentley on 2015-10-22
Status: Superseded
Proposed branch: lp:~trb143/openlp/bugs-2_4b
Merge into: lp:openlp
Diff against target: 1181 lines (+340/-301)
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 (+1/-1)
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 (+2/-2)
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-10-22 Needs Information on 2015-10-28
Review via email: mp+275390@code.launchpad.net

This proposal supersedes a proposal from 2015-10-18.

This proposal has been superseded by a proposal from 2015-10-28.

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.

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/

review: Needs Information
lp:~trb143/openlp/bugs-2_4b updated on 2015-11-04
2578. By Tim Bentley on 2015-10-28

replace code removed in error

2579. By Tim Bentley on 2015-11-02

minor fix ups

2580. By Tim Bentley on 2015-11-02

head

2581. By Tim Bentley on 2015-11-04

more missed

Unmerged revisions

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'openlp/core/__init__.py'
2--- openlp/core/__init__.py 2015-03-24 22:33:57 +0000
3+++ openlp/core/__init__.py 2015-10-28 21:21:37 +0000
4@@ -30,7 +30,7 @@
5 import os
6 import sys
7 import logging
8-from optparse import OptionParser
9+import argparse
10 from traceback import format_exception
11 import shutil
12 import time
13@@ -282,17 +282,18 @@
14 :return: a tuple of parsed options of type optparse.Value and a list of remaining argsZ
15 """
16 # Set up command line options.
17- usage = 'Usage: %prog [options] [qt-options]'
18- parser = OptionParser(usage=usage)
19- parser.add_option('-e', '--no-error-form', dest='no_error_form', action='store_true',
20- help='Disable the error notification form.')
21- parser.add_option('-l', '--log-level', dest='loglevel', default='warning', metavar='LEVEL',
22- help='Set logging to LEVEL level. Valid values are "debug", "info", "warning".')
23- parser.add_option('-p', '--portable', dest='portable', action='store_true',
24- help='Specify if this should be run as a portable app, off a USB flash drive (not implemented).')
25- parser.add_option('-d', '--dev-version', dest='dev_version', action='store_true',
26- help='Ignore the version file and pull the version directly from Bazaar')
27- parser.add_option('-s', '--style', dest='style', help='Set the Qt4 style (passed directly to Qt4).')
28+ parser = argparse.ArgumentParser(prog='openlp.py')
29+ parser.add_argument('-e', '--no-error-form', dest='no_error_form', action='store_true',
30+ help='Disable the error notification form.')
31+ parser.add_argument('-l', '--log-level', dest='loglevel', default='warning', metavar='LEVEL',
32+ help='Set logging to LEVEL level. Valid values are "debug", "info", "warning".')
33+ parser.add_argument('-p', '--portable', dest='portable', action='store_true',
34+ help='Specify if this should be run as a portable app, '
35+ 'off a USB flash drive (not implemented).')
36+ parser.add_argument('-d', '--dev-version', dest='dev_version', action='store_true',
37+ help='Ignore the version file and pull the version directly from Bazaar')
38+ parser.add_argument('-s', '--style', dest='style', help='Set the Qt4 style (passed directly to Qt4).')
39+ parser.add_argument('rargs', nargs='?', default=[])
40 # Parse command line options and deal with them. Use args supplied pragmatically if possible.
41 return parser.parse_args(args) if args else parser.parse_args()
42
43@@ -318,18 +319,18 @@
44
45 :param args: Some args
46 """
47- (options, args) = parse_options(args)
48+ args = parse_options(args)
49 qt_args = []
50- if options.loglevel.lower() in ['d', 'debug']:
51+ if args and args.loglevel.lower() in ['d', 'debug']:
52 log.setLevel(logging.DEBUG)
53- elif options.loglevel.lower() in ['w', 'warning']:
54+ elif args and args.loglevel.lower() in ['w', 'warning']:
55 log.setLevel(logging.WARNING)
56 else:
57 log.setLevel(logging.INFO)
58- if options.style:
59- qt_args.extend(['-style', options.style])
60+ if args and args.style:
61+ qt_args.extend(['-style', args.style])
62 # Throw the rest of the arguments at Qt, just in case.
63- qt_args.extend(args)
64+ qt_args.extend(args.rargs)
65 # Bug #1018855: Set the WM_CLASS property in X11
66 if not is_win() and not is_macosx():
67 qt_args.append('OpenLP')
68@@ -339,7 +340,7 @@
69 application = OpenLP(qt_args)
70 application.setOrganizationName('OpenLP')
71 application.setOrganizationDomain('openlp.org')
72- if options.portable:
73+ if args and args.portable:
74 application.setApplicationName('OpenLPPortable')
75 Settings.setDefaultFormat(Settings.IniFormat)
76 # Get location OpenLPPortable.ini
77@@ -383,6 +384,6 @@
78 application.installTranslator(default_translator)
79 else:
80 log.debug('Could not find default_translator.')
81- if not options.no_error_form:
82+ if args and not args.no_error_form:
83 sys.excepthook = application.hook_exception
84 sys.exit(application.run(qt_args))
85
86=== modified file 'openlp/core/common/settings.py'
87--- openlp/core/common/settings.py 2015-09-08 19:13:59 +0000
88+++ openlp/core/common/settings.py 2015-10-28 21:21:37 +0000
89@@ -118,6 +118,7 @@
90 'advanced/slide limits': SlideLimits.End,
91 'advanced/single click preview': False,
92 'advanced/x11 bypass wm': X11_BYPASS_DEFAULT,
93+ 'advanced/search as type': True,
94 'crashreport/last directory': '',
95 'formattingTags/html_tags': '',
96 'core/audio repeat list': False,
97@@ -321,48 +322,10 @@
98 }
99 __file_path__ = ''
100 __obsolete_settings__ = [
101- # Changed during 1.9.x development.
102- ('bibles/bookname language', 'bibles/book name language', []),
103- ('general/enable slide loop', 'advanced/slide limits', [(SlideLimits.Wrap, True), (SlideLimits.End, False)]),
104- ('songs/ccli number', 'core/ccli number', []),
105- ('media/use phonon', '', []),
106- # Changed during 2.1.x development.
107- ('advanced/stylesheet fix', '', []),
108- ('bibles/last directory 1', 'bibles/last directory import', []),
109- ('media/background color', 'players/background color', []),
110- ('themes/last directory', 'themes/last directory import', []),
111- ('themes/last directory 1', 'themes/last directory export', []),
112- ('songs/last directory 1', 'songs/last directory import', []),
113- ('songusage/last directory 1', 'songusage/last directory export', []),
114- ('user interface/mainwindow splitter geometry', 'user interface/main window splitter geometry', []),
115- ('shortcuts/makeLive', 'shortcuts/make_live', []),
116- ('general/audio repeat list', 'core/audio repeat list', []),
117- ('general/auto open', 'core/auto open', []),
118- ('general/auto preview', 'core/auto preview', []),
119- ('general/audio start paused', 'core/audio start paused', []),
120- ('general/auto unblank', 'core/auto unblank', []),
121- ('general/blank warning', 'core/blank warning', []),
122- ('general/ccli number', 'core/ccli number', []),
123- ('general/has run wizard', 'core/has run wizard', []),
124- ('general/language', 'core/language', []),
125- ('general/last version test', 'core/last version test', []),
126- ('general/loop delay', 'core/loop delay', []),
127- ('general/recent files', 'core/recent files', [(recent_files_conv, None)]),
128- ('general/save prompt', 'core/save prompt', []),
129- ('general/screen blank', 'core/screen blank', []),
130- ('general/show splash', 'core/show splash', []),
131- ('general/songselect password', 'core/songselect password', []),
132- ('general/songselect username', 'core/songselect username', []),
133- ('general/update check', 'core/update check', []),
134- ('general/view mode', 'core/view mode', []),
135- ('general/display on monitor', 'core/display on monitor', []),
136- ('general/override position', 'core/override position', []),
137- ('general/x position', 'core/x position', []),
138- ('general/y position', 'core/y position', []),
139- ('general/monitor', 'core/monitor', []),
140- ('general/height', 'core/height', []),
141- ('general/monitor', 'core/monitor', []),
142- ('general/width', 'core/width', [])
143+ # Changed during 2.2.x development.
144+ # ('advanced/stylesheet fix', '', []),
145+ # ('general/recent files', 'core/recent files', [(recent_files_conv, None)]),
146+ ('songs/search as type', 'advanced/search as type', [])
147 ]
148
149 @staticmethod
150
151=== modified file 'openlp/core/common/uistrings.py'
152--- openlp/core/common/uistrings.py 2015-04-21 21:49:22 +0000
153+++ openlp/core/common/uistrings.py 2015-10-28 21:21:37 +0000
154@@ -108,8 +108,9 @@
155 self.NFSp = translate('OpenLP.Ui', 'No Files Selected', 'Plural')
156 self.NISs = translate('OpenLP.Ui', 'No Item Selected', 'Singular')
157 self.NISp = translate('OpenLP.Ui', 'No Items Selected', 'Plural')
158- self.OLPV2 = translate('OpenLP.Ui', 'OpenLP 2')
159- self.OLPV2x = translate('OpenLP.Ui', 'OpenLP 2.2')
160+ self.OLP = translate('OpenLP.Ui', 'OpenLP')
161+ self.OLPV2 = "%s %s" % (self.OLP, "2")
162+ self.OLPV2x = "%s %s" % (self.OLP, "2.4")
163 self.OpenLPStart = translate('OpenLP.Ui', 'OpenLP is already running. Do you wish to continue?')
164 self.OpenService = translate('OpenLP.Ui', 'Open service.')
165 self.PlaySlidesInLoop = translate('OpenLP.Ui', 'Play Slides in Loop')
166
167=== modified file 'openlp/core/lib/plugin.py'
168--- openlp/core/lib/plugin.py 2015-01-18 13:39:21 +0000
169+++ openlp/core/lib/plugin.py 2015-10-28 21:21:37 +0000
170@@ -288,13 +288,7 @@
171 """
172 Perform tasks on application startup
173 """
174- # FIXME: Remove after 2.2 release.
175- # This is needed to load the list of media/presentation from the config saved before the settings rewrite.
176- if self.media_item_class is not None and self.name != 'images':
177- loaded_list = Settings().get_files_from_config(self)
178- # Now save the list to the config using our Settings class.
179- if loaded_list:
180- Settings().setValue('%s/%s files' % (self.settings_section, self.name), loaded_list)
181+ pass
182
183 def uses_theme(self, theme):
184 """
185
186=== modified file 'openlp/core/lib/serviceitem.py'
187--- openlp/core/lib/serviceitem.py 2015-09-08 19:13:59 +0000
188+++ openlp/core/lib/serviceitem.py 2015-10-28 21:21:37 +0000
189@@ -129,7 +129,7 @@
190 OnLoadUpdate = 8
191 AddIfNewItem = 9
192 ProvidesOwnDisplay = 10
193- HasDetailedTitleDisplay = 11
194+ # HasDetailedTitleDisplay = 11
195 HasVariableStartTime = 12
196 CanSoftBreak = 13
197 CanWordSplit = 14
198@@ -415,11 +415,6 @@
199 self.will_auto_start = header.get('will_auto_start', False)
200 self.processor = header.get('processor', None)
201 self.has_original_files = True
202- # TODO: Remove me in 2,3 build phase
203- if self.is_capable(ItemCapabilities.HasDetailedTitleDisplay):
204- self.capabilities.remove(ItemCapabilities.HasDetailedTitleDisplay)
205- self.processor = self.title
206- self.title = None
207 if 'background_audio' in header:
208 self.background_audio = []
209 for filename in header['background_audio']:
210
211=== modified file 'openlp/core/ui/advancedtab.py'
212--- openlp/core/ui/advancedtab.py 2015-01-18 13:39:21 +0000
213+++ openlp/core/ui/advancedtab.py 2015-10-28 21:21:37 +0000
214@@ -80,6 +80,9 @@
215 self.expand_service_item_check_box = QtGui.QCheckBox(self.ui_group_box)
216 self.expand_service_item_check_box.setObjectName('expand_service_item_check_box')
217 self.ui_layout.addRow(self.expand_service_item_check_box)
218+ self.search_as_type_check_box = QtGui.QCheckBox(self.ui_group_box)
219+ self.search_as_type_check_box.setObjectName('SearchAsType_check_box')
220+ self.ui_layout.addRow(self.search_as_type_check_box)
221 self.enable_auto_close_check_box = QtGui.QCheckBox(self.ui_group_box)
222 self.enable_auto_close_check_box.setObjectName('enable_auto_close_check_box')
223 self.ui_layout.addRow(self.enable_auto_close_check_box)
224@@ -251,6 +254,7 @@
225 self.end_slide_radio_button.clicked.connect(self.on_end_slide_button_clicked)
226 self.wrap_slide_radio_button.clicked.connect(self.on_wrap_slide_button_clicked)
227 self.next_item_radio_button.clicked.connect(self.on_next_item_button_clicked)
228+ self.search_as_type_check_box.stateChanged.connect(self.on_search_as_type_check_box_changed)
229
230 def retranslateUi(self):
231 """
232@@ -319,6 +323,7 @@
233 self.end_slide_radio_button.setText(translate('OpenLP.GeneralTab', '&Remain on Slide'))
234 self.wrap_slide_radio_button.setText(translate('OpenLP.GeneralTab', '&Wrap around'))
235 self.next_item_radio_button.setText(translate('OpenLP.GeneralTab', '&Move to next/previous service item'))
236+ self.search_as_type_check_box.setText(translate('SongsPlugin.GeneralTab', 'Enable search as you type'))
237
238 def load(self):
239 """
240@@ -349,6 +354,8 @@
241 self.default_color = settings.value('default color')
242 self.default_file_edit.setText(settings.value('default image'))
243 self.slide_limits = settings.value('slide limits')
244+ self.search_as_you_type = settings.value('search as type')
245+ self.search_as_type_check_box.setChecked(self.search_as_you_type)
246 # Prevent the dialog displayed by the alternate_rows_check_box to display.
247 self.alternate_rows_check_box.blockSignals(True)
248 self.alternate_rows_check_box.setChecked(settings.value('alternate rows'))
249@@ -424,8 +431,14 @@
250 settings.setValue('x11 bypass wm', self.x11_bypass_check_box.isChecked())
251 self.settings_form.register_post_process('config_screen_changed')
252 self.settings_form.register_post_process('slidecontroller_update_slide_limits')
253+ settings.setValue('search as type', self.search_as_you_type)
254 settings.endGroup()
255
256+ def on_search_as_type_check_box_changed(self, check_state):
257+ self.search_as_you_type = (check_state == QtCore.Qt.Checked)
258+ self.settings_form.register_post_process('songs_config_updated')
259+ self.settings_form.register_post_process('custom_config_updated')
260+
261 def cancel(self):
262 """
263 Dialogue was cancelled, remove any pending data path change.
264
265=== modified file 'openlp/core/ui/mainwindow.py'
266--- openlp/core/ui/mainwindow.py 2015-08-24 18:19:30 +0000
267+++ openlp/core/ui/mainwindow.py 2015-10-28 21:21:37 +0000
268@@ -389,7 +389,7 @@
269 self.file_menu.setTitle(translate('OpenLP.MainWindow', '&File'))
270 self.file_import_menu.setTitle(translate('OpenLP.MainWindow', '&Import'))
271 self.file_export_menu.setTitle(translate('OpenLP.MainWindow', '&Export'))
272- self.recent_files_menu.setTitle(translate('OpenLP.MainWindow', '&Recent Files'))
273+ self.recent_files_menu.setTitle(translate('OpenLP.MainWindow', '&Recent Services'))
274 self.view_menu.setTitle(translate('OpenLP.MainWindow', '&View'))
275 self.view_mode_menu.setTitle(translate('OpenLP.MainWindow', 'M&ode'))
276 self.tools_menu.setTitle(translate('OpenLP.MainWindow', '&Tools'))
277@@ -400,16 +400,16 @@
278 self.service_manager_dock.setWindowTitle(translate('OpenLP.MainWindow', 'Service Manager'))
279 self.theme_manager_dock.setWindowTitle(translate('OpenLP.MainWindow', 'Theme Manager'))
280 self.projector_manager_dock.setWindowTitle(translate('OpenLP.MainWindow', 'Projector Manager'))
281- self.file_new_item.setText(translate('OpenLP.MainWindow', '&New'))
282+ self.file_new_item.setText(translate('OpenLP.MainWindow', '&New Service'))
283 self.file_new_item.setToolTip(UiStrings().NewService)
284 self.file_new_item.setStatusTip(UiStrings().CreateService)
285- self.file_open_item.setText(translate('OpenLP.MainWindow', '&Open'))
286+ self.file_open_item.setText(translate('OpenLP.MainWindow', '&Open Service'))
287 self.file_open_item.setToolTip(UiStrings().OpenService)
288 self.file_open_item.setStatusTip(translate('OpenLP.MainWindow', 'Open an existing service.'))
289- self.file_save_item.setText(translate('OpenLP.MainWindow', '&Save'))
290+ self.file_save_item.setText(translate('OpenLP.MainWindow', '&Save Service'))
291 self.file_save_item.setToolTip(UiStrings().SaveService)
292 self.file_save_item.setStatusTip(translate('OpenLP.MainWindow', 'Save the current service to disk.'))
293- self.file_save_as_item.setText(translate('OpenLP.MainWindow', 'Save &As...'))
294+ self.file_save_as_item.setText(translate('OpenLP.MainWindow', 'Save Service &As...'))
295 self.file_save_as_item.setToolTip(translate('OpenLP.MainWindow', 'Save Service As'))
296 self.file_save_as_item.setStatusTip(translate('OpenLP.MainWindow',
297 'Save the current service under a new name.'))
298@@ -456,7 +456,7 @@
299 self.lock_panel.setText(translate('OpenLP.MainWindow', 'L&ock Panels'))
300 self.lock_panel.setStatusTip(translate('OpenLP.MainWindow', 'Prevent the panels being moved.'))
301 self.view_live_panel.setStatusTip(translate('OpenLP.MainWindow', 'Toggle the visibility of the live panel.'))
302- self.settings_plugin_list_item.setText(translate('OpenLP.MainWindow', '&Plugin List'))
303+ self.settings_plugin_list_item.setText(translate('OpenLP.MainWindow', '&Manage Plugins'))
304 self.settings_plugin_list_item.setStatusTip(translate('OpenLP.MainWindow', 'List the Plugins'))
305 self.about_item.setText(translate('OpenLP.MainWindow', '&About'))
306 self.about_item.setStatusTip(translate('OpenLP.MainWindow', 'More information about OpenLP'))
307@@ -505,7 +505,7 @@
308 super(MainWindow, self).__init__()
309 Registry().register('main_window', self)
310 self.clipboard = self.application.clipboard()
311- self.arguments = self.application.args
312+ self.arguments = ''.join(self.application.args)
313 # Set up settings sections for the main application (not for use by plugins).
314 self.ui_settings_section = 'user interface'
315 self.general_settings_section = 'core'
316@@ -634,7 +634,7 @@
317 self.live_controller.display.setFocus()
318 self.activateWindow()
319 if self.arguments:
320- self.open_cmd_line_files()
321+ self.open_cmd_line_files(self.arguments)
322 elif Settings().value(self.general_settings_section + '/auto open'):
323 self.service_manager_contents.load_last_file()
324 view_mode = Settings().value('%s/view mode' % self.general_settings_section)
325@@ -1416,15 +1416,11 @@
326 settings.remove('advanced/data path')
327 self.application.set_normal_cursor()
328
329- def open_cmd_line_files(self):
330+ def open_cmd_line_files(self, filename):
331 """
332 Open files passed in through command line arguments
333 """
334- args = []
335- for a in self.arguments:
336- args.extend([a])
337- for filename in args:
338- if not isinstance(filename, str):
339- filename = str(filename, sys.getfilesystemencoding())
340- if filename.endswith(('.osz', '.oszl')):
341- self.service_manager_contents.load_file(filename)
342+ if not isinstance(filename, str):
343+ filename = str(filename, sys.getfilesystemencoding())
344+ if filename.endswith(('.osz', '.oszl')):
345+ self.service_manager_contents.load_file(filename)
346
347=== modified file 'openlp/core/ui/plugindialog.py'
348--- openlp/core/ui/plugindialog.py 2015-01-18 13:39:21 +0000
349+++ openlp/core/ui/plugindialog.py 2015-10-28 21:21:37 +0000
350@@ -78,7 +78,7 @@
351 """
352 Translate the UI on the fly
353 """
354- pluginViewDialog.setWindowTitle(translate('OpenLP.PluginForm', 'Plugin List'))
355+ pluginViewDialog.setWindowTitle(translate('OpenLP.PluginForm', 'Manage Plugins'))
356 self.plugin_info_group_box.setTitle(translate('OpenLP.PluginForm', 'Plugin Details'))
357 self.version_label.setText('%s:' % UiStrings().Version)
358 self.about_label.setText('%s:' % UiStrings().About)
359
360=== modified file 'openlp/core/ui/printserviceform.py'
361--- openlp/core/ui/printserviceform.py 2015-04-11 22:13:30 +0000
362+++ openlp/core/ui/printserviceform.py 2015-10-28 21:21:37 +0000
363@@ -162,7 +162,7 @@
364 html_data = self._add_element('html')
365 self._add_element('head', parent=html_data)
366 self._add_element('title', self.title_line_edit.text(), html_data.head)
367- css_path = os.path.join(AppLocation.get_data_path(), 'service_print.css')
368+ css_path = os.path.join(AppLocation.get_data_path(), 'serviceprint', 'service_print.css')
369 custom_css = get_text_file_string(css_path)
370 if not custom_css:
371 custom_css = DEFAULT_CSS
372
373=== modified file 'openlp/core/ui/thememanager.py'
374--- openlp/core/ui/thememanager.py 2015-09-08 19:13:59 +0000
375+++ openlp/core/ui/thememanager.py 2015-10-28 21:21:37 +0000
376@@ -755,12 +755,19 @@
377 return False
378 # check for use in the system else where.
379 if test_plugin:
380+ plugin_usage = ""
381 for plugin in self.plugin_manager.plugins:
382- if plugin.uses_theme(theme):
383- critical_error_message_box(translate('OpenLP.ThemeManager', 'Validation Error'),
384- translate('OpenLP.ThemeManager',
385- 'Theme %s is used in the %s plugin.')
386- % (theme, plugin.name))
387- return False
388+ used_count = plugin.uses_theme(theme)
389+ if used_count:
390+ plugin_usage = "%s%s" % (plugin_usage, (translate('OpenLP.ThemeManager',
391+ '%s time(s) by %s') %
392+ (used_count, plugin.name)))
393+ plugin_usage = "%s\n" % plugin_usage
394+ if plugin_usage:
395+ critical_error_message_box(translate('OpenLP.ThemeManager', 'Unable to delete theme'),
396+ translate('OpenLP.ThemeManager', 'Theme is currently used \n\n%s') %
397+ plugin_usage)
398+
399+ return False
400 return True
401 return False
402
403=== modified file 'openlp/plugins/bibles/bibleplugin.py'
404--- openlp/plugins/bibles/bibleplugin.py 2015-03-10 21:33:35 +0000
405+++ openlp/plugins/bibles/bibleplugin.py 2015-10-28 21:21:37 +0000
406@@ -178,12 +178,14 @@
407
408 def uses_theme(self, theme):
409 """
410- Called to find out if the bible plugin is currently using a theme. Returns ``True`` if the theme is being used,
411- otherwise returns ``False``.
412+ Called to find out if the bible plugin is currently using a theme. Returns ``1`` if the theme is being used,
413+ otherwise returns ``0``.
414
415 :param theme: The theme
416 """
417- return str(self.settings_tab.bible_theme) == theme
418+ if str(self.settings_tab.bible_theme) == theme:
419+ return 1
420+ return 0
421
422 def rename_theme(self, old_theme, new_theme):
423 """
424
425=== modified file 'openlp/plugins/bibles/lib/db.py'
426--- openlp/plugins/bibles/lib/db.py 2015-09-08 19:13:26 +0000
427+++ openlp/plugins/bibles/lib/db.py 2015-10-28 21:21:37 +0000
428@@ -476,16 +476,6 @@
429 self.save_meta('language_id', language_id)
430 return language_id
431
432- def is_old_database(self):
433- """
434- Returns ``True`` if it is a bible database, which has been created prior to 1.9.6.
435- """
436- try:
437- self.session.query(Book).all()
438- except:
439- return True
440- return False
441-
442 def dump_bible(self):
443 """
444 Utility debugging method to dump the contents of a bible.
445
446=== modified file 'openlp/plugins/bibles/lib/manager.py'
447--- openlp/plugins/bibles/lib/manager.py 2015-01-31 21:52:02 +0000
448+++ openlp/plugins/bibles/lib/manager.py 2015-10-28 21:21:37 +0000
449@@ -129,11 +129,6 @@
450 bible.session.close()
451 delete_file(os.path.join(self.path, filename))
452 continue
453- # Find old database versions.
454- if bible.is_old_database():
455- self.old_bible_databases.append([filename, name])
456- bible.session.close()
457- continue
458 log.debug('Bible Name: "%s"', name)
459 self.db_cache[name] = bible
460 # Look to see if lazy load bible exists and get create getter.
461
462=== modified file 'openlp/plugins/custom/customplugin.py'
463--- openlp/plugins/custom/customplugin.py 2015-02-11 20:56:13 +0000
464+++ openlp/plugins/custom/customplugin.py 2015-10-28 21:21:37 +0000
465@@ -72,11 +72,9 @@
466 """
467 Called to find out if the custom plugin is currently using a theme.
468
469- Returns True if the theme is being used, otherwise returns False.
470+ Returns count of the times the theme is used.
471 """
472- if self.db_manager.get_all_objects(CustomSlide, CustomSlide.theme_name == theme):
473- return True
474- return False
475+ return len(self.db_manager.get_all_objects(CustomSlide, CustomSlide.theme_name == theme))
476
477 def rename_theme(self, old_theme, new_theme):
478 """
479
480=== modified file 'openlp/plugins/custom/lib/mediaitem.py'
481--- openlp/plugins/custom/lib/mediaitem.py 2015-04-02 20:49:19 +0000
482+++ openlp/plugins/custom/lib/mediaitem.py 2015-10-28 21:21:37 +0000
483@@ -85,6 +85,7 @@
484 """
485 log.debug('Config loaded')
486 self.add_custom_from_service = Settings().value(self.settings_section + '/add custom from service')
487+ self.search_as_you_type = Settings().value('advanced/search as type')
488
489 def retranslateUi(self):
490 """
491@@ -269,11 +270,12 @@
492
493 :param text: The search text
494 """
495- search_length = 2
496- if len(text) > search_length:
497- self.on_search_text_button_clicked()
498- elif not text:
499- self.on_clear_text_button_click()
500+ if self.search_as_you_type:
501+ search_length = 2
502+ if len(text) > search_length:
503+ self.on_search_text_button_clicked()
504+ elif not text:
505+ self.on_clear_text_button_click()
506
507 def service_load(self, item):
508 """
509
510=== modified file 'openlp/plugins/images/imageplugin.py'
511--- openlp/plugins/images/imageplugin.py 2015-02-11 22:15:46 +0000
512+++ openlp/plugins/images/imageplugin.py 2015-10-28 21:21:37 +0000
513@@ -67,36 +67,13 @@
514 'provided by the theme.')
515 return about_text
516
517- def app_startup(self):
518- """
519- Perform tasks on application startup.
520- """
521- # TODO: Can be removed when the upgrade path from 2.0.x to 2.2.x is no longer needed
522- Plugin.app_startup(self)
523- # Convert old settings-based image list to the database.
524- files_from_config = Settings().get_files_from_config(self)
525- if files_from_config:
526- for file in files_from_config:
527- filename = os.path.split(file)[1]
528- thumb = os.path.join(self.media_item.service_path, filename)
529- try:
530- os.remove(thumb)
531- except:
532- pass
533- log.debug('Importing images list from old config: %s' % files_from_config)
534- self.media_item.save_new_images_list(files_from_config)
535-
536 def upgrade_settings(self, settings):
537 """
538 Upgrade the settings of this plugin.
539
540 :param settings: The Settings object containing the old settings.
541 """
542- # TODO: Can be removed when the upgrade path from 2.0.x to 2.2.x is no longer needed
543- files_from_config = settings.get_files_from_config(self)
544- if files_from_config:
545- log.debug('Importing images list from old config: %s' % files_from_config)
546- self.media_item.save_new_images_list(files_from_config)
547+ pass
548
549 def set_plugin_text_strings(self):
550 """
551
552=== modified file 'openlp/plugins/images/lib/mediaitem.py'
553--- openlp/plugins/images/lib/mediaitem.py 2015-09-08 19:13:59 +0000
554+++ openlp/plugins/images/lib/mediaitem.py 2015-10-28 21:21:37 +0000
555@@ -119,14 +119,6 @@
556 icon=':/general/general_edit.png',
557 triggers=self.on_edit_click)
558 create_widget_action(self.list_view, separator=True)
559- if self.has_delete_icon:
560- create_widget_action(
561- self.list_view,
562- 'listView%s%sItem' % (self.plugin.name.title(), StringContent.Delete.title()),
563- text=self.plugin.get_string(StringContent.Delete)['title'],
564- icon=':/general/general_delete.png',
565- can_shortcuts=True, triggers=self.on_delete_click)
566- create_widget_action(self.list_view, separator=True)
567 create_widget_action(
568 self.list_view,
569 'listView%s%sItem' % (self.plugin.name.title(), StringContent.Preview.title()),
570@@ -155,6 +147,14 @@
571 text=translate('OpenLP.MediaManagerItem', '&Add to selected Service Item'),
572 icon=':/general/general_add.png',
573 triggers=self.on_add_edit_click)
574+ create_widget_action(self.list_view, separator=True)
575+ if self.has_delete_icon:
576+ create_widget_action(
577+ self.list_view,
578+ 'listView%s%sItem' % (self.plugin.name.title(), StringContent.Delete.title()),
579+ text=self.plugin.get_string(StringContent.Delete)['title'],
580+ icon=':/general/general_delete.png',
581+ can_shortcuts=True, triggers=self.on_delete_click)
582 self.add_custom_context_actions()
583 # Create the context menu and add all actions from the list_view.
584 self.menu = QtGui.QMenu()
585
586=== modified file 'openlp/plugins/presentations/presentationplugin.py'
587--- openlp/plugins/presentations/presentationplugin.py 2015-05-26 21:26:59 +0000
588+++ openlp/plugins/presentations/presentationplugin.py 2015-10-28 21:21:37 +0000
589@@ -137,22 +137,6 @@
590 self.register_controllers(controller)
591 return bool(self.controllers)
592
593- def app_startup(self):
594- """
595- Perform tasks on application startup.
596- """
597- # TODO: Can be removed when the upgrade path from 2.0.x to 2.2.x is no longer needed
598- super().app_startup()
599- files_from_config = Settings().value('presentations/presentations files')
600- for file in files_from_config:
601- try:
602- self.media_item.clean_up_thumbnails(file, True)
603- except AttributeError:
604- pass
605- self.media_item.list_view.clear()
606- Settings().setValue('presentations/thumbnail_scheme', 'md5')
607- self.media_item.validate_and_load(files_from_config)
608-
609 def about(self):
610 """
611 Return information about this plugin.
612
613=== modified file 'openlp/plugins/remotes/html/openlp.js'
614--- openlp/plugins/remotes/html/openlp.js 2015-01-18 13:39:21 +0000
615+++ openlp/plugins/remotes/html/openlp.js 2015-10-28 21:21:37 +0000
616@@ -271,9 +271,15 @@
617 if (typeof value[0] !== "number"){
618 value[0] = OpenLP.escapeString(value[0])
619 }
620+ var txt = "";
621+ if (value[2].length > 0) {
622+ txt = value[1] + " ( " + value[2] + " )";
623+ } else {
624+ txt = value[1];
625+ }
626 ul.append($("<li>").append($("<a>").attr("href", "#options")
627 .attr("data-rel", "dialog").attr("value", value[0])
628- .click(OpenLP.showOptions).text(value[1])));
629+ .click(OpenLP.showOptions).text(txt)));
630 });
631 }
632 ul.listview("refresh");
633
634=== modified file 'openlp/plugins/remotes/lib/httprouter.py'
635--- openlp/plugins/remotes/lib/httprouter.py 2015-02-14 09:12:35 +0000
636+++ openlp/plugins/remotes/lib/httprouter.py 2015-10-28 21:21:37 +0000
637@@ -309,10 +309,13 @@
638 """
639 Translate various strings in the mobile app.
640 """
641+ remote = translate('RemotePlugin.Mobile', 'Remote')
642+ stage = translate('RemotePlugin.Mobile', 'Stage View')
643+ live = translate('RemotePlugin.Mobile', 'Live View')
644 self.template_vars = {
645- 'app_title': translate('RemotePlugin.Mobile', 'OpenLP 2.2 Remote'),
646- 'stage_title': translate('RemotePlugin.Mobile', 'OpenLP 2.2 Stage View'),
647- 'live_title': translate('RemotePlugin.Mobile', 'OpenLP 2.2 Live View'),
648+ 'app_title': "%s %s" % (UiStrings().OLPV2x, remote),
649+ 'stage_title': "%s %s" % (UiStrings().OLPV2x, stage),
650+ 'live_title': "%s %s" % (UiStrings().OLPV2x, live),
651 'service_manager': translate('RemotePlugin.Mobile', 'Service Manager'),
652 'slide_controller': translate('RemotePlugin.Mobile', 'Slide Controller'),
653 'alerts': translate('RemotePlugin.Mobile', 'Alerts'),
654
655=== modified file 'openlp/plugins/songs/forms/editsongform.py'
656--- openlp/plugins/songs/forms/editsongform.py 2015-01-18 13:39:21 +0000
657+++ openlp/plugins/songs/forms/editsongform.py 2015-10-28 21:21:37 +0000
658@@ -178,7 +178,7 @@
659 if invalid_verses:
660 valid = create_separated_list(verse_names)
661 if len(invalid_verses) > 1:
662- msg = translate('SongsPlugin.EditSongForm', 'There are no verses corresponding to "%(invalid)s".'
663+ msg = translate('SongsPlugin.EditSongForm', 'There are no verses corresponding to "%(invalid)s". '
664 'Valid entries are %(valid)s.\nPlease enter the verses separated by spaces.') % \
665 {'invalid': ', '.join(invalid_verses), 'valid': valid}
666 else:
667
668=== modified file 'openlp/plugins/songs/lib/mediaitem.py'
669--- openlp/plugins/songs/lib/mediaitem.py 2015-01-18 13:39:21 +0000
670+++ openlp/plugins/songs/lib/mediaitem.py 2015-10-28 21:21:37 +0000
671@@ -115,7 +115,7 @@
672 Is triggered when the songs config is updated
673 """
674 log.debug('config_updated')
675- self.search_as_you_type = Settings().value(self.settings_section + '/search as type')
676+ self.search_as_you_type = Settings().value('advanced/search as type')
677 self.update_service_on_edit = Settings().value(self.settings_section + '/update service on edit')
678 self.add_song_from_service = Settings().value(self.settings_section + '/add song from service')
679 self.display_songbook = Settings().value(self.settings_section + '/display songbook')
680@@ -590,4 +590,4 @@
681 :param show_error: Is this an error?
682 """
683 search_results = self.search_entire(string)
684- return [[song.id, song.title] for song in search_results]
685+ return [[song.id, song.title, song.alternate_title] for song in search_results]
686
687=== modified file 'openlp/plugins/songs/lib/openlyricsxml.py'
688--- openlp/plugins/songs/lib/openlyricsxml.py 2015-09-08 19:13:59 +0000
689+++ openlp/plugins/songs/lib/openlyricsxml.py 2015-10-28 21:21:37 +0000
690@@ -121,17 +121,7 @@
691 """
692 self.song_xml = None
693 verse_list = []
694- if not xml.startswith('<?xml') and not xml.startswith('<song'):
695- # This is an old style song, without XML. Let's handle it correctly by iterating through the verses, and
696- # then recreating the internal xml object as well.
697- self.song_xml = objectify.fromstring('<song version="1.0" />')
698- self.lyrics = etree.SubElement(self.song_xml, 'lyrics')
699- verses = xml.split('\n\n')
700- for count, verse in enumerate(verses):
701- verse_list.append([{'type': 'v', 'label': str(count)}, str(verse)])
702- self.add_verse_to_lyrics('v', str(count), verse)
703- return verse_list
704- elif xml.startswith('<?xml'):
705+ if xml.startswith('<?xml'):
706 xml = xml[38:]
707 try:
708 self.song_xml = objectify.fromstring(xml)
709
710=== modified file 'openlp/plugins/songs/lib/songstab.py'
711--- openlp/plugins/songs/lib/songstab.py 2015-10-10 20:50:59 +0000
712+++ openlp/plugins/songs/lib/songstab.py 2015-10-28 21:21:37 +0000
713@@ -41,9 +41,6 @@
714 self.mode_group_box.setObjectName('mode_group_box')
715 self.mode_layout = QtGui.QVBoxLayout(self.mode_group_box)
716 self.mode_layout.setObjectName('mode_layout')
717- self.search_as_type_check_box = QtGui.QCheckBox(self.mode_group_box)
718- self.search_as_type_check_box.setObjectName('SearchAsType_check_box')
719- self.mode_layout.addWidget(self.search_as_type_check_box)
720 self.tool_bar_active_check_box = QtGui.QCheckBox(self.mode_group_box)
721 self.tool_bar_active_check_box.setObjectName('tool_bar_active_check_box')
722 self.mode_layout.addWidget(self.tool_bar_active_check_box)
723@@ -62,7 +59,6 @@
724 self.left_layout.addWidget(self.mode_group_box)
725 self.left_layout.addStretch()
726 self.right_layout.addStretch()
727- self.search_as_type_check_box.stateChanged.connect(self.on_search_as_type_check_box_changed)
728 self.tool_bar_active_check_box.stateChanged.connect(self.on_tool_bar_active_check_box_changed)
729 self.update_on_edit_check_box.stateChanged.connect(self.on_update_on_edit_check_box_changed)
730 self.add_from_service_check_box.stateChanged.connect(self.on_add_from_service_check_box_changed)
731@@ -71,7 +67,6 @@
732
733 def retranslateUi(self):
734 self.mode_group_box.setTitle(translate('SongsPlugin.SongsTab', 'Songs Mode'))
735- self.search_as_type_check_box.setText(translate('SongsPlugin.SongsTab', 'Enable search as you type'))
736 self.tool_bar_active_check_box.setText(translate('SongsPlugin.SongsTab',
737 'Display verses on live tool bar'))
738 self.update_on_edit_check_box.setText(translate('SongsPlugin.SongsTab', 'Update service from song edit'))
739@@ -103,13 +98,11 @@
740 def load(self):
741 settings = Settings()
742 settings.beginGroup(self.settings_section)
743- self.song_search = settings.value('search as type')
744 self.tool_bar = settings.value('display songbar')
745 self.update_edit = settings.value('update service on edit')
746 self.update_load = settings.value('add song from service')
747 self.display_songbook = settings.value('display songbook')
748 self.display_copyright_symbol = settings.value('display copyright symbol')
749- self.search_as_type_check_box.setChecked(self.song_search)
750 self.tool_bar_active_check_box.setChecked(self.tool_bar)
751 self.update_on_edit_check_box.setChecked(self.update_edit)
752 self.add_from_service_check_box.setChecked(self.update_load)
753@@ -120,7 +113,6 @@
754 def save(self):
755 settings = Settings()
756 settings.beginGroup(self.settings_section)
757- settings.setValue('search as type', self.song_search)
758 settings.setValue('display songbar', self.tool_bar)
759 settings.setValue('update service on edit', self.update_edit)
760 settings.setValue('add song from service', self.update_load)
761
762=== modified file 'openlp/plugins/songs/songsplugin.py'
763--- openlp/plugins/songs/songsplugin.py 2015-02-11 20:56:13 +0000
764+++ openlp/plugins/songs/songsplugin.py 2015-10-28 21:21:37 +0000
765@@ -57,7 +57,6 @@
766 'songs/last search type': SongSearch.Entire,
767 'songs/last import type': SongFormat.OpenLyrics,
768 'songs/update service on edit': False,
769- 'songs/search as type': True,
770 'songs/add song from service': True,
771 'songs/display songbar': True,
772 'songs/display songbook': False,
773@@ -226,11 +225,9 @@
774 Called to find out if the song plugin is currently using a theme.
775
776 :param theme: The theme to check for usage
777- :return: True if the theme is being used, otherwise returns False
778+ :return: count of the number of times the theme is used.
779 """
780- if self.manager.get_all_objects(Song, Song.theme_name == theme):
781- return True
782- return False
783+ return len(self.manager.get_all_objects(Song, Song.theme_name == theme))
784
785 def rename_theme(self, old_theme, new_theme):
786 """
787
788=== added directory 'tests/functional/openlp_core'
789=== added file 'tests/functional/openlp_core/test_init.py'
790--- tests/functional/openlp_core/test_init.py 1970-01-01 00:00:00 +0000
791+++ tests/functional/openlp_core/test_init.py 2015-10-28 21:21:37 +0000
792@@ -0,0 +1,144 @@
793+# -*- coding: utf-8 -*-
794+# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
795+
796+###############################################################################
797+# OpenLP - Open Source Lyrics Projection #
798+# --------------------------------------------------------------------------- #
799+# Copyright (c) 2008-2015 OpenLP Developers #
800+# --------------------------------------------------------------------------- #
801+# This program is free software; you can redistribute it and/or modify it #
802+# under the terms of the GNU General Public License as published by the Free #
803+# Software Foundation; version 2 of the License. #
804+# #
805+# This program is distributed in the hope that it will be useful, but WITHOUT #
806+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
807+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
808+# more details. #
809+# #
810+# You should have received a copy of the GNU General Public License along #
811+# with this program; if not, write to the Free Software Foundation, Inc., 59 #
812+# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
813+###############################################################################
814+
815+import sys
816+from unittest import TestCase
817+
818+from openlp.core import parse_options
819+from tests.helpers.testmixin import TestMixin
820+
821+
822+class TestInitFunctions(TestMixin, TestCase):
823+
824+ def parse_options_basic_test(self):
825+ """
826+ Test the parse options process works
827+
828+ """
829+ # GIVEN: a a set of system arguments.
830+ sys.argv[1:] = []
831+ # WHEN: We we parse them to expand to options
832+ args = parse_options()
833+ # THEN: the following fields will have been extracted.
834+ self.assertFalse(args.dev_version, 'The dev_version flag should be False')
835+ self.assertEquals(args.loglevel, 'warning', 'The log level should be set to warning')
836+ self.assertFalse(args.no_error_form, 'The no_error_form should be set to False')
837+ self.assertFalse(args.portable, 'The portable flag should be set to false')
838+ self.assertEquals(args.style, None, 'There are no style flags to be processed')
839+ self.assertEquals(args.rargs, [], 'The service file should be blank')
840+
841+ def parse_options_debug_test(self):
842+ """
843+ Test the parse options process works for debug only
844+
845+ """
846+ # GIVEN: a a set of system arguments.
847+ sys.argv[1:] = ['-l debug']
848+ # WHEN: We we parse them to expand to options
849+ args = parse_options()
850+ # THEN: the following fields will have been extracted.
851+ self.assertFalse(args.dev_version, 'The dev_version flag should be False')
852+ self.assertEquals(args.loglevel, ' debug', 'The log level should be set to debug')
853+ self.assertFalse(args.no_error_form, 'The no_error_form should be set to False')
854+ self.assertFalse(args.portable, 'The portable flag should be set to false')
855+ self.assertEquals(args.style, None, 'There are no style flags to be processed')
856+ self.assertEquals(args.rargs, [], 'The service file should be blank')
857+
858+ def parse_options_debug_and_portable_test(self):
859+ """
860+ Test the parse options process works for debug and portable
861+
862+ """
863+ # GIVEN: a a set of system arguments.
864+ sys.argv[1:] = ['--portable']
865+ # WHEN: We we parse them to expand to options
866+ args = parse_options()
867+ # THEN: the following fields will have been extracted.
868+ self.assertFalse(args.dev_version, 'The dev_version flag should be False')
869+ self.assertEquals(args.loglevel, 'warning', 'The log level should be set to warning')
870+ self.assertFalse(args.no_error_form, 'The no_error_form should be set to False')
871+ self.assertTrue(args.portable, 'The portable flag should be set to true')
872+ self.assertEquals(args.style, None, 'There are no style flags to be processed')
873+ self.assertEquals(args.rargs, [], 'The service file should be blank')
874+
875+ def parse_options_all_no_file_test(self):
876+ """
877+ Test the parse options process works with two options
878+
879+ """
880+ # GIVEN: a a set of system arguments.
881+ sys.argv[1:] = ['-l debug', '-d']
882+ # WHEN: We we parse them to expand to options
883+ args = parse_options()
884+ # THEN: the following fields will have been extracted.
885+ self.assertTrue(args.dev_version, 'The dev_version flag should be True')
886+ self.assertEquals(args.loglevel, ' debug', 'The log level should be set to debug')
887+ self.assertFalse(args.no_error_form, 'The no_error_form should be set to False')
888+ self.assertFalse(args.portable, 'The portable flag should be set to false')
889+ self.assertEquals(args.style, None, 'There are no style flags to be processed')
890+ self.assertEquals(args.rargs, [], 'The service file should be blank')
891+
892+ def parse_options_file_test(self):
893+ """
894+ Test the parse options process works with a file
895+
896+ """
897+ # GIVEN: a a set of system arguments.
898+ sys.argv[1:] = ['dummy_temp']
899+ # WHEN: We we parse them to expand to options
900+ args = parse_options()
901+ # THEN: the following fields will have been extracted.
902+ self.assertFalse(args.dev_version, 'The dev_version flag should be False')
903+ self.assertEquals(args.loglevel, 'warning', 'The log level should be set to warning')
904+ self.assertFalse(args.no_error_form, 'The no_error_form should be set to False')
905+ self.assertFalse(args.portable, 'The portable flag should be set to false')
906+ self.assertEquals(args.style, None, 'There are no style flags to be processed')
907+ self.assertEquals(args.rargs, 'dummy_temp', 'The service file should not be blank')
908+
909+ def parse_options_file_and_debug_test(self):
910+ """
911+ Test the parse options process works with a file
912+
913+ """
914+ # GIVEN: a a set of system arguments.
915+ sys.argv[1:] = ['-l debug', 'dummy_temp']
916+ # WHEN: We we parse them to expand to options
917+ args = parse_options()
918+ # THEN: the following fields will have been extracted.
919+ self.assertFalse(args.dev_version, 'The dev_version flag should be False')
920+ self.assertEquals(args.loglevel, ' debug', 'The log level should be set to debug')
921+ self.assertFalse(args.no_error_form, 'The no_error_form should be set to False')
922+ self.assertFalse(args.portable, 'The portable flag should be set to false')
923+ self.assertEquals(args.style, None, 'There are no style flags to be processed')
924+ self.assertEquals(args.rargs, 'dummy_temp', 'The service file should not be blank')
925+
926+ def parse_options_two_files_test(self):
927+ """
928+ Test the parse options process works with a file
929+
930+ """
931+ # GIVEN: a a set of system arguments.
932+ sys.argv[1:] = ['dummy_temp', 'dummy_temp2']
933+ # WHEN: We we parse them to expand to options
934+ args = parse_options()
935+ # THEN: the following fields will have been extracted.
936+ self.assertEquals(args, None, 'The args should be None')
937
938=== added file 'tests/functional/openlp_core_ui/test_advancedtab.py'
939--- tests/functional/openlp_core_ui/test_advancedtab.py 1970-01-01 00:00:00 +0000
940+++ tests/functional/openlp_core_ui/test_advancedtab.py 2015-10-28 21:21:37 +0000
941@@ -0,0 +1,69 @@
942+# -*- coding: utf-8 -*-
943+# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
944+
945+###############################################################################
946+# OpenLP - Open Source Lyrics Projection #
947+# --------------------------------------------------------------------------- #
948+# Copyright (c) 2008-2015 OpenLP Developers #
949+# --------------------------------------------------------------------------- #
950+# This program is free software; you can redistribute it and/or modify it #
951+# under the terms of the GNU General Public License as published by the Free #
952+# Software Foundation; version 2 of the License. #
953+# #
954+# This program is distributed in the hope that it will be useful, but WITHOUT #
955+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
956+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
957+# more details. #
958+# #
959+# You should have received a copy of the GNU General Public License along #
960+# with this program; if not, write to the Free Software Foundation, Inc., 59 #
961+# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
962+###############################################################################
963+"""
964+Package to test the openlp.core.ui.advancedtab package.
965+"""
966+from unittest import TestCase
967+
968+from openlp.core.common import Registry
969+from openlp.core.ui.advancedtab import AdvancedTab
970+from openlp.core.ui.settingsform import SettingsForm
971+
972+from tests.helpers.testmixin import TestMixin
973+
974+
975+class TestAdvancedTab(TestCase, TestMixin):
976+
977+ def setUp(self):
978+ """
979+ Set up a few things for the tests
980+ """
981+ Registry.create()
982+
983+ def test_creation(self):
984+ """
985+ Test that Advanced Tab is created.
986+ """
987+ # GIVEN: A new Advanced Tab
988+ settings_form = SettingsForm(None)
989+
990+ # WHEN: I create an advanced tab
991+ advanced_tab = AdvancedTab(settings_form)
992+
993+ # THEN:
994+ self.assertEqual("Advanced", advanced_tab.tab_title, 'The tab title should be Advanced')
995+
996+ def test_change_search_as_type(self):
997+ """
998+ Test that when search as type is changed custom and song configs are updated
999+ """
1000+ # GIVEN: A new Advanced Tab
1001+ settings_form = SettingsForm(None)
1002+ advanced_tab = AdvancedTab(settings_form)
1003+
1004+ # WHEN: I change search as type check box
1005+ advanced_tab.on_search_as_type_check_box_changed(True)
1006+
1007+ # THEN: we should have two post save processed to run
1008+ self.assertEqual(2, len(settings_form.processes), 'Two post save processes should be created')
1009+ self.assertTrue("songs_config_updated" in settings_form.processes, 'The songs plugin should be called')
1010+ self.assertTrue("custom_config_updated" in settings_form.processes, 'The custom plugin should be called')
1011
1012=== modified file 'tests/functional/openlp_core_ui/test_mainwindow.py'
1013--- tests/functional/openlp_core_ui/test_mainwindow.py 2015-01-30 21:15:03 +0000
1014+++ tests/functional/openlp_core_ui/test_mainwindow.py 2015-10-28 21:21:37 +0000
1015@@ -71,7 +71,7 @@
1016 with patch('openlp.core.ui.servicemanager.ServiceManager.load_file') as mocked_load_path:
1017
1018 # WHEN the argument is processed
1019- self.main_window.open_cmd_line_files()
1020+ self.main_window.open_cmd_line_files(service)
1021
1022 # THEN the service from the arguments is loaded
1023 mocked_load_path.assert_called_with(service), 'load_path should have been called with the service\'s path'
1024@@ -86,7 +86,7 @@
1025 with patch('openlp.core.ui.servicemanager.ServiceManager.load_file') as mocked_load_path:
1026
1027 # WHEN the argument is processed
1028- self.main_window.open_cmd_line_files()
1029+ self.main_window.open_cmd_line_files("")
1030
1031 # THEN the file should not be opened
1032 assert not mocked_load_path.called, 'load_path should not have been called'
1033
1034=== modified file 'tests/functional/openlp_core_utils/test_init.py'
1035--- tests/functional/openlp_core_utils/test_init.py 2015-01-19 08:34:29 +0000
1036+++ tests/functional/openlp_core_utils/test_init.py 2015-10-28 21:21:37 +0000
1037@@ -25,7 +25,7 @@
1038 from unittest import TestCase
1039
1040 from openlp.core.common.settings import Settings
1041-from openlp.core.utils import VersionThread, get_application_version, get_uno_command
1042+from openlp.core.utils import VersionThread, get_uno_command
1043 from tests.functional import MagicMock, patch
1044 from tests.helpers.testmixin import TestMixin
1045
1046
1047=== modified file 'tests/functional/test_init.py'
1048--- tests/functional/test_init.py 2015-04-25 19:29:39 +0000
1049+++ tests/functional/test_init.py 2015-10-28 21:21:37 +0000
1050@@ -33,7 +33,6 @@
1051 from tests.helpers.testmixin import TestMixin
1052 from tests.functional import MagicMock, patch, call
1053
1054-
1055 TEST_PATH = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'resources'))
1056
1057
1058@@ -132,60 +131,3 @@
1059 # THEN: It should ask if we want to create a backup
1060 self.assertEqual(Settings().value('core/application version'), '2.2.0', 'Version should be upgraded!')
1061 self.assertEqual(mocked_question.call_count, 1, 'A question should have been asked!')
1062-
1063- @patch(u'openlp.core.OptionParser')
1064- def parse_options_test(self, MockedOptionParser):
1065- """
1066- Test that parse_options sets up OptionParser correctly and parses the options given
1067- """
1068- # GIVEN: A list of valid options and a mocked out OptionParser object
1069- options = ['-e', '-l', 'debug', '-pd', '-s', 'style', 'extra', 'qt', 'args']
1070- mocked_parser = MagicMock()
1071- MockedOptionParser.return_value = mocked_parser
1072- expected_calls = [
1073- call('-e', '--no-error-form', dest='no_error_form', action='store_true',
1074- help='Disable the error notification form.'),
1075- call('-l', '--log-level', dest='loglevel', default='warning', metavar='LEVEL',
1076- help='Set logging to LEVEL level. Valid values are "debug", "info", "warning".'),
1077- call('-p', '--portable', dest='portable', action='store_true',
1078- help='Specify if this should be run as a portable app, off a USB flash drive (not implemented).'),
1079- call('-d', '--dev-version', dest='dev_version', action='store_true',
1080- help='Ignore the version file and pull the version directly from Bazaar'),
1081- call('-s', '--style', dest='style', help='Set the Qt4 style (passed directly to Qt4).')
1082- ]
1083-
1084- # WHEN: Calling parse_options
1085- parse_options(options)
1086-
1087- # THEN: A tuple should be returned with the parsed options and left over options
1088- MockedOptionParser.assert_called_with(usage='Usage: %prog [options] [qt-options]')
1089- self.assertEquals(expected_calls, mocked_parser.add_option.call_args_list)
1090- mocked_parser.parse_args.assert_called_with(options)
1091-
1092- @patch(u'openlp.core.OptionParser')
1093- def parse_options_from_sys_argv_test(self, MockedOptionParser):
1094- """
1095- Test that parse_options sets up OptionParser correctly and parses sys.argv
1096- """
1097- # GIVEN: A list of valid options and a mocked out OptionParser object
1098- mocked_parser = MagicMock()
1099- MockedOptionParser.return_value = mocked_parser
1100- expected_calls = [
1101- call('-e', '--no-error-form', dest='no_error_form', action='store_true',
1102- help='Disable the error notification form.'),
1103- call('-l', '--log-level', dest='loglevel', default='warning', metavar='LEVEL',
1104- help='Set logging to LEVEL level. Valid values are "debug", "info", "warning".'),
1105- call('-p', '--portable', dest='portable', action='store_true',
1106- help='Specify if this should be run as a portable app, off a USB flash drive (not implemented).'),
1107- call('-d', '--dev-version', dest='dev_version', action='store_true',
1108- help='Ignore the version file and pull the version directly from Bazaar'),
1109- call('-s', '--style', dest='style', help='Set the Qt4 style (passed directly to Qt4).')
1110- ]
1111-
1112- # WHEN: Calling parse_options
1113- parse_options([])
1114-
1115- # THEN: A tuple should be returned with the parsed options and left over options
1116- MockedOptionParser.assert_called_with(usage='Usage: %prog [options] [qt-options]')
1117- self.assertEquals(expected_calls, mocked_parser.add_option.call_args_list)
1118- mocked_parser.parse_args.assert_called_with()
1119
1120=== modified file 'tests/utils/test_bzr_tags.py'
1121--- tests/utils/test_bzr_tags.py 2015-10-17 11:18:23 +0000
1122+++ tests/utils/test_bzr_tags.py 2015-10-28 21:21:37 +0000
1123@@ -23,39 +23,13 @@
1124 Package to test for proper bzr tags.
1125 """
1126 import os
1127-import re
1128 from unittest import TestCase
1129
1130 from subprocess import Popen, PIPE
1131
1132-TAGS = [
1133- ['1.9.0', '1'],
1134- ['1.9.1', '775'],
1135- ['1.9.2', '890'],
1136- ['1.9.3', '1063'],
1137- ['1.9.4', '1196'],
1138- ['1.9.5', '1421'],
1139- ['1.9.6', '1657'],
1140- ['1.9.7', '1761'],
1141- ['1.9.8', '1856'],
1142- ['1.9.9', '1917'],
1143- ['1.9.10', '2003'],
1144- ['1.9.11', '2039'],
1145- ['1.9.12', '2063'],
1146- ['2.0', '2118'],
1147- ['2.1.0', '2119'],
1148- ['2.1.1', '2438'],
1149- ['2.1.2', '2488'],
1150- ['2.1.3', '2513'],
1151- ['2.1.4', '2532'],
1152- ['2.1.5', '2543'],
1153- ['2.1.6', '2550'],
1154- ['2.2', '2562']
1155-]
1156-# Depending on the repository, we sometimes have the 2.0.x tags in the repo too. They come up with a revision number of
1157-# "?", which I suspect is due to the fact that we're using shared repositories. This regular expression matches all
1158-# 2.0.x tags.
1159-TAG_SEARCH = re.compile('2\.0\.\d')
1160+TAGS1 = {'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',
1161+ '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'
1162+ }
1163
1164
1165 class TestBzrTags(TestCase):
1166@@ -70,8 +44,12 @@
1167 # WHEN getting the branches tags
1168 bzr = Popen(('bzr', 'tags', '--directory=' + path), stdout=PIPE)
1169 std_out = bzr.communicate()[0]
1170- tags = [line.decode('utf-8').split() for line in std_out.splitlines()]
1171- tags = [t_r for t_r in tags if t_r[1] != '?' or not (t_r[1] == '?' and TAG_SEARCH.search(t_r[0]))]
1172+ count = len(TAGS1)
1173+ tags = [line.decode('utf-8').split()[0] for line in std_out.splitlines()]
1174+ count1 = 0
1175+ for t in tags:
1176+ if t in TAGS1:
1177+ count1 += 1
1178
1179 # THEN the tags should match the accepted tags
1180- self.assertEqual(TAGS, tags, 'List of tags should match')
1181+ self.assertEqual(count, count1, 'List of tags should match')