source: sasview/src/sas/sasgui/perspectives/calculator/data_editor.py @ b64b87c

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 b64b87c was d85c194, checked in by Piotr Rozyczko <piotr.rozyczko@…>, 8 years ago

Remaining modules refactored

  • Property mode set to 100644
File size: 22.6 KB
RevLine 
[91f151a]1
2import wx
3import sys
[49ab5d7]4import os
[91f151a]5from copy import deepcopy
6
[b699768]7from sas.sascalc.dataloader.loader import Loader
8from sas.sascalc.dataloader.data_info import Data2D
[91f151a]9from detector_editor import DetectorDialog
10from collimation_editor import CollimationDialog
11from console import ConsoleDialog
12
[d85c194]13from sas.sasgui.guiframe.events import StatusEvent
[91f151a]14
[c5dca87]15
[91f151a]16_QMIN_DEFAULT = 0.001
17_QMAX_DEFAULT = 0.13
18_NPTS_DEFAULT = 50
19#Control panel width
[b0ab6cb]20if sys.platform.count("darwin") == 0:
[91f151a]21    PANEL_WIDTH = 500
22    PANEL_HEIGTH = 350
23    FONT_VARIANT = 0
[c5dca87]24    _BOX_WIDTH = 51
[91f151a]25    ON_MAC = False
26else:
[c5dca87]27    _BOX_WIDTH = 76
[91f151a]28    PANEL_WIDTH = 550
29    PANEL_HEIGTH = 400
30    FONT_VARIANT = 1
31    ON_MAC = True
[49ab5d7]32
[91f151a]33def load_error(error=None):
34    """
35        Pop up an error message.
[49ab5d7]36
[91f151a]37        @param error: details error message to be displayed
38    """
39    message = "You had to try this, didn't you?\n\n"
40    message += "The data file you selected could not be loaded.\n"
41    message += "Make sure the content of your file is properly formatted.\n\n"
[49ab5d7]42
[91f151a]43    if error is not None:
[b45cde3]44        message += "When contacting the SasView team,"
[b0ab6cb]45        message += " mention the following:\n%s" % str(error)
[49ab5d7]46
47    dial = wx.MessageDialog(None, message,
[b0ab6cb]48                            'Error Loading File', wx.OK | wx.ICON_EXCLAMATION)
[49ab5d7]49    dial.ShowModal()
50
51
[91f151a]52class DataEditorPanel(wx.ScrolledWindow):
53    """
[49ab5d7]54    :param data: when not empty the class can
[ac7be54]55        same information into a dat object
[91f151a]56        and post event containing the changed data object to some other frame
57    """
58    def __init__(self, parent, data=[], *args, **kwds):
[b0ab6cb]59        kwds['name'] = "Data Editor"
60        kwds["size"] = (PANEL_WIDTH, PANEL_HEIGTH)
61        wx.ScrolledWindow.__init__(self, parent, *args, **kwds)
62        self.parent = parent
63        self._data = data
64        self._reset_data = deepcopy(data)
65        self.reader = None
66        self._notes = ""
67        self._description = "Edit Data"
68        self._default_save_location = os.getcwd()
69        self._do_layout()
70        self.reset_panel()
71        self.bt_apply.Disable()
72        if data:
73            self.complete_loading(data=data)
74            self.bt_apply.Enable()
[49ab5d7]75
[91f151a]76    def _define_structure(self):
77        """
[49ab5d7]78        define initial sizer
[91f151a]79        """
80        self.main_sizer = wx.BoxSizer(wx.VERTICAL)
81        name_box = wx.StaticBox(self, -1, "Load Data")
82        self.name_sizer = wx.StaticBoxSizer(name_box, wx.HORIZONTAL)
[49ab5d7]83
[91f151a]84        self.title_sizer = wx.BoxSizer(wx.HORIZONTAL)
85        self.run_sizer = wx.BoxSizer(wx.HORIZONTAL)
86        self.instrument_sizer = wx.BoxSizer(wx.HORIZONTAL)
[49ab5d7]87
[91f151a]88        edit_box = wx.StaticBox(self, -1, "Edit ")
89        self.edit_sizer = wx.StaticBoxSizer(edit_box, wx.HORIZONTAL)
[49ab5d7]90
[91f151a]91        self.button_sizer = wx.BoxSizer(wx.HORIZONTAL)
[49ab5d7]92
[91f151a]93    def _layout_name(self):
94        """
[b0ab6cb]95        Do the layout for data name related widgets
[91f151a]96        """
97        #data name [string]
[49ab5d7]98        data_name_txt = wx.StaticText(self, -1, 'Data : ')
[91f151a]99        self.data_cbox = wx.ComboBox(self, -1, style=wx.CB_READONLY)
[49ab5d7]100        wx.EVT_COMBOBOX(self.data_cbox, -1, self.on_select_data)
[91f151a]101        hint_data = "Loaded data."
102        self.data_cbox.SetToolTipString(hint_data)
103        id = wx.NewId()
104        self.browse_button = wx.Button(self, id, "Browse")
105        hint_on_browse = "Click on this button to import data in this panel."
106        self.browse_button.SetToolTipString(hint_on_browse)
107        self.Bind(wx.EVT_BUTTON, self.on_click_browse, id=id)
108        self.name_sizer.AddMany([(data_name_txt, 0, wx.LEFT, 15),
109                                       (self.data_cbox, 0, wx.LEFT, 10),
110                                       (self.browse_button, 0, wx.LEFT, 10)])
[49ab5d7]111
[91f151a]112    def _layout_title(self):
113        """
[b0ab6cb]114        Do the layout for data title related widgets
[91f151a]115        """
116        #title name [string]
[49ab5d7]117        data_title_txt = wx.StaticText(self, -1, 'Title : ')
118        self.data_title_tcl = wx.TextCtrl(self, -1, size=(PANEL_WIDTH * 3 / 5, -1))
[91f151a]119        self.data_title_tcl.Bind(wx.EVT_TEXT_ENTER, self.on_change_title)
120        hint_title = "Data's title."
121        self.data_title_tcl.SetToolTipString(hint_title)
122        self.title_sizer.AddMany([(data_title_txt, 0, wx.LEFT, 15),
123                                       (self.data_title_tcl, 0, wx.LEFT, 10)])
[49ab5d7]124
[91f151a]125    def _layout_run(self):
126        """
[b0ab6cb]127        Do the layout for data run related widgets
[91f151a]128        """
[49ab5d7]129        data_run_txt = wx.StaticText(self, -1, 'Run : ')
130        data_run_txt.SetToolTipString('')
131        self.data_run_tcl = wx.TextCtrl(self, -1, size=(PANEL_WIDTH * 3 / 5, -1),
[b0ab6cb]132                                         style=wx.TE_MULTILINE)
[91f151a]133        hint_run = "Data's run."
134        self.data_run_tcl.SetToolTipString(hint_run)
135        self.run_sizer.AddMany([(data_run_txt, 0, wx.LEFT, 15),
136                                       (self.data_run_tcl, 0, wx.LEFT, 10)])
[49ab5d7]137
[91f151a]138    def _layout_instrument(self):
139        """
[b0ab6cb]140        Do the layout for instrument related widgets
[91f151a]141        """
[49ab5d7]142        instrument_txt = wx.StaticText(self, -1, 'Instrument : ')
[91f151a]143        hint_instrument_txt = ''
[49ab5d7]144        instrument_txt.SetToolTipString(hint_instrument_txt)
145        self.instrument_tcl = wx.TextCtrl(self, -1, size=(_BOX_WIDTH * 5, 20))
[91f151a]146        hint_instrument = "Instrument."
147        self.instrument_tcl.SetToolTipString(hint_instrument)
148        self.instrument_sizer.AddMany([(instrument_txt, 0, wx.LEFT, 15),
149                                (self.instrument_tcl, 0, wx.LEFT, 10)])
[49ab5d7]150
[91f151a]151    def _layout_editor(self):
152        """
[b0ab6cb]153        Do the layout for sample related widgets
[91f151a]154        """
155        self.detector_rb = wx.RadioButton(self, -1, "Detector",
156                                           style=wx.RB_GROUP)
157        self.sample_rb = wx.RadioButton(self, -1, "Sample")
158        self.source_rb = wx.RadioButton(self, -1, "Source")
159        self.collimation_rb = wx.RadioButton(self, -1, "Collimation")
[49ab5d7]160
[91f151a]161        self.bt_edit = wx.Button(self, -1, "Edit")
162        self.bt_edit.SetToolTipString("Edit data.")
163        self.bt_edit.Bind(wx.EVT_BUTTON, self.on_edit)
164        self.edit_sizer.AddMany([(self.detector_rb, 0, wx.ALL, 10),
[49ab5d7]165                        (self.sample_rb, 0, wx.RIGHT | wx.BOTTOM | wx.TOP, 10),
166                        (self.source_rb, 0, wx.RIGHT | wx.BOTTOM | wx.TOP, 10),
167                    (self.collimation_rb, 0, wx.RIGHT | wx.BOTTOM | wx.TOP, 10),
[91f151a]168                    (self.bt_edit, 0,
[49ab5d7]169                                  wx.RIGHT | wx.BOTTOM | wx.TOP, 10)])
[91f151a]170        self.reset_radiobox()
[49ab5d7]171
172
[91f151a]173    def _layout_source(self):
174        """
175            Do the layout for source related widgets
176        """
[49ab5d7]177        source_txt = wx.StaticText(self, -1, 'Source ')
[91f151a]178        hint_source_txt = ''
[49ab5d7]179        source_txt.SetToolTipString(hint_source_txt)
[91f151a]180        self.bt_edit_source = wx.Button(self, -1, "Edit")
181        self.bt_edit_source.SetToolTipString("Edit data's sample.")
182        self.bt_edit_source.Bind(wx.EVT_BUTTON, self.edit_source)
[7c720e9]183        #self.source_sizer.AddMany([(source_txt, 0, wx.ALL, 10),
184        #                        (self.bt_edit_source, 0,
185        #                          wx.RIGHT|wx.BOTTOM|wx.TOP, 10)])
[91f151a]186
187    def _layout_summary(self):
188        """
189            Layout widgets related to data's summary
190        """
[b0ab6cb]191        self.data_summary = wx.TextCtrl(self, -1,
[49ab5d7]192                                         style=wx.TE_MULTILINE | wx.HSCROLL,
[91f151a]193                                        size=(-1, 200))
194        summary = 'No data info available...'
195        self.data_summary.SetValue(summary)
[7c720e9]196        #self.summary_sizer.Add(self.data_summary, 1, wx.EXPAND|wx.ALL, 10) 
[49ab5d7]197
198    def _layout_button(self):
[91f151a]199        """
200            Do the layout for the button widgets
[49ab5d7]201        """
[b0ab6cb]202        self.bt_summary = wx.Button(self, -1, "View", size=(_BOX_WIDTH, -1))
[91f151a]203        self.bt_summary.SetToolTipString("View final changes on data.")
204        self.bt_summary.Bind(wx.EVT_BUTTON, self.on_click_view)
[49ab5d7]205
[b0ab6cb]206        self.bt_save = wx.Button(self, -1, "Save As", size=(_BOX_WIDTH, -1))
[91f151a]207        self.bt_save.SetToolTipString("Save changes in a file.")
208        self.bt_save.Bind(wx.EVT_BUTTON, self.on_click_save)
[49ab5d7]209
[b0ab6cb]210        self.bt_apply = wx.Button(self, -1, "Apply", size=(_BOX_WIDTH, -1))
[91f151a]211        self.bt_apply.SetToolTipString("Save changes into the imported data.")
212        self.bt_apply.Bind(wx.EVT_BUTTON, self.on_click_apply)
[49ab5d7]213
[b0ab6cb]214        self.bt_reset = wx.Button(self, -1, 'Reset', size=(_BOX_WIDTH, -1))
[91f151a]215        self.bt_reset.Bind(wx.EVT_BUTTON, self.on_click_reset)
216        self.bt_reset.SetToolTipString("Reset data to its initial state.")
[49ab5d7]217
[b0ab6cb]218        self.bt_close = wx.Button(self, -1, 'Close', size=(_BOX_WIDTH, -1))
[91f151a]219        self.bt_close.Bind(wx.EVT_BUTTON, self.on_close)
220        self.bt_close.SetToolTipString("Close this panel.")
[49ab5d7]221
[91f151a]222        self.button_sizer.AddMany([(self.bt_save, 0, wx.LEFT, 120),
223                                   (self.bt_apply, 0, wx.LEFT, 10),
[49ab5d7]224                                   (self.bt_reset, 0, wx.LEFT | wx.RIGHT, 10),
[91f151a]225                                   (self.bt_summary, 0, wx.RIGHT, 10),
226                                   (self.bt_close, 0, wx.RIGHT, 10)])
[49ab5d7]227
[b0ab6cb]228    def _do_layout(self):
[91f151a]229        """
[b0ab6cb]230        Draw the current panel
[91f151a]231        """
232        self._define_structure()
233        self._layout_name()
234        self._layout_title()
235        self._layout_run()
236        self._layout_editor()
237        self._layout_button()
[49ab5d7]238        self.main_sizer.AddMany([(self.name_sizer, 0, wx.EXPAND | wx.ALL, 10),
[91f151a]239                                (self.title_sizer, 0,
[49ab5d7]240                                         wx.EXPAND | wx.TOP | wx.BOTTOM, 5),
[91f151a]241                                (self.run_sizer, 0,
[49ab5d7]242                                         wx.EXPAND | wx.TOP | wx.BOTTOM, 5),
[91f151a]243                                (self.instrument_sizer, 0,
[49ab5d7]244                                         wx.EXPAND | wx.TOP | wx.BOTTOM, 5),
[91f151a]245                                (self.edit_sizer, 0,
[49ab5d7]246                                        wx.EXPAND | wx.LEFT | wx.RIGHT | wx.TOP, 10),
[91f151a]247                                (self.button_sizer, 0,
[49ab5d7]248                                          wx.EXPAND | wx.TOP | wx.BOTTOM, 5)])
[91f151a]249        self.SetSizer(self.main_sizer)
[b0ab6cb]250        self.SetScrollbars(20, 20, 25, 65)
[91f151a]251        self.SetAutoLayout(True)
[49ab5d7]252
[91f151a]253    def fill_data_combox(self):
254        """
[b0ab6cb]255        fill the current combobox with the available data
[91f151a]256        """
257        if not self._data:
258            return
259        self.data_cbox.Clear()
260        for data in self._data:
[051e22f]261            name = data.title
262            if data.run:
263                name = data.run[0]
[49ab5d7]264            if name.lstrip().rstrip() == "":
[051e22f]265                name = data.filename
266            pos = self.data_cbox.Append(str(name))
[91f151a]267            self.data_cbox.SetClientData(pos, data)
268            self.data_cbox.SetSelection(pos)
[49ab5d7]269            self.data_cbox.SetStringSelection(str(name))
270
[91f151a]271    def reset_panel(self):
272        """
273        """
274        self.enable_data_cbox()
275        self.data_title_tcl.SetValue("")
[051e22f]276        self.data_run_tcl.SetValue("")
[49ab5d7]277
[91f151a]278    def on_select_data(self, event=None):
279        """
280        """
[b0ab6cb]281        data, _, _ = self.get_current_data()
[91f151a]282        self.reset_panel()
283        if data is None:
284            return
285        self.data_title_tcl.SetValue(str(data.title))
[051e22f]286        text = ""
287        if data.run:
288            for item in data.run:
[49ab5d7]289                text += item + "\n"
[051e22f]290        self.data_run_tcl.SetValue(str(text))
[49ab5d7]291
[91f151a]292    def get_current_data(self):
293        """
294        """
[49ab5d7]295        position = self.data_cbox.GetSelection()
[91f151a]296        if position == wx.NOT_FOUND:
297            return None, None, None
[49ab5d7]298        data_name = self.data_cbox.GetStringSelection()
[91f151a]299        data = self.data_cbox.GetClientData(position)
300        return data, data_name, position
[49ab5d7]301
[91f151a]302    def enable_data_cbox(self):
303        """
304        """
305        if self._data:
306            self.data_cbox.Enable()
307            self.bt_summary.Enable()
308            self.bt_reset.Enable()
309            self.bt_save.Enable()
310            self.bt_edit.Enable()
311        else:
312            self.data_cbox.Disable()
313            self.bt_summary.Disable()
314            self.bt_reset.Disable()
315            self.bt_save.Disable()
316            self.bt_edit.Disable()
[49ab5d7]317
[91f151a]318    def reset_radiobox(self):
319        """
320        """
321        self.detector_rb.SetValue(True)
322        self.source_rb.SetValue(False)
323        self.sample_rb.SetValue(False)
324        self.collimation_rb.SetValue(False)
[49ab5d7]325
[91f151a]326    def set_sample(self, sample, notes=None):
327        """
[b0ab6cb]328        set sample for data
[91f151a]329        """
[b0ab6cb]330        data, _, _ = self.get_current_data()
[91f151a]331        if data is None:
[49ab5d7]332            return
[91f151a]333        data.sample = sample
334        if notes is not None:
335            data.process.append(notes)
[49ab5d7]336
[91f151a]337    def set_source(self, source, notes=None):
338        """
[b0ab6cb]339        set source for data
[91f151a]340        """
341        data, data_name, position = self.get_current_data()
342        if data is None:
[49ab5d7]343            return
[91f151a]344        data.source = source
345        if notes is not None:
346            data.process.append(notes)
[49ab5d7]347
[91f151a]348    def set_detector(self, detector, notes=None):
349        """
[b0ab6cb]350        set detector for data
[91f151a]351        """
352        data, data_name, position = self.get_current_data()
353        if data is None:
[49ab5d7]354            return
[91f151a]355        data.detector = detector
356        if notes is not None:
357            data.process.append(notes)
[49ab5d7]358
[91f151a]359    def set_collimation(self, collimation, notes=None):
360        """
[b0ab6cb]361        set collimation for data
[91f151a]362        """
363        data, data_name, position = self.get_current_data()
364        if data is None:
[49ab5d7]365            return
[91f151a]366        data.collimation = collimation
367        if notes is not None:
368            data.process.append(notes)
[49ab5d7]369
[91f151a]370    def edit_collimation(self):
371        """
[b0ab6cb]372        Edit the selected collimation
[91f151a]373        """
374        data, data_name, position = self.get_current_data()
375        if data is None:
[49ab5d7]376            return
[91f151a]377        dlg = CollimationDialog(collimation=data.collimation)
378        dlg.set_manager(self)
379        dlg.ShowModal()
[49ab5d7]380
[91f151a]381    def edit_detector(self):
382        """
[b0ab6cb]383        Edit the selected detector
[91f151a]384        """
385        data, data_name, position = self.get_current_data()
386        if data is None:
[49ab5d7]387            return
[91f151a]388        dlg = DetectorDialog(detector=data.detector)
389        dlg.set_manager(self)
390        dlg.ShowModal()
391
392    def edit_sample(self):
393        """
[b0ab6cb]394        Open the dialog to edit the sample of the current data
[91f151a]395        """
[b0ab6cb]396        data, _, _ = self.get_current_data()
[91f151a]397        if data is None:
398            return
399        from sample_editor import SampleDialog
400        dlg = SampleDialog(parent=self, sample=data.sample)
401        dlg.set_manager(self)
402        dlg.ShowModal()
[49ab5d7]403
[91f151a]404    def edit_source(self):
405        """
[b0ab6cb]406        Open the dialog to edit the saource of the current data
[91f151a]407        """
408        data, data_name, position = self.get_current_data()
409        if data is None:
410            return
411        from source_editor import SourceDialog
412        dlg = SourceDialog(parent=self, source=data.source)
413        dlg.set_manager(self)
414        dlg.ShowModal()
[49ab5d7]415
[051e22f]416    def choose_data_file(self, location=None):
[91f151a]417        """
[b0ab6cb]418        Open a file dialog to allow loading a file
[91f151a]419        """
420        path = None
421        if location == None:
422            location = os.getcwd()
[49ab5d7]423
[91f151a]424        l = Loader()
425        cards = l.get_wildcards()
426        wlist = '|'.join(cards)
[49ab5d7]427
[051e22f]428        dlg = wx.FileDialog(self, "Choose a file", location, "", wlist, wx.OPEN)
[91f151a]429        if dlg.ShowModal() == wx.ID_OK:
430            path = dlg.GetPath()
431            mypath = os.path.basename(path)
432        dlg.Destroy()
433        return path
[49ab5d7]434
435
[91f151a]436    def complete_loading(self, data=None, filename=''):
437        """
[b0ab6cb]438        Complete the loading and compute the slit size
[91f151a]439        """
[051e22f]440        self.done = True
[91f151a]441        self._data = []
442        if data is None:
443            msg = "Couldn't load data"
[b0ab6cb]444            wx.PostEvent(self.parent.parent, StatusEvent(status=msg,
[49ab5d7]445                                             info="warning", type='stop'))
446            return
[91f151a]447        if not  data.__class__.__name__ == "list":
448            self._data.append(data)
449            self._reset_data.append(deepcopy(data))
450        else:
[051e22f]451            self._data = deepcopy(data)
[91f151a]452            self._reset_data = deepcopy(data)
453        self.set_values()
454        if self.parent.parent is None:
[49ab5d7]455            return
[91f151a]456        msg = "Load Complete"
[b0ab6cb]457        wx.PostEvent(self.parent.parent, StatusEvent(status=msg,
[49ab5d7]458                                                info="info", type='stop'))
459
[91f151a]460    def set_values(self):
461        """
[b0ab6cb]462        take the aperture values of the current data and display them
463        through the panel
[91f151a]464        """
[051e22f]465        if self._data:
466            self.fill_data_combox()
467            self.on_select_data(event=None)
[49ab5d7]468
[91f151a]469    def get_data(self):
470        """
[b0ab6cb]471        return the current data
[91f151a]472        """
473        return self._data
[49ab5d7]474
[91f151a]475    def get_notes(self):
476        """
[b0ab6cb]477        return notes
[91f151a]478        """
479        return self._notes
[49ab5d7]480
[91f151a]481    def on_change_run(self, event=None):
482        """
[b0ab6cb]483        Change run
[91f151a]484        """
[051e22f]485        run = []
[b0ab6cb]486        data, _, _ = self.get_current_data()
[051e22f]487        for i in range(self.data_run_tcl.GetNumberOfLines()):
[0c0d458]488            text = self.data_run_tcl.GetLineText(i).lstrip().rstrip()
489            if text != "":
490                run.append(text)
[91f151a]491        if data.run != run:
492            self._notes += "Change data 's "
[b0ab6cb]493            self._notes += "run from %s to %s \n" % (data.run, str(run))
[051e22f]494            data.run = run
[b0ab6cb]495        if event is not None:
496            event.Skip()
[49ab5d7]497
[91f151a]498    def on_change_title(self, event=None):
499        """
[b0ab6cb]500        Change title
[91f151a]501        """
[b0ab6cb]502        data, _, _ = self.get_current_data()
[91f151a]503        #Change data's name
504        title = self.data_title_tcl.GetValue().lstrip().rstrip()
[49ab5d7]505
[91f151a]506        if data.title != title:
507            self._notes += "Change data 's "
[b0ab6cb]508            self._notes += "title from %s to %s \n" % (data.title, str(title))
[91f151a]509            data.title = title
[b0ab6cb]510        if event is not None:
511            event.Skip()
[49ab5d7]512
[91f151a]513    def on_click_browse(self, event):
514        """
[b0ab6cb]515        Open a file dialog to allow the user to select a given file.
516        Display the loaded data if available.
[91f151a]517        """
518        path = self.choose_data_file(location=self._default_save_location)
519        if path is None:
[49ab5d7]520            return
[051e22f]521        if self.parent.parent is not None:
[b0ab6cb]522            wx.PostEvent(self.parent.parent, StatusEvent(status="Loading...",
523                                        info="info", type="progress"))
[49ab5d7]524
[051e22f]525        self.done = False
[91f151a]526        self._default_save_location = path
527        try:
528            #Load data
529            from load_thread import DataReader
530            ## If a thread is already started, stop it
531            if self.reader is not None and self.reader.isrunning():
532                self.reader.stop()
533            self.reader = DataReader(path=path,
534                                    completefn=self.complete_loading,
535                                    updatefn=None)
536            self.reader.queue()
537        except:
[b0ab6cb]538            msg = "Data Editor: %s" % (sys.exc_value)
[91f151a]539            load_error(msg)
[49ab5d7]540            return
[b0ab6cb]541        event.Skip()
[49ab5d7]542
[91f151a]543    def on_edit(self, event):
544        """
545        """
546        if self.detector_rb.GetValue():
547            self.edit_detector()
548        if self.sample_rb.GetValue():
549            self.edit_sample()
550        if self.source_rb.GetValue():
551            self.edit_source()
552        if self.collimation_rb.GetValue():
553            self.edit_collimation()
[b0ab6cb]554        event.Skip()
[49ab5d7]555
[91f151a]556    def on_click_apply(self, event):
[49ab5d7]557        """
[b0ab6cb]558        changes are saved in data object imported to edit
[91f151a]559        """
[b0ab6cb]560        data, _, _ = self.get_current_data()
[91f151a]561        if data is None:
562            return
563        self.on_change_run(event=None)
564        self.on_change_title(event=None)
565        #must post event here
[b0ab6cb]566        event.Skip()
[49ab5d7]567
[91f151a]568    def on_click_save(self, event):
569        """
[b0ab6cb]570        Save change into a file
[91f151a]571        """
[c5dca87]572        if not self._data:
[91f151a]573            return
574        self.on_change_run(event=None)
575        self.on_change_title(event=None)
576        path = None
[49ab5d7]577        wildcard = "CanSAS 1D files(*.xml)|*.xml"
[91f151a]578        dlg = wx.FileDialog(self, "Choose a file",
[49ab5d7]579                            self._default_save_location, "", wildcard , wx.SAVE)
580
[c5dca87]581        for data in self._data:
582            if issubclass(data.__class__, Data2D):
583                msg = "No conventional writing format for \n\n"
584                msg += "Data2D at this time.\n"
585                dlg = wx.MessageDialog(None, msg, 'Error Loading File',
586                                             wx.OK | wx.ICON_EXCLAMATION)
[49ab5d7]587                dlg.ShowModal()
[c5dca87]588            else:
589                if dlg.ShowModal() == wx.ID_OK:
590                    path = dlg.GetPath()
591                    mypath = os.path.basename(path)
[49ab5d7]592                    loader = Loader()
[c5dca87]593                    format = ".xml"
[b0ab6cb]594                    if os.path.splitext(mypath)[1].lower() == format:
[49ab5d7]595                        loader.save(path, data, format)
[c5dca87]596                    try:
597                        self._default_save_location = os.path.dirname(path)
598                    except:
[49ab5d7]599                        pass
[c5dca87]600                    dlg.Destroy()
[b0ab6cb]601        event.Skip()
[49ab5d7]602
[91f151a]603    def on_click_view(self, event):
604        """
[49ab5d7]605        Display data info
[91f151a]606        """
607        data, data_name, position = self.get_current_data()
608        if data is None:
609            return
610        self.on_change_run(event=None)
611        self.on_change_title(event=None)
612        dlg = ConsoleDialog(data=data)
613        dlg.ShowModal()
[b0ab6cb]614        event.Skip()
[49ab5d7]615
[91f151a]616    def on_click_reset(self, event):
617        """
618        """
619        data, data_name, position = self.get_current_data()
620        if data is None:
621            return
[b0ab6cb]622        self._data[position] = deepcopy(self._reset_data[position])
[91f151a]623        self.set_values()
[b0ab6cb]624        event.Skip()
[49ab5d7]625
[91f151a]626    def on_close(self, event):
627        """
[b0ab6cb]628        leave data as it is and close
[91f151a]629        """
630        self.parent.Close()
[b0ab6cb]631        event.Skip()
[49ab5d7]632
[91f151a]633class DataEditorWindow(wx.Frame):
[ae84427]634    def __init__(self, parent, manager, data=None, *args, **kwds):
[b0ab6cb]635        kwds["size"] = (PANEL_WIDTH, PANEL_HEIGTH)
[91f151a]636        wx.Frame.__init__(self, parent, *args, **kwds)
637        self.parent = parent
[ae84427]638        self.manager = manager
[91f151a]639        self.panel = DataEditorPanel(parent=self, data=data)
640        self.Show()
[49ab5d7]641
[91f151a]642    def get_data(self):
643        """
644            return the current data
645        """
646        return self.panel.get_data()
[49ab5d7]647
[b0ab6cb]648if __name__ == "__main__":
[49ab5d7]649
650    app = wx.App()
[91f151a]651    window = DataEditorWindow(parent=None, data=[], title="Data Editor")
652    app.MainLoop()
Note: See TracBrowser for help on using the repository browser.