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

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.2ticket-1009ticket-1094-headlessticket-1242-2d-resolutionticket-1243ticket-1249ticket885unittest-saveload
Last change on this file since dc8a553 was b5c44f0, checked in by butler, 8 years ago

closes ticket:599. Help button on DataManager? Panel is no longer
stretchable.

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