import os import subprocess import json import ttkbootstrap as tb from ttkbootstrap.constants import * from tkinter import filedialog, messagebox, StringVar, BooleanVar from ..core.core import convert_markdown CONFIG_FILE = os.path.join(os.path.expanduser("~"), ".markdown_converter_config.json") def save_config(font_name): # This function seems duplicated with config.py, consider centralizing with open(CONFIG_FILE, "w", encoding="utf-8") as f: json.dump({"font": font_name}, f) def load_config(): # This function seems duplicated with config.py, consider centralizing if os.path.exists(CONFIG_FILE): with open(CONFIG_FILE, "r", encoding="utf-8") as f: data = json.load(f) return data.get("font", "") return "" def open_with_default_app(filepath): """Opens a file with the default registered application.""" if not filepath: messagebox.showwarning("Warning", "No output file has been generated yet.") return try: os.startfile(filepath) # Windows-specific except FileNotFoundError: messagebox.showerror("Error", f"File not found:\n{filepath}") except Exception as e: messagebox.showerror("Error", f"Could not open the file:\n{str(e)}") def open_output_folder(filepath): """Opens the folder containing the specified file.""" if not filepath: messagebox.showwarning("Warning", "No output file has been generated yet.") return try: folder = os.path.dirname(filepath) os.startfile(folder) except Exception as e: messagebox.showerror("Error", f"Could not open the folder:\n{str(e)}") def run_app(): """Initializes and runs the main application window.""" app = tb.Window(themename="sandstone") app.title("Markdown Converter") app.geometry("680x280") # Increased height for the new widget app.resizable(False, False) # --- Variables --- selected_file = StringVar() selected_font = StringVar(value=load_config()) selected_template = StringVar() output_path = StringVar() add_toc_var = BooleanVar(value=True) # Variable for the TOC checkbox # --- Functions --- def browse_markdown(): """Opens a file dialog to select a Markdown file.""" path = filedialog.askopenfilename( title="Select a Markdown file", filetypes=[("Markdown files", "*.md"), ("All files", "*.*")] ) if path: selected_file.set(path) def browse_template(): """Opens a file dialog to select a DOCX or DOTX template file.""" path = filedialog.askopenfilename( title="Select a template file", filetypes=[ ("Word Documents", "*.docx"), ("Word Templates", "*.dotx"), ("All files", "*.*") ] ) if path: selected_template.set(path) def convert(fmt): """Handles the conversion process when a button is clicked.""" file_path = selected_file.get() font = selected_font.get() template = selected_template.get() add_toc = add_toc_var.get() if not file_path: messagebox.showerror("Error", "Please select a Markdown file.") return try: output = convert_markdown(file_path, fmt, add_toc, font, template) output_path.set(output) save_config(font) # Save font on successful conversion messagebox.showinfo("Success", f"File converted successfully:\n{output}") except Exception as e: messagebox.showerror("Error", f"An error occurred during conversion:\n{str(e)}") # --- Layout --- main_frame = tb.Frame(app, padding=10) main_frame.pack(fill=BOTH, expand=True) # Row 0: Input file tb.Label(main_frame, text="Markdown File:").grid(row=0, column=0, padx=(0, 10), pady=5, sticky="w") tb.Entry(main_frame, textvariable=selected_file, width=60).grid(row=0, column=1, padx=5, sticky="ew") tb.Button(main_frame, text="Browse...", command=browse_markdown, bootstyle=PRIMARY).grid(row=0, column=2, padx=5) # Row 1: Font (for PDF) tb.Label(main_frame, text="Font (PDF):").grid(row=1, column=0, padx=(0, 10), pady=5, sticky="w") fonts = ["Arial", "Times New Roman", "Verdana", "Calibri", "Courier New"] tb.Combobox(main_frame, values=fonts, textvariable=selected_font, width=30, bootstyle=INFO).grid(row=1, column=1, sticky="w", padx=5) # Row 2: Template (for DOCX) tb.Label(main_frame, text="Template (DOCX):").grid(row=2, column=0, padx=(0, 10), pady=5, sticky="w") tb.Entry(main_frame, textvariable=selected_template, width=60).grid(row=2, column=1, padx=5, sticky="ew") tb.Button(main_frame, text="Browse...", command=browse_template, bootstyle=SECONDARY).grid(row=2, column=2, padx=5) # Row 3: Options (TOC) tb.Checkbutton( main_frame, text="Add Table of Contents at the beginning", variable=add_toc_var, bootstyle="primary-round-toggle" ).grid(row=3, column=1, pady=10, sticky="w") # Row 4: Action Buttons action_frame = tb.Frame(main_frame) action_frame.grid(row=4, column=0, columnspan=3, pady=10) tb.Button(action_frame, text="Convert to PDF", command=lambda: convert("PDF"), bootstyle=SUCCESS).pack(side=LEFT, padx=5) tb.Button(action_frame, text="Convert to DOCX", command=lambda: convert("DOCX"), bootstyle=SUCCESS).pack(side=LEFT, padx=5) tb.Button(action_frame, text="Open File", command=lambda: open_with_default_app(output_path.get()), bootstyle=WARNING).pack(side=LEFT, padx=(20, 5)) tb.Button(action_frame, text="Open Folder", command=lambda: open_output_folder(output_path.get()), bootstyle=WARNING).pack(side=LEFT, padx=5) main_frame.columnconfigure(1, weight=1) app.mainloop()