def OnGridSelection(self, event): """Event handler for grid selection in selection mode adds text""" current_table = copy(self.main_window.grid.current_table) post_command_event(self, self.GridActionTableSwitchMsg, newtable=self.last_table) if is_gtk(): try: wx.Yield() except: pass sel_start, sel_stop = self.last_selection shape = self.main_window.grid.code_array.shape selection_string = event.selection.get_access_string( shape, current_table) self.Replace(sel_start, sel_stop, selection_string) self.last_selection = sel_start, sel_start + len(selection_string) post_command_event(self, self.GridActionTableSwitchMsg, newtable=current_table)
def OnText(self, event): """Text event method evals the cell and updates the grid""" if not self.ignore_changes: post_command_event(self, self.CodeEntryMsg, code=event.GetString()) event.Skip()
def OnSecondaryCheckbox(self, event): """Top Checkbox event handler""" self.attrs["top"] = event.IsChecked() self.attrs["right"] = event.IsChecked() post_command_event(self, self.DrawChartMsg)
def OnFind(self, event): """Find functionality, called from toolbar, returns find position""" # Search starts in next cell after the current one gridpos = list(self.grid.actions.cursor) text, flags = event.text, event.flags findpos = self.grid.actions.find(gridpos, text, flags) if findpos is None: # If nothing is found mention it in the statusbar and return statustext = _("'{text}' not found.").format(text=text) else: # Otherwise select cell with next occurrence if successful self.grid.actions.cursor = findpos # Update statusbar statustext = _(u"Found '{text}' in cell {key}.") statustext = statustext.format(text=text, key=findpos) post_command_event(self.grid.main_window, self.grid.StatusBarMsg, text=statustext) event.Skip()
def OnMacroListLoad(self, event): """Macro list load event handler""" # Get filepath from user wildcard = \ _("Macro file") + " (*.py)|*.py|" + \ _("All files") + " (*.*)|*.*" message = _("Choose macro file.") style = wx.OPEN filepath, filterindex = \ self.interfaces.get_filepath_findex_from_user(wildcard, message, style) if filepath is None: return # Enter safe mode because macro file could be harmful post_command_event(self.main_window, self.main_window.SafeModeEntryMsg) # Load macros from file self.main_window.actions.open_macros(filepath) event.Skip()
def OnCellSelected(self, event): """Cell selection event handler""" key = row, col, tab = event.Row, event.Col, self.grid.current_table # Is the cell merged then go to merging cell cell_attributes = self.grid.code_array.cell_attributes merging_cell = cell_attributes.get_merging_cell(key) if merging_cell is not None and merging_cell != key: post_command_event(self.grid, self.grid.GotoCellMsg, key=merging_cell) return # If in selection mode do nothing # This prevents the current cell from changing if not self.grid.IsEditable(): return # Redraw cursor self.grid.ForceRefresh() # Disable entry line if cell is locked self.grid.lock_entry_line( self.grid.code_array.cell_attributes[key]["locked"]) # Update entry line self.grid.update_entry_line(key) # Update attribute toolbar self.grid.update_attribute_toolbar(key) self.grid._last_selected_cell = key event.Skip()
def OnSeriesDeleted(self, event): """FlatNotebook closing event handler""" # Redraw Chart post_command_event(self, self.DrawChartMsg) event.Skip()
def OnReplace(self, event): """Called when a replace operation is started, returns find position""" find_string = event.GetFindString() flags = self._wxflag2flag(event.GetFlags()) replace_string = event.GetReplaceString() gridpos = list(self.grid.actions.cursor) findpos = self.grid.actions.find(gridpos, find_string, flags, search_result=False) if findpos is None: statustext = _(u"'{find_string}' not found.") statustext = statustext.format(find_string=find_string) else: self.grid.actions.replace(findpos, find_string, replace_string) self.grid.actions.cursor = findpos # Update statusbar statustext = _(u"Replaced '{find_string}' in cell {key} with " u"{replace_string}.") statustext = statustext.format(find_string=find_string, key=findpos, replace_string=replace_string) post_command_event(self.grid.main_window, self.grid.StatusBarMsg, text=statustext) event.Skip()
def OnFont(self, event): """Check event handler""" font_data = wx.FontData() # Disable color chooser on Windows font_data.EnableEffects(False) if self.chosen_font: font_data.SetInitialFont(self.chosen_font) dlg = wx.FontDialog(self, font_data) if dlg.ShowModal() == wx.ID_OK: font_data = dlg.GetFontData() font = self.chosen_font = font_data.GetChosenFont() self.font_face = font.GetFaceName() self.font_size = font.GetPointSize() self.font_style = font.GetStyle() self.font_weight = font.GetWeight() dlg.Destroy() post_command_event(self, self.DrawChartMsg)
def OnChar(self, event): self._update_control_length() val = self._tc.GetValue() post_command_event(self.main_window, self.TableChangedMsg, updated_cell=val) event.Skip()
def OnApprove(self, event): """File approve event handler""" if not self.main_window.safe_mode: return msg = _(u"You are going to approve and trust a file that\n" u"you have received from an untrusted source.\n" u"After proceeding, the file is executed.\n" u"It can harm your system as any program can.\n" u"Unless you took precautions, it can delete your\n" u"files or send them away over the Internet.\n" u"CHECK EACH CELL BEFORE PROCEEDING.\n \n" u"Do not forget cells outside the visible range.\n" u"You have been warned.\n \n" u"Proceed and sign this file as trusted?") short_msg = _("Security warning") if self.main_window.interfaces.get_warning_choice(msg, short_msg): # Leave safe mode self.main_window.grid.actions.leave_safe_mode() # Display safe mode end in status bar statustext = _("Safe mode deactivated.") post_command_event(self.main_window, self.main_window.StatusBarMsg, text=statustext)
def __init__(self, main_window, *args, **kwargs): S = kwargs.pop("S") self.main_window = main_window self._states() self.interfaces = GuiInterfaces(self.main_window) if S is None: dimensions = kwargs.pop("dimensions") else: dimensions = S.shape kwargs.pop("dimensions") wx.grid.Grid.__init__(self, main_window, *args, **kwargs) self.SetDefaultCellBackgroundColour(wx.Colour(255, 255, 255, 255)) # Cursor position on entering selection mode self.sel_mode_cursor = None # Set multi line editor self.SetDefaultEditor(GridCellEditor(main_window)) # Create new grid if S is None: self.code_array = CodeArray(dimensions) post_command_event(self, self.GridActionNewMsg, shape=dimensions) else: self.code_array = S _grid_table = GridTable(self, self.code_array) self.SetTable(_grid_table, True) # Grid renderer draws the grid self.grid_renderer = GridRenderer(self.code_array) self.SetDefaultRenderer(self.grid_renderer) # Context menu for quick access of important functions self.contextmenu = ContextMenu(parent=self) # Handler classes contain event handler methods self.handlers = GridEventHandlers(self) self.cell_handlers = GridCellEventHandlers(self) # Grid actions self.actions = AllGridActions(self) # Layout and bindings self._layout() self._bind() # Update toolbars self.update_entry_line() self.update_attribute_toolbar() # Focus on grid so that typing can start immediately self.SetFocus()
def OnKeyUp(self, event): # Handle <Ctrl> + <Enter> keycode = event.GetKeyCode() if keycode == 13 and event.ControlDown(): self._tc.SetValue(quote(self._tc.GetValue())) post_command_event(self.main_window, self.TableChangedMsg, updated_cell=self._tc.GetValue()) event.Skip()
def OnDirectionChoice(self, event): """Direction choice event handler""" label = self.direction_choicectrl.GetItems()[event.GetSelection()] param = self.choice_label2param[label] self.attrs["direction"] = param post_command_event(self, self.DrawChartMsg)
def OnLineColor(self, event): """Line color choice event handler""" color = event.GetValue().GetRGB() borders = self.bordermap[self.borderstate] post_command_event(self, self.BorderColorMsg, color=color, borders=borders)
def OnRotate(self, event): """Rotation spin control event handler""" angle = self.rotation_spinctrl.GetValue() post_command_event(self, self.TextRotationMsg, angle=angle) # end of class AttributesToolbar
def OnTextRotationDialog(self, event): """Text rotation dialog event handler""" cond_func = lambda i: 0 <= i <= 359 angle = self.grid.interfaces.get_int_from_user(_("Enter text angle in degrees."), cond_func) if angle is not None: post_command_event(self.grid.main_window, self.grid.TextRotationMsg, angle=angle)
def OnKey(self, event): """Handles non-standard shortcut events""" keycode = event.GetKeyCode() # If in selection mode and <Enter> is pressed end it if not self.grid.IsEditable() and keycode == 13: ## TODO! pass elif event.ControlDown(): if keycode == 388: # Ctrl + + pressed post_command_event(self.grid, self.grid.ZoomInMsg) elif keycode == 390: # Ctrl + - pressed post_command_event(self.grid, self.grid.ZoomOutMsg) elif keycode == 13: # <Ctrl> + <Enter> grid = self.grid grid.DisableCellEditControl() row = self.grid.GetGridCursorRow() col = self.grid.GetGridCursorCol() tab = grid.current_table key = row, col, tab val = grid.code_array(key) grid.actions.set_code(key, '"' + val + '"') grid.MoveCursorDown(False) else: # No Ctrl pressed if keycode == 127: # Del pressed # Delete cell at cursor cursor = self.grid.actions.cursor self.grid.actions.delete_cell(cursor) # Delete selection self.grid.actions.delete_selection() # Update grid self.grid.ForceRefresh() # Do not enter cell return elif keycode == 27: # Esc pressed self.grid.actions.need_abort = True event.Skip()
def OnText(self, event): """Text event method evals the cell and updates the grid""" if not self.ignore_changes: post_command_event(self, self.CodeEntryMsg, code=event.GetString()) self.main_window.grid.grid_renderer.cell_cache.clear() event.Skip()
def __init__(self, parent, code, **kwds): kwds["style"] = wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER | \ wx.THICK_FRAME self.grid = parent wx.Dialog.__init__(self, parent, **kwds) agwstyle = fnb.FNB_NODRAG | fnb.FNB_DROPDOWN_TABS_LIST | fnb.FNB_BOTTOM self.series_notebook = fnb.FlatNotebook(self, -1, agwStyle=agwstyle) if code[:7] == "charts.": # If chart data is present build the chart key = self.grid.actions.cursor self.figure = self.grid.code_array._eval_cell(key, code) # Get data from figure code_param_string = code.split("(", 1)[1][:-1] code_param_list = list(parse_dict_strings(code_param_string)) code_param = [] for series_param_string in code_param_list: series_param_list = \ list(parse_dict_strings(series_param_string[1:-1])) series_param = dict((ast.literal_eval(k), v) for k, v in zip(series_param_list[::2], series_param_list[1::2])) code_param.append(series_param) for series_param in code_param: plot_panel = PlotPanel(self, -1, series_param) self.series_notebook.AddPage(plot_panel, _("Series")) for key in series_param: plot_panel.series_data[key] = series_param[key] else: # Use default values plot_panel = PlotPanel(self, -1) self.series_notebook.AddPage(plot_panel, _("Series")) chart_data = self.eval_chart_data() self.figure = charts.ChartFigure(*chart_data) self.series_notebook.AddPage(wx.Panel(self, -1), _("+")) # end series creation self.cancel_button = wx.Button(self, wx.ID_CANCEL) self.ok_button = wx.Button(self, wx.ID_OK) self.figure_canvas = FigureCanvasWxAgg(self, -1, self.figure) self.__set_properties() self.__do_layout() self.__bindings() # Draw figure initially post_command_event(self, self.DrawChartMsg)
def OnTextSize(self, event): """Text size combo text event handler""" try: size = int(event.GetString()) except Exception: size = get_default_font().GetPointSize() post_command_event(self, self.FontSizeMsg, size=size)
def Reset(self): """ Reset the value in the control back to its starting value. *Must Override* """ self._tc.SetValue(self.startValue) self._tc.SetInsertionPointEnd() # Update the Entry Line post_command_event(self.main_window, self.TableChangedMsg, updated_cell=self.startValue)
def OnLineWidth(self, event): """Line width choice event handler""" linewidth_combobox = event.GetEventObject() idx = event.GetInt() width = int(linewidth_combobox.GetString(idx)) borders = self.bordermap[self.borderstate] post_command_event(self, self.BorderWidthMsg, width=width, borders=borders)
def _set_properties(self): """Setup title, icon, size, scale, statusbar, main grid""" self.set_icon(icons["PyspreadLogo"]) # Without minimum size, initial size is minimum size in wxGTK self.minSizeSet = False # Leave save mode post_command_event(self, self.SafeModeExitMsg)
def OnItemSelected(self, event): """Item selection event handler""" value = event.m_itemIndex self.startIndex = value self.switching = True post_command_event(self, self.GridActionTableSwitchMsg, newtable=value) self.switching = False event.Skip()
def OnButtonCell(self, event): """Event handler for cell button toggle button""" if self.button_cell_button_id == event.GetId(): if event.IsChecked(): label = self._get_button_label() post_command_event(self, self.ButtonCellMsg, text=label) else: post_command_event(self, self.ButtonCellMsg, text=False) event.Skip()
def lock_entry_line(self, lock): """Lock or unlock entry line Parameters ---------- lock: Bool \tIf True then the entry line is locked if Falsse unlocked """ post_command_event(self, self.LockEntryLineMsg, lock=lock)
def _update_entry_line(self, key): """Updates the entry line""" cell_code = self.grid.code_array(key) # Do not display anything if there is no cell code, i. e. it is None # Also do not display anything if there is too much code because # wx.TextCtrl can only handle up to max_textctrl_length characters if cell_code is None or len(cell_code) < int(config["max_textctrl_length"]): post_command_event(self.grid, self.grid.EntryLineMsg, text=cell_code)
def OnTextFont(self, event): """Text font choice event handler""" fontchoice_combobox = event.GetEventObject() idx = event.GetInt() try: font_string = fontchoice_combobox.GetString(idx) except AttributeError: font_string = event.GetString() post_command_event(self, self.FontMsg, font=font_string)
def OnRangeSelected(self, event): """Event handler for grid selection""" # If grid editing is disabled then pyspread is in selection mode if not self.grid.IsEditable(): selection = self.grid.selection row, col, __ = self.grid.sel_mode_cursor if (row, col) in selection: self.grid.ClearSelection() else: self.grid.SetGridCursor(row, col) post_command_event(self.grid, self.grid.SelectionMsg, selection=selection)
def OnNew(self, event): """New grid event handler""" # If changes have taken place save of old grid if self.main_window.changed_since_save: save_choice = self.interfaces.get_save_request_from_user() if save_choice is None: # Cancelled close operation return elif save_choice: # User wants to save content post_command_event(self.main_window, self.main_window.SaveMsg) # Get grid dimensions shape = self.interfaces.get_dimensions_from_user(no_dim=3) if shape is None: return self.main_window.grid.actions.change_grid_shape(shape) # Set new filepath and post it to the title bar self.main_window.filepath = None post_command_event(self.main_window, self.main_window.TitleMsg, text="pyspread") # Clear globals self.main_window.grid.actions.clear_globals_reload_modules() # Create new grid post_command_event(self.main_window, self.main_window.GridActionNewMsg, shape=shape) # Update TableChoiceIntCtrl post_command_event(self.main_window, self.main_window.ResizeGridMsg, shape=shape) self.main_window.grid.GetTable().ResetView() self.main_window.grid.ForceRefresh() # Display grid creation in status bar msg = _("New grid with dimensions {dim} created.").format(dim=shape) post_command_event(self.main_window, self.main_window.StatusBarMsg, text=msg) self.main_window.grid.ForceRefresh()
def _set_properties(self): """Setup title, icon, size, scale, statusbar, main grid""" self.set_icon(icons["PyspreadLogo"]) # Set initial size to 90% of screen self.SetInitialSize(config["window_size"]) self.SetPosition(config["window_position"]) # Without minimum size, initial size is minimum size in wxGTK self.SetMinSize((2, 2)) # Leave save mode post_command_event(self, self.SafeModeExitMsg)
def OnMouseWheel(self, event): """Event handler for mouse wheel actions Invokes zoom when mouse when Ctrl is also pressed """ if event.ControlDown(): if event.WheelRotation > 0: post_command_event(self.grid, self.grid.ZoomInMsg) else: post_command_event(self.grid, self.grid.ZoomOutMsg) else: event.Skip()
def OnVideoCell(self, event): """Event handler for video cell toggle button""" if self.video_cell_button_id == event.GetId(): if event.IsChecked(): wildcard = _("Media files") + " (*.*)|*.*" videofile, __ = self.get_filepath_findex_from_user( wildcard, "Choose video or audio file", wx.OPEN) post_command_event(self, self.VideoCellMsg, videofile=videofile) else: post_command_event(self, self.VideoCellMsg, videofile=False) event.Skip()
def OnTextRotationDialog(self, event): """Text rotation dialog event handler""" cond_func = lambda i: 0 <= i <= 359 get_int = self.grid.interfaces.get_int_from_user angle = get_int(_("Enter text angle in degrees."), cond_func) if angle is not None: post_command_event(self.grid.main_window, self.grid.TextRotationMsg, angle=angle) self.grid.ForceRefresh() self.grid.update_attribute_toolbar()
def OnClearGlobals(self, event): """Clear globals event handler""" msg = _("Deleting globals and reloading modules cannot be undone." " Proceed?") short_msg = _("Really delete globals and modules?") choice = self.main_window.interfaces.get_warning_choice(msg, short_msg) if choice: self.main_window.grid.actions.clear_globals_reload_modules() statustext = _("Globals cleared and base modules reloaded.") post_command_event(self.main_window, self.main_window.StatusBarMsg, text=statustext)
def Reset(self): """ Reset the value in the control back to its starting value. *Must Override* """ try: self._tc.SetValue(self.startValue) except TypeError: # Start value was None pass self._tc.SetInsertionPointEnd() # Update the Entry Line post_command_event(self.main_window, self.TableChangedMsg, updated_cell=self.startValue)
def update_entry_line(self, key=None): """Updates the entry line Parameters ---------- key: 3-tuple of Integer, defaults to current cell \tCell to which code the entry line is updated """ if key is None: key = self.actions.cursor cell_code = self.GetTable().GetValue(*key) post_command_event(self, self.EntryLineMsg, text=cell_code)
def OnInt(self, event): """IntCtrl event method that updates the current table""" self.SetMax(self.no_tabs - 1) if event.GetValue() > self.GetMax(): self.SetValue(self.GetMax()) return if not self.switching: self.switching = True post_command_event(self, self.GridActionTableSwitchMsg, newtable=event.GetValue()) if is_gtk(): wx.Yield() self.switching = False
def update_attribute_toolbar(self, key=None): """Updates the attribute toolbar Parameters ---------- key: 3-tuple of Integer, defaults to current cell \tCell to which attributes the attributes toolbar is updated """ if key is None: key = self.actions.cursor post_command_event(self, self.ToolbarUpdateMsg, key=key, attr=self.code_array.cell_attributes[key])
def OnInt(self, event): """IntCtrl event method that updates the current table""" value = event.GetValue() current_time = time.clock() if current_time < self.last_change_s + 0.01: return self.last_change_s = current_time self.cursor_pos = wx.TextCtrl.GetInsertionPoint(self) + 1 if event.GetValue() > self.no_tabs - 1: value = self.no_tabs - 1 self.switching = True post_command_event(self, self.GridActionTableSwitchMsg, newtable=value) self.switching = False
def OnTextColorDialog(self, event): """Event handler for launching text color dialog""" dlg = wx.ColourDialog(self.main_window) # Ensure the full colour dialog is displayed, # not the abbreviated version. dlg.GetColourData().SetChooseFull(True) if dlg.ShowModal() == wx.ID_OK: # Fetch color data data = dlg.GetColourData() color = data.GetColour().GetRGB() post_command_event(self.main_window, self.main_window.TextColorMsg, color=color) dlg.Destroy()
def OnContentChanged(self, event): """Titlebar star adjustment event handler""" self.main_window.changed_since_save = event.changed title = self.main_window.GetTitle() if event.changed: # Put * in front of title if title[:2] != "* ": new_title = "* " + title post_command_event(self.main_window, self.main_window.TitleMsg, text=new_title) elif title[:2] == "* ": # Remove * in front of title new_title = title[2:] post_command_event(self.main_window, self.main_window.TitleMsg, text=new_title)
def OnSearch(self, event): """Event handler for starting the search""" search_string = self.search.GetValue() if search_string not in self.search_history: self.search_history.append(search_string) if len(self.search_history) > 10: self.search_history.pop(0) self.menu = self.make_menu() self.search.SetMenu(self.menu) search_flags = self.search_options + ["FIND_NEXT"] post_command_event(self, self.FindMsg, text=search_string, flags=search_flags) self.search.SetFocus()