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