source: sasview/sansguiframe/src/sans/guiframe/data_processor.py @ 0ea247e

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 0ea247e was a5e749f, checked in by Mathieu Doucet <doucetm@…>, 12 years ago

Fixing code style problems and bugs

  • 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_view(self, event):
839        """
840        Get object represented buy the given cell and plot them.
841        """
842        pos = self.notebook.GetSelection()
843        grid = self.notebook.GetPage(pos)
844        title = self.notebook.GetPageText(pos)
845        if len(grid.selected_cells) == 0:
846            msg = "Highlight a Data or Chi2 column first..."
847            wx.PostEvent(self.parent.parent, 
848                             StatusEvent(status=msg, info="error")) 
849            return
850        elif len(grid.selected_cells) > 20:
851            msg = "Too many data (> 20) to plot..."
852            msg += "\n Please select no more than 20 data."
853            dial = wx.MessageDialog(self, msg, 'Plotting', wx.OK)
854            wx.PostEvent(self.parent.parent, 
855                             StatusEvent(status=msg, info="error")) 
856            return
857
858        for cell in grid.selected_cells:
859            row, col = cell
860            label_row = 0
861            label = grid.GetCellValue(label_row, col)
862            if label in grid.data:
863                values = grid.data[label]
864                if row > len(values) or row < 1:
865                    msg = "Invalid cell was chosen." 
866                    wx.PostEvent(self.parent.parent, StatusEvent(status=msg, 
867                                                                info="error"))
868                    time.sleep(0.5)
869                    continue
870                else:
871                     value = values[row -1]
872                if issubclass(value.__class__, BatchCell):
873                    if value.object is None or len(value.object) == 0:
874                        msg = "Row %s , " % str(row)
875                        msg += "Column %s is NOT " % str(label)
876                        msg += "the results of fits to view..."
877                        #raise ValueError, msg
878                        wx.PostEvent(self.parent.parent, StatusEvent(status=msg, 
879                                                                info="error")) 
880                        return
881                    for new_plot in value.object:
882                        if new_plot is None or \
883                         not issubclass(new_plot.__class__, 
884                                        plottables.Plottable):
885                            msg = "Row %s , " % str(row)
886                            msg += "Column %s is NOT " % str(label)
887                            msg += "the results of fits to view..."
888                            #raise ValueError, msg
889                            wx.PostEvent(self.parent.parent, 
890                                 StatusEvent(status=msg, info="error")) 
891                            time.sleep(0.5)
892                            continue
893                        #new_plot.name =  title + ': ' + new_plot.title
894                        if issubclass(new_plot.__class__, Data1D):
895                            if label in grid.list_plot_panels.keys():
896                                group_id = grid.list_plot_panels[label]
897                            else:
898                                group_id = str(new_plot.group_id) + str(grid.uid)
899                                grid.list_plot_panels[label] = group_id
900                            if group_id not in new_plot.list_group_id:
901                                new_plot.group_id = group_id
902                                new_plot.list_group_id.append(group_id)
903                        else:
904                            if label.lower() in ["data", "chi2"]:
905                                if len(grid.selected_cells) != 1:
906                                    msg = "2D View: Please select one data set"
907                                    msg += " at a time for View Fit Results."
908                                    wx.PostEvent(self.parent.parent, 
909                                                 StatusEvent(status=msg,
910                                                              info="error"))
911                                    time.sleep(0.5) 
912                                    continue 
913                        """
914                        wx.PostEvent(self.parent.parent,
915                                     NewPlotEvent(action="clear",
916                                                  group_id=str(group_id),
917                                                  title=title))
918                        """ 
919                        wx.PostEvent(self.parent.parent, 
920                                     NewPlotEvent(plot=new_plot, 
921                                                group_id=str(new_plot.group_id),
922                                                title=title)) 
923                        msg = "Plotting the View Fit Results  completed!"
924                        wx.PostEvent( self.parent.parent, 
925                                      StatusEvent(status=msg)) 
926                else:
927                   
928                    msg = "Row %s , " % str(row)
929                    msg += "Column %s is NOT " % str(label)
930                    msg += "the results of fits to view..."
931                    #raise ValueError, msg
932                    wx.PostEvent(self.parent.parent, 
933                         StatusEvent(status=msg, info="error")) 
934                    time.sleep(0.5)
935                    continue
936   
937       
938     
939   
940    def on_plot(self, event):
941        """
942        Evaluate the contains of textcrtl and plot result
943        """ 
944        pos = self.notebook.GetSelection()
945        grid = self.notebook.GetPage(pos)
946        column_names = {}
947        if grid is not None:
948            column_names = self.notebook.get_column_labels()
949        #evaluate x
950        sentence = self.x_axis_label.GetValue()
951        try:
952            if sentence.strip() == "":
953                msg = "Select column values for x axis"
954                raise ValueError, msg
955        except:
956             wx.PostEvent(self.parent.parent, 
957                             StatusEvent(status=msg, info="error")) 
958             return
959
960        dict = parse_string(sentence, column_names.keys())
961        for tok, (col_name, list) in dict.iteritems():
962            col = column_names[col_name]
963            xaxis = self.get_plot_axis(col, list)
964            sentence = sentence.replace(tok, 
965                                        "numpy.array(%s)" % str(xaxis))
966        for key, value in FUNC_DICT.iteritems():
967            sentence = sentence.replace(key.lower(), value)
968        x = eval(sentence)
969        #evaluate y
970        sentence = self.y_axis_label.GetValue()
971        if sentence.strip() == "":
972            msg = "select value for y axis"
973            raise ValueError, msg
974        dict = parse_string(sentence, column_names.keys())
975        for tok, (col_name, list) in dict.iteritems():
976            col = column_names[col_name]
977            yaxis = self.get_plot_axis(col, list)
978            sentence = sentence.replace(tok, 
979                                        "numpy.array(%s)" % str(yaxis))
980        for key, value in FUNC_DICT.iteritems():
981            sentence = sentence.replace(key, value)
982        y = eval(sentence)
983        if len(x) != len(y) and (len(x) == 0 or len(y) == 0):
984            msg = "Need same length for X and Y axis and both greater than 0"
985            msg += " to plot.\n"
986            msg += "Got X length = %s, Y length = %s" % (str(len(x)),
987                                                          str(len(y)))
988            wx.PostEvent(self.parent.parent, 
989                             StatusEvent(status=msg, info="error")) 
990            return
991           
992        #plotting
993        new_plot = Data1D(x=x, y=y)
994        new_plot.id =  wx.NewId()
995        new_plot.group_id = wx.NewId()
996        title = "%s vs %s" % (self.y_axis_title.GetValue(), 
997                              self.x_axis_title.GetValue())
998        new_plot.xaxis(self.x_axis_title.GetValue(), 
999                       self.x_axis_unit.GetValue())
1000        new_plot.yaxis(self.y_axis_title.GetValue(), 
1001                       self.y_axis_unit.GetValue())
1002        try:
1003            title = self.notebook.GetPageText(pos)
1004            new_plot.name = title
1005            new_plot.xtransform = "x"
1006            new_plot.ytransform  = "y" 
1007            wx.PostEvent(self.parent.parent, 
1008                        NewPlotEvent(plot=new_plot, 
1009                        group_id=str(new_plot.group_id), title =title)) 
1010            msg = "Plotting completed!"
1011            wx.PostEvent( self.parent.parent, 
1012                                      StatusEvent(status=msg))   
1013        except:
1014             wx.PostEvent(self.parent.parent, 
1015                             StatusEvent(status=msg, info="error")) 
1016
1017    def layout_grid(self):
1018        """
1019        Draw the area related to the grid
1020        """
1021        self.notebook = Notebook(parent=self)
1022        self.notebook.set_data(self._data_inputs, self._data_outputs)
1023        self.grid_sizer.Add(self.notebook, 1, wx.EXPAND, 0)
1024       
1025    def layout_plotting_area(self):
1026        """
1027        Draw area containing options to plot
1028        """
1029       
1030        self.x_axis_title = wx.TextCtrl(self, -1)
1031        self.y_axis_title = wx.TextCtrl(self, -1)
1032        self.x_axis_label = wx.TextCtrl(self, -1, size=(200, -1))
1033        self.y_axis_label = wx.TextCtrl(self, -1, size=(200, -1))
1034        self.x_axis_add = wx.Button(self, -1, "Add")
1035        self.x_axis_add.Bind(event=wx.EVT_BUTTON, handler=self.on_edit_axis, 
1036                            id=self.x_axis_add.GetId())
1037        self.y_axis_add = wx.Button(self, -1, "Add")
1038        self.y_axis_add.Bind(event=wx.EVT_BUTTON, handler=self.on_edit_axis, 
1039                            id=self.y_axis_add.GetId())
1040        self.x_axis_unit = wx.TextCtrl(self, -1)
1041        self.y_axis_unit = wx.TextCtrl(self, -1)
1042        self.view_button = wx.Button(self, -1, "View Fits")
1043        view_tip = "Highlight the data set or the Chi2 column first."
1044        self.view_button.SetToolTipString(view_tip)
1045        wx.EVT_BUTTON(self, self.view_button.GetId(), self.on_view)
1046        self.plot_button = wx.Button(self, -1, "Plot")
1047        plot_tip = "Highlight a column for each axis and \n"
1048        plot_tip += "click the Add buttons first."
1049        self.plot_button.SetToolTipString(plot_tip)
1050        self.button_sizer.AddMany( [ (500, 30),
1051                                (self.view_button, 0, wx.RIGHT|wx.BOTTOM, 10),
1052                                (self.plot_button, 0, wx.RIGHT|wx.BOTTOM, 10)])
1053       
1054        wx.EVT_BUTTON(self, self.plot_button.GetId(), self.on_plot)
1055        self.plotting_sizer.AddMany([
1056                    (wx.StaticText(self, -1, 
1057                                   "X-axis Label\nSelection Range"), 1,
1058                      wx.TOP|wx.BOTTOM|wx.LEFT, 10),
1059                    (self.x_axis_label, 1, wx.TOP|wx.BOTTOM, 10),
1060                    (self.x_axis_add, 1, wx.TOP|wx.BOTTOM|wx.RIGHT, 10),
1061                    (wx.StaticText(self, -1, "X-axis Label"), 1, 
1062                     wx.TOP|wx.BOTTOM|wx.LEFT, 10),
1063                    (self.x_axis_title, 1, wx.TOP|wx.BOTTOM, 10),
1064                    (wx.StaticText(self, -1 , "X-axis Unit"), 1, 
1065                     wx.TOP|wx.BOTTOM, 10),
1066                    (self.x_axis_unit, 1, wx.TOP|wx.BOTTOM, 10),
1067                    (wx.StaticText(self, -1, 
1068                                   "Y-axis Label\nSelection Range"), 1, 
1069                     wx.BOTTOM|wx.LEFT, 10),
1070                    (self.y_axis_label, wx.BOTTOM, 10),
1071                    (self.y_axis_add, 1, wx.BOTTOM|wx.RIGHT, 10),
1072                    (wx.StaticText(self, -1, "Y-axis Label"), 1, 
1073                     wx.BOTTOM|wx.LEFT, 10),
1074                    (self.y_axis_title,  wx.BOTTOM, 10),
1075                    (wx.StaticText(self, -1 , "Y-axis Unit"), 1, wx.BOTTOM, 10),
1076                    (self.y_axis_unit, 1, wx.BOTTOM, 10),
1077                      (-1, -1),
1078                      (-1, -1),
1079                      (-1, -1),
1080                      (-1, -1),
1081                      (-1, -1),
1082                      (-1, -1),
1083                      (-1, 1)])
1084   
1085    def on_edit_axis(self, event):
1086        """
1087        Get the selected column on  the visible grid and set values for axis
1088        """
1089        try:
1090            cell_list = self.notebook.on_edit_axis()
1091        except:
1092            msg = str(sys.exc_value)
1093            wx.PostEvent(self.parent.parent, 
1094                             StatusEvent(status=msg, info="error")) 
1095            return 
1096        label, title = self.create_axis_label(cell_list)
1097        tcrtl = event.GetEventObject()
1098        if tcrtl == self.x_axis_add:
1099            self.edit_axis_helper(self.x_axis_label, self.x_axis_title,
1100                                   label, title)
1101        elif tcrtl == self.y_axis_add:
1102            self.edit_axis_helper(self.y_axis_label, self.y_axis_title,
1103                                   label, title)
1104           
1105    def create_axis_label(self, cell_list):
1106        """
1107        Receive a list of cells and  create a string presenting the selected
1108        cells.
1109        :param cell_list: list of tuple
1110       
1111        """
1112        if self.notebook is not None:
1113            return self.notebook.create_axis_label(cell_list)
1114   
1115    def edit_axis_helper(self, tcrtl_label, tcrtl_title, label, title):
1116        """
1117        get controls to modify
1118        """
1119        tcrtl_label.SetValue(str(label))
1120        tcrtl_title.SetValue(str(title))
1121       
1122    def add_column(self):
1123        """
1124        """
1125        if self.notebook is not None:
1126            self.notebook.add_column()
1127       
1128    def on_remove_column(self):
1129        """
1130        """
1131        if self.notebook is not None:
1132            self.notebook.on_remove_column()
1133       
1134       
1135class GridFrame(wx.Frame):
1136    def __init__(self, parent=None, data_inputs=None, data_outputs=None, id=-1, 
1137                 title="Batch Window", size=(800, 500)):
1138        wx.Frame.__init__(self, parent=parent, id=id, title=title, size=size)
1139        self.parent = parent
1140        self.panel = GridPanel(self, data_inputs, data_outputs)
1141        menubar = wx.MenuBar()
1142        self.SetMenuBar(menubar)
1143       
1144        self.curr_col = None
1145        self.curr_grid = None
1146        self.curr_col_name = ""
1147        file = wx.Menu()
1148        menubar.Append(file, "&File")
1149       
1150        hint = "Open file containing batch results"
1151        open_menu = file.Append(wx.NewId(), 'Open ', hint)
1152        wx.EVT_MENU(self, open_menu.GetId(), self.on_open)
1153       
1154        hint = "Open the the current grid into excel"
1155        open_excel_menu = file.Append(wx.NewId(), 'Open with Excel', hint)
1156        wx.EVT_MENU(self, open_excel_menu.GetId(), self.open_with_excel)
1157        file.AppendSeparator()
1158        save_menu = file.Append(wx.NewId(), 'Save As', 'Save into File')
1159        wx.EVT_MENU(self, save_menu.GetId(), self.on_save_page)
1160       
1161        self.edit = wx.Menu()
1162        hint = "Insert column before the selected column"
1163        self.insert_before_menu = wx.Menu()
1164        self.insert_sub_menu = self.edit.AppendSubMenu(self.insert_before_menu, 
1165                                                      'Insert Before', hint)
1166 
1167        hint = "Remove the selected column"
1168        self.remove_menu = self.edit.Append(-1, 'Remove Column', hint)
1169        wx.EVT_MENU(self, self.remove_menu.GetId(), self.on_remove_column)
1170       
1171        self.Bind(wx.EVT_MENU_OPEN, self.on_menu_open)
1172        menubar.Append(self.edit, "&Edit")
1173        self.Bind(wx.EVT_CLOSE, self.on_close)
1174    def GetLabelText(self, id):
1175        """
1176        """
1177        for item in self.insert_before_menu.GetMenuItems():
1178            m_id = item.GetId() 
1179            if m_id == id:
1180                return item.GetLabel() 
1181   
1182    def on_remove_column(self, event):
1183        """
1184        """
1185        pos = self.panel.notebook.GetSelection()
1186        grid = self.panel.notebook.GetPage(pos)
1187        grid.on_remove_column(event=None)
1188       
1189    def on_menu_open(self, event):
1190        """
1191       
1192        """
1193        if self.edit == event.GetMenu():
1194            #get the selected column
1195            pos = self.panel.notebook.GetSelection()
1196            grid = self.panel.notebook.GetPage(pos)
1197            col_list = grid.GetSelectedCols()
1198            if len(col_list) > 0:
1199                self.remove_menu.Enable(True)
1200            else:
1201                self.remove_menu.Enable(False)
1202            if len(col_list) == 0 or len(col_list) > 1:
1203                self.insert_sub_menu.Enable(False)
1204               
1205                label = "Insert Column Before"
1206                self.insert_sub_menu.SetText(label)
1207            else:
1208                self.insert_sub_menu.Enable(True)
1209               
1210                col = col_list[0]
1211                #GetColLabelValue(self, col)
1212                col_name = grid.GetCellValue(row=0, col=col)
1213                label = "Insert Column Before " + str(col_name)
1214                self.insert_sub_menu.SetText(label)
1215                for item in self.insert_before_menu.GetMenuItems():
1216                    self.insert_before_menu.DeleteItem(item)
1217                grid.insert_col_menu(menu=self.insert_before_menu, 
1218                                     label=col_name, window=self)
1219        event.Skip()
1220       
1221 
1222       
1223    def on_save_page(self, event):
1224        """
1225        """
1226        if self.parent is not None:
1227            pos = self.panel.notebook.GetSelection()
1228            grid = self.panel.notebook.GetPage(pos)
1229            if grid.file_name is None or grid.file_name.strip() == "" or \
1230                grid.data is None or len(grid.data) == 0:
1231                name = self.panel.notebook.GetPageText(pos)
1232                msg = " %s has not data to save" % str(name)
1233                wx.PostEvent(self.parent, 
1234                             StatusEvent(status=msg, info="error")) 
1235           
1236                return
1237            reader, ext = os.path.splitext(grid.file_name)
1238            path = None
1239            if self.parent is not None: 
1240                location = os.path.dirname(grid.file_name)
1241                dlg = wx.FileDialog(self, "Save Project file",
1242                            location, grid.file_name, ext, wx.SAVE)
1243                path = None
1244                if dlg.ShowModal() == wx.ID_OK:
1245                    path = dlg.GetPath()
1246                dlg.Destroy()
1247                if path != None:
1248                    if self.parent is not None:
1249                        data = grid.get_grid_view()
1250                        self.parent.write_batch_tofile(data=data, 
1251                                               file_name=path,
1252                                               details=grid.details)
1253   
1254    def on_open(self, event):
1255        """
1256        Open file containg batch result
1257        """
1258        if self.parent is not None:
1259            self.parent.on_read_batch_tofile(event)
1260           
1261    def open_with_excel(self, event):
1262        """
1263        open excel and display batch result in Excel
1264        """
1265        if self.parent is not None:
1266            pos = self.panel.notebook.GetSelection()
1267            grid = self.panel.notebook.GetPage(pos)
1268            data = grid.get_grid_view()
1269            if grid.file_name is None or grid.file_name.strip() == "" or \
1270                grid.data is None or len(grid.data) == 0:
1271                name = self.panel.notebook.GetPageText(pos)
1272                msg = " %s has not data to open on excel" % str(name)
1273                wx.PostEvent(self.parent, 
1274                             StatusEvent(status=msg, info="error")) 
1275           
1276                return
1277            self.parent.open_with_externalapp(data=data,
1278                                              file_name=grid.file_name, 
1279                                              details=grid.details)
1280           
1281    def on_close(self, event):
1282        """
1283        """
1284        self.Hide()
1285       
1286   
1287    def on_append_column(self, event):
1288        """
1289        Append a new column to the grid
1290        """
1291        self.panel.add_column()
1292       
1293    def set_data(self, data_inputs, data_outputs, details="", file_name=None):
1294        """
1295        """
1296       
1297        self.panel.notebook.set_data(data_inputs=data_inputs, 
1298                            file_name=file_name,
1299                            details=details,
1300                            data_outputs=data_outputs)
1301     
1302     
1303class BatchOutputFrame(wx.Frame):
1304    """
1305    Allow to select where the result of batch will be displayed or stored
1306    """
1307    def __init__(self, parent, data_inputs, data_outputs, file_name="",
1308                 details="", *args, **kwds):
1309        """
1310        :param parent: Window instantiating this dialog
1311        :param result: result to display in a grid or export to an external
1312                application.
1313        """
1314        #kwds['style'] = wx.CAPTION|wx.SYSTEM_MENU
1315        wx.Frame.__init__(self, parent, *args, **kwds)
1316        self.parent = parent
1317        self.panel = wx.Panel(self)
1318        self.file_name = file_name
1319        self.details = details
1320        self.data_inputs = data_inputs
1321        self.data_outputs = data_outputs
1322        self.data = {}
1323        for item in (self.data_outputs, self.data_inputs):
1324            self.data.update(item)
1325        self.flag = 1
1326        self.SetSize((300, 200))
1327        self.local_app_selected = None
1328        self.external_app_selected = None
1329        self.save_to_file = None
1330        self._do_layout()
1331   
1332    def _do_layout(self):
1333        """
1334        Draw the content of the current dialog window
1335        """
1336        vbox = wx.BoxSizer(wx.VERTICAL)
1337        box_description = wx.StaticBox(self.panel, -1, str("Batch Outputs"))
1338        hint_sizer = wx.StaticBoxSizer(box_description, wx.VERTICAL)
1339        selection_sizer = wx.GridBagSizer(5, 5)
1340        button_sizer = wx.BoxSizer(wx.HORIZONTAL)
1341        text = "Open with %s" % self.parent.application_name
1342        self.local_app_selected = wx.RadioButton(self.panel, -1, text,
1343                                                style=wx.RB_GROUP)
1344        self.Bind(wx.EVT_RADIOBUTTON, self.onselect,
1345                    id=self.local_app_selected.GetId())
1346        text = "Open with Excel"
1347        self.external_app_selected  = wx.RadioButton(self.panel, -1, text)
1348        self.Bind(wx.EVT_RADIOBUTTON, self.onselect,
1349                    id=self.external_app_selected.GetId())
1350        text = "Save to File"
1351        self.save_to_file = wx.CheckBox(self.panel, -1, text)
1352        self.Bind(wx.EVT_CHECKBOX, self.onselect,
1353                    id=self.save_to_file.GetId())
1354        self.local_app_selected.SetValue(True)
1355        self.external_app_selected.SetValue(False)
1356        self.save_to_file.SetValue(False)
1357        button_close = wx.Button(self.panel, -1, "Close")
1358        button_close.Bind(wx.EVT_BUTTON, id=button_close.GetId(),
1359                           handler=self.on_close)
1360        button_apply = wx.Button(self.panel, -1, "Apply")
1361        button_apply.Bind(wx.EVT_BUTTON, id=button_apply.GetId(),
1362                        handler=self.on_apply)
1363        button_apply.SetFocus()
1364        hint = ""
1365        hint_sizer.Add(wx.StaticText(self.panel, -1, hint))
1366        hint_sizer.Add(selection_sizer)
1367        #draw area containing radio buttons
1368        ix = 0
1369        iy = 0
1370        selection_sizer.Add(self.local_app_selected, (iy, ix),
1371                           (1, 1), wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
1372        iy += 1
1373        selection_sizer.Add(self.external_app_selected, (iy, ix),
1374                           (1, 1), wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
1375        iy += 1
1376        selection_sizer.Add(self.save_to_file, (iy, ix),
1377                           (1, 1), wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
1378        #contruction the sizer contaning button
1379        button_sizer.Add((20, 20), 1, wx.EXPAND|wx.ADJUST_MINSIZE, 0)
1380
1381        button_sizer.Add(button_close, 0,
1382                        wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
1383        button_sizer.Add(button_apply, 0,
1384                                wx.LEFT|wx.RIGHT|wx.ADJUST_MINSIZE, 10)
1385        vbox.Add(hint_sizer, 0, wx.EXPAND|wx.ALL, 10)
1386        vbox.Add(wx.StaticLine(self.panel, -1),  0, wx.EXPAND, 0)
1387        vbox.Add(button_sizer, 0, wx.TOP|wx.BOTTOM, 10)
1388        self.SetSizer(vbox)
1389       
1390    def on_apply(self, event):
1391        """
1392        Get the user selection and display output to the selected application
1393        """
1394        if self.flag == 1:
1395            self.parent.open_with_localapp(data_inputs=self.data_inputs,
1396                                           data_outputs=self.data_outputs)
1397        elif self.flag == 2:
1398            self.parent.open_with_externalapp(data=self.data, 
1399                                              file_name=self.file_name,
1400                                              details=self.details)
1401    def on_close(self, event):
1402        """
1403        close the Window
1404        """
1405        self.Close()
1406       
1407    def onselect(self, event=None):
1408        """
1409        Receive event and display data into third party application
1410        or save data to file.
1411       
1412        """
1413        if self.save_to_file.GetValue():
1414            reader, ext = os.path.splitext(self.file_name)
1415            path = None
1416            location = os.getcwd()
1417            if self.parent is not None: 
1418                location = os.path.dirname(self.file_name)
1419                dlg = wx.FileDialog(self, "Save Project file",
1420                            location, self.file_name, ext, wx.SAVE)
1421                path = None
1422                if dlg.ShowModal() == wx.ID_OK:
1423                    path = dlg.GetPath()
1424                dlg.Destroy()
1425                if path != None:
1426                    if self.parent is not None and  self.data is not None:
1427                        self.parent.write_batch_tofile(data=self.data, 
1428                                                       file_name=path,
1429                                                       details=self.details)
1430        if self.local_app_selected.GetValue():
1431            self.flag = 1
1432        else:
1433            self.flag = 2
1434        return self.flag
1435   
1436 
1437       
1438if __name__ == "__main__":
1439    app = wx.App()
1440   
1441    try:
1442        data = {}
1443        j = 0
1444        for i in range(4):
1445            j += 1
1446            data["index"+str(i)] = [i/j, i*j, i, i+j]
1447       
1448        data_input =  copy.deepcopy(data)   
1449        data_input["index5"] = [10, 20, 40, 50]
1450        frame = GridFrame(data_outputs=data, data_inputs=data_input)
1451        frame.Show(True)
1452    except:
1453        print sys.exc_value
1454       
1455    app.MainLoop()
Note: See TracBrowser for help on using the repository browser.