SXXXXXXX_MarkdownConverter/markdownconverter/gui/gui.py
2025-06-11 09:12:34 +02:00

142 lines
5.7 KiB
Python

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()