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 """Module containing the classes for GUI components involving spectral data."""
26
27
28 import wx
29 import wx.lib.buttons
30
31
32 from status import Status; status = Status()
33 from generic_fns.spectrum import replicated_flags, replicated_ids
34
35
36 from gui.components.menu import build_menu_item
37 from gui.fonts import font
38 from gui.misc import add_border, float_to_gui, gui_to_str, str_to_gui
39 from gui import paths
40 from gui.user_functions import User_functions; user_functions = User_functions()
41
42
44 """The GUI element for listing loaded spectral data."""
45
46 - def __init__(self, gui=None, parent=None, box=None, id=None, fn_add=None, buttons=True):
47 """Build the spectral list GUI element.
48
49 @keyword gui: The main GUI object.
50 @type gui: wx.Frame instance
51 @keyword parent: The parent GUI element that this is to be attached to (the panel object).
52 @type parent: wx object
53 @keyword data: The data storage container.
54 @type data: class instance
55 @keyword box: The vertical box sizer to pack this GUI component into.
56 @type box: wx.BoxSizer instance
57 @keyword id: A unique identification string. This is used to register the update method with the GUI user function observer object.
58 @type id: str
59 @keyword fn_add: The function to execute when clicking on the 'Add' button.
60 @type fn_add: func
61 @keyword buttons: A flag which if True will display the buttons at the top.
62 @type buttons: bool
63 """
64
65
66 self.gui = gui
67 self.parent = parent
68 self.fn_add = fn_add
69
70
71 self.spacing = 5
72 self.border = 5
73 self.height_buttons = 40
74
75
76 self.panel = wx.Panel(self.parent)
77 box.Add(self.panel, 0, wx.ALL|wx.EXPAND, 0)
78
79
80 panel_sizer = wx.BoxSizer(wx.VERTICAL)
81 self.panel.SetSizer(panel_sizer)
82
83
84 stat_box = wx.StaticBox(self.panel, -1, "Spectra list")
85 stat_box.SetFont(font.subtitle)
86 sub_sizer = wx.StaticBoxSizer(stat_box, wx.VERTICAL)
87
88
89 panel_sizer.Add(sub_sizer, 0, wx.ALL|wx.EXPAND, 0)
90
91
92 box_centre = add_border(sub_sizer, border=self.border)
93
94
95 if buttons:
96 self.add_buttons(box_centre)
97
98
99 box_centre.AddSpacer(self.spacing)
100 self.init_element(box_centre)
101
102
103 self.build_element()
104
105
106 self.name = 'spectra list: %s' % id
107
108
109 self.observer_register()
110
111
112 - def Enable(self, enable=True):
113 """Enable or disable the element.
114
115 @keyword enable: The flag specifying if the element should be enabled or disabled.
116 @type enable: bool
117 """
118
119
120 self.button_add.Enable(enable)
121 self.button_delete.Enable(enable)
122
123
152
153
155 """Build the spectra listing GUI element."""
156
157
158 if status.exec_lock.locked():
159 return
160
161
162 wx.CallAfter(self.build_element_safe)
163
164
166 """Build the spectra listing GUI element in a thread safe wx.CallAfter call."""
167
168
169 self.element.Freeze()
170
171
172 index = 1
173
174
175 self.element.DeleteAllItems()
176 self.element.DeleteAllColumns()
177
178
179 self.element.InsertColumn(0, str_to_gui("Spectrum ID string"))
180
181
182 n = 0
183 if hasattr(cdp, 'spectrum_ids'):
184
185 n = len(cdp.spectrum_ids)
186
187
188 for i in range(n):
189 self.element.InsertStringItem(i, str_to_gui(cdp.spectrum_ids[i]))
190
191
192 if self.noe_spectrum_type(index):
193 index += 1
194
195
196 if self.relax_times(index):
197 index += 1
198
199
200 if self.replicates(index):
201 index += 1
202
203
204 event = wx.PyCommandEvent(wx.EVT_SIZE.typeId, self.parent.GetId())
205 wx.PostEvent(self.parent.GetEventHandler(), event)
206
207
208 self.size_cols()
209
210
211 height = self.height_char * (n + 1) + 50
212 self.element.SetMinSize((-1, height))
213 self.element.Layout()
214
215
216 self.element.Thaw()
217
218
220 """Launch the spectrum.delete user function.
221
222 @param event: The wx event.
223 @type event: wx event
224 """
225
226
227 item = self.element.GetFirstSelected()
228
229
230 if item == -1:
231 id = None
232
233
234 else:
235
236 id = gui_to_str(self.element.GetItemText(item))
237
238
239 user_functions.spectrum.delete(spectrum_id=id)
240
241
247
248
250 """Initialise the GUI element for the spectra listing.
251
252 @param sizer: The sizer element to pack the element into.
253 @type sizer: wx.BoxSizer instance
254 """
255
256
257 self.element = wx.ListCtrl(self.panel, -1, style=wx.BORDER_SUNKEN|wx.LC_REPORT)
258
259
260 self.element.SetFont(font.normal)
261
262
263 self.height_char = self.element.GetCharHeight()
264
265
266 self.element.Bind(wx.EVT_SIZE, self.resize)
267 self.element.Bind(wx.EVT_COMMAND_RIGHT_CLICK, self.on_right_click)
268 self.element.Bind(wx.EVT_RIGHT_UP, self.on_right_click)
269
270
271 sizer.Add(self.element, 0, wx.ALL|wx.EXPAND, 0)
272
273
275 """Register and unregister methods with the observer objects.
276
277 @keyword remove: If set to True, then the methods will be unregistered.
278 @type remove: False
279 """
280
281
282 if not remove:
283 status.observers.gui_uf.register(self.name, self.build_element)
284
285
286 else:
287 status.observers.gui_uf.unregister(self.name)
288
289
291 """Pop up menu for the right click.
292
293 @param event: The wx event.
294 @type event: wx event
295 """
296
297
298 if status.exec_lock.locked():
299 return
300
301
302 if not hasattr(self, 'popup_id_del'):
303
304 self.popup_id_del = wx.NewId()
305
306
307 self.element.Bind(wx.EVT_MENU, self.data_delete, id=self.popup_id_del)
308
309
310 menu = wx.Menu()
311
312
313 menu.AppendItem(build_menu_item(menu, id=self.popup_id_del, text="&Delete", icon=paths.icon_16x16.remove))
314
315
316 self.element.PopupMenu(menu)
317 menu.Destroy()
318
319
321 """Catch the resize to allow the element to be resized.
322
323 @param event: The wx event.
324 @type event: wx event
325 """
326
327
328 self.size_cols()
329
330
331 event.Skip()
332
333
335 """Add the NOE spectral type info to the element.
336
337 @param index: The column index for the data.
338 @type index: int
339 @return: True if a spectrum type exists, False otherwise.
340 @rtype: bool
341 """
342
343
344 if not hasattr(cdp, 'spectrum_type') or not len(cdp.spectrum_type):
345 return False
346
347
348 self.element.InsertColumn(index, str_to_gui("NOE spectrum type"))
349
350
351 table = {
352 'sat': 'Saturated',
353 'ref': 'Reference'
354 }
355
356
357 for i in range(len(cdp.spectrum_ids)):
358
359 if cdp.spectrum_ids[i] not in cdp.spectrum_type.keys():
360 continue
361
362
363 self.element.SetStringItem(i, index, str_to_gui(table[cdp.spectrum_type[cdp.spectrum_ids[i]]]))
364
365
366 return True
367
368
370 """Add the relaxation delay time info to the element.
371
372 @param index: The column index for the data.
373 @type index: int
374 @return: True if relaxation times exist, False otherwise.
375 @rtype: bool
376 """
377
378
379 if not hasattr(cdp, 'relax_times') or not len(cdp.relax_times):
380 return False
381
382
383 self.element.InsertColumn(index, str_to_gui("Delay times"))
384
385
386 for i in range(len(cdp.spectrum_ids)):
387
388 if cdp.spectrum_ids[i] not in cdp.relax_times.keys():
389 continue
390
391
392 self.element.SetStringItem(i, index, float_to_gui(cdp.relax_times[cdp.spectrum_ids[i]]))
393
394
395 return True
396
397
399 """Add the replicated spectra info to the element.
400
401 @param index: The column index for the data.
402 @type index: int
403 @return: True if relaxation times exist, False otherwise.
404 @rtype: bool
405 """
406
407
408 if not hasattr(cdp, 'replicates') or not len(cdp.replicates):
409 return False
410
411
412 repl = replicated_flags()
413
414
415 self.element.InsertColumn(index, str_to_gui("Replicate IDs"))
416
417
418 for i in range(len(cdp.spectrum_ids)):
419
420 if not repl[cdp.spectrum_ids[i]]:
421 continue
422
423
424 id_list = replicated_ids(cdp.spectrum_ids[i])
425
426
427 text = ''
428 for j in range(len(id_list)):
429
430 text = "%s%s" % (text, id_list[j])
431
432
433 if j < len(id_list)-1:
434 text = "%s, " % text
435
436
437 self.element.SetStringItem(i, index, str_to_gui(text))
438
439
440 return True
441
442
444 """Set the column sizes."""
445
446
447 x, y = self.element.GetSize()
448
449
450 n = self.element.GetColumnCount()
451
452
453 if n == 0:
454 width = x
455 else:
456 width = int(x / n)
457
458
459 for i in range(n):
460 self.element.SetColumnWidth(i, width)
461