source: sasview/src/sas/sasgui/perspectives/calculator/sample_editor.py @ bacc04b

Last change on this file since bacc04b was d85c194, checked in by Piotr Rozyczko <piotr.rozyczko@…>, 9 years ago

Remaining modules refactored

  • Property mode set to 100644
File size: 24.8 KB
Line 
1
2import wx
3import sys
4from copy import deepcopy
5from sas.sasgui.guiframe.utils import check_float
6
7_BOX_WIDTH = 60
8if sys.platform.count("win32") > 0:
9    _STATICBOX_WIDTH = 450
10    PANEL_WIDTH = 500
11    PANEL_HEIGHT = 430
12    FONT_VARIANT = 0
13else:
14    _STATICBOX_WIDTH = 480
15    PANEL_WIDTH = 550
16    PANEL_HEIGHT = 430
17    FONT_VARIANT = 1
18
19class SampleDialog(wx.Dialog):
20    def __init__(self, parent=None, manager=None, sample=None,
21                 size=(PANEL_WIDTH, PANEL_HEIGHT), title='Sample Editor'):
22
23        wx.Dialog.__init__(self, parent=parent, size=size, title=title)
24        self.parent = parent
25        self.manager = manager
26        self._sample = sample
27        self._reset_sample = deepcopy(sample)
28        self._notes = ""
29        self._description = "Edit Sample"
30        self._do_layout()
31        self.set_values()
32
33    def _define_structure(self):
34        """
35            define initial sizer
36        """
37        self.main_sizer = wx.BoxSizer(wx.VERTICAL)
38        self.box_sample = wx.StaticBox(self, -1, str("Sample"))
39        self.boxsizer_sample = wx.StaticBoxSizer(self.box_sample,
40                                                    wx.VERTICAL)
41        self.name_sizer = wx.BoxSizer(wx.HORIZONTAL)
42        self.id_sizer = wx.BoxSizer(wx.HORIZONTAL)
43        self.thickness_sizer = wx.BoxSizer(wx.HORIZONTAL)
44        self.transmission_sizer = wx.BoxSizer(wx.HORIZONTAL)
45        self.temperature_sizer = wx.BoxSizer(wx.HORIZONTAL)
46        self.position_sizer = wx.BoxSizer(wx.HORIZONTAL)
47        self.orientation_sizer = wx.BoxSizer(wx.HORIZONTAL)
48        self.details_sizer = wx.BoxSizer(wx.HORIZONTAL)
49        self.button_sizer = wx.BoxSizer(wx.HORIZONTAL)
50
51    def _layout_name(self):
52        """
53            Do the layout for sample name related widgets
54        """
55        ## Short name for sample [string]
56        sample_name_txt = wx.StaticText(self, -1, 'Sample Name : ')
57        self.sample_name_tcl = wx.TextCtrl(self, -1,
58                                            size=(_BOX_WIDTH * 5, 20), style=0)
59        self.name_sizer.AddMany([(sample_name_txt, 0, wx.LEFT | wx.RIGHT, 10),
60                                       (self.sample_name_tcl, 0, wx.EXPAND)])
61    def _layout_id(self):
62        """
63            Do the layout for id related widgets
64        """
65        ## ID [String]
66        id_txt = wx.StaticText(self, -1, 'ID: ')
67        self.id_tcl = wx.TextCtrl(self, -1, size=(_BOX_WIDTH, 20), style=0)
68        self.id_sizer.AddMany([(id_txt, 0, wx.LEFT | wx.RIGHT, 10),
69                                     (self.id_tcl, 0, wx.LEFT, 55)])
70
71    def _layout_thickness(self):
72        """
73            Do the  layout for thickness related widgets
74        """
75        ## Thickness [float] [mm]
76        thickness_txt = wx.StaticText(self, -1, 'Thickness:')
77        self.thickness_tcl = wx.TextCtrl(self, -1,
78                                          size=(_BOX_WIDTH, 20), style=0)
79        thickness_unit_txt = wx.StaticText(self, -1, 'Unit: ')
80        self.thickness_unit_tcl = wx.TextCtrl(self, -1, size=(_BOX_WIDTH, 20),
81                                              style=0)
82        self.thickness_sizer.AddMany([(thickness_txt, 0, wx.LEFT | wx.RIGHT, 10),
83                                     (self.thickness_tcl, 0, wx.LEFT, 25),
84                            (thickness_unit_txt, 0, wx.LEFT | wx.RIGHT, 10),
85                                     (self.thickness_unit_tcl, 0, wx.EXPAND)])
86    def _layout_transmission(self):
87        """
88            Do the  layout for transmission related widgets
89        """
90        ## Transmission [float] [fraction]
91        transmission = None
92        transmission_txt = wx.StaticText(self, -1, 'Transmission:')
93        self.transmission_tcl = wx.TextCtrl(self, -1,
94                                             size=(_BOX_WIDTH, 20), style=0)
95        self.transmission_sizer.AddMany([(transmission_txt,
96                                         0, wx.LEFT | wx.RIGHT, 10),
97                                     (self.transmission_tcl, 0, wx.LEFT, 12)])
98
99    def _layout_temperature(self):
100        """
101            Do the  layout for temperature related widgets
102        """
103        ## Temperature [float] [C]
104        temperature_txt = wx.StaticText(self, -1, 'Temperature:')
105        self.temperature_tcl = wx.TextCtrl(self, -1,
106                                           size=(_BOX_WIDTH, 20), style=0)
107        temperature_unit_txt = wx.StaticText(self, -1, 'Unit: ')
108        self.temperature_unit_tcl = wx.TextCtrl(self, -1, size=(_BOX_WIDTH, 20),
109                                                            style=0)
110        self.temperature_sizer.AddMany([(temperature_txt, 0,
111                                          wx.LEFT | wx.RIGHT, 10),
112                                     (self.temperature_tcl, 0, wx.LEFT, 10),
113                                (temperature_unit_txt, 0, wx.LEFT | wx.RIGHT, 10),
114                                     (self.temperature_unit_tcl, 0, wx.EXPAND)])
115
116    def _layout_position(self):
117        """
118            Do the  layout for position related widgets
119        """
120        ## Position [Vector] [mm]
121        position_txt = wx.StaticText(self, -1, 'Position:')
122        x_position_txt = wx.StaticText(self, -1, 'x = ')
123        self.x_position_tcl = wx.TextCtrl(self, -1,
124                                           size=(_BOX_WIDTH, 20), style=0)
125        y_position_txt = wx.StaticText(self, -1, 'y = ')
126        self.y_position_tcl = wx.TextCtrl(self, -1,
127                                           size=(_BOX_WIDTH, 20), style=0)
128        z_position_txt = wx.StaticText(self, -1, 'z = ')
129        self.z_position_tcl = wx.TextCtrl(self, -1,
130                                           size=(_BOX_WIDTH, 20), style=0)
131        position_unit_txt = wx.StaticText(self, -1, 'Unit: ')
132        self.position_unit_tcl = wx.TextCtrl(self, -1,
133                                             size=(_BOX_WIDTH, 20), style=0)
134        self.position_sizer.AddMany([(position_txt, 0, wx.LEFT | wx.RIGHT, 10),
135                                     (x_position_txt, 0, wx.LEFT, 14),
136                                     (self.x_position_tcl, 0, wx.RIGHT, 10),
137                                     (y_position_txt, 0, wx.EXPAND),
138                                     (self.y_position_tcl, 0, wx.RIGHT, 10),
139                                     (z_position_txt, 0, wx.EXPAND),
140                                     (self.z_position_tcl, 0, wx.RIGHT, 10),
141                                     (position_unit_txt, 0, wx.EXPAND),
142                                     (self.position_unit_tcl, 0, wx.RIGHT, 10)])
143    def _layout_orientation(self):
144        """
145            Do the  layout for orientation related widgets
146        """
147        ## Orientation [Vector] [degrees]
148        orientation_txt = wx.StaticText(self, -1, 'Orientation:')
149        x_orientation_txt = wx.StaticText(self, -1, 'x = ')
150        self.x_orientation_tcl = wx.TextCtrl(self, -1,
151                                              size=(_BOX_WIDTH, 20), style=0)
152        y_orientation_txt = wx.StaticText(self, -1, 'y = ')
153        self.y_orientation_tcl = wx.TextCtrl(self, -1,
154                                              size=(_BOX_WIDTH, 20), style=0)
155        z_orientation_txt = wx.StaticText(self, -1, 'z = ')
156        self.z_orientation_tcl = wx.TextCtrl(self, -1,
157                                              size=(_BOX_WIDTH, 20), style=0)
158        orientation_unit_txt = wx.StaticText(self, -1, 'Unit: ')
159        self.orientation_unit_tcl = wx.TextCtrl(self, -1,
160                                                 size=(_BOX_WIDTH, 20), style=0)
161        self.orientation_sizer.AddMany([(orientation_txt, 0,
162                                          wx.LEFT | wx.RIGHT, 10),
163                                     (x_orientation_txt, 0, wx.LEFT, 0),
164                                     (self.x_orientation_tcl, 0, wx.RIGHT, 10),
165                                     (y_orientation_txt, 0, wx.EXPAND),
166                                     (self.y_orientation_tcl, 0, wx.RIGHT, 10),
167                                     (z_orientation_txt, 0, wx.EXPAND),
168                                     (self.z_orientation_tcl, 0, wx.RIGHT, 10),
169                                     (orientation_unit_txt, 0, wx.EXPAND),
170                            (self.orientation_unit_tcl, 0, wx.RIGHT, 10)])
171
172    def _layout_details(self):
173        """
174            Do the layout for beam size name related widgets
175        """
176        ## Details
177        details = None
178        details_txt = wx.StaticText(self, -1, 'Details: ')
179        self.details_tcl = wx.TextCtrl(self, -1, size=(_BOX_WIDTH * 5, _BOX_WIDTH),
180                                       style=wx.TE_MULTILINE | wx.HSCROLL)
181        self.details_sizer.AddMany([(details_txt, 0, wx.LEFT | wx.RIGHT, 10),
182                                       (self.details_tcl, 0, wx.EXPAND)])
183
184    def _layout_button(self):
185        """
186            Do the layout for the button widgets
187        """
188        self.bt_apply = wx.Button(self, -1, 'Apply')
189        self.bt_apply.Bind(wx.EVT_BUTTON, self.on_click_apply)
190        self.bt_apply.SetToolTipString("Apply current changes to the sample.")
191        self.bt_cancel = wx.Button(self, -1, 'Cancel')
192        self.bt_cancel.SetToolTipString("Cancel current changes.")
193        self.bt_cancel.Bind(wx.EVT_BUTTON, self.on_click_cancel)
194        self.bt_close = wx.Button(self, wx.ID_CANCEL, 'Close')
195        self.bt_close.SetToolTipString("Close window.")
196        self.button_sizer.AddMany([(self.bt_apply, 0, wx.LEFT, 200),
197                                   (self.bt_cancel, 0, wx.LEFT, 10),
198                                   (self.bt_close, 0, wx.LEFT, 10)])
199
200    def _do_layout(self, data=None):
201        """
202             Draw the current panel
203        """
204        self._define_structure()
205        self._layout_name()
206        self._layout_id()
207        self._layout_thickness()
208        self._layout_transmission()
209        self._layout_temperature()
210        self._layout_position()
211        self._layout_orientation()
212        self._layout_details()
213        self._layout_button()
214        self.boxsizer_sample.AddMany([(self.name_sizer, 0,
215                                          wx.EXPAND | wx.TOP | wx.BOTTOM, 5),
216                                   (self.id_sizer, 0,
217                                     wx.EXPAND | wx.TOP | wx.BOTTOM, 5),
218                                   (self.thickness_sizer, 0,
219                                     wx.EXPAND | wx.TOP | wx.BOTTOM, 5),
220                                   (self.transmission_sizer, 0,
221                                    wx.EXPAND | wx.TOP | wx.BOTTOM, 5),
222                                   (self.temperature_sizer, 0,
223                                    wx.EXPAND | wx.TOP | wx.BOTTOM, 5),
224                                   (self.position_sizer, 0,
225                                    wx.EXPAND | wx.TOP | wx.BOTTOM, 5),
226                                    (self.orientation_sizer, 0,
227                                    wx.EXPAND | wx.TOP | wx.BOTTOM, 5),
228                                   (self.details_sizer, 0,
229                                     wx.EXPAND | wx.TOP | wx.BOTTOM, 5)])
230        self.main_sizer.AddMany([(self.boxsizer_sample, 0, wx.ALL, 10),
231                                  (self.button_sizer, 0,
232                                    wx.EXPAND | wx.TOP | wx.BOTTOM, 5)])
233
234        self.SetSizer(self.main_sizer)
235        self.SetAutoLayout(True)
236
237    def reset_sample(self):
238        """
239            Put initial values of the sample back to the current sample
240        """
241        self._sample.name = self._reset_sample.name
242        self._sample.ID = self._reset_sample.ID
243        self._sample.thickness = self._reset_sample.thickness
244        self._sample.thickness_unit = self._reset_sample.thickness_unit
245        self._sample.transmission = self._reset_sample.transmission
246        self._sample.temperature = self._reset_sample.temperature
247        self._sample.temperature_unit = self._reset_sample.temperature_unit
248
249        self._sample.position.x = self._reset_sample.position.x
250        self._sample.position.y = self._reset_sample.position.y
251        self._sample.position.z = self._reset_sample.position.x
252        self._sample.position_unit = self._reset_sample.position_unit
253
254        self._sample.orientation.x = self._reset_sample.orientation.x
255        self._sample.orientation.y = self._reset_sample.orientation.y
256        self._sample.orientation.z = self._reset_sample.orientation.x
257        self._sample.orientation_unit = self._reset_sample.orientation_unit
258
259        self._sample.details = self._reset_sample.details
260
261    def set_manager(self, manager):
262        """
263            Set manager of this window
264        """
265        self.manager = manager
266
267    def set_values(self):
268        """
269            take the sample values of the current data and display them
270            through the panel
271        """
272        sample = self._sample
273        #Name
274        self.sample_name_tcl.SetValue(str(sample.name))
275        #id
276        self.id_tcl.SetValue(str(sample.ID))
277        #thickness
278        self.thickness_tcl.SetValue(str(sample.thickness))
279        self.thickness_unit_tcl.SetValue(str(sample.thickness_unit))
280        #transmission
281        self.transmission_tcl.SetValue(str(sample.transmission))
282        #temperature
283        self.temperature_tcl.SetValue(str(sample.temperature))
284        self.temperature_unit_tcl.SetValue(str(sample.temperature_unit))
285        #position
286        x, y, z = sample.position.x, sample.position.y , sample.position.z
287        self.x_position_tcl.SetValue(str(x))
288        self.y_position_tcl.SetValue(str(y))
289        self.z_position_tcl.SetValue(str(z))
290        self.position_unit_tcl.SetValue(str(sample.position_unit))
291        #orientation
292        x, y = sample.orientation.x, sample.orientation.y
293        z = sample.orientation.z
294        self.x_orientation_tcl.SetValue(str(x))
295        self.y_orientation_tcl.SetValue(str(y))
296        self.z_orientation_tcl.SetValue(str(z))
297        self.orientation_unit_tcl.SetValue(str(sample.orientation_unit))
298
299        self.set_details(sample)
300
301    def set_details(self, sample):
302        """
303            print details on the current sample
304        """
305        #detail
306        msg = ''
307        if sample.details is not None or sample.details:
308            for item in sample.details:
309                msg += "      %s\n" % item
310        self.details_tcl.SetValue(str(msg))
311
312    def get_sample(self):
313        """
314            return the current sample
315        """
316        return self._sample
317
318    def get_notes(self):
319        """
320            return notes
321        """
322        return self._notes
323
324    def on_change_name(self):
325        """
326            Change name
327        """
328        #Change the name of the sample
329        name = self.sample_name_tcl.GetValue().lstrip().rstrip()
330        if name == "" or name == str(None):
331            name = None
332        if self._sample.name != name:
333            self._notes += "Change sample 's "
334            self._notes += "name from %s to %s \n" % (self._sample.name, name)
335            self._sample.name = name
336
337    def on_change_id(self):
338        """
339            Change id of the sample
340        """
341        #Change id
342        id = self.id_tcl.GetValue().lstrip().rstrip()
343        self._sample.ID = id
344        self._notes += " Change ID from"
345        self._notes += " %s to %s \n" % (self._sample.ID, id)
346
347    def on_change_thickness(self):
348        """
349            Change thickness
350        """
351       #Change thickness
352        thickness = self.thickness_tcl.GetValue().lstrip().rstrip()
353        self._sample.thickness = thickness
354        self._notes += " Change thickness from"
355        self._notes += " %s to %s \n" % (self._sample.thickness, thickness)
356
357    def on_change_transmission(self):
358        """
359            Change transmission
360        """
361        #Change transmission
362        transmission = self.transmission_tcl.GetValue().lstrip().rstrip()
363        if self._sample.transmission != transmission:
364            self._notes += " Change transmission from"
365            self._notes += " %s to %s \n" % (self._sample.transmission,
366                                              transmission)
367            self._sample.transmission = transmission
368
369    def on_change_temperature(self):
370        """
371            Change temperature
372        """
373        #Change temperature
374        temperature = self.temperature_tcl.GetValue().lstrip().rstrip()
375        self._sample.temperature = temperature
376        self._notes += " Change temperature from"
377        self._notes += " %s to %s \n" % (self._sample.temperature, temperature)
378        #change temperature unit
379        unit = self.temperature_unit_tcl.GetValue().lstrip().rstrip()
380        if self._sample.temperature_unit != unit:
381            self._notes += " Change temperature's unit from "
382            self._notes += "%s to %s" % (self._sample.temperature_unit, unit)
383            self._sample.temperature_unit = unit
384
385    def on_change_position(self):
386        """
387            Change position
388        """
389        #Change x coordinate
390        x_position = self.x_position_tcl.GetValue().lstrip().rstrip()
391        if x_position == "" or x_position == str(None):
392            x_position = None
393        else:
394            if check_float(self.x_position_tcl):
395                if self._sample.position.x != float(x_position) :
396                    self._notes += "Change x of position from "
397                    self._notes += "%s to %s \n" % (self._sample.position.x,
398                                                     x_position)
399                    self._sample.position.x = float(x_position)
400            else:
401                self._notes += "Error: Expected a float for the position 's x "
402                self._notes += "won't changes x position from "
403                self._notes += "%s to %s" % (self._sample.position.x, x_position)
404        #Change y coordinate
405        y_position = self.y_position_tcl.GetValue().lstrip().rstrip()
406        if y_position == "" or y_position == str(None):
407            y_position = None
408            self._sample.position.y = y_position
409        else:
410            if check_float(self.y_position_tcl):
411                if self._sample.position.y != float(y_position):
412                    self._notes += "Change y of position from "
413                    self._notes += "%s to %s \n" % (self._sample.position.y,
414                                                    y_position)
415                    self._sample.position.y = float(y_position)
416            else:
417                self._notes += "Error: Expected a float for the beam size's y "
418                self._notes += "won't changes y position from "
419                self._notes += "%s to %s" % (self._sample.position.y, y_position)
420        #Change z coordinate
421        z_position = self.z_position_tcl.GetValue().lstrip().rstrip()
422        if z_position == "" or z_position == str(None):
423            z_position = None
424            self._sample.position.z = z_position
425        else:
426            if check_float(self.z_position_tcl):
427                if self._sample.position.z != float(z_position):
428                    self._notes += "Change z of position from "
429                    self._notes += "%s to %s \n" % (self._sample.position.z,
430                                                    z_position)
431                    self._sample.position.z = float(z_position)
432            else:
433                self._notes += "Error: Expected a float for position's x "
434                self._notes += "won't changes z position from "
435                self._notes += "%s to %s" % (self._sample.position.z, z_position)
436        #change the beam center unit
437        unit = self.position_unit_tcl.GetValue().lstrip().rstrip()
438        if self._sample.position_unit != unit:
439            self._notes += " Change position's unit from "
440            self._notes += "%s to %s" % (self._sample.position_unit, unit)
441
442    def on_change_orientation(self):
443        """
444            Change orientation
445        """
446        #Change x coordinate
447        x_orientation = self.x_orientation_tcl.GetValue().lstrip().rstrip()
448        if x_orientation == "" or x_orientation == str(None):
449            x_orientation = None
450        else:
451            if check_float(self.x_orientation_tcl):
452                if self._sample.orientation.x != float(x_orientation) :
453                    self._notes += "Change x of orientation from "
454                    self._notes += "%s to %s \n" % (self._sample.orientation.x,
455                                                   x_orientation)
456                    self._sample.orientation.x = float(x_orientation)
457            else:
458                self._notes += "Error: Expected a float for orientation 's x "
459                self._notes += "won't changes x orientation from "
460                self._notes += "%s to %s" % (self._sample.orientation.x,
461                                              x_orientation)
462        #Change y coordinate
463        y_orientation = self.y_orientation_tcl.GetValue().lstrip().rstrip()
464        if y_orientation == "" or y_orientation == str(None):
465            y_orientation = None
466            self._sample.orientation.y = y_orientation
467        else:
468            if check_float(self.y_orientation_tcl):
469                if self._sample.orientation.y != float(y_orientation):
470                    self._notes += "Change y of orientation from "
471                    self._notes += "%s to %s \n" % (self._sample.orientation.y,
472                                                     y_orientation)
473                    self._sample.orientation.y = float(y_orientation)
474            else:
475                self._notes += "Error: Expected a float for orientation's y "
476                self._notes += "won't changes y orientation from "
477                self._notes += "%s to %s" % (self._sample.orientation.y,
478                                            y_orientation)
479        #Change z coordinate
480        z_orientation = self.z_orientation_tcl.GetValue().lstrip().rstrip()
481        if z_orientation == "" or z_orientation == str(None):
482            z_orientation = None
483            self._sample.orientation.z = z_orientation
484        else:
485            if check_float(self.z_orientation_tcl):
486                if self._sample.orientation.z != float(z_orientation):
487                    self._notes += "Change z of orientation from "
488                    self._notes += "%s to %s \n" % (self._sample.orientation.z,
489                                                     z_orientation)
490                    self._sample.orientation.z = float(z_orientation)
491            else:
492                self._notes += "Error: Expected a float for orientation 's x "
493                self._notes += "won't changes z orientation from "
494                self._notes += "%s to %s" % (self._sample.orientation.z,
495                                              z_orientation)
496        #change the beam center unit
497        unit = self.orientation_unit_tcl.GetValue().lstrip().rstrip()
498        if self._sample.orientation_unit != unit:
499            self._notes += " Change orientation's unit from "
500            self._notes += "%s to %s" % (self._sample.orientation_unit, unit)
501
502    def on_change_details(self):
503        """
504            Change details
505        """
506        #Change details
507        details = self.details_tcl.GetValue().lstrip().rstrip()
508        msg = ""
509        if self._sample.details is not None or self._sample.details:
510            for item in self._sample.details:
511                if item != details:
512                    msg += "      %s\n" % item
513                    self._notes += " Change details from"
514                    self._notes += " %s to %s \n" % (msg, details)
515                    self._sample.details.append(details)
516
517    def on_click_apply(self, event):
518        """
519            Apply user values to the sample
520        """
521        self.on_change_name()
522        self.on_change_id()
523        self.on_change_thickness()
524        self.on_change_transmission()
525        self.on_change_temperature()
526        self.on_change_position()
527        self.on_change_orientation()
528        self.on_change_details()
529        self.set_details(self._sample)
530        if self.manager is not None:
531            self.manager.set_sample(self._sample)
532        if event is not None:
533            event.Skip()
534
535    def on_click_cancel(self, event):
536        """
537            leave the sample as it is and close
538        """
539        self.reset_sample()
540        self.set_values()
541        if self.manager is not None:
542             self.manager.set_sample(self._sample, self._notes)
543        if event is not None:
544            event.Skip()
545
546if __name__ == "__main__":
547    app = wx.App()
548    from sas.sascalc.dataloader.data_info import Sample
549    sample = Sample()
550    dlg = SampleDialog(sample=sample)
551    dlg.ShowModal()
552    app.MainLoop()
Note: See TracBrowser for help on using the repository browser.