Untitled

 avatar
unknown
plain_text
5 months ago
14 kB
3
Indexable
class TouchKeyboard(ctk.CTkFrame):
    def __init__(self, parent, entry_widget, dark_mode=False):
        super().__init__(parent)
        self.entry_widget = entry_widget
        self.dark_mode = dark_mode
        self.shift_mode = False
        self.special_chars_mode = False
        
        # Define keyboard layouts
        self.normal_layout = [
            "1234567890",
            "qwertzuiop",
            "asdfghjkl",
            "yxcvbnm",
        ]
        
        self.shift_layout = [
            "1234567890",
            "QWERTZUIOP",
            "ASDFGHJKL",
            "YXCVBNM",
        ]
        
        self.special_layout = [
            "!@#$%^&*()",
            "äöüß-_+:;",
            ",.<>/?\'\"",
            "\\|[]{}",
        ]
        
        # Current layout starts with normal
        self.current_layout = self.normal_layout
        
        # Button styling
        self.button_style = {
            "height": 45,
            "corner_radius": 8,
            "fg_color": '#2c2c2e' if dark_mode else '#e5e5e7',
            "hover_color": '#3a3a3c' if dark_mode else '#d1d1d6',
            "text_color": 'white' if dark_mode else 'black',
            "font": ("Helvetica", 16)
        }
        
        self.create_keyboard()
        
    def create_keyboard(self):
        # Main keyboard container with padding
        keyboard_container = ctk.CTkFrame(self, fg_color="transparent")
        keyboard_container.pack(padx=20, pady=20)
        
        # Create rows for each line of keys
        for row in self.current_layout:
            row_frame = ctk.CTkFrame(keyboard_container, fg_color="transparent")
            row_frame.pack(pady=4)
            
            # Calculate button width based on row length
            button_width = min(55, 460 // len(row))
            
            for char in row:
                btn = ctk.CTkButton(
                    row_frame,
                    text=char,
                    width=button_width,
                    command=lambda c=char: self.button_click(c),
                    **self.button_style
                )
                btn.pack(side="left", padx=2)
        
        # Create bottom row with special keys
        bottom_frame = ctk.CTkFrame(keyboard_container, fg_color="transparent")
        bottom_frame.pack(pady=4)
        
        # Special characters toggle
        special_btn = ctk.CTkButton(
            bottom_frame,
            text="!#$",
            width=70,
            command=self.toggle_special,
            **self.button_style
        )
        special_btn.pack(side="left", padx=2)
        
        # Shift key
        self.shift_btn = ctk.CTkButton(
            bottom_frame,
            text="⇧",
            width=70,
            command=self.toggle_shift,
            **self.button_style
        )
        self.shift_btn.pack(side="left", padx=2)
        
        # Space bar
        space_btn = ctk.CTkButton(
            bottom_frame,
            text="Space",
            width=180,
            command=lambda: self.button_click(" "),
            **self.button_style
        )
        space_btn.pack(side="left", padx=2)
        
        # Backspace key
        backspace_btn = ctk.CTkButton(
            bottom_frame,
            text="←",
            width=70,
            command=self.backspace,
            **self.button_style
        )
        backspace_btn.pack(side="left", padx=2)
        
        # Enter key
        enter_btn = ctk.CTkButton(
            bottom_frame,
            text="✓",
            width=70,
            command=self.enter_click,
            fg_color='#34c759',
            hover_color='#30d158',
            text_color='white',
            height=45,
            corner_radius=8,
            font=("Helvetica", 16)
        )
        enter_btn.pack(side="left", padx=2)
        
    def rebuild_keyboard(self):
        # Destroy all existing widgets
        for widget in self.winfo_children():
            widget.destroy()
        # Rebuild with current layout
        self.create_keyboard()
        
    def toggle_shift(self):
        self.shift_mode = not self.shift_mode
        self.special_chars_mode = False
        self.current_layout = self.shift_layout if self.shift_mode else self.normal_layout
        self.rebuild_keyboard()
        
    def toggle_special(self):
        self.special_chars_mode = not self.special_chars_mode
        self.shift_mode = False
        self.current_layout = self.special_layout if self.special_chars_mode else self.normal_layout
        self.rebuild_keyboard()
        
    def button_click(self, char):
        current = self.entry_widget.get()
        self.entry_widget.delete(0, ctk.END)
        self.entry_widget.insert(0, current + char)
        # If shift is on, turn it off after one character
        if self.shift_mode:
            self.toggle_shift()
            
    def backspace(self):
        current = self.entry_widget.get()
        if current:
            self.entry_widget.delete(len(current) - 1)
            
    def enter_click(self):
        self.event_generate("<<KeyboardEnter>>")

class PasswordEntryScreen(ctk.CTkFrame):
    def __init__(self, parent, network_name, dark_mode: bool, language: str, callback):
        super().__init__(
            parent,
            fg_color='#1c1c1e' if dark_mode else '#f5f5f7',
            width=1024,
            height=600
        )
        
        self.parent = parent
        self.dark_mode = dark_mode
        self.network_name = network_name
        self.language = language
        self.callback = callback
        
        # Create main container
        self.container = ctk.CTkFrame(
            self,
            fg_color='transparent',
            corner_radius=0
        )
        self.container.pack(fill='both', expand=True, padx=40, pady=40)
        
        # Create centered content frame
        self.content_frame = ctk.CTkFrame(
            self.container,
            fg_color='#2c2c2e' if dark_mode else '#e5e5e7',
            corner_radius=15
        )
        self.content_frame.pack(expand=True, fill='both')
        
        # Header with network name
        header_frame = ctk.CTkFrame(
            self.content_frame,
            fg_color='transparent'
        )
        header_frame.pack(fill='x', padx=20, pady=(20, 0))
        
        # Back button
        back_btn = ctk.CTkButton(
            header_frame,
            text="←",
            width=40,
            command=self.destroy,
            fg_color='#3a3a3c' if dark_mode else '#d1d1d6',
            hover_color='#4a4a4c' if dark_mode else '#c1c1c6',
            text_color='white' if dark_mode else 'black'
        )
        back_btn.pack(side='left')
        
        # Network name
        network_label = ctk.CTkLabel(
            header_frame,
            text=network_name,
            font=("Helvetica", 20, "bold"),
            text_color='white' if dark_mode else 'black'
        )
        network_label.pack(side='left', padx=20)
        
        # Password entry
        self.password_frame = ctk.CTkFrame(
            self.content_frame,
            fg_color='transparent'
        )
        self.password_frame.pack(fill='x', padx=20, pady=20)
        
        self.password_entry = ctk.CTkEntry(
            self.password_frame,
            placeholder_text="Password",
            font=("Helvetica", 16),
            height=45,
            show="•"
        )
        self.password_entry.pack(fill='x')
        
        # Add keyboard
        self.keyboard = TouchKeyboard(
            self.content_frame,
            self.password_entry,
            dark_mode
        )
        self.keyboard.pack(pady=20)
        
        # Bind keyboard enter event
        self.bind("<<KeyboardEnter>>", self.handle_connect)
        
    def handle_connect(self, event=None):
        password = self.password_entry.get()
        if password:
            self.callback(self.network_name, password)
            self.destroy()

class WiFiScreen(ctk.CTkFrame):
    def __init__(self, parent, dark_mode: bool, language: str):
        super().__init__(
            parent,
            fg_color='#1c1c1e' if dark_mode else '#f5f5f7',
            width=1024,
            height=600
        )
        
        self.parent = parent
        self.dark_mode = dark_mode
        self.language = language
        self.networks = set()  # Use set to store unique network names
        self.scanning = False
        
        # Create main container with padding
        self.container = ctk.CTkFrame(
            self,
            fg_color='transparent'
        )
        self.container.pack(fill='both', expand=True, padx=30, pady=30)
        
        # Create header
        self.create_header()
        
        # Create scrollable content area
        self.scrollable_frame = ctk.CTkScrollableFrame(
            self.container,
            fg_color='transparent',
            height=450
        )
        self.scrollable_frame.pack(fill='x', pady=(20, 0))
        
        # Start network scan
        self.scan_networks()
        
    def create_header(self):
        header_frame = ctk.CTkFrame(
            self.container,
            fg_color='transparent'
        )
        header_frame.pack(fill='x')
        
        # Back button
        back_btn = ctk.CTkButton(
            header_frame,
            text="←",
            width=40,
            command=self.destroy,
            fg_color='#2c2c2e' if self.dark_mode else '#e5e5e7',
            hover_color='#3a3a3c' if self.dark_mode else '#d1d1d6',
            text_color='white' if self.dark_mode else 'black'
        )
        back_btn.pack(side='left')
        
        # Title
        title = ctk.CTkLabel(
            header_frame,
            text=TRANSLATIONS[self.language]['wifi_diagnostics'],
            font=("Helvetica", 22, "bold"),
            text_color='white' if self.dark_mode else 'black'
        )
        title.pack(side='left', padx=20)
        
        # Refresh button
        self.refresh_btn = ctk.CTkButton(
            header_frame,
            text="⟳",
            width=40,
            command=self.scan_networks,
            fg_color='#2c2c2e' if self.dark_mode else '#e5e5e7',
            hover_color='#3a3a3c' if self.dark_mode else '#d1d1d6',
            text_color='white' if self.dark_mode else 'black'
        )
        self.refresh_btn.pack(side='right')
        
    def scan_networks(self):
        if self.scanning:
            return
            
        self.scanning = True
        self.refresh_btn.configure(state="disabled")
        
        # Clear existing network list
        for widget in self.scrollable_frame.winfo_children():
            widget.destroy()
        
        # Add scanning message
        self.scanning_label = ctk.CTkLabel(
            self.scrollable_frame,
            text=TRANSLATIONS[self.language]['diagnostic_running'],
            font=("Helvetica", 16),
            text_color='white' if self.dark_mode else 'black'
        )
        self.scanning_label.pack(pady=20)
        
        # Start scan in separate thread
        thread = threading.Thread(target=self._scan_networks_thread)
        thread.daemon = True
        thread.start()
        
    def _scan_networks_thread(self):
        try:
            # Get list of networks
            result = subprocess.run(['sudo', 'iwlist', 'wlan0', 'scan'], 
                                 capture_output=True, text=True)
            
            # Clear existing networks set
            self.networks.clear()
            
            # Parse networks from output and add to set (ensures uniqueness)
            for line in result.stdout.split('\n'):
                if "ESSID:" in line:
                    ssid = re.findall(r'ESSID:"([^"]*)"', line)
                    if ssid and ssid[0]:
                        self.networks.add(ssid[0])
            
            # Update UI in main thread
            self.after(0, self._update_network_list)
            
        except Exception as e:
            print(f"Error scanning networks: {e}")
            self.after(0, self._show_scan_error)
        
        finally:
            self.scanning = False
            self.after(0, lambda: self.refresh_btn.configure(state="normal"))
            
    def _update_network_list(self):
        # Remove scanning message
        if hasattr(self, 'scanning_label'):
            self.scanning_label.destroy()
        
        # Get current network
        current_network = self._get_current_network()
        
        # Add network buttons
        for network in sorted(self.networks):
            network_frame = ctk.CTkFrame(
                self.scrollable_frame,
                fg_color='#2c2c2e' if self.dark_mode else '#e5e5e7',
                corner_radius=10,
                height=60
            )
            network_frame.pack(fill='x', pady=5, padx=10)
            network_frame.pack_propagate(False)
            
            # Network name
            name_label = ctk.CTkLabel(
                network_frame,
                text=network,
                font=("Helvetica", 16),
                text_color='white' if self.dark_mode else 'black'
            )
            name_label.pack(side='left', padx=20, pady=10)
            
            # Connection status/button
            if network == current_network:
                status_label = ctk.CTkLabel(
                    network_frame,
                    text=TRANSLATIONS[self.language]['wifi_connected'],
                    font=("Helvetica", 16),
                    text_color='#34c759'
                )
                status_label.pack(side='right', padx=20)
            else:
                connect_btn = ctk.CTkButton(
                    network_frame,
                    text=TRANSLATIONS[self.language]['reconnect'],
                    font=
Editor is loading...
Leave a Comment