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

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

working on dataprocessor

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