Move no results functionality to the ListWidgetWithDnD

This commit is contained in:
Philip Ridout 2016-11-10 07:09:04 +00:00
parent 389fb391df
commit 94fca706ff
6 changed files with 42 additions and 58 deletions

View File

@ -397,8 +397,6 @@ class MediaManagerItem(QtWidgets.QWidget, RegistryProperties):
# Decide if we have to show the context menu or not. # Decide if we have to show the context menu or not.
if item is None: if item is None:
return return
if not item.flags() & QtCore.Qt.ItemIsSelectable:
return
self.menu.exec(self.list_view.mapToGlobal(point)) self.menu.exec(self.list_view.mapToGlobal(point))
def get_file_list(self): def get_file_list(self):
@ -638,34 +636,6 @@ class MediaManagerItem(QtWidgets.QWidget, RegistryProperties):
""" """
return item return item
def check_search_result(self):
"""
Checks if the list_view is empty and adds a "No Search Results" item.
"""
if self.list_view.count():
return
message = translate('OpenLP.MediaManagerItem', 'No Search Results')
item = QtWidgets.QListWidgetItem(message)
item.setFlags(QtCore.Qt.NoItemFlags)
font = QtGui.QFont()
font.setItalic(True)
item.setFont(font)
self.list_view.addItem(item)
def check_search_result_search_while_typing_short(self):
"""
This is used in Bible "Search while typing" if the search is shorter than the min required len.
"""
if self.list_view.count():
return
message = translate('OpenLP.MediaManagerItem', 'Search is too short to be used in: "Search while typing"')
item = QtWidgets.QListWidgetItem(message)
item.setFlags(QtCore.Qt.NoItemFlags)
font = QtGui.QFont()
font.setItalic(True)
item.setFont(font)
self.list_view.addItem(item)
def _get_id_of_item_to_generate(self, item, remote_item): def _get_id_of_item_to_generate(self, item, remote_item):
""" """
Utility method to check items being submitted for slide generation. Utility method to check items being submitted for slide generation.

View File

@ -26,7 +26,10 @@ import os
from PyQt5 import QtCore, QtGui, QtWidgets from PyQt5 import QtCore, QtGui, QtWidgets
from openlp.core.common import Registry from openlp.core.common import Registry, translate
NO_RESULTS = translate('OpenLP.ListWidgetWithDnD', 'No Search Results')
SHORT_RESULTS = translate('OpenLP.ListWidgetWithDnD', 'Please type more text to use \'Search As You Type\'')
class ListWidgetWithDnD(QtWidgets.QListWidget): class ListWidgetWithDnD(QtWidgets.QListWidget):
@ -37,8 +40,9 @@ class ListWidgetWithDnD(QtWidgets.QListWidget):
""" """
Initialise the list widget Initialise the list widget
""" """
super(ListWidgetWithDnD, self).__init__(parent) super().__init__(parent)
self.mime_data_text = name self.mime_data_text = name
self.no_results_text = NO_RESULTS
def activateDnD(self): def activateDnD(self):
""" """
@ -48,6 +52,19 @@ class ListWidgetWithDnD(QtWidgets.QListWidget):
self.setDragDropMode(QtWidgets.QAbstractItemView.DragDrop) self.setDragDropMode(QtWidgets.QAbstractItemView.DragDrop)
Registry().register_function(('%s_dnd' % self.mime_data_text), self.parent().load_file) Registry().register_function(('%s_dnd' % self.mime_data_text), self.parent().load_file)
def clear(self, search_while_typing=False):
"""
Re-implement clear, so that we can customise feedback when using 'Search as you type'
:param search_while_typing: True if we want to display the customised message
:return: None
"""
if search_while_typing:
self.no_results_text = SHORT_RESULTS
else:
self.no_results_text = NO_RESULTS
super().clear()
def mouseMoveEvent(self, event): def mouseMoveEvent(self, event):
""" """
Drag and drop event does not care what data is selected as the recipient will use events to request the data Drag and drop event does not care what data is selected as the recipient will use events to request the data
@ -102,6 +119,24 @@ class ListWidgetWithDnD(QtWidgets.QListWidget):
listing = os.listdir(local_file) listing = os.listdir(local_file)
for file in listing: for file in listing:
files.append(os.path.join(local_file, file)) files.append(os.path.join(local_file, file))
Registry().execute('%s_dnd' % self.mime_data_text, {'files': files, 'target': self.itemAt(event.pos())}) Registry().execute('{mime_data}_dnd'.format(mime_data=self.mime_data_text),
{'files': files, 'target': self.itemAt(event.pos())})
else: else:
event.ignore() event.ignore()
def paintEvent(self, event):
"""
Re-implement paintEvent so that we can add 'No Results' text when the listWidget is empty.
:param event: A QPaintEvent
:return: None
"""
super().paintEvent(event)
if not self.count():
viewport = self.viewport()
painter = QtGui.QPainter(viewport)
font = QtGui.QFont()
font.setItalic(True)
painter.setFont(font)
painter.drawText(QtCore.QRect(0, 0, viewport.width(), viewport.height()),
(QtCore.Qt.AlignHCenter | QtCore.Qt.TextWordWrap), self.no_results_text)

View File

@ -75,21 +75,16 @@ class BibleMediaItem(MediaManagerItem):
self.has_search = True self.has_search = True
self.search_results = {} self.search_results = {}
self.second_search_results = {} self.second_search_results = {}
self.check_search_result()
Registry().register_function('bibles_load_list', self.reload_bibles) Registry().register_function('bibles_load_list', self.reload_bibles)
def __check_second_bible(self, bible, second_bible): def __check_second_bible(self, bible, second_bible):
""" """
Check if the first item is a second bible item or not. Check if the first item is a second bible item or not.
""" """
bitem = self.list_view.item(0) if not self.list_view.count():
if not bitem.flags() & QtCore.Qt.ItemIsSelectable:
# The item is the "No Search Results" item.
self.list_view.clear()
self.display_results(bible, second_bible) self.display_results(bible, second_bible)
return return
else: item_second_bible = self._decode_qt_object(self.list_view.item(0), 'second_bible')
item_second_bible = self._decode_qt_object(bitem, 'second_bible')
if item_second_bible and second_bible or not item_second_bible and not second_bible: if item_second_bible and second_bible or not item_second_bible and not second_bible:
self.display_results(bible, second_bible) self.display_results(bible, second_bible)
elif critical_error_message_box( elif critical_error_message_box(
@ -551,14 +546,12 @@ class BibleMediaItem(MediaManagerItem):
def on_clear_button_clicked(self): def on_clear_button_clicked(self):
# Clear the list, then set the "No search Results" message, then clear the text field and give it focus. # Clear the list, then set the "No search Results" message, then clear the text field and give it focus.
self.list_view.clear() self.list_view.clear()
self.check_search_result()
self.quick_search_edit.clear() self.quick_search_edit.clear()
self.quick_search_edit.setFocus() self.quick_search_edit.setFocus()
def on_advanced_clear_button_clicked(self): def on_advanced_clear_button_clicked(self):
# The same as the on_clear_button_clicked, but gives focus to Book name field in "Select" (advanced). # The same as the on_clear_button_clicked, but gives focus to Book name field in "Select" (advanced).
self.list_view.clear() self.list_view.clear()
self.check_search_result()
self.advanced_book_combo_box.setFocus() self.advanced_book_combo_box.setFocus()
def on_lock_button_toggled(self, checked): def on_lock_button_toggled(self, checked):
@ -692,7 +685,6 @@ class BibleMediaItem(MediaManagerItem):
elif self.search_results: elif self.search_results:
self.display_results(bible, second_bible) self.display_results(bible, second_bible)
self.advancedSearchButton.setEnabled(True) self.advancedSearchButton.setEnabled(True)
self.check_search_result()
self.application.set_normal_cursor() self.application.set_normal_cursor()
def on_quick_reference_search(self): def on_quick_reference_search(self):
@ -886,7 +878,6 @@ class BibleMediaItem(MediaManagerItem):
elif self.search_results: elif self.search_results:
self.display_results(bible, second_bible) self.display_results(bible, second_bible)
self.quickSearchButton.setEnabled(True) self.quickSearchButton.setEnabled(True)
self.check_search_result()
self.application.set_normal_cursor() self.application.set_normal_cursor()
def on_quick_search_while_typing(self): def on_quick_search_while_typing(self):
@ -917,7 +908,6 @@ class BibleMediaItem(MediaManagerItem):
self.__check_second_bible(bible, second_bible) self.__check_second_bible(bible, second_bible)
elif self.search_results: elif self.search_results:
self.display_results(bible, second_bible) self.display_results(bible, second_bible)
self.check_search_result()
self.application.set_normal_cursor() self.application.set_normal_cursor()
def on_search_text_edit_changed(self): def on_search_text_edit_changed(self):
@ -956,17 +946,13 @@ class BibleMediaItem(MediaManagerItem):
if len(text) == 0: if len(text) == 0:
if not self.quickLockButton.isChecked(): if not self.quickLockButton.isChecked():
self.list_view.clear() self.list_view.clear()
self.check_search_result()
else: else:
if limit == 3 and (len(text) < limit or len(count_space_digit_reference) == 0): if limit == 3 and (len(text) < limit or len(count_space_digit_reference) == 0):
if not self.quickLockButton.isChecked(): if not self.quickLockButton.isChecked():
self.list_view.clear() self.list_view.clear()
self.check_search_result() elif (limit == 8 and len(text) < limit ):
elif (limit == 8 and (len(text) < limit or len(count_spaces_two_chars_text) == 0 or
len(count_two_chars_text) < 2)):
if not self.quickLockButton.isChecked(): if not self.quickLockButton.isChecked():
self.list_view.clear() self.list_view.clear(search_while_typing=True)
self.check_search_result_search_while_typing_short()
else: else:
""" """
Start search if no chars are entered or deleted for 0.2 s Start search if no chars are entered or deleted for 0.2 s

View File

@ -131,7 +131,6 @@ class CustomMediaItem(MediaManagerItem):
# Called to redisplay the custom list screen edith from a search # Called to redisplay the custom list screen edith from a search
# or from the exit of the Custom edit dialog. If remote editing is # or from the exit of the Custom edit dialog. If remote editing is
# active trigger it and clean up so it will not update again. # active trigger it and clean up so it will not update again.
self.check_search_result()
def on_new_click(self): def on_new_click(self):
""" """
@ -268,7 +267,6 @@ class CustomMediaItem(MediaManagerItem):
CustomSlide.theme_name.like(search_keywords), CustomSlide.theme_name.like(search_keywords),
order_by_ref=CustomSlide.title) order_by_ref=CustomSlide.title)
self.load_list(search_results) self.load_list(search_results)
self.check_search_result()
def on_search_text_edit_changed(self, text): def on_search_text_edit_changed(self, text):
""" """

View File

@ -232,7 +232,6 @@ class SongMediaItem(MediaManagerItem):
search_results = self.plugin.manager.get_all_objects( search_results = self.plugin.manager.get_all_objects(
Song, and_(Song.ccli_number.like(search_string), Song.ccli_number != '')) Song, and_(Song.ccli_number.like(search_string), Song.ccli_number != ''))
self.display_results_cclinumber(search_results) self.display_results_cclinumber(search_results)
self.check_search_result()
def search_entire(self, search_keywords): def search_entire(self, search_keywords):
search_string = '%{text}%'.format(text=clean_string(search_keywords)) search_string = '%{text}%'.format(text=clean_string(search_keywords))

View File

@ -155,7 +155,6 @@ class TestMediaItem(TestCase, TestMixin):
self.media_item.list_view = MagicMock() self.media_item.list_view = MagicMock()
self.media_item.search_results = MagicMock() self.media_item.search_results = MagicMock()
self.media_item.display_results = MagicMock() self.media_item.display_results = MagicMock()
self.media_item.check_search_result = MagicMock()
self.app.set_normal_cursor = MagicMock() self.app.set_normal_cursor = MagicMock()
# WHEN: on_quick_search_button is called # WHEN: on_quick_search_button is called
@ -169,7 +168,6 @@ class TestMediaItem(TestCase, TestMixin):
self.assertEqual(1, self.media_item.quickLockButton.isChecked.call_count, 'Lock Should had been called once') self.assertEqual(1, self.media_item.quickLockButton.isChecked.call_count, 'Lock Should had been called once')
self.assertEqual(1, self.media_item.display_results.call_count, 'Display results Should had been called once') self.assertEqual(1, self.media_item.display_results.call_count, 'Display results Should had been called once')
self.assertEqual(2, self.media_item.quickSearchButton.setEnabled.call_count, 'Disable and Enable the button') self.assertEqual(2, self.media_item.quickSearchButton.setEnabled.call_count, 'Disable and Enable the button')
self.assertEqual(1, self.media_item.check_search_result.call_count, 'Check results Should had been called once')
self.assertEqual(1, self.app.set_normal_cursor.call_count, 'Normal cursor should had been called once') self.assertEqual(1, self.app.set_normal_cursor.call_count, 'Normal cursor should had been called once')
def test_on_clear_button_clicked(self): def test_on_clear_button_clicked(self):
@ -178,7 +176,6 @@ class TestMediaItem(TestCase, TestMixin):
""" """
# GIVEN: Mocked list_view, check_search_results & quick_search_edit. # GIVEN: Mocked list_view, check_search_results & quick_search_edit.
self.media_item.list_view = MagicMock() self.media_item.list_view = MagicMock()
self.media_item.check_search_result = MagicMock()
self.media_item.quick_search_edit = MagicMock() self.media_item.quick_search_edit = MagicMock()
# WHEN: on_clear_button_clicked is called # WHEN: on_clear_button_clicked is called
@ -186,7 +183,6 @@ class TestMediaItem(TestCase, TestMixin):
# THEN: Search result should be reset and search field should receive focus. # THEN: Search result should be reset and search field should receive focus.
self.media_item.list_view.clear.assert_called_once_with(), self.media_item.list_view.clear.assert_called_once_with(),
self.media_item.check_search_result.assert_called_once_with(),
self.media_item.quick_search_edit.clear.assert_called_once_with(), self.media_item.quick_search_edit.clear.assert_called_once_with(),
self.media_item.quick_search_edit.setFocus.assert_called_once_with() self.media_item.quick_search_edit.setFocus.assert_called_once_with()