source: sasview/calculatorview/perspectives/calculator/collimation_editor.py @ 1a3a03b

ESS_GUIESS_GUI_DocsESS_GUI_batch_fittingESS_GUI_bumps_abstractionESS_GUI_iss1116ESS_GUI_iss879ESS_GUI_iss959ESS_GUI_openclESS_GUI_orderingESS_GUI_sync_sascalccostrafo411magnetic_scattrelease-4.1.1release-4.1.2release-4.2.2release_4.0.1ticket-1009ticket-1094-headlessticket-1242-2d-resolutionticket-1243ticket-1249ticket885unittest-saveload
Last change on this file since 1a3a03b was 6137b150, checked in by Gervaise Alina <gervyh@…>, 14 years ago

disable data editor

  • Property mode set to 100644
File size: 22.4 KB
RevLine 
[91f151a]1
2import wx
3import sys
4from copy import deepcopy
5from DataLoader.loader import Loader
6from DataLoader.data_info import Aperture, Collimation
7from aperture_editor import ApertureDialog
8
9from sans.guiframe.utils import check_float
10_BOX_WIDTH = 60
11
12if sys.platform.count("win32")>0:
[ad6f597]13    _STATICBOX_WIDTH = 500
[91f151a]14    PANEL_WIDTH = 530
15    PANEL_HEIGHT = 430
16    FONT_VARIANT = 0
17else:
[ad6f597]18    _STATICBOX_WIDTH = 550
[91f151a]19    PANEL_WIDTH = 600
20    PANEL_HEIGHT = 480
21    FONT_VARIANT = 1
22   
23class CollimationDialog(wx.Dialog):
[6137b150]24    """
25    """
[91f151a]26    def __init__(self, parent=None, manager=None,
27                 collimation=[], *args, **kwds):
[ad6f597]28        """
29        """
30        kwds['size'] =(PANEL_WIDTH, PANEL_HEIGHT)
31        kwds['title'] = "Collimation Editor"
32        wx.Dialog.__init__(self, parent=parent, *args, **kwds)
33        self.parent = parent
34        self.manager = manager
35        self._collimation = collimation
36        self._reset_collimation = deepcopy(collimation)
37        self._notes = ""
38        self._description = "Edit collimation"
39        self._do_layout()
40        self.set_values()
41 
[91f151a]42    def _define_structure(self):
43        """
[6137b150]44        define initial sizer
[91f151a]45        """
46        self.main_sizer = wx.BoxSizer(wx.VERTICAL)
47        self.box_collimation = wx.StaticBox(self, -1,str("Edit Selected Collimation"))
48        self.boxsizer_collimation = wx.StaticBoxSizer(self.box_collimation, wx.VERTICAL)
49       
50        collimation_box = wx.StaticBox(self, -1, "Edit Number of Collimations")
51        self.collimation_sizer = wx.StaticBoxSizer(collimation_box, wx.VERTICAL)
[ad6f597]52        self.collimation_sizer.SetMinSize((_STATICBOX_WIDTH, -1))
[91f151a]53        self.collimation_button_sizer = wx.BoxSizer(wx.HORIZONTAL)
54        self.collimation_hint_sizer = wx.BoxSizer(wx.HORIZONTAL)
55       
56        self.name_sizer = wx.BoxSizer(wx.HORIZONTAL)
57        self.length_sizer = wx.BoxSizer(wx.HORIZONTAL)
58        self.button_sizer = wx.BoxSizer(wx.HORIZONTAL)
59       
60        aperture_box = wx.StaticBox(self, -1, "Edit Aperture")
61        self.aperture_sizer = wx.StaticBoxSizer(aperture_box, wx.VERTICAL)
62        self.aperture_button_sizer = wx.BoxSizer(wx.HORIZONTAL)
63        self.aperture_hint_sizer = wx.BoxSizer(wx.HORIZONTAL)
64     
65    def _layout_collimation(self):
66        """
[6137b150]67        Do the layout for collimation related widgets
[91f151a]68        """
69        collimation_name_txt = wx.StaticText(self, -1, "Collimation:") 
70        hint_collimation_txt = 'Current available collimation.'
71        collimation_name_txt.SetToolTipString(hint_collimation_txt) 
72        self.collimation_cbox = wx.ComboBox(self, -1, style=wx.CB_READONLY)
[c5dca87]73        wx.EVT_COMBOBOX(self.collimation_cbox, -1, self.on_select_collimation) 
[91f151a]74        hint_collimation_name_txt = 'Name of collimations.'
75        self.collimation_cbox.SetToolTipString(hint_collimation_name_txt) 
76   
77        self.bt_add_collimation = wx.Button(self, -1, "Add")
78        self.bt_add_collimation.SetToolTipString("Edit data's collimation.")
79        self.bt_add_collimation.Bind(wx.EVT_BUTTON, self.add_collimation)
80       
81        self.bt_remove_collimation = wx.Button(self, -1, "Remove")
82        self.bt_remove_collimation.SetToolTipString("Remove data's collimation.")
83        self.bt_remove_collimation.Bind(wx.EVT_BUTTON, self.remove_collimation)
84     
85        self.collimation_button_sizer.AddMany([(collimation_name_txt, 0, wx.LEFT, 15),
86                                     (self.collimation_cbox, 0, wx.LEFT, 5),
87                                     (self.bt_add_collimation, 0, wx.LEFT, 10),
88                                     (self.bt_remove_collimation, 0, wx.LEFT, 5)])
89        collimation_hint_txt = 'No collimation is available for this data.'
90        self.collimation_txt = wx.StaticText(self, -1, collimation_hint_txt) 
91        self.collimation_hint_sizer.Add(self.collimation_txt, 0, wx.LEFT, 10)
92        self.collimation_sizer.AddMany([(self.collimation_button_sizer, 0, wx.ALL, 10),
93                                     (self.collimation_hint_sizer, 0, wx.ALL, 10)])
94     
95        self.fill_collimation_combox()
96        self.enable_collimation()
97       
98
99    def _layout_name(self):
100        """
[6137b150]101        Do the layout for collimation name related widgets
[91f151a]102        """
103        #Collimation name [string]
104        name_txt = wx.StaticText(self, -1, 'Name : ') 
105        self.name_tcl = wx.TextCtrl(self, -1, size=(_BOX_WIDTH*5, 20), style=0) 
106        self.name_sizer.AddMany([(name_txt, 0, wx.LEFT|wx.RIGHT, 10),
107                                       (self.name_tcl, 0, wx.EXPAND)])
108       
109    def _layout_length(self):
110        """
[6137b150]111        Do the  layout for length related widgets
[91f151a]112        """
113        #Collimation length
114        length_txt = wx.StaticText(self, -1, 'Length:') 
115        self.length_tcl = wx.TextCtrl(self, -1, size=(_BOX_WIDTH, 20), style=0)   
116        length_unit_txt = wx.StaticText(self, -1, 'Unit: ') 
117        self.length_unit_tcl = wx.TextCtrl(self, -1, size=(_BOX_WIDTH, 20),style=0) 
118        self.length_sizer.AddMany([(length_txt, 0, wx.LEFT|wx.RIGHT, 10),
119                                     (self.length_tcl, 0, wx.LEFT, 12),
120                                     (length_unit_txt, 0, wx.LEFT|wx.RIGHT, 10),
121                                     (self.length_unit_tcl, 0, wx.EXPAND)]) 
122   
123    def _layout_button(self): 
124        """
[6137b150]125        Do the layout for the button widgets
[91f151a]126        """ 
127        self.bt_apply = wx.Button(self, -1,'Apply')
128        self.bt_apply.Bind(wx.EVT_BUTTON, self.on_click_apply)
129        self.bt_apply.SetToolTipString("Apply current changes to collimation.")
130        self.bt_cancel = wx.Button(self, -1,'Cancel')
131        self.bt_cancel.SetToolTipString("Cancel current changes.")
132        self.bt_cancel.Bind(wx.EVT_BUTTON, self.on_click_cancel)
133        self.bt_close = wx.Button(self, wx.ID_CANCEL,'Close')
134        self.bt_close.SetToolTipString("Close window.")
135        self.button_sizer.AddMany([(self.bt_apply, 0, wx.LEFT, 200),
136                                   (self.bt_cancel, 0, wx.LEFT, 10),
137                                   (self.bt_close, 0, wx.LEFT, 10)])
138    def _layout_aperture(self):
139        """
[6137b150]140        Do the layout for aperture related widgets
[91f151a]141        """
142        aperture_name_txt = wx.StaticText(self, -1, "Aperture:") 
143        hint_aperture_txt = 'Current available aperture.'
144        aperture_name_txt.SetToolTipString(hint_aperture_txt) 
145        self.aperture_cbox = wx.ComboBox(self, -1, style=wx.CB_READONLY)
146        hint_aperture_name_txt = 'Name of apertures.'
147        self.aperture_cbox.SetToolTipString(hint_aperture_name_txt) 
148   
149        self.bt_add_aperture = wx.Button(self, -1, "Add")
150        self.bt_add_aperture.SetToolTipString("Edit data's aperture.")
151        self.bt_add_aperture.Bind(wx.EVT_BUTTON, self.add_aperture)
152        self.bt_edit_aperture = wx.Button(self, -1, "Edit")
153        self.bt_edit_aperture.SetToolTipString("Edit data's aperture.")
154        self.bt_edit_aperture.Bind(wx.EVT_BUTTON, self.edit_aperture)
155        self.bt_remove_aperture = wx.Button(self, -1, "Remove")
156        self.bt_remove_aperture.SetToolTipString("Remove data's aperture.")
157        self.bt_remove_aperture.Bind(wx.EVT_BUTTON, self.remove_aperture)
158     
159        self.aperture_button_sizer.AddMany([(aperture_name_txt, 0, wx.LEFT, 15),
160                                     (self.aperture_cbox, 0, wx.LEFT, 5),
161                                     (self.bt_add_aperture, 0, wx.LEFT, 10),
162                                     (self.bt_edit_aperture, 0, wx.LEFT, 5),
163                                     (self.bt_remove_aperture, 0, wx.LEFT, 5)])
164        aperture_hint_txt = 'No aperture is available for this data.'
165        self.aperture_txt = wx.StaticText(self, -1, aperture_hint_txt) 
166        self.aperture_hint_sizer.Add(self.aperture_txt, 0, wx.LEFT, 10)
167        self.aperture_sizer.AddMany([(self.aperture_button_sizer, 0, wx.ALL, 10),
168                                     (self.aperture_hint_sizer, 0, wx.ALL, 10)])
169        self.fill_aperture_combox()
170        self.enable_aperture()
171   
172    def _do_layout(self, data=None):
173        """
[6137b150]174        Draw the current panel
[91f151a]175        """
176        self._define_structure()
177        self._layout_collimation()
178        self._layout_name()
179        self._layout_length()
180        self._layout_aperture()
181        self._layout_button()
182     
183        self.boxsizer_collimation.AddMany([(self.name_sizer, 0,
184                                          wx.EXPAND|wx.TOP|wx.BOTTOM, 5),
185                                          (self.length_sizer, 0,
186                                     wx.EXPAND|wx.TOP|wx.BOTTOM, 5),
187                                     (self.aperture_sizer, 0,
188                                     wx.EXPAND|wx.ALL, 10)])
189        self.main_sizer.AddMany([(self.collimation_sizer, 0, wx.ALL, 10),
190                                  (self.boxsizer_collimation, 0, wx.ALL, 10),
191                                  (self.button_sizer, 0,
192                                    wx.EXPAND|wx.TOP|wx.BOTTOM, 5)])
193        self.SetSizer(self.main_sizer)
194        self.SetAutoLayout(True)
195       
196    def get_current_collimation(self):
197        """
198        """
199        if not self.collimation_cbox.IsEnabled():
200            return None, None, None
201        position = self.collimation_cbox.GetSelection() 
202        if position == wx.NOT_FOUND:
203            return None, None, None
204        collimation_name = self.collimation_cbox.GetStringSelection() 
205        collimation = self.collimation_cbox.GetClientData(position)
206        return collimation, collimation_name, position
207   
208    def fill_collimation_combox(self):
209        """
[6137b150]210        fill the current combobox with the available collimation
[91f151a]211        """
212        if self._collimation is None or self._collimation == []:
213            return
214        for collimation in self._collimation:
215            pos = self.collimation_cbox.Append(str(collimation.name))
216            self.collimation_cbox.SetClientData(pos, collimation)
217            self.collimation_cbox.SetSelection(pos)
218            self.collimation_cbox.SetStringSelection(str(collimation.name)) 
219           
220    def add_collimation(self, event):
221        """
[6137b150]222        Append empty collimation to data's list of collimation
[91f151a]223        """
224       
225        if not self.collimation_cbox.IsEnabled():
226            self.collimation_cbox.Enable()
227        collimation = Collimation()
228        self._collimation.append(collimation)
229        position = self.collimation_cbox.Append(str(collimation.name))
230        self.collimation_cbox.SetClientData(position, collimation)
231        self.collimation_cbox.SetSelection(position) 
232        self.enable_collimation() 
[ad6f597]233        self.bt_add_aperture.Enable()
[c5dca87]234        self.fill_aperture_combox()
235        self.enable_aperture()
[85e665e]236        self.set_values()
[91f151a]237       
238    def remove_collimation(self, event):
239        """
[6137b150]240        Remove collimation to data's list of collimation
[91f151a]241        """
242        if self.collimation_cbox.IsEnabled():
[ad6f597]243            if self.collimation_cbox.GetCount() > 0:
[91f151a]244                position = self.collimation_cbox.GetCurrentSelection()
245                collimation = self.collimation_cbox.GetClientData(position)
246                if collimation in self._collimation:
247                    self._collimation.remove(collimation)
248                    self.collimation_cbox.Delete(position) 
249                    #set the combo box box the next available item
250                    position = self.collimation_cbox.GetCount()
251                    if position > 0:
252                        position -= 1 
253                    self.collimation_cbox.SetSelection(position)
[85e665e]254        if not self._collimation and self.collimation_cbox.GetCount() == 0:       
255            self.bt_add_aperture.Disable() 
256            self.name_tcl.Clear()
257            self.length_tcl.Clear()
258            self.length_unit_tcl.Clear()
259            self.aperture_cbox.Clear()
260            self.aperture_cbox.Disable()
[91f151a]261        #disable or enable the combo box when necessary
262        self.enable_collimation()
[85e665e]263        self.enable_aperture()
[91f151a]264       
[c5dca87]265    def on_select_collimation(self, event):
266        """
[6137b150]267        fill the control on the panel according to the current  selected collimation
[c5dca87]268        """
269        self.set_values()
270        self.fill_aperture_combox()
271        self.enable_aperture()
272   
[91f151a]273    def enable_collimation(self):
274        """
[6137b150]275        Enable /disable widgets related to collimation
[91f151a]276        """
277        if self._collimation is not None and self.collimation_cbox.GetCount() > 0:
278            self.collimation_cbox.Enable()
279            self.bt_remove_collimation.Enable()
280            n_collimation = self.collimation_cbox.GetCount()
281            collimation_hint_txt = 'collimations available: %s '%str(n_collimation)
[ad6f597]282            if len(self._collimation) > 0:
[91f151a]283                self.bt_remove_collimation.Enable()
284            else:
285                self.bt_remove_collimation.Disable()
286        else:
287            self.collimation_cbox.Disable()
288            self.bt_remove_collimation.Disable()
289            collimation_hint_txt = 'No collimation is available for this data.'
290        self.collimation_txt.SetLabel(collimation_hint_txt)
291           
292   
293    def reset_collimation_combobox(self, edited_collimation):
294        """
[6137b150]295        take all edited editor and reset clientdata of collimation combo box
[91f151a]296        """
297        for position in range(self.collimation_cbox.GetCount()):
298            collimation = self.collimation_cbox.GetClientData(position)
299            if collimation == edited_collimation:
300                collimation = edited_collimation
301                self.collimation_cbox.SetString(position, str(collimation.name)) 
302                self.collimation_cbox.SetClientData(position, collimation)
303                self.collimation_cbox.SetStringSelection(str(collimation.name)) 
304         
305    def add_aperture(self, event):
306        """
[6137b150]307        Append empty aperture to data's list of aperture
[91f151a]308        """
309        collimation, _, _ = self.get_current_collimation()
310        if not self.aperture_cbox.IsEnabled():
311            self.aperture_cbox.Enable()
312        aperture = Aperture()
313        collimation.aperture.append(aperture)
314        position = self.aperture_cbox.Append(str(aperture.name))
315        self.aperture_cbox.SetClientData(position, aperture)
316        self.aperture_cbox.SetSelection(position) 
317        self.enable_aperture()
318       
319    def edit_aperture(self, event):
320        """
[6137b150]321        Edit the selected aperture
[91f151a]322        """
323        if self._collimation is None or not self.aperture_cbox.IsEnabled():
324            return 
325        position = self.aperture_cbox.GetSelection() 
326        if position != wx.NOT_FOUND:
327            name = self.aperture_cbox.GetStringSelection() 
328            aperture = self.aperture_cbox.GetClientData(position)
329            dlg = ApertureDialog(parent=self, aperture=aperture)
330            dlg.set_manager(self)
331            dlg.ShowModal()
332           
333    def remove_aperture(self, event):
334        """
[6137b150]335        Remove aperture to data's list of aperture
[91f151a]336        """
[ad6f597]337        if self._collimation is None or not self._collimation:
[91f151a]338            return
339        collimation, _, _ = self.get_current_collimation()
340        if self.aperture_cbox.IsEnabled():
341            if self.aperture_cbox.GetCount() > 1:
342                position = self.aperture_cbox.GetCurrentSelection()
343                aperture = self.aperture_cbox.GetClientData(position)
344                if aperture in collimation.aperture:
345                    collimation.aperture.remove(aperture)
346                    self.aperture_cbox.Delete(position) 
347                    #set the combo box box the next available item
348                    position = self.aperture_cbox.GetCount()
349                    if position > 0:
350                        position -= 1 
351                    self.aperture_cbox.SetSelection(position)
352                   
353        #disable or enable the combo box when necessary
354        self.enable_aperture()
355       
356    def set_aperture(self, aperture):
357        """
[6137b150]358        set aperture for data
[91f151a]359        """
[ad6f597]360        if self._collimation is None or not self._collimation:
[91f151a]361            return
362        collimation, _, _ = self.get_current_collimation()
363        if collimation.aperture:
364            for item in collimation.aperture:
365                if item == aperture:
366                    item = aperture
367                    self.reset_aperture_combobox(edited_aperture=aperture)
368                    return
[ad6f597]369               
[91f151a]370    def enable_aperture(self):
371        """
[6137b150]372        Enable /disable widgets crelated to aperture
[91f151a]373        """
374        collimation, _, _ = self.get_current_collimation()
375        if  self.aperture_cbox.GetCount() > 0:
376            self.aperture_cbox.Enable()
377            self.bt_edit_aperture.Enable()
378            self.bt_remove_aperture.Enable()
379            n_aperture = self.aperture_cbox.GetCount()
380            aperture_hint_txt = 'apertures available: %s '%str(n_aperture)
[c5dca87]381            if len(collimation.aperture) > 0:
[91f151a]382                self.bt_remove_aperture.Enable()
383            else:
384                self.bt_remove_aperture.Disable()
385        else:
386            self.aperture_cbox.Disable()
387            self.bt_edit_aperture.Disable()
388            self.bt_remove_aperture.Disable()
389            aperture_hint_txt = 'No aperture is available for this data.'
390        self.aperture_txt.SetLabel(aperture_hint_txt)
391   
392    def reset_aperture_combobox(self, edited_aperture):
393        """
[6137b150]394        take all edited editor and reset clientdata of aperture combo box
[91f151a]395        """
396        for position in range(self.aperture_cbox.GetCount()):
397            aperture = self.aperture_cbox.GetClientData(position)
398            if aperture == edited_aperture:
399                aperture = edited_aperture
400                self.aperture_cbox.SetString(position, str(aperture.name)) 
401                self.aperture_cbox.SetClientData(position, aperture)
402                self.aperture_cbox.SetStringSelection(str(aperture.name)) 
403               
404    def fill_aperture_combox(self):
405        """
[6137b150]406        fill the current combobox with the available aperture
[91f151a]407        """
[c5dca87]408        self.aperture_cbox.Clear()
[91f151a]409        collimation, _, _ = self.get_current_collimation()
410        if collimation is None or not collimation.aperture:
411            return
412        for aperture in collimation.aperture:
413            pos = self.aperture_cbox.Append(str(aperture.name))
414            self.aperture_cbox.SetClientData(pos, aperture)
415            self.aperture_cbox.SetSelection(pos)
416            self.aperture_cbox.SetStringSelection(str(aperture.name)) 
417         
418    def set_manager(self, manager):
419        """   
[6137b150]420        Set manager of this window
[91f151a]421        """
422        self.manager = manager
423       
424    def set_values(self):
425        """
[6137b150]426        take the collimation values of the current data and display them
427        through the panel
[91f151a]428        """
429        collimation, _, _ = self.get_current_collimation()
430        if collimation is None:
[ad6f597]431            self.bt_add_aperture.Disable()
432            self.length_tcl.SetValue("")
433            self.name_tcl.SetValue("")
434            self.length_unit_tcl.SetValue("")
[91f151a]435            return
436        #Name
437        self.name_tcl.SetValue(str(collimation.name))
438        #length
439        self.length_tcl.SetValue(str(collimation.length))
440        #Length unit
441        self.length_unit_tcl.SetValue(str(collimation.length_unit))
442       
443    def get_collimation(self):
444        """
[6137b150]445        return the current collimation
[91f151a]446        """
447        return self._collimation
448   
449    def get_notes(self):
450        """
[6137b150]451        return notes
[91f151a]452        """
453        return self._notes
454   
455    def on_change_name(self):
456        """
[6137b150]457        Change name
[91f151a]458        """
459        collimation, collimation_name, position = self.get_current_collimation()
460        if collimation is None: 
461            return
462        #Change the name of the collimation
463        name = self.name_tcl.GetValue().lstrip().rstrip()
464        if name == "" or name == str(None):
465            name = None
466        if collimation.name != name:
467            self._notes += "Change collimation 's "
468            self._notes += "name from %s to %s \n"%(collimation.name, name)
469            collimation.name = name
470            self.collimation_cbox.SetString(position, str(collimation.name)) 
471            self.collimation_cbox.SetClientData(position, collimation)
472            self.collimation_cbox.SetStringSelection(str(collimation.name)) 
473   
474    def on_change_length(self):
475        """
[6137b150]476        Change the length
[91f151a]477        """
478        collimation, collimation_name, position = self.get_current_collimation()
479        if collimation is None: 
480            return
481        #Change length 
482        length = self.length_tcl.GetValue().lstrip().rstrip()
483        if length == "" or length == str(None):
484            length = None
485            collimation.length = length
486        else:
487            if check_float(self.length_tcl):
488                if collimation.length != float(length):
489                    self._notes += "Change Collimation length from "
490                    self._notes += "%s to %s \n"%(collimation.length, length)
491                    collimation.length  = float(length)
492            else:
493                self._notes += "Error: Expected a float for collimation length "
494                self._notes += "won't changes length from "
495                self._notes += "%s to %s"%(collimation.length, length)
496        #change length  unit
497        unit = self.length_unit_tcl.GetValue().lstrip().rstrip()
498        if collimation.length_unit != unit:
499            self._notes += " Change length's unit from "
500            self._notes += "%s to %s"%(collimation.length_unit, unit)
501            collimation.length_unit = unit
502   
503    def on_click_apply(self, event):
504        """
[6137b150]505        Apply user values to the collimation
[91f151a]506        """
507        self.on_change_name()
508        self.on_change_length()
509        self.set_values()
510        if self.manager is not None:
511            self.manager.set_collimation(self._collimation, self._notes)
512       
513    def on_click_cancel(self, event):
514        """
[6137b150]515        leave the collimation as it is and close
[91f151a]516        """
[ad6f597]517        self._collimation = deepcopy(self._reset_collimation)
[91f151a]518        self.set_values()
519        if self.manager is not None:
520             self.manager.set_collimation(self._collimation)
521       
522 
523if __name__ =="__main__":
524
525    app  = wx.App()
[ad6f597]526    dlg = CollimationDialog(collimation=[Collimation()])
[91f151a]527    dlg.ShowModal()
528    app.MainLoop()
529 
Note: See TracBrowser for help on using the repository browser.