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

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

working on grid

  • Property mode set to 100644
File size: 33.5 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 = {}
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        self.Bind(wx.aui.EVT_AUINOTEBOOK_PAGE_CLOSE, self.on_close_page)
313   
314    def enable_close_button(self):
315        """
316        display the close button on tab for more than 1 tabs else remove the
317        close button
318        """
319        if self.GetPageCount() <= 1:
320            style = self.GetWindowStyleFlag() 
321            flag = wx.aui.AUI_NB_CLOSE_ON_ACTIVE_TAB
322            if style & wx.aui.AUI_NB_CLOSE_ON_ACTIVE_TAB == flag:
323                style = style & ~wx.aui.AUI_NB_CLOSE_ON_ACTIVE_TAB
324                self.SetWindowStyle(style)
325        else:
326            style = self.GetWindowStyleFlag()
327            flag = wx.aui.AUI_NB_CLOSE_ON_ACTIVE_TAB
328            if style & wx.aui.AUI_NB_CLOSE_ON_ACTIVE_TAB != flag:
329                style |= wx.aui.AUI_NB_CLOSE_ON_ACTIVE_TAB
330                self.SetWindowStyle(style)
331             
332    def on_edit_axis(self):
333        """
334        Return the select cell of a given selected column
335        """
336        pos = self.GetSelection()
337        grid = self.GetPage(pos)
338        if len(grid.selected_cols) > 1:
339            msg = "Edit axis doesn't understand this selection.\n"
340            msg += "Please select only one column"
341            raise ValueError, msg
342        if len(grid.selected_cols) == 1:
343            col = grid.selected_cols[0]
344            if len(grid.selected_cells) > 0:
345                cell_row, cell_col = grid.selected_cells[0]
346                if cell_col  != col:
347                    msg = "Edit axis doesn't understand this selection.\n"
348                    msg += "Please select element of the same col"
349                    raise ValueError, msg
350        return grid.selected_cells
351       
352   
353    def get_column_labels(self):
354        """
355        return dictionary of columns labels of the current page
356        """
357        pos = self.GetSelection()
358        grid = self.GetPage(pos)
359        labels = {}
360        row = 0
361        for col in range(grid.GetNumberCols()):
362            label = grid.GetCellValue(row, col)
363            if label.strip() != "" :
364                labels[label.strip()] = col
365        return labels
366       
367    def create_axis_label(self, cell_list):
368        """
369        Receive a list of cells and  create a string presenting the selected
370        cells.
371        :param cell_list: list of tuple
372       
373        """
374        pos = self.GetSelection()
375        grid = self.GetPage(pos)
376        label = ""
377        col_name = ""
378        def create_label(col_name,  row_min=None, row_max=None):
379            """
380            """
381            result = ""
382            if row_min is not  None or row_max is not None:
383                if row_min is None:
384                    result = str(row_max) + "]"
385                elif row_max is None:
386                     result = str(col_name) + "[" + str(row_min) + ":"
387                else:
388                    result = str(col_name) +  "[" + str(row_min) + ":"
389                    result += str(col_name) + str(row_max) + "]"
390            return result
391           
392        if len(cell_list) > 0:
393            if len(cell_list) == 1:
394                 row_min, col  = cell_list[0]   
395                 col_name = grid.GetCellValue(0, col)
396                 label = create_label(col_name, row_min+1 , row_min+1)
397                 return  label,  col_name
398            else:
399                temp_list = copy.deepcopy(cell_list)
400                temp_list.sort()
401                length = len(temp_list)
402                row_min, col  = temp_list[0]   
403                row_max, _  = temp_list[length-1]
404                col_name = grid.GetCellValue(0, col)
405                index = 0
406                for row in xrange(row_min, row_max +1):
407                    if index > 0 and index < len(temp_list):
408                        new_row, _ = temp_list[index]
409                        if row != new_row:
410                            temp_list.insert(index, (None, None))
411                            if index -1 >=0:
412                                new_row, _ = temp_list[index-1]
413                                label += create_label(col_name, None, new_row +1)
414                                label += ","
415                            if index + 1 < len(temp_list):
416                                new_row, _ = temp_list[index + 1]
417                                label += create_label(col_name, new_row+1, None)
418                    if index == 0:
419                        label += create_label(col_name,  row_min+1, None)
420                    elif index == len(temp_list)-1:
421                        label += create_label(col_name, None, row_max+1)
422                    index += 1
423                return label, col_name
424   
425    def on_close_page(self, event):
426        """
427        close the page
428        """
429        if self.GetPageCount() == 1:
430            event.Veto()
431        self.enable_close_button()
432       
433    def set_data(self, data_inputs, data_outputs):
434        if data_outputs is None or data_outputs == {}:
435            return
436        grid = GridPage(self, panel=self.parent)
437        grid.set_data(data_inputs, data_outputs) 
438        self.AddPage(grid, "")
439        pos = self.GetPageIndex(grid)
440        title = "Batch " + str(self.GetPageCount())
441        self.SetPageText(pos, title)
442       
443    def add_column(self):
444        """
445        Append a new column to the grid
446        """
447        pos = self.GetSelection()
448        grid = self.GetPage(pos)
449        grid.AppendCols(1, True)
450       
451    def on_remove_column(self):
452        """
453        Remove column to the current grid
454        """
455        pos = self.GetSelection()
456        grid = self.GetPage(pos)
457        cols_pos = grid.GetSelectedCols() 
458        for cpos in cols_pos:
459            grid.DeleteCols(cpos)
460         
461         
462class SPanel(ScrolledPanel):
463    def __init__(self, parent, *args, **kwds):
464        ScrolledPanel.__init__(self, parent , *args, **kwds)
465        self.SetupScrolling() 
466
467
468class GridPanel(SPanel):
469    def __init__(self, parent, data_inputs=None,
470                 data_outputs=None, *args, **kwds):
471        SPanel.__init__(self, parent , *args, **kwds)
472        self.vbox = wx.BoxSizer(wx.VERTICAL)
473       
474        self.plotting_sizer = wx.FlexGridSizer(3, 7, 10, 5)
475        self.grid_sizer = wx.BoxSizer(wx.HORIZONTAL)
476        self.vbox.AddMany([(self.grid_sizer, 1, wx.EXPAND, 0),
477                           (wx.StaticLine(self, -1), 0, wx.EXPAND, 0),
478                           (self.plotting_sizer)])
479        self.parent = parent
480        self._data_inputs = data_inputs
481        self._data_outputs = data_outputs
482        self.x = []
483        self.= []
484        self.x_axis_label = None
485        self.y_axis_label = None
486        self.x_axis_title = None
487        self.y_axis_title = None
488        self.x_axis_unit = None
489        self.y_axis_unit = None
490        self.plot_button = None
491        self.notebook = None
492        self.layout_grid()
493        self.layout_plotting_area()
494        self.SetSizer(self.vbox)
495       
496    def set_data(self, data_inputs, data_outputs):
497        """
498        """
499        if self.notebook is not None:
500            self.notebook.set_data(data_inputs, data_outputs)
501       
502    def set_xaxis(self, label="", x=None):
503        """
504        """
505        if x is None:
506            x = []
507        self.x = x
508        self.x_axis_label.SetValue("%s[:]" % str(label))
509        self.x_axis_title.SetValue(str(label))
510       
511    def set_yaxis(self, label="", y=None):
512        """
513        """
514        if y is None:
515            y = []
516        self.y = y
517        self.y_axis_label.SetValue("%s[:]" % str(label))
518        self.y_axis_title.SetValue(str(label))
519       
520    def get_plot_axis(self, col, list):
521        """
522       
523        """
524        axis = []
525        pos = self.notebook.GetSelection()
526        grid = self.notebook.GetPage(pos)
527        for row in list:
528            label = grid.GetCellValue(0, col)
529            value = grid.GetCellValue(row - 1, col).strip()
530            if value != "":
531                if label.lower().strip() == "data":
532                    axis.append(float(row - 1))
533                else:
534                    try:
535                        axis.append(float(value))
536                    except:
537                        msg = "Invalid data in row %s column %s" % (str(row),
538                                                                    str(col))
539                        wx.PostEvent(self.parent.parent, 
540                             SatusEvent(status=msg, info="error")) 
541            else:
542                axis.append(None) 
543        return axis
544   
545    def on_save_column(self, parent):
546        """
547        """
548        pos = self.notebook.GetSelection()
549        grid = self.notebook.GetPage(pos)
550        if parent is not None and  self.data is not None:
551            parent.write_batch_tofile(data=grid.data, 
552                                               file_name=path,
553                                               details=self.details)
554       
555    def on_plot(self, event):
556        """
557        Evaluate the contains of textcrtl and plot result
558        """ 
559        pos = self.notebook.GetSelection()
560        grid = self.notebook.GetPage(pos)
561        column_names = {}
562        if grid is not None:
563            column_names = self.notebook.get_column_labels()
564        #evalue x
565        sentence = self.x_axis_label.GetValue()
566        if sentence.strip() == "":
567            msg = "select value for x axis"
568            raise ValueError, msg
569        dict = parse_string(sentence, column_names.keys())
570        for tok, (col_name, list) in dict.iteritems():
571            col = column_names[col_name]
572            xaxis = self.get_plot_axis(col, list)
573            sentence = sentence.replace(tok, 
574                                        "numpy.array(%s)" % str(xaxis))
575        for key, value in FUNC_DICT.iteritems():
576            sentence = sentence.replace(key.lower(), value)
577        x = eval(sentence)
578        #evaluate y
579        sentence = self.y_axis_label.GetValue()
580        if sentence.strip() == "":
581            msg = "select value for y axis"
582            raise ValueError, msg
583        dict = parse_string(sentence, column_names.keys())
584        for tok, (col_name, list) in dict.iteritems():
585            col = column_names[col_name]
586            yaxis = self.get_plot_axis(col, list)
587            sentence = sentence.replace(tok, 
588                                        "numpy.array(%s)" % str(yaxis))
589        for key, value in FUNC_DICT.iteritems():
590            sentence = sentence.replace(key, value)
591        y = eval(sentence)
592        #plotting
593        new_plot = Data1D(x=x, y=y)
594        new_plot.id =  wx.NewId()
595        new_plot.group_id = wx.NewId()
596        title = "%s vs %s" % (self.y_axis_title.GetValue(), 
597                              self.x_axis_title.GetValue())
598        new_plot.xaxis(self.x_axis_title.GetValue(), self.x_axis_unit.GetValue())
599        new_plot.yaxis(self.y_axis_title.GetValue(), self.y_axis_unit.GetValue())
600        try:
601            title = self.notebook.GetPageText(pos)
602            new_plot.name = title
603            wx.PostEvent(self.parent.parent, 
604                             NewPlotEvent(plot=new_plot, 
605                        group_id=str(new_plot.group_id), title =title))   
606        except:
607             wx.PostEvent(self.parent.parent, 
608                             SatusEvent(status=msg, info="error")) 
609       
610    def layout_grid(self):
611        """
612        Draw the area related to the grid
613        """
614        self.notebook = Notebook(parent=self)
615        self.notebook.set_data(self._data_inputs, self._data_outputs)
616        self.grid_sizer.Add(self.notebook, 1, wx.EXPAND, 0)
617       
618    def layout_plotting_area(self):
619        """
620        Draw area containing options to plot
621        """
622        self.x_axis_title = wx.TextCtrl(self, -1)
623        self.y_axis_title = wx.TextCtrl(self, -1)
624        self.x_axis_label = wx.TextCtrl(self, -1, size=(200, -1))
625        self.y_axis_label = wx.TextCtrl(self, -1, size=(200, -1))
626        self.x_axis_add = wx.Button(self, -1, "Add")
627        self.x_axis_add.Bind(event=wx.EVT_BUTTON, handler=self.on_edit_axis, 
628                            id=self.x_axis_add.GetId())
629        self.y_axis_add = wx.Button(self, -1, "Add")
630        self.y_axis_add.Bind(event=wx.EVT_BUTTON, handler=self.on_edit_axis, 
631                            id=self.y_axis_add.GetId())
632        self.x_axis_unit = wx.TextCtrl(self, -1)
633        self.y_axis_unit = wx.TextCtrl(self, -1)
634        self.plot_button = wx.Button(self, -1, "Plot")
635        wx.EVT_BUTTON(self, self.plot_button.GetId(), self.on_plot)
636        self.plotting_sizer.AddMany([
637                    (wx.StaticText(self, -1, "x-axis label"), 1,
638                      wx.TOP|wx.BOTTOM|wx.LEFT, 10),
639                    (self.x_axis_label, 1, wx.TOP|wx.BOTTOM, 10),
640                    (self.x_axis_add, 1, wx.TOP|wx.BOTTOM|wx.RIGHT, 10),
641                    (wx.StaticText(self, -1, "x-axis title"), 1, 
642                     wx.TOP|wx.BOTTOM|wx.LEFT, 10),
643                    (self.x_axis_title, 1, wx.TOP|wx.BOTTOM, 10),
644                    (wx.StaticText(self, -1 , "unit"), 1, 
645                     wx.TOP|wx.BOTTOM, 10),
646                    (self.x_axis_unit, 1, wx.TOP|wx.BOTTOM, 10),
647                    (wx.StaticText(self, -1, "y-axis label"), 1, 
648                     wx.BOTTOM|wx.LEFT, 10),
649                    (self.y_axis_label, wx.BOTTOM, 10),
650                    (self.y_axis_add, 1, wx.BOTTOM|wx.RIGHT, 10),
651                    (wx.StaticText(self, -1, "y-axis title"), 1, 
652                     wx.BOTTOM|wx.LEFT, 10),
653                    (self.y_axis_title,  wx.BOTTOM, 10),
654                    (wx.StaticText(self, -1 , "unit"), 1, wx.BOTTOM, 10),
655                    (self.y_axis_unit, 1, wx.BOTTOM, 10),
656                      (-1, -1),
657                      (-1, -1),
658                      (-1, -1),
659                      (-1, -1),
660                      (-1, -1),
661                      (-1, -1),
662                      (self.plot_button, 1, wx.LEFT|wx.BOTTOM, 10)])
663   
664    def on_edit_axis(self, event):
665        """
666        Get the selected column on  the visible grid and set values for axis
667        """
668        cell_list = self.notebook.on_edit_axis()
669        label, title = self.create_axis_label(cell_list)
670        tcrtl = event.GetEventObject()
671        if tcrtl == self.x_axis_add:
672            self.edit_axis_helper(self.x_axis_label, self.x_axis_title,
673                                   label, title)
674        elif tcrtl == self.y_axis_add:
675            self.edit_axis_helper(self.y_axis_label, self.y_axis_title,
676                                   label, title)
677           
678    def create_axis_label(self, cell_list):
679        """
680        Receive a list of cells and  create a string presenting the selected
681        cells.
682        :param cell_list: list of tuple
683       
684        """
685        if self.notebook is not None:
686            return self.notebook.create_axis_label(cell_list)
687   
688    def edit_axis_helper(self, tcrtl_label, tcrtl_title, label, title):
689        """
690        get controls to modify
691        """
692        tcrtl_label.SetValue(str(label))
693        tcrtl_title.SetValue(str(title))
694       
695    def add_column(self):
696        """
697        """
698        if self.notebook is not None:
699            self.notebook.add_column()
700       
701    def on_remove_column(self):
702        """
703        """
704        if self.notebook is not None:
705            self.notebook.on_remove_column()
706       
707       
708class GridFrame(wx.Frame):
709    def __init__(self, parent=None, data_inputs=None, data_outputs=None, id=-1, 
710                 title="Batch Results", size=(700, 400)):
711        wx.Frame.__init__(self, parent=parent, id=id, title=title, size=size)
712        self.parent = parent
713        self.panel = GridPanel(self, data_inputs, data_outputs)
714        menubar = wx.MenuBar()
715        self.SetMenuBar(menubar)
716        """
717        edit = wx.Menu()
718        menubar.Append(edit, "&File")
719        save_menu = edit.Append(wx.NewId(), 'Save As', 'Save into File')
720        wx.EVT_MENU(self, save_menu.GetId(), self.on_save_column)
721        """
722        self.Bind(wx.EVT_CLOSE, self.on_close)
723       
724    def on_save_column(self, event):
725        """
726        """
727        self.panel.on_save_column(self.parent)
728
729    def on_close(self, event):
730        """
731        """
732        self.Hide()
733       
734    def on_remove_column(self, event):
735        """
736        Remove the selected column to the grid
737        """
738        self.panel.on_remove_column()
739       
740    def on_insert_column(self, event):
741        """
742        Insert a new column to the grid
743        """
744        self.panel.insert_column()
745       
746    def on_append_column(self, event):
747        """
748        Append a new column to the grid
749        """
750        self.panel.add_column()
751       
752    def set_data(self, data_inputs, data_outputs):
753        """
754        """
755        self.panel.set_data(data_inputs, data_outputs)
756     
757     
758class BatchOutputFrame(wx.Frame):
759    """
760    Allow to select where the result of batch will be displayed or stored
761    """
762    def __init__(self, parent, data_inputs, data_outputs, file_name="",
763                 details="", *args, **kwds):
764        """
765        :param parent: Window instantiating this dialog
766        :param result: result to display in a grid or export to an external
767                application.
768        """
769        #kwds['style'] = wx.CAPTION|wx.SYSTEM_MENU
770        wx.Frame.__init__(self, parent, *args, **kwds)
771        self.parent = parent
772        self.panel = wx.Panel(self)
773        self.file_name = file_name
774        self.details = details
775        self.data_inputs = data_inputs
776        self.data_outputs = data_outputs
777        self.data = {}
778        for item in (self.data_outputs, self.data_inputs):
779            self.data.update(item)
780        self.flag = 1
781        self.SetSize((300, 200))
782        self.local_app_selected = None
783        self.external_app_selected = None
784        self.save_to_file = None
785        self._do_layout()
786   
787    def _do_layout(self):
788        """
789        Draw the content of the current dialog window
790        """
791        vbox = wx.BoxSizer(wx.VERTICAL)
792        box_description = wx.StaticBox(self.panel, -1, str("Batch Outputs"))
793        hint_sizer = wx.StaticBoxSizer(box_description, wx.VERTICAL)
794        selection_sizer = wx.GridBagSizer(5, 5)
795        button_sizer = wx.BoxSizer(wx.HORIZONTAL)
796        text = "Open with %s" % self.parent.application_name
797        self.local_app_selected = wx.RadioButton(self.panel, -1, text,
798                                                style=wx.RB_GROUP)
799        self.Bind(wx.EVT_RADIOBUTTON, self.onselect,
800                    id=self.local_app_selected.GetId())
801        text = "Open with Excel"
802        self.external_app_selected  = wx.RadioButton(self.panel, -1, text)
803        self.Bind(wx.EVT_RADIOBUTTON, self.onselect,
804                    id=self.external_app_selected.GetId())
805        text = "Save to File"
806        self.save_to_file = wx.CheckBox(self.panel, -1, text)
807        self.Bind(wx.EVT_CHECKBOX, self.onselect,
808                    id=self.save_to_file.GetId())
809        self.local_app_selected.SetValue(True)
810        self.external_app_selected.SetValue(False)
811        self.save_to_file.SetValue(False)
812        button_close = wx.Button(self.panel, -1, "Close")
813        button_close.Bind(wx.EVT_BUTTON, id=button_close.GetId(),
814                           handler=self.on_close)
815        button_apply = wx.Button(self.panel, -1, "Apply")
816        button_apply.Bind(wx.EVT_BUTTON, id=button_apply.GetId(),
817                        handler=self.on_apply)
818        button_apply.SetFocus()
819        hint = ""
820        hint_sizer.Add(wx.StaticText(self.panel, -1, hint))
821        hint_sizer.Add(selection_sizer)
822        #draw area containing radio buttons
823        ix = 0
824        iy = 0
825        selection_sizer.Add(self.local_app_selected, (iy, ix),
826                           (1, 1), wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
827        iy += 1
828        selection_sizer.Add(self.external_app_selected, (iy, ix),
829                           (1, 1), wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
830        iy += 1
831        selection_sizer.Add(self.save_to_file, (iy, ix),
832                           (1, 1), wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
833        #contruction the sizer contaning button
834        button_sizer.Add((20, 20), 1, wx.EXPAND|wx.ADJUST_MINSIZE, 0)
835
836        button_sizer.Add(button_close, 0,
837                        wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
838        button_sizer.Add(button_apply, 0,
839                                wx.LEFT|wx.RIGHT|wx.ADJUST_MINSIZE, 10)
840        vbox.Add(hint_sizer,  0, wx.EXPAND|wx.ALL, 10)
841        vbox.Add(wx.StaticLine(self.panel, -1),  0, wx.EXPAND, 0)
842        vbox.Add(button_sizer, 0 , wx.TOP|wx.BOTTOM, 10)
843        self.SetSizer(vbox)
844       
845    def on_apply(self, event):
846        """
847        Get the user selection and display output to the selected application
848        """
849        if self.flag == 1:
850            self.parent.open_with_localapp(data_inputs=self.data_inputs,
851                                            data_outputs=self.data_outputs)
852        elif self.flag == 2:
853            self.parent.open_with_externalapp(data=self.data, 
854                                           file_name=self.file_name,
855                                           details=self.details)
856    def on_close(self, event):
857        """
858        close the Window
859        """
860        self.Close()
861       
862    def onselect(self, event=None):
863        """
864        Receive event and display data into third party application
865        or save data to file.
866       
867        """
868        if self.save_to_file.GetValue():
869            reader, ext = os.path.splitext(self.file_name)
870            path = None
871            location = os.getcwd()
872            if self.parent is not None: 
873                location = os.path.dirname(self.file_name)
874                dlg = wx.FileDialog(self, "Save Project file",
875                            location, self.file_name, ext, wx.SAVE)
876                path = None
877                if dlg.ShowModal() == wx.ID_OK:
878                    path = dlg.GetPath()
879                dlg.Destroy()
880                if path != None:
881                    if self.parent is not None and  self.data is not None:
882                        self.parent.write_batch_tofile(data=self.data, 
883                                               file_name=path,
884                                               details=self.details)
885        if self.local_app_selected.GetValue():
886            self.flag = 1
887        else:
888            self.flag = 2
889        return self.flag
890   
891 
892       
893if __name__ == "__main__":
894    app = wx.App()
895   
896    try:
897        data = {}
898        j = 0
899        for i in range(4):
900            j += 1
901            data["index"+str(i)] = [i/j, i*j, i, i+j]
902       
903        data_input =  copy.deepcopy(data)   
904        data_input["index5"] = [10,20,40, 50]
905        frame = GridFrame(data_outputs=data, data_inputs=data_input)
906        frame.Show(True)
907    except:
908        print sys.exc_value
909       
910    app.MainLoop()
Note: See TracBrowser for help on using the repository browser.