1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 """Module containing a set of special GUI elements to be used in the relax wizards."""
24
25
26 import wx
27 from wx.lib import scrolledpanel
28 import wx.lib.mixins.listctrl
29
30
31 from graphics import fetch_icon
32 from gui.filedialog import RelaxFileDialog
33 from gui.fonts import font
34 from gui.misc import add_border, open_file
35 from gui.string_conv import gui_to_list, gui_to_str, list_to_gui, str_to_gui
36 from lib.errors import RelaxError
37 from status import Status; status = Status()
38
39
41 """A single file element for the multiple file input GUI element."""
42
43 - def __init__(self, default='', parent=None, index=None, wildcard=wx.FileSelectorDefaultWildcardStr, style=wx.FD_DEFAULT_STYLE, padding=3, height_spacer=1, width_spacer=2, height_element=27, preview=True, can_be_none=False):
44 """Set up the file GUI element.
45
46 @keyword default: The default value of the element.
47 @type default: str
48 @keyword parent: The parent GUI element.
49 @type parent: wx.Panel instance
50 @keyword index: The index of the file element, to display its sequence number in the GUI element.
51 @type index: int
52 @keyword wildcard: The file wildcard pattern. For example for opening PDB files, this could be "PDB files (*.pdb)|*.pdb;*.PDB".
53 @type wildcard: String
54 @keyword style: The dialog style. To open a single file, set to wx.FD_OPEN. To open multiple files, set to wx.FD_OPEN|wx.FD_MULTIPLE. To save a single file, set to wx.FD_SAVE. To save multiple files, set to wx.FD_SAVE|wx.FD_MULTIPLE.
55 @type style: long
56 @keyword padding: Spacing to the left and right of the widgets.
57 @type padding: int
58 @keyword height_spacer: The amount of spacing to add below the field in pixels.
59 @type height_spacer: int
60 @keyword width_spacer: The amount of spacing to add horizontally between the TextCtrl and buttons in pixels.
61 @type width_spacer: int
62 @keyword height_element: The height in pixels of the GUI element.
63 @type height_element: int
64 @keyword preview: A flag which if true will allow the file to be previewed.
65 @type preview: bool
66 @keyword can_be_none: A flag which specifies if the element is allowed to have the None value.
67 @type can_be_none: bool
68 """
69
70
71 self.default = default
72 self.parent = parent
73 self.wildcard = wildcard
74 self.style = style
75 self.can_be_none = can_be_none
76
77
78 self.sizer = wx.BoxSizer(wx.VERTICAL)
79
80
81 sub_sizer = wx.BoxSizer(wx.HORIZONTAL)
82
83
84 sub_sizer.AddSpacer(padding)
85
86
87 desc = str_to_gui("%i: " % (index+1))
88 text = wx.StaticText(self.parent, -1, desc, style=wx.ALIGN_LEFT)
89 text.SetFont(font.normal_bold)
90 text.SetMinSize((35, -1))
91 sub_sizer.Add(text, 0, wx.LEFT|wx.ALIGN_CENTER_VERTICAL|wx.ADJUST_MINSIZE, 0)
92
93
94 sub_sizer.AddSpacer(width_spacer)
95
96
97 self.field = wx.TextCtrl(self.parent, -1, self.default)
98 self.field.SetMinSize((-1, height_element))
99 self.field.SetFont(font.normal)
100 sub_sizer.Add(self.field, 1, wx.EXPAND|wx.ADJUST_MINSIZE|wx.ALIGN_CENTER_VERTICAL, 0)
101
102
103 sub_sizer.AddSpacer(width_spacer)
104
105
106 button = wx.BitmapButton(self.parent, -1, wx.Bitmap(fetch_icon('oxygen.actions.document-open', "16x16"), wx.BITMAP_TYPE_ANY))
107 button.SetMinSize((height_element, height_element))
108 button.SetToolTipString("Select the file.")
109 sub_sizer.Add(button, 0, wx.ADJUST_MINSIZE|wx.ALIGN_CENTER_VERTICAL, 0)
110 self.parent.Bind(wx.EVT_BUTTON, self.select_file, button)
111
112
113 if preview:
114
115 sub_sizer.AddSpacer(width_spacer)
116
117
118 button = wx.BitmapButton(self.parent, -1, wx.Bitmap(fetch_icon('oxygen.actions.document-preview', "16x16"), wx.BITMAP_TYPE_ANY))
119 button.SetMinSize((height_element, height_element))
120 button.SetToolTipString("Preview")
121 sub_sizer.Add(button, 0, wx.ADJUST_MINSIZE|wx.ALIGN_CENTER_VERTICAL, 0)
122 self.parent.Bind(wx.EVT_BUTTON, self.preview_file, button)
123
124
125 sub_sizer.AddSpacer(padding)
126
127
128 self.sizer.Add(sub_sizer, 1, wx.ALL|wx.EXPAND, 0)
129
130
131 self.sizer.AddSpacer(height_spacer)
132
133
135 """Return the file name.
136
137 @return: The file name.
138 @rtype: str
139 """
140
141
142 return gui_to_str(self.field.GetValue())
143
144
146 """Set up the list of file.
147
148 @param value: The list of values to add to the list.
149 @type value: list of str or None
150 """
151
152
153 self.field.SetValue(str_to_gui(value))
154
155
157 """Preview a file.
158
159 @keyword event: The wx event.
160 @type event: wx event
161 """
162
163
164 file = gui_to_str(self.field.GetValue())
165
166
167 if file == None:
168 return
169
170
171 open_file(file, force_text=True)
172
173
175 """Select a file.
176
177 @keyword event: The wx event.
178 @type event: wx event
179 """
180
181
182 dialog = RelaxFileDialog(self.parent, field=self.field, message="File selection", defaultFile=self.default, wildcard=self.wildcard, style=self.style)
183
184
185 if status.show_gui:
186 dialog.select_event(event)
187
188
189
191 """Wizard GUI element for selecting files."""
192
193 - def __init__(self, name=None, default=None, parent=None, sizer=None, desc=None, message='File selection', wildcard=wx.FileSelectorDefaultWildcardStr, style=wx.FD_DEFAULT_STYLE, tooltip=None, divider=None, padding=0, spacer=None, height_element=27, preview=True, read_only=False):
194 """Build the file selection element.
195
196 @keyword name: The name of the element to use in titles, etc.
197 @type name: str
198 @keyword default: The default value of the element.
199 @type default: str
200 @keyword parent: The wizard GUI element.
201 @type parent: wx.Panel instance
202 @keyword sizer: The sizer to put the input field into.
203 @type sizer: wx.Sizer instance
204 @keyword desc: The text description.
205 @type desc: str
206 @keyword message: The file selector prompt string.
207 @type message: String
208 @keyword wildcard: The file wildcard pattern. For example for opening PDB files, this could be "PDB files (*.pdb)|*.pdb;*.PDB".
209 @type wildcard: String
210 @keyword style: The dialog style. To open a single file, set to wx.FD_OPEN. To open multiple files, set to wx.FD_OPEN|wx.FD_MULTIPLE. To save a single file, set to wx.FD_SAVE. To save multiple files, set to wx.FD_SAVE|wx.FD_MULTIPLE.
211 @type style: long
212 @keyword tooltip: The tooltip which appears on hovering over all the GUI elements.
213 @type tooltip: str
214 @keyword divider: The position of the divider.
215 @type divider: int
216 @keyword padding: Spacing to the left and right of the widgets.
217 @type padding: int
218 @keyword spacer: The amount of spacing to add below the field in pixels. If None, a stretchable spacer will be used.
219 @type spacer: None or int
220 @keyword height_element: The height in pixels of the GUI element.
221 @type height_element: int
222 @keyword preview: A flag which if true will allow the file to be previewed.
223 @type preview: bool
224 @keyword read_only: A flag which if True means that the text of the element cannot be edited.
225 @type read_only: bool
226 """
227
228
229 self.name = name
230
231
232 if default == None:
233 default = wx.EmptyString
234
235
236 sub_sizer = wx.BoxSizer(wx.HORIZONTAL)
237
238
239 sub_sizer.AddSpacer(padding)
240
241
242 text = wx.StaticText(parent, -1, desc, style=wx.ALIGN_LEFT)
243 text.SetFont(font.normal)
244 sub_sizer.Add(text, 0, wx.LEFT|wx.ALIGN_CENTER_VERTICAL, 0)
245
246
247 if not divider:
248 raise RelaxError("The divider position has not been supplied.")
249
250
251 x, y = text.GetSize()
252 sub_sizer.AddSpacer((divider - x, 0))
253
254
255 self._field = wx.TextCtrl(parent, -1, default)
256 self._field.SetMinSize((-1, height_element))
257 self._field.SetFont(font.normal)
258 sub_sizer.Add(self._field, 1, wx.ADJUST_MINSIZE|wx.ALIGN_CENTER_VERTICAL, 0)
259
260
261 obj = RelaxFileDialog(parent, field=self._field, message=message, defaultFile=default, wildcard=wildcard, style=style)
262
263
264 sub_sizer.AddSpacer(5)
265
266
267 button = wx.BitmapButton(parent, -1, wx.Bitmap(fetch_icon('oxygen.actions.document-open', "16x16"), wx.BITMAP_TYPE_ANY))
268 button.SetMinSize((height_element, height_element))
269 button.SetToolTipString("Select the file.")
270 sub_sizer.Add(button, 0, wx.ADJUST_MINSIZE|wx.ALIGN_CENTER_VERTICAL, 0)
271 parent.Bind(wx.EVT_BUTTON, obj.select_event, button)
272
273
274 if preview:
275
276 sub_sizer.AddSpacer(5)
277
278
279 button = wx.BitmapButton(parent, -1, wx.Bitmap(fetch_icon('oxygen.actions.document-preview', "16x16"), wx.BITMAP_TYPE_ANY))
280 button.SetMinSize((height_element, height_element))
281 button.SetToolTipString("Preview")
282 sub_sizer.Add(button, 0, wx.ADJUST_MINSIZE|wx.ALIGN_CENTER_VERTICAL, 0)
283 parent.Bind(wx.EVT_BUTTON, self.preview_file, button)
284
285
286 sub_sizer.AddSpacer(padding)
287
288
289 sizer.Add(sub_sizer, 1, wx.EXPAND|wx.ALL, 0)
290
291
292 if spacer == None:
293 sizer.AddStretchSpacer()
294 else:
295 sizer.AddSpacer(spacer)
296
297
298 if tooltip:
299 text.SetToolTipString(tooltip)
300 self._field.SetToolTipString(tooltip)
301
302
304 """Special method for clearing or resetting the GUI element."""
305
306
307 self._field.Clear()
308
309
311 """Special method for returning the value of the GUI element.
312
313 @return: The string value.
314 @rtype: list of str
315 """
316
317
318 return gui_to_str(self._field.GetValue())
319
320
322 """Special method for setting the value of the GUI element.
323
324 @param value: The value to set.
325 @type value: str
326 """
327
328
329 self._field.SetValue(str_to_gui(value))
330
331
333 """Preview a file.
334
335 @keyword event: The wx event.
336 @type event: wx event
337 """
338
339
340 file = gui_to_str(self._field.GetValue())
341
342
343 if file == None:
344 return
345
346
347 open_file(file, force_text=True)
348
349
350
352 """Wizard GUI element for selecting files."""
353
354 - def __init__(self, name=None, default=None, parent=None, sizer=None, desc=None, message='File selection', wildcard=wx.FileSelectorDefaultWildcardStr, style=wx.FD_DEFAULT_STYLE, tooltip=None, divider=None, padding=0, spacer=None, height_element=27, preview=True, read_only=False, can_be_none=False):
355 """Build the file selection element.
356
357 @keyword name: The name of the element to use in titles, etc.
358 @type name: str
359 @keyword default: The default value of the element.
360 @type default: str
361 @keyword parent: The wizard GUI element.
362 @type parent: wx.Panel instance
363 @keyword sizer: The sizer to put the input field into.
364 @type sizer: wx.Sizer instance
365 @keyword desc: The text description.
366 @type desc: str
367 @keyword message: The file selector prompt string.
368 @type message: String
369 @keyword wildcard: The file wildcard pattern. For example for opening PDB files, this could be "PDB files (*.pdb)|*.pdb;*.PDB".
370 @type wildcard: String
371 @keyword style: The dialog style. To open a single file, set to wx.FD_OPEN. To open multiple files, set to wx.FD_OPEN|wx.FD_MULTIPLE. To save a single file, set to wx.FD_SAVE. To save multiple files, set to wx.FD_SAVE|wx.FD_MULTIPLE.
372 @type style: long
373 @keyword tooltip: The tooltip which appears on hovering over all the GUI elements.
374 @type tooltip: str
375 @keyword divider: The position of the divider.
376 @type divider: int
377 @keyword padding: Spacing to the left and right of the widgets.
378 @type padding: int
379 @keyword spacer: The amount of spacing to add below the field in pixels. If None, a stretchable spacer will be used.
380 @type spacer: None or int
381 @keyword height_element: The height in pixels of the GUI element.
382 @type height_element: int
383 @keyword preview: A flag which if true will allow the file to be previewed.
384 @type preview: bool
385 @keyword read_only: A flag which if True means that the text of the element cannot be edited.
386 @type read_only: bool
387 @keyword can_be_none: A flag which specifies if the element is allowed to have the None value.
388 @type can_be_none: bool
389 """
390
391
392 self.name = name
393 self.parent = parent
394 self.can_be_none = can_be_none
395
396
397 if default == None:
398 default = wx.EmptyString
399
400
401 sub_sizer = wx.BoxSizer(wx.HORIZONTAL)
402
403
404 sub_sizer.AddSpacer(padding)
405
406
407 text = wx.StaticText(parent, -1, desc, style=wx.ALIGN_LEFT)
408 text.SetFont(font.normal)
409 sub_sizer.Add(text, 0, wx.LEFT|wx.ALIGN_CENTER_VERTICAL, 0)
410
411
412 if not divider:
413 raise RelaxError("The divider position has not been supplied.")
414
415
416 x, y = text.GetSize()
417 sub_sizer.AddSpacer((divider - x, 0))
418
419
420 self._field = wx.TextCtrl(parent, -1, default)
421 self._field.SetMinSize((-1, height_element))
422 self._field.SetFont(font.normal)
423 sub_sizer.Add(self._field, 1, wx.ADJUST_MINSIZE|wx.ALIGN_CENTER_VERTICAL, 0)
424
425
426 obj = RelaxFileDialog(parent, field=self._field, message=message, defaultFile=default, wildcard=wildcard, style=style)
427
428
429 sub_sizer.AddSpacer(5)
430
431
432 button = wx.BitmapButton(parent, -1, wx.Bitmap(fetch_icon('oxygen.actions.document-open', "16x16"), wx.BITMAP_TYPE_ANY))
433 button.SetMinSize((height_element, height_element))
434 button.SetToolTipString("Choose the file(s).")
435 sub_sizer.Add(button, 0, wx.ADJUST_MINSIZE|wx.ALIGN_CENTER_VERTICAL, 0)
436 parent.Bind(wx.EVT_BUTTON, self.open_dialog, button)
437
438
439 sub_sizer.AddSpacer(padding)
440
441
442 sizer.Add(sub_sizer, 1, wx.EXPAND|wx.ALL, 0)
443
444
445 if spacer == None:
446 sizer.AddStretchSpacer()
447 else:
448 sizer.AddSpacer(spacer)
449
450
451 if tooltip:
452 text.SetToolTipString(tooltip)
453 self._field.SetToolTipString(tooltip)
454
455
457 """Special method for clearing or resetting the GUI element."""
458
459
460 self._field.Clear()
461
462
510
511
513 """Special method for setting the value of the GUI element.
514
515 @param value: The value to set.
516 @type value: str
517 """
518
519
520 if isinstance(value, list) and len(value) == 1:
521 value = value[0]
522
523
524 self._field.SetValue(list_to_gui(value))
525
526
528 """Open a special dialog for inputting a list of text values.
529
530 @param event: The wx event.
531 @type event: wx event
532 """
533
534
535 self.selection_win_show()
536
537
538 self.selection_win_data()
539
540
541 del self.sel_win
542
543
545 """Preview a file.
546
547 @keyword event: The wx event.
548 @type event: wx event
549 """
550
551
552 file = gui_to_str(self._field.GetValue())
553
554
555 if file == None:
556 return
557
558
559 open_file(file, force_text=True)
560
561
563 """Extract the data from the file list selection window."""
564
565
566 value = self.sel_win.GetValue()
567
568
569 if not len(value):
570 self.Clear()
571
572
573 else:
574 self.SetValue(value)
575
576
590
591
592
594 """The file list selection window."""
595
596
597 SIZE = (800, 600)
598
599
600 BORDER = 10
601
602
603 SIZE_BUTTON = (150, 33)
604
605 - def __init__(self, parent=None, name='', spacing=10):
606 """Set up the file list selection window.
607
608 @keyword parent: The parent GUI element.
609 @type parent: wx.Window instance or None
610 @keyword name: The name of the window.
611 @type name: str
612 @keyword spacing: The spacing between elements in pixels.
613 @type spacing: int
614 """
615
616
617 self.name = name
618 self.spacing = spacing
619
620
621 title = "Multiple %s selection." % name
622
623
624 wx.Dialog.__init__(self, parent, id=-1, title=title)
625
626
627 self.width = self.SIZE[0] - 2*self.BORDER
628
629
630 self.SetSize(self.SIZE)
631 self.Centre()
632 self.SetFont(font.normal)
633
634
635 main_sizer = wx.BoxSizer(wx.VERTICAL)
636
637
638 self.SetSizer(main_sizer)
639
640
641 sizer = add_border(main_sizer, border=self.BORDER, packing=wx.VERTICAL)
642
643
644 self.add_file_list(sizer)
645
646
647 sizer.AddSpacer(self.BORDER)
648
649
650 self.add_buttons(sizer)
651
652
653 self.elements = []
654 self.add_element()
655
656
658 """Return the file names as a list.
659
660 @return: The list of file names.
661 @rtype: list of str
662 """
663
664
665 values = []
666
667
668 for i in range(len(self.elements)):
669 values.append(self.elements[i].GetValue())
670
671
672 return values
673
674
676 """Set up the list of file names.
677
678 @param values: The list of file names to add.
679 @type values: list of str or None
680 """
681
682
683 if values == None:
684 return
685
686
687 if isinstance(values, str):
688 values = [values]
689
690
691 self.delete_all()
692
693
694 for i in range(len(values)):
695
696 if i == 0:
697 self.elements[0].SetValue(values[i])
698
699
700 else:
701 self.add_element(path=values[i])
702
703
758
759
761 """Add a new file selection element to the list.
762
763 @keyword event: The wx event.
764 @type event: wx event
765 @keyword path: The file path to set the element value to.
766 @type path: str or None
767 """
768
769
770 element = File_element(parent=self.panel, index=len(self.elements))
771
772
773 if path != None:
774 element.SetValue(path)
775
776
777 self.element_sizer.Add(element.sizer, 0, wx.ALL|wx.EXPAND, 0)
778
779
780 self.elements.append(element)
781
782
783 self.panel.SetupScrolling(scroll_x=False, scroll_y=True)
784
785
786 self.panel.Layout()
787
788
790 """Initialise the control.
791
792 @param sizer: A sizer object.
793 @type sizer: wx.Sizer instance
794 """
795
796
797 self.panel = scrolledpanel.ScrolledPanel(self, -1, name="file list")
798
799
800 panel_sizer = wx.BoxSizer(wx.VERTICAL)
801
802
803 title = "File list"
804 text = wx.StaticText(self.panel, -1, title, style=wx.TE_MULTILINE)
805 text.SetFont(font.subtitle)
806 panel_sizer.Add(text, 0, wx.ALIGN_LEFT, 0)
807 panel_sizer.AddSpacer(self.spacing)
808
809
810 self.element_sizer = wx.BoxSizer(wx.VERTICAL)
811 panel_sizer.Add(self.element_sizer, 1, wx.ALL|wx.EXPAND, 0)
812
813
814 self.panel.SetSizer(panel_sizer)
815 self.panel.SetAutoLayout(1)
816 self.panel.SetupScrolling(scroll_x=False, scroll_y=True)
817 sizer.Add(self.panel, 1, wx.ALL|wx.EXPAND, 0)
818
819
821 """Close the window.
822
823 @param event: The wx event.
824 @type event: wx event
825 """
826
827
828 self.Close()
829
830
831 - def delete(self, event=None):
832 """Remove the last file selection item from the list.
833
834 @keyword event: The wx event.
835 @type event: wx event
836 """
837
838
839 self.elements[-1].sizer.DeleteWindows()
840 self.element_sizer.Remove(self.elements[-1].sizer)
841
842
843 self.elements.pop()
844
845
846 if not len(self.elements):
847 self.add_element()
848
849
850 self.panel.Layout()
851
852
854 """Remove all file selection items from the list.
855
856 @keyword event: The wx event.
857 @type event: wx event
858 """
859
860
861 for i in range(len(self.elements)):
862 self.elements[i].sizer.DeleteWindows()
863 self.element_sizer.Remove(self.elements[i].sizer)
864
865
866 del self.elements
867
868
869 self.elements = []
870 self.add_element()
871
872
873 self.panel.Layout()
874