]> git.phdru.name Git - m_librarian.git/blob - m_librarian/wx/ListBooks.py
58f910d840afd359d5351cbc0dec9dc5e5dab600
[m_librarian.git] / m_librarian / wx / ListBooks.py
1 # coding: utf-8
2
3 import wx, wx.grid  # noqa: E401 multiple imports on one line
4 from ..compat import string_type, unicode_type
5 from ..translations import translations
6 from .Grids import GridWindow, GridPanel
7
8
9 _ = getattr(translations, 'ugettext', None) or translations.gettext
10
11
12 class BooksDataTable(wx.grid.GridTableBase):
13     def __init__(self, rows_count, column_names):
14         wx.grid.GridTableBase.__init__(self)
15         self.rows_count = rows_count
16         self.column_names = column_names
17         self.data = []
18         for row in range(rows_count + 1):
19             row_data = []
20             self.data.append(row_data)
21             for col in range(len(column_names)):
22                 row_data.append('')
23
24     # required methods for the wxPyGridTableBase interface
25
26     def GetNumberRows(self):
27         return self.rows_count
28
29     def GetNumberCols(self):
30         return len(self.column_names)
31
32     def IsEmptyCell(self, row, col):
33         return False
34
35     # Get/Set values in the table.  The Python version of these
36     # methods can handle any data-type, (as long as the Editor and
37     # Renderer understands the type too,) not just strings as in the
38     # C++ version.
39     def GetValue(self, row, col):
40         return self.data[row][col]
41
42     def SetValue(self, row, col, value):
43         self.data[row][col] = value
44
45     # Optional methods
46
47     # Called when the grid needs to display labels
48     def GetRowLabelValue(self, row):
49         return str(row)
50
51     def GetColLabelValue(self, col):
52         return _(self.column_names[col])
53
54     # Called to determine the kind of editor/renderer to use by
55     # default, doesn't necessarily have to be the same type used
56     # natively by the editor/renderer if they know how to convert.
57     def GetTypeName(self, row, col):
58         if col == 0:
59             return wx.grid.GRID_VALUE_BOOL
60         else:
61             return wx.grid.GRID_VALUE_STRING
62
63     # Called to determine how the data can be fetched and stored by the
64     # editor and renderer.  This allows you to enforce some type-safety
65     # in the grid.
66     def CanGetValueAs(self, row, col, typeName):
67         colType = self.GetTypeName(row, col)
68         if typeName == colType:
69             return True
70         else:
71             return False
72
73     def CanSetValueAs(self, row, col, typeName):
74         return self.CanGetValueAs(row, col, typeName)
75
76
77 class ListBooksPanel(GridPanel):
78
79     def InitGrid(self):
80         books_by_author = self.param['books_by_author']
81         columns = self.param['columns']
82         columns.insert(0, u'Выбрать')
83         total_rows = 0
84         for author in books_by_author:
85             books = books_by_author[author]
86             series = {book.series for book in books}
87             total_rows += len(books) + len(series) + 1
88         grid = self.grid
89         grid.SetTable(
90             BooksDataTable(total_rows+1, columns),
91             takeOwnership=True,
92         )
93         grid.EnableEditing(False)
94         for col, col_name in enumerate(columns):
95             grid.AutoSizeColLabelSize(col)
96             if col == 0:
97                 cell_attr = wx.grid.GridCellAttr()
98                 cell_attr.SetAlignment(wx.ALIGN_CENTRE, wx. ALIGN_CENTRE)
99                 grid.SetColAttr(col, cell_attr)
100             elif col_name in ('ser_no', 'size'):
101                 cell_attr = wx.grid.GridCellAttr()
102                 cell_attr.SetAlignment(wx.ALIGN_RIGHT, wx. ALIGN_CENTRE)
103                 grid.SetColAttr(col, cell_attr)
104         row = 0
105         grid.SetCellAlignment(row, 1, wx.ALIGN_CENTRE, wx. ALIGN_CENTRE)
106         grid.SetCellSize(row, 1, 1, len(columns)-1)
107         row = 1
108         self.toggle_rows = toggle_rows = {}  # map {row: [list of subrows]}
109         for author in sorted(books_by_author):
110             grid.SetCellAlignment(row, 1, wx.ALIGN_LEFT, wx. ALIGN_CENTRE)
111             grid.SetCellSize(row, 1, 1, len(columns)-1)
112             grid.SetCellValue(row, 1, u'%s' % (author,))
113             author_row = row
114             toggle_rows[author_row] = []
115             row += 1
116             books = books_by_author[author]
117             series = None
118             for book in books:
119                 if book.series != series:
120                     if book.series:
121                         value = book.series
122                     else:
123                         value = u'Вне серий'
124                     grid.SetCellAlignment(row, 1,
125                                           wx.ALIGN_LEFT, wx. ALIGN_CENTRE)
126                     grid.SetCellSize(row, 1, 1, len(columns)-1)
127                     grid.SetCellValue(row, 1,
128                                       u'%s — %s' % (book.author1, value))
129                     series_row = row
130                     toggle_rows[author_row].append(row)
131                     toggle_rows[series_row] = []
132                     row += 1
133                     series = book.series
134                 for col, col_name in enumerate(columns[1:]):
135                     value = getattr(book, col_name)
136                     if value is None:
137                         value = u''
138                     elif not isinstance(value, (string_type, unicode_type)):
139                         value = str(value)
140                     grid.SetCellValue(row, col+1, value)
141                 toggle_rows[author_row].append(row)
142                 toggle_rows[series_row].append(row)
143                 row += 1
144         toggle_rows[0] = [row_ for row_ in range(1, row)]
145         grid.AutoSizeColumns()
146         grid.AutoSizeRows()
147         grid.Bind(wx.grid.EVT_GRID_CELL_LEFT_CLICK, self.OnClick)
148
149     def toggleCB(self, row):
150         value = self.grid.GetCellValue(row, 0)
151         if value:
152             value = ''
153         else:
154             value = '1'
155         self.grid.SetCellValue(row, 0, value)
156         toggle_rows = self.toggle_rows
157         if row in toggle_rows:
158             for row_ in toggle_rows[row]:
159                 self.grid.SetCellValue(row_, 0, value)
160
161     def OnClick(self, event):
162         if event.GetCol() > 0:
163             return
164         self.toggleCB(event.GetRow())
165
166     def OnDClick(self, event):
167         if event.GetCol() == 0:
168             return
169         self.toggleCB(event.GetRow())
170
171     def OnKeyDown(self, event):
172         if event.GetKeyCode() == wx.WXK_ESCAPE:
173             self.Parent.Close()
174         else:
175             event.Skip()
176
177
178 class ListBooksWindow(GridWindow):
179
180     session_config_section_name = 'list_books'
181     window_title = u"m_Librarian: Список книг"
182     GridPanelClass = ListBooksPanel