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

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

fix select row on grid

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