diff --git a/openlp/plugins/bibles/lib/__init__.py b/openlp/plugins/bibles/lib/__init__.py index bb190ab65..e4025411c 100644 --- a/openlp/plugins/bibles/lib/__init__.py +++ b/openlp/plugins/bibles/lib/__init__.py @@ -341,10 +341,10 @@ def parse_reference(reference, bible, language_selection, book_ref_id=False): if not book_ref_id: book_ref_id = bible.get_book_ref_id_by_localised_name(book, language_selection) elif not bible.get_book_by_book_ref_id(book_ref_id): - return False + return [] # We have not found the book so do not continue if not book_ref_id: - return False + return [] ranges = match.group('ranges') range_list = get_reference_match('range_separator').split(ranges) ref_list = [] @@ -403,7 +403,7 @@ def parse_reference(reference, bible, language_selection, book_ref_id=False): return ref_list else: log.debug('Invalid reference: {text}'.format(text=reference)) - return None + return [] class SearchResults(object): diff --git a/openlp/plugins/bibles/lib/db.py b/openlp/plugins/bibles/lib/db.py index aaa90efe4..acfb85a26 100644 --- a/openlp/plugins/bibles/lib/db.py +++ b/openlp/plugins/bibles/lib/db.py @@ -158,6 +158,7 @@ class BibleDB(Manager): self.get_name() if 'path' in kwargs: self.path = kwargs['path'] + self._is_web_bible = None def get_name(self): """ @@ -426,6 +427,18 @@ class BibleDB(Manager): return 0 return count + @property + def is_web_bible(self): + """ + A read only property indicating if the bible is a 'web bible' + + :return: If the bible is a web bible. + :rtype: bool + """ + if self._is_web_bible == None: + self._is_web_bible = bool(self.get_object(BibleMeta, 'download_source')) + return self._is_web_bible + def dump_bible(self): """ Utility debugging method to dump the contents of a bible. diff --git a/openlp/plugins/bibles/lib/manager.py b/openlp/plugins/bibles/lib/manager.py index 6154c83a9..fb3a00e64 100644 --- a/openlp/plugins/bibles/lib/manager.py +++ b/openlp/plugins/bibles/lib/manager.py @@ -142,8 +142,8 @@ class BibleManager(OpenLPMixin, RegistryProperties): log.debug('Bible Name: "{name}"'.format(name=name)) self.db_cache[name] = bible # Look to see if lazy load bible exists and get create getter. - source = self.db_cache[name].get_object(BibleMeta, 'download_source') - if source: + if self.db_cache[name].is_web_bible: + source = self.db_cache[name].get_object(BibleMeta, 'download_source') download_name = self.db_cache[name].get_object(BibleMeta, 'download_name').value meta_proxy = self.db_cache[name].get_object(BibleMeta, 'proxy_server') web_bible = HTTPBible(self.parent, path=self.path, file=filename, download_source=source.value, @@ -278,7 +278,7 @@ class BibleManager(OpenLPMixin, RegistryProperties): :param show_error: """ if not bible or not ref_list: - return None + return [] return self.db_cache[bible].get_verses(ref_list, show_error) def get_language_selection(self, bible): @@ -308,8 +308,13 @@ class BibleManager(OpenLPMixin, RegistryProperties): :param bible: The bible to search in (unicode). :param second_bible: The second bible (unicode). We do not search in this bible. :param text: The text to search for (unicode). + + :return: The search results if valid, or None if the search is invalid. + :rtype: None, list """ log.debug('BibleManager.verse_search("{bible}", "{text}")'.format(bible=bible, text=text)) + if not text: + return None # If no bibles are installed, message is given. if not bible: self.main_window.information_message( @@ -317,8 +322,7 @@ class BibleManager(OpenLPMixin, RegistryProperties): UiStrings().BibleNoBibles) return None # Check if the bible or second_bible is a web bible. - web_bible = self.db_cache[bible].get_object(BibleMeta, 'download_source') - if web_bible: + if self.db_cache[bible].is_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( @@ -328,41 +332,8 @@ class BibleManager(OpenLPMixin, RegistryProperties): 'This means that the currently selected Bible is a Web Bible.') ) return None - # Shorter than 3 char searches break OpenLP with very long search times, thus they are blocked. - if len(text) - text.count(' ') < 3: - return None # Fetch the results from db. If no results are found, return None, no message is given for this. - elif text: - return self.db_cache[bible].verse_search(text) - else: - return None - - def verse_search_while_typing(self, bible, second_bible, text): - """ - Does a verse search for the given bible and text. - This is used during "Search while typing" - It's the same thing as the normal text search, but it does not show the web Bible error. - (It would result in the error popping every time a char is entered or removed) - It also does not have a minimum text len, this is set in mediaitem.py - - :param bible: The bible to search in (unicode). - :param second_bible: The second bible (unicode). We do not search in this bible. - :param text: The text to search for (unicode). - """ - # If no bibles are installed, message is given. - if not bible: - return None - # Check if the bible or second_bible is a web bible. - web_bible = self.db_cache[bible].get_object(BibleMeta, 'download_source') - second_web_bible = '' - if second_bible: - second_web_bible = self.db_cache[second_bible].get_object(BibleMeta, 'download_source') - if web_bible or second_web_bible: - # If either Bible is Web, cursor is reset to normal and search ends w/o any message. - self.application.set_normal_cursor() - return None - # Fetch the results from db. If no results are found, return None, no message is given for this. - elif text: + if text: return self.db_cache[bible].verse_search(text) else: return None diff --git a/openlp/plugins/bibles/lib/mediaitem.py b/openlp/plugins/bibles/lib/mediaitem.py index 0fbabab31..7f6d077dc 100755 --- a/openlp/plugins/bibles/lib/mediaitem.py +++ b/openlp/plugins/bibles/lib/mediaitem.py @@ -175,8 +175,10 @@ class BibleMediaItem(MediaManagerItem): self.select_tab.setVisible(False) self.page_layout.addWidget(self.select_tab) # General Search Opions - self.options_widget = QtWidgets.QGroupBox(translate('BiblesPlugin.MediaItem', 'Options'), self) - self.general_bible_layout = QtWidgets.QFormLayout(self.options_widget) + self.options_tab = QtWidgets.QWidget() + self.options_tab.setSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum) + self.search_tab_bar.addTab(translate('BiblesPlugin.MediaItem', 'Options')) + self.general_bible_layout = QtWidgets.QFormLayout(self.options_tab) self.version_combo_box = create_horizontal_adjusting_combo_box(self, 'version_combo_box') self.general_bible_layout.addRow('{version}:'.format(version=UiStrings().Version), self.version_combo_box) self.second_combo_box = create_horizontal_adjusting_combo_box(self, 'second_combo_box') @@ -184,19 +186,23 @@ class BibleMediaItem(MediaManagerItem): self.style_combo_box = create_horizontal_adjusting_combo_box(self, 'style_combo_box') self.style_combo_box.addItems(['', '', '']) self.general_bible_layout.addRow(UiStrings().LayoutStyle, self.style_combo_box) - self.search_button_layout = QtWidgets.QHBoxLayout() + self.options_tab.setVisible(False) + self.page_layout.addWidget(self.options_tab) + # This widget is the easier way to reset the spacing of search_button_layout. (Because page_layout has had its + # spacing set to 0) + self.search_button_widget = QtWidgets.QWidget() + self.search_button_layout = QtWidgets.QHBoxLayout(self.search_button_widget) self.search_button_layout.addStretch() # Note: If we use QPushButton instead of the QToolButton, the icon will be larger than the Lock icon. - self.clear_button = QtWidgets.QToolButton(self) + self.clear_button = QtWidgets.QPushButton() self.clear_button.setIcon(self.clear_icon) - self.save_results_button = QtWidgets.QToolButton(self) + self.save_results_button = QtWidgets.QPushButton() self.save_results_button.setIcon(self.save_results_icon) self.search_button_layout.addWidget(self.clear_button) self.search_button_layout.addWidget(self.save_results_button) self.search_button = QtWidgets.QPushButton(self) self.search_button_layout.addWidget(self.search_button) - self.general_bible_layout.addRow(self.search_button_layout) - self.page_layout.addWidget(self.options_widget) + self.page_layout.addWidget(self.search_button_widget) self.results_view_tab = QtWidgets.QTabBar(self) self.results_view_tab.addTab('') self.results_view_tab.addTab('') @@ -438,9 +444,13 @@ class BibleMediaItem(MediaManagerItem): :param index: The tab selected (int) :return: None """ - search_tab = index == 0 - self.search_tab.setVisible(search_tab) - self.select_tab.setVisible(not search_tab) + if index == 0 or index == 1: + self.search_button.setEnabled(True) + else: + self.search_button.setEnabled(False) + self.search_tab.setVisible(index == 0) + self.select_tab.setVisible(index == 1) + self.options_tab.setVisible(index == 2) self.on_focus() def on_results_view_tab_current_changed(self, index): @@ -542,16 +552,15 @@ class BibleMediaItem(MediaManagerItem): :return: None """ new_selection = self.second_combo_box.currentData() - if self.list_view.count(): + if self.saved_results: # Exclusive or (^) the new and previous selections to detect if the user has switched between single and # dual bible mode if (new_selection is None) ^ (self.second_bible is None): if critical_error_message_box( message=translate('BiblesPlugin.MediaItem', 'OpenLP cannot combine single and dual Bible verse search results. ' - 'Do you want to clear your results and start a new search?'), + 'Do you want to clear your saved results?'), parent=self, question=True) == QtWidgets.QMessageBox.Yes: - self.display_results() self.saved_results = [] self.on_results_view_tab_total_update(ResultsTab.Saved) else: @@ -706,6 +715,8 @@ class BibleMediaItem(MediaManagerItem): This search is called on def text_search by 'Search' Text and Combined Searches. """ self.search_results = self.plugin.manager.verse_search(self.bible.name, text) + if self.search_results is None: + return if self.second_bible and self.search_results: filtered_search_results = [] not_found_count = 0 @@ -774,9 +785,12 @@ class BibleMediaItem(MediaManagerItem): :return: None """ - if Settings().value('bibles/is search while typing enabled'): - if not self.search_timer.isActive(): - self.search_timer.start() + if not Settings().value('bibles/is search while typing enabled') or \ + not self.bible or self.bible.is_web_bible or \ + (self.second_bible and self.bible.is_web_bible): + return + if not self.search_timer.isActive(): + self.search_timer.start() def on_search_timer_timeout(self): """ @@ -969,6 +983,8 @@ class BibleMediaItem(MediaManagerItem): """ Search for some Bible verses (by reference). """ + if self.bible is None: + return [] reference = self.plugin.manager.parse_ref(self.bible.name, string) search_results = self.plugin.manager.get_verses(self.bible.name, reference, showError) if search_results: @@ -980,6 +996,8 @@ class BibleMediaItem(MediaManagerItem): """ Create a media item from an item id. """ + if self.bible is None: + return [] reference = self.plugin.manager.parse_ref(self.bible.name, item_id) search_results = self.plugin.manager.get_verses(self.bible.name, reference, False) items = self.build_display_results(self.bible, None, search_results)