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

Proposed by Tim Bentley on 2015-10-18
Status: Superseded
Proposed branch: lp:~trb143/openlp/bugs-2_4b
Merge into: lp:openlp
Diff against target: 1204 lines (+347/-304)
31 files modified
openlp/core/__init__.py (+28/-23)
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
OpenLP Core 2015-10-18 Pending
Review via email: mp+274826@code.launchpad.net

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

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 :

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/

lp:~trb143/openlp/bugs-2_4b updated on 2015-11-04
2577. By Tim Bentley on 2015-10-22

Missing strings

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