source: sasview/sansguiframe/src/sans/guiframe/data_processor.py @ 23155ba

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

PROTECTION FOR PLOT W/ TOO MANY DATA SET

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