Exemple #1
0
class FrameDialog(tk.Toplevel, FrameVisualizer):
    def __init__(self, master, frame_info):
        tk.Toplevel.__init__(self, master)
        
        self.transient(master)
        if misc_utils.running_on_windows():
            self.wm_attributes('-toolwindow', 1)
        
        
        # TODO: take size from prefs
        editor_notebook = get_workbench().get_editor_notebook()
        if master.winfo_toplevel() == get_workbench():
            position_reference = editor_notebook
        else:
            # align to previous frame
            position_reference = master.winfo_toplevel()
            
        self.geometry("{}x{}+{}+{}".format(editor_notebook.winfo_width(),
                                           editor_notebook.winfo_height()-20,
                                           position_reference.winfo_rootx(),
                                           position_reference.winfo_rooty()))
        self.protocol("WM_DELETE_WINDOW", self._on_close)
        
        self._init_layout_widgets(master, frame_info)
        FrameVisualizer.__init__(self, self._text_frame, frame_info)
        
        self._load_code(frame_info)
        self._text_frame.text.focus()
    
    def _init_layout_widgets(self, master, frame_info):
        self.main_frame= ttk.Frame(self) # just a backgroud behind padding of main_pw, without this OS X leaves white border
        self.main_frame.grid(sticky=tk.NSEW)        
        self.rowconfigure(0, weight=1)
        self.columnconfigure(0, weight=1)
        self.main_pw = ui_utils.AutomaticPanedWindow(self.main_frame, orient=tk.VERTICAL)
        self.main_pw.grid(sticky=tk.NSEW, padx=10, pady=10)
        self.main_frame.rowconfigure(0, weight=1)
        self.main_frame.columnconfigure(0, weight=1)
        
        self._code_book = ttk.Notebook(self.main_pw)
        self._text_frame = CodeView(self._code_book, 
                                      first_line_number=frame_info.firstlineno,
                                      font=get_workbench().get_font("EditorFont"))
        self._code_book.add(self._text_frame, text="Source")
        self.main_pw.add(self._code_book, minsize=100)
        
    
    def _load_code(self, frame_info):
        self._text_frame.set_content(frame_info.source)
    
    def _update_this_frame(self, msg, frame_info):
        FrameVisualizer._update_this_frame(self, msg, frame_info)
    
    def _on_close(self):
        showinfo("Can't close yet", 'Use "Stop" command if you want to cancel debugging')
    
    
    def close(self):
        FrameVisualizer.close(self)
        self.destroy()
Exemple #2
0
 def _init_layout_widgets(self, master, frame_info):
     self.main_frame= ttk.Frame(self) # just a backgroud behind padding of main_pw, without this OS X leaves white border
     self.main_frame.grid(sticky=tk.NSEW)        
     self.rowconfigure(0, weight=1)
     self.columnconfigure(0, weight=1)
     self.main_pw = ui_utils.AutomaticPanedWindow(self.main_frame, orient=tk.VERTICAL)
     self.main_pw.grid(sticky=tk.NSEW, padx=10, pady=10)
     self.main_frame.rowconfigure(0, weight=1)
     self.main_frame.columnconfigure(0, weight=1)
     
     self._code_book = ttk.Notebook(self.main_pw)
     self._text_frame = CodeView(self._code_book, 
                                   first_line_number=frame_info.firstlineno,
                                   font=get_workbench().get_font("EditorFont"))
     self._code_book.add(self._text_frame, text="Source")
     self.main_pw.add(self._code_book, minsize=100)
Exemple #3
0
 def _init_layout_widgets(self, master, msg):
     self.main_frame= ttk.Frame(self) # just a backgroud behind padding of main_pw, without this OS X leaves white border
     self.main_frame.grid(sticky=tk.NSEW)        
     self.rowconfigure(0, weight=1)
     self.columnconfigure(0, weight=1)
     self.main_pw = ui_utils.AutomaticPanedWindow(self.main_frame, orient=tk.VERTICAL)
     self.main_pw.grid(sticky=tk.NSEW, padx=10, pady=10)
     self.main_frame.rowconfigure(0, weight=1)
     self.main_frame.columnconfigure(0, weight=1)
     
     self._code_book = ttk.Notebook(self.main_pw)
     self._code_view = CodeView(self._code_book, first_line_no=msg.firstlineno)
     self._code_book.add(self._code_view)
     self._code_view.enter_execution_mode()
     
     #self._code_book.rowconfigure(1, weight=1)
     #self._code_book.columnconfigure(0, weight=1)
     
     
     self._locals_book = ttk.Notebook(self.main_pw)
     self._locals_frame = LocalsFrame(self._locals_book)
     self._locals_book.add(self._locals_frame, text="Local variables")
     
     
     self.main_pw.add(self._code_book, minsize=130)
     self.main_pw.add(self._locals_book, minsize=75)
Exemple #4
0
    def _create_widgets(self):

        bg = "#ffff99"
        banner_frame = tk.Frame(self, background=bg)
        banner_frame.grid(row=0, column=0, sticky="nsew")
        banner_frame.rowconfigure(0, weight=1)
        banner_frame.columnconfigure(0, weight=1)
        banner_text = tk.Label(
            banner_frame,
            text=_("These\nare\ninstructions asdfa afs fa sfasdf"),
            background=bg,
            justify="left",
        )
        banner_text.grid(column=0, row=0, pady=10, padx=10, sticky="nsew")

        main_frame = ttk.Frame(self)
        main_frame.grid(row=1, column=0, sticky=tk.NSEW, padx=15, pady=15)
        self.rowconfigure(0, weight=1)
        self.columnconfigure(0, weight=1)

        self.main_command_text = CodeView(main_frame, height=5)
        self.main_command_text.grid(column=0, row=1, sticky="nsew")
        # main_command_text["relief"] = "groove"

        main_frame.rowconfigure(1, weight=1)
        main_frame.columnconfigure(0, weight=1)

        button_frame = ttk.Frame(main_frame)
        button_frame.grid(row=2, column=0, sticky="nsew")

        run_button = ttk.Button(button_frame,
                                text=_("Save and execute"),
                                command=self._save_exec)
        run_button.grid(row=0, column=1, sticky="nsew")
        ok_button = ttk.Button(button_frame,
                               text=_("Save"),
                               command=self._save)
        ok_button.grid(row=0, column=2, sticky="nsew")
        cancel_button = ttk.Button(button_frame,
                                   text=_("Cancel"),
                                   command=self._cancel)
        cancel_button.grid(row=0, column=3, sticky="nsew")
        button_frame.columnconfigure(0, weight=1)
Exemple #5
0
    def __init__(self, master, filename=None):

        ttk.Frame.__init__(self, master)
        assert isinstance(master, EditorNotebook)

        # parent of codeview will be workbench so that it can be maximized
        self._code_view = CodeView(get_workbench(),
                                   propose_remove_line_numbers=True,
                                   font=get_workbench().get_font("EditorFont"))
        get_workbench().event_generate("EditorTextCreated",
                                       editor=self,
                                       text_widget=self.get_text_widget())

        self._code_view.grid(row=0, column=0, sticky=tk.NSEW, in_=self)
        self._code_view.home_widget = self  # don't forget home
        self.maximizable_widget = self._code_view

        self.columnconfigure(0, weight=1)
        self.rowconfigure(0, weight=1)

        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 e: master.update_editor_title(self),
                                  True)
        self._code_view.text.bind("<Control-Tab>", self._control_tab, True)

        get_workbench().bind("AfterKnownMagicCommand",
                             self._listen_for_execute, True)
        get_workbench().bind("ToplevelResult",
                             self._listen_for_toplevel_result, True)

        self.update_appearance()
Exemple #6
0
 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), "+")            
Exemple #7
0
class ShellMacroDialog(tk.Toplevel):
    def __init__(self, master):
        tk.Toplevel.__init__(self, master)

        self.title(_("Configure shell macro"))
        if misc_utils.running_on_mac_os():
            self.configure(background="systemSheetBackground")
        self.transient(master)
        self.grab_set()  # to make it active
        # self.grab_release() # to allow eg. copy something from the editor

        self._create_widgets()

        self.bind("<Escape>", self._on_close, True)
        self.protocol("WM_DELETE_WINDOW", self._on_close)
        self.main_command_text.focus_set()

    def _create_widgets(self):

        bg = "#ffff99"
        banner_frame = tk.Frame(self, background=bg)
        banner_frame.grid(row=0, column=0, sticky="nsew")
        banner_frame.rowconfigure(0, weight=1)
        banner_frame.columnconfigure(0, weight=1)
        banner_text = tk.Label(
            banner_frame,
            text=_("These\nare\ninstructions asdfa afs fa sfasdf"),
            background=bg,
            justify="left",
        )
        banner_text.grid(column=0, row=0, pady=10, padx=10, sticky="nsew")

        main_frame = ttk.Frame(self)
        main_frame.grid(row=1, column=0, sticky=tk.NSEW, padx=15, pady=15)
        self.rowconfigure(0, weight=1)
        self.columnconfigure(0, weight=1)

        self.main_command_text = CodeView(main_frame, height=5)
        self.main_command_text.grid(column=0, row=1, sticky="nsew")
        # main_command_text["relief"] = "groove"

        main_frame.rowconfigure(1, weight=1)
        main_frame.columnconfigure(0, weight=1)

        button_frame = ttk.Frame(main_frame)
        button_frame.grid(row=2, column=0, sticky="nsew")

        run_button = ttk.Button(button_frame,
                                text=_("Save and execute"),
                                command=self._save_exec)
        run_button.grid(row=0, column=1, sticky="nsew")
        ok_button = ttk.Button(button_frame,
                               text=_("Save"),
                               command=self._save)
        ok_button.grid(row=0, column=2, sticky="nsew")
        cancel_button = ttk.Button(button_frame,
                                   text=_("Cancel"),
                                   command=self._cancel)
        cancel_button.grid(row=0, column=3, sticky="nsew")
        button_frame.columnconfigure(0, weight=1)

    def _on_close(self, event=None):
        self.destroy()

    def _save_exec(self, event=None):
        self._save(event)
        execute_macro()

    def _save(self, event=None):
        source = self.main_command_text.text.get("1.0", "end")
        get_workbench().set_option("run.shell_macro_main", repr(source))
        self.destroy()

    def _cancel(self, event=None):
        self.destroy()
Exemple #8
0
class Editor(ttk.Frame):
    def __init__(self, master, filename=None):

        ttk.Frame.__init__(self, master)
        assert isinstance(master, EditorNotebook)

        # parent of codeview will be workbench so that it can be maximized
        self._code_view = CodeView(get_workbench(),
                                   propose_remove_line_numbers=True,
                                   font=get_workbench().get_font("EditorFont"))
        get_workbench().event_generate("EditorTextCreated",
                                       editor=self,
                                       text_widget=self.get_text_widget())

        self._code_view.grid(row=0, column=0, sticky=tk.NSEW, in_=self)
        self._code_view.home_widget = self  # don't forget home
        self.maximizable_widget = self._code_view

        self.columnconfigure(0, weight=1)
        self.rowconfigure(0, weight=1)

        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 e: master.update_editor_title(self),
                                  True)
        self._code_view.text.bind("<Control-Tab>", self._control_tab, True)

        get_workbench().bind("AfterKnownMagicCommand",
                             self._listen_for_execute, True)
        get_workbench().bind("ToplevelResult",
                             self._listen_for_toplevel_result, True)

        self.update_appearance()

    def get_text_widget(self):
        return self._code_view.text

    def get_code_view(self):
        # TODO: try to get rid of this
        return self._code_view

    def get_filename(self, try_hard=False):
        if self._filename is None and try_hard:
            self.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
        get_workbench().event_generate("Open", editor=self, filename=filename)
        self._code_view.set_content(source)
        self._code_view.focus_set()
        self.master.remember_recent_file(filename)

    def is_modified(self):
        return self._code_view.text.edit_modified()

    def save_file_enabled(self):
        return self.is_modified() or not self.get_filename()

    def save_file(self, ask_filename=False):
        if self._filename is not None and not ask_filename:
            filename = self._filename
            get_workbench().event_generate("Save",
                                           editor=self,
                                           filename=filename)
        else:
            # http://tkinter.unpythonic.net/wiki/tkFileDialog
            filename = asksaveasfilename(
                filetypes=_dialog_filetypes,
                defaultextension=".py",
                initialdir=get_workbench().get_option("run.working_directory"))
            if filename in [
                    "", (), None
            ]:  # Different tkinter versions may return different values
                return None

            # Seems that in some Python versions defaultextension
            # acts funny
            if filename.lower().endswith(".py.py"):
                filename = filename[:-3]

            get_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._filename = filename
        self.master.remember_recent_file(filename)

        self._code_view.text.edit_modified(False)

        return self._filename

    def show(self):
        self.master.select(self)

    def update_appearance(self):
        self._code_view.set_line_numbers(
            get_workbench().get_option("view.show_line_numbers"))
        self._code_view.set_line_length_margin(
            get_workbench().get_option("view.recommended_line_length"))
        self._code_view.text.event_generate("<<UpdateAppearance>>")

    def _listen_for_execute(self, event):
        command, args = parse_shell_command(event.cmd_line)
        if command.lower() in ["run", "debug"]:
            if len(args) == 0:
                return
            filename = args[0]
            self_filename = self.get_filename()
            if self_filename is not None and os.path.basename(
                    self_filename) == filename:
                # Not that command has only basename
                # so this solution may make more editors read-only than necessary
                self._code_view.text.set_read_only(True)

    def _listen_for_toplevel_result(self, event):
        self._code_view.text.set_read_only(False)

    def _control_tab(self, event):
        if event.state & 1:  # shift was pressed
            direction = -1
        else:
            direction = 1
        self.master.select_next_prev_editor(direction)
        return "break"

    def _shift_control_tab(self, event):
        self.master.select_next_prev_editor(-1)
        return "break"

    def select_range(self, text_range):
        self._code_view.select_range(text_range)

    def focus_set(self):
        self._code_view.focus_set()

    def is_focused(self):
        return self.focus_displayof() == self._code_view.text

    def destroy(self):
        get_workbench().unbind("AfterKnownMagicCommand",
                               self._listen_for_execute)
        get_workbench().unbind("ToplevelResult",
                               self._listen_for_toplevel_result)
        ttk.Frame.destroy(self)
Exemple #9
0
class FunctionDialog(tk.Toplevel):
    def __init__(self, master, msg, title):
        tk.Toplevel.__init__(self, master)
        self._frame_id = msg.frame_id
        self.title(title)
        self.transient(master)
        if misc_utils.running_on_windows():
            self.wm_attributes('-toolwindow', 1)
        
        
        # TODO: take size from prefs
        self.geometry("{}x{}+{}+{}".format(master.winfo_width(),
                                           master.winfo_height(),
                                           master.winfo_toplevel().winfo_rootx(),
                                           master.winfo_toplevel().winfo_rooty()))
        self.protocol("WM_DELETE_WINDOW", self._on_close)
        
        self._init_layout_widgets(master, msg)
        self._load_function(msg)
        self._stepper = StatementStepper(msg.frame_id, self, self._workbench, self._code_view)
        self._code_view.text.focus()
    
    def get_frame_id(self):
        return self._frame_id
    
    def _init_layout_widgets(self, master, msg):
        self.main_frame= ttk.Frame(self) # just a backgroud behind padding of main_pw, without this OS X leaves white border
        self.main_frame.grid(sticky=tk.NSEW)        
        self.rowconfigure(0, weight=1)
        self.columnconfigure(0, weight=1)
        self.main_pw = ui_utils.AutomaticPanedWindow(self.main_frame, orient=tk.VERTICAL)
        self.main_pw.grid(sticky=tk.NSEW, padx=10, pady=10)
        self.main_frame.rowconfigure(0, weight=1)
        self.main_frame.columnconfigure(0, weight=1)
        
        self._code_book = ttk.Notebook(self.main_pw)
        self._code_view = CodeView(self._code_book, first_line_no=msg.firstlineno)
        self._code_book.add(self._code_view)
        self._code_view.enter_execution_mode()
        
        #self._code_book.rowconfigure(1, weight=1)
        #self._code_book.columnconfigure(0, weight=1)
        
        
        self._locals_book = ttk.Notebook(self.main_pw)
        self._locals_frame = LocalsFrame(self._locals_book)
        self._locals_book.add(self._locals_frame, text="Local variables")
        
        
        self.main_pw.add(self._code_book, minsize=130)
        self.main_pw.add(self._locals_book, minsize=75)
    
    def _load_function(self, msg):
        self._code_view.set_content(msg.source)
        if hasattr(msg, "function"):
            function_label = msg.function.repr
        else:
            function_label = msg.code_name
             
        self._code_book.tab(self._code_view, text=function_label)
        #self._locals_frame.handle_vm_message(msg)
    
    def handle_vm_message(self, msg):
        self._stepper.handle_vm_message(msg)
        
        if hasattr(msg, "stack"):
            frame = list(filter(lambda f: f.id == self._frame_id, msg.stack))[0]
            self._locals_frame.update_variables(frame.locals)
        else:
            self._locals_frame.update_variables(None)
                
    
    def _on_close(self):
        showinfo("Can't close yet", "Step until the end of this function to close it")
Exemple #10
0
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