diff --git a/rdp_client.py b/rdp_client.py index d2ac7aa..c192641 100755 --- a/rdp_client.py +++ b/rdp_client.py @@ -366,33 +366,16 @@ class RDPClient: left_frame = ttk.Frame(main_frame) left_frame.grid(row=1, column=0, sticky=(tk.W, tk.E, tk.N, tk.S), padx=(0, 10)) left_frame.rowconfigure(1, weight=1) - left_frame.rowconfigure(3, weight=1) + left_frame.rowconfigure(1, weight=1) # Only saved connections now left_frame.columnconfigure(0, weight=1) - # Recent Connections - recent_label = ttk.Label(left_frame, text="Recent Connections", font=('Arial', 10, 'bold')) - recent_label.grid(row=0, column=0, sticky=tk.W, pady=(0, 5)) - - # Recent connections frame with listbox and scrollbar - recent_frame = ttk.Frame(left_frame) - recent_frame.grid(row=1, column=0, sticky=(tk.W, tk.E, tk.N, tk.S), pady=(0, 10)) - recent_frame.rowconfigure(0, weight=1) - recent_frame.columnconfigure(0, weight=1) - - self.recent_listbox = tk.Listbox(recent_frame, font=('Arial', 9), height=6, width=30) - recent_scrollbar = ttk.Scrollbar(recent_frame, orient="vertical", command=self.recent_listbox.yview) - self.recent_listbox.configure(yscrollcommand=recent_scrollbar.set) - - self.recent_listbox.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S)) - recent_scrollbar.grid(row=0, column=1, sticky=(tk.N, tk.S)) - - # Saved Connections + # Saved Connections (now the main/only connections list) saved_label = ttk.Label(left_frame, text="Saved Connections", font=('Arial', 10, 'bold')) - saved_label.grid(row=2, column=0, sticky=tk.W, pady=(10, 5)) + saved_label.grid(row=0, column=0, sticky=tk.W, pady=(0, 5)) # Saved connections frame with listbox and scrollbar saved_frame = ttk.Frame(left_frame) - saved_frame.grid(row=3, column=0, sticky=(tk.W, tk.E, tk.N, tk.S)) + saved_frame.grid(row=1, column=0, sticky=(tk.W, tk.E, tk.N, tk.S)) saved_frame.rowconfigure(0, weight=1) saved_frame.columnconfigure(0, weight=1) @@ -405,7 +388,7 @@ class RDPClient: # Connection buttons conn_buttons_frame = ttk.Frame(left_frame) - conn_buttons_frame.grid(row=4, column=0, pady=(10, 0), sticky=(tk.W, tk.E)) + conn_buttons_frame.grid(row=2, column=0, pady=(10, 0), sticky=(tk.W, tk.E)) ttk.Button(conn_buttons_frame, text="Connect", command=self._connect_selected).pack(side=tk.LEFT, padx=(0, 5)) @@ -465,8 +448,6 @@ class RDPClient: # Bind listbox selection self.connections_listbox.bind('<>', self._on_connection_select) self.connections_listbox.bind('', self._connect_selected) - self.recent_listbox.bind('<>', self._on_recent_select) - self.recent_listbox.bind('', self._connect_recent) # Keyboard shortcuts self._setup_keyboard_shortcuts() @@ -503,55 +484,16 @@ class RDPClient: self.connections_listbox.bind('', lambda e: self._edit_selected()) self.connections_listbox.bind('', lambda e: self._test_selected_connection()) - self.recent_listbox.bind('', lambda e: self._connect_selected()) - self.recent_listbox.bind('', lambda e: self._delete_selected()) - self.recent_listbox.bind('', lambda e: self._edit_selected()) - self.recent_listbox.bind('', lambda e: self._test_selected_connection()) - - # Set focus handling - self.root.bind('', self._handle_tab_focus) - self.root.bind('', self._handle_shift_tab_focus) + # Set initial focus + self.connections_listbox.focus_set() + if self.connections_listbox.size() > 0: + self.connections_listbox.selection_set(0) # Add tooltip information for shortcuts self._add_keyboard_shortcuts_info() - def _handle_tab_focus(self, event): - """Handle Tab key for focus navigation""" - current_focus = self.root.focus_get() - - if current_focus == self.recent_listbox: - self.connections_listbox.focus_set() - if self.connections_listbox.size() > 0: - self.connections_listbox.selection_set(0) - elif current_focus == self.connections_listbox: - self.recent_listbox.focus_set() - if self.recent_listbox.size() > 0: - self.recent_listbox.selection_set(0) - else: - self.recent_listbox.focus_set() - if self.recent_listbox.size() > 0: - self.recent_listbox.selection_set(0) - - return "break" # Prevent default Tab behavior - - def _handle_shift_tab_focus(self, event): - """Handle Shift+Tab key for reverse focus navigation""" - current_focus = self.root.focus_get() - - if current_focus == self.connections_listbox: - self.recent_listbox.focus_set() - if self.recent_listbox.size() > 0: - self.recent_listbox.selection_set(0) - elif current_focus == self.recent_listbox: - self.connections_listbox.focus_set() - if self.connections_listbox.size() > 0: - self.connections_listbox.selection_set(0) - else: - self.connections_listbox.focus_set() - if self.connections_listbox.size() > 0: - self.connections_listbox.selection_set(0) - - return "break" # Prevent default Shift+Tab behavior + # Add tooltip information for shortcuts + self._add_keyboard_shortcuts_info() def _add_keyboard_shortcuts_info(self): """Add keyboard shortcuts information to the status bar or help""" @@ -563,11 +505,9 @@ class RDPClient: def clear_shortcuts_hint(event): self.status_var.set("Ready") - # Show shortcuts hint when certain widgets get focus + # Show shortcuts hint when connections listbox gets focus self.connections_listbox.bind('', show_shortcuts_hint) - self.recent_listbox.bind('', show_shortcuts_hint) self.connections_listbox.bind('', clear_shortcuts_hint) - self.recent_listbox.bind('', clear_shortcuts_hint) def _show_help(self): """Show keyboard shortcuts help dialog""" @@ -588,15 +528,12 @@ Connection List Shortcuts: • Double-click - Connect to selected connection • Delete - Delete selected connection • F2 - Edit selected connection -• Tab - Switch between Recent and Saved connections Navigation: -• Tab - Move between Recent and Saved connections -• Shift+Tab - Move between connections (reverse) -• Arrow keys - Navigate within lists +• Arrow keys - Navigate within connections list Tips: -• Recent connections show usage count (e.g., "Server (5x)") +• Connections are sorted alphabetically by name • Double-click any connection to connect quickly • Use Test Connection to verify server availability • Import/Export to backup or share connection profiles @@ -612,50 +549,17 @@ Multi-Monitor Support: messagebox.showinfo("Keyboard Shortcuts", help_text) def _refresh_connections_list(self): - """Refresh the connections listbox""" + """Refresh the connections listbox with sorted saved connections""" self.connections_listbox.delete(0, tk.END) - for name in sorted(self.connections.keys()): + # Sort connections by name (case-insensitive) + for name in sorted(self.connections.keys(), key=str.lower): self.connections_listbox.insert(tk.END, name) - # Refresh recent connections - self.recent_listbox.delete(0, tk.END) - for entry in self.history[:10]: # Show last 10 recent connections - name = entry.get('name', '') - count = entry.get('count', 0) - if name in self.connections: # Only show if connection still exists - display_text = f"{name} ({count}x)" - self.recent_listbox.insert(tk.END, display_text) - # Clear details if no connections if not self.connections: for label in self.details_labels.values(): label.config(text="") - def _on_recent_select(self, event=None): - """Handle recent connection selection""" - selection = self.recent_listbox.curselection() - if selection: - display_text = self.recent_listbox.get(selection[0]) - # Extract connection name (everything before " (") - name = display_text.split(' (')[0] - if name in self.connections: - # Clear saved connections selection - self.connections_listbox.selection_clear(0, tk.END) - # Update details - conn = self.connections[name] - self._update_details(conn) - - def _connect_recent(self, event=None): - """Connect to selected recent connection""" - selection = self.recent_listbox.curselection() - if not selection: - return - - display_text = self.recent_listbox.get(selection[0]) - name = display_text.split(' (')[0] - if name in self.connections: - self._connect_to(name) - def _update_details(self, conn): """Update the details panel with connection info""" self.details_labels["server"].config(text=conn.get("server", "")) @@ -676,8 +580,6 @@ Multi-Monitor Support: name = self.connections_listbox.get(selection[0]) conn = self.connections[name] - # Clear recent connections selection - self.recent_listbox.selection_clear(0, tk.END) # Update details self._update_details(conn) @@ -706,7 +608,7 @@ Multi-Monitor Support: self.credentials[name]["password"] = self._encrypt_password(dialog.result["password"]) self._save_credentials() - # Add new connection to history so it appears in recent connections + # Add new connection to history self._add_to_history(name) self._refresh_connections_list() @@ -714,16 +616,12 @@ Multi-Monitor Support: def _edit_selected(self): """Edit selected connection""" - # Check which listbox has a selection + # Check saved connections selection saved_selection = self.connections_listbox.curselection() - recent_selection = self.recent_listbox.curselection() name = None if saved_selection: name = self.connections_listbox.get(saved_selection[0]) - elif recent_selection: - display_text = self.recent_listbox.get(recent_selection[0]) - name = display_text.split(' (')[0] if not name: messagebox.showwarning("No Selection", "Please select a connection to edit.") @@ -782,16 +680,12 @@ Multi-Monitor Support: def _delete_selected(self): """Delete selected connection""" - # Check which listbox has a selection + # Check saved connections selection saved_selection = self.connections_listbox.curselection() - recent_selection = self.recent_listbox.curselection() name = None if saved_selection: name = self.connections_listbox.get(saved_selection[0]) - elif recent_selection: - display_text = self.recent_listbox.get(recent_selection[0]) - name = display_text.split(' (')[0] if not name: messagebox.showwarning("No Selection", "Please select a connection to delete.") @@ -817,18 +711,12 @@ Multi-Monitor Support: def _connect_selected(self, event=None): """Connect to selected connection""" - # Check which listbox has a selection + # Check saved connections selection saved_selection = self.connections_listbox.curselection() - recent_selection = self.recent_listbox.curselection() if saved_selection: name = self.connections_listbox.get(saved_selection[0]) self._connect_to(name) - elif recent_selection: - display_text = self.recent_listbox.get(recent_selection[0]) - name = display_text.split(' (')[0] - if name in self.connections: - self._connect_to(name) else: messagebox.showwarning("No Selection", "Please select a connection to connect.") @@ -853,7 +741,7 @@ Multi-Monitor Support: # Build and execute RDP command self._add_to_history(name) self._execute_rdp_connection(conn, password) - self._refresh_connections_list() # Refresh to update recent connections + self._refresh_connections_list() # Refresh connections list def _execute_rdp_connection(self, conn, password): """Execute the RDP connection in a separate thread""" @@ -1225,16 +1113,12 @@ Multi-Monitor Support: def _test_selected_connection(self): """Test the selected connection for reachability""" - # Check which listbox has a selection + # Check saved connections selection saved_selection = self.connections_listbox.curselection() - recent_selection = self.recent_listbox.curselection() name = None if saved_selection: name = self.connections_listbox.get(saved_selection[0]) - elif recent_selection: - display_text = self.recent_listbox.get(recent_selection[0]) - name = display_text.split(' (')[0] if not name: messagebox.showwarning("No Selection", "Please select a connection to test.")