class Editor(ttk.Frame): """ Text editor and visual part of module stepper """ def __init__(self, master, workbench, filename=None): self._workbench = workbench ttk.Frame.__init__(self, master) assert isinstance(master, EditorNotebook) self._code_view = CodeView(self, workbench, propose_remove_line_numbers=True) self._code_view.grid(sticky=tk.NSEW) self.columnconfigure(0, weight=1) self.rowconfigure(0, weight=1) self._stepper = None self._filename = None self.file_encoding = None if filename is not None: self._load_file(filename) self._code_view.text.edit_modified(False) self._code_view.text.bind("<<Modified>>", lambda _: self.event_generate(EDITOR_STATE_CHANGE), "+") def get_filename(self, try_hard=False): if self._filename is None and try_hard: self._cmd_save_file() return self._filename def _load_file(self, filename): source, self.file_encoding = misc_utils.read_python_file(filename) # TODO: support also text files self._filename = filename self._code_view.modified_since_last_save = False self._workbench.event_generate("Open", editor=self, filename=filename) self._code_view.set_content(source) self._code_view.focus_set() def is_modified(self): return self._code_view.modified_since_last_save def save_file_enabled(self): return self.is_modified() or not self.get_filename() def save_file(self): if self._filename is not None: filename = self._filename self._workbench.event_generate("Save", editor=self) else: # http://tkinter.unpythonic.net/wiki/tkFileDialog filename = asksaveasfilename ( filetypes = _dialog_filetypes, defaultextension = ".py", initialdir = self._workbench.get_option("run.working_directory") ) if filename == "": return None self._workbench.event_generate("SaveAs", editor=self, filename=filename) content = self._code_view.get_content() encoding = self.file_encoding or "UTF-8" f = open(filename, mode="wb", ) f.write(content.encode(encoding)) f.close() self._code_view.modified_since_last_save = False self._filename = filename self._code_view.text.edit_modified(False) self.event_generate(EDITOR_STATE_CHANGE) return self._filename def change_font_size(self, delta): self._code_view.change_font_size(delta) def show(self): self.master.select(self) def handle_vm_message(self, msg): assert isinstance(msg, DebuggerResponse) if self.is_modified(): raise RuntimeError ("Can't show debug info in modified editor") """ # actually this check is not sound, as this_frame.source is not guaranteed # to be saved at code compilation time if frame.source != self._code_view.get_content(): print("Editor content>" + self._code_view.get_content() + "<") print("frame.source>" + frame.source + "<") raise RuntimeError ("Editor content doesn't match module source. Did you change it after starting the program?") """ if self._stepper is None: self._stepper = StatementStepper(msg.frame_id, self, self._workbench, self._code_view) self._stepper.handle_vm_message(msg) def select_range(self, text_range): self._code_view.select_range(text_range) def enter_execution_mode(self): self._code_view.enter_execution_mode() def clear_debug_view(self): if self._stepper is not None: self._stepper.clear_debug_view() def exit_execution_mode(self): self.clear_debug_view() self._code_view.exit_execution_mode() self._stepper = None def get_frame_id(self): if self._stepper is None: return None else: return self._stepper.frame_id def focus_set(self): self._code_view.focus_set() def is_focused(self): return self.focus_displayof() == self._code_view.text