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