def download(): selection = self.get_selection_info(True) if not selection: return response = get_runner().send_command_and_wait( InlineCommand( "prepare_download", source_paths=selection["paths"], description=tr("Downloading %s to %s") % (selection["description"], target_dir), ), dialog_title=tr("Preparing"), ) prepared_items = self._prepare_download_items( response["all_items"], self.get_active_directory(), target_dir) existing_target_items = self._get_existing_target_items( prepared_items) picked_items = pick_transfer_items(prepared_items, existing_target_items, self) if picked_items: response = get_runner().send_command_and_wait( InlineCommand("download", items=picked_items), dialog_title=tr("Copying")) _check_transfer_errors(response, self) self.master.local_files.refresh_tree()
def upload(paths, source_dir, target_dir, master) -> bool: items = [] for path in paths: for item in _prepare_upload_items(path, source_dir, target_dir): # same path could have been provided directly and also via its parent if item not in items: items.append(item) target_paths = [x["target_path"] for x in items] response = get_runner().send_command_and_wait( InlineCommand( "prepare_upload", target_paths=target_paths, ), dialog_title=tr("Preparing"), ) picked_items = list( sorted( pick_transfer_items(items, response["existing_items"], master), key=lambda x: x["target_path"], )) if picked_items: response = get_runner().send_command_and_wait(InlineCommand( "upload", items=picked_items), dialog_title="Copying") _check_transfer_errors(response, master) return True else: return False
def _load_remote_file(self, filename): self._filename = filename self.update_file_type() self._code_view.set_content("") self._code_view.text.set_read_only(True) target_filename = extract_target_path(self._filename) self.update_title() response = get_runner().send_command_and_wait( InlineCommand("read_file", path=target_filename, description=tr("Loading %s") % target_filename), dialog_title=tr("Loading"), ) if response.get("error"): # TODO: make it softer raise RuntimeError(response["error"]) content = response["content_bytes"] self._code_view.text.set_read_only(False) if not self._code_view.set_content_as_bytes(content): return False self.get_text_widget().edit_modified(False) self.update_title() return True
def _loop_tkupdate(self, force=False): if force or get_runner().get_state() == "waiting_toplevel_command": self.send_command(InlineCommand("tkupdate")) self._tkupdate_loop_id = get_workbench().after( 50, self._loop_tkupdate) else: self._tkupdate_loop_id = None
def write_remote_file(self, save_filename, content_bytes, save_copy): if get_runner().ready_for_remote_file_operations(show_message=True): target_filename = extract_target_path(save_filename) get_runner().send_command_and_wait( InlineCommand( "write_file", path=target_filename, content_bytes=content_bytes, editor_id=id(self), blocking=True, description=tr("Saving to %s") % target_filename, ), dialog_title=tr("Saving"), ) if not save_copy: self._code_view.text.edit_modified(False) self.update_title() # NB! edit_modified is not falsed yet! get_workbench().event_generate("RemoteFileOperation", path=target_filename, operation="save") get_workbench().event_generate("RemoteFilesChanged") return True else: return False
def _cmd_move_rename_file(self): editor = self.get_current_editor() old_filename = editor.get_filename() assert old_filename is not None if is_remote_path(old_filename): node = "remote" else: node = "local" self._cmd_save_file_as(node=node) if editor.get_filename() != old_filename: if is_remote_path(old_filename): remote_path = extract_target_path(old_filename) get_runner().send_command_and_wait( InlineCommand("delete", paths=[remote_path], description=tr("Deleting" + remote_path)), dialog_title=tr("Deleting"), ) get_workbench().event_generate("RemoteFileOperation", path=remote_path, operation="delete") else: os.remove(old_filename) get_workbench().event_generate("LocalFileOperation", path=old_filename, operation="delete")
def write_remote_file(self, save_filename, content_bytes, save_copy): if get_runner().can_do_file_operations(): target_filename = extract_target_path(save_filename) get_runner().send_command( InlineCommand( "write_file", path=target_filename, content_bytes=content_bytes, editor_id=id(self), blocking=True, description=_("Saving") + "...", )) if not save_copy: self._code_view.text.edit_modified(False) self.update_title() # NB! edit_modified is not falsed yet! get_workbench().event_generate("RemoteFileOperation", path=target_filename, operation="save") return True else: messagebox.showwarning("Can't save", "Device is busy, wait and try again!") return False
def handle_autocomplete_request(self): row, column = self._get_position() source = self.text.get("1.0", "end-1c") backend_code = dedent("""\ try: import jedi script = jedi.Script(source, row, column, filename) completions = [{"name":c.name, "complete":c.complete} for c in script.completions()] except ImportError: completions = [{"name":"", "complete":"<could not import jedi>"}] __result__ = { "source" : source, "row" : row, "column" : column, "filename" : filename, "completions" : completions } """) get_runner().send_command( InlineCommand(command="execute_source", source=backend_code, request_id=self._get_request_id(), global_vars={ "source": source, "row": row, "column": column, "filename": self._get_filename() }))
def perform_mkdir(self, parent_dir, name): path = (parent_dir + self.get_dir_separator() + name).replace( "//", "/") get_runner().send_command_and_wait( InlineCommand("mkdir", path=path), dialog_title=tr("Creating directory"), )
def upload(): selection = self.get_selection_info(True) if not selection: return if "dir" in selection[ "kinds"] and not proxy.supports_remote_directories(): messagebox.showerror( "Can't upload directory", "%s does not support directories.\n" % proxy.get_node_label() + "You can only upload files.", ) else: response = get_runner().send_command( InlineCommand( "upload", allow_overwrite=False, source_paths=selection["paths"], target_dir=target_dir, blocking=True, description=tr("Uploading %s to %s") % (selection["description"], target_dir), )) check_upload_download_response("upload", response) self.master.remote_files.refresh_tree()
def check_upload_download_response(command_name, command_response): if command_response and command_response.get("existing_files"): # command was not performed because overwriting existing files need confirmation existing = sorted(command_response["existing_files"][:25]) if len(command_response["existing_files"]) > 25: existing.append("...") user_response = messagebox.askokcancel( "Overwriting", "Some file(s) will be overwritten:\n\n" + " " + "\n ".join(existing), icon="info", ) if not user_response: return else: get_runner().send_command( InlineCommand( command_name, allow_overwrite=True, source_paths=command_response["source_paths"], target_dir=command_response["target_dir"], blocking=True, description=command_response["description"], ))
def _handle_toplevel_response(self, event): if "globals" in event: self.show_globals(event["globals"], "__main__") else: # MicroPython get_runner().send_command( InlineCommand("get_globals", module_name="__main__"))
def _load_remote_file(self, filename): self._filename = filename self._newlines = None self._code_view.set_content("") self._code_view.text.set_read_only(True) target_filename = extract_target_path(self._filename) self.update_title() response = get_runner().send_command( InlineCommand("read_file", path=target_filename, blocking=True, description=_("Loading") + "...")) if response.get("error"): # TODO: make it softer raise RuntimeError(response["error"]) content = response["content_bytes"] if content.count(b"\r\n") > content.count(b"\n") / 2: self._newlines = "\r\n" else: self._newlines = "\n" self._code_view.text.set_read_only(False) self._code_view.set_content_as_bytes(content) self.get_text_widget().edit_modified(False) self.update_title()
def open_custom_system_shell(self): from thonny import terminal get_runner().send_command_and_wait(InlineCommand("prepare_disconnect"), "Disconnecting") self.disconnect() terminal.run_in_terminal( [ running.get_interpreter_for_subprocess(sys.executable), "-m", # "serial.tools.miniterm", "thonny.plugins.micropython.miniterm_wrapper", "--exit-char", "20", "--menu-char", "29", "--filter", "direct", "--quiet", self._port, "115200", ], cwd=get_workbench().get_local_cwd(), keep_open=False, title=self._port, )
def request_object_info(self): # current width and height of the frame are required for # some content providers if self.active_page is not None: frame_width = self.active_page.winfo_width() frame_height = self.active_page.winfo_height() # in some cases measures are inaccurate if frame_width < 5 or frame_height < 5: frame_width = None frame_height = None # print("pa", frame_width, frame_height) else: frame_width = None frame_height = None get_runner().send_command( InlineCommand( "get_object_info", object_id=self.object_id, include_attributes=self.active_page == self.attributes_page, all_attributes=False, frame_width=frame_width, frame_height=frame_height, ) )
def _start_update_list(self, name_to_show=None): assert self._get_state() in [None, "idle"] self._set_state("listing") get_workbench().bind("get_active_distributions_response", self._complete_update_list, True) self._last_name_to_show = name_to_show get_runner().send_command(InlineCommand("get_active_distributions"))
def __init__(self, master): VariablesFrame.__init__(self, master) get_workbench().bind("Globals", self._handle_globals_event, True) get_workbench().bind("DebuggerProgress", self._request_globals, True) get_workbench().bind("ToplevelResult", self._request_globals, True) get_runner().send_command( InlineCommand("get_globals", module_name="__main__"))
def _advance_background_tk_mainloop(self): """Enables running Tkinter programs which doesn't call mainloop. When mainloop is omitted, then program can be interacted with from the shell after it runs to the end. """ if self._proxy.get_state() == "waiting_toplevel_command": self._proxy.send_command(InlineCommand("tkupdate")) get_workbench().after(50, self._advance_background_tk_mainloop)
def download(): get_runner().send_command( InlineCommand( "download", source_paths=paths, target_dir=target_dir, blocking=True, description=label, ))
def handle_frame_click(event, frame_id=frame_id, filename=filename, lineno=lineno): get_runner().send_command( InlineCommand("get_frame_info", frame_id=frame_id)) if os.path.exists(filename): get_workbench().get_editor_notebook().show_file( filename, lineno, set_focus=False)
def handle_autocomplete_request(self): row, column = self._get_position() source = self.text.get("1.0", "end-1c") get_runner().send_command( InlineCommand(command="editor_autocomplete", source=source, row=row, column=column, filename=self._get_filename()))
def request_dirs_child_data(self, node_id, paths): if get_runner(): get_runner().send_command( InlineCommand( "get_dirs_children_info", node_id=node_id, paths=paths, include_hidden=show_hidden_files(), ))
def _start_show_module_info(self, name): self._clear_info_text() self.command_frame.grid_remove() self.title_label["text"] = tr("Module") + (" '%s'" % name) self.title_label.grid() self._set_state("fetching") self.advanced_button.grid_remove() get_workbench().bind("get_module_info_response", self._complete_display_module_info, True) get_runner().send_command(InlineCommand("get_module_info", module_name=name))
def _loop_gui_update(self, force=False): if force or get_runner().is_waiting_toplevel_command(): try: self.send_command(InlineCommand("process_gui_events")) except OSError: # the backend process may have been closed already # https://github.com/thonny/thonny/issues/966 logging.getLogger("thonny").exception("Could not send process_gui_events") self._gui_update_loop_id = get_workbench().after(50, self._loop_gui_update)
def request_calltip_for_text(self, text: SyntaxText) -> None: source, row, column = editor_helpers.get_relevant_source_and_cursor_position(text) get_runner().send_command( InlineCommand( "get_shell_calltip" if isinstance(text, ShellText) else "get_editor_calltip", row=row, column=column, source=source, filename=get_text_filename(text), ) )
def __init__(self, master, paths, description, target_dir): self._stage = "preparation" self._target_dir = target_dir cmd = InlineCommand( "prepare_download", source_paths=paths, description=tr("Downloading %s to %s") % (description, target_dir), ) super(DownloadDialog, self).__init__(master, cmd, "Downloading")
def _start_loading_remote_file(self, filename): self._loading = True self._filename = filename self._newlines = None self._code_view.set_content("") self._code_view.text.set_read_only(True) target_filename = extract_target_path(self._filename) get_runner().send_command(InlineCommand("read_file", path=target_filename)) self.update_title()
def request_completions_for_text(self, text: SyntaxText) -> None: source, row, column = editor_helpers.get_relevant_source_and_cursor_position(text) get_runner().send_command( InlineCommand( "shell_autocomplete" if isinstance(text, ShellText) else "editor_autocomplete", source=source, row=row, column=column, filename=editor_helpers.get_text_filename(text), ) )
def _confirm_and_start_main_work(self, preparation_response): prepared_items = self._prepare_download_items( preparation_response["all_items"], self._target_dir) existing_target_items = self._get_existing_target_items(prepared_items) picked_items = pick_transfer_items(prepared_items, existing_target_items, self) if picked_items: self._cmd = InlineCommand("download", items=picked_items) get_runner().send_command(self._cmd) return True else: return False
def _confirm_and_start_main_work(self, preparation_response): picked_items = list( sorted( pick_transfer_items(self.items, preparation_response["existing_items"], self), key=lambda x: x["target_path"], ) ) if picked_items: self._cmd = InlineCommand("upload", items=picked_items) get_runner().send_command(self._cmd) return True else: return False