import tkinter as tk
from tkinter import filedialog, messagebox

class SimpleNotepad:
    def __init__(self, root):
        self.root = root
        self.root.title("记事本")
        self.root.geometry("800x600")

        # 1. 文本区域（开启撤销功能 undo=True）
        self.text_area = tk.Text(
            root, 
            font=("微软雅黑", 14),  # 适配中文系统
            wrap=tk.WORD,
            undo=True  # 核心：开启撤销/重做
        )
        self.text_area.pack(expand=True, fill=tk.BOTH, padx=5, pady=5)

        # 2. 菜单栏
        self.menu_bar = tk.Menu(root)
        root.config(menu=self.menu_bar)

        # 文件菜单
        file_menu = tk.Menu(self.menu_bar, tearoff=0)
        self.menu_bar.add_cascade(label="文件(F)", menu=file_menu)
        file_menu.add_command(label="新建    Ctrl+N", command=self.new_file)
        file_menu.add_command(label="打开    Ctrl+O", command=self.open_file)
        file_menu.add_command(label="保存    Ctrl+S", command=self.save_file)
        file_menu.add_command(label="另存为  Ctrl+Shift+S", command=self.save_as)
        file_menu.add_separator()
        file_menu.add_command(label="退出", command=self.exit_editor)

        # 编辑菜单
        edit_menu = tk.Menu(self.menu_bar, tearoff=0)
        self.menu_bar.add_cascade(label="编辑(E)", menu=edit_menu)
        edit_menu.add_command(label="撤销    Ctrl+Z", command=lambda: self.text_area.event_generate("<<Undo>>"))
        edit_menu.add_command(label="重做    Ctrl+Y", command=lambda: self.text_area.event_generate("<<Redo>>"))
        edit_menu.add_separator()
        edit_menu.add_command(label="剪切    Ctrl+X", command=lambda: self.text_area.event_generate("<<Cut>>"))
        edit_menu.add_command(label="复制    Ctrl+C", command=lambda: self.text_area.event_generate("<<Copy>>"))
        edit_menu.add_command(label="粘贴    Ctrl+V", command=lambda: self.text_area.event_generate("<<Paste>>"))
        edit_menu.add_command(label="清空全部", command=self.clear_all)

        # 3. 底部状态栏
        self.status_bar = tk.Label(root, text="就绪", anchor=tk.W)
        self.status_bar.pack(fill=tk.X, padx=5, pady=2)

        # 4. 绑定快捷键
        self.bind_shortcuts()

        # 5. 监听窗口关闭事件
        self.root.protocol("WM_DELETE_WINDOW", self.exit_editor)

        # 当前编辑的文件路径
        self.current_file = None

    def bind_shortcuts(self):
        """绑定快捷键"""
        self.root.bind("<Control-n>", lambda e: self.new_file())
        self.root.bind("<Control-o>", lambda e: self.open_file())
        self.root.bind("<Control-s>", lambda e: self.save_file())
        self.root.bind("<Control-S>", lambda e: self.save_as())  # Shift+S

    def new_file(self):
        """新建文件"""
        # 检查是否有未保存内容
        if self.text_area.get(1.0, tk.END+'-1c') != "" and not self.confirm_save():
            return
        self.text_area.delete(1.0, tk.END)
        self.current_file = None
        self.root.title("Tkinter 记事本")
        self.status_bar.config(text="新建文档")

    def open_file(self):
        """打开文件"""
        if not self.confirm_save():
            return
        file_path = filedialog.askopenfilename(
            defaultextension=".txt",
            filetypes=[("文本文档", "*.txt"), ("所有文件", "*.*")]
        )
        if file_path:
            try:
                self.current_file = file_path
                with open(file_path, "r", encoding="utf-8") as f:
                    content = f.read()
                self.text_area.delete(1.0, tk.END)
                self.text_area.insert(tk.END, content)
                self.root.title(f"Tkinter 记事本 - {file_path}")
                self.status_bar.config(text=f"已打开：{file_path}")
            except Exception as e:
                messagebox.showerror("错误", f"打开文件失败：{str(e)}")

    def save_file(self):
        """保存文件"""
        if self.current_file:
            try:
                # END+'-1c' 去除末尾多余空行
                content = self.text_area.get(1.0, tk.END+'-1c')
                with open(self.current_file, "w", encoding="utf-8") as f:
                    f.write(content)
                self.status_bar.config(text="保存成功")
                messagebox.showinfo("提示", "保存成功！")
            except Exception as e:
                messagebox.showerror("错误", f"保存失败：{str(e)}")
        else:
            self.save_as()

    def save_as(self):
        """另存为"""
        file_path = filedialog.asksaveasfilename(
            defaultextension=".txt",
            filetypes=[("文本文档", "*.txt"), ("所有文件", "*.*")]
        )
        if file_path:
            self.current_file = file_path
            self.save_file()

    def clear_all(self):
        """清空文本（二次确认）"""
        if messagebox.askyesno("确认", "确定要清空所有内容吗？"):
            self.text_area.delete(1.0, tk.END)
            self.status_bar.config(text="已清空")

    def confirm_save(self):
        """确认是否保存未保存的内容"""
        content = self.text_area.get(1.0, tk.END+'-1c')
        if not content:
            return True
        res = messagebox.askyesnocancel("提示", "文档已修改，是否保存？")
        if res:  # 是
            self.save_file()
            return True
        elif res is False:  # 否
            return True
        else:  # 取消
            return False

    def exit_editor(self):
        """退出编辑器（确认保存）"""
        if self.confirm_save():
            self.root.quit()

if __name__ == "__main__":
    window = tk.Tk()
    app = SimpleNotepad(window)
    window.mainloop()