From 2930bdb0812f69f0098aa6b6a78b73ad6adec5fc Mon Sep 17 00:00:00 2001 From: Jason Ross Date: Thu, 21 Aug 2025 14:05:53 -0500 Subject: [PATCH] Removed text boxes for paths to prevent accidental incorrect path entry --- src/gui/file_browser.py | 47 +++++++++++++++++++++---------- src/gui/main_window.py | 61 +++++++++++++++++++++++------------------ 2 files changed, 67 insertions(+), 41 deletions(-) diff --git a/src/gui/file_browser.py b/src/gui/file_browser.py index 708bb74..0d1041e 100644 --- a/src/gui/file_browser.py +++ b/src/gui/file_browser.py @@ -16,8 +16,12 @@ class AndroidFileBrowser: self.adb_manager = adb_manager self.remote_path_var = remote_path_var - def show_browser(self): - """Show a browsable Android folder tree for Windows users.""" + def show_browser(self, direction="pull"): + """Show a browsable Android folder tree. + + Args: + direction: "pull" to show files and folders, "push" to show folders only + """ # Check if device is connected device = self.adb_manager.check_device() if not device: @@ -29,14 +33,20 @@ class AndroidFileBrowser: # Create browsable folder dialog browser_window = tk.Toplevel(self.parent) - browser_window.title("Browse Android Files and Folders") + if direction == "push": + browser_window.title("Browse Android Folders (Destination)") + label_text = "Browse Android device folders (select destination):" + else: + browser_window.title("Browse Android Files and Folders") + label_text = "Browse Android device files and folders:" + browser_window.geometry("500x400") browser_window.transient(self.parent) browser_window.grab_set() tk.Label( browser_window, - text="Browse Android device files and folders:", + text=label_text, font=("Arial", 10, "bold"), ).pack(pady=10) @@ -174,8 +184,8 @@ class AndroidFileBrowser: and not folder_name.startswith(".") ): folders.append(folder_name) - elif line.startswith("-"): - # Regular file entry + elif line.startswith("-") and direction != "push": + # Regular file entry - only show files if not in push mode parts = line.split() if len(parts) >= 8: # Extract file name using same method as folders @@ -220,8 +230,8 @@ class AndroidFileBrowser: # Add a dummy child to make it expandable tree.insert(item, "end", text="Loading...") - # Add files to tree (sorted) - if files: + # Add files to tree (sorted) - only if not in push mode + if files and direction != "push": for file in sorted(files): file_path = f"{path.rstrip('/')}/{file}" tree.insert( @@ -232,9 +242,10 @@ class AndroidFileBrowser: ) # If no folders or files found, show indicator - if not folders and not files: + if not folders and (not files or direction == "push"): + empty_text = "(No Folders)" if direction == "push" else "(Empty Directory)" tree.insert( - parent_item, "end", text="(Empty Directory)", values=["", ""] + parent_item, "end", text=empty_text, values=["", ""] ) self.parent.after(0, update_tree) @@ -451,10 +462,15 @@ class AndroidFileBrowser: item_path = item_values[0] # Check if it's a file or folder (if we have type info) if len(item_values) >= 2 and item_values[1] == "file": - # It's a file - select the file path directly - self.remote_path_var.set(item_path) - browser_window.destroy() - return + if direction == "push": + # In push mode, don't allow file selection + messagebox.showwarning("Invalid Selection", "Please select a folder as the destination.") + return + else: + # It's a file and we're in pull mode - select the file path directly + self.remote_path_var.set(item_path) + browser_window.destroy() + return elif len(item_values) >= 2 and item_values[1] == "folder": # It's a folder - select the folder path directly self.remote_path_var.set(item_path) @@ -467,7 +483,8 @@ class AndroidFileBrowser: self.remote_path_var.set(current_path) browser_window.destroy() else: - messagebox.showwarning("No Selection", "Please select a file or folder.") + selection_type = "folder" if direction == "push" else "file or folder" + messagebox.showwarning("No Selection", f"Please select a {selection_type}.") tk.Button( button_frame, text="Select", command=select_current_item diff --git a/src/gui/main_window.py b/src/gui/main_window.py index 418c7ac..72253f5 100644 --- a/src/gui/main_window.py +++ b/src/gui/main_window.py @@ -101,11 +101,13 @@ class AndroidFileHandlerGUI(tk.Tk): android_path_frame = tk.Frame(self.android_frame) android_path_frame.pack(fill="x", pady=(0, 10)) - self.remote_path_var = tk.StringVar() - self.remote_path_entry = tk.Entry( - android_path_frame, textvariable=self.remote_path_var, width=50 + self.remote_path_var = tk.StringVar(value="Please select file or folder ->") + self.remote_path_display = tk.Label( + android_path_frame, + textvariable=self.remote_path_var, + anchor="w" ) - self.remote_path_entry.pack(side="left", fill="x", expand=True) + self.remote_path_display.pack(side="left", fill="x", expand=True) tk.Button( android_path_frame, text="Browse...", command=self.browse_remote_folder ).pack(side="right", padx=(5, 0)) @@ -117,11 +119,13 @@ class AndroidFileHandlerGUI(tk.Tk): computer_path_frame = tk.Frame(self.computer_frame) computer_path_frame.pack(fill="x", pady=(0, 10)) - self.local_path_var = tk.StringVar() - self.local_path_entry = tk.Entry( - computer_path_frame, textvariable=self.local_path_var, width=50 + self.local_path_var = tk.StringVar(value="Please select file or folder ->") + self.local_path_display = tk.Label( + computer_path_frame, + textvariable=self.local_path_var, + anchor="w" ) - self.local_path_entry.pack(side="left", fill="x", expand=True) + self.local_path_display.pack(side="left", fill="x", expand=True) tk.Button( computer_path_frame, text="Browse...", command=self.browse_local_folder ).pack(side="right", padx=(5, 0)) @@ -244,51 +248,56 @@ class AndroidFileHandlerGUI(tk.Tk): def browse_remote_folder(self): """Browse remote Android files and folders.""" - self.browser.show_browser() + # Pass the current direction to the browser + direction = self.direction_var.get() + self.browser.show_browser(direction) def browse_local_folder(self): """Browse for local folder or file based on direction.""" + import tkinter.filedialog as fd + import os + direction = self.direction_var.get() + # Set initial directory to user's home directory + initial_dir = os.path.expanduser("~") + if direction == "push": - # For push, show a unified dialog that handles both files and folders - # Start with file selection dialog that has "Open" and "Cancel" - # If user selects a file, use it. If they navigate and click "Cancel" on file dialog, - # we'll assume they want to select the current folder + # For push, show file selection first, then folder selection if cancelled - import tkinter.filedialog as fd - import os - - # Use askopenfilename but allow folder selection by providing both options # First try file selection selected_path = fd.askopenfilename( - title="Select file to push (or Cancel and then select folder)", + title="Select file to push to Android device", + initialdir=initial_dir, filetypes=[("All files", "*.*")] ) - # If no file was selected, offer folder selection + # If no file was selected, offer folder selection as an alternative if not selected_path: selected_path = fd.askdirectory( - title="Select folder to push to Android device" + title="Select folder to push to Android device", + initialdir=initial_dir ) - # Set the path if something was selected + # Only set the path if something was actually selected + # If user cancels both dialogs, selected_path will be empty and nothing happens if selected_path: self.local_path_var.set(selected_path) else: # pull direction # For pull, only allow folder selection (destination) folder = filedialog.askdirectory( - title="Select destination folder for pulled files" + title="Select destination folder for pulled files", + initialdir=initial_dir ) if folder: self.local_path_var.set(folder) def disable_controls(self): """Disable UI controls during operations.""" - self.remote_path_entry.config(state="disabled") - self.local_path_entry.config(state="disabled") + # Path displays are already read-only (Labels), no need to disable them # Don't disable start_btn here - it will be handled by button mode switching + pass def enable_controls(self): """Enable UI controls after operations (thread-safe).""" @@ -297,9 +306,9 @@ class AndroidFileHandlerGUI(tk.Tk): def _enable_controls_ui(self): """Internal method to enable controls on main thread.""" - self.remote_path_entry.config(state="normal") - self.local_path_entry.config(state="normal") + # Path displays are already read-only (Labels), no need to enable them # Button state is handled by mode switching methods + pass def _on_direction_change(self): """Handle radio button direction change."""