source: sasview/src/sas/sasgui/guiframe/data_panel.py @ eb38181

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 eb38181 was e767897, checked in by lewis, 8 years ago

Select/deselct children datasets when select/deselect all is clicked (fixes #259)

  • Property mode set to 100644
File size: 55.8 KB
RevLine 
[3c44c66]1################################################################################
2#This software was developed by the University of Tennessee as part of the
3#Distributed Data Analysis of Neutron Scattering Experiments (DANSE)
[e767897]4#project funded by the US National Science Foundation.
[3c44c66]5#
6#See the license text in license.txt
7#
8#copyright 2010, University of Tennessee
9################################################################################
10"""
11This module provides Graphic interface for the data_manager module.
12"""
13import wx
[31f3222b]14from wx.build import build_options
[1941e6a]15
[af7ba61]16# Check version
[dc0cfa4]17toks = str(wx.__version__).split('.')
[af7ba61]18if int(toks[1]) < 9:
[228a8bb]19    if int(toks[2]) < 12:
20        wx_version = 811
21    else:
22        wx_version = 812
[af7ba61]23else:
[228a8bb]24    wx_version = 900
[3c44c66]25import sys
26from wx.lib.scrolledpanel import ScrolledPanel
[3feed3e]27import  wx.lib.agw.customtreectrl as CT
[d85c194]28from sas.sasgui.guiframe.dataFitting import Data1D
29from sas.sasgui.guiframe.dataFitting import Data2D
30from sas.sasgui.guiframe.panel_base import PanelBase
31from sas.sasgui.guiframe.events import StatusEvent
32from sas.sasgui.guiframe.events import EVT_DELETE_PLOTPANEL
33from sas.sasgui.guiframe.events import NewLoadDataEvent
34from sas.sasgui.guiframe.events import NewPlotEvent
35from sas.sasgui.guiframe.gui_style import GUIFRAME
36from sas.sasgui.guiframe.events import NewBatchEvent
[b699768]37from sas.sascalc.dataloader.loader import Loader
[d85c194]38#from sas.sasgui.guiframe.local_perspectives.plotting.masking \
[318b5bbb]39#    import FloatPanel as QucikPlotDialog
[d85c194]40from sas.sasgui.guiframe.local_perspectives.plotting.SimplePlot import PlotFrame \
[318b5bbb]41        as QucikPlotDialog
[d85c194]42import sas.sasgui.guiframe.config as config
[e767897]43
[2a62d5c]44extension_list = []
45if config.APPLICATION_STATE_EXTENSION is not None:
46    extension_list.append(config.APPLICATION_STATE_EXTENSION)
[e767897]47EXTENSIONS = config.PLUGIN_STATE_EXTENSIONS + extension_list
[99f9ecf]48PLUGINS_WLIST = config.PLUGINS_WLIST
49APPLICATION_WLIST = config.APPLICATION_WLIST
[3f0c330]50
[e767897]51#Control panel width
[57f537a]52if sys.platform.count("win32") > 0:
[3f0c330]53    PANEL_WIDTH = 235
54    PANEL_HEIGHT = 700
55    CBOX_WIDTH = 140
56    BUTTON_WIDTH = 80
57    FONT_VARIANT = 0
[234a3fa]58    IS_MAC = False
[3f0c330]59else:
60    PANEL_WIDTH = 255
61    PANEL_HEIGHT = 750
62    CBOX_WIDTH = 155
63    BUTTON_WIDTH = 100
64    FONT_VARIANT = 1
[234a3fa]65    IS_MAC = True
[3f0c330]66
[dc0cfa4]67STYLE_FLAG = wx.RAISED_BORDER|CT.TR_HAS_BUTTONS| CT.TR_HIDE_ROOT|\
[91bdf87]68                    wx.WANTS_CHARS|CT.TR_HAS_VARIABLE_ROW_HEIGHT
[e767897]69
70
[3feed3e]71class DataTreeCtrl(CT.CustomTreeCtrl):
[3c44c66]72    """
73    Check list control to be used for Data Panel
74    """
[6605880]75    def __init__(self, parent, *args, **kwds):
[73581ce]76        #agwstyle is introduced in wx.2.8.11 but is not working for mac
[228a8bb]77        if IS_MAC and wx_version < 812:
[91bdf87]78            try:
79                kwds['style'] = STYLE_FLAG
[d34f9f6]80                CT.CustomTreeCtrl.__init__(self, parent, *args, **kwds)
[91bdf87]81            except:
[af7ba61]82                del kwds['style']
[d34f9f6]83                CT.CustomTreeCtrl.__init__(self, parent, *args, **kwds)
[73581ce]84        else:
[6605880]85            # agwstyle is introduced in wx.2.8.11
86            # argument working only for windows
[73581ce]87            try:
88                kwds['agwStyle'] = STYLE_FLAG
[d34f9f6]89                CT.CustomTreeCtrl.__init__(self, parent, *args, **kwds)
[73581ce]90            except:
91                try:
[d34f9f6]92                    del kwds['agwStyle']
[73581ce]93                    kwds['style'] = STYLE_FLAG
[d34f9f6]94                    CT.CustomTreeCtrl.__init__(self, parent, *args, **kwds)
[73581ce]95                except:
[d34f9f6]96                    del kwds['style']
97                    CT.CustomTreeCtrl.__init__(self, parent, *args, **kwds)
[3feed3e]98        self.root = self.AddRoot("Available Data")
[e767897]99
[0b705915]100    def OnCompareItems(self, item1, item2):
[e767897]101        """
102        Overrides OnCompareItems in wx.TreeCtrl.
103        Used by the SortChildren method.
[0b705915]104        """
105        # Get the item data
[d4d4c8a]106        data_1 = self.GetItemText(item1)
107        data_2 = self.GetItemText(item2)
[0b705915]108        # Compare the item data
[d4d4c8a]109        if data_1 < data_2:
[0b705915]110            return -1
[d4d4c8a]111        elif data_1 > data_2:
[0b705915]112            return 1
113        else:
114            return 0
[e767897]115
[52725d6]116class DataPanel(ScrolledPanel, PanelBase):
[3c44c66]117    """
[e767897]118    This panel displays data available in the application and widgets to
[3c44c66]119    interact with data.
120    """
[3feed3e]121    ## Internal name for the AUI manager
122    window_name = "Data Panel"
123    ## Title to appear on top of the window
[1b1bbf9]124    window_caption = "Data Explorer"
[e767897]125    #type of window
[3feed3e]126    window_type = "Data Panel"
127    ## Flag to tell the GUI manager that this panel is not
128    #  tied to any perspective
129    #ALWAYS_ON = True
[e767897]130    def __init__(self, parent,
[600eca2]131                 list=None,
[ea4dfe0]132                 size=(PANEL_WIDTH, PANEL_HEIGHT),
[cb6a2b7]133                 id=-1,
[ea4dfe0]134                 list_of_perspective=None, manager=None, *args, **kwds):
[31ac4a1]135        #kwds['size'] = size
136        #kwds['style'] = STYLE_FLAG
[cb6a2b7]137        ScrolledPanel.__init__(self, parent=parent, id=id, *args, **kwds)
[31ac4a1]138        PanelBase.__init__(self, parent)
[3c44c66]139        self.SetupScrolling()
[e767897]140        #Set window's font size
[3f0c330]141        self.SetWindowVariant(variant=FONT_VARIANT)
[e767897]142        self.loader = Loader()
[2a62d5c]143        #Default location
[e767897]144        self._default_save_location = None
[ee2b492]145        self.all_data1d = True
[ae84427]146        self.parent = parent.parent
147        self._manager = manager
[31ac4a1]148        self.frame = parent
[600eca2]149        if list is None:
150            list = []
[3c44c66]151        self.list_of_data = list
[600eca2]152        if list_of_perspective is None:
153            list_of_perspective = []
[3feed3e]154        self.list_of_perspective = list_of_perspective
[6605880]155        self.list_rb_perspectives = []
[c70eb7c]156        self.list_cb_data = {}
157        self.list_cb_theory = {}
[61ffd1e]158        self.tree_ctrl = None
159        self.tree_ctrl_theory = None
[600eca2]160        self.perspective_cbox = None
[bf39777]161        ## Create context menu for page
162        self.data_menu = None
[dc0cfa4]163        self.popUpMenu = None
[5e5704d]164        self.plot3d_id = None
165        self.editmask_id = None
166        # Default attr
167        self.vbox  = None
168        self.sizer1 = None
169        self.sizer2 = None
170        self.sizer3 = None
171        self.sizer4 = None
172        self.sizer5 = None
173        self.selection_cbox = None
174        self.bt_add = None
175        self.bt_remove = None
176        self.bt_import = None
177        self.bt_append_plot = None
178        self.bt_plot = None
179        self.bt_freeze = None
180        self.cb_plotpanel = None
181        self.rb_single_mode = None
182        self.rb_batch_mode = None
183
[3feed3e]184        self.owner = None
185        self.do_layout()
[600eca2]186        self.fill_cbox_analysis(self.list_of_perspective)
[1b1bbf9]187        self.Bind(wx.EVT_SHOW, self.on_close_page)
[13a63ab]188        if self.parent is not None:
189            self.parent.Bind(EVT_DELETE_PLOTPANEL, self._on_delete_plot_panel)
[e767897]190
[3feed3e]191    def do_layout(self):
[6db811e]192        """
[6605880]193            Create the panel layout
[6db811e]194        """
[3c44c66]195        self.define_panel_structure()
196        self.layout_selection()
[5c4b674]197        self.layout_data_list()
[8f19b69]198        self.layout_batch()
[64f9fa6]199        self.layout_button()
[e767897]200
[7fb69f26]201    def disable_app_combo(self, enable):
202        """
[5e5704d]203        Disable app combo box
[7fb69f26]204        """
205        self.perspective_cbox.Enable(enable)
[e767897]206
[3c44c66]207    def define_panel_structure(self):
208        """
209        Define the skeleton of the panel
210        """
[3feed3e]211        w, h = self.parent.GetSize()
[3c44c66]212        self.vbox  = wx.BoxSizer(wx.VERTICAL)
213        self.sizer1 = wx.BoxSizer(wx.VERTICAL)
[e095c3a9]214        self.sizer1.SetMinSize(wx.Size(w/13, h*2/5))
[e767897]215
[3feed3e]216        self.sizer2 = wx.BoxSizer(wx.VERTICAL)
[2990dd3]217        self.sizer3 = wx.FlexGridSizer(9, 2, 4, 1)
[64f9fa6]218        self.sizer4 = wx.BoxSizer(wx.VERTICAL)
[18ec684]219        self.sizer5 = wx.BoxSizer(wx.VERTICAL)
[e767897]220
[6605880]221        self.vbox.Add(self.sizer5, 0, wx.EXPAND|wx.ALL, 1)
222        self.vbox.Add(self.sizer1, 1, wx.EXPAND|wx.ALL, 0)
223        self.vbox.Add(self.sizer2, 0, wx.EXPAND|wx.ALL, 1)
224        self.vbox.Add(self.sizer3, 0, wx.EXPAND|wx.ALL, 10)
[64f9fa6]225        #self.vbox.Add(self.sizer4, 0, wx.EXPAND|wx.ALL,5)
[e767897]226
[3c44c66]227        self.SetSizer(self.vbox)
[e767897]228
[3feed3e]229    def layout_selection(self):
[3c44c66]230        """
[6605880]231            Create selection option combo box
[3c44c66]232        """
[3feed3e]233        select_txt = wx.StaticText(self, -1, 'Selection Options')
[bffa3d0]234        select_txt.SetForegroundColour('blue')
[3feed3e]235        self.selection_cbox = wx.ComboBox(self, -1, style=wx.CB_READONLY)
236        list_of_options = ['Select all Data',
237                            'Unselect all Data',
238                           'Select all Data 1D',
239                           'Unselect all Data 1D',
240                           'Select all Data 2D',
241                           'Unselect all Data 2D' ]
242        for option in list_of_options:
243            self.selection_cbox.Append(str(option))
[18ec684]244        self.selection_cbox.SetValue('Select all Data')
[5e5704d]245        wx.EVT_COMBOBOX(self.selection_cbox, -1, self._on_selection_type)
[e767897]246        self.sizer5.AddMany([(select_txt, 0, wx.ALL, 5),
[d4d4c8a]247                            (self.selection_cbox, 0, wx.ALL,5)])
[61ffd1e]248        self.enable_selection()
[e767897]249
250
[3feed3e]251    def _on_selection_type(self, event):
[3c44c66]252        """
[6605880]253            Select data according to patterns
254            :param event: UI event
[3c44c66]255        """
[e767897]256        def check_item_and_children(control, check_value=True):
257            self.tree_ctrl.CheckItem(data_ctrl, check_value)
258            if data_ctrl.HasChildren():
259                if check_value == True and not control.IsExpanded():
260                    # Only select children if control is expanded
261                    # Always deselect children, regardless (see ticket #259)
262                    return
263                for child_ctrl in data_ctrl.GetChildren():
264                    self.tree_ctrl.CheckItem(child_ctrl, check_value)
265
[3feed3e]266        option = self.selection_cbox.GetValue()
[e767897]267
[18ec684]268        pos = self.selection_cbox.GetSelection()
269        if pos == wx.NOT_FOUND:
[e767897]270            return
[18ec684]271        option = self.selection_cbox.GetString(pos)
[b5e79f7]272        for item in self.list_cb_data.values():
[5e5704d]273            data_ctrl, _, _, _, _, _, _, _ = item
[e767897]274            _, data_class, _ = self.tree_ctrl.GetItemPyData(data_ctrl)
[18ec684]275            if option == 'Select all Data':
[e767897]276                check_item_and_children(data_ctrl, check_value=True)
[18ec684]277            elif option == 'Unselect all Data':
[e767897]278                check_item_and_children(data_ctrl, check_value=False)
[18ec684]279            elif option == 'Select all Data 1D':
280                if data_class == 'Data1D':
[e767897]281                    check_item_and_children(data_ctrl, check_value=True)
[18ec684]282            elif option == 'Unselect all Data 1D':
[c70eb7c]283                if data_class == 'Data1D':
[e767897]284                    check_item_and_children(data_ctrl, check_value=False)
[18ec684]285            elif option == 'Select all Data 2D':
286                if data_class == 'Data2D':
[e767897]287                    check_item_and_children(data_ctrl, check_value=True)
[18ec684]288            elif option == 'Unselect all Data 2D':
289                if data_class == 'Data2D':
[e767897]290                    check_item_and_children(data_ctrl, check_value=False)
[1e3394f]291        self.enable_append()
292        self.enable_freeze()
293        self.enable_plot()
294        self.enable_import()
[248b918]295        self.enable_remove()
[e767897]296
[3c44c66]297    def layout_button(self):
298        """
299        Layout widgets related to buttons
300        """
[1941e6a]301        #Load Data Button
[e767897]302        self.bt_add = wx.Button(self, wx.NewId(), "Load Data",
[2567003]303                                size=(BUTTON_WIDTH, -1))
[c461ebe]304        self.bt_add.SetToolTipString("Load data files")
[2a62d5c]305        wx.EVT_BUTTON(self, self.bt_add.GetId(), self._load_data)
[e767897]306
[1941e6a]307        #Delete Data Button
[c5a769e]308        self.bt_remove = wx.Button(self, wx.NewId(), "Delete Data",
[248b918]309         size=(BUTTON_WIDTH, -1))
[c5a769e]310        self.bt_remove.SetToolTipString("Delete data from the application")
[248b918]311        wx.EVT_BUTTON(self, self.bt_remove.GetId(), self.on_remove)
[e767897]312
[1941e6a]313        #Send data to perspective button
[2567003]314        self.bt_import = wx.Button(self, wx.NewId(), "Send To",
315                                    size=(BUTTON_WIDTH, -1))
[5e5704d]316        self.bt_import.SetToolTipString("Send Data set to active perspective")
[3c44c66]317        wx.EVT_BUTTON(self, self.bt_import.GetId(), self.on_import)
[e767897]318
[1941e6a]319        #Choose perspective to be send data to combo box
[df58ecab]320        self.perspective_cbox = wx.ComboBox(self, -1,
[600eca2]321                                style=wx.CB_READONLY)
[66f7016]322        if not IS_MAC:
323            self.perspective_cbox.SetMinSize((BUTTON_WIDTH*1.6, -1))
[e767897]324        wx.EVT_COMBOBOX(self.perspective_cbox, -1,
[600eca2]325                        self._on_perspective_selection)
[e767897]326
[1941e6a]327        #Append data to current Graph Button
[2567003]328        self.bt_append_plot = wx.Button(self, wx.NewId(), "Append Plot To",
329                                        size=(BUTTON_WIDTH, -1))
[5e5704d]330        self.bt_append_plot.SetToolTipString( \
331                                "Plot the selected data in the active panel")
[213892bc]332        wx.EVT_BUTTON(self, self.bt_append_plot.GetId(), self.on_append_plot)
[e767897]333
[1941e6a]334        #Create a new graph and send data to that new graph button
[e767897]335        self.bt_plot = wx.Button(self, wx.NewId(), "New Plot",
[2567003]336                                 size=(BUTTON_WIDTH, -1))
[3c44c66]337        self.bt_plot.SetToolTipString("To trigger plotting")
338        wx.EVT_BUTTON(self, self.bt_plot.GetId(), self.on_plot)
[e767897]339
[1941e6a]340        #Freeze current theory button - becomes a data set and stays on graph
[e767897]341        self.bt_freeze = wx.Button(self, wx.NewId(), "Freeze Theory",
[2567003]342                                   size=(BUTTON_WIDTH, -1))
[7360816]343        freeze_tip = "To trigger freeze a theory: making a copy\n"
344        freeze_tip += "of the theory checked to Data box,\n"
[2719255]345        freeze_tip += "     so that it can act like a real data set."
346        self.bt_freeze.SetToolTipString(freeze_tip)
[c70eb7c]347        wx.EVT_BUTTON(self, self.bt_freeze.GetId(), self.on_freeze)
[e767897]348
[1941e6a]349        #select plot to send to combo box (blank if no data)
[b9f6d83]350        if sys.platform == 'darwin':
[e767897]351            self.cb_plotpanel = wx.ComboBox(self, -1,
[31f3222b]352                                            style=wx.CB_READONLY)
353        else:
[e767897]354            self.cb_plotpanel = wx.ComboBox(self, -1,
[31f3222b]355                                            style=wx.CB_READONLY|wx.CB_SORT)
[5e5704d]356        wx.EVT_COMBOBOX(self.cb_plotpanel, -1, self._on_plot_selection)
[5e8e615]357        self.cb_plotpanel.Disable()
[e767897]358
[1941e6a]359        #Help button
360        self.bt_help = wx.Button(self, wx.NewId(), "HELP",
361                                 size=(BUTTON_WIDTH, -1))
362        self.bt_help.SetToolTipString("Help for the Data Explorer.")
363        wx.EVT_BUTTON(self,self.bt_help.GetId(), self.on_help)
[0a2fdca]364
[600eca2]365        self.sizer3.AddMany([(self.bt_add),
366                             ((10, 10)),
[248b918]367                             (self.bt_remove),
368                             ((10, 10)),
[7360816]369                             (self.bt_freeze),
370                             ((10, 10)),
371                             (self.bt_plot),
372                             ((10, 10)),
373                             (self.bt_append_plot),
[e767897]374                             (self.cb_plotpanel,
[5e5704d]375                              wx.EXPAND|wx.ADJUST_MINSIZE, 5),
[64f9fa6]376                             ((5, 5)),
377                             ((5, 5)),
[2567003]378                             (self.bt_import, 0, wx.EXPAND|wx.RIGHT, 5),
[e767897]379                             (self.perspective_cbox,
[5e5704d]380                              wx.EXPAND|wx.ADJUST_MINSIZE, 5),
[64f9fa6]381                             ((10, 10)),
382                             (self.sizer4),
[1941e6a]383                             ((10, 10)),
[b5c44f0]384                             (self.bt_help, 0, wx.RIGHT, 5)])
[c461ebe]385
[600eca2]386        self.sizer3.AddGrowableCol(1, 1)
[a03d419]387        self.show_data_button()
[248b918]388        self.enable_remove()
[f7d0b74]389        self.enable_import()
390        self.enable_plot()
391        self.enable_append()
392        self.enable_freeze()
[e26d0db]393        self.enable_remove_plot()
[e767897]394
[3feed3e]395    def layout_batch(self):
[3c44c66]396        """
[6605880]397            Set up batch mode options
[3c44c66]398        """
[3feed3e]399        self.rb_single_mode = wx.RadioButton(self, -1, 'Single Mode',
400                                             style=wx.RB_GROUP)
401        self.rb_batch_mode = wx.RadioButton(self, -1, 'Batch Mode')
[24adb89]402        self.Bind(wx.EVT_RADIOBUTTON, self.on_single_mode,
403                     id=self.rb_single_mode.GetId())
404        self.Bind(wx.EVT_RADIOBUTTON, self.on_batch_mode,
405                   id=self.rb_batch_mode.GetId())
[e767897]406
[d03a356]407        self.rb_single_mode.SetValue(not self.parent.batch_on)
408        self.rb_batch_mode.SetValue(self.parent.batch_on)
[6605880]409        self.sizer4.AddMany([(self.rb_single_mode, 0, wx.ALL, 4),
410                             (self.rb_batch_mode, 0, wx.ALL, 4)])
[e767897]411
[80ddbd0]412    def on_single_mode(self, event):
413        """
[6605880]414            Change to single mode
415            :param event: UI event
[80ddbd0]416        """
417        if self.parent is not None:
[5e5704d]418            wx.PostEvent(self.parent, NewBatchEvent(enable=False))
[e767897]419
[80ddbd0]420    def on_batch_mode(self, event):
421        """
[6605880]422            Change to batch mode
423            :param event: UI event
[80ddbd0]424        """
425        if self.parent is not None:
[e767897]426            wx.PostEvent(self.parent,
[6605880]427                         NewBatchEvent(enable=True))
[e767897]428
429    def _get_data_selection(self, event):
[176fbf1]430        """
[6605880]431            Get data selection from the right click
432            :param event: UI event
[176fbf1]433        """
[8ae522c]434        data = None
[d4d4c8a]435        #selection = event.GetSelection()
[176fbf1]436        id, _, _ = self.FindFocus().GetSelection().GetData()
437        data_list, theory_list = \
[5e5704d]438                        self.parent.get_data_manager().get_by_id(id_list=[id])
[176fbf1]439        if data_list:
440            data = data_list.values()[0]
[8ae522c]441        if data == None:
[176fbf1]442            data = theory_list.values()[0][0]
443        return data
[e767897]444
[bf39777]445    def on_edit_data(self, event):
446        """
447        Pop Up Data Editor
448        """
[176fbf1]449        data = self._get_data_selection(event)
[d85c194]450        from sas.sasgui.guiframe.local_perspectives.plotting.masking \
[5cf5f51]451            import MaskPanel as MaskDialog
[e767897]452
453        panel = MaskDialog(parent=self.parent, base=self,
[7434020]454                           data=data, id=wx.NewId())
[5cf5f51]455        panel.ShowModal()
[e767897]456
[7434020]457    def on_plot_3d(self, event):
458        """
459        Frozen image of 3D
460        """
461        data = self._get_data_selection(event)
[d85c194]462        from sas.sasgui.guiframe.local_perspectives.plotting.masking \
[7434020]463        import FloatPanel as Float3dDialog
[e767897]464
465        panel = Float3dDialog(base=self, data=data,
[7434020]466                              dimension=3, id=wx.NewId())
[e767897]467        panel.ShowModal()
468
[7434020]469    def on_quick_plot(self, event):
470        """
471        Frozen plot
472        """
473        data = self._get_data_selection(event)
474        if data.__class__.__name__ == "Data2D":
475            dimension = 2
476        else:
[e767897]477            dimension = 1
478        #panel = QucikPlotDialog(base=self, data=data,
[318b5bbb]479        #                        dimension=dimension, id=wx.NewId())
480        frame = QucikPlotDialog(self, -1, "Plot " + data.name, 'log_{10}')
481        self.parent.put_icon(frame)
482        frame.add_plot(data)
483        #frame.SetTitle(title)
484        frame.Show(True)
485        frame.SetFocus()
[e767897]486        #panel.ShowModal()
487
[0aca693]488    def on_data_info(self, event):
489        """
490        Data Info panel
491        """
492        data = self._get_data_selection(event)
493        if data.__class__.__name__ == "Data2D":
494            self.parent.show_data2d(data, data.name)
495        else:
496            self.parent.show_data1d(data, data.name)
[e767897]497
[176fbf1]498    def on_save_as(self, event):
499        """
500        Save data as a file
501        """
502        data = self._get_data_selection(event)
[d4d4c8a]503        #path = None
[176fbf1]504        default_name = data.name
505        if default_name.count('.') > 0:
506            default_name = default_name.split('.')[0]
507        default_name += "_out"
508        if self.parent != None:
509            if issubclass(data.__class__, Data1D):
510                self.parent.save_data1d(data, default_name)
511            elif issubclass(data.__class__, Data2D):
512                self.parent.save_data2d(data, default_name)
513            else:
514                print "unable to save this type of data"
[e767897]515
[91bdf87]516    def layout_data_list(self):
[bffa3d0]517        """
518        Add a listcrtl in the panel
519        """
520        tree_ctrl_label = wx.StaticText(self, -1, "Data")
521        tree_ctrl_label.SetForegroundColour('blue')
[e095c3a9]522        self.tree_ctrl = DataTreeCtrl(parent=self, style=wx.SUNKEN_BORDER)
[bffa3d0]523        self.tree_ctrl.Bind(CT.EVT_TREE_ITEM_CHECKING, self.on_check_item)
[176fbf1]524        self.tree_ctrl.Bind(CT.EVT_TREE_ITEM_MENU, self.on_right_click_data)
[bf39777]525        ## Create context menu for page
526        self.data_menu = wx.Menu()
527        id = wx.NewId()
[0aca693]528        name = "Data Info"
529        msg = "Show Data Info"
530        self.data_menu.Append(id, name, msg)
531        wx.EVT_MENU(self, id, self.on_data_info)
[e767897]532
[0aca693]533        id = wx.NewId()
[176fbf1]534        name = "Save As"
535        msg = "Save Theory/Data as a file"
[bf39777]536        self.data_menu.Append(id, name, msg)
[176fbf1]537        wx.EVT_MENU(self, id, self.on_save_as)
[e767897]538
[5e5704d]539        quickplot_id = wx.NewId()
[7434020]540        name = "Quick Plot"
541        msg = "Plot the current Data"
[5e5704d]542        self.data_menu.Append(quickplot_id, name, msg)
543        wx.EVT_MENU(self, quickplot_id, self.on_quick_plot)
[e767897]544
[7434020]545        self.plot3d_id = wx.NewId()
546        name = "Quick 3DPlot (Slow)"
547        msg = "Plot3D the current 2D Data"
548        self.data_menu.Append(self.plot3d_id, name, msg)
549        wx.EVT_MENU(self, self.plot3d_id, self.on_plot_3d)
[e767897]550
[176fbf1]551        self.editmask_id = wx.NewId()
552        name = "Edit Mask"
553        msg = "Edit Mask for the current 2D Data"
554        self.data_menu.Append(self.editmask_id, name, msg)
555        wx.EVT_MENU(self, self.editmask_id, self.on_edit_data)
[e767897]556
[bffa3d0]557        tree_ctrl_theory_label = wx.StaticText(self, -1, "Theory")
558        tree_ctrl_theory_label.SetForegroundColour('blue')
[e767897]559        self.tree_ctrl_theory = DataTreeCtrl(parent=self,
[e095c3a9]560                                                    style=wx.SUNKEN_BORDER)
[e767897]561        self.tree_ctrl_theory.Bind(CT.EVT_TREE_ITEM_CHECKING,
[e095c3a9]562                                                    self.on_check_item)
[e767897]563        self.tree_ctrl_theory.Bind(CT.EVT_TREE_ITEM_MENU,
[176fbf1]564                                   self.on_right_click_theory)
[bffa3d0]565        self.sizer1.Add(tree_ctrl_label, 0, wx.LEFT, 10)
566        self.sizer1.Add(self.tree_ctrl, 1, wx.EXPAND|wx.ALL, 10)
567        self.sizer1.Add(tree_ctrl_theory_label, 0,  wx.LEFT, 10)
568        self.sizer1.Add(self.tree_ctrl_theory, 1, wx.EXPAND|wx.ALL, 10)
[e767897]569
[176fbf1]570    def on_right_click_theory(self, event):
571        """
572        On click theory data
573        """
[c668b1b]574        try:
[a8db60c]575            id, data_class_name, _ = \
576                            self.tree_ctrl_theory.GetSelection().GetData()
[d4d4c8a]577            _, _ = self.parent.get_data_manager().get_by_id(id_list=[id])
[c668b1b]578        except:
579            return
[176fbf1]580        if self.data_menu is not None:
[a8db60c]581            menu_enable = (data_class_name == "Data2D")
[176fbf1]582            self.data_menu.Enable(self.editmask_id, False)
[a8db60c]583            self.data_menu.Enable(self.plot3d_id, menu_enable)
[e767897]584            self.PopupMenu(self.data_menu)
585
[176fbf1]586    def on_right_click_data(self, event):
[bf39777]587        """
588        Allow Editing Data
589        """
[5e5704d]590        #selection = event.GetSelection()
[176fbf1]591        is_data = True
592        try:
593            id, data_class_name, _ = self.tree_ctrl.GetSelection().GetData()
594            data_list, _ = \
[4cc25e9]595                        self.parent.get_data_manager().get_by_id(id_list=[id])
[176fbf1]596            if not data_list:
597                is_data = False
598        except:
599            return
600        if self.data_menu is not None:
[7434020]601            menu_enable = (data_class_name == "Data2D")
602            maskmenu_enable = (menu_enable and is_data)
603            self.data_menu.Enable(self.editmask_id, maskmenu_enable)
604            self.data_menu.Enable(self.plot3d_id, menu_enable)
[e767897]605            self.PopupMenu(self.data_menu)
606
607    def onContextMenu(self, event):
[3c44c66]608        """
[3feed3e]609        Retrieve the state selected state
[3c44c66]610        """
[3feed3e]611        # Skipping the save state functionality for release 0.9.0
612        #return
613        pos = event.GetPosition()
614        pos = self.ScreenToClient(pos)
[e767897]615        self.PopupMenu(self.popUpMenu, pos)
616
617
[3feed3e]618    def on_check_item(self, event):
[3c44c66]619        """
[5e5704d]620        On check item
[3c44c66]621        """
[3feed3e]622        item = event.GetItem()
[e767897]623        item.Check(not item.IsChecked())
[1e3394f]624        self.enable_append()
625        self.enable_freeze()
626        self.enable_plot()
627        self.enable_import()
[248b918]628        self.enable_remove()
[ee2b492]629        event.Skip()
[e767897]630
[600eca2]631    def fill_cbox_analysis(self, plugin):
[ee2b492]632        """
[600eca2]633        fill the combobox with analysis name
[ee2b492]634        """
[600eca2]635        self.list_of_perspective = plugin
636        if self.parent is None or \
637            not hasattr(self.parent, "get_current_perspective") or \
638            len(self.list_of_perspective) == 0:
639            return
640        if self.parent is not None and self.perspective_cbox  is not None:
641            for plug in self.list_of_perspective:
642                if plug.get_perspective():
643                    self.perspective_cbox.Append(plug.sub_menu, plug)
[e767897]644
[600eca2]645            curr_pers = self.parent.get_current_perspective()
[911cae5]646            if curr_pers:
647                self.perspective_cbox.SetStringSelection(curr_pers.sub_menu)
[1ba8201d]648                self.enable_import()
[e767897]649
[3feed3e]650    def load_data_list(self, list):
[3c44c66]651        """
[c70eb7c]652        add need data with its theory under the tree
[3c44c66]653        """
[61ffd1e]654        if list:
655            for state_id, dstate in list.iteritems():
656                data = dstate.get_data()
657                theory_list = dstate.get_theory()
658                if data is not None:
[755cac4]659                    data_name = str(data.name)
[b2aef1c]660                    data_title = str(data.title)
661                    data_run = str(data.run)
[61ffd1e]662                    data_class = data.__class__.__name__
[e767897]663                    path = dstate.get_path()
[61ffd1e]664                    process_list = data.process
665                    data_id = data.id
[76703da]666                    s_path = str(path)
[61ffd1e]667                    if state_id not in self.list_cb_data:
668                        #new state
[5e5704d]669                        data_c = self.tree_ctrl.InsertItem(self.tree_ctrl.root,
[e767897]670                                        0, data_name, ct_type=1,
[5e5704d]671                                        data=(data_id, data_class, state_id))
[61ffd1e]672                        data_c.Check(True)
673                        d_i_c = self.tree_ctrl.AppendItem(data_c, 'Info')
[e767897]674                        d_t_c = self.tree_ctrl.AppendItem(d_i_c,
[b2aef1c]675                                                      'Title: %s' % data_title)
[e767897]676                        r_n_c = self.tree_ctrl.AppendItem(d_i_c,
[b2aef1c]677                                                      'Run: %s' % data_run)
[e767897]678                        i_c_c = self.tree_ctrl.AppendItem(d_i_c,
[61ffd1e]679                                                      'Type: %s' % data_class)
680                        p_c_c = self.tree_ctrl.AppendItem(d_i_c,
[603fb0f]681                                                      "Path: '%s'" % s_path)
[61ffd1e]682                        d_p_c = self.tree_ctrl.AppendItem(d_i_c, 'Process')
[e767897]683
[61ffd1e]684                        for process in process_list:
[0b0b7de]685                            process_str = str(process).replace('\n',' ')
686                            if len(process_str)>20:
687                                process_str = process_str[:20]+' [...]'
[5e5704d]688                            self.tree_ctrl.AppendItem(d_p_c, process_str)
[e767897]689                        theory_child = self.tree_ctrl.AppendItem(data_c,
[5e5704d]690                                                                 "THEORIES")
[e767897]691                        self.list_cb_data[state_id] = [data_c,
[61ffd1e]692                                                       d_i_c,
[b2aef1c]693                                                       d_t_c,
694                                                       r_n_c,
[61ffd1e]695                                                       i_c_c,
[5e5704d]696                                                       p_c_c,
697                                                       d_p_c,
698                                                       theory_child]
[61ffd1e]699                    else:
700                        data_ctrl_list =  self.list_cb_data[state_id]
701                        #This state is already display replace it contains
[d4d4c8a]702                        data_c, d_i_c, d_t_c, r_n_c,  i_c_c, p_c_c, d_p_c, _ \
[5e5704d]703                                = data_ctrl_list
[e767897]704                        self.tree_ctrl.SetItemText(data_c, data_name)
[61ffd1e]705                        temp = (data_id, data_class, state_id)
[e767897]706                        self.tree_ctrl.SetItemPyData(data_c, temp)
707                        self.tree_ctrl.SetItemText(i_c_c,
[5e5704d]708                                                   'Type: %s' % data_class)
[e767897]709                        self.tree_ctrl.SetItemText(p_c_c,
710                                                   'Path: %s' % s_path)
711                        self.tree_ctrl.DeleteChildren(d_p_c)
[61ffd1e]712                        for process in process_list:
[3a5f7c8]713                            if not process.is_empty():
714                                _ = self.tree_ctrl.AppendItem(d_p_c,
715                                                              process.single_line_desc())
[98fdccd]716                wx.CallAfter(self.append_theory, state_id, theory_list)
[0b705915]717            # Sort by data name
718            if self.tree_ctrl.root:
[e767897]719                self.tree_ctrl.SortChildren(self.tree_ctrl.root)
[248b918]720        self.enable_remove()
[f7d0b74]721        self.enable_import()
722        self.enable_plot()
723        self.enable_freeze()
[61ffd1e]724        self.enable_selection()
[e767897]725
[48665ed]726    def _uncheck_all(self):
727        """
728        Uncheck all check boxes
729        """
730        for item in self.list_cb_data.values():
[5e5704d]731            data_ctrl, _, _, _, _, _, _, _ = item
[e767897]732            self.tree_ctrl.CheckItem(data_ctrl, False)
[1e3394f]733        self.enable_append()
734        self.enable_freeze()
735        self.enable_plot()
736        self.enable_import()
[248b918]737        self.enable_remove()
[e767897]738
[91bdf87]739    def append_theory(self, state_id, theory_list):
[bffa3d0]740        """
741        append theory object under data from a state of id = state_id
742        replace that theory if  already displayed
743        """
744        if not theory_list:
[e767897]745            return
[bffa3d0]746        if state_id not in self.list_cb_data.keys():
747            root = self.tree_ctrl_theory.root
[91bdf87]748            tree = self.tree_ctrl_theory
[bffa3d0]749        else:
750            item = self.list_cb_data[state_id]
[b2aef1c]751            data_c, _, _, _, _, _, _, _ = item
[bffa3d0]752            root = data_c
[91bdf87]753            tree = self.tree_ctrl
[bffa3d0]754        if root is not None:
[e767897]755            wx.CallAfter(self.append_theory_helper, tree=tree, root=root,
756                                       state_id=state_id,
[bffa3d0]757                                       theory_list=theory_list)
[e767897]758
759
[91bdf87]760    def append_theory_helper(self, tree, root, state_id, theory_list):
[71bd773]761        """
[5e5704d]762        Append theory helper
[71bd773]763        """
764        if state_id in self.list_cb_theory.keys():
[c70eb7c]765            #update current list of theory for this data
[71bd773]766            theory_list_ctrl = self.list_cb_theory[state_id]
[c70eb7c]767
768            for theory_id, item in theory_list.iteritems():
[5e5704d]769                theory_data, _ = item
[c70eb7c]770                if theory_data is None:
771                    name = "Unknown"
772                    theory_class = "Unknown"
773                    theory_id = "Unknown"
774                    temp = (None, None, None)
775                else:
776                    name = theory_data.name
777                    theory_class = theory_data.__class__.__name__
778                    theory_id = theory_data.id
[ee2b492]779                    #if theory_state is not None:
780                    #    name = theory_state.model.name
[c70eb7c]781                    temp = (theory_id, theory_class, state_id)
782                if theory_id not in theory_list_ctrl:
783                    #add new theory
[91bdf87]784                    t_child = tree.AppendItem(root,
[c70eb7c]785                                                    name, ct_type=1, data=temp)
[91bdf87]786                    t_i_c = tree.AppendItem(t_child, 'Info')
[e767897]787                    i_c_c = tree.AppendItem(t_i_c,
[c70eb7c]788                                                  'Type: %s' % theory_class)
[91bdf87]789                    t_p_c = tree.AppendItem(t_i_c, 'Process')
[e767897]790
[c70eb7c]791                    for process in theory_data.process:
[5e5704d]792                        tree.AppendItem(t_p_c, process.__str__())
[e767897]793                    theory_list_ctrl[theory_id] = [t_child,
794                                                   i_c_c,
[c70eb7c]795                                                   t_p_c]
796                else:
797                    #replace theory
798                    t_child, i_c_c, t_p_c = theory_list_ctrl[theory_id]
[e767897]799                    tree.SetItemText(t_child, name)
800                    tree.SetItemPyData(t_child, temp)
801                    tree.SetItemText(i_c_c, 'Type: %s' % theory_class)
802                    tree.DeleteChildren(t_p_c)
[c70eb7c]803                    for process in theory_data.process:
[5e5704d]804                        tree.AppendItem(t_p_c, process.__str__())
[e767897]805
[c70eb7c]806        else:
807            #data didn't have a theory associated it before
808            theory_list_ctrl = {}
809            for theory_id, item in theory_list.iteritems():
[d4d4c8a]810                theory_data, _ = item
[c70eb7c]811                if theory_data is not None:
[e88ebfd]812                    name = theory_data.name
[c70eb7c]813                    theory_class = theory_data.__class__.__name__
[e88ebfd]814                    theory_id = theory_data.id
[ee2b492]815                    #if theory_state is not None:
[e767897]816                    #    name = theory_state.model.name
[e88ebfd]817                    temp = (theory_id, theory_class, state_id)
[91bdf87]818                    t_child = tree.AppendItem(root,
[e767897]819                            name, ct_type=1,
[c70eb7c]820                            data=(theory_data.id, theory_class, state_id))
[91bdf87]821                    t_i_c = tree.AppendItem(t_child, 'Info')
[e767897]822                    i_c_c = tree.AppendItem(t_i_c,
[c70eb7c]823                                                  'Type: %s' % theory_class)
[91bdf87]824                    t_p_c = tree.AppendItem(t_i_c, 'Process')
[e767897]825
[c70eb7c]826                    for process in theory_data.process:
[5e5704d]827                        tree.AppendItem(t_p_c, process.__str__())
[e767897]828
[c70eb7c]829                    theory_list_ctrl[theory_id] = [t_child, i_c_c, t_p_c]
[71bd773]830                #self.list_cb_theory[data_id] = theory_list_ctrl
831                self.list_cb_theory[state_id] = theory_list_ctrl
[e767897]832
833
834
[3feed3e]835    def set_data_helper(self):
[3c44c66]836        """
[5e5704d]837        Set data helper
[3c44c66]838        """
[3feed3e]839        data_to_plot = []
[e88ebfd]840        state_to_plot = []
841        theory_to_plot = []
[c70eb7c]842        for value in self.list_cb_data.values():
[b2aef1c]843            item, _, _, _, _, _, _,  _ = value
[3feed3e]844            if item.IsChecked():
[3658717e]845                data_id, _, state_id = self.tree_ctrl.GetItemPyData(item)
846                data_to_plot.append(data_id)
847                if state_id not in state_to_plot:
848                    state_to_plot.append(state_id)
[e767897]849
[c70eb7c]850        for theory_dict in self.list_cb_theory.values():
[5e5704d]851            for _, value in theory_dict.iteritems():
[c70eb7c]852                item, _, _ = value
853                if item.IsChecked():
[e88ebfd]854                    theory_id, _, state_id = self.tree_ctrl.GetItemPyData(item)
[c70eb7c]855                    theory_to_plot.append(theory_id)
[e88ebfd]856                    if state_id not in state_to_plot:
857                        state_to_plot.append(state_id)
858        return data_to_plot, theory_to_plot, state_to_plot
[e767897]859
[c70eb7c]860    def remove_by_id(self, id):
861        """
[5e5704d]862        Remove_dat by id
[c70eb7c]863        """
864        for item in self.list_cb_data.values():
[5e5704d]865            data_c, _, _, _, _, _,  _, _ = item
[e767897]866            data_id, _, state_id = self.tree_ctrl.GetItemPyData(data_c)
[c70eb7c]867            if id == data_id:
868                self.tree_ctrl.Delete(data_c)
869                del self.list_cb_data[state_id]
870                del self.list_cb_theory[data_id]
[e767897]871
[2a62d5c]872    def load_error(self, error=None):
873        """
874        Pop up an error message.
[e767897]875
[2a62d5c]876        :param error: details error message to be displayed
877        """
[8cb8c89]878        if error is not None or str(error).strip() != "":
[e767897]879            dial = wx.MessageDialog(self.parent, str(error),
[5e5704d]880                                    'Error Loading File',
881                                    wx.OK | wx.ICON_EXCLAMATION)
[e767897]882            dial.ShowModal()
883
[2a62d5c]884    def _load_data(self, event):
885        """
[a03d419]886        send an event to the parent to trigger load from plugin module
[2a62d5c]887        """
888        if self.parent is not None:
[a03d419]889            wx.PostEvent(self.parent, NewLoadDataEvent())
[e767897]890
[a03d419]891
[3feed3e]892    def on_remove(self, event):
[18ec684]893        """
[3658717e]894        Get a list of item checked and remove them from the treectrl
[e767897]895        Ask the parent to remove reference to this item
[18ec684]896        """
[296b9c1]897        msg = "This operation will delete the data sets checked "
[6a7cf2c]898        msg += "and all the dependents."
[296b9c1]899        msg_box = wx.MessageDialog(None, msg, 'Warning', wx.OK|wx.CANCEL)
900        if msg_box.ShowModal() != wx.ID_OK:
901            return
[e767897]902
[665c083]903        data_to_remove, theory_to_remove, _ = self.set_data_helper()
904        data_key = []
905        theory_key = []
[3658717e]906        #remove  data from treectrl
907        for d_key, item in self.list_cb_data.iteritems():
[5e5704d]908            data_c, _, _, _,  _, _, _, _ = item
[665c083]909            if data_c.IsChecked():
910                self.tree_ctrl.Delete(data_c)
[3658717e]911                data_key.append(d_key)
912                if d_key in self.list_cb_theory.keys():
913                    theory_list_ctrl = self.list_cb_theory[d_key]
914                    theory_to_remove += theory_list_ctrl.keys()
[e767897]915        # Remove theory from treectrl
[5e5704d]916        for _, theory_dict in self.list_cb_theory.iteritems():
[3658717e]917            for  key, value in theory_dict.iteritems():
[665c083]918                item, _, _ = value
919                if item.IsChecked():
[e26d0db]920                    try:
921                        self.tree_ctrl.Delete(item)
922                    except:
923                        pass
[665c083]924                    theory_key.append(key)
[e767897]925
[3658717e]926        #Remove data and related theory references
[665c083]927        for key in data_key:
928            del self.list_cb_data[key]
[3658717e]929            if key in theory_key:
930                del self.list_cb_theory[key]
931        #remove theory  references independently of data
[665c083]932        for key in theory_key:
[d4d4c8a]933            for _, theory_dict in self.list_cb_theory.iteritems():
[71bd773]934                if key in theory_dict:
[e26d0db]935                    for  key, value in theory_dict.iteritems():
936                        item, _, _ = value
937                        if item.IsChecked():
938                            try:
939                                self.tree_ctrl_theory.Delete(item)
940                            except:
941                                pass
[71bd773]942                    del theory_dict[key]
[e767897]943
944
[18ec684]945        self.parent.remove_data(data_id=data_to_remove,
[665c083]946                                  theory_id=theory_to_remove)
[248b918]947        self.enable_remove()
[f7d0b74]948        self.enable_freeze()
[e26d0db]949        self.enable_remove_plot()
[e767897]950
[3feed3e]951    def on_import(self, event=None):
[3c44c66]952        """
[3feed3e]953        Get all select data and set them to the current active perspetive
[3c44c66]954        """
[3603b2e]955        if event != None:
956            event.Skip()
[e88ebfd]957        data_id, theory_id, state_id = self.set_data_helper()
[248b918]958        temp = data_id + state_id
959        self.parent.set_data(data_id=temp, theory_id=theory_id)
[e767897]960
[213892bc]961    def on_append_plot(self, event=None):
962        """
963        append plot to plot panel on focus
964        """
[0a2fdca]965        self._on_plot_selection()
[e88ebfd]966        data_id, theory_id, state_id = self.set_data_helper()
[e767897]967        self.parent.plot_data(data_id=data_id,
[e88ebfd]968                              state_id=state_id,
969                              theory_id=theory_id,
970                              append=True)
[e767897]971
[3feed3e]972    def on_plot(self, event=None):
[3c44c66]973        """
[3feed3e]974        Send a list of data names to plot
[3c44c66]975        """
[e88ebfd]976        data_id, theory_id, state_id = self.set_data_helper()
[e767897]977        self.parent.plot_data(data_id=data_id,
[e88ebfd]978                              state_id=state_id,
979                              theory_id=theory_id,
980                              append=False)
[e26d0db]981        self.enable_remove_plot()
[e767897]982
[1b1bbf9]983    def on_close_page(self, event=None):
984        """
985        On close
986        """
987        if event != None:
988            event.Skip()
989        # send parent to update menu with no show nor hide action
990        self.parent.show_data_panel(action=False)
[e767897]991
[c70eb7c]992    def on_freeze(self, event):
993        """
[2719255]994        On freeze to make a theory to a data set
[c70eb7c]995        """
[e88ebfd]996        _, theory_id, state_id = self.set_data_helper()
[2719255]997        if len(theory_id) > 0:
998            self.parent.freeze(data_id=state_id, theory_id=theory_id)
999            msg = "Freeze Theory:"
1000            msg += " The theory(s) copied to the Data box as a data set."
1001        else:
1002            msg = "Freeze Theory: Requires at least one theory checked."
1003        wx.PostEvent(self.parent, StatusEvent(status=msg))
[e767897]1004
[3feed3e]1005    def set_active_perspective(self, name):
[3c44c66]1006        """
[3feed3e]1007        set the active perspective
[3c44c66]1008        """
[600eca2]1009        self.perspective_cbox.SetStringSelection(name)
[2a62d5c]1010        self.enable_import()
[e767897]1011
[13a63ab]1012    def _on_delete_plot_panel(self, event):
1013        """
[e767897]1014        get an event with attribute name and caption to delete existing name
[13a63ab]1015        from the combobox of the current panel
1016        """
[5e5704d]1017        #name = event.name
[13a63ab]1018        caption = event.caption
1019        if self.cb_plotpanel is not None:
[e767897]1020            pos = self.cb_plotpanel.FindString(str(caption))
[13a63ab]1021            if pos != wx.NOT_FOUND:
1022                self.cb_plotpanel.Delete(pos)
1023        self.enable_append()
[e767897]1024
[83a75c5]1025    def set_panel_on_focus(self, name=None):
[3c44c66]1026        """
[3feed3e]1027        set the plot panel on focus
[3c44c66]1028        """
[f22d219]1029        if self.cb_plotpanel and self.cb_plotpanel.IsBeingDeleted():
1030            return
[5e5704d]1031        for _, value in self.parent.plot_panels.iteritems():
[0a2fdca]1032            name_plot_panel = str(value.window_caption)
1033            if name_plot_panel not in self.cb_plotpanel.GetItems():
1034                self.cb_plotpanel.Append(name_plot_panel, value)
[83a75c5]1035            if name != None and name == name_plot_panel:
1036                self.cb_plotpanel.SetStringSelection(name_plot_panel)
1037                break
[f7d0b74]1038        self.enable_append()
[e26d0db]1039        self.enable_remove_plot()
[e767897]1040
[ae84427]1041    def set_plot_unfocus(self):
1042        """
1043        Unfocus plot
1044        """
1045        return
[e767897]1046
[600eca2]1047    def _on_perspective_selection(self, event=None):
1048        """
1049        select the current perspective for guiframe
1050        """
1051        selection = self.perspective_cbox.GetSelection()
1052        if self.perspective_cbox.GetValue() != 'None':
1053            perspective = self.perspective_cbox.GetClientData(selection)
1054            perspective.on_perspective(event=None)
[e4d790f]1055            self.parent.check_multimode(perspective=perspective)
[e767897]1056
[e26d0db]1057    def _on_plot_selection(self, event=None):
[0a2fdca]1058        """
1059        On source combobox selection
1060        """
1061        if event != None:
1062            combo = event.GetEventObject()
[b113128]1063            event.Skip()
[0a2fdca]1064        else:
1065            combo = self.cb_plotpanel
1066        selection = combo.GetSelection()
1067
1068        if combo.GetValue() != 'None':
1069            panel = combo.GetClientData(selection)
[e767897]1070            self.parent.on_set_plot_focus(panel)
1071
[e26d0db]1072    def on_close_plot(self, event):
1073        """
1074        clseo the panel on focus
[e767897]1075        """
[e26d0db]1076        self.enable_append()
1077        selection = self.cb_plotpanel.GetSelection()
1078        if self.cb_plotpanel.GetValue() != 'None':
1079            panel = self.cb_plotpanel.GetClientData(selection)
1080            if self.parent is not None and panel is not None:
[e767897]1081                wx.PostEvent(self.parent,
[e26d0db]1082                             NewPlotEvent(group_id=panel.group_id,
1083                                          action="delete"))
1084        self.enable_remove_plot()
[e767897]1085
[ae84427]1086    def set_frame(self, frame):
1087        """
1088        """
1089        self.frame = frame
[e767897]1090
[ae84427]1091    def get_frame(self):
1092        """
1093        """
[e767897]1094        return self.frame
1095
[1941e6a]1096    def on_help(self, event):
1097        """
1098        Bring up the data manager Documentation whenever
1099        the HELP button is clicked.
1100
1101        Calls DocumentationWindow with the path of the location within the
1102        documentation tree (after /doc/ ....".  Note that when using old
1103        versions of Wx (before 2.9) and thus not the release version of
1104        installers, the help comes up at the top level of the file as
1105        webbrowser does not pass anything past the # to the browser when it is
1106        running "file:///...."
1107
1108    :param evt: Triggers on clicking the help button
1109    """
1110
1111        #import documentation window here to avoid circular imports
1112        #if put at top of file with rest of imports.
1113        from documentation_window import DocumentationWindow
1114
1115        _TreeLocation = "user/sasgui/guiframe/data_explorer_help.html"
1116        _doc_viewer = DocumentationWindow(self, -1, _TreeLocation, "",
1117                                          "Data Explorer Help")
1118
[af72b2e]1119    def on_close(self, event):
1120        """
1121        On close event
1122        """
1123        self.parent.show_data_panel(event)
[e767897]1124
[ae84427]1125    def set_schedule_full_draw(self, panel=None, func='del'):
1126        """
1127        Send full draw to guimanager
1128        """
1129        self.parent.set_schedule_full_draw(panel, func)
[e767897]1130
[e26d0db]1131    def enable_remove_plot(self):
1132        """
1133        enable remove plot button if there is a plot panel on focus
1134        """
[c5a769e]1135        pass
1136        #if self.cb_plotpanel.GetCount() == 0:
1137        #    self.bt_close_plot.Disable()
1138        #else:
1139        #    self.bt_close_plot.Enable()
[e767897]1140
[2a62d5c]1141    def enable_remove(self):
1142        """
1143        enable or disable remove button
1144        """
1145        n_t = self.tree_ctrl.GetCount()
1146        n_t_t = self.tree_ctrl_theory.GetCount()
1147        if n_t + n_t_t <= 0:
1148            self.bt_remove.Disable()
1149        else:
1150            self.bt_remove.Enable()
[e767897]1151
[2a62d5c]1152    def enable_import(self):
1153        """
1154        enable or disable send button
1155        """
[61ffd1e]1156        n_t = 0
1157        if self.tree_ctrl != None:
1158            n_t = self.tree_ctrl.GetCount()
[600eca2]1159        if n_t > 0 and len(self.list_of_perspective) > 0:
1160            self.bt_import.Enable()
1161        else:
[2a62d5c]1162            self.bt_import.Disable()
[600eca2]1163        if len(self.list_of_perspective) <= 0 or \
1164            self.perspective_cbox.GetValue()  in ["None",
1165                                                "No Active Application"]:
1166            self.perspective_cbox.Disable()
[2a62d5c]1167        else:
[600eca2]1168            self.perspective_cbox.Enable()
[e767897]1169
[f7d0b74]1170    def enable_plot(self):
1171        """
1172        enable or disable plot button
1173        """
[e767897]1174        n_t = 0
[600eca2]1175        n_t_t = 0
1176        if self.tree_ctrl != None:
1177            n_t = self.tree_ctrl.GetCount()
1178        if self.tree_ctrl_theory != None:
1179            n_t_t = self.tree_ctrl_theory.GetCount()
[f7d0b74]1180        if n_t + n_t_t <= 0:
1181            self.bt_plot.Disable()
1182        else:
1183            self.bt_plot.Enable()
[5e8e615]1184        self.enable_append()
[e767897]1185
[f7d0b74]1186    def enable_append(self):
1187        """
1188        enable or disable append button
1189        """
[e767897]1190        n_t = 0
[600eca2]1191        n_t_t = 0
1192        if self.tree_ctrl != None:
1193            n_t = self.tree_ctrl.GetCount()
1194        if self.tree_ctrl_theory != None:
1195            n_t_t = self.tree_ctrl_theory.GetCount()
[e767897]1196        if n_t + n_t_t <= 0:
[f7d0b74]1197            self.bt_append_plot.Disable()
[600eca2]1198            self.cb_plotpanel.Disable()
[5e8e615]1199        elif self.cb_plotpanel.GetCount() <= 0:
[5e5704d]1200            self.cb_plotpanel.Disable()
1201            self.bt_append_plot.Disable()
[f7d0b74]1202        else:
1203            self.bt_append_plot.Enable()
[df8cc63]1204            self.cb_plotpanel.Enable()
[e767897]1205
[1e3394f]1206    def check_theory_to_freeze(self):
1207        """
[d4d4c8a]1208        Check_theory_to_freeze
[1e3394f]1209        """
[f7d0b74]1210    def enable_freeze(self):
1211        """
1212        enable or disable the freeze button
1213        """
[61ffd1e]1214        n_t_t = 0
1215        n_l = 0
1216        if self.tree_ctrl_theory != None:
1217            n_t_t = self.tree_ctrl_theory.GetCount()
[f7d0b74]1218        n_l = len(self.list_cb_theory)
[5e8e615]1219        if (n_t_t + n_l > 0):
[f7d0b74]1220            self.bt_freeze.Enable()
[1e3394f]1221        else:
1222            self.bt_freeze.Disable()
[e767897]1223
[61ffd1e]1224    def enable_selection(self):
1225        """
1226        enable or disable combobo box selection
1227        """
1228        n_t = 0
1229        n_t_t = 0
1230        if self.tree_ctrl != None:
1231            n_t = self.tree_ctrl.GetCount()
1232        if self.tree_ctrl_theory != None:
1233            n_t_t = self.tree_ctrl_theory.GetCount()
1234        if n_t + n_t_t > 0 and self.selection_cbox != None:
1235            self.selection_cbox.Enable()
1236        else:
1237            self.selection_cbox.Disable()
[e767897]1238
[a03d419]1239    def show_data_button(self):
1240        """
[e767897]1241        show load data and remove data button if
[a03d419]1242        dataloader on else hide them
1243        """
1244        try:
1245            gui_style = self.parent.get_style()
1246            style = gui_style & GUIFRAME.DATALOADER_ON
[e767897]1247            if style == GUIFRAME.DATALOADER_ON:
[a03d419]1248                #self.bt_remove.Show(True)
[e767897]1249                self.bt_add.Show(True)
[a03d419]1250            else:
1251                #self.bt_remove.Hide()
1252                self.bt_add.Hide()
[e767897]1253        except:
[a03d419]1254            #self.bt_remove.Hide()
[e767897]1255            self.bt_add.Hide()
1256
[60fff67]1257
1258
1259WIDTH = 400
1260HEIGHT = 300
1261
1262
1263class DataDialog(wx.Dialog):
1264    """
1265    Allow file selection at loading time
1266    """
1267    def __init__(self, data_list, parent=None, text='', *args, **kwds):
1268        wx.Dialog.__init__(self, parent, *args, **kwds)
1269        self.SetTitle("Data Selection")
1270        self.SetSize((WIDTH, HEIGHT))
1271        self.list_of_ctrl = []
1272        if not data_list:
[e767897]1273            return
[60fff67]1274        self._sizer_main = wx.BoxSizer(wx.VERTICAL)
1275        self._sizer_txt = wx.BoxSizer(wx.VERTICAL)
1276        self._sizer_button = wx.BoxSizer(wx.HORIZONTAL)
1277        self.sizer = wx.GridBagSizer(5, 5)
1278        self._panel = ScrolledPanel(self, style=wx.RAISED_BORDER,
1279                               size=(WIDTH-20, HEIGHT-50))
1280        self._panel.SetupScrolling()
1281        self.__do_layout(data_list, text=text)
[e767897]1282
[60fff67]1283    def __do_layout(self, data_list, text=''):
1284        """
1285        layout the dialog
1286        """
1287        if not data_list or len(data_list) <= 1:
[e767897]1288            return
[60fff67]1289        #add text
[e767897]1290
[60fff67]1291        text = "Deleting these file reset some panels.\n"
1292        text += "Do you want to proceed?\n"
1293        text_ctrl = wx.StaticText(self, -1, str(text))
1294        self._sizer_txt.Add(text_ctrl)
1295        iy = 0
1296        ix = 0
[5e5704d]1297        #data_count = 0
[60fff67]1298        for (data_name, in_use, sub_menu) in range(len(data_list)):
1299            if in_use == True:
1300                ctrl_name = wx.StaticBox(self, -1, str(data_name))
1301                ctrl_in_use = wx.StaticBox(self, -1, " is used by ")
1302                plug_name = str(sub_menu) + "\n"
[5e5704d]1303                #ctrl_sub_menu = wx.StaticBox(self, -1, plug_name)
[60fff67]1304                self.sizer.Add(ctrl_name, (iy, ix),
1305                           (1, 1), wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
1306                ix += 1
1307                self._sizer_button.Add(ctrl_in_use, 1,
1308                                        wx.EXPAND|wx.ADJUST_MINSIZE, 0)
1309                ix += 1
1310                self._sizer_button.Add(plug_name, 1,
1311                                        wx.EXPAND|wx.ADJUST_MINSIZE, 0)
1312            iy += 1
1313        self._panel.SetSizer(self.sizer)
1314        #add sizer
1315        self._sizer_button.Add((20, 20), 1, wx.EXPAND|wx.ADJUST_MINSIZE, 0)
1316        button_cancel = wx.Button(self, wx.ID_CANCEL, "Cancel")
1317        self._sizer_button.Add(button_cancel, 0,
1318                          wx.LEFT|wx.RIGHT|wx.ADJUST_MINSIZE, 10)
1319        button_OK = wx.Button(self, wx.ID_OK, "Ok")
1320        button_OK.SetFocus()
1321        self._sizer_button.Add(button_OK, 0,
1322                                wx.LEFT|wx.RIGHT|wx.ADJUST_MINSIZE, 10)
1323        static_line = wx.StaticLine(self, -1)
[e767897]1324
[60fff67]1325        self._sizer_txt.Add(self._panel, 1, wx.EXPAND|wx.LEFT|wx.RIGHT, 5)
1326        self._sizer_main.Add(self._sizer_txt, 1, wx.EXPAND|wx.ALL, 10)
[e767897]1327        #self._sizer_main.Add(self._data_text_ctrl, 0,
[38226d26]1328        #                     wx.EXPAND|wx.LEFT|wx.RIGHT, 10)
[60fff67]1329        self._sizer_main.Add(static_line, 0, wx.EXPAND, 0)
1330        self._sizer_main.Add(self._sizer_button, 0, wx.EXPAND|wx.ALL, 10)
1331        self.SetSizer(self._sizer_main)
1332        self.Layout()
[e767897]1333
[60fff67]1334    def get_data(self):
1335        """
1336        return the selected data
1337        """
1338        temp = []
1339        for item in self.list_of_ctrl:
1340            cb, data = item
1341            if cb.GetValue():
1342                temp.append(data)
1343        return temp
[e767897]1344
[3c44c66]1345class DataFrame(wx.Frame):
[5e5704d]1346    """
1347    Data Frame
1348    """
[3feed3e]1349    ## Internal name for the AUI manager
1350    window_name = "Data Panel"
1351    ## Title to appear on top of the window
1352    window_caption = "Data Panel"
1353    ## Flag to tell the GUI manager that this panel is not
1354    #  tied to any perspective
1355    ALWAYS_ON = True
[e767897]1356
[5e5704d]1357    def __init__(self, parent=None, owner=None, manager=None, size=(300, 800),
1358                         list_of_perspective=[], list=[], *args, **kwds):
[cc061c3]1359        kwds['size'] = size
[3c44c66]1360        kwds['id'] = -1
[5e5704d]1361        kwds['title'] = "Loaded Data"
[3c44c66]1362        wx.Frame.__init__(self, parent=parent, *args, **kwds)
1363        self.parent = parent
1364        self.owner = owner
[ae84427]1365        self._manager = manager
[e767897]1366        self.panel = DataPanel(parent=self,
[ae84427]1367                               manager=manager,
[32c0841]1368                               list_of_perspective=list_of_perspective)
[e767897]1369
[3feed3e]1370    def load_data_list(self, list=[]):
[3c44c66]1371        """
1372        Fill the list inside its panel
1373        """
[3feed3e]1374        self.panel.load_data_list(list=list)
[e767897]1375
1376
1377
[d85c194]1378from sas.sasgui.guiframe.dataFitting import Theory1D
1379from sas.sasgui.guiframe.data_state import DataState
[5e5704d]1380
[3feed3e]1381class State():
[5e5704d]1382    """
1383    DataPanel State
1384    """
[3feed3e]1385    def __init__(self):
1386        self.msg = ""
1387    def __str__(self):
1388        self.msg = "model mane : model1\n"
1389        self.msg += "params : \n"
1390        self.msg += "name  value\n"
[dc0cfa4]1391        return self.msg
[e767897]1392
[71bd773]1393def set_data_state(data=None, path=None, theory=None, state=None):
[5e5704d]1394    """
1395    Set data state
1396    """
[3feed3e]1397    dstate = DataState(data=data)
1398    dstate.set_path(path=path)
[c70eb7c]1399    dstate.set_theory(theory, state)
[e767897]1400
[3feed3e]1401    return dstate
[e767897]1402
[3c44c66]1403if __name__ == "__main__":
[e767897]1404
[3c44c66]1405    app = wx.App()
[3feed3e]1406    try:
[5e5704d]1407        #list_of_perspective = [('perspective2', False), ('perspective1', True)]
1408        data_list1 = {}
[c70eb7c]1409        # state 1
[5e5704d]1410        data1 = Data2D()
1411        data1.name = "data2"
1412        data1.id = 1
1413        data1.append_empty_process()
1414        process1 = data1.process[len(data1.process)-1]
1415        process1.data = "07/01/2010"
[4cc25e9]1416        theory1 = Data2D()
1417        theory1.id = 34
1418        theory1.name = "theory1"
1419        path1 = "path1"
[5e5704d]1420        state1 = State()
[4cc25e9]1421        data_list1['1'] = set_data_state(data1, path1, theory1, state1)
[c70eb7c]1422        #state 2
[5e5704d]1423        data1 = Data2D()
1424        data1.name = "data2"
1425        data1.id = 76
[4cc25e9]1426        theory1 = Data2D()
1427        theory1.id = 78
1428        theory1.name = "CoreShell 07/24/25"
1429        path1 = "path2"
[c70eb7c]1430        #state3
[5e5704d]1431        state1 = State()
[4cc25e9]1432        data_list1['2'] = set_data_state(data1, path1, theory1, state1)
[5e5704d]1433        data1 = Data1D()
1434        data1.id = 3
1435        data1.name = "data2"
[4cc25e9]1436        theory1 = Theory1D()
1437        theory1.name = "CoreShell"
1438        theory1.id = 4
1439        theory1.append_empty_process()
1440        process1 = theory1.process[len(theory1.process)-1]
[5e5704d]1441        process1.description = "this is my description"
[4cc25e9]1442        path1 = "path3"
[5e5704d]1443        data1.append_empty_process()
1444        process1 = data1.process[len(data1.process)-1]
1445        process1.data = "07/22/2010"
[4cc25e9]1446        data_list1['4'] = set_data_state(data1, path1, theory1, state1)
[c70eb7c]1447        #state 4
1448        temp_data_list = {}
[5e5704d]1449        data1.name = "data5 erasing data2"
[4cc25e9]1450        temp_data_list['4'] = set_data_state(data1, path1, theory1, state1)
[c70eb7c]1451        #state 5
[5e5704d]1452        data1 = Data2D()
1453        data1.name = "data3"
1454        data1.id = 5
1455        data1.append_empty_process()
[d4d4c8a]1456        process1 = data1.process[len(data1.process)-1]
[5e5704d]1457        process1.data = "07/01/2010"
[4cc25e9]1458        theory1 = Theory1D()
1459        theory1.name = "Cylinder"
1460        path1 = "path2"
[5e5704d]1461        state1 = State()
[4cc25e9]1462        dstate1 = set_data_state(data1, path1, theory1, state1)
1463        theory1 = Theory1D()
1464        theory1.id = 6
1465        theory1.name = "CoreShell"
1466        dstate1.set_theory(theory1)
1467        theory1 = Theory1D()
1468        theory1.id = 6
1469        theory1.name = "CoreShell replacing coreshell in data3"
1470        dstate1.set_theory(theory1)
[d4d4c8a]1471        data_list1['3'] = dstate1
[c70eb7c]1472        #state 6
[4cc25e9]1473        data_list1['6'] = set_data_state(None, path1, theory1, state1)
1474        data_list1['6'] = set_data_state(theory=theory1, state=None)
1475        theory1 = Theory1D()
1476        theory1.id = 7
1477        data_list1['6'] = set_data_state(theory=theory1, state=None)
1478        data_list1['7'] = set_data_state(theory=theory1, state=None)
[5e5704d]1479        window = DataFrame(list=data_list1)
1480        window.load_data_list(list=data_list1)
[3feed3e]1481        window.Show(True)
[c70eb7c]1482        window.load_data_list(list=temp_data_list)
[3feed3e]1483    except:
1484        #raise
[5e5704d]1485        print "error", sys.exc_value
[e767897]1486
1487    app.MainLoop()
Note: See TracBrowser for help on using the repository browser.