source: sasview/sansguiframe/src/sans/guiframe/data_processor.py @ 4e0dfe4

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 4e0dfe4 was 4e0dfe4, checked in by Jae Cho <jhjcho@…>, 12 years ago

batch-panel: better cell selection: still many more to go

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