コード例 #1
0
    def get_kill_process_instructions(self):
        s = (
            "Let's say you need port 5000. If you don't know which process is using it,"
            + " then enter following system command into Thonny's Shell:\n\n"
        )

        if running_on_windows():
            s += (
                "``!netstat -ano | findstr :5000``\n\n"
                + "You should see the process ID in the last column.\n\n"
            )
        else:
            s += (
                "``!lsof -i:5000``\n\n" + "You should see the process ID under the heading PID.\n\n"
            )

        s += (
            "Let's pretend the ID is 12345."
            " You can try hard-killing the process with following command:\n\n"
        )

        if running_on_windows():
            s += "``!tskill 12345``\n"
        else:
            s += (
                "``!kill -9 12345``\n\n"
                + "Both steps can be combined into single command:\n\n"
                + "``!kill -9 $(lsof -t -i:5000)``\n\n"
            )

        return s
コード例 #2
0
ファイル: code.py プロジェクト: aroberge/thonny-deconstructed
    def ask_new_local_path(self):
        if self._filename is None:
            initialdir = get_workbench().get_local_cwd()
            initialfile = None
        else:
            initialdir = os.path.dirname(self._filename)
            initialfile = os.path.basename(self._filename)

        # http://tkinter.unpythonic.net/wiki/tkFileDialog
        new_filename = asksaveasfilename(
            filetypes=_dialog_filetypes,
            defaultextension=".py",
            initialdir=initialdir,
            initialfile=initialfile,
        )

        # Different tkinter versions may return different values
        if new_filename in ["", (), None]:
            return None

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

        if running_on_windows():
            # may have /-s instead of \-s and wrong case
            new_filename = os.path.join(
                normpath_with_actual_case(os.path.dirname(new_filename)),
                os.path.basename(new_filename),
            )

        if new_filename.endswith(".py"):
            base = os.path.basename(new_filename)
            mod_name = base[:-3].lower()
            if running_on_windows():
                mod_name = mod_name.lower()

            if mod_name in [
                    "math",
                    "turtle",
                    "random",
                    "statistics",
                    "pygame",
                    "matplotlib",
                    "numpy",
            ]:

                # More proper name analysis will be performed by ProgramNamingAnalyzer
                if not tk.messagebox.askyesno(
                        "Potential problem",
                        "If you name your script '%s', " % base +
                        "you won't be able to import the library module named '%s'"
                        % mod_name + ".\n\n" +
                        "Do you still want to use this name for your script?",
                ):
                    return self.ask_new_local_path()

        return new_filename
コード例 #3
0
def _text_settings() -> BasicUiThemeSettings:
    return {
        "Text": {
            "configure": {
                "background": "SystemWindow" if running_on_windows() else "white",
                "foreground": "SystemWindowText" if running_on_windows() else "black",
            }
        },
        "Syntax.Text": {"map": {"background": [("readonly", "Yellow")]}},
        "Gutter": {"configure": {"background": "#e0e0e0", "foreground": "#999999"}},
    }
コード例 #4
0
    def __init__(self, master, frame_info):
        CommonDialog.__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.bind("<FocusIn>", self._on_focus, True)

        self._init_layout_widgets(master, frame_info)
        FrameVisualizer.__init__(self, self._text_frame, frame_info)
        self._firstlineno = frame_info.firstlineno

        self._load_code(frame_info)
        self._text_frame.text.focus()
        self.update()
コード例 #5
0
    def __init__(self, master):
        super().__init__(master)

        self._configuration_variable = create_string_var(
            get_workbench().get_option("CustomInterpreter.path"))

        entry_label = ttk.Label(self, text=_("Known interpreters"))
        entry_label.grid(row=0, column=0, columnspan=2, sticky=tk.W)

        self._entry = ttk.Combobox(
            self,
            exportselection=False,
            textvariable=self._configuration_variable,
            values=self._get_interpreters(),
        )

        self._entry.grid(row=1, column=0, columnspan=2, sticky=tk.NSEW)
        self._entry.state(["!disabled", "readonly"])

        another_label = ttk.Label(
            self, text=_("Your interpreter isn't in the list?"))
        another_label.grid(row=2,
                           column=0,
                           columnspan=2,
                           sticky=tk.W,
                           pady=(10, 0))

        ttk.Style().configure("Centered.TButton", justify="center")
        self._select_button = ttk.Button(
            self,
            style="Centered.TButton",
            text=_("Locate another") + " " +
            ("python.exe ..."
             if running_on_windows() else _("python executable") + " ...") +
            "\n" + _("NB! Thonny only supports Python 3.5 and later"),
            command=self._select_executable,
        )

        self._select_button.grid(row=3, column=0, columnspan=2, sticky=tk.NSEW)

        self._venv_button = ttk.Button(
            self,
            style="Centered.TButton",
            text=_("Create new virtual environment") + " ...\n" + "(" +
            _("Select existing or create a new empty directory") + ")",
            command=self._create_venv,
        )

        self._venv_button.grid(row=4,
                               column=0,
                               columnspan=2,
                               sticky=tk.NSEW,
                               pady=(5, 0))

        self.columnconfigure(0, weight=1)
        self.columnconfigure(1, weight=1)
コード例 #6
0
    def add_middle_menu_items(self):
        if self.supports_trash():
            if running_on_windows():
                trash_label = _("Move to Recycle Bin")
            else:
                trash_label = _("Move to Trash")
            self.menu.add_command(label=trash_label, command=self.move_to_trash)
        else:
            self.menu.add_command(label=_("Delete"), command=self.delete)

        if self.supports_directories():
            self.menu.add_command(label=_("New directory") + "...", command=self.mkdir)
コード例 #7
0
    def _select_executable(self):
        # TODO: get dir of current interpreter
        options = {"master": self}
        if running_on_windows():
            options["filetypes"] = [
                (_("Python interpreters"), "python.exe"),
                (_("all files"), ".*"),
            ]

        filename = askopenfilename(**options)

        if filename:
            self._configuration_variable.set(filename)
コード例 #8
0
    def split_path(self, path):
        parts = super().split_path(path)
        if running_on_windows() and path.startswith("\\\\"):
            # Don't split a network name!
            sep = self.get_dir_separator()
            for i in reversed(range(len(parts))):
                prefix = sep.join(parts[: i + 1])
                if os.path.ismount(prefix):
                    return [prefix] + parts[i + 1 :]

            # Could not find the prefix corresponding to mount
            return [path]
        else:
            return parts
コード例 #9
0
    def _create_venv(self):
        path = None
        while True:
            path = askdirectory(
                master=self,
                initialdir=path,
                title=_("Select empty directory for new virtual environment"),
            )
            if not path:
                return

            if os.listdir(path):
                messagebox.showerror(
                    _("Bad directory"),
                    _("Selected directory is not empty.\nSelect another or cancel."
                      ),
                )
            else:
                break
        assert os.path.isdir(path)
        path = normpath_with_actual_case(path)

        proc = subprocess.Popen(
            [running.get_interpreter_for_subprocess(), "-m", "venv", path],
            stdin=None,
            stdout=subprocess.PIPE,
            stderr=subprocess.STDOUT,
            universal_newlines=True,
        )
        dlg = SubprocessDialog(self, proc, _("Creating virtual environment"))
        ui_utils.show_dialog(dlg)

        if running_on_windows():
            exe_path = normpath_with_actual_case(
                os.path.join(path, "Scripts", "python.exe"))
        else:
            exe_path = os.path.join(path, "bin", "python3")

        if os.path.exists(exe_path):
            self._configuration_variable.set(exe_path)
コード例 #10
0
    def move_to_trash(self):
        assert self.supports_trash()

        selection = self.get_selection_info(True)
        if not selection:
            return

        trash = "Recycle Bin" if running_on_windows() else "Trash"
        if not messagebox.askokcancel(
            "Moving to %s" % trash,
            "I'll try to move %s to %s,\n" % (selection["description"], trash)
            + "but my method is not always reliable —\n"
            + "in some cases the files will be deleted\n"
            + "without the possibility to restore.",
            icon="info",
        ):
            return

        self.perform_move_to_trash(
            selection["paths"], _("Moving %s to %s") % (selection["description"], trash)
        )
        self.refresh_tree()
コード例 #11
0
    def request_focus_into(self, path):
        if path == "":
            if running_on_windows():
                # list of drives, can't cd
                return self.focus_into(path)
            else:
                path = "/"

        if not os.path.isdir(path):
            return

        proxy = get_runner().get_backend_proxy()
        if (
            proxy
            and proxy.uses_local_filesystem()
            and proxy.get_cwd() != path
            and get_runner().is_waiting_toplevel_command()
        ):
            get_shell().submit_magic_command(construct_cd_command(path))
        else:
            # it's OK, if it's already focused into this directory
            # focus again to refresh
            self.focus_into(path)
            get_workbench().set_local_cwd(path)
コード例 #12
0
    def _get_interpreters(self):
        result = set()

        if running_on_windows():
            # registry
            result.update(self._get_interpreters_from_windows_registry())

            for minor in [5, 6, 7, 8]:
                for dir_ in [
                        "C:\\Python3%d" % minor,
                        "C:\\Python3%d-32" % minor,
                        "C:\\Python3%d-64" % minor,
                        "C:\\Program Files\\Python 3.%d" % minor,
                        "C:\\Program Files\\Python 3.%d-64" % minor,
                        "C:\\Program Files (x86)\\Python 3.%d" % minor,
                        "C:\\Program Files (x86)\\Python 3.%d-32" % minor,
                ]:
                    path = os.path.join(dir_, WINDOWS_EXE)
                    if os.path.exists(path):
                        result.add(normpath_with_actual_case(path))

            # other locations
            for dir_ in ["C:\\Anaconda3", os.path.expanduser("~/Anaconda3")]:
                path = os.path.join(dir_, WINDOWS_EXE)
                if os.path.exists(path):
                    result.add(normpath_with_actual_case(path))

        else:
            # Common unix locations
            dirs = [
                "/bin", "/usr/bin", "/usr/local/bin",
                os.path.expanduser("~/.local/bin")
            ]
            for dir_ in dirs:
                # if the dir_ is just a link to another dir_, skip it
                # (not to show items twice)
                # for example on Fedora /bin -> usr/bin
                if not os.path.exists(dir_):
                    continue

                apath = normpath_with_actual_case(dir_)
                if apath != dir_ and apath in dirs:
                    continue
                for name in [
                        "python3", "python3.5", "python3.6", "python3.7",
                        "python3.8"
                ]:
                    path = os.path.join(dir_, name)
                    if os.path.exists(path):
                        result.add(path)

        if running_on_mac_os():
            for version in ["3.5", "3.6", "3.7", "3.8"]:
                dir_ = os.path.join(
                    "/Library/Frameworks/Python.framework/Versions", version,
                    "bin")
                path = os.path.join(dir_, "python3")

                if os.path.exists(path):
                    result.add(path)

        for command in [
                "python3", "python3.5", "python3.5", "python3.6", "python3.7",
                "python3.8"
        ]:
            path = which(command)
            if path is not None and os.path.isabs(path):
                result.add(path)

        for path in get_workbench().get_option("CustomInterpreter.used_paths"):
            if os.path.exists(path):
                result.add(normpath_with_actual_case(path))

        return sorted(result)
コード例 #13
0
def clean(
    frame_background: str,
    text_background: str,
    normal_detail: str,
    high_detail: str,
    low_detail: str,
    normal_foreground: str,
    high_foreground: str,
    low_foreground: str,
    custom_menubar: Optional[
        int] = None,  # NB! Should be 1 or 0, not True or False (Tk would convert False to "False")
) -> UiThemeSettings:

    # https://wiki.tcl.tk/37973 (Changing colors)
    # https://github.com/tcltk/tk/blob/master/library/ttk/clamTheme.tcl
    # https://github.com/tcltk/tk/blob/master/generic/ttk/ttkClamTheme.c

    return {
        ".": {
            "configure": {
                "foreground": normal_foreground,
                "background": frame_background,
                "lightcolor": frame_background,
                "darkcolor": frame_background,
                "bordercolor": frame_background,
                "selectbackground": high_detail,
                "selectforeground": high_foreground,
            },
            "map": {
                "foreground": [("disabled", low_foreground),
                               ("active", high_foreground)],
                "background": [("disabled", frame_background),
                               ("active", high_detail)],
                "selectbackground": [("!focus", low_detail)],
                "selectforeground": [("!focus", normal_foreground)],
            },
        },
        "TNotebook": {
            # https://github.com/tcltk/tk/blob/master/generic/ttk/ttkNotebook.c
            "configure": {
                "bordercolor": normal_detail,
                "tabmargins": [scale(1), 0, 0, 0],  # Margins around tab row
            }
        },
        "ButtonNotebook.TNotebook": {
            "configure": {
                "bordercolor": frame_background
            }
        },
        "AutomaticNotebook.TNotebook": {
            "configure": {
                "bordercolor": frame_background
            }
        },
        "TNotebook.Tab": {
            "configure": {
                "background": frame_background,
                "bordercolor": normal_detail
            },
            "map": {
                "background": [
                    ("selected", normal_detail),
                    ("!selected", "!active", frame_background),
                    ("active", "!selected", high_detail),
                ],
                "bordercolor": [("selected", frame_background),
                                ("!selected", normal_detail)],
                "lightcolor": [("selected", normal_detail),
                               ("!selected", frame_background)],
            },
        },
        "Treeview": {
            "configure": {
                "background": text_background,
                "borderwidth": 0,
                "relief": "flat"
            },
            "map": {
                "background": [
                    ("selected", "focus", high_detail),
                    ("selected", "!focus", low_detail),
                ],
                "foreground": [
                    ("selected", "focus", high_foreground),
                    ("selected", "!focus", normal_foreground),
                ],
            },
        },
        "Treeview.Heading": {
            # https://stackoverflow.com/questions/32051780/how-to-edit-the-style-of-a-heading-in-treeview-python-ttk
            "configure": {
                "background": normal_detail,
                "lightcolor": normal_detail,
                "borderwidth": 0,
            },
            "map": {
                "background": [("!active", normal_detail),
                               ("active", normal_detail)]
            },
        },
        "TEntry": {
            "configure": {
                "fieldbackground": text_background,
                "lightcolor": normal_detail,
                "insertcolor": normal_foreground,
            },
            "map": {
                "background": [("readonly", text_background)],
                "bordercolor": [],
                "lightcolor": [("focus", high_detail)],
                "darkcolor": [],
            },
        },
        "TCombobox": {
            "configure": {
                "background": text_background,
                "fieldbackground": text_background,
                "selectbackground": text_background,
                "lightcolor": text_background,
                "darkcolor": text_background,
                "bordercolor": text_background,
                "arrowcolor": normal_foreground,
                "foreground": normal_foreground,
                "seleftforeground": normal_foreground,
                # "padding" : [12,2,12,2],
            },
            "map": {
                "background": [("active", text_background)],
                "fieldbackground": [],
                "selectbackground": [],
                "selectforeground": [],
                "foreground": [],
                "arrowcolor": [],
            },
        },
        "TScrollbar": {
            "configure": {
                "gripcount": 0,
                "borderwidth": 0,
                "relief": "flat",
                "darkcolor": normal_detail,
                "lightcolor": normal_detail,
                "bordercolor": text_background,
                "troughcolor": text_background,
                # arrowcolor="white"
            },
            "map": {
                "background": [("!disabled", normal_detail),
                               ("disabled", normal_detail)],
                "darkcolor": [("!disabled", text_background),
                              ("disabled", text_background)],
                "lightcolor": [("!disabled", text_background),
                               ("disabled", text_background)],
            },
        },
        "Vertical.TScrollbar": {
            # Remove scrollbar buttons/arrows:
            "layout": [(
                "Vertical.Scrollbar.trough",
                {
                    "sticky":
                    "ns",
                    "children": [("Vertical.Scrollbar.thumb", {
                        "expand": "1",
                        "sticky": "nswe"
                    })],
                },
            )]
        },
        "Horizontal.TScrollbar": {
            # Remove scrollbar buttons/arrows:
            "layout": [(
                "Horizontal.Scrollbar.trough",
                {
                    "sticky":
                    "we",
                    "children": [("Horizontal.Scrollbar.thumb", {
                        "expand": "1",
                        "sticky": "nswe"
                    })],
                },
            )],
            "map": {
                # Make disabled Hor Scrollbar invisible
                "background": [("disabled", frame_background),
                               ("!disabled", normal_detail)],
                "troughcolor": [("disabled", frame_background)],
                "bordercolor": [("disabled", frame_background)],
                "darkcolor": [("disabled", frame_background)],
                "lightcolor": [("disabled", frame_background)],
            },
        },
        "TButton": {
            "configure": {
                "background": normal_detail,
                "foreground": normal_foreground
            },
            "map": {
                "foreground": [("disabled", low_foreground),
                               ("alternate", high_foreground)],
                "background": [("pressed", low_detail),
                               ("active", high_detail)],
                "bordercolor": [("alternate", high_detail)],
            },
        },
        "TCheckbutton": {
            "configure": {
                "indicatorforeground": normal_foreground,
                "indicatorbackground": text_background,
            },
            "map": {
                "indicatorforeground": [
                    ("disabled", "alternate", low_foreground),
                    ("disabled", low_foreground),
                ]
            },
        },
        "TRadiobutton": {
            "configure": {
                "indicatorforeground": normal_foreground,
                "indicatorbackground": text_background,
            },
            "map": {
                "indicatorforeground": [
                    ("disabled", "alternate", low_foreground),
                    ("disabled", low_foreground),
                ]
            },
        },
        "Toolbutton": {
            "configure": {
                "background": frame_background
            },
            "map": {
                "background": [("disabled", frame_background),
                               ("active", high_detail)]
            },
        },
        "TLabel": {
            "configure": {
                "foreground": normal_foreground
            }
        },
        "Url.TLabel": {
            "configure": {
                "foreground": high_foreground
            }
        },
        "TScale": {
            "configure": {
                "background": high_detail,
                "troughcolor": normal_detail,
                "lightcolor": high_detail,
                "darkcolor": high_detail,
                # "bordercolor" : "red",
                # "sliderlength" : 40,
                # "sliderthickness" : 60,
                "gripcount": 0,
            },
            "map": {
                "background": [],
                "troughcolor": []
            },
        },
        "TScale.slider": {
            "configure": {
                "background": "red",
                "troughcolor": "yellow",
                "lightcolor": "green",
                "darkcolor": "white",
                # "sliderlength" : 40,
                # "sliderthickness" : 60,
            }
        },
        "ViewBody.TFrame": {
            "configure": {
                "background": text_background
            }
        },
        "ViewToolbar.TFrame": {
            "configure": {
                "background": normal_detail
            }
        },
        "ViewToolbar.Toolbutton": {
            "configure": {
                "background": normal_detail
            }
        },
        "ViewTab.TLabel": {
            "configure": {
                "background": normal_detail,
                "padding": [5, 0]
            }
        },
        "ViewToolbar.TLabel": {
            "configure": {
                "background": normal_detail,
                "padding": [scale(4), 0]
            }
        },
        "Active.ViewTab.TLabel": {
            "configure": {
                "foreground": high_foreground,
                # "font" : "BoldTkDefaultFont",
                "background": text_background,
            }
        },
        "Inactive.ViewTab.TLabel": {
            "configure": {
                "foreground": normal_foreground,
                "font": "UnderlineTkDefaultFont"
            },
            "map": {
                "background": [("hover", high_detail)]
            },
        },
        "Text": {
            "configure": {
                "background": text_background,
                "foreground": normal_foreground
            }
        },
        "Gutter": {
            "configure": {
                "background": low_detail,
                "foreground": low_foreground
            }
        },
        "Listbox": {
            "configure": {
                "background": text_background,
                "foreground": normal_foreground,
                "selectbackground": high_detail,
                "selectforeground": high_foreground,
                "disabledforeground": low_foreground,
                "highlightbackground": normal_detail,
                "highlightcolor": high_detail,
                "highlightthickness": 1,
            }
        },
        "Menubar": {
            "configure": {
                # Regular, system-provided Windows menubar doesn't allow changing colors.
                # custom=True replaces it with a custom-built menubar.
                "custom": running_on_windows()
                if custom_menubar is None else custom_menubar,
                "background": frame_background,
                "foreground": normal_foreground,
                "activebackground": normal_foreground,
                "activeforeground": frame_background,
                "relief": "flat",
            }
        },
        "Menu": {
            "configure": {
                "background": normal_detail,
                "foreground": high_foreground,
                "selectcolor": normal_foreground,
                # "borderwidth": 0, # Interacts badly with right-clicks in Linux
                "activebackground": normal_foreground,
                "activeforeground": frame_background,
                # "activeborderwidth": 0, # Interacts badly with right-clicks in Linux
                "relief": "flat",
            }
        },
        "CustomMenubarLabel.TLabel": {
            "configure": {
                "padding": [scale(10), scale(2), 0,
                            scale(15)]
            }
        },
    }