Skip to content

Commit

Permalink
Move back-end package management to view, WIP #3151
Browse files Browse the repository at this point in the history
  • Loading branch information
aivarannamaa committed Mar 31, 2024
1 parent 4cc0062 commit 3fb5623
Showing 1 changed file with 66 additions and 59 deletions.
125 changes: 66 additions & 59 deletions thonny/plugins/pip_gui.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
_EXTRA_MARKER_RE = re.compile(r"""^.*\bextra\s*==.+$""")


class PipDialog(CommonDialog, ABC):
class PipFrame(ttk.Frame, ABC):
def __init__(self, master):
self._state = "idle" # possible values: "listing", "fetching", "idle"
self._process = None
Expand All @@ -55,19 +55,10 @@ def __init__(self, master):

super().__init__(master)

main_frame = ttk.Frame(self)
main_frame.grid(sticky=tk.NSEW, ipadx=self.get_medium_padding())
self.rowconfigure(0, weight=1)
self.columnconfigure(0, weight=1)

self.title(self._get_title())

self._create_widgets(main_frame)
self._create_widgets(self)

self.search_box.focus_set()

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

self._start_update_list()
Expand Down Expand Up @@ -156,6 +147,7 @@ def _create_widgets(self, parent):
self.listbox["yscrollcommand"] = list_scrollbar.set

info_frame = ttk.Frame(main_pw)
self.info_frame = info_frame
info_frame.columnconfigure(0, weight=1)
info_frame.rowconfigure(1, weight=1)

Expand Down Expand Up @@ -252,9 +244,6 @@ def _create_widgets(self, parent):

self.advanced_button.grid(row=0, column=2, sticky="w", padx=(self.get_small_padding(), 0))

self.close_button = ttk.Button(info_frame, text=tr("Close"), command=self._on_close)
self.close_button.grid(row=2, column=3, sticky="e")

def _set_state(self, state, force_normal_cursor=False):
self._state = state
action_buttons = [
Expand Down Expand Up @@ -822,10 +811,6 @@ def _handle_url_click(self, event):
else:
self._start_show_package_info(url)

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

def _get_active_version(self, name):
dist = self._get_active_dist(name)
if dist is None:
Expand Down Expand Up @@ -858,9 +843,6 @@ def _installer_runs_locally(self):
def _get_target_directory(self):
raise NotImplementedError()

def _get_title(self):
return tr("Manage packages for %s") % self._get_interpreter_description()

def _confirm_install(self, package_data):
return True

Expand All @@ -882,8 +864,17 @@ def _advertise_pipkin(self):
self._append_info_text("https://pypi.org/project/pipkin/", ("url", "right"))
self._append_info_text(" for more info. \n", ("right",))

def get_large_padding(self):
return ems_to_pixels(1.5)

def get_medium_padding(self):
return ems_to_pixels(1)

def get_small_padding(self):
return ems_to_pixels(0.6)


class BackendPipDialog(PipDialog):
class BackendPipFrame(PipFrame):
def __init__(self, master):
self._backend_proxy = get_runner().get_backend_proxy()
super().__init__(master)
Expand Down Expand Up @@ -994,10 +985,9 @@ def get_search_button_text(self):
return self._backend_proxy.get_search_button_text()


class PluginsPipDialog(PipDialog):
class PluginsPipFrame(PipFrame):
def __init__(self, master):
PipDialog.__init__(self, master)

super().__init__(master)
# make sure directory exists, so user can put her plug-ins there
d = self._get_target_directory()
makedirs(d, exist_ok=True)
Expand Down Expand Up @@ -1123,30 +1113,6 @@ def _get_target_directory(self):
def _normalize_target_path(self, path: str) -> str:
return normpath_with_actual_case(path)

def _create_widgets(self, parent):
banner = ttk.Frame(parent, style="Tip.TFrame")
banner.grid(row=0, column=0, sticky="nsew")

banner_msg = (
tr(
"This dialog is for managing Thonny plug-ins and their dependencies.\n"
+ "If you want to install packages for your own programs then choose 'Tools → Manage packages...'"
)
+ "\n"
)

banner_msg += "\n" + tr(
"NB! You need to restart Thonny after installing / upgrading / uninstalling a plug-in."
)

banner_text = ttk.Label(banner, text=banner_msg, style="Tip.TLabel", justify="left")
banner_text.grid(pady=self.get_medium_padding(), padx=self.get_medium_padding())

PipDialog._create_widgets(self, parent)

def _get_title(self):
return tr("Thonny plug-ins")

def _run_pip_with_dialog(self, command: str, args: Dict, title: str) -> Tuple[int, str, str]:
cmd = ["-m", "pip", "--disable-pip-version-check", "--no-color", command]
if command == "install":
Expand All @@ -1173,6 +1139,54 @@ def _fetch_search_results(self, query: str) -> List[Dict[str, str]]:
return perform_pypi_search(query)


class PluginsPipDialog(CommonDialog):
def __init__(self, master):
super().__init__(master)

banner = ttk.Frame(self, style="Tip.TFrame")
banner.grid(row=0, column=0, sticky="nsew")

banner_msg = (
tr(
"This dialog is for managing Thonny plug-ins and their dependencies.\n"
+ "If you want to install packages for your own programs then choose 'Tools → Manage packages...'"
)
+ "\n"
)

banner_msg += "\n" + tr(
"NB! You need to restart Thonny after installing / upgrading / uninstalling a plug-in."
)

banner_text = ttk.Label(banner, text=banner_msg, style="Tip.TLabel", justify="left")
banner_text.grid(pady=self.get_medium_padding(), padx=self.get_medium_padding())

banner.grid(row=0, column=0)

pip_frame = PluginsPipFrame(self)
pip_frame.grid(row=1, sticky=tk.NSEW, ipadx=self.get_medium_padding())
self.rowconfigure(0, weight=1)
self.columnconfigure(0, weight=1)

self.close_button = ttk.Button(
pip_frame.info_frame, text=tr("Close"), command=self._on_close
)
self.close_button.grid(row=2, column=3, sticky="e")

self.title(tr("Thonny plug-ins"))

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

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


class PackagesView(PipFrame):
pass


def _fetch_url_future(url, fallback_url=None, timeout=10):
from urllib.request import urlopen

Expand Down Expand Up @@ -1316,21 +1330,14 @@ def _extract_click_text(widget, event, tag):

def load_plugin() -> None:
def open_backend_pip_gui(*args):
if not get_runner().is_waiting_toplevel_command():
showerror(
tr("Not available"),
tr("You need to stop your program before launching the package manager."),
master=get_workbench(),
)
return

pg = BackendPipDialog(get_workbench())
ui_utils.show_dialog(pg)
get_workbench().show_view("PackagesView")

def open_plugins_pip_gui(*args):
pg = PluginsPipDialog(get_workbench())
ui_utils.show_dialog(pg)

get_workbench().add_view(BackendPipFrame, tr("Packages"), "s")

get_workbench().add_command(
"backendpipgui",
"tools",
Expand Down

0 comments on commit 3fb5623

Please sign in to comment.