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

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

Auto expand data and theory trees once data is in list.

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