""" 样式管理GUI模块 提供样式选择、预览、编辑的图形界面。 """ import tkinter as tk from tkinter import ttk, filedialog, messagebox, simpledialog from typing import Optional from style_manager import style_manager, DocumentStyle from config import Config from advanced_style_editor import open_advanced_editor # 创建配置管理器实例 config_manager = Config() def create_style_tab(parent): """创建样式管理选项卡""" style_frame = ttk.Frame(parent) # 标题 ttk.Label(style_frame, text='文章排版样式管理', font=('', 12, 'bold')).pack(anchor='w', padx=10, pady=(10, 5)) ttk.Separator(style_frame, orient='horizontal').pack(fill='x', padx=10, pady=5) # 样式选择区域 selection_frame = ttk.LabelFrame(style_frame, text='样式选择', padding="10") selection_frame.pack(fill='x', padx=10, pady=5) # 当前样式 current_frame = ttk.Frame(selection_frame) current_frame.pack(fill='x', pady=2) ttk.Label(current_frame, text='当前样式:', width=12).pack(side='left') style_var = tk.StringVar(value=config_manager.current_style) style_combo = ttk.Combobox(current_frame, textvariable=style_var, values=style_manager.get_style_names(), state='readonly', width=25) style_combo.pack(side='left', padx=(0, 10)) def on_style_change(*args): config_manager.set('current_style', style_var.get()) _update_style_info() style_var.trace('w', on_style_change) ttk.Button(current_frame, text='预览', command=lambda: _preview_style(style_var.get(), parent)).pack(side='left', padx=5) # 样式信息显示 info_frame = ttk.Frame(selection_frame) info_frame.pack(fill='x', pady=(5, 0)) info_text = tk.Text(info_frame, height=3, wrap=tk.WORD, state='disabled') info_text.pack(fill='x') def _update_style_info(): """更新样式信息显示""" style = style_manager.get_style(style_var.get()) if style: info = f"描述: {style.description}\n作者: {style.author} 版本: {style.version}\n" info += f"正文字体: {style.body_font.name if style.body_font else '默认'} {style.body_font.size if style.body_font else 12}pt" info_text.config(state='normal') info_text.delete(1.0, tk.END) info_text.insert(1.0, info) info_text.config(state='disabled') # 样式管理区域 management_frame = ttk.LabelFrame(style_frame, text='样式管理', padding="10") management_frame.pack(fill='x', padx=10, pady=5) button_frame = ttk.Frame(management_frame) button_frame.pack(fill='x') def _create_new_style(): """创建新样式""" name = simpledialog.askstring("新建样式", "请输入样式名称:") if name and name not in style_manager.get_style_names(): new_style = DocumentStyle(name=name, description="自定义样式", author="用户") if style_manager.create_custom_style(new_style): style_combo['values'] = style_manager.get_style_names() messagebox.showinfo("成功", f"样式 '{name}' 创建成功") else: messagebox.showerror("错误", "创建样式失败") elif name: messagebox.showerror("错误", "样式名称已存在") def _duplicate_style(): """复制样式""" current_name = style_var.get() if current_name: new_name = simpledialog.askstring("复制样式", f"基于 '{current_name}' 创建新样式,请输入新名称:") if new_name and new_name not in style_manager.get_style_names(): if style_manager.duplicate_style(current_name, new_name): style_combo['values'] = style_manager.get_style_names() messagebox.showinfo("成功", f"样式 '{new_name}' 创建成功") else: messagebox.showerror("错误", "复制样式失败") elif new_name: messagebox.showerror("错误", "样式名称已存在") def _edit_style_advanced(): """高级样式编辑""" current_name = style_var.get() if not current_name: messagebox.showwarning("警告", "请先选择一个样式") return # 创建高级编辑窗口 try: edit_window = open_advanced_editor(parent, current_name) if edit_window: def on_window_close(): # 更新样式列表 style_combo['values'] = style_manager.get_style_names() _update_style_info() # 等待窗口关闭后更新 style_frame.after(1000, on_window_close) except Exception as e: messagebox.showerror("错误", f"打开高级编辑器失败: {str(e)}") def _delete_style(): """删除样式""" current_name = style_var.get() if current_name and current_name not in style_manager.builtin_styles: if messagebox.askyesno("确认删除", f"确定要删除样式 '{current_name}' 吗?"): if style_manager.delete_custom_style(current_name): style_combo['values'] = style_manager.get_style_names() style_var.set(style_manager.get_style_names()[0] if style_manager.get_style_names() else "") messagebox.showinfo("成功", "样式删除成功") else: messagebox.showerror("错误", "删除样式失败") else: messagebox.showerror("错误", "无法删除内置样式") def _export_style(): """导出样式""" current_name = style_var.get() if current_name: file_path = filedialog.asksaveasfilename( title="导出样式", defaultextension=".json", filetypes=[("JSON文件", "*.json"), ("所有文件", "*.*")] ) if file_path: if style_manager.export_style(current_name, file_path): messagebox.showinfo("成功", "样式导出成功") else: messagebox.showerror("错误", "导出样式失败") def _import_style(): """导入样式""" file_path = filedialog.askopenfilename( title="导入样式", filetypes=[("JSON文件", "*.json"), ("所有文件", "*.*")] ) if file_path: style_name = style_manager.import_style(file_path) if style_name: style_combo['values'] = style_manager.get_style_names() messagebox.showinfo("成功", f"样式 '{style_name}' 导入成功") else: messagebox.showerror("错误", "导入样式失败") # 管理按钮 ttk.Button(button_frame, text='新建', command=_create_new_style).pack(side='left', padx=5) ttk.Button(button_frame, text='复制', command=_duplicate_style).pack(side='left', padx=5) ttk.Button(button_frame, text='高级编辑', command=_edit_style_advanced).pack(side='left', padx=5) ttk.Button(button_frame, text='删除', command=_delete_style).pack(side='left', padx=5) ttk.Button(button_frame, text='导出', command=_export_style).pack(side='left', padx=5) ttk.Button(button_frame, text='导入', command=_import_style).pack(side='left', padx=5) # 初始化信息显示 _update_style_info() return style_frame def _preview_style(style_name: str, parent): """预览样式""" style = style_manager.get_style(style_name) if not style: return preview_text = f"""样式预览: {style.name} 正文示例: 这是正文内容,使用 {style.body_font.name if style.body_font else '默认字体'} 字体, 大小为 {style.body_font.size if style.body_font else 12} 磅, 行距为 {style.body_paragraph.line_spacing if style.body_paragraph else 1.5} 倍。 # 一级标题示例 ## 二级标题示例 ### 三级标题示例 这是一个包含**粗体**和*斜体*的段落。 > 这是引用块的示例内容。 `这是行内代码`的示例。 - 无序列表项目1 - 无序列表项目2 1. 有序列表项目1 2. 有序列表项目2 """ # 创建预览窗口 preview_window = tk.Toplevel(parent) preview_window.title(f'样式预览 - {style_name}') preview_window.geometry('500x400') preview_window.transient(parent) text_widget = tk.Text(preview_window, wrap=tk.WORD, padx=10, pady=10) text_widget.pack(fill='both', expand=True, padx=10, pady=10) text_widget.insert(1.0, preview_text) text_widget.config(state='disabled') ttk.Button(preview_window, text='关闭', command=preview_window.destroy).pack(pady=10) # 兼容性函数 def show_style_manager(parent=None): """显示样式管理器窗口""" if parent is None: root = tk.Tk() root.withdraw() parent = root window = tk.Toplevel(parent) window.title('样式管理器') window.geometry('600x500') window.transient(parent) window.grab_set() style_tab = create_style_tab(window) style_tab.pack(fill='both', expand=True, padx=10, pady=10) ttk.Button(window, text='关闭', command=window.destroy).pack(pady=10)