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

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 a582d28 was d03a356, checked in by Gervaise Alina <gervyh@…>, 13 years ago

working on data processor

  • Property mode set to 100644
File size: 33.9 KB
Line 
1"""
2Implement grid used to store data
3"""
4import wx
5import numpy
6import math
7import re
8import os
9import sys
10import copy
11from wx.lib.scrolledpanel import ScrolledPanel
12import  wx.grid as  Grid
13import wx.aui
14from wx.aui import AuiNotebook as nb
15from sans.guiframe.panel_base import PanelBase
16import wx.lib.sheet as sheet
17
18from sans.guiframe.events import NewPlotEvent
19from sans.guiframe.events import StatusEvent 
20from sans.guiframe.dataFitting import Data1D
21
22FUNC_DICT = {"sqrt": "math.sqrt",
23             "pow": "math.sqrt"}
24
25
26def parse_string(sentence, list):
27    """
28    Return a dictionary of column label and index or row selected
29    :param sentence: String to parse
30    :param list: list of columns label
31    """
32    toks = []
33    p2 = re.compile(r'\d+')
34    p = re.compile(r'[\+\-\*\%\/]')
35    labels = p.split(sentence)
36    col_dict = {}
37    for elt in labels:
38        rang = None
39        temp_arr = []
40        for label in  list:
41            label_pos =  elt.find(label)
42            if label_pos != -1:
43                if elt.count(',') > 0:
44                    new_temp = []
45                    temp = elt.split(label)
46                    for item in temp:
47                        range_pos = item.find(":")
48                        if range_pos != -1:
49                            rang = p2.findall(item)
50                            for i in xrange(int(rang[0]), int(rang[1])+1 ):
51                                new_temp.append(i)
52                    temp_arr += new_temp
53                else:
54                    temp = elt.split(label)
55                    for item in temp:
56                        range_pos = item.find(":")
57                        if range_pos != -1:
58                            rang = p2.findall(item)
59                            for i in xrange(int(rang[0]), int(rang[1])+1 ):
60                                temp_arr.append(i)
61                col_dict[elt] = (label, temp_arr)
62    return col_dict
63
64class GridPage(sheet.CSheet):
65    """
66    """
67    def __init__(self, parent, panel=None):
68        """
69        """
70        sheet.CSheet.__init__(self, parent)
71        self.SetLabelBackgroundColour('#DBD4D4')
72        self.AutoSize()
73        self.panel = panel
74        self.col_names = []
75        self.data_inputs = {}
76        self.data_outputs = {}
77        self.data = None
78        self._cols = 50
79        self._rows = 51
80        col_with = 30
81        row_height = 20
82        self.max_row_touse = 0
83        self.axis_value = []
84        self.axis_label = ""
85        self.selected_cells = []
86        self.selected_cols = []
87        self.SetColMinimalAcceptableWidth(col_with)
88        self.SetRowMinimalAcceptableHeight(row_height)
89        self.SetNumberRows(self._cols)
90        self.SetNumberCols(self._rows)
91        self.Bind(wx.grid.EVT_GRID_LABEL_LEFT_CLICK, self.on_left_click)
92        self.Bind(wx.grid.EVT_GRID_LABEL_RIGHT_CLICK, self.on_right_click)
93        self.Bind(wx.grid.EVT_GRID_CELL_LEFT_CLICK, self.on_selected_cell)
94        self.Bind(wx.grid.EVT_GRID_CMD_CELL_CHANGE, self.on_edit_cell)
95       
96    def on_edit_cell(self, event):
97        """
98        """
99        row, col = event.GetRow(), event.GetCol()
100        if row > self.max_row_touse:
101            self.max_row_touse = row
102        event.Skip()
103       
104    def on_selected_cell(self, event):
105        """
106        Handler catching cell selection
107        """
108        flag = event.CmdDown() or event.ControlDown()
109        row, col = event.GetRow(), event.GetCol()
110        cell = (row, col)
111        if not flag:
112            self.selected_cells = []
113            self.axis_value = []
114            self.axis_label = ""
115        if cell not in self.selected_cells:
116            if row > 0:
117                self.selected_cells.append(cell)
118        else:
119            if flag:
120                self.selected_cells.remove(cell)
121        self.axis_value = []
122        for cell_row, cell_col in self.selected_cells:
123            if cell_row > 0 and cell_row < self.max_row_touse:
124                self.axis_value.append(self.GetCellValue(cell_row, cell_col))
125        self.axis_label = self.GetCellValue(0, col)
126        event.Skip()
127     
128    def on_left_click(self, event):
129        """
130        Catch the left click on label mouse event
131        """
132        flag = event.CmdDown() or event.ControlDown()
133        col = event.GetCol()
134        if not flag:
135            self.selected_cols = []
136            self.selected_cells = []
137            self.axis_label = ""
138        for row in range(1, self.GetNumberRows()+ 1):
139            cell = (row, col)
140            if row > 0 and row < self.max_row_touse:
141                if cell not in self.selected_cells:
142                    self.selected_cells.append(cell)
143        self.selected_cols.append(col)
144        self.axis_value = []
145        for cell_row, cell_col in self.selected_cells:
146            self.axis_value.append(self.GetCellValue(cell_row, cell_col))
147        self.axis_label = self.GetCellValue(0, col)
148        event.Skip()
149       
150       
151    def on_right_click(self, event):
152        """
153        Catch the right click mouse
154        """
155       
156        col = event.GetCol()
157        self.selected_cols = []
158        self.selected_cols.append(col)
159        # Slicer plot popup menu
160        slicerpop = wx.Menu()
161        col_label_menu  = wx.Menu()
162        slicerpop.AppendSubMenu(col_label_menu , 
163                                 '&Insert Column', 'Insert Column')
164        hint = 'Insert empty column before the selected column'
165        id = wx.NewId()
166        col_label_menu.Append(id, '&Empty', hint)
167        wx.EVT_MENU(self, id, self.on_insert_column)
168        col_name = [self.GetCellValue(0, col) 
169                        for col in range(self.GetNumberCols())]
170        for label in self.data.keys():
171            if label not in col_name:
172                id = wx.NewId()
173                hint = 'Insert %s column before the selected column' % str(label)
174                col_label_menu.Append(id, '&%s' % str(label), hint)
175                wx.EVT_MENU(self, id, self.on_insert_column)
176        id = wx.NewId()   
177        hint = 'Remove selected column %s'
178        slicerpop.Append(id, 
179                                 '&Remove Column', hint)
180        wx.EVT_MENU(self, id, self.on_remove_column)
181       
182        pos = wx.GetMousePosition()
183        pos = self.ScreenToClient(pos)
184        self.PopupMenu(slicerpop, pos)
185       
186    def on_remove_column(self, event):
187        """
188        """
189        if self.selected_cols is not None or len(self.selected_cols) > 0:
190            col = self.selected_cols[0]
191            # add data to the grid   
192            row = 0
193            id = event.GetId()
194            col_name = self.GetCellValue(row, col)
195            self.data[col_name] = []
196            for row in range(1, self.GetNumberRows() + 1):
197                if row < self.max_row_touse:
198                    value = self.GetCellValue(row, col)
199                    self.data[col_name].append(value)
200                    for k , value_list in self.data.iteritems():
201                        if k != col_name:
202                            length = len(value_list)
203                            if length < self.max_row_touse:
204                                diff = self.max_row_touse - length
205                                for i in range(diff):
206                                    self.data[k].append("")
207            self.DeleteCols(pos=col, numCols=1, updateLabels=True)
208            self.AutoSize()
209           
210    def on_insert_column(self, event):
211        """
212        """
213        if self.selected_cols is not None or len(self.selected_cols) > 0:
214            col = self.selected_cols[0]
215            # add data to the grid   
216            row = 0
217            id = event.GetId()
218            col_name = event.GetEventObject().GetLabelText(id)
219            self.InsertCols(pos=col, numCols=1, updateLabels=True)
220            if col_name.strip() != "Empty":
221                self.SetCellValue(row, col, str(col_name.strip()))
222            if col_name in self.data.keys():
223                value_list = self.data[col_name]
224                cell_row =  1
225                for value in value_list:
226                    self.SetCellValue(cell_row, col, str(value))
227                    cell_row += 1
228            self.AutoSize()
229               
230       
231    def on_set_x_axis(self, event):
232        """
233        """
234        self.panel.set_xaxis(x=self.axis_value, label=self.axis_label)
235   
236    def on_set_y_axis(self, event):
237        """
238        """
239        self.panel.set_yaxis(y=self.axis_value, label=self.axis_label)     
240           
241    def set_data(self, data_inputs, data_outputs):
242        """
243        Add data to the grid
244        :param data_inputs: data to use from the context menu of the grid
245        :param data_ouputs: default columns deplayed
246        """
247        if data_outputs is None:
248            data_outputs = {}
249        self.data_outputs = data_outputs
250        if self.data_inputs is None:
251            data_inputs = {}
252        self.data_inputs = data_inputs
253        self.data = {}
254        for item in (self.data_outputs, self.data_inputs):
255            self.data.update(item)
256        if  len(self.data_outputs) > 0:
257            self._cols = self.GetNumberCols()
258            self._rows = self.GetNumberRows()
259            self.col_names = self.data_outputs.keys()
260            self.col_names.sort() 
261            nbr_user_cols = len(self.col_names)
262            #Add more columns to the grid if necessary
263            if nbr_user_cols > self._cols:
264                new_col_nbr = nbr_user_cols -  self._cols
265                self.AppendCols(new_col_nbr, True)
266            #Add more rows to the grid if necessary 
267            nbr_user_row = len(self.data_outputs.values())
268            if nbr_user_row > self._rows + 1:
269                new_row_nbr =  nbr_user_row - self._rows
270                self.AppendRows(new_row_nbr, True)
271            # add data to the grid   
272            row = 0
273            col = 0
274            cell_col = 0
275            for col_name in  self.col_names:
276                # use the first row of the grid to add user defined labels
277                self.SetCellValue(row, col, str(col_name))
278                col += 1
279                cell_row =  1
280                value_list = self.data_outputs[col_name]
281               
282                for value in value_list:
283                    self.SetCellValue(cell_row, cell_col, str(value))
284                    cell_row += 1
285                cell_col += 1
286                if cell_row > self.max_row_touse:
287                    self.max_row_touse = cell_row
288            self.AutoSize()
289           
290
291class Notebook(nb, PanelBase):
292    """
293    ## Internal name for the AUI manager
294    window_name = "Fit panel"
295    ## Title to appear on top of the window
296    """
297    window_caption = "Notebook "
298   
299    def __init__(self, parent, manager=None, data=None, *args, **kwargs):
300        """
301        """
302        nb.__init__(self, parent, -1,
303                    style= wx.aui.AUI_BUTTON_DOWN|
304                    wx.aui.AUI_NB_WINDOWLIST_BUTTON|
305                    wx.aui.AUI_NB_DEFAULT_STYLE|
306                    wx.CLIP_CHILDREN)
307        PanelBase.__init__(self, parent)
308        self.enable_close_button()
309        self.parent = parent
310        self.manager = manager
311        self.data = data
312        #add empty page
313        self.add_empty_page()
314       
315        self.Bind(wx.aui.EVT_AUINOTEBOOK_PAGE_CLOSE, self.on_close_page)
316   
317    def add_empty_page(self):
318        """
319        """
320        grid = GridPage(self, panel=self.parent)
321        self.AddPage(grid, "", True)
322        pos = self.GetPageIndex(grid)
323        title = "Batch " + str(self.GetPageCount())
324        self.SetPageText(pos, title)
325        self.SetSelection(pos)
326        return grid
327       
328    def enable_close_button(self):
329        """
330        display the close button on tab for more than 1 tabs else remove the
331        close button
332        """
333        if self.GetPageCount() <= 1:
334            style = self.GetWindowStyleFlag() 
335            flag = wx.aui.AUI_NB_CLOSE_ON_ACTIVE_TAB
336            if style & wx.aui.AUI_NB_CLOSE_ON_ACTIVE_TAB == flag:
337                style = style & ~wx.aui.AUI_NB_CLOSE_ON_ACTIVE_TAB
338                self.SetWindowStyle(style)
339        else:
340            style = self.GetWindowStyleFlag()
341            flag = wx.aui.AUI_NB_CLOSE_ON_ACTIVE_TAB
342            if style & wx.aui.AUI_NB_CLOSE_ON_ACTIVE_TAB != flag:
343                style |= wx.aui.AUI_NB_CLOSE_ON_ACTIVE_TAB
344                self.SetWindowStyle(style)
345             
346    def on_edit_axis(self):
347        """
348        Return the select cell of a given selected column
349        """
350        pos = self.GetSelection()
351        grid = self.GetPage(pos)
352        if len(grid.selected_cols) > 1:
353            msg = "Edit axis doesn't understand this selection.\n"
354            msg += "Please select only one column"
355            raise ValueError, msg
356        if len(grid.selected_cols) == 1:
357            col = grid.selected_cols[0]
358            if len(grid.selected_cells) > 0:
359                cell_row, cell_col = grid.selected_cells[0]
360                if cell_col  != col:
361                    msg = "Edit axis doesn't understand this selection.\n"
362                    msg += "Please select element of the same col"
363                    raise ValueError, msg
364        return grid.selected_cells
365       
366   
367    def get_column_labels(self):
368        """
369        return dictionary of columns labels of the current page
370        """
371        pos = self.GetSelection()
372        grid = self.GetPage(pos)
373        labels = {}
374        row = 0
375        for col in range(grid.GetNumberCols()):
376            label = grid.GetCellValue(row, col)
377            if label.strip() != "" :
378                labels[label.strip()] = col
379        return labels
380       
381    def create_axis_label(self, cell_list):
382        """
383        Receive a list of cells and  create a string presenting the selected
384        cells.
385        :param cell_list: list of tuple
386       
387        """
388        pos = self.GetSelection()
389        grid = self.GetPage(pos)
390        label = ""
391        col_name = ""
392        def create_label(col_name,  row_min=None, row_max=None):
393            """
394            """
395            result = ""
396            if row_min is not  None or row_max is not None:
397                if row_min is None:
398                    result = str(row_max) + "]"
399                elif row_max is None:
400                     result = str(col_name) + "[" + str(row_min) + ":"
401                else:
402                    result = str(col_name) +  "[" + str(row_min) + ":"
403                    result += str(col_name) + str(row_max) + "]"
404            return result
405           
406        if len(cell_list) > 0:
407            if len(cell_list) == 1:
408                 row_min, col  = cell_list[0]   
409                 col_name = grid.GetCellValue(0, col)
410                 label = create_label(col_name, row_min+1 , row_min+1)
411                 return  label,  col_name
412            else:
413                temp_list = copy.deepcopy(cell_list)
414                temp_list.sort()
415                length = len(temp_list)
416                row_min, col  = temp_list[0]   
417                row_max, _  = temp_list[length-1]
418                col_name = grid.GetCellValue(0, col)
419                index = 0
420                for row in xrange(row_min, row_max +1):
421                    if index > 0 and index < len(temp_list):
422                        new_row, _ = temp_list[index]
423                        if row != new_row:
424                            temp_list.insert(index, (None, None))
425                            if index -1 >=0:
426                                new_row, _ = temp_list[index-1]
427                                label += create_label(col_name, None, new_row +1)
428                                label += ","
429                            if index + 1 < len(temp_list):
430                                new_row, _ = temp_list[index + 1]
431                                label += create_label(col_name, new_row+1, None)
432                    if index == 0:
433                        label += create_label(col_name,  row_min+1, None)
434                    elif index == len(temp_list)-1:
435                        label += create_label(col_name, None, row_max+1)
436                    index += 1
437                return label, col_name
438   
439    def on_close_page(self, event):
440        """
441        close the page
442        """
443        if self.GetPageCount() == 1:
444            event.Veto()
445        self.enable_close_button()
446       
447    def set_data(self, data_inputs, data_outputs):
448        if data_outputs is None or data_outputs == {}:
449            return
450        grid = self.add_empty_page()
451        #grid = GridPage(self, panel=self.parent)
452        grid.set_data(data_inputs, data_outputs) 
453        #self.AddPage(grid, "", True)
454        #pos = self.GetPageIndex(grid)
455        #title = "Batch " + str(self.GetPageCount())
456        #self.SetPageText(pos, title)
457        #self.SetSelection(pos)
458       
459    def add_column(self):
460        """
461        Append a new column to the grid
462        """
463        pos = self.GetSelection()
464        grid = self.GetPage(pos)
465        grid.AppendCols(1, True)
466       
467    def on_remove_column(self):
468        """
469        Remove column to the current grid
470        """
471        pos = self.GetSelection()
472        grid = self.GetPage(pos)
473        cols_pos = grid.GetSelectedCols() 
474        for cpos in cols_pos:
475            grid.DeleteCols(cpos)
476         
477         
478class SPanel(ScrolledPanel):
479    def __init__(self, parent, *args, **kwds):
480        ScrolledPanel.__init__(self, parent , *args, **kwds)
481        self.SetupScrolling() 
482
483
484class GridPanel(SPanel):
485    def __init__(self, parent, data_inputs=None,
486                 data_outputs=None, *args, **kwds):
487        SPanel.__init__(self, parent , *args, **kwds)
488        self.vbox = wx.BoxSizer(wx.VERTICAL)
489       
490        self.plotting_sizer = wx.FlexGridSizer(3, 7, 10, 5)
491        self.grid_sizer = wx.BoxSizer(wx.HORIZONTAL)
492        self.vbox.AddMany([(self.grid_sizer, 1, wx.EXPAND, 0),
493                           (wx.StaticLine(self, -1), 0, wx.EXPAND, 0),
494                           (self.plotting_sizer)])
495        self.parent = parent
496        self._data_inputs = data_inputs
497        self._data_outputs = data_outputs
498        self.x = []
499        self.= []
500        self.x_axis_label = None
501        self.y_axis_label = None
502        self.x_axis_title = None
503        self.y_axis_title = None
504        self.x_axis_unit = None
505        self.y_axis_unit = None
506        self.plot_button = None
507        self.notebook = None
508        self.layout_grid()
509        self.layout_plotting_area()
510        self.SetSizer(self.vbox)
511       
512    def set_data(self, data_inputs, data_outputs):
513        """
514        """
515        if self.notebook is not None:
516            self.notebook.set_data(data_inputs, data_outputs)
517       
518    def set_xaxis(self, label="", x=None):
519        """
520        """
521        if x is None:
522            x = []
523        self.x = x
524        self.x_axis_label.SetValue("%s[:]" % str(label))
525        self.x_axis_title.SetValue(str(label))
526       
527    def set_yaxis(self, label="", y=None):
528        """
529        """
530        if y is None:
531            y = []
532        self.y = y
533        self.y_axis_label.SetValue("%s[:]" % str(label))
534        self.y_axis_title.SetValue(str(label))
535       
536    def get_plot_axis(self, col, list):
537        """
538       
539        """
540        axis = []
541        pos = self.notebook.GetSelection()
542        grid = self.notebook.GetPage(pos)
543        for row in list:
544            label = grid.GetCellValue(0, col)
545            value = grid.GetCellValue(row - 1, col).strip()
546            if value != "":
547                if label.lower().strip() == "data":
548                    axis.append(float(row - 1))
549                else:
550                    try:
551                        axis.append(float(value))
552                    except:
553                        msg = "Invalid data in row %s column %s" % (str(row),
554                                                                    str(col))
555                        wx.PostEvent(self.parent.parent, 
556                             SatusEvent(status=msg, info="error")) 
557            else:
558                axis.append(None) 
559        return axis
560   
561    def on_save_column(self, parent):
562        """
563        """
564        pos = self.notebook.GetSelection()
565        grid = self.notebook.GetPage(pos)
566        if parent is not None and  self.data is not None:
567            parent.write_batch_tofile(data=grid.data, 
568                                               file_name=path,
569                                               details=self.details)
570       
571    def on_plot(self, event):
572        """
573        Evaluate the contains of textcrtl and plot result
574        """ 
575        pos = self.notebook.GetSelection()
576        grid = self.notebook.GetPage(pos)
577        column_names = {}
578        if grid is not None:
579            column_names = self.notebook.get_column_labels()
580        #evalue x
581        sentence = self.x_axis_label.GetValue()
582        if sentence.strip() == "":
583            msg = "select value for x axis"
584            raise ValueError, msg
585        dict = parse_string(sentence, column_names.keys())
586        for tok, (col_name, list) in dict.iteritems():
587            col = column_names[col_name]
588            xaxis = self.get_plot_axis(col, list)
589            sentence = sentence.replace(tok, 
590                                        "numpy.array(%s)" % str(xaxis))
591        for key, value in FUNC_DICT.iteritems():
592            sentence = sentence.replace(key.lower(), value)
593        x = eval(sentence)
594        #evaluate y
595        sentence = self.y_axis_label.GetValue()
596        if sentence.strip() == "":
597            msg = "select value for y axis"
598            raise ValueError, msg
599        dict = parse_string(sentence, column_names.keys())
600        for tok, (col_name, list) in dict.iteritems():
601            col = column_names[col_name]
602            yaxis = self.get_plot_axis(col, list)
603            sentence = sentence.replace(tok, 
604                                        "numpy.array(%s)" % str(yaxis))
605        for key, value in FUNC_DICT.iteritems():
606            sentence = sentence.replace(key, value)
607        y = eval(sentence)
608        #plotting
609        new_plot = Data1D(x=x, y=y)
610        new_plot.id =  wx.NewId()
611        new_plot.group_id = wx.NewId()
612        title = "%s vs %s" % (self.y_axis_title.GetValue(), 
613                              self.x_axis_title.GetValue())
614        new_plot.xaxis(self.x_axis_title.GetValue(), self.x_axis_unit.GetValue())
615        new_plot.yaxis(self.y_axis_title.GetValue(), self.y_axis_unit.GetValue())
616        try:
617            title = self.notebook.GetPageText(pos)
618            new_plot.name = title
619            wx.PostEvent(self.parent.parent, 
620                             NewPlotEvent(plot=new_plot, 
621                        group_id=str(new_plot.group_id), title =title))   
622        except:
623             wx.PostEvent(self.parent.parent, 
624                             SatusEvent(status=msg, info="error")) 
625       
626    def layout_grid(self):
627        """
628        Draw the area related to the grid
629        """
630        self.notebook = Notebook(parent=self)
631        self.notebook.set_data(self._data_inputs, self._data_outputs)
632        self.grid_sizer.Add(self.notebook, 1, wx.EXPAND, 0)
633       
634    def layout_plotting_area(self):
635        """
636        Draw area containing options to plot
637        """
638        self.x_axis_title = wx.TextCtrl(self, -1)
639        self.y_axis_title = wx.TextCtrl(self, -1)
640        self.x_axis_label = wx.TextCtrl(self, -1, size=(200, -1))
641        self.y_axis_label = wx.TextCtrl(self, -1, size=(200, -1))
642        self.x_axis_add = wx.Button(self, -1, "Add")
643        self.x_axis_add.Bind(event=wx.EVT_BUTTON, handler=self.on_edit_axis, 
644                            id=self.x_axis_add.GetId())
645        self.y_axis_add = wx.Button(self, -1, "Add")
646        self.y_axis_add.Bind(event=wx.EVT_BUTTON, handler=self.on_edit_axis, 
647                            id=self.y_axis_add.GetId())
648        self.x_axis_unit = wx.TextCtrl(self, -1)
649        self.y_axis_unit = wx.TextCtrl(self, -1)
650        self.plot_button = wx.Button(self, -1, "Plot")
651        wx.EVT_BUTTON(self, self.plot_button.GetId(), self.on_plot)
652        self.plotting_sizer.AddMany([
653                    (wx.StaticText(self, -1, "x-axis label"), 1,
654                      wx.TOP|wx.BOTTOM|wx.LEFT, 10),
655                    (self.x_axis_label, 1, wx.TOP|wx.BOTTOM, 10),
656                    (self.x_axis_add, 1, wx.TOP|wx.BOTTOM|wx.RIGHT, 10),
657                    (wx.StaticText(self, -1, "x-axis title"), 1, 
658                     wx.TOP|wx.BOTTOM|wx.LEFT, 10),
659                    (self.x_axis_title, 1, wx.TOP|wx.BOTTOM, 10),
660                    (wx.StaticText(self, -1 , "unit"), 1, 
661                     wx.TOP|wx.BOTTOM, 10),
662                    (self.x_axis_unit, 1, wx.TOP|wx.BOTTOM, 10),
663                    (wx.StaticText(self, -1, "y-axis label"), 1, 
664                     wx.BOTTOM|wx.LEFT, 10),
665                    (self.y_axis_label, wx.BOTTOM, 10),
666                    (self.y_axis_add, 1, wx.BOTTOM|wx.RIGHT, 10),
667                    (wx.StaticText(self, -1, "y-axis title"), 1, 
668                     wx.BOTTOM|wx.LEFT, 10),
669                    (self.y_axis_title,  wx.BOTTOM, 10),
670                    (wx.StaticText(self, -1 , "unit"), 1, wx.BOTTOM, 10),
671                    (self.y_axis_unit, 1, wx.BOTTOM, 10),
672                      (-1, -1),
673                      (-1, -1),
674                      (-1, -1),
675                      (-1, -1),
676                      (-1, -1),
677                      (-1, -1),
678                      (self.plot_button, 1, wx.LEFT|wx.BOTTOM, 10)])
679   
680    def on_edit_axis(self, event):
681        """
682        Get the selected column on  the visible grid and set values for axis
683        """
684        cell_list = self.notebook.on_edit_axis()
685        label, title = self.create_axis_label(cell_list)
686        tcrtl = event.GetEventObject()
687        if tcrtl == self.x_axis_add:
688            self.edit_axis_helper(self.x_axis_label, self.x_axis_title,
689                                   label, title)
690        elif tcrtl == self.y_axis_add:
691            self.edit_axis_helper(self.y_axis_label, self.y_axis_title,
692                                   label, title)
693           
694    def create_axis_label(self, cell_list):
695        """
696        Receive a list of cells and  create a string presenting the selected
697        cells.
698        :param cell_list: list of tuple
699       
700        """
701        if self.notebook is not None:
702            return self.notebook.create_axis_label(cell_list)
703   
704    def edit_axis_helper(self, tcrtl_label, tcrtl_title, label, title):
705        """
706        get controls to modify
707        """
708        tcrtl_label.SetValue(str(label))
709        tcrtl_title.SetValue(str(title))
710       
711    def add_column(self):
712        """
713        """
714        if self.notebook is not None:
715            self.notebook.add_column()
716       
717    def on_remove_column(self):
718        """
719        """
720        if self.notebook is not None:
721            self.notebook.on_remove_column()
722       
723       
724class GridFrame(wx.Frame):
725    def __init__(self, parent=None, data_inputs=None, data_outputs=None, id=-1, 
726                 title="Batch Results", size=(700, 400)):
727        wx.Frame.__init__(self, parent=parent, id=id, title=title, size=size)
728        self.parent = parent
729        self.panel = GridPanel(self, data_inputs, data_outputs)
730        menubar = wx.MenuBar()
731        self.SetMenuBar(menubar)
732        """
733        edit = wx.Menu()
734        menubar.Append(edit, "&File")
735        save_menu = edit.Append(wx.NewId(), 'Save As', 'Save into File')
736        wx.EVT_MENU(self, save_menu.GetId(), self.on_save_column)
737        """
738        self.Bind(wx.EVT_CLOSE, self.on_close)
739       
740    def on_save_column(self, event):
741        """
742        """
743        self.panel.on_save_column(self.parent)
744
745    def on_close(self, event):
746        """
747        """
748        self.Hide()
749       
750    def on_remove_column(self, event):
751        """
752        Remove the selected column to the grid
753        """
754        self.panel.on_remove_column()
755       
756    def on_insert_column(self, event):
757        """
758        Insert a new column to the grid
759        """
760        self.panel.insert_column()
761       
762    def on_append_column(self, event):
763        """
764        Append a new column to the grid
765        """
766        self.panel.add_column()
767       
768    def set_data(self, data_inputs, data_outputs):
769        """
770        """
771        self.panel.set_data(data_inputs, data_outputs)
772     
773     
774class BatchOutputFrame(wx.Frame):
775    """
776    Allow to select where the result of batch will be displayed or stored
777    """
778    def __init__(self, parent, data_inputs, data_outputs, file_name="",
779                 details="", *args, **kwds):
780        """
781        :param parent: Window instantiating this dialog
782        :param result: result to display in a grid or export to an external
783                application.
784        """
785        #kwds['style'] = wx.CAPTION|wx.SYSTEM_MENU
786        wx.Frame.__init__(self, parent, *args, **kwds)
787        self.parent = parent
788        self.panel = wx.Panel(self)
789        self.file_name = file_name
790        self.details = details
791        self.data_inputs = data_inputs
792        self.data_outputs = data_outputs
793        self.data = {}
794        for item in (self.data_outputs, self.data_inputs):
795            self.data.update(item)
796        self.flag = 1
797        self.SetSize((300, 200))
798        self.local_app_selected = None
799        self.external_app_selected = None
800        self.save_to_file = None
801        self._do_layout()
802   
803    def _do_layout(self):
804        """
805        Draw the content of the current dialog window
806        """
807        vbox = wx.BoxSizer(wx.VERTICAL)
808        box_description = wx.StaticBox(self.panel, -1, str("Batch Outputs"))
809        hint_sizer = wx.StaticBoxSizer(box_description, wx.VERTICAL)
810        selection_sizer = wx.GridBagSizer(5, 5)
811        button_sizer = wx.BoxSizer(wx.HORIZONTAL)
812        text = "Open with %s" % self.parent.application_name
813        self.local_app_selected = wx.RadioButton(self.panel, -1, text,
814                                                style=wx.RB_GROUP)
815        self.Bind(wx.EVT_RADIOBUTTON, self.onselect,
816                    id=self.local_app_selected.GetId())
817        text = "Open with Excel"
818        self.external_app_selected  = wx.RadioButton(self.panel, -1, text)
819        self.Bind(wx.EVT_RADIOBUTTON, self.onselect,
820                    id=self.external_app_selected.GetId())
821        text = "Save to File"
822        self.save_to_file = wx.CheckBox(self.panel, -1, text)
823        self.Bind(wx.EVT_CHECKBOX, self.onselect,
824                    id=self.save_to_file.GetId())
825        self.local_app_selected.SetValue(True)
826        self.external_app_selected.SetValue(False)
827        self.save_to_file.SetValue(False)
828        button_close = wx.Button(self.panel, -1, "Close")
829        button_close.Bind(wx.EVT_BUTTON, id=button_close.GetId(),
830                           handler=self.on_close)
831        button_apply = wx.Button(self.panel, -1, "Apply")
832        button_apply.Bind(wx.EVT_BUTTON, id=button_apply.GetId(),
833                        handler=self.on_apply)
834        button_apply.SetFocus()
835        hint = ""
836        hint_sizer.Add(wx.StaticText(self.panel, -1, hint))
837        hint_sizer.Add(selection_sizer)
838        #draw area containing radio buttons
839        ix = 0
840        iy = 0
841        selection_sizer.Add(self.local_app_selected, (iy, ix),
842                           (1, 1), wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
843        iy += 1
844        selection_sizer.Add(self.external_app_selected, (iy, ix),
845                           (1, 1), wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
846        iy += 1
847        selection_sizer.Add(self.save_to_file, (iy, ix),
848                           (1, 1), wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
849        #contruction the sizer contaning button
850        button_sizer.Add((20, 20), 1, wx.EXPAND|wx.ADJUST_MINSIZE, 0)
851
852        button_sizer.Add(button_close, 0,
853                        wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
854        button_sizer.Add(button_apply, 0,
855                                wx.LEFT|wx.RIGHT|wx.ADJUST_MINSIZE, 10)
856        vbox.Add(hint_sizer,  0, wx.EXPAND|wx.ALL, 10)
857        vbox.Add(wx.StaticLine(self.panel, -1),  0, wx.EXPAND, 0)
858        vbox.Add(button_sizer, 0 , wx.TOP|wx.BOTTOM, 10)
859        self.SetSizer(vbox)
860       
861    def on_apply(self, event):
862        """
863        Get the user selection and display output to the selected application
864        """
865        if self.flag == 1:
866            self.parent.open_with_localapp(data_inputs=self.data_inputs,
867                                            data_outputs=self.data_outputs)
868        elif self.flag == 2:
869            self.parent.open_with_externalapp(data=self.data, 
870                                           file_name=self.file_name,
871                                           details=self.details)
872    def on_close(self, event):
873        """
874        close the Window
875        """
876        self.Close()
877       
878    def onselect(self, event=None):
879        """
880        Receive event and display data into third party application
881        or save data to file.
882       
883        """
884        if self.save_to_file.GetValue():
885            reader, ext = os.path.splitext(self.file_name)
886            path = None
887            location = os.getcwd()
888            if self.parent is not None: 
889                location = os.path.dirname(self.file_name)
890                dlg = wx.FileDialog(self, "Save Project file",
891                            location, self.file_name, ext, wx.SAVE)
892                path = None
893                if dlg.ShowModal() == wx.ID_OK:
894                    path = dlg.GetPath()
895                dlg.Destroy()
896                if path != None:
897                    if self.parent is not None and  self.data is not None:
898                        self.parent.write_batch_tofile(data=self.data, 
899                                               file_name=path,
900                                               details=self.details)
901        if self.local_app_selected.GetValue():
902            self.flag = 1
903        else:
904            self.flag = 2
905        return self.flag
906   
907 
908       
909if __name__ == "__main__":
910    app = wx.App()
911   
912    try:
913        data = {}
914        j = 0
915        for i in range(4):
916            j += 1
917            data["index"+str(i)] = [i/j, i*j, i, i+j]
918       
919        data_input =  copy.deepcopy(data)   
920        data_input["index5"] = [10,20,40, 50]
921        frame = GridFrame(data_outputs=data, data_inputs=data_input)
922        frame.Show(True)
923    except:
924        print sys.exc_value
925       
926    app.MainLoop()
Note: See TracBrowser for help on using the repository browser.