source: sasview/sansguiframe/src/sans/guiframe/data_processor.py @ 89441d1

ESS_GUIESS_GUI_DocsESS_GUI_batch_fittingESS_GUI_bumps_abstractionESS_GUI_iss1116ESS_GUI_iss879ESS_GUI_iss959ESS_GUI_openclESS_GUI_orderingESS_GUI_sync_sascalccostrafo411magnetic_scattrelease-4.1.1release-4.1.2release-4.2.2release_4.0.1ticket-1009ticket-1094-headlessticket-1242-2d-resolutionticket-1243ticket-1249ticket885unittest-saveload
Last change on this file since 89441d1 was e25d908, checked in by Jae Cho <jhjcho@…>, 13 years ago

Batch Grid: fixed a bug when a file opened and read

  • Property mode set to 100644
File size: 53.5 KB
RevLine 
[24adb89]1"""
2Implement grid used to store data
3"""
4import wx
5import numpy
[904830e]6import math
[1ec979d]7import time
[904830e]8import re
[850525c]9import os
[24adb89]10import sys
[7ad194fa]11import copy
[24adb89]12from wx.lib.scrolledpanel import ScrolledPanel
13import  wx.grid as  Grid
14import wx.aui
15from wx.aui import AuiNotebook as nb
16import wx.lib.sheet as sheet
[1c86a37]17from sans.guiframe.panel_base import PanelBase
18from sans.guiframe.utils import format_number
[24adb89]19from sans.guiframe.events import NewPlotEvent
20from sans.guiframe.events import StatusEvent 
[fe98127]21from danse.common.plottools import plottables
[24adb89]22from sans.guiframe.dataFitting import Data1D
23
[904830e]24FUNC_DICT = {"sqrt": "math.sqrt",
25             "pow": "math.sqrt"}
[73197d0]26
[5425990]27class BatchCell:
28    """
29    Object describing a cell in  the grid.
30   
31    """
32    def __init__(self):
33        self.label = ""
34        self.value = None
35        self.col = -1
36        self.row = -1
[75790dc]37        self.object = []
[5425990]38       
[73197d0]39
[904830e]40def parse_string(sentence, list):
41    """
42    Return a dictionary of column label and index or row selected
43    :param sentence: String to parse
44    :param list: list of columns label
45    """
46    toks = []
47    p2 = re.compile(r'\d+')
48    p = re.compile(r'[\+\-\*\%\/]')
49    labels = p.split(sentence)
50    col_dict = {}
51    for elt in labels:
52        rang = None
53        temp_arr = []
54        for label in  list:
55            label_pos =  elt.find(label)
[08dc9e87]56            separator_pos  = label_pos + len(label)
57            if label_pos != -1 and len(elt) >= separator_pos  and\
58                elt[separator_pos]== "[":
59                # the label contain , meaning the range selected is not
60                # continuous
[904830e]61                if elt.count(',') > 0:
62                    new_temp = []
63                    temp = elt.split(label)
64                    for item in temp:
65                        range_pos = item.find(":")
66                        if range_pos != -1:
67                            rang = p2.findall(item)
68                            for i in xrange(int(rang[0]), int(rang[1])+1 ):
69                                new_temp.append(i)
70                    temp_arr += new_temp
71                else:
[08dc9e87]72                    # continuous range
[904830e]73                    temp = elt.split(label)
74                    for item in temp:
[08dc9e87]75                        if item.strip() != "":
76                            range_pos = item.find(":")
77                            if range_pos != -1:
78                                rang = p2.findall(item)
79                                for i in xrange(int(rang[0]), int(rang[1])+1 ):
80                                    temp_arr.append(i)
[904830e]81                col_dict[elt] = (label, temp_arr)
82    return col_dict
[24adb89]83
[f4b37d1]84         
85         
86class SPanel(ScrolledPanel):
87    def __init__(self, parent, *args, **kwds):
88        ScrolledPanel.__init__(self, parent , *args, **kwds)
89        self.SetupScrolling() 
90       
[24adb89]91class GridPage(sheet.CSheet):
[9c8f3ad]92    """
93    """
[24adb89]94    def __init__(self, parent, panel=None):
95        """
96        """
97        sheet.CSheet.__init__(self, parent)
[f4b37d1]98       
99        self.AdjustScrollbars()
100        #self.SetLabelBackgroundColour('#DBD4D4')
[fd51a7c]101        self.uid = wx.NewId()
[f4b37d1]102        self.parent = parent
[24adb89]103        self.panel = panel
104        self.col_names = []
[8523a1f2]105        self.data_inputs = {}
106        self.data_outputs = {}
[d03a356]107        self.data = None
[71fa9028]108        self.details = ""
109        self.file_name = None
[9c8f3ad]110        self._cols = 50
111        self._rows = 51
[63dc6e5]112        self.last_selected_row = -1
113        self.last_selected_col = -1
[1c86a37]114        self.col_width = 30
115        self.row_height = 20
[656d65d]116        self.max_row_touse = 0
[49ad00b]117        self.axis_value = []
118        self.axis_label = ""
119        self.selected_cells = []
120        self.selected_cols = []
[75790dc]121        self.selected_rows = []
122        self.plottable_cells = []
[63dc6e5]123        self.plottable_flag = False
[1c86a37]124        self.SetColMinimalAcceptableWidth(self.col_width)
125        self.SetRowMinimalAcceptableHeight(self.row_height)
[24adb89]126        self.SetNumberRows(self._cols)
127        self.SetNumberCols(self._rows)
[f4b37d1]128        self.AutoSize()
[23477c6]129        self.list_plot_panels = {}
[1c86a37]130        self.default_col_width = 75
[5531a46]131        self.EnableEditing(False)
[1c86a37]132        if self.GetNumberCols() > 0:
133            self.default_col_width =  self.GetColSize(0)
[49ad00b]134        self.Bind(wx.grid.EVT_GRID_LABEL_LEFT_CLICK, self.on_left_click)
[24adb89]135        self.Bind(wx.grid.EVT_GRID_LABEL_RIGHT_CLICK, self.on_right_click)
[49ad00b]136        self.Bind(wx.grid.EVT_GRID_CELL_LEFT_CLICK, self.on_selected_cell)
[656d65d]137        self.Bind(wx.grid.EVT_GRID_CMD_CELL_CHANGE, self.on_edit_cell)
[1c86a37]138       
139       
[656d65d]140    def on_edit_cell(self, event):
141        """
142        """
143        row, col = event.GetRow(), event.GetCol()
144        if row > self.max_row_touse:
145            self.max_row_touse = row
146        event.Skip()
[49ad00b]147       
148    def on_selected_cell(self, event):
149        """
150        Handler catching cell selection
151        """
152        flag = event.CmdDown() or event.ControlDown()
[904830e]153        row, col = event.GetRow(), event.GetCol()
154        cell = (row, col)
[63dc6e5]155        event.Skip()
[49ad00b]156        if not flag:
[08dc9e87]157            self.selected_cols = []
158            self.selected_rows = []
[49ad00b]159            self.selected_cells = []
[904830e]160            self.axis_label = ""
[08dc9e87]161            self.axis_value = []
162            self.plottable_list = []
163            self.plottable_cells = []
164            self.plottable_flag = False
165        self.last_selected_col = col
166        self.last_selected_row = row
[63dc6e5]167        if col >= 0:
[08dc9e87]168            label_row = 0
169            self.axis_label = self.GetCellValue(label_row, col)
170            self.selected_cols.append(col)
[dadf255]171        if cell not in self.selected_cells:
172            if row > 0:
173                self.selected_cells.append(cell)
[08dc9e87]174                self.selected_rows.append(row)
[49ad00b]175        else:
[dadf255]176            if flag:
177                self.selected_cells.remove(cell)
178        self.axis_value = []
179        for cell_row, cell_col in self.selected_cells:
180            if cell_row > 0 and cell_row < self.max_row_touse:
181                self.axis_value.append(self.GetCellValue(cell_row, cell_col))
[08dc9e87]182
[63dc6e5]183               
[49ad00b]184    def on_left_click(self, event):
185        """
186        Catch the left click on label mouse event
187        """
[647df0d1]188        event.Skip()
[49ad00b]189        flag = event.CmdDown() or event.ControlDown()
190        col = event.GetCol()
[63dc6e5]191        row = event.GetRow()
[dadf255]192        if not flag:
193            self.selected_cols = []
[75790dc]194            self.selected_rows = []
[dadf255]195            self.selected_cells = []
196            self.axis_label = ""
[08dc9e87]197            self.axis_value = []
[63dc6e5]198            self.plottable_list = []
[75790dc]199            self.plottable_cells = []
[63dc6e5]200            self.plottable_flag = False
[75790dc]201       
[63dc6e5]202        self.last_selected_col = col
203        self.last_selected_row = row
[75790dc]204        if row != -1 and row not in self.selected_rows:
205             self.selected_rows.append(row)
206             
[647df0d1]207        if col != -1:
208            for row in range(1, self.GetNumberRows()+ 1):
209                cell = (row, col)
210                if row > 0 and row < self.max_row_touse:
211                    if cell not in self.selected_cells:
212                        self.selected_cells.append(cell)
[08dc9e87]213                    else:
214                        if flag:
215                             self.selected_cells.remove(cell)
[647df0d1]216            self.selected_cols.append(col)
217            self.axis_value = []
218            for cell_row, cell_col in self.selected_cells:
219                self.axis_value.append(self.GetCellValue(cell_row, cell_col))
220            self.axis_label = self.GetCellValue(0, col)
[75790dc]221       
[24adb89]222    def on_right_click(self, event):
[9c8f3ad]223        """
224        Catch the right click mouse
225        """
[656d65d]226       
[24adb89]227        col = event.GetCol()
[656d65d]228        self.selected_cols = []
229        self.selected_cols.append(col)
[24adb89]230        # Slicer plot popup menu
231        slicerpop = wx.Menu()
[656d65d]232        col_label_menu  = wx.Menu()
[1c86a37]233        c_name = self.GetCellValue(0, col) 
234        label = "Insert column before %s " % str(c_name)
[656d65d]235        slicerpop.AppendSubMenu(col_label_menu , 
[1c86a37]236                                 '&%s' % str(label), str(label))
[71fa9028]237        col_name = [self.GetCellValue(0, c) 
238                        for c in range(self.GetNumberCols())]
239        row = 0
240        label = self.GetCellValue(row, col)
241        self.insert_col_menu(col_label_menu, label, self)
[b18cf3d]242       
243       
244        col_after_menu  = wx.Menu()
245        label = "Insert column after %s " % str(c_name)
246        slicerpop.AppendSubMenu(col_after_menu , 
247                                 '&%s' % str(label), str(label))
248        col_name = [self.GetCellValue(0, c) 
249                        for c in range(self.GetNumberCols())]
250        self.insert_after_col_menu(col_after_menu, label, self)
251       
252       
[656d65d]253        id = wx.NewId()   
254        hint = 'Remove selected column %s'
[71fa9028]255        slicerpop.Append(id, '&Remove Column', hint)
[656d65d]256        wx.EVT_MENU(self, id, self.on_remove_column)
[24adb89]257       
[656d65d]258        pos = wx.GetMousePosition()
[24adb89]259        pos = self.ScreenToClient(pos)
260        self.PopupMenu(slicerpop, pos)
[647df0d1]261        event.Skip()
[24adb89]262       
[71fa9028]263    def insert_col_menu(self, menu, label, window):
264        """
265        """
[5531a46]266        if self.data is None:
267            return
[71fa9028]268        id = wx.NewId()
269        title = "Empty"
270        hint = 'Insert empty column before %s' % str(label)
271        menu.Append(id, title, hint)
272        wx.EVT_MENU(window, id, self.on_insert_column)
[fb0de166]273        row = 0
274        col_name = [self.GetCellValue(row, col) 
[71fa9028]275                        for col in range(self.GetNumberCols())]
276        for c_name in self.data.keys():
277            if c_name not in col_name:
278                id = wx.NewId()
279                hint = "Insert %s column before the " % str(c_name)
280                hint += " %s column" % str(label)
281                menu.Append(id, '&%s' % str(c_name), hint)
282                wx.EVT_MENU(window, id, self.on_insert_column)
283           
[b18cf3d]284    def insert_after_col_menu(self, menu, label, window):
285        """
286        """
[5531a46]287        if self.data is None:
288            return
[b18cf3d]289        id = wx.NewId()
290        title = "Empty"
291        hint = 'Insert empty column after %s' % str(label)
292        menu.Append(id, title, hint)
293        wx.EVT_MENU(window, id, self.on_insert_after_column)
294        row = 0
295        col_name = [self.GetCellValue(row, col) 
296                        for col in range(self.GetNumberCols())]
297        for c_name in self.data.keys():
298            if c_name not in col_name:
299                id = wx.NewId()
300                hint = "Insert %s column after the " % str(c_name)
301                hint += " %s column" % str(label)
302                menu.Append(id, '&%s' % str(c_name), hint)
303                wx.EVT_MENU(window, id, self.on_insert_after_column)
304                               
[71fa9028]305    def on_remove_column(self, event=None):
[656d65d]306        """
307        """
308        if self.selected_cols is not None or len(self.selected_cols) > 0:
309            col = self.selected_cols[0]
[71fa9028]310            self.remove_column(col=col, numCols=1)
311           
312    def remove_column(self, col, numCols=1):
313        """
314        Remove column to the current grid
315        """
316        # add data to the grid   
317        row = 0
318        col_name = self.GetCellValue(row, col)
319        self.data[col_name] = []
320        for row in range(1, self.GetNumberRows() + 1):
321            if row < self.max_row_touse:
322                value = self.GetCellValue(row, col)
323                self.data[col_name].append(value)
324                for k , value_list in self.data.iteritems():
325                    if k != col_name:
326                        length = len(value_list)
327                        if length < self.max_row_touse:
328                            diff = self.max_row_touse - length
329                            for i in range(diff):
330                                self.data[k].append("")
331        self.DeleteCols(pos=col, numCols=numCols, updateLabels=True)
[656d65d]332           
333    def on_insert_column(self, event):
334        """
335        """
336        if self.selected_cols is not None or len(self.selected_cols) > 0:
337            col = self.selected_cols[0]
338            # add data to the grid   
339            row = 0
340            id = event.GetId()
341            col_name = event.GetEventObject().GetLabelText(id)
[71fa9028]342            self.insert_column(col=col, col_name=col_name)
343            if  not issubclass(event.GetEventObject().__class__ , wx.Menu):
344                col += 1
345                self.selected_cols[0] += 1
[b18cf3d]346               
347    def on_insert_after_column(self, event):
348        """
349        Insert the given column after the highlighted column
350        """
351        if self.selected_cols is not None or len(self.selected_cols) > 0:
352            col = self.selected_cols[0] + 1
353            # add data to the grid   
354            row = 0
355            id = event.GetId()
356            col_name = event.GetEventObject().GetLabelText(id)
357            self.insert_column(col=col, col_name=col_name)
358            if  not issubclass(event.GetEventObject().__class__ , wx.Menu):
359                self.selected_cols[0] += 1
[71fa9028]360           
361    def insert_column(self, col, col_name):
362        """
363        """ 
364         
365        row = 0
366        self.InsertCols(pos=col, numCols=1, updateLabels=True)
367        if col_name.strip() != "Empty":
368            self.SetCellValue(row, col, str(col_name.strip()))
369        if col_name in self.data.keys():
370            value_list = self.data[col_name]
371            cell_row =  1
372            for value in value_list:
[6dad639]373                label = value#format_number(value, high=True)
[b18cf3d]374                self.SetCellValue(cell_row, col, str(label))
[71fa9028]375                cell_row += 1
[b18cf3d]376        self.AutoSizeColumn(col, True)
377        width = self.GetColSize(col)
378        if width < self.default_col_width:
379           self.SetColSize(col, self.default_col_width)
380        self.ForceRefresh()
[656d65d]381       
[24adb89]382    def on_set_x_axis(self, event):
[9c8f3ad]383        """
384        """
[24adb89]385        self.panel.set_xaxis(x=self.axis_value, label=self.axis_label)
386   
387    def on_set_y_axis(self, event):
[9c8f3ad]388        """
389        """
[24adb89]390        self.panel.set_yaxis(y=self.axis_value, label=self.axis_label)     
391           
[71fa9028]392    def set_data(self, data_inputs, data_outputs, details, file_name):
[24adb89]393        """
[9c8f3ad]394        Add data to the grid
[dadf255]395        :param data_inputs: data to use from the context menu of the grid
396        :param data_ouputs: default columns deplayed
[24adb89]397        """
[71fa9028]398        self.file_name = file_name
399        self.details = details
400       
[8523a1f2]401        if data_outputs is None:
402            data_outputs = {}
403        self.data_outputs = data_outputs
[71fa9028]404        if data_inputs is None:
[8523a1f2]405            data_inputs = {}
406        self.data_inputs = data_inputs
[656d65d]407        self.data = {}
408        for item in (self.data_outputs, self.data_inputs):
409            self.data.update(item)
[5531a46]410           
411        if len(self.data) + len(self.data_inputs) +len(self.data_outputs) == 0:
412            self.EnableEditing(False)
413        else:
414            self.EnableEditing(True)
[8523a1f2]415        if  len(self.data_outputs) > 0:
[9c8f3ad]416            self._cols = self.GetNumberCols()
417            self._rows = self.GetNumberRows()
[8523a1f2]418            self.col_names = self.data_outputs.keys()
[24adb89]419            self.col_names.sort() 
[9c8f3ad]420            nbr_user_cols = len(self.col_names)
421            #Add more columns to the grid if necessary
422            if nbr_user_cols > self._cols:
423                new_col_nbr = nbr_user_cols -  self._cols
424                self.AppendCols(new_col_nbr, True)
425            #Add more rows to the grid if necessary 
[8523a1f2]426            nbr_user_row = len(self.data_outputs.values())
[9c8f3ad]427            if nbr_user_row > self._rows + 1:
428                new_row_nbr =  nbr_user_row - self._rows
429                self.AppendRows(new_row_nbr, True)
430            # add data to the grid   
[10675c3]431            row = 0
[24adb89]432            col = 0
[8523a1f2]433            cell_col = 0
434            for col_name in  self.col_names:
435                # use the first row of the grid to add user defined labels
436                self.SetCellValue(row, col, str(col_name))
[24adb89]437                col += 1
[8523a1f2]438                cell_row =  1
439                value_list = self.data_outputs[col_name]
440               
441                for value in value_list:
[5425990]442                    label = value
443                    if issubclass(value.__class__, BatchCell):
444                        label = value.label
[1c86a37]445                    try:
446                        float(label)
[6dad639]447                        label = str(label)#format_number(label, high=True)
[1c86a37]448                    except:
449                        label = str(label)
450                    self.SetCellValue(cell_row, cell_col, label)
451                    self.AutoSizeColumn(cell_col, True)
452                    width = self.GetColSize(cell_col)
453                    if width < self.default_col_width:
454                       self.SetColSize(cell_col, self.default_col_width)
455                   
[8523a1f2]456                    cell_row += 1
457                cell_col += 1
[656d65d]458                if cell_row > self.max_row_touse:
459                    self.max_row_touse = cell_row
[1c86a37]460        self.ForceRefresh()
461       
[71fa9028]462    def get_grid_view(self):
463        """
464        Return value contained in the grid
465        """
466        grid_view = {}
467        for col in xrange(self.GetNumberCols()):
468            label = self.GetCellValue(row=0, col=col) 
469            label = label.strip()
470            if label != "":
471                grid_view[label] = []
[c27a111]472                for row in range(1, self.max_row_touse):
[71fa9028]473                    value = self.GetCellValue(row=row, col=col)
474                    if value != "":
475                        grid_view[label].append(value) 
476                    else:
477                        grid_view[label].append(None) 
478        return grid_view
479   
[24adb89]480class Notebook(nb, PanelBase):
481    """
482    ## Internal name for the AUI manager
483    window_name = "Fit panel"
484    ## Title to appear on top of the window
485    """
486    window_caption = "Notebook "
487   
488    def __init__(self, parent, manager=None, data=None, *args, **kwargs):
489        """
490        """
491        nb.__init__(self, parent, -1,
[f4b37d1]492                    style=wx.aui.AUI_NB_WINDOWLIST_BUTTON| 
493                    wx.aui.AUI_BUTTON_DOWN|
[9c8f3ad]494                    wx.aui.AUI_NB_DEFAULT_STYLE|
495                    wx.CLIP_CHILDREN)
[24adb89]496        PanelBase.__init__(self, parent)
[9c8f3ad]497        self.enable_close_button()
[24adb89]498        self.parent = parent
499        self.manager = manager
500        self.data = data
[d03a356]501        #add empty page
502        self.add_empty_page()
503       
[9c8f3ad]504        self.Bind(wx.aui.EVT_AUINOTEBOOK_PAGE_CLOSE, self.on_close_page)
[7ad194fa]505   
[d03a356]506    def add_empty_page(self):
507        """
508        """
509        grid = GridPage(self, panel=self.parent)
510        self.AddPage(grid, "", True)
511        pos = self.GetPageIndex(grid)
[63f4b8e]512        title = "Batch" + str(self.GetPageCount())
[d03a356]513        self.SetPageText(pos, title)
514        self.SetSelection(pos)
[f4b37d1]515        return grid , pos
[d03a356]516       
[9c8f3ad]517    def enable_close_button(self):
518        """
519        display the close button on tab for more than 1 tabs else remove the
520        close button
521        """
522        if self.GetPageCount() <= 1:
523            style = self.GetWindowStyleFlag() 
524            flag = wx.aui.AUI_NB_CLOSE_ON_ACTIVE_TAB
525            if style & wx.aui.AUI_NB_CLOSE_ON_ACTIVE_TAB == flag:
526                style = style & ~wx.aui.AUI_NB_CLOSE_ON_ACTIVE_TAB
527                self.SetWindowStyle(style)
528        else:
529            style = self.GetWindowStyleFlag()
530            flag = wx.aui.AUI_NB_CLOSE_ON_ACTIVE_TAB
531            if style & wx.aui.AUI_NB_CLOSE_ON_ACTIVE_TAB != flag:
532                style |= wx.aui.AUI_NB_CLOSE_ON_ACTIVE_TAB
533                self.SetWindowStyle(style)
[9680906d]534             
535    def on_edit_axis(self):
536        """
[08dc9e87]537        Return the select cell of a given selected column. Check that all cells
538        are from the same column
[9680906d]539        """
540        pos = self.GetSelection()
541        grid = self.GetPage(pos)
[08dc9e87]542        if len(grid.selected_cols) >= 1:
[49ad00b]543            col = grid.selected_cols[0]
[08dc9e87]544            for c in grid.selected_cols:
545                if c != col:
[7ad194fa]546                    msg = "Edit axis doesn't understand this selection.\n"
[08dc9e87]547                    msg += "Please select only one column"
[7ad194fa]548                    raise ValueError, msg
[08dc9e87]549            for (cell_row, cell_col) in grid.selected_cells:
550                if cell_col != col:
551                    msg = "Cannot use cells from different columns for "
552                    msg += "this operation.\n"
553                    msg += "Please select elements of the same col.\n"
554                    raise ValueError, msg
555        else:
556            msg = "No item selected.\n"
557            msg += "Please select only one column or one cell"
558            raise ValueError, msg
559       
[dadf255]560        return grid.selected_cells
561       
[7ad194fa]562   
[904830e]563    def get_column_labels(self):
564        """
565        return dictionary of columns labels of the current page
566        """
567        pos = self.GetSelection()
568        grid = self.GetPage(pos)
569        labels = {}
570        row = 0
571        for col in range(grid.GetNumberCols()):
572            label = grid.GetCellValue(row, col)
573            if label.strip() != "" :
574                labels[label.strip()] = col
575        return labels
576       
[7ad194fa]577    def create_axis_label(self, cell_list):
578        """
579        Receive a list of cells and  create a string presenting the selected
580        cells.
581        :param cell_list: list of tuple
[9680906d]582       
[7ad194fa]583        """
584        pos = self.GetSelection()
585        grid = self.GetPage(pos)
586        label = ""
587        col_name = ""
[dadf255]588        def create_label(col_name,  row_min=None, row_max=None):
589            """
590            """
591            result = ""
592            if row_min is not  None or row_max is not None:
593                if row_min is None:
594                    result = str(row_max) + "]"
595                elif row_max is None:
596                     result = str(col_name) + "[" + str(row_min) + ":"
597                else:
598                    result = str(col_name) +  "[" + str(row_min) + ":"
[08dc9e87]599                    result += str(row_max) + "]"
600            return str(result)
[dadf255]601           
[7ad194fa]602        if len(cell_list) > 0:
[dadf255]603            if len(cell_list) == 1:
604                 row_min, col  = cell_list[0]   
605                 col_name = grid.GetCellValue(0, col)
606                 label = create_label(col_name, row_min+1 , row_min+1)
607                 return  label,  col_name
608            else:
609                temp_list = copy.deepcopy(cell_list)
610                temp_list.sort()
611                length = len(temp_list)
612                row_min, col  = temp_list[0]   
613                row_max, _  = temp_list[length-1]
614                col_name = grid.GetCellValue(0, col)
615                index = 0
616                for row in xrange(row_min, row_max +1):
617                    if index > 0 and index < len(temp_list):
618                        new_row, _ = temp_list[index]
619                        if row != new_row:
620                            temp_list.insert(index, (None, None))
[08dc9e87]621                            if index -1 >= 0:
[dadf255]622                                new_row, _ = temp_list[index-1]
623                                label += create_label(col_name, None, new_row +1)
624                                label += ","
625                            if index + 1 < len(temp_list):
626                                new_row, _ = temp_list[index + 1]
627                                label += create_label(col_name, new_row+1, None)
628                    if index == 0:
629                        label += create_label(col_name,  row_min+1, None)
630                    elif index == len(temp_list)-1:
631                        label += create_label(col_name, None, row_max+1)
632                    index += 1
633                return label, col_name
[7ad194fa]634   
[9c8f3ad]635    def on_close_page(self, event):
636        """
637        close the page
638        """
639        if self.GetPageCount() == 1:
640            event.Veto()
641        self.enable_close_button()
[24adb89]642       
[71fa9028]643    def set_data(self, data_inputs, data_outputs, details="", file_name=None):
[8523a1f2]644        if data_outputs is None or data_outputs == {}:
[24adb89]645            return
[98fdccd]646        inputs, outputs = self.get_odered_results(data_inputs, data_outputs)
[f4b37d1]647        for pos in range(self.GetPageCount()):
648            grid = self.GetPage(pos)
649            if grid.data is None:
650                #Found empty page
[98fdccd]651                grid.set_data(data_inputs=inputs, 
652                              data_outputs=outputs,
[71fa9028]653                              details=details,
654                              file_name=file_name) 
[f4b37d1]655                self.SetSelection(pos) 
656                return
657               
658        grid, pos = self.add_empty_page()
[98fdccd]659        grid.set_data(data_inputs=inputs, 
660                      data_outputs=outputs,
[a84ca2a]661                      file_name=file_name,
662                      details=details)
[98fdccd]663       
664    def get_odered_results(self, inputs, outputs=None):
665        """
666        Get ordered the results
667        """
668        # Let's re-order the data from the keys in 'Data' name.
669        if outputs == None:
670            return
[e25d908]671        try:
672            # For outputs from batch
673            to_be_sort = [str(item.label) for item in outputs['Data']]
674        except:
675            # When inputs are from an external file
676            return inputs, outputs
[98fdccd]677        inds = numpy.lexsort((to_be_sort, to_be_sort))
678        for key in outputs.keys():
679            key_list = outputs[key]
680            temp_key = [item for item in key_list]
681            for ind in inds:
682                temp_key[ind] = key_list[inds[ind]]
683            outputs[key] = temp_key
684        for key in inputs.keys():
685            key_list = inputs[key]
686            if len(key_list) > 0:
687                temp_key = [item for item in key_list]
688                for ind in inds:
689                    temp_key[ind] = key_list[inds[ind]]
690                inputs[key] = temp_key
691        return inputs, outputs
[f4b37d1]692   
[9c8f3ad]693    def add_column(self):
694        """
695        Append a new column to the grid
696        """
697        pos = self.GetSelection()
698        grid = self.GetPage(pos)
699        grid.AppendCols(1, True)
700       
[24adb89]701class GridPanel(SPanel):
[8523a1f2]702    def __init__(self, parent, data_inputs=None,
703                 data_outputs=None, *args, **kwds):
[24adb89]704        SPanel.__init__(self, parent , *args, **kwds)
[f4b37d1]705       
[24adb89]706        self.vbox = wx.BoxSizer(wx.VERTICAL)
707       
[9680906d]708        self.plotting_sizer = wx.FlexGridSizer(3, 7, 10, 5)
[75790dc]709        self.button_sizer = wx.BoxSizer(wx.HORIZONTAL)
[24adb89]710        self.grid_sizer = wx.BoxSizer(wx.HORIZONTAL)
711        self.vbox.AddMany([(self.grid_sizer, 1, wx.EXPAND, 0),
712                           (wx.StaticLine(self, -1), 0, wx.EXPAND, 0),
[75790dc]713                           (self.plotting_sizer),
714                           (self.button_sizer)])
[24adb89]715        self.parent = parent
[8523a1f2]716        self._data_inputs = data_inputs
717        self._data_outputs = data_outputs
[24adb89]718        self.x = []
719        self.= []
720        self.x_axis_label = None
721        self.y_axis_label = None
[904830e]722        self.x_axis_title = None
723        self.y_axis_title = None
[24adb89]724        self.x_axis_unit = None
725        self.y_axis_unit = None
[75790dc]726        self.view_button = None
[24adb89]727        self.plot_button = None
[904830e]728        self.notebook = None
[23477c6]729       
[24adb89]730        self.layout_grid()
731        self.layout_plotting_area()
732        self.SetSizer(self.vbox)
[98fdccd]733
[904830e]734    def set_xaxis(self, label="", x=None):
735        """
736        """
[24adb89]737        if x is None:
738            x = []
739        self.x = x
[904830e]740        self.x_axis_label.SetValue("%s[:]" % str(label))
741        self.x_axis_title.SetValue(str(label))
[24adb89]742       
[904830e]743    def set_yaxis(self, label="", y=None):
744        """
745        """
[24adb89]746        if y is None:
747            y = []
748        self.y = y
[904830e]749        self.y_axis_label.SetValue("%s[:]" % str(label))
750        self.y_axis_title.SetValue(str(label))
[24adb89]751       
[904830e]752    def get_plot_axis(self, col, list):
753        """
754       
755        """
756        axis = []
757        pos = self.notebook.GetSelection()
758        grid = self.notebook.GetPage(pos)
759        for row in list:
[c911f34]760            label = grid.GetCellValue(0, col)
761            value = grid.GetCellValue(row - 1, col).strip()
762            if value != "":
763                if label.lower().strip() == "data":
764                    axis.append(float(row - 1))
765                else:
[dadf255]766                    try:
767                        axis.append(float(value))
768                    except:
769                        msg = "Invalid data in row %s column %s" % (str(row),
770                                                                    str(col))
771                        wx.PostEvent(self.parent.parent, 
[75790dc]772                             StatusEvent(status=msg, info="error")) 
[c911f34]773            else:
774                axis.append(None) 
[904830e]775        return axis
776   
[656d65d]777    def on_save_column(self, parent):
778        """
779        """
780        pos = self.notebook.GetSelection()
781        grid = self.notebook.GetPage(pos)
782        if parent is not None and  self.data is not None:
783            parent.write_batch_tofile(data=grid.data, 
784                                               file_name=path,
785                                               details=self.details)
786       
[75790dc]787    def on_view(self, event):
788        """
789        Get object represented buy the given cell and plot them.
790        """
791        pos = self.notebook.GetSelection()
792        grid = self.notebook.GetPage(pos)
793        title = self.notebook.GetPageText(pos)
[9400de6]794        if len(grid.selected_cells) == 0:
795            msg = "Highlight a Data or Chi2 column first..."
796            wx.PostEvent(self.parent.parent, 
797                             StatusEvent(status=msg, info="error")) 
798            return
[75790dc]799        for cell in grid.selected_cells:
800            row, col = cell
801            label_row = 0
802            label = grid.GetCellValue(label_row, col)
803            if label in grid.data:
804                values = grid.data[label]
[344c5d8]805                if row > len(values) or row < 1:
[9400de6]806                    msg = "Invalid cell was chosen." 
807                    wx.PostEvent(self.parent.parent, StatusEvent(status=msg, 
808                                                                info="error"))
[1ec979d]809                    time.sleep(0.5)
[9400de6]810                    continue
[344c5d8]811                else:
812                     value = values[row -1]
[75790dc]813                if issubclass(value.__class__, BatchCell):
[fe98127]814                    if value.object is None or len(value.object) == 0:
815                        msg = "Row %s , " % str(row)
[c27a111]816                        msg += "Column %s is NOT " % str(label)
817                        msg += "the results of fits to view..."
[fe98127]818                        #raise ValueError, msg
819                        wx.PostEvent(self.parent.parent, StatusEvent(status=msg, 
820                                                                info="error")) 
821                        return
[75790dc]822                    for new_plot in value.object:
[fe98127]823                        if new_plot is None or \
[1f83477]824                         not issubclass(new_plot.__class__, 
[fe98127]825                                        plottables.Plottable):
[75790dc]826                            msg = "Row %s , " % str(row)
[c27a111]827                            msg += "Column %s is NOT " % str(label)
828                            msg += "the results of fits to view..."
[75790dc]829                            #raise ValueError, msg
830                            wx.PostEvent(self.parent.parent, 
831                                 StatusEvent(status=msg, info="error")) 
[1ec979d]832                            time.sleep(0.5)
[7d47789]833                            continue
[63f4b8e]834                        #new_plot.name =  title + ': ' + new_plot.title
[75790dc]835                        if issubclass(new_plot.__class__, Data1D):
[23477c6]836                            if label in grid.list_plot_panels.keys():
837                                group_id = grid.list_plot_panels[label]
[fd51a7c]838                            else:
[5d192cd]839                                group_id = str(new_plot.group_id) + str(grid.uid)
[23477c6]840                                grid.list_plot_panels[label] = group_id
[fd51a7c]841                            if group_id not in new_plot.list_group_id:
842                                new_plot.group_id = group_id
843                                new_plot.list_group_id.append(group_id)
[75790dc]844                        else:
[18a6556]845                            if label.lower() in ["data", "chi2"]:
[75790dc]846                                if len(grid.selected_cells) != 1:
[b18cf3d]847                                    msg = "2D View: Please select one data set"
[c27a111]848                                    msg += " at a time for View Results."
[75790dc]849                                    wx.PostEvent(self.parent.parent, 
850                                                 StatusEvent(status=msg,
[1ec979d]851                                                              info="error"))
852                                    time.sleep(0.5) 
[7d47789]853                                    continue 
[23477c6]854                        """
[75790dc]855                        wx.PostEvent(self.parent.parent,
[fd51a7c]856                                     NewPlotEvent(action="clear",
857                                                  group_id=str(group_id),
[23477c6]858                                                  title=title))
859                        """ 
[fd51a7c]860                        wx.PostEvent(self.parent.parent, 
[75790dc]861                                     NewPlotEvent(plot=new_plot, 
[1ec979d]862                                                group_id=str(new_plot.group_id),
863                                                title=title)) 
[c27a111]864                        msg = "Plotting the View Results  completed!"
865                        wx.PostEvent( self.parent.parent, 
866                                      StatusEvent(status=msg)) 
[75790dc]867                else:
868                   
869                    msg = "Row %s , " % str(row)
[c27a111]870                    msg += "Column %s is NOT " % str(label)
871                    msg += "the results of fits to view..."
[75790dc]872                    #raise ValueError, msg
873                    wx.PostEvent(self.parent.parent, 
874                         StatusEvent(status=msg, info="error")) 
[1ec979d]875                    time.sleep(0.5)
[665fd06]876                    continue
[75790dc]877   
878       
879     
880   
[24adb89]881    def on_plot(self, event):
882        """
[904830e]883        Evaluate the contains of textcrtl and plot result
[24adb89]884        """ 
[904830e]885        pos = self.notebook.GetSelection()
886        grid = self.notebook.GetPage(pos)
887        column_names = {}
888        if grid is not None:
889            column_names = self.notebook.get_column_labels()
[08dc9e87]890        #evaluate x
[904830e]891        sentence = self.x_axis_label.GetValue()
[1c86a37]892        try:
893            if sentence.strip() == "":
[08dc9e87]894                msg = "Select column values for x axis"
[1c86a37]895                raise ValueError, msg
896        except:
897             wx.PostEvent(self.parent.parent, 
898                             StatusEvent(status=msg, info="error")) 
899             return
[08dc9e87]900
[904830e]901        dict = parse_string(sentence, column_names.keys())
902        for tok, (col_name, list) in dict.iteritems():
903            col = column_names[col_name]
904            xaxis = self.get_plot_axis(col, list)
905            sentence = sentence.replace(tok, 
906                                        "numpy.array(%s)" % str(xaxis))
907        for key, value in FUNC_DICT.iteritems():
908            sentence = sentence.replace(key.lower(), value)
909        x = eval(sentence)
910        #evaluate y
911        sentence = self.y_axis_label.GetValue()
912        if sentence.strip() == "":
913            msg = "select value for y axis"
914            raise ValueError, msg
915        dict = parse_string(sentence, column_names.keys())
916        for tok, (col_name, list) in dict.iteritems():
917            col = column_names[col_name]
918            yaxis = self.get_plot_axis(col, list)
919            sentence = sentence.replace(tok, 
920                                        "numpy.array(%s)" % str(yaxis))
921        for key, value in FUNC_DICT.iteritems():
922            sentence = sentence.replace(key, value)
923        y = eval(sentence)
[08dc9e87]924        if len(x) != len(y) and (len(x) == 0 or len(y) == 0):
925            msg = "Need same length for X and Y axis and both greater than 0"
926            msg += " to plot.\n"
927            msg += "Got X length = %s, Y length = %s" % (str(len(x)),
928                                                          str(len(y)))
929            wx.PostEvent(self.parent.parent, 
930                             StatusEvent(status=msg, info="error")) 
931            return
932           
[904830e]933        #plotting
934        new_plot = Data1D(x=x, y=y)
[24adb89]935        new_plot.id =  wx.NewId()
936        new_plot.group_id = wx.NewId()
[904830e]937        title = "%s vs %s" % (self.y_axis_title.GetValue(), 
938                              self.x_axis_title.GetValue())
[1ec979d]939        new_plot.xaxis(self.x_axis_title.GetValue(), 
940                       self.x_axis_unit.GetValue())
941        new_plot.yaxis(self.y_axis_title.GetValue(), 
942                       self.y_axis_unit.GetValue())
[904830e]943        try:
944            title = self.notebook.GetPageText(pos)
[dadf255]945            new_plot.name = title
[1c86a37]946            new_plot.xtransform = "x"
947            new_plot.ytransform  = "y" 
[904830e]948            wx.PostEvent(self.parent.parent, 
[1ec979d]949                        NewPlotEvent(plot=new_plot, 
[c27a111]950                        group_id=str(new_plot.group_id), title =title)) 
951            msg = "Plotting completed!"
952            wx.PostEvent( self.parent.parent, 
953                                      StatusEvent(status=msg))   
[904830e]954        except:
[dadf255]955             wx.PostEvent(self.parent.parent, 
[75790dc]956                             StatusEvent(status=msg, info="error")) 
[c27a111]957
[24adb89]958    def layout_grid(self):
959        """
960        Draw the area related to the grid
961        """
[904830e]962        self.notebook = Notebook(parent=self)
[8523a1f2]963        self.notebook.set_data(self._data_inputs, self._data_outputs)
[904830e]964        self.grid_sizer.Add(self.notebook, 1, wx.EXPAND, 0)
[24adb89]965       
966    def layout_plotting_area(self):
967        """
968        Draw area containing options to plot
969        """
[75790dc]970       
[904830e]971        self.x_axis_title = wx.TextCtrl(self, -1)
972        self.y_axis_title = wx.TextCtrl(self, -1)
973        self.x_axis_label = wx.TextCtrl(self, -1, size=(200, -1))
974        self.y_axis_label = wx.TextCtrl(self, -1, size=(200, -1))
[9680906d]975        self.x_axis_add = wx.Button(self, -1, "Add")
976        self.x_axis_add.Bind(event=wx.EVT_BUTTON, handler=self.on_edit_axis, 
977                            id=self.x_axis_add.GetId())
978        self.y_axis_add = wx.Button(self, -1, "Add")
979        self.y_axis_add.Bind(event=wx.EVT_BUTTON, handler=self.on_edit_axis, 
980                            id=self.y_axis_add.GetId())
[24adb89]981        self.x_axis_unit = wx.TextCtrl(self, -1)
982        self.y_axis_unit = wx.TextCtrl(self, -1)
[1c86a37]983        self.view_button = wx.Button(self, -1, "View Results")
[7d47789]984        view_tip = "Highlight the data set or the Chi2 column first."
[b18cf3d]985        self.view_button.SetToolTipString(view_tip)
[75790dc]986        wx.EVT_BUTTON(self, self.view_button.GetId(), self.on_view)
[24adb89]987        self.plot_button = wx.Button(self, -1, "Plot")
[7d47789]988        plot_tip = "Highlight a column for each axis and \n"
989        plot_tip += "click the Add buttons first."
[b18cf3d]990        self.plot_button.SetToolTipString(plot_tip)
[75790dc]991        self.button_sizer.AddMany( [ (500, 30),
992                                (self.view_button, 0, wx.RIGHT|wx.BOTTOM, 10),
993                                (self.plot_button, 0, wx.RIGHT|wx.BOTTOM, 10)])
994       
[24adb89]995        wx.EVT_BUTTON(self, self.plot_button.GetId(), self.on_plot)
[9680906d]996        self.plotting_sizer.AddMany([
[9bfa73f]997                    (wx.StaticText(self, -1, 
998                                   "X-axis Label\nSelection Range"), 1,
[904830e]999                      wx.TOP|wx.BOTTOM|wx.LEFT, 10),
1000                    (self.x_axis_label, 1, wx.TOP|wx.BOTTOM, 10),
1001                    (self.x_axis_add, 1, wx.TOP|wx.BOTTOM|wx.RIGHT, 10),
[9bfa73f]1002                    (wx.StaticText(self, -1, "X-axis Label"), 1, 
[904830e]1003                     wx.TOP|wx.BOTTOM|wx.LEFT, 10),
1004                    (self.x_axis_title, 1, wx.TOP|wx.BOTTOM, 10),
[7124300]1005                    (wx.StaticText(self, -1 , "X-axis Unit"), 1, 
[904830e]1006                     wx.TOP|wx.BOTTOM, 10),
1007                    (self.x_axis_unit, 1, wx.TOP|wx.BOTTOM, 10),
[9bfa73f]1008                    (wx.StaticText(self, -1, 
1009                                   "Y-axis Label\nSelection Range"), 1, 
[904830e]1010                     wx.BOTTOM|wx.LEFT, 10),
1011                    (self.y_axis_label, wx.BOTTOM, 10),
1012                    (self.y_axis_add, 1, wx.BOTTOM|wx.RIGHT, 10),
[9bfa73f]1013                    (wx.StaticText(self, -1, "Y-axis Label"), 1, 
[904830e]1014                     wx.BOTTOM|wx.LEFT, 10),
1015                    (self.y_axis_title,  wx.BOTTOM, 10),
[9bfa73f]1016                    (wx.StaticText(self, -1 , "Y-axis Unit"), 1, wx.BOTTOM, 10),
[904830e]1017                    (self.y_axis_unit, 1, wx.BOTTOM, 10),
[9680906d]1018                      (-1, -1),
1019                      (-1, -1),
1020                      (-1, -1),
1021                      (-1, -1),
1022                      (-1, -1),
1023                      (-1, -1),
[75790dc]1024                      (-1, 1)])
[24adb89]1025   
[9680906d]1026    def on_edit_axis(self, event):
1027        """
1028        Get the selected column on  the visible grid and set values for axis
1029        """
[08dc9e87]1030        try:
1031            cell_list = self.notebook.on_edit_axis()
1032        except:
1033            msg = str(sys.exc_value)
1034            wx.PostEvent(self.parent.parent, 
1035                             StatusEvent(status=msg, info="error")) 
1036            return 
[904830e]1037        label, title = self.create_axis_label(cell_list)
1038        tcrtl = event.GetEventObject()
1039        if tcrtl == self.x_axis_add:
1040            self.edit_axis_helper(self.x_axis_label, self.x_axis_title,
1041                                   label, title)
1042        elif tcrtl == self.y_axis_add:
1043            self.edit_axis_helper(self.y_axis_label, self.y_axis_title,
1044                                   label, title)
1045           
[7ad194fa]1046    def create_axis_label(self, cell_list):
1047        """
1048        Receive a list of cells and  create a string presenting the selected
1049        cells.
1050        :param cell_list: list of tuple
[24adb89]1051       
[7ad194fa]1052        """
[904830e]1053        if self.notebook is not None:
1054            return self.notebook.create_axis_label(cell_list)
[7ad194fa]1055   
[904830e]1056    def edit_axis_helper(self, tcrtl_label, tcrtl_title, label, title):
[9680906d]1057        """
[904830e]1058        get controls to modify
[9680906d]1059        """
[904830e]1060        tcrtl_label.SetValue(str(label))
1061        tcrtl_title.SetValue(str(title))
1062       
[24adb89]1063    def add_column(self):
[9c8f3ad]1064        """
1065        """
[904830e]1066        if self.notebook is not None:
1067            self.notebook.add_column()
[24adb89]1068       
[9c8f3ad]1069    def on_remove_column(self):
1070        """
1071        """
[904830e]1072        if self.notebook is not None:
1073            self.notebook.on_remove_column()
[9c8f3ad]1074       
[24adb89]1075       
1076class GridFrame(wx.Frame):
[8523a1f2]1077    def __init__(self, parent=None, data_inputs=None, data_outputs=None, id=-1, 
[cf0eb8e]1078                 title="Batch Window", size=(800, 500)):
[24adb89]1079        wx.Frame.__init__(self, parent=parent, id=id, title=title, size=size)
1080        self.parent = parent
[8523a1f2]1081        self.panel = GridPanel(self, data_inputs, data_outputs)
[24adb89]1082        menubar = wx.MenuBar()
1083        self.SetMenuBar(menubar)
[71fa9028]1084       
1085        self.curr_col = None
1086        self.curr_grid = None
1087        self.curr_col_name = ""
1088        file = wx.Menu()
1089        menubar.Append(file, "&File")
1090       
1091        hint = "Open file containing batch results"
1092        open_menu = file.Append(wx.NewId(), 'Open ', hint)
1093        wx.EVT_MENU(self, open_menu.GetId(), self.on_open)
1094       
1095        hint = "Open the the current grid into excel"
1096        open_excel_menu = file.Append(wx.NewId(), 'Open with Excel', hint)
1097        wx.EVT_MENU(self, open_excel_menu.GetId(), self.open_with_excel)
1098        file.AppendSeparator()
1099        save_menu = file.Append(wx.NewId(), 'Save As', 'Save into File')
1100        wx.EVT_MENU(self, save_menu.GetId(), self.on_save_page)
1101       
1102        self.edit = wx.Menu()
1103        hint = "Insert column before the selected column"
1104        self.insert_before_menu = wx.Menu()
1105        self.insert_sub_menu = self.edit.AppendSubMenu(self.insert_before_menu, 
1106                                                      'Insert Before', hint)
1107 
1108        hint = "Remove the selected column"
1109        self.remove_menu = self.edit.Append(-1, 'Remove Column', hint)
1110        wx.EVT_MENU(self, self.remove_menu.GetId(), self.on_remove_column)
1111       
1112        self.Bind(wx.EVT_MENU_OPEN, self.on_menu_open)
1113        menubar.Append(self.edit, "&Edit")
[cb26857]1114        self.Bind(wx.EVT_CLOSE, self.on_close)
[71fa9028]1115    def GetLabelText(self, id):
[656d65d]1116        """
1117        """
[71fa9028]1118        for item in self.insert_before_menu.GetMenuItems():
1119            m_id = item.GetId() 
1120            if m_id == id:
1121                return item.GetLabel() 
1122   
1123    def on_remove_column(self, event):
[cb26857]1124        """
1125        """
[71fa9028]1126        pos = self.panel.notebook.GetSelection()
1127        grid = self.panel.notebook.GetPage(pos)
1128        grid.on_remove_column(event=None)
[cb26857]1129       
[71fa9028]1130    def on_menu_open(self, event):
[9c8f3ad]1131        """
[71fa9028]1132       
[9c8f3ad]1133        """
[71fa9028]1134        if self.edit == event.GetMenu():
1135            #get the selected column
1136            pos = self.panel.notebook.GetSelection()
1137            grid = self.panel.notebook.GetPage(pos)
1138            col_list = grid.GetSelectedCols()
1139            if len(col_list) > 0:
1140                self.remove_menu.Enable(True)
1141            else:
1142                self.remove_menu.Enable(False)
1143            if len(col_list)== 0 or len(col_list) > 1:
1144                self.insert_sub_menu.Enable(False)
1145               
1146                label = "Insert Column Before"
1147                self.insert_sub_menu.SetText(label)
1148            else:
1149                self.insert_sub_menu.Enable(True)
1150               
1151                col = col_list[0]
1152                #GetColLabelValue(self, col)
1153                col_name = grid.GetCellValue(row=0, col=col)
1154                label = "Insert Column Before " + str(col_name)
1155                self.insert_sub_menu.SetText(label)
1156                for item in self.insert_before_menu.GetMenuItems():
1157                    self.insert_before_menu.DeleteItem(item)
1158                grid.insert_col_menu(menu=self.insert_before_menu, 
1159                                     label=col_name, window=self)
1160        event.Skip()
[9c8f3ad]1161       
[71fa9028]1162 
1163       
1164    def on_save_page(self, event):
1165        """
1166        """
1167        if self.parent is not None:
1168            pos = self.panel.notebook.GetSelection()
1169            grid = self.panel.notebook.GetPage(pos)
[7b48b08]1170            if grid.file_name is None or grid.file_name.strip() == "" or \
1171                grid.data is None or len(grid.data) == 0:
1172                name = self.panel.notebook.GetPageText(pos)
1173                msg = " %s has not data to save" % str(name)
1174                wx.PostEvent(self.parent, 
1175                             StatusEvent(status=msg, info="error")) 
1176           
1177                return
[71fa9028]1178            reader, ext = os.path.splitext(grid.file_name)
1179            path = None
1180            if self.parent is not None: 
1181                location = os.path.dirname(grid.file_name)
1182                dlg = wx.FileDialog(self, "Save Project file",
1183                            location, grid.file_name, ext, wx.SAVE)
1184                path = None
1185                if dlg.ShowModal() == wx.ID_OK:
1186                    path = dlg.GetPath()
1187                dlg.Destroy()
1188                if path != None:
1189                    if self.parent is not None:
1190                        data = grid.get_grid_view()
1191                        self.parent.write_batch_tofile(data=data, 
1192                                               file_name=path,
1193                                               details=grid.details)
1194   
1195    def on_open(self, event):
[656d65d]1196        """
[71fa9028]1197        Open file containg batch result
[656d65d]1198        """
[71fa9028]1199        if self.parent is not None:
1200            self.parent.on_read_batch_tofile(event)
1201           
1202    def open_with_excel(self, event):
1203        """
1204        open excel and display batch result in Excel
1205        """
1206        if self.parent is not None:
1207            pos = self.panel.notebook.GetSelection()
1208            grid = self.panel.notebook.GetPage(pos)
1209            data = grid.get_grid_view()
[7b48b08]1210            if grid.file_name is None or grid.file_name.strip() == "" or \
1211                grid.data is None or len(grid.data) == 0:
1212                name = self.panel.notebook.GetPageText(pos)
1213                msg = " %s has not data to open on excel" % str(name)
1214                wx.PostEvent(self.parent, 
1215                             StatusEvent(status=msg, info="error")) 
1216           
1217                return
[71fa9028]1218            self.parent.open_with_externalapp(data=data,
1219                                               file_name=grid.file_name, 
1220                                               details=grid.details)
1221           
1222    def on_close(self, event):
1223        """
1224        """
1225        self.Hide()
[656d65d]1226       
[71fa9028]1227   
[656d65d]1228    def on_append_column(self, event):
[cb26857]1229        """
[9c8f3ad]1230        Append a new column to the grid
[cb26857]1231        """
[24adb89]1232        self.panel.add_column()
[cb26857]1233       
[71fa9028]1234    def set_data(self, data_inputs, data_outputs, details="", file_name=None):
[cb26857]1235        """
1236        """
[a84ca2a]1237       
1238        self.panel.notebook.set_data(data_inputs=data_inputs, 
[71fa9028]1239                            file_name=file_name,
1240                            details=details,
1241                            data_outputs=data_outputs)
[24adb89]1242     
1243     
[83eb1b52]1244class BatchOutputFrame(wx.Frame):
[73197d0]1245    """
1246    Allow to select where the result of batch will be displayed or stored
1247    """
[8523a1f2]1248    def __init__(self, parent, data_inputs, data_outputs, file_name="",
[850525c]1249                 details="", *args, **kwds):
[73197d0]1250        """
1251        :param parent: Window instantiating this dialog
1252        :param result: result to display in a grid or export to an external
1253                application.
1254        """
[850525c]1255        #kwds['style'] = wx.CAPTION|wx.SYSTEM_MENU
[83eb1b52]1256        wx.Frame.__init__(self, parent, *args, **kwds)
[73197d0]1257        self.parent = parent
[83eb1b52]1258        self.panel = wx.Panel(self)
[850525c]1259        self.file_name = file_name
1260        self.details = details
[8523a1f2]1261        self.data_inputs = data_inputs
1262        self.data_outputs = data_outputs
1263        self.data = {}
1264        for item in (self.data_outputs, self.data_inputs):
1265            self.data.update(item)
[73197d0]1266        self.flag = 1
1267        self.SetSize((300, 200))
1268        self.local_app_selected = None
1269        self.external_app_selected = None
1270        self.save_to_file = None
1271        self._do_layout()
[8523a1f2]1272   
[73197d0]1273    def _do_layout(self):
1274        """
1275        Draw the content of the current dialog window
1276        """
1277        vbox = wx.BoxSizer(wx.VERTICAL)
[83eb1b52]1278        box_description = wx.StaticBox(self.panel, -1, str("Batch Outputs"))
[73197d0]1279        hint_sizer = wx.StaticBoxSizer(box_description, wx.VERTICAL)
[83eb1b52]1280        selection_sizer = wx.GridBagSizer(5, 5)
[73197d0]1281        button_sizer = wx.BoxSizer(wx.HORIZONTAL)
[caf3a08f]1282        text = "Open with %s" % self.parent.application_name
[83eb1b52]1283        self.local_app_selected = wx.RadioButton(self.panel, -1, text,
[73197d0]1284                                                style=wx.RB_GROUP)
1285        self.Bind(wx.EVT_RADIOBUTTON, self.onselect,
1286                    id=self.local_app_selected.GetId())
1287        text = "Open with Excel"
[83eb1b52]1288        self.external_app_selected  = wx.RadioButton(self.panel, -1, text)
[73197d0]1289        self.Bind(wx.EVT_RADIOBUTTON, self.onselect,
1290                    id=self.external_app_selected.GetId())
[caf3a08f]1291        text = "Save to File"
[83eb1b52]1292        self.save_to_file = wx.CheckBox(self.panel, -1, text)
[73197d0]1293        self.Bind(wx.EVT_CHECKBOX, self.onselect,
1294                    id=self.save_to_file.GetId())
1295        self.local_app_selected.SetValue(True)
1296        self.external_app_selected.SetValue(False)
1297        self.save_to_file.SetValue(False)
[83eb1b52]1298        button_close = wx.Button(self.panel, -1, "Close")
1299        button_close.Bind(wx.EVT_BUTTON, id=button_close.GetId(),
1300                           handler=self.on_close)
1301        button_apply = wx.Button(self.panel, -1, "Apply")
1302        button_apply.Bind(wx.EVT_BUTTON, id=button_apply.GetId(),
1303                        handler=self.on_apply)
1304        button_apply.SetFocus()
[73197d0]1305        hint = ""
[83eb1b52]1306        hint_sizer.Add(wx.StaticText(self.panel, -1, hint))
[73197d0]1307        hint_sizer.Add(selection_sizer)
1308        #draw area containing radio buttons
1309        ix = 0
1310        iy = 0
1311        selection_sizer.Add(self.local_app_selected, (iy, ix),
1312                           (1, 1), wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
1313        iy += 1
1314        selection_sizer.Add(self.external_app_selected, (iy, ix),
1315                           (1, 1), wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
1316        iy += 1
1317        selection_sizer.Add(self.save_to_file, (iy, ix),
1318                           (1, 1), wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
1319        #contruction the sizer contaning button
1320        button_sizer.Add((20, 20), 1, wx.EXPAND|wx.ADJUST_MINSIZE, 0)
[caf3a08f]1321
1322        button_sizer.Add(button_close, 0,
1323                        wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
[83eb1b52]1324        button_sizer.Add(button_apply, 0,
[73197d0]1325                                wx.LEFT|wx.RIGHT|wx.ADJUST_MINSIZE, 10)
1326        vbox.Add(hint_sizer,  0, wx.EXPAND|wx.ALL, 10)
[83eb1b52]1327        vbox.Add(wx.StaticLine(self.panel, -1),  0, wx.EXPAND, 0)
[73197d0]1328        vbox.Add(button_sizer, 0 , wx.TOP|wx.BOTTOM, 10)
1329        self.SetSizer(vbox)
1330       
[83eb1b52]1331    def on_apply(self, event):
1332        """
1333        Get the user selection and display output to the selected application
1334        """
1335        if self.flag == 1:
[8523a1f2]1336            self.parent.open_with_localapp(data_inputs=self.data_inputs,
1337                                            data_outputs=self.data_outputs)
[83eb1b52]1338        elif self.flag == 2:
1339            self.parent.open_with_externalapp(data=self.data, 
1340                                           file_name=self.file_name,
1341                                           details=self.details)
1342    def on_close(self, event):
1343        """
1344        close the Window
1345        """
1346        self.Close()
1347       
[73197d0]1348    def onselect(self, event=None):
1349        """
1350        Receive event and display data into third party application
1351        or save data to file.
1352       
1353        """
1354        if self.save_to_file.GetValue():
[850525c]1355            reader, ext = os.path.splitext(self.file_name)
1356            path = None
1357            location = os.getcwd()
1358            if self.parent is not None: 
[83eb1b52]1359                location = os.path.dirname(self.file_name)
[850525c]1360                dlg = wx.FileDialog(self, "Save Project file",
1361                            location, self.file_name, ext, wx.SAVE)
1362                path = None
1363                if dlg.ShowModal() == wx.ID_OK:
1364                    path = dlg.GetPath()
1365                dlg.Destroy()
1366                if path != None:
1367                    if self.parent is not None and  self.data is not None:
[83eb1b52]1368                        self.parent.write_batch_tofile(data=self.data, 
[850525c]1369                                               file_name=path,
1370                                               details=self.details)
1371        if self.local_app_selected.GetValue():
[73197d0]1372            self.flag = 1
1373        else:
1374            self.flag = 2
1375        return self.flag
1376   
1377 
1378       
[24adb89]1379if __name__ == "__main__":
1380    app = wx.App()
1381   
1382    try:
1383        data = {}
1384        j = 0
1385        for i in range(4):
1386            j += 1
1387            data["index"+str(i)] = [i/j, i*j, i, i+j]
[656d65d]1388       
1389        data_input =  copy.deepcopy(data)   
1390        data_input["index5"] = [10,20,40, 50]
1391        frame = GridFrame(data_outputs=data, data_inputs=data_input)
[24adb89]1392        frame.Show(True)
1393    except:
1394        print sys.exc_value
1395       
1396    app.MainLoop()
Note: See TracBrowser for help on using the repository browser.