modify the programm so that the tksheet tables automaticly adjust to the width and fill the rest of the window that are not filled by the sidebar and the space filler between the sidebar and the tksheet table. Python 3.12: import tkinter as tk
from tkinter import simpledialog, messagebox, filedialog
from tksheet import Sheet
import json
import csv
from pathlib import Path
import ctypes

def set_dpi_awareness():
    """Enable DPI awareness for high DPI settings."""
    try:
        ctypes.windll.shcore.SetProcessDpiAwareness(1)
    except Exception as e:
        print(f"Error setting DPI awareness: {e}")

class TableApp:
    def __init__(self, root):
        """Initialize the Table Editor application."""
        self.root = root
        self.root.title("Table Editor with Sidebar")
        self.root.geometry("1280x720")

        # Font Configurations
        font_name = "Literata"
        font_size = 12
        font_style = "normal"
        self.default_font = (font_name, font_size, font_style)
        self.root.option_add("*Font", f"{font_name} {font_size}")

        # Color Configurations
        self.TEXT_COLOR = '#333333'
        self.BACKGROUND_COLOR = '#FFFFFF'
        self.SIDEBAR_COLOR = '#F7F8FC'
        self.BUTTON_COLOR = '#F7F8FC'
        self.BUTTON_COLOR_SELECTED = '#EAEDEF'

        self.setup_ui()
        self.initialize_data()
        self.load_tables()

    def setup_ui(self):
        """Set up the user interface components."""
        self.create_sidebar()
        self.create_main_frame()
        self.create_header_frame()
        self.create_table_frame()

    def create_sidebar(self):
        """Create the sidebar and its components."""
        self.sidebar = tk.Frame(self.root, width=200, bg=self.SIDEBAR_COLOR, bd=0, relief='flat')
        self.sidebar.pack(expand=False, fill='y', side='left', anchor='nw')

        self.separator = tk.Frame(self.root, width=100, bg=self.BACKGROUND_COLOR, bd=0, relief='flat')
        self.separator.pack(expand=False, fill='y', side='left', anchor='nw')

        self.new_table_label = self.create_clickable_label(
            self.sidebar, "Create New Table", self.create_new_table)
        self.new_table_label.pack(padx=0, pady=10, fill='x')

        self.import_table_label = self.create_clickable_label(
            self.sidebar, "Import Table", self.import_file)
        self.import_table_label.pack(padx=0, pady=10, fill='x')

        self.table_labels_frame = tk.Frame(self.sidebar, bg=self.SIDEBAR_COLOR)
        self.table_labels_frame.pack(expand=True, fill='both', padx=0, pady=10)

        # Add delete table option
        self.delete_table_label = self.create_clickable_label(
            self.sidebar, "Delete Selected Table", self.delete_table)
        self.delete_table_label.pack(side='bottom', padx=0, pady=10, fill='x')

        self.add_custom_hover(self.new_table_label)
        self.add_custom_hover(self.import_table_label)
        self.add_custom_hover(self.delete_table_label)

    def create_main_frame(self):
        """Create the main frame of the application."""
        self.main_frame = tk.Frame(self.root)
        self.main_frame.pack(expand=True, fill='both', side='right')

    def create_header_frame(self):
        """Create the header frame with filter and rename options."""
        self.header_frame = tk.Frame(self.main_frame, height=50, bg=self.BACKGROUND_COLOR)
        self.header_frame.pack(fill='x')

        self.filter_label = tk.Label(self.header_frame, text="Filter:", bg=self.BACKGROUND_COLOR, fg=self.TEXT_COLOR, anchor="w")
        self.filter_label.pack(side='left', padx=5, pady=10)

        self.filter_entry = tk.Entry(self.header_frame, fg=self.TEXT_COLOR)
        self.filter_entry.pack(side='left', padx=5, pady=10)
        self.filter_entry.bind("<KeyRelease>", lambda event: self.apply_filter())

        self.rename_headers_label = self.create_clickable_label(
            self.header_frame, "Rename Headers", self.rename_headers)
        self.rename_headers_label.pack(side='left', padx=5, pady=10, fill='x')

    def create_table_frame(self):
        """Create the frame to hold the table."""
        self.table_frame = tk.Frame(self.main_frame, bg=self.BACKGROUND_COLOR)
        self.table_frame.pack(expand=True, fill='both')

    def initialize_data(self):
        """Initialize data structures and variables."""
        self.save_file_dir = Path("tables")
        self.tables = {}
        self.table_labels = {}
        self.original_data = {}
        self.headers = {}
        self.current_table_name = None
        self.rename_entry = None
        self.selected_table_label = None

        self.save_file_dir.mkdir(exist_ok=True)

    def create_clickable_label(self, parent, text, command, allow_rename=True):
        """Create a clickable Label widget."""
        label = tk.Label(
            parent, text=text, bg=self.BUTTON_COLOR, fg=self.TEXT_COLOR,
            borderwidth=0, relief='flat', cursor='arrow', anchor='w',
            padx=10, pady=5
        )
        label.bind("<Button-1>", lambda e: command())
        if allow_rename:
            label.bind("<Double-1>", lambda e: self.begin_rename(text))
        return label

    def create_new_table(self):
        """Create a new table and add it to the available tables list."""
        table_name = f"Table {len(self.tables) + 1}"
        self.add_table(table_name)
        self.load_selected_table(table_name)

    def import_file(self):
        """Import a CSV or JSON file to create a new table."""
        file_path = filedialog.askopenfilename(
            title="Open File",
            filetypes=[("CSV files", "*.csv"), ("JSON files", "*.json")]
        )
        if not file_path:
            return

        if file_path.endswith('.csv'):
            with open(file_path, newline='', encoding='utf-8') as csvfile:
                reader = csv.reader(csvfile)
                data = list(reader)
            headers, table_data = data[0], data[1:]

        elif file_path.endswith('.json'):
            with open(file_path, 'r', encoding='utf-8') as jsonfile:
                data = json.load(jsonfile)
            headers, table_data = data[0], data[1:]

        else:
            messagebox.showerror("Unsupported File", "The selected file format is not supported.")
            return

        table_name = Path(file_path).stem
        self.add_table(table_name, table_data)
        self.headers[table_name] = headers
        self.load_selected_table(table_name)

    def add_table(self, table_name, data=None):
        """Add a table to the UI and internal storage."""
        default_data = [["" for _ in range(5)] for _ in range(10)]
        self.tables[table_name] = Sheet(
            self.table_frame,
            data=data or default_data,
            show_table=True,
            headers=None,
            font=self.default_font,  # Use default font
            header_font=self.default_font,  # Set the header font
        )
        
        self.tables[table_name].set_options(table_fg=self.TEXT_COLOR, header_fg=self.TEXT_COLOR)

        self.tables[table_name].enable_bindings()
        self.tables[table_name].extra_bindings([
            ("end_edit_cell", lambda event, tn=table_name: self.save_data(tn)),
        ])
        self.tables[table_name].pack_forget()
        self.original_data[table_name] = self.tables[table_name].get_sheet_data()

        if table_name not in self.headers:
            self.headers[table_name] = self.tables[table_name].headers()

        table_label = self.create_clickable_label(
            self.table_labels_frame, table_name,
            lambda name=table_name: self.load_selected_table(name)
        )
        table_label.pack(fill='x', pady=2)
        self.table_labels[table_name] = table_label

        self.add_custom_hover(table_label)

    def delete_table(self):
        """Delete the currently selected table."""
        if not self.current_table_name:
            messagebox.showwarning("No Table Selected", "Please select a table to delete.")
            return

        response = messagebox.askyesno(
            "Delete Table",
            f"Are you sure you want to delete the table '{self.current_table_name}'?"
        )
        if response:
            # Remove from the UI
            self.tables[self.current_table_name].destroy()
            self.table_labels[self.current_table_name].destroy()

            # Remove from internal storage
            del self.tables[self.current_table_name]
            del self.original_data[self.current_table_name]
            del self.headers[self.current_table_name]
            del self.table_labels[self.current_table_name]

            # Remove from disk
            file_path = self.save_file_dir / f"{self.current_table_name}.json"
            if file_path.exists():
                file_path.unlink()

            # Reset current table selection
            self.current_table_name = None
            self.selected_table_label = None

    def load_tables(self):
        """Load existing tables from the directory."""
        for file_path in self.save_file_dir.glob("*.json"):
            table_name = file_path.stem
            with file_path.open('r') as file:
                data = json.load(file)
                headers = data.pop(0)
                self.add_table(table_name, data)
                self.headers[table_name] = headers

    def load_selected_table(self, table_name):
        """Display the selected table and hide others."""
        for name, sheet in self.tables.items():
            if name == table_name:
                sheet.pack(expand=True, fill='both')
                self.current_table_name = table_name
                sheet.headers(self.headers[name])
                self.apply_filter()

                selected_label = self.table_labels[name]
                selected_label.config(bg=self.BUTTON_COLOR_SELECTED)
                self.selected_table_label = selected_label
            else:
                sheet.pack_forget()
                self.table_labels[name].config(bg=self.BUTTON_COLOR)

    def save_data(self, table_name):
        """Save current data of a table to a file."""
        data = [self.headers[table_name]] + self.tables[table_name].get_sheet_data()
        file_path = self.save_file_dir / f"{table_name}.json"
        with file_path.open('w') as file:
            json.dump(data, file)
        print(f"Data for {table_name} saved successfully.")

    def apply_filter(self):
        """Apply filtering based on the entered term."""
        if not self.current_table_name:
            return

        term = self.filter_entry.get().lower()
        original_data = self.original_data[self.current_table_name]

        filtered_data = [
            row for row in original_data
            if any(term in str(cell).lower() for cell in row)
        ]

        self.tables[self.current_table_name].set_sheet_data(filtered_data)

    def rename_headers(self):
        """Prompt user to rename headers of the currently selected table."""
        if not self.current_table_name:
            messagebox.showwarning("No Table Selected", "Please select a table to rename headers.")
            return

        current_headers = self.headers[self.current_table_name]
        new_headers = simpledialog.askstring(
            "Rename Headers",
            "Enter new headers (comma-separated):",
            initialvalue=", ".join(current_headers)
        )

        if new_headers:
            header_list = [header.strip() for header in new_headers.split(',')]
            self.headers[self.current_table_name] = header_list
            self.tables[self.current_table_name].headers(header_list)
            self.save_data(self.current_table_name)

    def begin_rename(self, table_name):
        """Begin renaming of the table with a double click."""
        label = self.table_labels[table_name]
        
        if self.rename_entry:
            self.rename_entry.destroy()
        
        label.update_idletasks()
        label_x, label_y = label.winfo_x(), label.winfo_y()
        label_width, label_height = label.winfo_width(), label.winfo_height()
        
        self.rename_entry = tk.Entry(
            self.table_labels_frame,
            bg=label.cget("bg"),
            fg=self.TEXT_COLOR,
            relief='flat',
            borderwidth=0,
            highlightthickness=0,
            justify='left'
        )
        self.rename_entry.insert(0, table_name)
        
        self.rename_entry.place(x=label_x, y=label_y, width=label_width, height=label_height)
        self.rename_entry.focus()
        self.rename_entry.select_range(0, tk.END)
        
        self.rename_entry.bind('<Return>', lambda event: self.end_rename(table_name))
        self.rename_entry.bind('<FocusOut>', lambda event: self.cancel_rename())

    def end_rename(self, old_name):
        """Finish the renaming process for the specified table."""
        new_name = self.rename_entry.get().strip()

        if not new_name:
            messagebox.showerror("Invalid Name", "Table name cannot be empty.")
            self.rename_entry.focus_set()
            return

        if new_name in self.tables and new_name != old_name:
            messagebox.showerror("Duplicate Name", f"A table named '{new_name}' already exists.")
            self.rename_entry.focus_set()
            return

        if new_name != old_name:
            self.tables[new_name] = self.tables.pop(old_name)
            self.original_data[new_name] = self.original_data.pop(old_name)
            self.headers[new_name] = self.headers.pop(old_name)

            self.table_labels[new_name] = self.table_labels.pop(old_name)
            self.table_labels[new_name].config(text=new_name)

            if self.selected_table_label == self.table_labels[new_name]:
                self.selected_table_label = self.table_labels[new_name]
                self.table_labels[new_name].config(bg=self.BUTTON_COLOR_SELECTED)

            current_file = self.save_file_dir / f"{old_name}.json"
            new_file = self.save_file_dir / f"{new_name}.json"

            if current_file.exists():
                current_file.rename(new_file)

        self.cancel_rename()

    def cancel_rename(self):
        """Cancel the renaming entry."""
        if self.rename_entry:
            self.rename_entry.destroy()
            self.rename_entry = None

    def add_custom_hover(self, label):
        """Add custom hover effects to a label."""
        def on_enter(e):
            if label != self.selected_table_label:
                label.config(bg=self.BUTTON_COLOR_SELECTED)

        def on_leave(e):
            if label != self.selected_table_label:
                label.config(bg=self.BUTTON_COLOR)

        label.bind("<Enter>", on_enter)
        label.bind("<Leave>", on_leave)

if __name__ == "__main__":
    set_dpi_awareness()
    root = tk.Tk()
    app = TableApp(root)
    root.mainloop()