This commit is contained in:
Vic Sergeev 2026-07-04 16:04:48 +03:00
commit a385308f38
44 changed files with 1614 additions and 0 deletions

219
app/ui/dialogs.py Normal file
View file

@ -0,0 +1,219 @@
"""Диалоговые окна"""
import tkinter as tk
from tkinter import ttk, messagebox
from app.config import Config
class PasswordDialog(tk.Toplevel):
"""Диалог установки/ввода мастер-пароля"""
def __init__(self, parent, auth, mode='set'):
super().__init__(parent)
self.auth = auth
self.mode = mode # 'set' или 'check'
self.result = False
self.title("Мастер-пароль" if mode == 'set' else "Введите пароль")
self.geometry("400x250")
self.resizable(False, False)
self.configure(bg=Config.COLORS['bg'])
self.transient(parent)
self.grab_set()
self.create_widgets()
# Центрируем окно
self.update_idletasks()
x = parent.winfo_rootx() + (parent.winfo_width() - 400) // 2
y = parent.winfo_rooty() + (parent.winfo_height() - 250) // 2
self.geometry(f"+{x}+{y}")
def create_widgets(self):
main_frame = tk.Frame(self, bg=Config.COLORS['bg'])
main_frame.pack(expand=True, fill='both', padx=20, pady=20)
if self.mode == 'set':
text = "Придумайте мастер-пароль\nдля защиты ваших заметок:"
else:
text = "Введите мастер-пароль:"
tk.Label(
main_frame,
text=text,
bg=Config.COLORS['bg'],
fg=Config.COLORS['fg'],
font=('Arial', 12),
wraplength=350
).pack(pady=(0, 15))
# Поле ввода пароля
self.password_var = tk.StringVar()
self.password_entry = ttk.Entry(
main_frame,
textvariable=self.password_var,
show='*',
font=('Arial', 12)
)
self.password_entry.pack(fill='x', pady=(0, 10))
self.password_entry.focus()
if self.mode == 'set':
# Подтверждение пароля
tk.Label(
main_frame,
text="Подтвердите пароль:",
bg=Config.COLORS['bg'],
fg=Config.COLORS['fg'],
font=('Arial', 11)
).pack()
self.confirm_var = tk.StringVar()
self.confirm_entry = ttk.Entry(
main_frame,
textvariable=self.confirm_var,
show='*',
font=('Arial', 12)
)
self.confirm_entry.pack(fill='x', pady=(0, 15))
# Чекбокс "спрашивать при входе"
self.ask_var = tk.BooleanVar(value=True)
tk.Checkbutton(
main_frame,
text="Спрашивать при входе",
variable=self.ask_var,
bg=Config.COLORS['bg'],
fg=Config.COLORS['fg'],
selectcolor=Config.COLORS['bg'],
activebackground=Config.COLORS['bg'],
activeforeground=Config.COLORS['fg']
).pack(pady=(0, 15))
# Кнопки
button_frame = tk.Frame(main_frame, bg=Config.COLORS['bg'])
button_frame.pack(fill='x')
if self.mode == 'set':
tk.Button(
button_frame,
text="Установить пароль",
command=self.set_password,
bg=Config.COLORS['accent'],
fg=Config.COLORS['fg'],
font=('Arial', 11, 'bold'),
relief='flat',
cursor='hand2'
).pack(fill='x', pady=(0, 5))
else:
tk.Button(
button_frame,
text="Войти",
command=self.check_password,
bg=Config.COLORS['accent'],
fg=Config.COLORS['fg'],
font=('Arial', 11, 'bold'),
relief='flat',
cursor='hand2'
).pack(fill='x', pady=(0, 5))
if self.mode == 'check':
tk.Button(
button_frame,
text="Отмена",
command=self.destroy,
bg=Config.COLORS['button_bg'],
fg=Config.COLORS['fg'],
relief='flat',
cursor='hand2'
).pack(fill='x')
def set_password(self):
password = self.password_var.get()
confirm = self.confirm_var.get()
if not password:
messagebox.showwarning("Ошибка", "Введите пароль")
return
if password != confirm:
messagebox.showwarning("Ошибка", "Пароли не совпадают")
return
self.auth.set_master_password(password)
self.auth.set_ask_password_on_startup(self.ask_var.get())
self.result = True
self.destroy()
def check_password(self):
password = self.password_var.get()
if self.auth.check_password(password):
self.result = True
self.destroy()
else:
messagebox.showerror("Ошибка", "Неверный пароль")
self.password_var.set('')
self.password_entry.focus()
class ConfirmDialog(tk.Toplevel):
"""Диалог подтверждения действия"""
def __init__(self, parent, title, message):
super().__init__(parent)
self.result = False
self.title(title)
self.geometry("350x150")
self.resizable(False, False)
self.configure(bg=Config.COLORS['bg'])
self.transient(parent)
self.grab_set()
# Центрируем окно
self.update_idletasks()
x = parent.winfo_rootx() + (parent.winfo_width() - 350) // 2
y = parent.winfo_rooty() + (parent.winfo_height() - 150) // 2
self.geometry(f"+{x}+{y}")
# Сообщение
tk.Label(
self,
text=message,
bg=Config.COLORS['bg'],
fg=Config.COLORS['fg'],
font=('Arial', 11),
wraplength=320
).pack(expand=True, pady=(20, 10))
# Кнопки
btn_frame = tk.Frame(self, bg=Config.COLORS['bg'])
btn_frame.pack(fill='x', padx=20, pady=(0, 20))
tk.Button(
btn_frame,
text="Да",
command=self.confirm,
bg=Config.COLORS['danger'],
fg=Config.COLORS['fg'],
relief='flat',
cursor='hand2',
width=10
).pack(side='left', padx=(0, 10))
tk.Button(
btn_frame,
text="Нет",
command=self.destroy,
bg=Config.COLORS['button_bg'],
fg=Config.COLORS['fg'],
relief='flat',
cursor='hand2',
width=10
).pack(side='left')
def confirm(self):
self.result = True
self.destroy()