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

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

working on display plot

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