diff --git a/openlp/plugins/bibles/bibleplugin.py b/openlp/plugins/bibles/bibleplugin.py index 509173d7b..0a69068f8 100644 --- a/openlp/plugins/bibles/bibleplugin.py +++ b/openlp/plugins/bibles/bibleplugin.py @@ -61,7 +61,9 @@ __default_settings__ = { 'bibles/list separator': '', 'bibles/end separator': '', 'bibles/last directory import': '', - 'bibles/hide combined quick error': False + 'bibles/hide combined quick error': False, + 'bibles/is search while typing enabled': True, + 'bibles/hide web bible error if searching while typing': True } diff --git a/openlp/plugins/bibles/lib/biblestab.py b/openlp/plugins/bibles/lib/biblestab.py index 840adc3f2..177192605 100644 --- a/openlp/plugins/bibles/lib/biblestab.py +++ b/openlp/plugins/bibles/lib/biblestab.py @@ -139,6 +139,9 @@ class BiblesTab(SettingsTab): self.hide_combined_quick_error_check_box = QtWidgets.QCheckBox(self.bible_quick_settings_group_box) self.hide_combined_quick_error_check_box.setObjectName('hide_combined_quick_error_check_box') self.search_settings_layout.addRow(self.hide_combined_quick_error_check_box) + self.bible_search_while_typing_check_box = QtWidgets.QCheckBox(self.bible_quick_settings_group_box) + self.bible_search_while_typing_check_box.setObjectName('bible_search_while_typing_check_box') + self.search_settings_layout.addRow(self.bible_search_while_typing_check_box) self.left_layout.addStretch() self.right_layout.addStretch() # Signals and slots @@ -166,6 +169,8 @@ class BiblesTab(SettingsTab): self.on_reset_to_combined_quick_search_check_box_changed) self.hide_combined_quick_error_check_box.stateChanged.connect( self.on_hide_combined_quick_error_check_box_changed) + self.bible_search_while_typing_check_box.stateChanged.connect( + self.on_bible_search_while_typing_check_box_changed) def retranslateUi(self): self.verse_display_group_box.setTitle(translate('BiblesPlugin.BiblesTab', 'Verse Display')) @@ -216,6 +221,8 @@ class BiblesTab(SettingsTab): self.hide_combined_quick_error_check_box.setText(translate('BiblesPlugin.BiblesTab', 'Don\'t show error if nothing is found in "Text or ' 'Scripture Reference"')) + self.bible_search_while_typing_check_box.setText(translate('BiblesPlugin.BiblesTab', + 'Search automatically while typing')) def on_bible_theme_combo_box_changed(self): self.bible_theme = self.bible_theme_combo_box.currentText() @@ -336,6 +343,12 @@ class BiblesTab(SettingsTab): """ self.hide_combined_quick_error = (check_state == QtCore.Qt.Checked) + def on_bible_search_while_typing_check_box_changed(self, check_state): + """ + Event handler for the 'hide_combined_quick_error' check box + """ + self.bible_search_while_typing = (check_state == QtCore.Qt.Checked) + def load(self): settings = Settings() settings.beginGroup(self.settings_section) @@ -393,6 +406,8 @@ class BiblesTab(SettingsTab): self.reset_to_combined_quick_search_check_box.setChecked(self.reset_to_combined_quick_search) self.hide_combined_quick_error = settings.value('hide combined quick error') self.hide_combined_quick_error_check_box.setChecked(self.hide_combined_quick_error) + self.bible_search_while_typing = settings.value('is search while typing enabled') + self.bible_search_while_typing_check_box.setChecked(self.hide_combined_quick_error) settings.endGroup() def save(self): @@ -426,6 +441,7 @@ class BiblesTab(SettingsTab): self.settings_form.register_post_process('bibles_load_list') settings.setValue('reset to combined quick search', self.reset_to_combined_quick_search) settings.setValue('hide combined quick error', self.hide_combined_quick_error) + settings.setValue('is search while typing enabled', self.bible_search_while_typing) settings.endGroup() if self.tab_visited: self.settings_form.register_post_process('bibles_config_updated') diff --git a/openlp/plugins/bibles/lib/manager.py b/openlp/plugins/bibles/lib/manager.py index b0a429737..b7408f180 100644 --- a/openlp/plugins/bibles/lib/manager.py +++ b/openlp/plugins/bibles/lib/manager.py @@ -326,17 +326,20 @@ class BibleManager(RegistryProperties): if web_bible or second_web_bible: # If either Bible is Web, cursor is reset to normal and message is given. self.application.set_normal_cursor() - self.main_window.information_message( - translate('BiblesPlugin.BibleManager', 'Web Bible cannot be used'), - translate('BiblesPlugin.BibleManager', 'Text Search is not available with Web Bibles.\n' - 'Please use the Scripture Reference Search instead.') - ) + # If we are performing "Search while typing", do not show this error. + # Web Bible checking method is currently bound to this file, so it can't be properly moved to mediaitem.py + # Without making some changes to the stucture. (= self.db_cache[bible].get_object(BibleMeta,...) + if not Settings().value('bibles/hide web bible error if searching while typing'): + self.main_window.information_message( + translate('BiblesPlugin.BibleManager', 'Web Bible cannot be used'), + translate('BiblesPlugin.BibleManager', 'Text Search is not available with Web Bibles.\n' + 'Please use the Scripture Reference Search instead.\n\n' + 'This means that the currently used Bible or Second Bible\n' + 'is installed as Web Bible and may not be used.') + ) return None # Shorter than 3 char searches break OpenLP with very long search times, thus they are blocked. if len(text) - text.count(' ') < 3: - self.main_window.information_message( - ('%s' % UiStrings().BibleShortSearchTitle), - ('%s' % UiStrings().BibleShortSearch)) return None # Fetch the results from db. If no results are found, return None, no message is given for this. elif text: diff --git a/openlp/plugins/bibles/lib/mediaitem.py b/openlp/plugins/bibles/lib/mediaitem.py index 7ab311b66..7a055635d 100644 --- a/openlp/plugins/bibles/lib/mediaitem.py +++ b/openlp/plugins/bibles/lib/mediaitem.py @@ -35,6 +35,8 @@ from openlp.plugins.bibles.forms.editbibleform import EditBibleForm from openlp.plugins.bibles.lib import LayoutStyle, DisplayStyle, VerseReferenceList, get_reference_separator, \ LanguageSelection, BibleStrings from openlp.plugins.bibles.lib.db import BiblesResourcesDB +import re + log = logging.getLogger(__name__) @@ -251,6 +253,8 @@ class BibleMediaItem(MediaManagerItem): # Other stuff self.quick_search_edit.returnPressed.connect(self.on_quick_search_button) self.search_tab_bar.currentChanged.connect(self.on_search_tab_bar_current_changed) + # Cherry + self.quick_search_edit.textChanged.connect(self.on_search_text_edit_changed) def on_focus(self): if self.quickTab.isVisible(): @@ -669,19 +673,6 @@ class BibleMediaItem(MediaManagerItem): # This is triggered on reference search, use the search from manager.py if self.quick_search_edit.current_search_type() == BibleSearch.Reference: self.search_results = self.plugin.manager.get_verses(bible, text) - if not self.search_results: - # if nothing is found, message is given. - # Get reference separators from settings. - reference_separators = { - 'verse': get_reference_separator('sep_v_display'), - 'range': get_reference_separator('sep_r_display'), - 'list': get_reference_separator('sep_l_display')} - self.main_window.information_message( - translate('BiblesPlugin.BibleManager', 'Scripture Reference Error'), - translate('BiblesPlugin.BibleManager', 'OpenLP couldn’t find anything ' - 'with your search.

' - 'Please make sure that your reference follows one of these patterns:


%s' - % UiStrings().BibleScriptureError % reference_separators)) elif self.quick_search_edit.current_search_type() == BibleSearch.Combined: # In Combined Reference search no error is given if no results are found. (This would result in duplicate) self.search_results = self.plugin.manager.get_verses(bible, text) @@ -738,6 +729,8 @@ class BibleMediaItem(MediaManagerItem): "Eg. "Reference Search", "Text Search" or "Combined search". """ log.debug('Quick Search Button clicked') + # If we are performing "Search while typing", this setting is set to True, here it's reset to "False" + Settings().setValue('bibles/hide web bible error if searching while typing', False) # Disable the button while processing, get text from Quick search field. self.quickSearchButton.setEnabled(False) self.application.process_events() @@ -748,9 +741,27 @@ class BibleMediaItem(MediaManagerItem): if self.quick_search_edit.current_search_type() == BibleSearch.Reference: # We are doing a 'Reference Search'. (Get script from def on_quick_reference_search) self.on_quick_reference_search() + # if nothing is found, message is given. + # Get reference separators from settings. + if not self.search_results: + reference_separators = { + 'verse': get_reference_separator('sep_v_display'), + 'range': get_reference_separator('sep_r_display'), + 'list': get_reference_separator('sep_l_display')} + self.main_window.information_message( + translate('BiblesPlugin.BibleManager', 'Scripture Reference Error'), + translate('BiblesPlugin.BibleManager', 'OpenLP couldn’t find anything ' + 'with your search.

' + 'Please make sure that your reference follows ' + 'one of these patterns:


%s' + % UiStrings().BibleScriptureError % reference_separators)) elif self.quick_search_edit.current_search_type() == BibleSearch.Text: # We are doing a 'Text Search'. (Get script from def on_quick_text_search) self.on_quick_text_search() + if not self.search_results and len(text) - text.count(' ') < 3 and bible: + self.main_window.information_message( + ('%s' % UiStrings().BibleShortSearchTitle), + ('%s' % UiStrings().BibleShortSearch)) elif self.quick_search_edit.current_search_type() == BibleSearch.Combined: # We are doing a 'Combined search'. Starting with reference search. self.on_quick_reference_search() @@ -767,10 +778,12 @@ class BibleMediaItem(MediaManagerItem): # Text search starts here if no reference was found and keyword is longer than 2. # > 2 check is required in order to avoid duplicate error messages for short keywords. self.on_quick_text_search() - # If no Text or Reference is found, message is given. + # If no Text or Reference is found, message is given, unless a setting for not showing it is enabled. if not self.search_results and not \ Settings().value(self.settings_section + '/hide combined quick error'): self.application.set_normal_cursor() + # Reference separators need to be defined both, in here and on reference search, + # error won't work if they are left out from one. reference_separators = { 'verse': get_reference_separator('sep_v_display'), 'range': get_reference_separator('sep_r_display'), @@ -796,6 +809,37 @@ class BibleMediaItem(MediaManagerItem): self.check_search_result() self.application.set_normal_cursor() + def on_quick_search_search_as_type_text(self): + """ + This function is called when "Search as you type" is enabled for Bibles. + It is basically the same thing as "on_quick_search_search" but all the error messages are removed. + """ + log.debug('Quick Search Button clicked') + #self.application.process_events() + # These need to be defined here too so the search results can be displayed. + bible = self.quickVersionComboBox.currentText() + second_bible = self.quickSecondComboBox.currentText() + if self.quick_search_edit.current_search_type() == BibleSearch.Reference: + # We are doing a 'Reference Search'. (Get script from def on_quick_reference_search) + self.on_quick_reference_search() + elif self.quick_search_edit.current_search_type() == BibleSearch.Text: + # We are doing a 'Text Search'. (Get script from def on_quick_text_search) + self.on_quick_text_search() + elif self.quick_search_edit.current_search_type() == BibleSearch.Combined: + self.on_quick_reference_search() + if not self.search_results: + self.on_quick_text_search() + # Finalizing the search + # List is cleared if not locked, results are listed, button is set available, cursor is set to normal. + if not self.quickLockButton.isChecked(): + self.list_view.clear() + if self.list_view.count() != 0 and self.search_results: + self.__check_second_bible(bible, second_bible) + elif self.search_results: + self.display_results(bible, second_bible) + self.check_search_result() + self.application.set_normal_cursor() + def display_results(self, bible, second_bible=''): """ Displays the search results in the media manager. All data needed for further action is saved for/in each row. @@ -807,6 +851,39 @@ class BibleMediaItem(MediaManagerItem): self.search_results = {} self.second_search_results = {} + def on_search_text_edit_changed(self): + """ + If search as type enabled invoke the search on each key press. If the Lyrics are being searched do not start + till 7 characters have been entered. + """ + text = self.quick_search_edit.text() + # If web bible is used, don't show the error while searching and typing. + # This would result in seeing the same message multiple times. + # This message is located in lib\manager.py, so the setting is required. + Settings().setValue('bibles/hide web bible error if searching while typing', True) + search_length = 1 + if self.quick_search_edit.current_search_type() == BibleSearch.Combined: + search_length = 4 + if self.quick_search_edit.current_search_type() == BibleSearch.Reference: + search_length = 3 + elif self.quick_search_edit.current_search_type() == BibleSearch.Text: + search_length = 5 + # Regex for finding space + any non whitemark character. (Prevents search from starting on 1 word searches) + space_and_any = re.compile(' \S') + # Turn this into a format that may be used in if statement. + count_space_any = space_and_any.findall(text) + # Start searching if this behaviour is not disabled in settings and conditions are met. + if len(text) > search_length and len(count_space_any) != 0\ + and Settings().value('bibles/is search while typing enabled'): + # Start search if no chars are entered or deleted for 1.3 seconds + # Use the self.on_quick_search_search_as_type_text, this does not contain any error messages. + # This method may be a bit buggy sometimes and starts shorter than required searches due to the delay. + QtCore.QTimer().singleShot(1300, self.on_quick_search_search_as_type_text) + # If text lenght is less than 4 and results are not locked, it's still possible to search short references. + if not self.quickLockButton.isChecked() and len(text) < 4\ + and Settings().value('bibles/is search while typing enabled'): + self.list_view.clear() + def build_display_results(self, bible, second_bible, search_results): """ Displays the search results in the media manager. All data needed for further action is saved for/in each row.