[go: up one dir, main page]

Menu

[dfe9bc]: / ui / checklist.py  Maximize  Restore  History

Download this file

358 lines (282 with data), 10.1 kB

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
# ******************************************************
# * Copyright © 2017-2023 - Jordan Irwin (AntumDeluge) *
# ******************************************************
# * This software is licensed under the MIT license. *
# * See: LICENSE.txt for details. *
# ******************************************************
## @module ui.checklist
import wx
from dbr.language import GT
from libdbr import strings
from libdbr.logger import Logger
from libdebreate.ident import btnid
from libdebreate.ident import pnlid
from ui.button import CreateButton
from ui.helper import GetField
from ui.layout import BoxSizer
from ui.panel import BorderedPanel
from ui.panel import ScrolledPanel
from ui.style import layout as lyt
_logger = Logger(__name__)
## A checkable list
class CheckList(BorderedPanel):
def __init__(self, parent, ID=wx.ID_ANY, items=[], pos=wx.DefaultPosition, size=wx.DefaultSize,
style=wx.VSCROLL, name=wx.PanelNameStr):
BorderedPanel.__init__(self, parent, ID, pos, size, name=name)
self.SetBackgroundColour("white")
pnl_bg = ScrolledPanel(self, pnlid.BACKGROUND, style=style|wx.TAB_TRAVERSAL|wx.BORDER_NONE)
pnl_bg.SetBackgroundColour(self.GetBackgroundColour())
pnl_bg.SetScrollbars(20, 20, 50, 50)
# *** Event Handling *** #
self.Bind(wx.EVT_CHECKBOX, self.OnCheckItem)
# *** Layout *** #
lyt_bg = BoxSizer(wx.VERTICAL)
pnl_bg.SetSizer(lyt_bg)
pnl_bg.SetAutoLayout(True)
lyt_main = BoxSizer(wx.VERTICAL)
lyt_main.Add(pnl_bg, 1, wx.EXPAND)
self.SetSizer(lyt_main)
self.SetAutoLayout(True)
self.Layout()
# *** Post-Layout Actions *** #
if items:
self.AddItems(items)
## Add a single item to the list
#
# @param label
# Item's displayed text
# @param checked
# Sets item checked if True
def AddItem(self, label, checked=False):
# Yield for progress dialog pulse updates
wx.GetApp().Yield()
# FIXME: Static lines are counted
item_index = self.GetItemCount()
#_logger.debug(GT("Lintian tag: {}; Set checked: {}").format(label, checked))
pnl_bg = GetField(self, pnlid.BACKGROUND)
lyt_bg = pnl_bg.GetSizer()
lyt_bg.Add(wx.CheckBox(pnl_bg, label=label), 1, wx.EXPAND)
lyt_bg.Add(wx.StaticLine(pnl_bg, style=wx.LI_HORIZONTAL), 0, wx.EXPAND)
if checked:
check_box = self.GetItem(item_index)
if isinstance(check_box, wx.CheckBox):
check_box.SetValue(True)
pnl_bg.Layout()
self.Layout()
## Adds multiple items to the list
#
# @param labels
# List of text labels to be displayed
# @param checked
# Sets items as checked if True
def AddItems(self, labels, checked=False):
for l in labels:
_logger.debug("Adding item: {} (checked={})".format(l, checked))
self.AddItem(l, checked)
## Sets all item states to 'unchecked'
def Clear(self):
changed = False
for CHK in self.GetAllItems():
if CHK.GetValue():
CHK.SetValue(False)
changed = True
if changed:
self.PostCheckBoxEvent()
## Retrieves all check boxes
#
# @return
# Tuple containing all children check box instances
def GetAllItems(self):
pnl_bg = GetField(self, pnlid.BACKGROUND)
items = []
for item in pnl_bg.GetChildren():
if isinstance(item, wx.CheckBox):
items.append(item)
return tuple(items)
## Retrieves all item labels
#
# @return
# Tuple of all check box labels
def GetAllLabels(self):
labels = []
for CHK in self.GetAllItems():
labels.append(CHK.GetLabel())
return tuple(labels)
## Retrieves number of items in list that set as 'checked'
def GetCheckedCount(self):
checked_count = 0
for CHK in self.GetAllItems():
if CHK.GetValue():
checked_count += 1
return checked_count
## Retrieves list of items that are set as 'checked'
def GetCheckedLabels(self):
checked_list = []
for CHK in self.GetAllItems():
if CHK.IsChecked():
label = CHK.GetLabel()
_logger.debug(GT("Retrieving checked label: {}").format(label))
checked_list.append(label)
return tuple(checked_list)
## Retrieves a single item
#
# @param index
# Retrieve item at index
# @return
# True if label is found
def GetItem(self, index):
return self.GetAllItems()[index]
## Retrieves an item using a label
#
# @param label
# Text label to search for
def GetItemByLabel(self, label):
labels = self.GetAllLabels()
if label in labels:
return self.GetItem(labels.index(label))
## Retrieves number of items in list
def GetItemCount(self):
return len(self.GetAllItems())
## Retrieves the checked state of an item
#
# @param index
# \b \e Integer index of of item to check
def GetValue(self, index):
return self.GetItem(index).GetValue()
## Retrieves the checked state of an item
#
# @param label
# Label whose value to get
# @return
# \b \e True if label's state is 'checked'
def GetValueByLabel(self, label):
item = self.GetItemByLabel(label)
if item:
return item.GetValue()
return False
## Checks if any item's state is 'checked'
#
# @return
# \b \e True if any item's state is 'checked'
def HasSelected(self):
for CHK in self.GetAllItems():
if CHK.GetValue():
return True
return False
## Check if an item's state is 'checked'
#
# @param label
# Label of item to check
def IsSelected(self, label):
return label in self.GetCheckedLabels()
## Checks if a label is in the list
#
# @param label
# Text label to search for
def LabelExists(self, label):
for LABEL in self.GetAllLabels():
if LABEL == label:
return True
return False
## Handles check box events
def OnCheckItem(self, event=None):
self.PostCheckBoxEvent()
## Propagates check box event to parent or target
#
# @param target
# \b \e wx.Window instance to post event to
def PostCheckBoxEvent(self, target=None):
if not target:
target = self.Parent
wx.PostEvent(target, wx.CommandEvent(wx.wxEVT_COMMAND_CHECKBOX_CLICKED, self.Id))
## @todo Doxygen
def ScrollToEnd(self):
pnl_bg = GetField(self, pnlid.BACKGROUND)
pnl_bg.SetScrollPos(wx.VERTICAL, pnl_bg.GetScrollLines(wx.VERTICAL))
pnl_bg.Refresh()
self.Refresh()
## @todo Define & Doxygen
def SetItemCheckedByLabel(self, label, checked=True):
# FIXME: Should use a more efficient method to index & retrieve items
for C in self.GetAllItems():
if C.GetLabel() == label:
C.SetValue(checked)
break
## Sets the 'checked' state of an item
#
# @param index
# \b \e Integer index of item to manipulate
# @param checked
# State to set item
def SetValue(self, index, checked):
return self.GetItem(index).SetValue(checked)
## @todo Doxygen
class CheckListDialog(wx.Dialog):
def __init__(self, parent, ID=wx.ID_ANY, title=wx.EmptyString, pos=wx.DefaultPosition,
size=wx.DefaultSize, style=wx.DEFAULT_DIALOG_STYLE, name=wx.DialogNameStr,
allow_custom=False):
wx.Dialog.__init__(self, parent, ID, title, pos, size, style=style|wx.RESIZE_BORDER,
name=name)
self.check_list = CheckList(self)
# *** Buttons *** #
layout_buttons = BoxSizer(wx.HORIZONTAL)
btn_clear = CreateButton(self, btnid.CLEAR)
btn_confirm = CreateButton(self, btnid.CONFIRM)
btn_cancel = CreateButton(self, btnid.CANCEL)
btn_clear.Bind(wx.EVT_BUTTON, self.OnClearList)
# FIXME: Correct button order?
layout_buttons.Add(btn_clear, 0, wx.LEFT, 5)
layout_buttons.AddStretchSpacer(1)
layout_buttons.Add(btn_confirm, 0, wx.RIGHT, 5)
layout_buttons.Add(btn_cancel, 0, wx.RIGHT, 5)
# *** Layout *** #
layout_main = BoxSizer(wx.VERTICAL)
layout_main.Add(self.check_list, 1, wx.EXPAND|wx.ALL, 5)
layout_main.Add(layout_buttons, 0, wx.EXPAND|wx.BOTTOM, 5)
if allow_custom:
btn_add_custom = wx.Button(self, label=GT("Add custom"))
btn_add_custom.Bind(wx.EVT_BUTTON, self.OnAddCustom)
self.input_add_custom = wx.TextCtrl(self)
layout_add_custom = BoxSizer(wx.HORIZONTAL)
layout_add_custom.Add(btn_add_custom, 0, lyt.PAD_LR, 5)
layout_add_custom.Add(self.input_add_custom, 1, wx.RIGHT, 5)
layout_main.Insert(1, layout_add_custom, 0, wx.EXPAND)
self.SetSizer(layout_main)
self.SetAutoLayout(True)
self.Layout()
self.CenterOnParent()
## @todo Doxygen
def AddItem(self, label, checked=False):
self.check_list.AddItem(label, checked)
## @todo Doxygen
def GetCheckedCount(self):
return self.check_list.GetCheckedCount()
## @todo Doxygen
def GetCheckedLabels(self):
return self.check_list.GetCheckedLabels()
## @todo Doxygen
def InitCheckList(self, labels, checked=False):
self.check_list.AddItems(labels, checked)
## @todo Doxygen
def OnAddCustom(self, event=None):
custom_label = strings.toString(self.input_add_custom.GetValue()).strip(" ").replace(" ", "_")
if not strings.isEmpty(custom_label) and not self.check_list.LabelExists(custom_label):
self.check_list.AddItem(custom_label, True)
self.check_list.ScrollToEnd()
## @todo Doxygen
def OnClearList(self, event=None):
if self.GetCheckedCount():
warn_dialog = wx.MessageDialog(self, GT("Clear Lintian overrides list?"), GT("Warning"),
style=wx.YES_NO|wx.NO_DEFAULT|wx.ICON_WARNING)
warn_dialog.CenterOnParent()
if warn_dialog.ShowModal() == wx.ID_YES:
self.check_list.Clear()
## @todo Doxygen
def SetItemCheckedByLabel(self, label, checked=True):
self.check_list.SetItemCheckedByLabel(label, checked)
## @todo Doxygen
def ShowModal(self):
# wx 2.8 doesn't automatically center on parent
if self.Parent:
self.CenterOnParent()
return wx.Dialog.ShowModal(self)