From: Oleg Broytman Date: Mon, 8 Jan 2024 02:05:33 +0000 (+0300) Subject: Feat(wx/search): Search books X-Git-Tag: 0.3.0~9^2~9 X-Git-Url: https://git.phdru.name/?p=m_librarian.git;a=commitdiff_plain;h=7e33e119821fe2b97ffb74702739f935f59099eb Feat(wx/search): Search books Refactor common code in `SearchPanel`. Create 2 panels: search for authors and search for books. Display multiple authors' books. [skip ci] --- diff --git a/m_librarian/wx/Application.py b/m_librarian/wx/Application.py index 41d42d1..d99edb6 100644 --- a/m_librarian/wx/Application.py +++ b/m_librarian/wx/Application.py @@ -1,6 +1,6 @@ import wx from .AWindow import AWindow -from .SearchPanel import SearchPanel +from .SearchPanels import SearchAuthorsPanel, SearchBooksPanel class MainWindow(AWindow): @@ -10,7 +10,13 @@ class MainWindow(AWindow): def OnInit(self): AWindow.OnInit(self) - SearchPanel(self) + vsizer = wx.BoxSizer(wx.VERTICAL) + self.SetSizer(vsizer) + + search_authors_panel = SearchAuthorsPanel(self) + search_books_panel = SearchBooksPanel(self) + vsizer.Add(search_authors_panel, 0, wx.EXPAND, 0) + vsizer.Add(search_books_panel, 0, wx.EXPAND, 0) class Application(wx.App): diff --git a/m_librarian/wx/ListBooks.py b/m_librarian/wx/ListBooks.py index b1f84a1..4cfabcd 100644 --- a/m_librarian/wx/ListBooks.py +++ b/m_librarian/wx/ListBooks.py @@ -12,13 +12,15 @@ class ListBooksPanel(GridPanel): _ = getattr(translations, 'ugettext', None) or translations.gettext books_by_author = self.param['books_by_author'] columns = self.param['columns'] - author = next(iter(books_by_author)) - books = books_by_author[author] - series = {book.series for book in books} + total_rows = 0 + for author in books_by_author: + books = books_by_author[author] + series = {book.series for book in books} + total_rows += len(books) + len(series) grid = self.grid - grid.CreateGrid(len(books) + len(series), len(columns)) + grid.CreateGrid(total_rows, len(columns)) grid.EnableEditing(False) - for row in range(len(books)): + for row in range(total_rows): grid.SetRowLabelValue(row, str(row)) grid.AutoSizeRowLabelSize(row) for col, col_name in enumerate(columns): @@ -29,26 +31,28 @@ class ListBooksPanel(GridPanel): cell_attr.SetAlignment(wx.ALIGN_RIGHT, wx. ALIGN_CENTRE) grid.SetColAttr(col, cell_attr) row = 0 - series = None - for book in books: - if book.series != series: - if book.series: - value = book.series - else: - value = u'Вне серий' - grid.SetCellAlignment(row, 0, wx.ALIGN_LEFT, wx. ALIGN_CENTRE) - grid.SetCellSize(row, 0, 1, len(columns)) - grid.SetCellValue(row, 0, u'%s — %s' % (book.author1, value)) + for author in sorted(books_by_author): + books = books_by_author[author] + series = None + for book in books: + if book.series != series: + if book.series: + value = book.series + else: + value = u'Вне серий' + grid.SetCellAlignment(row, 0, wx.ALIGN_LEFT, wx. ALIGN_CENTRE) + grid.SetCellSize(row, 0, 1, len(columns)) + grid.SetCellValue(row, 0, u'%s — %s' % (book.author1, value)) + row += 1 + series = book.series + for col, col_name in enumerate(columns): + value = getattr(book, col_name) + if value is None: + value = u'' + elif not isinstance(value, (string_type, unicode_type)): + value = str(value) + grid.SetCellValue(row, col, value) row += 1 - series = book.series - for col, col_name in enumerate(columns): - value = getattr(book, col_name) - if value is None: - value = u'' - elif not isinstance(value, (string_type, unicode_type)): - value = str(value) - grid.SetCellValue(row, col, value) - row += 1 grid.AutoSizeColumns() grid.AutoSizeRows() diff --git a/m_librarian/wx/SearchPanel.py b/m_librarian/wx/SearchPanel.py deleted file mode 100644 index 8547c31..0000000 --- a/m_librarian/wx/SearchPanel.py +++ /dev/null @@ -1,51 +0,0 @@ -# coding: utf-8 - -import wx -from ..search import search_authors_raw -from .ListAuthors import ListAuthorsWindow - - -_search_types = ['start', 'substring', 'full'] - - -class SearchPanel(wx.Panel): - - def __init__(self, parent): - wx.Panel.__init__(self, parent) - search_authors_vsizer = \ - wx.StaticBoxSizer(wx.VERTICAL, self, u'Поиск авторов') - self.SetSizer(search_authors_vsizer) - - self.search_authors = search_authors = \ - wx.TextCtrl(self, style=wx.TE_PROCESS_ENTER) - search_authors_vsizer.Add(search_authors, 0, wx.EXPAND, 0) - search_authors.Bind(wx.EVT_TEXT_ENTER, self.SearchAuthors) - - self.search_substr = search_substr = wx.RadioBox( - self, - choices=[ - u'Подстрока в начале', - u'Подстрока', - u'Точное совпадение', - ], - majorDimension=1, style=wx.RA_SPECIFY_ROWS - ) - search_authors_vsizer.Add(search_substr) - - self.search_case = search_case = wx.CheckBox( - self, label=u'Различать прописные/строчные') - search_authors_vsizer.Add(search_case) - - search_authors_button = wx.Button(self, label=u'Искать авторов') - search_authors_vsizer.Add(search_authors_button, 0, wx.ALIGN_CENTER, 0) - search_authors_button.Bind(wx.EVT_BUTTON, self.SearchAuthors) - - def SearchAuthors(self, event): - search_authors = self.search_authors.GetValue() - search_substr = _search_types[self.search_substr.GetSelection()] - search_case = self.search_case.GetValue() - if search_case is False: - search_case = None - search_authors_results = \ - search_authors_raw(search_authors, search_substr, search_case) - ListAuthorsWindow(self.Parent, search_authors_results) diff --git a/m_librarian/wx/SearchPanels.py b/m_librarian/wx/SearchPanels.py new file mode 100644 index 0000000..ab7bee6 --- /dev/null +++ b/m_librarian/wx/SearchPanels.py @@ -0,0 +1,88 @@ +# coding: utf-8 + +import wx +from ..config import get_config +from ..search import search_authors_raw, search_books_raw +from .ListAuthors import ListAuthorsWindow, ListBooksWindow + + +_search_types = ['start', 'substring', 'full'] + + +class SearchPanel(wx.Panel): + + # Subclasses must override these + search_title = None + search_button_title = None + + def __init__(self, parent): + wx.Panel.__init__(self, parent) + search_vsizer = \ + wx.StaticBoxSizer(wx.VERTICAL, self, self.search_title) + self.SetSizer(search_vsizer) + + self.search = search = \ + wx.TextCtrl(self, style=wx.TE_PROCESS_ENTER) + search_vsizer.Add(search, 0, wx.EXPAND, 0) + search.Bind(wx.EVT_TEXT_ENTER, self.DoSearch) + + self.search_substr = search_substr = wx.RadioBox( + self, + choices=[ + u'Подстрока в начале', + u'Подстрока', + u'Точное совпадение', + ], + majorDimension=1, style=wx.RA_SPECIFY_ROWS + ) + search_vsizer.Add(search_substr) + + self.search_case = search_case = wx.CheckBox( + self, label=u'Различать прописные/строчные') + search_vsizer.Add(search_case) + + search_button = wx.Button(self, label=self.search_button_title) + search_vsizer.Add(search_button, 0, wx.ALIGN_CENTER, 0) + search_button.Bind(wx.EVT_BUTTON, self.DoSearch) + + def DoSearch(self, event): + search = self.search.GetValue() + search_substr = _search_types[self.search_substr.GetSelection()] + search_case = self.search_case.GetValue() + if search_case is False: + search_case = None + self.realSearch(search, search_substr, search_case) + + +class SearchAuthorsPanel(SearchPanel): + + search_title = u'Поиск авторов' + search_button_title = u'Искать авторов' + + def realSearch(self, value, search_substr, search_case): + search_results = \ + search_authors_raw(value, search_substr, search_case) + ListAuthorsWindow(self.Parent, search_results) + + +class SearchBooksPanel(SearchPanel): + + search_title = u'Поиск книг' + search_button_title = u'Искать книги' + + def __init__(self, parent): + SearchPanel.__init__(self, parent) + self.use_filters = use_filters = wx.CheckBox( + self, label=u'Использовать фильтры') + use_filters_cfg = \ + get_config().getint('filters', 'use_in_search_forms', 1) + use_filters.SetValue(use_filters_cfg) + sizer = self.GetSizer() + s_count = len(sizer.GetChildren()) + sizer.Insert(s_count-1, use_filters) # Insert before the cutton + + def realSearch(self, value, search_substr, search_case): + use_filters = self.use_filters.GetValue() + search_results = \ + search_books_raw(value, search_substr, search_case, use_filters) + ListBooksWindow(self.Parent, search_results)