From 095c2530c3fe67083a28149c07af29555ea2f968 Mon Sep 17 00:00:00 2001 From: David Michael Jackson Date: Wed, 29 May 2024 21:05:18 -0500 Subject: [PATCH] Delete webster123-v1.0.1.py Signed-off-by: David Michael Jackson --- webster123-v1.0.1.py | 740 ------------------------------------------- 1 file changed, 740 deletions(-) delete mode 100644 webster123-v1.0.1.py diff --git a/webster123-v1.0.1.py b/webster123-v1.0.1.py deleted file mode 100644 index 68f063f..0000000 --- a/webster123-v1.0.1.py +++ /dev/null @@ -1,740 +0,0 @@ -import tkinter as tk -from tkinter import font, filedialog, messagebox, simpledialog, Toplevel, Text, Scrollbar, Menu -import pandas as pd -import os -import webbrowser - -global_df = None # Global variable to store the DataFrame -current_selection = None -clipboard_data = None -shift_start_row = None # Variable to store the starting row for shift-click selection - -# Define the column order -columns = [ - "siteId", "folderPath", "ourUrl", "ourTitle", "ourContent", "Extra1", "Extra2","topMenu", - "ourHeader", "ourFooter", "styleSheet", "scriptsUrl", "fileExtension", "ourMeta", "shareImageUrl", - "Website", "websiteUrl","Icon", "topHtml", "headTag", "ourShareButton", "useLinkBox", "directoryMode", "frontPage" -] -# Define initial values -initial_data = { - "ourUrl": ["publish-and-view-me"], - "folderPath": ["c:\\webster123"], - "fileExtension": ["html"], - "scriptsUrl": [""], - "ourTitle": [""], - "ourContent": [f"""

Congratulations!

You've published your first page.
Change it to your html to get started.
This is v1.0.1
Visit Webster123.com for instructions.

"""], - "Extra1": [""], - "Extra2": [""], - "siteId": ["My Site"], - "topMenu": [""], - "ourHeader": [f""""""], - "ourFooter": [""], - "directoryMode": ["False"], - "shareImageUrl": [""], - "ourMeta": [""], - "Website": [""], - "websiteUrl": [""], - "styleSheet": [""], - "Icon": [""], - "topHtml": [""], - "headTag": [""], - "ourShareButton": [""], - "useLinkBox": ["False"], - "frontPage": ["False"] -} - -# Add 20 extra empty rows -for _ in range(20): - for key in initial_data.keys(): - initial_data[key].append("") - -column_config = { - "ourUrl": {"width": 220, "chars": 24, "instructions": "Words with a dash between them, no special characters"}, - "folderPath": {"width": 100, "chars": 12, "instructions": "The folder on your local where you wish to store the pages you create. Like C:\\webster123"}, - "fileExtension": {"width": 100, "chars": 12, "instructions": "html or php"}, - "ourTitle": {"width": 100, "chars": 12, "instructions": "The title of your web page."}, - "ourContent": {"width": 100, "chars": 12, "instructions": "Html content"}, - "Extra1": {"width": 100, "chars": 12, "instructions": "Extra Html content"}, - "Extra2": {"width": 100, "chars": 12, "instructions": "Extra Html content"}, - "siteId": {"width": 100, "chars": 12, "instructions": "Your site Id, Which site is this?"}, - "topMenu": {"width": 100, "chars": 12, "instructions": "Our menu entries are Anchor links stacked on top of each other."}, - "ourHeader": {"width": 100, "chars": 12, "instructions": "Html for the header of the website."}, - "ourFooter": {"width": 100, "chars": 12, "instructions": "Html for the Footer of our site."}, - "directoryMode": {"width": 100, "chars": 12, "instructions": "False and we produce a url like example.html. True and we create a folder example/ and put an index page in it.."}, - "shareImageUrl": {"width": 100, "chars": 12, "instructions": "The url of your share image"}, - "ourMeta": {"width": 100, "chars": 12, "instructions": "The meta Description of your page."}, - "Website": {"width": 100, "chars": 12, "instructions": "yoursite.com"}, - "websiteUrl": {"width": 100, "chars": 12, "instructions": "Website URL. Must have trailing slash '/', like https://yoursite.com/"}, - "styleSheet": {"width": 100, "chars": 12, "instructions": "The url of your stylesheet file. On your local drive it can look like file:///c:/Stylesheets/mystylesheet.css This way you can work with a stylesheet on your drive. When you publish the page on the internet, you can change it to something like https://mysite.com/mystylesheet.css"}, - "Icon": {"width": 100, "chars": 12, "instructions": "The website icon, usually 100x100px"}, - "topHtml": {"width": 100, "chars": 12, "instructions": "Inserted after "}, - "headTag": {"width": 100, "chars": 12, "instructions": "Inserted after "}, - "ourShareButton": {"width": 100, "chars": 12, "instructions": "AddtoAny Share Button. Leave blank to not use."}, - "useLinkBox": {"width": 100, "chars": 12, "instructions": "If True, a Link To This Page Box will be added"}, - "scriptsUrl": {"width": 100, "chars": 12, "instructions": "The url of your java script file. On your local drive it can look like file:///c:/Scriptsfolder/myscript.js This way you can work with a script on your drive. When you publish the page on the internet, you can change it to something like https://mysite.com/myscript.js"} - -} - -class SimpleTable(tk.Canvas): - def __init__(self, parent, rows=10, cols=5, font_size=10): - super().__init__(parent) - self.parent = parent - self.rows = rows - self.cols = cols - self.cells = {} - self.headers = [] - self.row_numbers = [] - self.header_height = 30 - self.row_number_width = 50 - self.font_size = font_size - self.font = font.Font(size=font_size) - self.cell_height = self.font.metrics("linespace") + 10 - - self.selection_rects = [] - self.start_row = None - self.edit_window = None # Track the edit window - self.clipboard_data = None # To store single cell value for pasting - - self.header_canvas = tk.Canvas(parent, height=self.header_height, bg='lightgrey') - self.row_number_canvas = tk.Canvas(parent, width=self.row_number_width, bg='lightgrey') - - self.header_canvas.grid(row=0, column=1, sticky='ew') - self.row_number_canvas.grid(row=1, column=0, sticky='ns') - - self.create_widgets() - self.bind_shortcuts() - - def create_widgets(self): - self.config(bg='white', highlightthickness=0) - self.bind("", self.on_table_click) - self.bind("", self.on_table_drag) - self.bind("", self.on_drag_end) - self.bind("", self.on_table_double_click) - self.bind("", self.on_table_right_click) - self.bind_all("", self.on_mouse_wheel) - self.row_number_canvas.bind("", self.on_row_number_right_click) - self.xview_moveto(0) - self.yview_moveto(0) - - def bind_shortcuts(self): - self.parent.bind("", self.copy_selection) - self.parent.bind("", self.cut_selection) - self.parent.bind("", self.paste_selection) - - def cut_selection(self): - self.copy_selection() - self.delete_selection(current_selection[0], current_selection[1]) - - def create_cell(self, row, col, value): - col_name = self.headers[col] - cell_config = column_config.get(col_name, {"width": 100, "chars": 12}) - cell_width = cell_config["width"] - x0 = self.row_number_width + sum(column_config.get(self.headers[c], {"width": 100})["width"] for c in range(col)) - y0 = row * self.cell_height - x1 = x0 + cell_width - y1 = y0 + self.cell_height - rect = self.create_rectangle(x0, y0, x1, y1, fill="white", outline="black") - - # Calculate the number of characters that fit in the cell width - char_width = self.font.measure("A") - max_chars = cell_width // char_width - display_value = str(value)[:max_chars] if value else "" - - text = self.create_text(x0 + 5, y0 + 5, anchor="nw", text=display_value, width=cell_width - 10, font=self.font, tag=f"cell_{row}_{col}") - self.cells[(row, col)] = (rect, text) - - def create_headers(self): - self.header_canvas.delete("all") - x_offset = 0 - for col, header in enumerate(self.headers): - cell_config = column_config.get(header, {"width": 100, "chars": 12}) - cell_width = cell_config["width"] - x0 = x_offset - y0 = 0 - x1 = x0 + cell_width - y1 = y0 + self.header_height - self.header_canvas.create_rectangle(x0, y0, x1, y1, fill="lightgrey", outline="black") - self.header_canvas.create_text(x0 + 5, y0 + 5, anchor="nw", text=header, font=self.font) - x_offset += cell_width - - def create_row_numbers(self): - self.row_number_canvas.delete("all") - for row in range(self.rows): - x0 = 0 - y0 = row * self.cell_height - x1 = x0 + self.row_number_width - y1 = y0 + self.cell_height - rect = self.row_number_canvas.create_rectangle(x0, y0, x1, y1, fill="lightgrey", outline="black") - text = self.row_number_canvas.create_text(x0 + 5, y0 + 5, anchor="nw", text=str(row + 1), font=self.font) - self.row_numbers.append((rect, text)) - self.row_number_canvas.tag_bind(rect, "", lambda event, r=row: self.on_row_number_click(event, r)) - self.row_number_canvas.tag_bind(text, "", lambda event, r=row: self.on_row_number_click(event, r)) - - def on_row_number_click(self, event, row): - global shift_start_row - if shift_start_row is None or not event.state & 0x1: # If shift key is not pressed - shift_start_row = row - self.clear_selection() - self.highlight_rows(shift_start_row, row) - global current_selection - current_selection = (min(shift_start_row, row), 0, max(shift_start_row, row), self.cols - 1) - - def highlight_rows(self, start_row, end_row): - for row in range(min(start_row, end_row), max(start_row, end_row) + 1): - for col in range(self.cols): - self.highlight_cell(row, col) - - def load_data(self, data, column_names): - self.rows = len(data) - self.cols = len(data[0]) if self.rows > 0 else 0 - self.headers = column_names - self.cells.clear() - self.delete("all") - self.populate_table() - for row, row_data in enumerate(data): - for col, value in enumerate(row_data): - self.create_cell(row, col, value) - self.update_idletasks() - self.config(scrollregion=self.bbox("all")) - self.create_headers() - self.create_row_numbers() - self.update_scroll_region() - - def populate_table(self): - for row in range(self.rows): - for col in range(self.cols): - self.create_cell(row, col, "") - self.create_headers() - self.create_row_numbers() - - def on_table_click(self, event): - global current_selection - x, y = self.canvasx(event.x), self.canvasy(event.y) - row, col = int(y // self.cell_height), self.get_col_at_x(x - self.row_number_width) - if row >= 0 and col >= 0: - self.clear_selection() - self.highlight_cell(row, col) - current_selection = (row, col, row, col) - - def get_col_at_x(self, x): - x_offset = 0 - for col, header in enumerate(self.headers): - cell_config = column_config.get(header, {"width": 100, "chars": 12}) - cell_width = cell_config["width"] - if x_offset <= x < x_offset + cell_width: - return col - x_offset += cell_width - return -1 - - def on_table_drag(self, event): - global current_selection - x, y = self.canvasx(event.x), self.canvasy(event.y) - row, col = int(y // self.cell_height), self.get_col_at_x(x - self.row_number_width) - if row >= 0 and col >= 0 and current_selection is not None: - self.clear_selection() - row1, col1, row2, col2 = current_selection - current_selection = (row1, col1, row, col) - self.highlight_rectangle(row1, col1, row, col) - - def on_drag_end(self, event): - self.start_row = None - - def on_table_double_click(self, event): - x, y = self.canvasx(event.x), self.canvasy(event.y) - row, col = int(y // self.cell_height), self.get_col_at_x(x - self.row_number_width) - if row >= 0 and col >= 0: - self.edit_cell(row, col) - - def on_table_right_click(self, event): - x, y = self.canvasx(event.x), self.canvasy(event.y) - row, col = int(y // self.cell_height), self.get_col_at_x(x - self.row_number_width) - if row >= 0 and col >= 0: - self.show_cell_context_menu(event, row, col) - - def on_row_number_right_click(self, event): - y = self.row_number_canvas.canvasy(event.y) - row = int(y // self.cell_height) - if row >= 0: - self.show_row_context_menu(event, row) - - def on_mouse_wheel(self, event): - if event.state & 0x1: # If Shift key is pressed - self.xview_scroll(-1 * int((event.delta / 120)), "units") - else: - self.yview_scroll(-1 * int((event.delta / 120)), "units") - self.update_scroll_region() - - def highlight_cell(self, row, col): - self.itemconfig(self.cells[(row, col)][0], fill="lightblue") - self.itemconfig(self.cells[(row, col)][1], fill="blue", font="Arial 10 bold") - - def clear_selection(self): - for rect in self.selection_rects: - self.delete(rect) - self.selection_rects.clear() - for (row, col), (rect, text) in self.cells.items(): - self.itemconfig(rect, fill="white") - self.itemconfig(text, fill="black", font="Arial 10") - - def highlight_rectangle(self, row1, col1, row2, col2): - for row in range(min(row1, row2), max(row1, row2) + 1): - for col in range(min(col1, col2), max(col1, col2) + 1): - self.highlight_cell(row, col) - cell_config = column_config.get(self.headers[col], {"width": 100, "chars": 12}) - cell_width = cell_config["width"] - x0 = self.row_number_width + sum(column_config.get(self.headers[c], {"width": 100})["width"] for c in range(col)) - y0 = row * self.cell_height - x1 = x0 + cell_width - y1 = y0 + self.cell_height - rect = self.create_rectangle(x0, y0, x1, y1, outline="blue", width=2) - self.selection_rects.append(rect) - - def show_cell_context_menu(self, event, row, col): - menu = Menu(self, tearoff=0) - menu.add_command(label="Copy Selection", command=self.copy_selection) - menu.add_command(label="Paste Selection", command=self.paste_selection) - menu.add_command(label="Delete Selection", command=lambda: self.delete_selection(row, col)) - menu.post(event.x_root, event.y_root) - - def show_row_context_menu(self, event, row): - menu = Menu(self, tearoff=0) - menu.add_command(label="Insert Row", command=lambda: self.insert_row(row)) - menu.add_command(label="Delete Row", command=lambda: self.delete_row(row)) - menu.add_command(label="Copy Selection", command=self.copy_selection) - menu.add_command(label="Publish Selected Rows", command=self.publish_selected_rows) - menu.add_command(label="View Selected Rows", command=self.view_selected_rows) - menu.post(event.x_root, event.y_root) - - def insert_row(self, row): - global global_df - new_row = [""] * self.cols - global_df = pd.concat([global_df.iloc[:row], pd.DataFrame([new_row], columns=global_df.columns), global_df.iloc[row:]]).reset_index(drop=True) - update_table() - - def delete_row(self, row): - global global_df - global_df = global_df.drop(global_df.index[row]).reset_index(drop=True) - update_table() - - def delete_selection(self, row, col): - global global_df, current_selection - if current_selection is not None: - row1, col1, row2, col2 = current_selection - global_df.iloc[min(row1, row2):max(row1, row2) + 1, min(col1, col2):max(col1, col2) + 1] = "" - update_table() - - def copy_selection(self): - global global_df, clipboard_data, current_selection - if current_selection is not None: - row1, col1, row2, col2 = current_selection - if row1 == row2 and col1 == col2: - # Copy a single cell - clipboard_data = global_df.iat[row1, col1] - else: - # Copy a range of cells - clipboard_data = global_df.iloc[min(row1, row2):max(row1, row2) + 1, min(col1, col2):max(col1, col2) + 1].copy() - - def paste_selection(self): - global global_df, clipboard_data, current_selection - if clipboard_data is not None and current_selection is not None: - row1, col1, row2, col2 = current_selection - if isinstance(clipboard_data, pd.DataFrame): - rows_to_paste = clipboard_data.shape[0] - cols_to_paste = clipboard_data.shape[1] - if row1 + rows_to_paste > self.rows or col1 + cols_to_paste > self.cols: - messagebox.showerror("Paste Error", "Not enough space to paste the selection") - return - for i in range(rows_to_paste): - for j in range(cols_to_paste): - global_df.iat[row1 + i, col1 + j] = clipboard_data.iat[i, j] - else: - for row in range(min(row1, row2), max(row1, row2) + 1): - for col in range(min(col1, col2), max(col1, col2) + 1): - global_df.iat[row, col] = clipboard_data - update_table() - - def edit_cell(self, row, col): - if self.edit_window is not None and self.edit_window.winfo_exists(): - self.edit_window.lift() # Bring the existing edit window to the front - return - if (row, col) not in self.cells: - return - full_text = global_df.iat[row, col] if not pd.isna(global_df.iat[row, col]) else "" # Handle NaN values - col_name = self.headers[col] - cell_config = column_config.get(col_name, {"width": 100, "chars": 12, "instructions": ""}) - instructions = cell_config.get("instructions", "") - - self.edit_window = tk.Toplevel(self) - self.edit_window.title(f"Edit Cell ({row}, {col})") - - if instructions: - instruction_label = tk.Label(self.edit_window, text=instructions, wraplength=400, justify="left") - instruction_label.pack(fill="x", padx=10, pady=10) - - text_frame = tk.Frame(self.edit_window, padx=10, pady=10) - text_frame.pack(fill="both", expand=True) - - text = Text(text_frame, wrap="word") - text.insert("1.0", full_text) - text.pack(fill="both", expand=True, side="left") - - scrollbar = Scrollbar(text_frame, command=text.yview) - scrollbar.pack(side="right", fill="y") - text.config(yscrollcommand=scrollbar.set) - - text.bind_all("", lambda event: text.yview_scroll(-1 * int((event.delta / 120)), "units")) - - button_frame = tk.Frame(self.edit_window) - button_frame.pack(fill="x", expand=False, pady=10) - - def save_edit(): - new_text = text.get("1.0", tk.END).strip() - self.itemconfig(self.cells[(row, col)][1], text=new_text[:cell_config["chars"]]) # Update with truncated text - global_df.iat[row, col] = new_text # Update the global DataFrame with full text - self.edit_window.destroy() - self.edit_window = None - self.update_scroll_region() # Update the scroll region after editing - - save_button = tk.Button(button_frame, text="Save", command=save_edit) - cancel_button = tk.Button(button_frame, text="Cancel", command=lambda: [self.edit_window.destroy(), setattr(self, 'edit_window', None)]) - save_button.pack(side="left", padx=20, pady=5) - cancel_button.pack(side="right", padx=20, pady=5) - - text.focus_set() - - def handle_return(event): - text.insert(tk.INSERT, "\n") - return "break" - - text.bind('', handle_return) - - # Update the scroll region after closing the edit window - self.edit_window.bind("", lambda event: [self.update_scroll_region(), setattr(self, 'edit_window', None)]) - - def update_scroll_region(self): - self.config(scrollregion=self.bbox("all")) - self.header_canvas.config(scrollregion=self.header_canvas.bbox("all")) - self.row_number_canvas.config(scrollregion=self.row_number_canvas.bbox("all")) - - if self.xview() is not None: - self.header_canvas.xview_moveto(self.xview()[0]) - if self.yview() is not None: - self.row_number_canvas.yview_moveto(self.yview()[0]) - - # Ensure headers and row numbers are always visible - self.tag_lower("header") - self.tag_lower("row_num") - self.parent.update() - - # Re-bind scroll events - self.bind_all("", self.on_mouse_wheel) - - def xview_handler(self, *args): - self.xview_moveto = super().xview_moveto - self.xview_scroll = super().xview_scroll - self.xview(*args) - self.header_canvas.xview(*args) - self.update_scroll_region() - - def yview_handler(self, *args): - self.yview_moveto = super().yview_moveto - self.yview_scroll = super().yview_scroll - self.yview(*args) - self.row_number_canvas.yview(*args) - self.update_scroll_region() - - def publish_selected_rows(self): - global current_selection - if current_selection is not None: - row1, col1, row2, col2 = current_selection - rows_to_publish = list(range(min(row1, row2) + 1, max(row1, row2) + 2)) - result = publish_rows_to_disk(",".join(map(str, rows_to_publish))) - messagebox.showinfo("Publish Result", result) - - def view_selected_rows(self): - global current_selection - if current_selection is not None: - row1, col1, row2, col2 = current_selection - rows_to_view = list(range(min(row1, row2) + 1, max(row1, row2) + 2)) - result = view_html_pages(",".join(map(str, rows_to_view))) - messagebox.showinfo("View Result", result) - -# Ensure directory creation -def ensure_dir(folder_path): - if not os.path.exists(folder_path): - os.makedirs(folder_path) - -# Write HTML to file -def write_html(content, filename): - with open(filename, 'w', encoding='utf-8') as file: - file.write(content) - -def parse_line_numbers(line_numbers): - result = [] - parts = line_numbers.split(',') - for part in parts: - if '-' in part: - start, end = map(int, part.split('-')) - result.extend(range(start - 1, end)) - else: - result.append(int(part) - 1) # Convert to zero-based index - return result - -# Generate HTML Content -def generate_html_content(row): - def check_nan(value): - return "" if pd.isna(value) else value - - full_content = f"{check_nan(row['ourContent'])}{check_nan(row.get('Extra1', ''))}{check_nan(row.get('Extra2', ''))}" - directory_mode = str(row.get('directoryMode', 'false')).strip().lower() == 'true' - front_page = str(row.get('frontPage', 'false')).strip().lower() == 'true' - canonical_url = row['websiteUrl'] if front_page and not directory_mode else f"{row['websiteUrl']}{row['ourUrl']}/" if directory_mode else f"{row['websiteUrl']}{row['ourUrl']}.{row.get('fileExtension', 'html')}" - use_link_box = str(row.get('useLinkBox', 'false')).strip().lower() == 'true' - - link_box_html = "" - if use_link_box: - link_box_html = f"""
-
- -
- """ - - return f""" - - {check_nan(row['ourTitle'])} - - - - - - - - - - - - - -
{check_nan(row['ourHeader'])}
-
{check_nan(row['topMenu'])}
-
-

{check_nan(row['ourTitle'])}

- {full_content} - {link_box_html} - {check_nan(row['ourShareButton'])} -
- - - - -""" - - -# Construct the file path for a given row -def construct_file_path(row): - folder_path = row['folderPath'] - directory_mode = str(row.get('directoryMode', 'false')).strip().lower() == 'true' - file_name = os.path.join(row['ourUrl'], "index") if directory_mode else row['ourUrl'] - file_extension = row.get('fileExtension', 'html') - return os.path.join(folder_path, f"{file_name}.{file_extension}") - -# Publish Rows to Disk -def publish_rows_to_disk(line_numbers): - global global_df - - if global_df is None: - messagebox.showwarning("No CSV", "No CSV loaded. Please load a CSV file first.") - return "No CSV loaded." - - try: - lines_to_process = parse_line_numbers(line_numbers) - output = [] - - for index in lines_to_process: - if index < len(global_df): - row = global_df.iloc[index] - folder_path = row['folderPath'] - - directory_mode = str(row.get('directoryMode', 'false')).strip().lower() == 'true' - file_name = os.path.join(row['ourUrl'], "index") if directory_mode else row['ourUrl'] - file_extension = row.get('fileExtension', 'html') - full_path = os.path.join(folder_path, f"{file_name}.{file_extension}") - - ensure_dir(os.path.dirname(full_path)) - html_content = generate_html_content(row) - write_html(html_content, full_path) - output.append(f"Processed row {index + 1} and saved to {full_path}") - - return "\n".join(output) - except Exception as e: - return f"Error processing data: {str(e)}" - -# View Html Pages -def view_html_pages(line_numbers=None): - global global_df - - if global_df is None: - messagebox.showwarning("No CSV", "No CSV loaded. Please load a CSV file first.") - return "No CSV loaded." - - try: - lines_to_open = parse_line_numbers(line_numbers) - files_to_open = [] - - for index in lines_to_open: - if index < len(global_df): - row = global_df.iloc[index] - file_path = construct_file_path(row) - files_to_open.append(file_path) - - if not files_to_open: - messagebox.showwarning("No Files", "No valid files to open.") - return "No valid files to open." - - for file in files_to_open: - webbrowser.open(f"file://{os.path.abspath(file)}", new=2) - return f"Opened {len(files_to_open)} files in the browser." - except Exception as e: - return f"Error opening files: {str(e)}" - -# Load CSV -def load_csv(): - global global_df - file_path = filedialog.askopenfilename(filetypes=[("CSV Files", "*.csv")]) - if not file_path: - return - try: - global_df = pd.read_csv(file_path) - - # Replace 0/1 with False/True for specific columns - bool_cols = ['directoryMode', 'useLinkBox', 'frontPage'] - for col in bool_cols: - if col in global_df.columns: - global_df[col] = global_df[col].replace({0: "False", 1: "True"}) - - # Ensure columns are in the predefined order - global_df = global_df.reindex(columns=columns) - - # Add extra empty rows if necessary to make sure there are at least 21 rows - if len(global_df) < 21: - extra_rows = 21 - len(global_df) - empty_rows = pd.DataFrame({col: [""] * extra_rows for col in columns}) - global_df = pd.concat([global_df, empty_rows], ignore_index=True) - - # Load the entire table to make all rows scrollable - update_table() - except Exception as e: - messagebox.showerror("Load Error", f"Failed to load CSV: {str(e)}") - -# Update Table -def update_table(rows_to_display=None): - global global_df - if global_df is not None: - if rows_to_display is not None: - data = global_df.head(rows_to_display).fillna("").values.tolist() - else: - data = global_df.fillna("").values.tolist() - column_names = global_df.columns.tolist() - table.load_data(data, column_names) - table.update_scroll_region() - - -# Save CSV -def save_csv(): - global global_df - if global_df is None: - messagebox.showwarning("No CSV", "No CSV loaded. Please load a CSV file first.") - return - file_path = filedialog.asksaveasfilename(defaultextension=".csv", filetypes=[("CSV Files", "*.csv")]) - if not file_path: - return - try: - global_df.to_csv(file_path, index=False) - messagebox.showinfo("CSV Saved", f"CSV file saved successfully to {file_path}.") - except Exception as e: - messagebox.showerror("Save Error", f"Failed to save CSV: {str(e)}") - -# Update Table -def update_table(rows_to_display=None): - global global_df - if global_df is not None: - if rows_to_display is not None: - data = global_df.head(rows_to_display).fillna("").values.tolist() - else: - data = global_df.fillna("").values.tolist() - column_names = global_df.columns.tolist() - table.load_data(data, column_names) - table.update_scroll_region() - -# Process Button Action -def process_button_action(): - row_numbers = simpledialog.askstring("Rows to Process", "Enter rows to process (e.g., 0-2,4,6-8):") - if row_numbers: - result = publish_rows_to_disk(row_numbers) - messagebox.showinfo("Process Result", result) - -# Open Button Action -def open_button_action(): - row_numbers = simpledialog.askstring("Rows to Open", "Enter rows to open (e.g., 0-2,4,6-8):") - if row_numbers: - result = view_html_pages(row_numbers) - messagebox.showinfo("Open Result", result) - -# Main GUI Setup -root = tk.Tk() -root.title("Webster123") -root.geometry("1200x600") - -toolbar = tk.Frame(root) -toolbar.pack(side="top", fill="x", pady=10) - -load_button = tk.Button(toolbar, text="Load CSV", command=load_csv) -load_button.pack(side="left", padx=5, pady=5) - -save_button = tk.Button(toolbar, text="Save CSV", command=save_csv) -save_button.pack(side="left", padx=5, pady=5) - -frame = tk.Frame(root) -frame.pack(fill="both", expand=True, pady=10) - -x_scrollbar = tk.Scrollbar(frame, orient="horizontal") -x_scrollbar.grid(row=2, column=1, sticky='ew') - -y_scrollbar = tk.Scrollbar(frame, orient="vertical") -y_scrollbar.grid(row=1, column=2, sticky='ns') - -# Use the SimpleTable class to create a custom table -table = SimpleTable(frame) -table.grid(row=1, column=1, sticky='nsew') - -# Configure scrollbars -x_scrollbar.config(command=table.xview_handler) -y_scrollbar.config(command=table.yview_handler) -table.config(xscrollcommand=x_scrollbar.set, yscrollcommand=y_scrollbar.set) - -# Configure grid weights to make the table expandable -frame.grid_rowconfigure(1, weight=1) -frame.grid_columnconfigure(1, weight=1) - -# Initialize with initial data if no CSV is loaded -if global_df is None: - global_df = pd.DataFrame(initial_data, columns=columns) - update_table() - -root.mainloop() \ No newline at end of file