- Added "Search while typing" feature for Bible Quick search.

- Added a Setting for controlling this ^^ behaviour
- Refactored some code to avoid duplicate error messages
This commit is contained in:
suutari-olli 2016-05-02 07:16:15 +03:00
parent 4e3ce9d596
commit 69b374f27b
4 changed files with 121 additions and 23 deletions

View File

@ -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
}

View File

@ -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')

View File

@ -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:

View File

@ -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', '<strong>OpenLP couldnt find anything '
'with your search.<br><br>'
'Please make sure that your reference follows one of these patterns:</strong><br><br>%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', '<strong>OpenLP couldnt find anything '
'with your search.<br><br>'
'Please make sure that your reference follows '
'one of these patterns:</strong><br><br>%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.