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

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

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

Description of the change

First merge for 2.4.

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

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

To post a comment you must log in.
Revision history for this message
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/

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

Minor "nitpicking"

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

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-11-04 18:37:45 +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-11-04 18:37:45 +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-11-04 18:37:45 +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-11-04 18:37:45 +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-11-04 18:37:45 +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-11-04 18:37:45 +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.is_search_as_you_type_enabled = settings.value('search as type')
245+ self.search_as_type_check_box.setChecked(self.is_search_as_you_type_enabled)
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.is_search_as_you_type_enabled)
254 settings.endGroup()
255
256+ def on_search_as_type_check_box_changed(self, check_state):
257+ self.is_search_as_you_type_enabled = (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-11-04 18:37:45 +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-11-04 18:37:45 +0000
350@@ -33,21 +33,21 @@
351 """
352 The UI of the plugin view dialog
353 """
354- def setupUi(self, pluginViewDialog):
355+ def setupUi(self, plugin_view_dialog):
356 """
357 Set up the UI
358 """
359- pluginViewDialog.setObjectName('pluginViewDialog')
360- pluginViewDialog.setWindowIcon(build_icon(u':/icon/openlp-logo.svg'))
361- pluginViewDialog.setWindowModality(QtCore.Qt.ApplicationModal)
362- self.plugin_layout = QtGui.QVBoxLayout(pluginViewDialog)
363+ plugin_view_dialog.setObjectName('plugin_view_dialog')
364+ plugin_view_dialog.setWindowIcon(build_icon(u':/icon/openlp-logo.svg'))
365+ plugin_view_dialog.setWindowModality(QtCore.Qt.ApplicationModal)
366+ self.plugin_layout = QtGui.QVBoxLayout(plugin_view_dialog)
367 self.plugin_layout.setObjectName('plugin_layout')
368 self.list_layout = QtGui.QHBoxLayout()
369 self.list_layout.setObjectName('list_layout')
370- self.plugin_list_widget = QtGui.QListWidget(pluginViewDialog)
371+ self.plugin_list_widget = QtGui.QListWidget(plugin_view_dialog)
372 self.plugin_list_widget.setObjectName('plugin_list_widget')
373 self.list_layout.addWidget(self.plugin_list_widget)
374- self.plugin_info_group_box = QtGui.QGroupBox(pluginViewDialog)
375+ self.plugin_info_group_box = QtGui.QGroupBox(plugin_view_dialog)
376 self.plugin_info_group_box.setObjectName('plugin_info_group_box')
377 self.plugin_info_layout = QtGui.QFormLayout(self.plugin_info_group_box)
378 self.plugin_info_layout.setObjectName('plugin_info_layout')
379@@ -70,15 +70,15 @@
380 self.plugin_info_layout.addRow(self.about_label, self.about_text_browser)
381 self.list_layout.addWidget(self.plugin_info_group_box)
382 self.plugin_layout.addLayout(self.list_layout)
383- self.button_box = create_button_box(pluginViewDialog, 'button_box', ['ok'])
384+ self.button_box = create_button_box(plugin_view_dialog, 'button_box', ['ok'])
385 self.plugin_layout.addWidget(self.button_box)
386- self.retranslateUi(pluginViewDialog)
387+ self.retranslateUi(plugin_view_dialog)
388
389- def retranslateUi(self, pluginViewDialog):
390+ def retranslateUi(self, plugin_view_dialog):
391 """
392 Translate the UI on the fly
393 """
394- pluginViewDialog.setWindowTitle(translate('OpenLP.PluginForm', 'Plugin List'))
395+ plugin_view_dialog.setWindowTitle(translate('OpenLP.PluginForm', 'Manage Plugins'))
396 self.plugin_info_group_box.setTitle(translate('OpenLP.PluginForm', 'Plugin Details'))
397 self.version_label.setText('%s:' % UiStrings().Version)
398 self.about_label.setText('%s:' % UiStrings().About)
399
400=== modified file 'openlp/core/ui/printserviceform.py'
401--- openlp/core/ui/printserviceform.py 2015-04-11 22:13:30 +0000
402+++ openlp/core/ui/printserviceform.py 2015-11-04 18:37:45 +0000
403@@ -162,7 +162,7 @@
404 html_data = self._add_element('html')
405 self._add_element('head', parent=html_data)
406 self._add_element('title', self.title_line_edit.text(), html_data.head)
407- css_path = os.path.join(AppLocation.get_data_path(), 'service_print.css')
408+ css_path = os.path.join(AppLocation.get_data_path(), 'serviceprint', 'service_print.css')
409 custom_css = get_text_file_string(css_path)
410 if not custom_css:
411 custom_css = DEFAULT_CSS
412
413=== modified file 'openlp/core/ui/thememanager.py'
414--- openlp/core/ui/thememanager.py 2015-09-08 19:13:59 +0000
415+++ openlp/core/ui/thememanager.py 2015-11-04 18:37:45 +0000
416@@ -755,12 +755,19 @@
417 return False
418 # check for use in the system else where.
419 if test_plugin:
420+ plugin_usage = ""
421 for plugin in self.plugin_manager.plugins:
422- if plugin.uses_theme(theme):
423- critical_error_message_box(translate('OpenLP.ThemeManager', 'Validation Error'),
424- translate('OpenLP.ThemeManager',
425- 'Theme %s is used in the %s plugin.')
426- % (theme, plugin.name))
427- return False
428+ used_count = plugin.uses_theme(theme)
429+ if used_count:
430+ plugin_usage = "%s%s" % (plugin_usage, (translate('OpenLP.ThemeManager',
431+ '%s time(s) by %s') %
432+ (used_count, plugin.name)))
433+ plugin_usage = "%s\n" % plugin_usage
434+ if plugin_usage:
435+ critical_error_message_box(translate('OpenLP.ThemeManager', 'Unable to delete theme'),
436+ translate('OpenLP.ThemeManager', 'Theme is currently used \n\n%s') %
437+ plugin_usage)
438+
439+ return False
440 return True
441 return False
442
443=== modified file 'openlp/plugins/bibles/bibleplugin.py'
444--- openlp/plugins/bibles/bibleplugin.py 2015-03-10 21:33:35 +0000
445+++ openlp/plugins/bibles/bibleplugin.py 2015-11-04 18:37:45 +0000
446@@ -178,12 +178,14 @@
447
448 def uses_theme(self, theme):
449 """
450- Called to find out if the bible plugin is currently using a theme. Returns ``True`` if the theme is being used,
451- otherwise returns ``False``.
452+ Called to find out if the bible plugin is currently using a theme. Returns ``1`` if the theme is being used,
453+ otherwise returns ``0``.
454
455 :param theme: The theme
456 """
457- return str(self.settings_tab.bible_theme) == theme
458+ if str(self.settings_tab.bible_theme) == theme:
459+ return 1
460+ return 0
461
462 def rename_theme(self, old_theme, new_theme):
463 """
464
465=== modified file 'openlp/plugins/bibles/lib/db.py'
466--- openlp/plugins/bibles/lib/db.py 2015-09-08 19:13:26 +0000
467+++ openlp/plugins/bibles/lib/db.py 2015-11-04 18:37:45 +0000
468@@ -476,16 +476,6 @@
469 self.save_meta('language_id', language_id)
470 return language_id
471
472- def is_old_database(self):
473- """
474- Returns ``True`` if it is a bible database, which has been created prior to 1.9.6.
475- """
476- try:
477- self.session.query(Book).all()
478- except:
479- return True
480- return False
481-
482 def dump_bible(self):
483 """
484 Utility debugging method to dump the contents of a bible.
485
486=== modified file 'openlp/plugins/bibles/lib/manager.py'
487--- openlp/plugins/bibles/lib/manager.py 2015-01-31 21:52:02 +0000
488+++ openlp/plugins/bibles/lib/manager.py 2015-11-04 18:37:45 +0000
489@@ -129,11 +129,6 @@
490 bible.session.close()
491 delete_file(os.path.join(self.path, filename))
492 continue
493- # Find old database versions.
494- if bible.is_old_database():
495- self.old_bible_databases.append([filename, name])
496- bible.session.close()
497- continue
498 log.debug('Bible Name: "%s"', name)
499 self.db_cache[name] = bible
500 # Look to see if lazy load bible exists and get create getter.
501
502=== modified file 'openlp/plugins/custom/customplugin.py'
503--- openlp/plugins/custom/customplugin.py 2015-02-11 20:56:13 +0000
504+++ openlp/plugins/custom/customplugin.py 2015-11-04 18:37:45 +0000
505@@ -72,11 +72,9 @@
506 """
507 Called to find out if the custom plugin is currently using a theme.
508
509- Returns True if the theme is being used, otherwise returns False.
510+ Returns count of the times the theme is used.
511 """
512- if self.db_manager.get_all_objects(CustomSlide, CustomSlide.theme_name == theme):
513- return True
514- return False
515+ return len(self.db_manager.get_all_objects(CustomSlide, CustomSlide.theme_name == theme))
516
517 def rename_theme(self, old_theme, new_theme):
518 """
519
520=== modified file 'openlp/plugins/custom/lib/mediaitem.py'
521--- openlp/plugins/custom/lib/mediaitem.py 2015-04-02 20:49:19 +0000
522+++ openlp/plugins/custom/lib/mediaitem.py 2015-11-04 18:37:45 +0000
523@@ -85,6 +85,7 @@
524 """
525 log.debug('Config loaded')
526 self.add_custom_from_service = Settings().value(self.settings_section + '/add custom from service')
527+ self.is_search_as_you_type_enabled = Settings().value('advanced/search as type')
528
529 def retranslateUi(self):
530 """
531@@ -269,11 +270,12 @@
532
533 :param text: The search text
534 """
535- search_length = 2
536- if len(text) > search_length:
537- self.on_search_text_button_clicked()
538- elif not text:
539- self.on_clear_text_button_click()
540+ if self.is_search_as_you_type_enabled:
541+ search_length = 2
542+ if len(text) > search_length:
543+ self.on_search_text_button_clicked()
544+ elif not text:
545+ self.on_clear_text_button_click()
546
547 def service_load(self, item):
548 """
549
550=== modified file 'openlp/plugins/images/imageplugin.py'
551--- openlp/plugins/images/imageplugin.py 2015-02-11 22:15:46 +0000
552+++ openlp/plugins/images/imageplugin.py 2015-11-04 18:37:45 +0000
553@@ -67,36 +67,13 @@
554 'provided by the theme.')
555 return about_text
556
557- def app_startup(self):
558- """
559- Perform tasks on application startup.
560- """
561- # TODO: Can be removed when the upgrade path from 2.0.x to 2.2.x is no longer needed
562- Plugin.app_startup(self)
563- # Convert old settings-based image list to the database.
564- files_from_config = Settings().get_files_from_config(self)
565- if files_from_config:
566- for file in files_from_config:
567- filename = os.path.split(file)[1]
568- thumb = os.path.join(self.media_item.service_path, filename)
569- try:
570- os.remove(thumb)
571- except:
572- pass
573- log.debug('Importing images list from old config: %s' % files_from_config)
574- self.media_item.save_new_images_list(files_from_config)
575-
576 def upgrade_settings(self, settings):
577 """
578 Upgrade the settings of this plugin.
579
580 :param settings: The Settings object containing the old settings.
581 """
582- # TODO: Can be removed when the upgrade path from 2.0.x to 2.2.x is no longer needed
583- files_from_config = settings.get_files_from_config(self)
584- if files_from_config:
585- log.debug('Importing images list from old config: %s' % files_from_config)
586- self.media_item.save_new_images_list(files_from_config)
587+ pass
588
589 def set_plugin_text_strings(self):
590 """
591
592=== modified file 'openlp/plugins/images/lib/mediaitem.py'
593--- openlp/plugins/images/lib/mediaitem.py 2015-09-08 19:13:59 +0000
594+++ openlp/plugins/images/lib/mediaitem.py 2015-11-04 18:37:45 +0000
595@@ -119,14 +119,6 @@
596 icon=':/general/general_edit.png',
597 triggers=self.on_edit_click)
598 create_widget_action(self.list_view, separator=True)
599- if self.has_delete_icon:
600- create_widget_action(
601- self.list_view,
602- 'listView%s%sItem' % (self.plugin.name.title(), StringContent.Delete.title()),
603- text=self.plugin.get_string(StringContent.Delete)['title'],
604- icon=':/general/general_delete.png',
605- can_shortcuts=True, triggers=self.on_delete_click)
606- create_widget_action(self.list_view, separator=True)
607 create_widget_action(
608 self.list_view,
609 'listView%s%sItem' % (self.plugin.name.title(), StringContent.Preview.title()),
610@@ -155,6 +147,14 @@
611 text=translate('OpenLP.MediaManagerItem', '&Add to selected Service Item'),
612 icon=':/general/general_add.png',
613 triggers=self.on_add_edit_click)
614+ create_widget_action(self.list_view, separator=True)
615+ if self.has_delete_icon:
616+ create_widget_action(
617+ self.list_view,
618+ 'listView%s%sItem' % (self.plugin.name.title(), StringContent.Delete.title()),
619+ text=self.plugin.get_string(StringContent.Delete)['title'],
620+ icon=':/general/general_delete.png',
621+ can_shortcuts=True, triggers=self.on_delete_click)
622 self.add_custom_context_actions()
623 # Create the context menu and add all actions from the list_view.
624 self.menu = QtGui.QMenu()
625
626=== modified file 'openlp/plugins/presentations/presentationplugin.py'
627--- openlp/plugins/presentations/presentationplugin.py 2015-05-26 21:26:59 +0000
628+++ openlp/plugins/presentations/presentationplugin.py 2015-11-04 18:37:45 +0000
629@@ -137,22 +137,6 @@
630 self.register_controllers(controller)
631 return bool(self.controllers)
632
633- def app_startup(self):
634- """
635- Perform tasks on application startup.
636- """
637- # TODO: Can be removed when the upgrade path from 2.0.x to 2.2.x is no longer needed
638- super().app_startup()
639- files_from_config = Settings().value('presentations/presentations files')
640- for file in files_from_config:
641- try:
642- self.media_item.clean_up_thumbnails(file, True)
643- except AttributeError:
644- pass
645- self.media_item.list_view.clear()
646- Settings().setValue('presentations/thumbnail_scheme', 'md5')
647- self.media_item.validate_and_load(files_from_config)
648-
649 def about(self):
650 """
651 Return information about this plugin.
652
653=== modified file 'openlp/plugins/remotes/html/openlp.js'
654--- openlp/plugins/remotes/html/openlp.js 2015-01-18 13:39:21 +0000
655+++ openlp/plugins/remotes/html/openlp.js 2015-11-04 18:37:45 +0000
656@@ -271,9 +271,15 @@
657 if (typeof value[0] !== "number"){
658 value[0] = OpenLP.escapeString(value[0])
659 }
660+ var txt = "";
661+ if (value[2].length > 0) {
662+ txt = value[1] + " ( " + value[2] + " )";
663+ } else {
664+ txt = value[1];
665+ }
666 ul.append($("<li>").append($("<a>").attr("href", "#options")
667 .attr("data-rel", "dialog").attr("value", value[0])
668- .click(OpenLP.showOptions).text(value[1])));
669+ .click(OpenLP.showOptions).text(txt)));
670 });
671 }
672 ul.listview("refresh");
673
674=== modified file 'openlp/plugins/remotes/lib/httprouter.py'
675--- openlp/plugins/remotes/lib/httprouter.py 2015-02-14 09:12:35 +0000
676+++ openlp/plugins/remotes/lib/httprouter.py 2015-11-04 18:37:45 +0000
677@@ -309,10 +309,13 @@
678 """
679 Translate various strings in the mobile app.
680 """
681+ remote = translate('RemotePlugin.Mobile', 'Remote')
682+ stage = translate('RemotePlugin.Mobile', 'Stage View')
683+ live = translate('RemotePlugin.Mobile', 'Live View')
684 self.template_vars = {
685- 'app_title': translate('RemotePlugin.Mobile', 'OpenLP 2.2 Remote'),
686- 'stage_title': translate('RemotePlugin.Mobile', 'OpenLP 2.2 Stage View'),
687- 'live_title': translate('RemotePlugin.Mobile', 'OpenLP 2.2 Live View'),
688+ 'app_title': "%s %s" % (UiStrings().OLPV2x, remote),
689+ 'stage_title': "%s %s" % (UiStrings().OLPV2x, stage),
690+ 'live_title': "%s %s" % (UiStrings().OLPV2x, live),
691 'service_manager': translate('RemotePlugin.Mobile', 'Service Manager'),
692 'slide_controller': translate('RemotePlugin.Mobile', 'Slide Controller'),
693 'alerts': translate('RemotePlugin.Mobile', 'Alerts'),
694
695=== modified file 'openlp/plugins/songs/forms/editsongform.py'
696--- openlp/plugins/songs/forms/editsongform.py 2015-01-18 13:39:21 +0000
697+++ openlp/plugins/songs/forms/editsongform.py 2015-11-04 18:37:45 +0000
698@@ -178,7 +178,7 @@
699 if invalid_verses:
700 valid = create_separated_list(verse_names)
701 if len(invalid_verses) > 1:
702- msg = translate('SongsPlugin.EditSongForm', 'There are no verses corresponding to "%(invalid)s".'
703+ msg = translate('SongsPlugin.EditSongForm', 'There are no verses corresponding to "%(invalid)s". '
704 'Valid entries are %(valid)s.\nPlease enter the verses separated by spaces.') % \
705 {'invalid': ', '.join(invalid_verses), 'valid': valid}
706 else:
707
708=== modified file 'openlp/plugins/songs/lib/mediaitem.py'
709--- openlp/plugins/songs/lib/mediaitem.py 2015-01-18 13:39:21 +0000
710+++ openlp/plugins/songs/lib/mediaitem.py 2015-11-04 18:37:45 +0000
711@@ -115,7 +115,7 @@
712 Is triggered when the songs config is updated
713 """
714 log.debug('config_updated')
715- self.search_as_you_type = Settings().value(self.settings_section + '/search as type')
716+ self.is_search_as_you_type_enabled = Settings().value('advanced/search as type')
717 self.update_service_on_edit = Settings().value(self.settings_section + '/update service on edit')
718 self.add_song_from_service = Settings().value(self.settings_section + '/add song from service')
719 self.display_songbook = Settings().value(self.settings_section + '/display songbook')
720@@ -279,7 +279,7 @@
721 If search as type enabled invoke the search on each key press. If the Lyrics are being searched do not start
722 till 7 characters have been entered.
723 """
724- if self.search_as_you_type:
725+ if self.is_search_as_you_type_enabled:
726 search_length = 1
727 if self.search_text_edit.current_search_type() == SongSearch.Entire:
728 search_length = 4
729@@ -590,4 +590,4 @@
730 :param show_error: Is this an error?
731 """
732 search_results = self.search_entire(string)
733- return [[song.id, song.title] for song in search_results]
734+ return [[song.id, song.title, song.alternate_title] for song in search_results]
735
736=== modified file 'openlp/plugins/songs/lib/openlyricsxml.py'
737--- openlp/plugins/songs/lib/openlyricsxml.py 2015-09-08 19:13:59 +0000
738+++ openlp/plugins/songs/lib/openlyricsxml.py 2015-11-04 18:37:45 +0000
739@@ -121,17 +121,7 @@
740 """
741 self.song_xml = None
742 verse_list = []
743- if not xml.startswith('<?xml') and not xml.startswith('<song'):
744- # This is an old style song, without XML. Let's handle it correctly by iterating through the verses, and
745- # then recreating the internal xml object as well.
746- self.song_xml = objectify.fromstring('<song version="1.0" />')
747- self.lyrics = etree.SubElement(self.song_xml, 'lyrics')
748- verses = xml.split('\n\n')
749- for count, verse in enumerate(verses):
750- verse_list.append([{'type': 'v', 'label': str(count)}, str(verse)])
751- self.add_verse_to_lyrics('v', str(count), verse)
752- return verse_list
753- elif xml.startswith('<?xml'):
754+ if xml.startswith('<?xml'):
755 xml = xml[38:]
756 try:
757 self.song_xml = objectify.fromstring(xml)
758
759=== modified file 'openlp/plugins/songs/lib/songstab.py'
760--- openlp/plugins/songs/lib/songstab.py 2015-10-10 20:50:59 +0000
761+++ openlp/plugins/songs/lib/songstab.py 2015-11-04 18:37:45 +0000
762@@ -41,9 +41,6 @@
763 self.mode_group_box.setObjectName('mode_group_box')
764 self.mode_layout = QtGui.QVBoxLayout(self.mode_group_box)
765 self.mode_layout.setObjectName('mode_layout')
766- self.search_as_type_check_box = QtGui.QCheckBox(self.mode_group_box)
767- self.search_as_type_check_box.setObjectName('SearchAsType_check_box')
768- self.mode_layout.addWidget(self.search_as_type_check_box)
769 self.tool_bar_active_check_box = QtGui.QCheckBox(self.mode_group_box)
770 self.tool_bar_active_check_box.setObjectName('tool_bar_active_check_box')
771 self.mode_layout.addWidget(self.tool_bar_active_check_box)
772@@ -62,7 +59,6 @@
773 self.left_layout.addWidget(self.mode_group_box)
774 self.left_layout.addStretch()
775 self.right_layout.addStretch()
776- self.search_as_type_check_box.stateChanged.connect(self.on_search_as_type_check_box_changed)
777 self.tool_bar_active_check_box.stateChanged.connect(self.on_tool_bar_active_check_box_changed)
778 self.update_on_edit_check_box.stateChanged.connect(self.on_update_on_edit_check_box_changed)
779 self.add_from_service_check_box.stateChanged.connect(self.on_add_from_service_check_box_changed)
780@@ -71,7 +67,6 @@
781
782 def retranslateUi(self):
783 self.mode_group_box.setTitle(translate('SongsPlugin.SongsTab', 'Songs Mode'))
784- self.search_as_type_check_box.setText(translate('SongsPlugin.SongsTab', 'Enable search as you type'))
785 self.tool_bar_active_check_box.setText(translate('SongsPlugin.SongsTab',
786 'Display verses on live tool bar'))
787 self.update_on_edit_check_box.setText(translate('SongsPlugin.SongsTab', 'Update service from song edit'))
788@@ -103,13 +98,11 @@
789 def load(self):
790 settings = Settings()
791 settings.beginGroup(self.settings_section)
792- self.song_search = settings.value('search as type')
793 self.tool_bar = settings.value('display songbar')
794 self.update_edit = settings.value('update service on edit')
795 self.update_load = settings.value('add song from service')
796 self.display_songbook = settings.value('display songbook')
797 self.display_copyright_symbol = settings.value('display copyright symbol')
798- self.search_as_type_check_box.setChecked(self.song_search)
799 self.tool_bar_active_check_box.setChecked(self.tool_bar)
800 self.update_on_edit_check_box.setChecked(self.update_edit)
801 self.add_from_service_check_box.setChecked(self.update_load)
802@@ -120,7 +113,6 @@
803 def save(self):
804 settings = Settings()
805 settings.beginGroup(self.settings_section)
806- settings.setValue('search as type', self.song_search)
807 settings.setValue('display songbar', self.tool_bar)
808 settings.setValue('update service on edit', self.update_edit)
809 settings.setValue('add song from service', self.update_load)
810
811=== modified file 'openlp/plugins/songs/songsplugin.py'
812--- openlp/plugins/songs/songsplugin.py 2015-02-11 20:56:13 +0000
813+++ openlp/plugins/songs/songsplugin.py 2015-11-04 18:37:45 +0000
814@@ -57,7 +57,6 @@
815 'songs/last search type': SongSearch.Entire,
816 'songs/last import type': SongFormat.OpenLyrics,
817 'songs/update service on edit': False,
818- 'songs/search as type': True,
819 'songs/add song from service': True,
820 'songs/display songbar': True,
821 'songs/display songbook': False,
822@@ -226,11 +225,9 @@
823 Called to find out if the song plugin is currently using a theme.
824
825 :param theme: The theme to check for usage
826- :return: True if the theme is being used, otherwise returns False
827+ :return: count of the number of times the theme is used.
828 """
829- if self.manager.get_all_objects(Song, Song.theme_name == theme):
830- return True
831- return False
832+ return len(self.manager.get_all_objects(Song, Song.theme_name == theme))
833
834 def rename_theme(self, old_theme, new_theme):
835 """
836
837=== added directory 'tests/functional/openlp_core'
838=== added file 'tests/functional/openlp_core/test_init.py'
839--- tests/functional/openlp_core/test_init.py 1970-01-01 00:00:00 +0000
840+++ tests/functional/openlp_core/test_init.py 2015-11-04 18:37:45 +0000
841@@ -0,0 +1,144 @@
842+# -*- coding: utf-8 -*-
843+# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
844+
845+###############################################################################
846+# OpenLP - Open Source Lyrics Projection #
847+# --------------------------------------------------------------------------- #
848+# Copyright (c) 2008-2015 OpenLP Developers #
849+# --------------------------------------------------------------------------- #
850+# This program is free software; you can redistribute it and/or modify it #
851+# under the terms of the GNU General Public License as published by the Free #
852+# Software Foundation; version 2 of the License. #
853+# #
854+# This program is distributed in the hope that it will be useful, but WITHOUT #
855+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
856+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
857+# more details. #
858+# #
859+# You should have received a copy of the GNU General Public License along #
860+# with this program; if not, write to the Free Software Foundation, Inc., 59 #
861+# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
862+###############################################################################
863+
864+import sys
865+from unittest import TestCase
866+
867+from openlp.core import parse_options
868+from tests.helpers.testmixin import TestMixin
869+
870+
871+class TestInitFunctions(TestMixin, TestCase):
872+
873+ def parse_options_basic_test(self):
874+ """
875+ Test the parse options process works
876+
877+ """
878+ # GIVEN: a a set of system arguments.
879+ sys.argv[1:] = []
880+ # WHEN: We we parse them to expand to options
881+ args = parse_options()
882+ # THEN: the following fields will have been extracted.
883+ self.assertFalse(args.dev_version, 'The dev_version flag should be False')
884+ self.assertEquals(args.loglevel, 'warning', 'The log level should be set to warning')
885+ self.assertFalse(args.no_error_form, 'The no_error_form should be set to False')
886+ self.assertFalse(args.portable, 'The portable flag should be set to false')
887+ self.assertEquals(args.style, None, 'There are no style flags to be processed')
888+ self.assertEquals(args.rargs, [], 'The service file should be blank')
889+
890+ def parse_options_debug_test(self):
891+ """
892+ Test the parse options process works for debug only
893+
894+ """
895+ # GIVEN: a a set of system arguments.
896+ sys.argv[1:] = ['-l debug']
897+ # WHEN: We we parse them to expand to options
898+ args = parse_options()
899+ # THEN: the following fields will have been extracted.
900+ self.assertFalse(args.dev_version, 'The dev_version flag should be False')
901+ self.assertEquals(args.loglevel, ' debug', 'The log level should be set to debug')
902+ self.assertFalse(args.no_error_form, 'The no_error_form should be set to False')
903+ self.assertFalse(args.portable, 'The portable flag should be set to false')
904+ self.assertEquals(args.style, None, 'There are no style flags to be processed')
905+ self.assertEquals(args.rargs, [], 'The service file should be blank')
906+
907+ def parse_options_debug_and_portable_test(self):
908+ """
909+ Test the parse options process works for debug and portable
910+
911+ """
912+ # GIVEN: a a set of system arguments.
913+ sys.argv[1:] = ['--portable']
914+ # WHEN: We we parse them to expand to options
915+ args = parse_options()
916+ # THEN: the following fields will have been extracted.
917+ self.assertFalse(args.dev_version, 'The dev_version flag should be False')
918+ self.assertEquals(args.loglevel, 'warning', 'The log level should be set to warning')
919+ self.assertFalse(args.no_error_form, 'The no_error_form should be set to False')
920+ self.assertTrue(args.portable, 'The portable flag should be set to true')
921+ self.assertEquals(args.style, None, 'There are no style flags to be processed')
922+ self.assertEquals(args.rargs, [], 'The service file should be blank')
923+
924+ def parse_options_all_no_file_test(self):
925+ """
926+ Test the parse options process works with two options
927+
928+ """
929+ # GIVEN: a a set of system arguments.
930+ sys.argv[1:] = ['-l debug', '-d']
931+ # WHEN: We we parse them to expand to options
932+ args = parse_options()
933+ # THEN: the following fields will have been extracted.
934+ self.assertTrue(args.dev_version, 'The dev_version flag should be True')
935+ self.assertEquals(args.loglevel, ' debug', 'The log level should be set to debug')
936+ self.assertFalse(args.no_error_form, 'The no_error_form should be set to False')
937+ self.assertFalse(args.portable, 'The portable flag should be set to false')
938+ self.assertEquals(args.style, None, 'There are no style flags to be processed')
939+ self.assertEquals(args.rargs, [], 'The service file should be blank')
940+
941+ def parse_options_file_test(self):
942+ """
943+ Test the parse options process works with a file
944+
945+ """
946+ # GIVEN: a a set of system arguments.
947+ sys.argv[1:] = ['dummy_temp']
948+ # WHEN: We we parse them to expand to options
949+ args = parse_options()
950+ # THEN: the following fields will have been extracted.
951+ self.assertFalse(args.dev_version, 'The dev_version flag should be False')
952+ self.assertEquals(args.loglevel, 'warning', 'The log level should be set to warning')
953+ self.assertFalse(args.no_error_form, 'The no_error_form should be set to False')
954+ self.assertFalse(args.portable, 'The portable flag should be set to false')
955+ self.assertEquals(args.style, None, 'There are no style flags to be processed')
956+ self.assertEquals(args.rargs, 'dummy_temp', 'The service file should not be blank')
957+
958+ def parse_options_file_and_debug_test(self):
959+ """
960+ Test the parse options process works with a file
961+
962+ """
963+ # GIVEN: a a set of system arguments.
964+ sys.argv[1:] = ['-l debug', 'dummy_temp']
965+ # WHEN: We we parse them to expand to options
966+ args = parse_options()
967+ # THEN: the following fields will have been extracted.
968+ self.assertFalse(args.dev_version, 'The dev_version flag should be False')
969+ self.assertEquals(args.loglevel, ' debug', 'The log level should be set to debug')
970+ self.assertFalse(args.no_error_form, 'The no_error_form should be set to False')
971+ self.assertFalse(args.portable, 'The portable flag should be set to false')
972+ self.assertEquals(args.style, None, 'There are no style flags to be processed')
973+ self.assertEquals(args.rargs, 'dummy_temp', 'The service file should not be blank')
974+
975+ def parse_options_two_files_test(self):
976+ """
977+ Test the parse options process works with a file
978+
979+ """
980+ # GIVEN: a a set of system arguments.
981+ sys.argv[1:] = ['dummy_temp', 'dummy_temp2']
982+ # WHEN: We we parse them to expand to options
983+ args = parse_options()
984+ # THEN: the following fields will have been extracted.
985+ self.assertEquals(args, None, 'The args should be None')
986
987=== added file 'tests/functional/openlp_core_ui/test_advancedtab.py'
988--- tests/functional/openlp_core_ui/test_advancedtab.py 1970-01-01 00:00:00 +0000
989+++ tests/functional/openlp_core_ui/test_advancedtab.py 2015-11-04 18:37:45 +0000
990@@ -0,0 +1,69 @@
991+# -*- coding: utf-8 -*-
992+# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
993+
994+###############################################################################
995+# OpenLP - Open Source Lyrics Projection #
996+# --------------------------------------------------------------------------- #
997+# Copyright (c) 2008-2015 OpenLP Developers #
998+# --------------------------------------------------------------------------- #
999+# This program is free software; you can redistribute it and/or modify it #
1000+# under the terms of the GNU General Public License as published by the Free #
1001+# Software Foundation; version 2 of the License. #
1002+# #
1003+# This program is distributed in the hope that it will be useful, but WITHOUT #
1004+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
1005+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
1006+# more details. #
1007+# #
1008+# You should have received a copy of the GNU General Public License along #
1009+# with this program; if not, write to the Free Software Foundation, Inc., 59 #
1010+# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
1011+###############################################################################
1012+"""
1013+Package to test the openlp.core.ui.advancedtab package.
1014+"""
1015+from unittest import TestCase
1016+
1017+from openlp.core.common import Registry
1018+from openlp.core.ui.advancedtab import AdvancedTab
1019+from openlp.core.ui.settingsform import SettingsForm
1020+
1021+from tests.helpers.testmixin import TestMixin
1022+
1023+
1024+class TestAdvancedTab(TestCase, TestMixin):
1025+
1026+ def setUp(self):
1027+ """
1028+ Set up a few things for the tests
1029+ """
1030+ Registry.create()
1031+
1032+ def test_creation(self):
1033+ """
1034+ Test that Advanced Tab is created.
1035+ """
1036+ # GIVEN: A new Advanced Tab
1037+ settings_form = SettingsForm(None)
1038+
1039+ # WHEN: I create an advanced tab
1040+ advanced_tab = AdvancedTab(settings_form)
1041+
1042+ # THEN:
1043+ self.assertEqual("Advanced", advanced_tab.tab_title, 'The tab title should be Advanced')
1044+
1045+ def test_change_search_as_type(self):
1046+ """
1047+ Test that when search as type is changed custom and song configs are updated
1048+ """
1049+ # GIVEN: A new Advanced Tab
1050+ settings_form = SettingsForm(None)
1051+ advanced_tab = AdvancedTab(settings_form)
1052+
1053+ # WHEN: I change search as type check box
1054+ advanced_tab.on_search_as_type_check_box_changed(True)
1055+
1056+ # THEN: we should have two post save processed to run
1057+ self.assertEqual(2, len(settings_form.processes), 'Two post save processes should be created')
1058+ self.assertTrue("songs_config_updated" in settings_form.processes, 'The songs plugin should be called')
1059+ self.assertTrue("custom_config_updated" in settings_form.processes, 'The custom plugin should be called')
1060
1061=== modified file 'tests/functional/openlp_core_ui/test_mainwindow.py'
1062--- tests/functional/openlp_core_ui/test_mainwindow.py 2015-01-30 21:15:03 +0000
1063+++ tests/functional/openlp_core_ui/test_mainwindow.py 2015-11-04 18:37:45 +0000
1064@@ -71,7 +71,7 @@
1065 with patch('openlp.core.ui.servicemanager.ServiceManager.load_file') as mocked_load_path:
1066
1067 # WHEN the argument is processed
1068- self.main_window.open_cmd_line_files()
1069+ self.main_window.open_cmd_line_files(service)
1070
1071 # THEN the service from the arguments is loaded
1072 mocked_load_path.assert_called_with(service), 'load_path should have been called with the service\'s path'
1073@@ -86,7 +86,7 @@
1074 with patch('openlp.core.ui.servicemanager.ServiceManager.load_file') as mocked_load_path:
1075
1076 # WHEN the argument is processed
1077- self.main_window.open_cmd_line_files()
1078+ self.main_window.open_cmd_line_files("")
1079
1080 # THEN the file should not be opened
1081 assert not mocked_load_path.called, 'load_path should not have been called'
1082
1083=== modified file 'tests/functional/openlp_core_utils/test_init.py'
1084--- tests/functional/openlp_core_utils/test_init.py 2015-01-19 08:34:29 +0000
1085+++ tests/functional/openlp_core_utils/test_init.py 2015-11-04 18:37:45 +0000
1086@@ -25,7 +25,7 @@
1087 from unittest import TestCase
1088
1089 from openlp.core.common.settings import Settings
1090-from openlp.core.utils import VersionThread, get_application_version, get_uno_command
1091+from openlp.core.utils import VersionThread, get_uno_command
1092 from tests.functional import MagicMock, patch
1093 from tests.helpers.testmixin import TestMixin
1094
1095
1096=== modified file 'tests/functional/test_init.py'
1097--- tests/functional/test_init.py 2015-04-25 19:29:39 +0000
1098+++ tests/functional/test_init.py 2015-11-04 18:37:45 +0000
1099@@ -33,7 +33,6 @@
1100 from tests.helpers.testmixin import TestMixin
1101 from tests.functional import MagicMock, patch, call
1102
1103-
1104 TEST_PATH = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'resources'))
1105
1106
1107@@ -132,60 +131,3 @@
1108 # THEN: It should ask if we want to create a backup
1109 self.assertEqual(Settings().value('core/application version'), '2.2.0', 'Version should be upgraded!')
1110 self.assertEqual(mocked_question.call_count, 1, 'A question should have been asked!')
1111-
1112- @patch(u'openlp.core.OptionParser')
1113- def parse_options_test(self, MockedOptionParser):
1114- """
1115- Test that parse_options sets up OptionParser correctly and parses the options given
1116- """
1117- # GIVEN: A list of valid options and a mocked out OptionParser object
1118- options = ['-e', '-l', 'debug', '-pd', '-s', 'style', 'extra', 'qt', 'args']
1119- mocked_parser = MagicMock()
1120- MockedOptionParser.return_value = mocked_parser
1121- expected_calls = [
1122- call('-e', '--no-error-form', dest='no_error_form', action='store_true',
1123- help='Disable the error notification form.'),
1124- call('-l', '--log-level', dest='loglevel', default='warning', metavar='LEVEL',
1125- help='Set logging to LEVEL level. Valid values are "debug", "info", "warning".'),
1126- call('-p', '--portable', dest='portable', action='store_true',
1127- help='Specify if this should be run as a portable app, off a USB flash drive (not implemented).'),
1128- call('-d', '--dev-version', dest='dev_version', action='store_true',
1129- help='Ignore the version file and pull the version directly from Bazaar'),
1130- call('-s', '--style', dest='style', help='Set the Qt4 style (passed directly to Qt4).')
1131- ]
1132-
1133- # WHEN: Calling parse_options
1134- parse_options(options)
1135-
1136- # THEN: A tuple should be returned with the parsed options and left over options
1137- MockedOptionParser.assert_called_with(usage='Usage: %prog [options] [qt-options]')
1138- self.assertEquals(expected_calls, mocked_parser.add_option.call_args_list)
1139- mocked_parser.parse_args.assert_called_with(options)
1140-
1141- @patch(u'openlp.core.OptionParser')
1142- def parse_options_from_sys_argv_test(self, MockedOptionParser):
1143- """
1144- Test that parse_options sets up OptionParser correctly and parses sys.argv
1145- """
1146- # GIVEN: A list of valid options and a mocked out OptionParser object
1147- mocked_parser = MagicMock()
1148- MockedOptionParser.return_value = mocked_parser
1149- expected_calls = [
1150- call('-e', '--no-error-form', dest='no_error_form', action='store_true',
1151- help='Disable the error notification form.'),
1152- call('-l', '--log-level', dest='loglevel', default='warning', metavar='LEVEL',
1153- help='Set logging to LEVEL level. Valid values are "debug", "info", "warning".'),
1154- call('-p', '--portable', dest='portable', action='store_true',
1155- help='Specify if this should be run as a portable app, off a USB flash drive (not implemented).'),
1156- call('-d', '--dev-version', dest='dev_version', action='store_true',
1157- help='Ignore the version file and pull the version directly from Bazaar'),
1158- call('-s', '--style', dest='style', help='Set the Qt4 style (passed directly to Qt4).')
1159- ]
1160-
1161- # WHEN: Calling parse_options
1162- parse_options([])
1163-
1164- # THEN: A tuple should be returned with the parsed options and left over options
1165- MockedOptionParser.assert_called_with(usage='Usage: %prog [options] [qt-options]')
1166- self.assertEquals(expected_calls, mocked_parser.add_option.call_args_list)
1167- mocked_parser.parse_args.assert_called_with()
1168
1169=== modified file 'tests/utils/test_bzr_tags.py'
1170--- tests/utils/test_bzr_tags.py 2015-10-17 11:18:23 +0000
1171+++ tests/utils/test_bzr_tags.py 2015-11-04 18:37:45 +0000
1172@@ -23,39 +23,13 @@
1173 Package to test for proper bzr tags.
1174 """
1175 import os
1176-import re
1177 from unittest import TestCase
1178
1179 from subprocess import Popen, PIPE
1180
1181-TAGS = [
1182- ['1.9.0', '1'],
1183- ['1.9.1', '775'],
1184- ['1.9.2', '890'],
1185- ['1.9.3', '1063'],
1186- ['1.9.4', '1196'],
1187- ['1.9.5', '1421'],
1188- ['1.9.6', '1657'],
1189- ['1.9.7', '1761'],
1190- ['1.9.8', '1856'],
1191- ['1.9.9', '1917'],
1192- ['1.9.10', '2003'],
1193- ['1.9.11', '2039'],
1194- ['1.9.12', '2063'],
1195- ['2.0', '2118'],
1196- ['2.1.0', '2119'],
1197- ['2.1.1', '2438'],
1198- ['2.1.2', '2488'],
1199- ['2.1.3', '2513'],
1200- ['2.1.4', '2532'],
1201- ['2.1.5', '2543'],
1202- ['2.1.6', '2550'],
1203- ['2.2', '2562']
1204-]
1205-# Depending on the repository, we sometimes have the 2.0.x tags in the repo too. They come up with a revision number of
1206-# "?", which I suspect is due to the fact that we're using shared repositories. This regular expression matches all
1207-# 2.0.x tags.
1208-TAG_SEARCH = re.compile('2\.0\.\d')
1209+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',
1210+ '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'
1211+ }
1212
1213
1214 class TestBzrTags(TestCase):
1215@@ -70,8 +44,12 @@
1216 # WHEN getting the branches tags
1217 bzr = Popen(('bzr', 'tags', '--directory=' + path), stdout=PIPE)
1218 std_out = bzr.communicate()[0]
1219- tags = [line.decode('utf-8').split() for line in std_out.splitlines()]
1220- tags = [t_r for t_r in tags if t_r[1] != '?' or not (t_r[1] == '?' and TAG_SEARCH.search(t_r[0]))]
1221+ count = len(TAGS1)
1222+ tags = [line.decode('utf-8').split()[0] for line in std_out.splitlines()]
1223+ count1 = 0
1224+ for t in tags:
1225+ if t in TAGS1:
1226+ count1 += 1
1227
1228 # THEN the tags should match the accepted tags
1229- self.assertEqual(TAGS, tags, 'List of tags should match')
1230+ self.assertEqual(count, count1, 'List of tags should match')