################################################################################
#This software was developed by the University of Tennessee as part of the
#Distributed Data Analysis of Neutron Scattering Experiments (DANSE)
#project funded by the US National Science Foundation.
#
#See the license text in license.txt
#
#copyright 2010, University of Tennessee
################################################################################
"""
This module provides Graphic interface for the data_manager module.
"""
import wx
from wx.build import build_options
# Check version
toks = str(wx.__version__).split('.')
if int(toks[1]) < 9:
if int(toks[2]) < 12:
wx_version = 811
else:
wx_version = 812
else:
wx_version = 900
import sys
from wx.lib.scrolledpanel import ScrolledPanel
import wx.lib.agw.customtreectrl as CT
from sas.guiframe.dataFitting import Data1D
from sas.guiframe.dataFitting import Data2D
from sas.guiframe.panel_base import PanelBase
from sas.guiframe.events import StatusEvent
from sas.guiframe.events import EVT_DELETE_PLOTPANEL
from sas.guiframe.events import NewLoadDataEvent
from sas.guiframe.events import NewPlotEvent
from sas.guiframe.gui_style import GUIFRAME
from sas.guiframe.events import NewBatchEvent
from sas.dataloader.loader import Loader
#from sas.guiframe.local_perspectives.plotting.masking \
# import FloatPanel as QucikPlotDialog
from sas.guiframe.local_perspectives.plotting.SimplePlot import PlotFrame \
as QucikPlotDialog
import sas.guiframe.config as config
extension_list = []
if config.APPLICATION_STATE_EXTENSION is not None:
extension_list.append(config.APPLICATION_STATE_EXTENSION)
EXTENSIONS = config.PLUGIN_STATE_EXTENSIONS + extension_list
PLUGINS_WLIST = config.PLUGINS_WLIST
APPLICATION_WLIST = config.APPLICATION_WLIST
#Control panel width
if sys.platform.count("win32") > 0:
PANEL_WIDTH = 235
PANEL_HEIGHT = 700
CBOX_WIDTH = 140
BUTTON_WIDTH = 80
FONT_VARIANT = 0
IS_MAC = False
else:
PANEL_WIDTH = 255
PANEL_HEIGHT = 750
CBOX_WIDTH = 155
BUTTON_WIDTH = 100
FONT_VARIANT = 1
IS_MAC = True
STYLE_FLAG = wx.RAISED_BORDER|CT.TR_HAS_BUTTONS| CT.TR_HIDE_ROOT|\
wx.WANTS_CHARS|CT.TR_HAS_VARIABLE_ROW_HEIGHT
[docs]class DataTreeCtrl(CT.CustomTreeCtrl):
"""
Check list control to be used for Data Panel
"""
def __init__(self, parent, *args, **kwds):
#agwstyle is introduced in wx.2.8.11 but is not working for mac
if IS_MAC and wx_version < 812:
try:
kwds['style'] = STYLE_FLAG
CT.CustomTreeCtrl.__init__(self, parent, *args, **kwds)
except:
del kwds['style']
CT.CustomTreeCtrl.__init__(self, parent, *args, **kwds)
else:
# agwstyle is introduced in wx.2.8.11
# argument working only for windows
try:
kwds['agwStyle'] = STYLE_FLAG
CT.CustomTreeCtrl.__init__(self, parent, *args, **kwds)
except:
try:
del kwds['agwStyle']
kwds['style'] = STYLE_FLAG
CT.CustomTreeCtrl.__init__(self, parent, *args, **kwds)
except:
del kwds['style']
CT.CustomTreeCtrl.__init__(self, parent, *args, **kwds)
self.root = self.AddRoot("Available Data")
[docs] def OnCompareItems(self, item1, item2):
"""
Overrides OnCompareItems in wx.TreeCtrl.
Used by the SortChildren method.
"""
# Get the item data
data_1 = self.GetItemText(item1)
data_2 = self.GetItemText(item2)
# Compare the item data
if data_1 < data_2:
return -1
elif data_1 > data_2:
return 1
else:
return 0
[docs]class DataPanel(ScrolledPanel, PanelBase):
"""
This panel displays data available in the application and widgets to
interact with data.
"""
## Internal name for the AUI manager
window_name = "Data Panel"
## Title to appear on top of the window
window_caption = "Data Explorer"
#type of window
window_type = "Data Panel"
## Flag to tell the GUI manager that this panel is not
# tied to any perspective
#ALWAYS_ON = True
def __init__(self, parent,
list=None,
size=(PANEL_WIDTH, PANEL_HEIGHT),
id=-1,
list_of_perspective=None, manager=None, *args, **kwds):
#kwds['size'] = size
#kwds['style'] = STYLE_FLAG
ScrolledPanel.__init__(self, parent=parent, id=id, *args, **kwds)
PanelBase.__init__(self, parent)
self.SetupScrolling()
#Set window's font size
self.SetWindowVariant(variant=FONT_VARIANT)
self.loader = Loader()
#Default location
self._default_save_location = None
self.all_data1d = True
self.parent = parent.parent
self._manager = manager
self.frame = parent
if list is None:
list = []
self.list_of_data = list
if list_of_perspective is None:
list_of_perspective = []
self.list_of_perspective = list_of_perspective
self.list_rb_perspectives = []
self.list_cb_data = {}
self.list_cb_theory = {}
self.tree_ctrl = None
self.tree_ctrl_theory = None
self.perspective_cbox = None
## Create context menu for page
self.data_menu = None
self.popUpMenu = None
self.plot3d_id = None
self.editmask_id = None
# Default attr
self.vbox = None
self.sizer1 = None
self.sizer2 = None
self.sizer3 = None
self.sizer4 = None
self.sizer5 = None
self.selection_cbox = None
self.bt_add = None
self.bt_remove = None
self.bt_import = None
self.bt_append_plot = None
self.bt_plot = None
self.bt_freeze = None
self.cb_plotpanel = None
self.rb_single_mode = None
self.rb_batch_mode = None
self.owner = None
self.do_layout()
self.fill_cbox_analysis(self.list_of_perspective)
self.Bind(wx.EVT_SHOW, self.on_close_page)
if self.parent is not None:
self.parent.Bind(EVT_DELETE_PLOTPANEL, self._on_delete_plot_panel)
[docs] def do_layout(self):
"""
Create the panel layout
"""
self.define_panel_structure()
self.layout_selection()
self.layout_data_list()
self.layout_batch()
self.layout_button()
[docs] def disable_app_combo(self, enable):
"""
Disable app combo box
"""
self.perspective_cbox.Enable(enable)
[docs] def define_panel_structure(self):
"""
Define the skeleton of the panel
"""
w, h = self.parent.GetSize()
self.vbox = wx.BoxSizer(wx.VERTICAL)
self.sizer1 = wx.BoxSizer(wx.VERTICAL)
self.sizer1.SetMinSize(wx.Size(w/13, h*2/5))
self.sizer2 = wx.BoxSizer(wx.VERTICAL)
self.sizer3 = wx.FlexGridSizer(9, 2, 4, 1)
self.sizer4 = wx.BoxSizer(wx.VERTICAL)
self.sizer5 = wx.BoxSizer(wx.VERTICAL)
self.vbox.Add(self.sizer5, 0, wx.EXPAND|wx.ALL, 1)
self.vbox.Add(self.sizer1, 1, wx.EXPAND|wx.ALL, 0)
self.vbox.Add(self.sizer2, 0, wx.EXPAND|wx.ALL, 1)
self.vbox.Add(self.sizer3, 0, wx.EXPAND|wx.ALL, 10)
#self.vbox.Add(self.sizer4, 0, wx.EXPAND|wx.ALL,5)
self.SetSizer(self.vbox)
[docs] def layout_selection(self):
"""
Create selection option combo box
"""
select_txt = wx.StaticText(self, -1, 'Selection Options')
select_txt.SetForegroundColour('blue')
self.selection_cbox = wx.ComboBox(self, -1, style=wx.CB_READONLY)
list_of_options = ['Select all Data',
'Unselect all Data',
'Select all Data 1D',
'Unselect all Data 1D',
'Select all Data 2D',
'Unselect all Data 2D' ]
for option in list_of_options:
self.selection_cbox.Append(str(option))
self.selection_cbox.SetValue('Select all Data')
wx.EVT_COMBOBOX(self.selection_cbox, -1, self._on_selection_type)
self.sizer5.AddMany([(select_txt, 0, wx.ALL, 5),
(self.selection_cbox, 0, wx.ALL,5)])
self.enable_selection()
def _on_selection_type(self, event):
"""
Select data according to patterns
:param event: UI event
"""
option = self.selection_cbox.GetValue()
pos = self.selection_cbox.GetSelection()
if pos == wx.NOT_FOUND:
return
option = self.selection_cbox.GetString(pos)
for item in self.list_cb_data.values():
data_ctrl, _, _, _, _, _, _, _ = item
_, data_class, _ = self.tree_ctrl.GetItemPyData(data_ctrl)
if option == 'Select all Data':
self.tree_ctrl.CheckItem(data_ctrl, True)
elif option == 'Unselect all Data':
self.tree_ctrl.CheckItem(data_ctrl, False)
elif option == 'Select all Data 1D':
if data_class == 'Data1D':
self.tree_ctrl.CheckItem(data_ctrl, True)
elif option == 'Unselect all Data 1D':
if data_class == 'Data1D':
self.tree_ctrl.CheckItem(data_ctrl, False)
elif option == 'Select all Data 1D':
if data_class == 'Data1D':
self.tree_ctrl.CheckItem(data_ctrl, True)
elif option == 'Select all Data 2D':
if data_class == 'Data2D':
self.tree_ctrl.CheckItem(data_ctrl, True)
elif option == 'Unselect all Data 2D':
if data_class == 'Data2D':
self.tree_ctrl.CheckItem(data_ctrl, False)
self.enable_append()
self.enable_freeze()
self.enable_plot()
self.enable_import()
self.enable_remove()
[docs] def layout_batch(self):
"""
Set up batch mode options
"""
self.rb_single_mode = wx.RadioButton(self, -1, 'Single Mode',
style=wx.RB_GROUP)
self.rb_batch_mode = wx.RadioButton(self, -1, 'Batch Mode')
self.Bind(wx.EVT_RADIOBUTTON, self.on_single_mode,
id=self.rb_single_mode.GetId())
self.Bind(wx.EVT_RADIOBUTTON, self.on_batch_mode,
id=self.rb_batch_mode.GetId())
self.rb_single_mode.SetValue(not self.parent.batch_on)
self.rb_batch_mode.SetValue(self.parent.batch_on)
self.sizer4.AddMany([(self.rb_single_mode, 0, wx.ALL, 4),
(self.rb_batch_mode, 0, wx.ALL, 4)])
[docs] def on_single_mode(self, event):
"""
Change to single mode
:param event: UI event
"""
if self.parent is not None:
wx.PostEvent(self.parent, NewBatchEvent(enable=False))
[docs] def on_batch_mode(self, event):
"""
Change to batch mode
:param event: UI event
"""
if self.parent is not None:
wx.PostEvent(self.parent,
NewBatchEvent(enable=True))
def _get_data_selection(self, event):
"""
Get data selection from the right click
:param event: UI event
"""
data = None
#selection = event.GetSelection()
id, _, _ = self.FindFocus().GetSelection().GetData()
data_list, theory_list = \
self.parent.get_data_manager().get_by_id(id_list=[id])
if data_list:
data = data_list.values()[0]
if data == None:
data = theory_list.values()[0][0]
return data
[docs] def on_edit_data(self, event):
"""
Pop Up Data Editor
"""
data = self._get_data_selection(event)
from sas.guiframe.local_perspectives.plotting.masking \
import MaskPanel as MaskDialog
panel = MaskDialog(parent=self.parent, base=self,
data=data, id=wx.NewId())
panel.ShowModal()
[docs] def on_plot_3d(self, event):
"""
Frozen image of 3D
"""
data = self._get_data_selection(event)
from sas.guiframe.local_perspectives.plotting.masking \
import FloatPanel as Float3dDialog
panel = Float3dDialog(base=self, data=data,
dimension=3, id=wx.NewId())
panel.ShowModal()
[docs] def on_quick_plot(self, event):
"""
Frozen plot
"""
data = self._get_data_selection(event)
if data.__class__.__name__ == "Data2D":
dimension = 2
else:
dimension = 1
#panel = QucikPlotDialog(base=self, data=data,
# dimension=dimension, id=wx.NewId())
frame = QucikPlotDialog(self, -1, "Plot " + data.name, 'log_{10}')
self.parent.put_icon(frame)
frame.add_plot(data)
#frame.SetTitle(title)
frame.Show(True)
frame.SetFocus()
#panel.ShowModal()
[docs] def on_data_info(self, event):
"""
Data Info panel
"""
data = self._get_data_selection(event)
if data.__class__.__name__ == "Data2D":
self.parent.show_data2d(data, data.name)
else:
self.parent.show_data1d(data, data.name)
[docs] def on_save_as(self, event):
"""
Save data as a file
"""
data = self._get_data_selection(event)
#path = None
default_name = data.name
if default_name.count('.') > 0:
default_name = default_name.split('.')[0]
default_name += "_out"
if self.parent != None:
if issubclass(data.__class__, Data1D):
self.parent.save_data1d(data, default_name)
elif issubclass(data.__class__, Data2D):
self.parent.save_data2d(data, default_name)
else:
print "unable to save this type of data"
[docs] def layout_data_list(self):
"""
Add a listcrtl in the panel
"""
tree_ctrl_label = wx.StaticText(self, -1, "Data")
tree_ctrl_label.SetForegroundColour('blue')
self.tree_ctrl = DataTreeCtrl(parent=self, style=wx.SUNKEN_BORDER)
self.tree_ctrl.Bind(CT.EVT_TREE_ITEM_CHECKING, self.on_check_item)
self.tree_ctrl.Bind(CT.EVT_TREE_ITEM_MENU, self.on_right_click_data)
## Create context menu for page
self.data_menu = wx.Menu()
id = wx.NewId()
name = "Data Info"
msg = "Show Data Info"
self.data_menu.Append(id, name, msg)
wx.EVT_MENU(self, id, self.on_data_info)
id = wx.NewId()
name = "Save As"
msg = "Save Theory/Data as a file"
self.data_menu.Append(id, name, msg)
wx.EVT_MENU(self, id, self.on_save_as)
quickplot_id = wx.NewId()
name = "Quick Plot"
msg = "Plot the current Data"
self.data_menu.Append(quickplot_id, name, msg)
wx.EVT_MENU(self, quickplot_id, self.on_quick_plot)
self.plot3d_id = wx.NewId()
name = "Quick 3DPlot (Slow)"
msg = "Plot3D the current 2D Data"
self.data_menu.Append(self.plot3d_id, name, msg)
wx.EVT_MENU(self, self.plot3d_id, self.on_plot_3d)
self.editmask_id = wx.NewId()
name = "Edit Mask"
msg = "Edit Mask for the current 2D Data"
self.data_menu.Append(self.editmask_id, name, msg)
wx.EVT_MENU(self, self.editmask_id, self.on_edit_data)
tree_ctrl_theory_label = wx.StaticText(self, -1, "Theory")
tree_ctrl_theory_label.SetForegroundColour('blue')
self.tree_ctrl_theory = DataTreeCtrl(parent=self,
style=wx.SUNKEN_BORDER)
self.tree_ctrl_theory.Bind(CT.EVT_TREE_ITEM_CHECKING,
self.on_check_item)
self.tree_ctrl_theory.Bind(CT.EVT_TREE_ITEM_MENU,
self.on_right_click_theory)
self.sizer1.Add(tree_ctrl_label, 0, wx.LEFT, 10)
self.sizer1.Add(self.tree_ctrl, 1, wx.EXPAND|wx.ALL, 10)
self.sizer1.Add(tree_ctrl_theory_label, 0, wx.LEFT, 10)
self.sizer1.Add(self.tree_ctrl_theory, 1, wx.EXPAND|wx.ALL, 10)
[docs] def on_right_click_theory(self, event):
"""
On click theory data
"""
try:
id, data_class_name, _ = \
self.tree_ctrl_theory.GetSelection().GetData()
_, _ = self.parent.get_data_manager().get_by_id(id_list=[id])
except:
return
if self.data_menu is not None:
menu_enable = (data_class_name == "Data2D")
self.data_menu.Enable(self.editmask_id, False)
self.data_menu.Enable(self.plot3d_id, menu_enable)
self.PopupMenu(self.data_menu)
[docs] def on_right_click_data(self, event):
"""
Allow Editing Data
"""
#selection = event.GetSelection()
is_data = True
try:
id, data_class_name, _ = self.tree_ctrl.GetSelection().GetData()
data_list, _ = \
self.parent.get_data_manager().get_by_id(id_list=[id])
if not data_list:
is_data = False
except:
return
if self.data_menu is not None:
menu_enable = (data_class_name == "Data2D")
maskmenu_enable = (menu_enable and is_data)
self.data_menu.Enable(self.editmask_id, maskmenu_enable)
self.data_menu.Enable(self.plot3d_id, menu_enable)
self.PopupMenu(self.data_menu)
[docs] def on_check_item(self, event):
"""
On check item
"""
item = event.GetItem()
item.Check(not item.IsChecked())
self.enable_append()
self.enable_freeze()
self.enable_plot()
self.enable_import()
self.enable_remove()
event.Skip()
[docs] def fill_cbox_analysis(self, plugin):
"""
fill the combobox with analysis name
"""
self.list_of_perspective = plugin
if self.parent is None or \
not hasattr(self.parent, "get_current_perspective") or \
len(self.list_of_perspective) == 0:
return
if self.parent is not None and self.perspective_cbox is not None:
for plug in self.list_of_perspective:
if plug.get_perspective():
self.perspective_cbox.Append(plug.sub_menu, plug)
curr_pers = self.parent.get_current_perspective()
if curr_pers:
self.perspective_cbox.SetStringSelection(curr_pers.sub_menu)
self.enable_import()
[docs] def load_data_list(self, list):
"""
add need data with its theory under the tree
"""
if list:
for state_id, dstate in list.iteritems():
data = dstate.get_data()
theory_list = dstate.get_theory()
if data is not None:
data_name = str(data.name)
data_title = str(data.title)
data_run = str(data.run)
data_class = data.__class__.__name__
path = dstate.get_path()
process_list = data.process
data_id = data.id
s_path = str(path)
if state_id not in self.list_cb_data:
#new state
data_c = self.tree_ctrl.InsertItem(self.tree_ctrl.root,
0, data_name, ct_type=1,
data=(data_id, data_class, state_id))
data_c.Check(True)
d_i_c = self.tree_ctrl.AppendItem(data_c, 'Info')
d_t_c = self.tree_ctrl.AppendItem(d_i_c,
'Title: %s' % data_title)
r_n_c = self.tree_ctrl.AppendItem(d_i_c,
'Run: %s' % data_run)
i_c_c = self.tree_ctrl.AppendItem(d_i_c,
'Type: %s' % data_class)
p_c_c = self.tree_ctrl.AppendItem(d_i_c,
"Path: '%s'" % s_path)
d_p_c = self.tree_ctrl.AppendItem(d_i_c, 'Process')
for process in process_list:
process_str = str(process).replace('\n',' ')
if len(process_str)>20:
process_str = process_str[:20]+' [...]'
self.tree_ctrl.AppendItem(d_p_c, process_str)
theory_child = self.tree_ctrl.AppendItem(data_c,
"THEORIES")
self.list_cb_data[state_id] = [data_c,
d_i_c,
d_t_c,
r_n_c,
i_c_c,
p_c_c,
d_p_c,
theory_child]
else:
data_ctrl_list = self.list_cb_data[state_id]
#This state is already display replace it contains
data_c, d_i_c, d_t_c, r_n_c, i_c_c, p_c_c, d_p_c, _ \
= data_ctrl_list
self.tree_ctrl.SetItemText(data_c, data_name)
temp = (data_id, data_class, state_id)
self.tree_ctrl.SetItemPyData(data_c, temp)
self.tree_ctrl.SetItemText(i_c_c,
'Type: %s' % data_class)
self.tree_ctrl.SetItemText(p_c_c,
'Path: %s' % s_path)
self.tree_ctrl.DeleteChildren(d_p_c)
for process in process_list:
_ = self.tree_ctrl.AppendItem(d_p_c,
process.__str__())
wx.CallAfter(self.append_theory, state_id, theory_list)
# Sort by data name
if self.tree_ctrl.root:
self.tree_ctrl.SortChildren(self.tree_ctrl.root)
self.enable_remove()
self.enable_import()
self.enable_plot()
self.enable_freeze()
self.enable_selection()
def _uncheck_all(self):
"""
Uncheck all check boxes
"""
for item in self.list_cb_data.values():
data_ctrl, _, _, _, _, _, _, _ = item
self.tree_ctrl.CheckItem(data_ctrl, False)
self.enable_append()
self.enable_freeze()
self.enable_plot()
self.enable_import()
self.enable_remove()
[docs] def append_theory(self, state_id, theory_list):
"""
append theory object under data from a state of id = state_id
replace that theory if already displayed
"""
if not theory_list:
return
if state_id not in self.list_cb_data.keys():
root = self.tree_ctrl_theory.root
tree = self.tree_ctrl_theory
else:
item = self.list_cb_data[state_id]
data_c, _, _, _, _, _, _, _ = item
root = data_c
tree = self.tree_ctrl
if root is not None:
wx.CallAfter(self.append_theory_helper, tree=tree, root=root,
state_id=state_id,
theory_list=theory_list)
[docs] def append_theory_helper(self, tree, root, state_id, theory_list):
"""
Append theory helper
"""
if state_id in self.list_cb_theory.keys():
#update current list of theory for this data
theory_list_ctrl = self.list_cb_theory[state_id]
for theory_id, item in theory_list.iteritems():
theory_data, _ = item
if theory_data is None:
name = "Unknown"
theory_class = "Unknown"
theory_id = "Unknown"
temp = (None, None, None)
else:
name = theory_data.name
theory_class = theory_data.__class__.__name__
theory_id = theory_data.id
#if theory_state is not None:
# name = theory_state.model.name
temp = (theory_id, theory_class, state_id)
if theory_id not in theory_list_ctrl:
#add new theory
t_child = tree.AppendItem(root,
name, ct_type=1, data=temp)
t_i_c = tree.AppendItem(t_child, 'Info')
i_c_c = tree.AppendItem(t_i_c,
'Type: %s' % theory_class)
t_p_c = tree.AppendItem(t_i_c, 'Process')
for process in theory_data.process:
tree.AppendItem(t_p_c, process.__str__())
theory_list_ctrl[theory_id] = [t_child,
i_c_c,
t_p_c]
else:
#replace theory
t_child, i_c_c, t_p_c = theory_list_ctrl[theory_id]
tree.SetItemText(t_child, name)
tree.SetItemPyData(t_child, temp)
tree.SetItemText(i_c_c, 'Type: %s' % theory_class)
tree.DeleteChildren(t_p_c)
for process in theory_data.process:
tree.AppendItem(t_p_c, process.__str__())
else:
#data didn't have a theory associated it before
theory_list_ctrl = {}
for theory_id, item in theory_list.iteritems():
theory_data, _ = item
if theory_data is not None:
name = theory_data.name
theory_class = theory_data.__class__.__name__
theory_id = theory_data.id
#if theory_state is not None:
# name = theory_state.model.name
temp = (theory_id, theory_class, state_id)
t_child = tree.AppendItem(root,
name, ct_type=1,
data=(theory_data.id, theory_class, state_id))
t_i_c = tree.AppendItem(t_child, 'Info')
i_c_c = tree.AppendItem(t_i_c,
'Type: %s' % theory_class)
t_p_c = tree.AppendItem(t_i_c, 'Process')
for process in theory_data.process:
tree.AppendItem(t_p_c, process.__str__())
theory_list_ctrl[theory_id] = [t_child, i_c_c, t_p_c]
#self.list_cb_theory[data_id] = theory_list_ctrl
self.list_cb_theory[state_id] = theory_list_ctrl
[docs] def set_data_helper(self):
"""
Set data helper
"""
data_to_plot = []
state_to_plot = []
theory_to_plot = []
for value in self.list_cb_data.values():
item, _, _, _, _, _, _, _ = value
if item.IsChecked():
data_id, _, state_id = self.tree_ctrl.GetItemPyData(item)
data_to_plot.append(data_id)
if state_id not in state_to_plot:
state_to_plot.append(state_id)
for theory_dict in self.list_cb_theory.values():
for _, value in theory_dict.iteritems():
item, _, _ = value
if item.IsChecked():
theory_id, _, state_id = self.tree_ctrl.GetItemPyData(item)
theory_to_plot.append(theory_id)
if state_id not in state_to_plot:
state_to_plot.append(state_id)
return data_to_plot, theory_to_plot, state_to_plot
[docs] def remove_by_id(self, id):
"""
Remove_dat by id
"""
for item in self.list_cb_data.values():
data_c, _, _, _, _, _, _, _ = item
data_id, _, state_id = self.tree_ctrl.GetItemPyData(data_c)
if id == data_id:
self.tree_ctrl.Delete(data_c)
del self.list_cb_data[state_id]
del self.list_cb_theory[data_id]
[docs] def load_error(self, error=None):
"""
Pop up an error message.
:param error: details error message to be displayed
"""
if error is not None or str(error).strip() != "":
dial = wx.MessageDialog(self.parent, str(error),
'Error Loading File',
wx.OK | wx.ICON_EXCLAMATION)
dial.ShowModal()
def _load_data(self, event):
"""
send an event to the parent to trigger load from plugin module
"""
if self.parent is not None:
wx.PostEvent(self.parent, NewLoadDataEvent())
[docs] def on_remove(self, event):
"""
Get a list of item checked and remove them from the treectrl
Ask the parent to remove reference to this item
"""
msg = "This operation will delete the data sets checked "
msg += "and all the dependents."
msg_box = wx.MessageDialog(None, msg, 'Warning', wx.OK|wx.CANCEL)
if msg_box.ShowModal() != wx.ID_OK:
return
data_to_remove, theory_to_remove, _ = self.set_data_helper()
data_key = []
theory_key = []
#remove data from treectrl
for d_key, item in self.list_cb_data.iteritems():
data_c, _, _, _, _, _, _, _ = item
if data_c.IsChecked():
self.tree_ctrl.Delete(data_c)
data_key.append(d_key)
if d_key in self.list_cb_theory.keys():
theory_list_ctrl = self.list_cb_theory[d_key]
theory_to_remove += theory_list_ctrl.keys()
# Remove theory from treectrl
for _, theory_dict in self.list_cb_theory.iteritems():
for key, value in theory_dict.iteritems():
item, _, _ = value
if item.IsChecked():
try:
self.tree_ctrl.Delete(item)
except:
pass
theory_key.append(key)
#Remove data and related theory references
for key in data_key:
del self.list_cb_data[key]
if key in theory_key:
del self.list_cb_theory[key]
#remove theory references independently of data
for key in theory_key:
for _, theory_dict in self.list_cb_theory.iteritems():
if key in theory_dict:
for key, value in theory_dict.iteritems():
item, _, _ = value
if item.IsChecked():
try:
self.tree_ctrl_theory.Delete(item)
except:
pass
del theory_dict[key]
self.parent.remove_data(data_id=data_to_remove,
theory_id=theory_to_remove)
self.enable_remove()
self.enable_freeze()
self.enable_remove_plot()
[docs] def on_import(self, event=None):
"""
Get all select data and set them to the current active perspetive
"""
if event != None:
event.Skip()
data_id, theory_id, state_id = self.set_data_helper()
temp = data_id + state_id
self.parent.set_data(data_id=temp, theory_id=theory_id)
[docs] def on_append_plot(self, event=None):
"""
append plot to plot panel on focus
"""
self._on_plot_selection()
data_id, theory_id, state_id = self.set_data_helper()
self.parent.plot_data(data_id=data_id,
state_id=state_id,
theory_id=theory_id,
append=True)
[docs] def on_plot(self, event=None):
"""
Send a list of data names to plot
"""
data_id, theory_id, state_id = self.set_data_helper()
self.parent.plot_data(data_id=data_id,
state_id=state_id,
theory_id=theory_id,
append=False)
self.enable_remove_plot()
[docs] def on_close_page(self, event=None):
"""
On close
"""
if event != None:
event.Skip()
# send parent to update menu with no show nor hide action
self.parent.show_data_panel(action=False)
[docs] def on_freeze(self, event):
"""
On freeze to make a theory to a data set
"""
_, theory_id, state_id = self.set_data_helper()
if len(theory_id) > 0:
self.parent.freeze(data_id=state_id, theory_id=theory_id)
msg = "Freeze Theory:"
msg += " The theory(s) copied to the Data box as a data set."
else:
msg = "Freeze Theory: Requires at least one theory checked."
wx.PostEvent(self.parent, StatusEvent(status=msg))
[docs] def set_active_perspective(self, name):
"""
set the active perspective
"""
self.perspective_cbox.SetStringSelection(name)
self.enable_import()
def _on_delete_plot_panel(self, event):
"""
get an event with attribute name and caption to delete existing name
from the combobox of the current panel
"""
#name = event.name
caption = event.caption
if self.cb_plotpanel is not None:
pos = self.cb_plotpanel.FindString(str(caption))
if pos != wx.NOT_FOUND:
self.cb_plotpanel.Delete(pos)
self.enable_append()
[docs] def set_panel_on_focus(self, name=None):
"""
set the plot panel on focus
"""
for _, value in self.parent.plot_panels.iteritems():
name_plot_panel = str(value.window_caption)
if name_plot_panel not in self.cb_plotpanel.GetItems():
self.cb_plotpanel.Append(name_plot_panel, value)
if name != None and name == name_plot_panel:
self.cb_plotpanel.SetStringSelection(name_plot_panel)
break
self.enable_append()
self.enable_remove_plot()
[docs] def set_plot_unfocus(self):
"""
Unfocus plot
"""
return
def _on_perspective_selection(self, event=None):
"""
select the current perspective for guiframe
"""
selection = self.perspective_cbox.GetSelection()
if self.perspective_cbox.GetValue() != 'None':
perspective = self.perspective_cbox.GetClientData(selection)
perspective.on_perspective(event=None)
self.parent.check_multimode(perspective=perspective)
def _on_plot_selection(self, event=None):
"""
On source combobox selection
"""
if event != None:
combo = event.GetEventObject()
event.Skip()
else:
combo = self.cb_plotpanel
selection = combo.GetSelection()
if combo.GetValue() != 'None':
panel = combo.GetClientData(selection)
self.parent.on_set_plot_focus(panel)
[docs] def on_close_plot(self, event):
"""
clseo the panel on focus
"""
self.enable_append()
selection = self.cb_plotpanel.GetSelection()
if self.cb_plotpanel.GetValue() != 'None':
panel = self.cb_plotpanel.GetClientData(selection)
if self.parent is not None and panel is not None:
wx.PostEvent(self.parent,
NewPlotEvent(group_id=panel.group_id,
action="delete"))
self.enable_remove_plot()
[docs] def set_frame(self, frame):
"""
"""
self.frame = frame
[docs] def get_frame(self):
"""
"""
return self.frame
[docs] def on_close(self, event):
"""
On close event
"""
self.parent.show_data_panel(event)
[docs] def set_schedule_full_draw(self, panel=None, func='del'):
"""
Send full draw to guimanager
"""
self.parent.set_schedule_full_draw(panel, func)
[docs] def enable_remove_plot(self):
"""
enable remove plot button if there is a plot panel on focus
"""
pass
#if self.cb_plotpanel.GetCount() == 0:
# self.bt_close_plot.Disable()
#else:
# self.bt_close_plot.Enable()
[docs] def enable_remove(self):
"""
enable or disable remove button
"""
n_t = self.tree_ctrl.GetCount()
n_t_t = self.tree_ctrl_theory.GetCount()
if n_t + n_t_t <= 0:
self.bt_remove.Disable()
else:
self.bt_remove.Enable()
[docs] def enable_import(self):
"""
enable or disable send button
"""
n_t = 0
if self.tree_ctrl != None:
n_t = self.tree_ctrl.GetCount()
if n_t > 0 and len(self.list_of_perspective) > 0:
self.bt_import.Enable()
else:
self.bt_import.Disable()
if len(self.list_of_perspective) <= 0 or \
self.perspective_cbox.GetValue() in ["None",
"No Active Application"]:
self.perspective_cbox.Disable()
else:
self.perspective_cbox.Enable()
[docs] def enable_plot(self):
"""
enable or disable plot button
"""
n_t = 0
n_t_t = 0
if self.tree_ctrl != None:
n_t = self.tree_ctrl.GetCount()
if self.tree_ctrl_theory != None:
n_t_t = self.tree_ctrl_theory.GetCount()
if n_t + n_t_t <= 0:
self.bt_plot.Disable()
else:
self.bt_plot.Enable()
self.enable_append()
[docs] def enable_append(self):
"""
enable or disable append button
"""
n_t = 0
n_t_t = 0
if self.tree_ctrl != None:
n_t = self.tree_ctrl.GetCount()
if self.tree_ctrl_theory != None:
n_t_t = self.tree_ctrl_theory.GetCount()
if n_t + n_t_t <= 0:
self.bt_append_plot.Disable()
self.cb_plotpanel.Disable()
elif self.cb_plotpanel.GetCount() <= 0:
self.cb_plotpanel.Disable()
self.bt_append_plot.Disable()
else:
self.bt_append_plot.Enable()
self.cb_plotpanel.Enable()
[docs] def check_theory_to_freeze(self):
"""
Check_theory_to_freeze
"""
[docs] def enable_freeze(self):
"""
enable or disable the freeze button
"""
n_t_t = 0
n_l = 0
if self.tree_ctrl_theory != None:
n_t_t = self.tree_ctrl_theory.GetCount()
n_l = len(self.list_cb_theory)
if (n_t_t + n_l > 0):
self.bt_freeze.Enable()
else:
self.bt_freeze.Disable()
[docs] def enable_selection(self):
"""
enable or disable combobo box selection
"""
n_t = 0
n_t_t = 0
if self.tree_ctrl != None:
n_t = self.tree_ctrl.GetCount()
if self.tree_ctrl_theory != None:
n_t_t = self.tree_ctrl_theory.GetCount()
if n_t + n_t_t > 0 and self.selection_cbox != None:
self.selection_cbox.Enable()
else:
self.selection_cbox.Disable()
WIDTH = 400
HEIGHT = 300
[docs]class DataDialog(wx.Dialog):
"""
Allow file selection at loading time
"""
def __init__(self, data_list, parent=None, text='', *args, **kwds):
wx.Dialog.__init__(self, parent, *args, **kwds)
self.SetTitle("Data Selection")
self.SetSize((WIDTH, HEIGHT))
self.list_of_ctrl = []
if not data_list:
return
self._sizer_main = wx.BoxSizer(wx.VERTICAL)
self._sizer_txt = wx.BoxSizer(wx.VERTICAL)
self._sizer_button = wx.BoxSizer(wx.HORIZONTAL)
self.sizer = wx.GridBagSizer(5, 5)
self._panel = ScrolledPanel(self, style=wx.RAISED_BORDER,
size=(WIDTH-20, HEIGHT-50))
self._panel.SetupScrolling()
self.__do_layout(data_list, text=text)
def __do_layout(self, data_list, text=''):
"""
layout the dialog
"""
if not data_list or len(data_list) <= 1:
return
#add text
text = "Deleting these file reset some panels.\n"
text += "Do you want to proceed?\n"
text_ctrl = wx.StaticText(self, -1, str(text))
self._sizer_txt.Add(text_ctrl)
iy = 0
ix = 0
#data_count = 0
for (data_name, in_use, sub_menu) in range(len(data_list)):
if in_use == True:
ctrl_name = wx.StaticBox(self, -1, str(data_name))
ctrl_in_use = wx.StaticBox(self, -1, " is used by ")
plug_name = str(sub_menu) + "\n"
#ctrl_sub_menu = wx.StaticBox(self, -1, plug_name)
self.sizer.Add(ctrl_name, (iy, ix),
(1, 1), wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
ix += 1
self._sizer_button.Add(ctrl_in_use, 1,
wx.EXPAND|wx.ADJUST_MINSIZE, 0)
ix += 1
self._sizer_button.Add(plug_name, 1,
wx.EXPAND|wx.ADJUST_MINSIZE, 0)
iy += 1
self._panel.SetSizer(self.sizer)
#add sizer
self._sizer_button.Add((20, 20), 1, wx.EXPAND|wx.ADJUST_MINSIZE, 0)
button_cancel = wx.Button(self, wx.ID_CANCEL, "Cancel")
self._sizer_button.Add(button_cancel, 0,
wx.LEFT|wx.RIGHT|wx.ADJUST_MINSIZE, 10)
button_OK = wx.Button(self, wx.ID_OK, "Ok")
button_OK.SetFocus()
self._sizer_button.Add(button_OK, 0,
wx.LEFT|wx.RIGHT|wx.ADJUST_MINSIZE, 10)
static_line = wx.StaticLine(self, -1)
self._sizer_txt.Add(self._panel, 1, wx.EXPAND|wx.LEFT|wx.RIGHT, 5)
self._sizer_main.Add(self._sizer_txt, 1, wx.EXPAND|wx.ALL, 10)
#self._sizer_main.Add(self._data_text_ctrl, 0,
# wx.EXPAND|wx.LEFT|wx.RIGHT, 10)
self._sizer_main.Add(static_line, 0, wx.EXPAND, 0)
self._sizer_main.Add(self._sizer_button, 0, wx.EXPAND|wx.ALL, 10)
self.SetSizer(self._sizer_main)
self.Layout()
[docs] def get_data(self):
"""
return the selected data
"""
temp = []
for item in self.list_of_ctrl:
cb, data = item
if cb.GetValue():
temp.append(data)
return temp
[docs]class DataFrame(wx.Frame):
"""
Data Frame
"""
## Internal name for the AUI manager
window_name = "Data Panel"
## Title to appear on top of the window
window_caption = "Data Panel"
## Flag to tell the GUI manager that this panel is not
# tied to any perspective
ALWAYS_ON = True
def __init__(self, parent=None, owner=None, manager=None, size=(300, 800),
list_of_perspective=[], list=[], *args, **kwds):
kwds['size'] = size
kwds['id'] = -1
kwds['title'] = "Loaded Data"
wx.Frame.__init__(self, parent=parent, *args, **kwds)
self.parent = parent
self.owner = owner
self._manager = manager
self.panel = DataPanel(parent=self,
manager=manager,
list_of_perspective=list_of_perspective)
[docs] def load_data_list(self, list=[]):
"""
Fill the list inside its panel
"""
self.panel.load_data_list(list=list)
from sas.guiframe.dataFitting import Theory1D
from sas.guiframe.data_state import DataState
[docs]class State():
"""
DataPanel State
"""
def __init__(self):
self.msg = ""
def __str__(self):
self.msg = "model mane : model1\n"
self.msg += "params : \n"
self.msg += "name value\n"
return self.msg
[docs]def set_data_state(data=None, path=None, theory=None, state=None):
"""
Set data state
"""
dstate = DataState(data=data)
dstate.set_path(path=path)
dstate.set_theory(theory, state)
return dstate
if __name__ == "__main__":
app = wx.App()
try:
#list_of_perspective = [('perspective2', False), ('perspective1', True)]
data_list1 = {}
# state 1
data1 = Data2D()
data1.name = "data2"
data1.id = 1
data1.append_empty_process()
process1 = data1.process[len(data1.process)-1]
process1.data = "07/01/2010"
theory1 = Data2D()
theory1.id = 34
theory1.name = "theory1"
path1 = "path1"
state1 = State()
data_list1['1'] = set_data_state(data1, path1, theory1, state1)
#state 2
data1 = Data2D()
data1.name = "data2"
data1.id = 76
theory1 = Data2D()
theory1.id = 78
theory1.name = "CoreShell 07/24/25"
path1 = "path2"
#state3
state1 = State()
data_list1['2'] = set_data_state(data1, path1, theory1, state1)
data1 = Data1D()
data1.id = 3
data1.name = "data2"
theory1 = Theory1D()
theory1.name = "CoreShell"
theory1.id = 4
theory1.append_empty_process()
process1 = theory1.process[len(theory1.process)-1]
process1.description = "this is my description"
path1 = "path3"
data1.append_empty_process()
process1 = data1.process[len(data1.process)-1]
process1.data = "07/22/2010"
data_list1['4'] = set_data_state(data1, path1, theory1, state1)
#state 4
temp_data_list = {}
data1.name = "data5 erasing data2"
temp_data_list['4'] = set_data_state(data1, path1, theory1, state1)
#state 5
data1 = Data2D()
data1.name = "data3"
data1.id = 5
data1.append_empty_process()
process1 = data1.process[len(data1.process)-1]
process1.data = "07/01/2010"
theory1 = Theory1D()
theory1.name = "Cylinder"
path1 = "path2"
state1 = State()
dstate1 = set_data_state(data1, path1, theory1, state1)
theory1 = Theory1D()
theory1.id = 6
theory1.name = "CoreShell"
dstate1.set_theory(theory1)
theory1 = Theory1D()
theory1.id = 6
theory1.name = "CoreShell replacing coreshell in data3"
dstate1.set_theory(theory1)
data_list1['3'] = dstate1
#state 6
data_list1['6'] = set_data_state(None, path1, theory1, state1)
data_list1['6'] = set_data_state(theory=theory1, state=None)
theory1 = Theory1D()
theory1.id = 7
data_list1['6'] = set_data_state(theory=theory1, state=None)
data_list1['7'] = set_data_state(theory=theory1, state=None)
window = DataFrame(list=data_list1)
window.load_data_list(list=data_list1)
window.Show(True)
window.load_data_list(list=temp_data_list)
except:
#raise
print "error", sys.exc_value
app.MainLoop()