108 lines
3.7 KiB
Python
108 lines
3.7 KiB
Python
import customtkinter as ctk
|
|
from view.theme import theme_manager
|
|
|
|
class NotificationDialog(ctk.CTkToplevel):
|
|
# 미확인 알림 다이얼로그 싱글톤 참조
|
|
_unchecked_dialog = None
|
|
|
|
def __init__(self, controller, title, msg, voc_id=None):
|
|
# 미확인 알림(⚠️ 미확인 VOC)인 경우 이미 열려있으면 기존 다이얼로그 앞으로 가져오기
|
|
is_unchecked = title.startswith("⚠️ 미확인 VOC")
|
|
if is_unchecked and NotificationDialog._unchecked_dialog is not None:
|
|
# 기존 다이얼로그를 앞으로 가져옴
|
|
NotificationDialog._unchecked_dialog.lift()
|
|
NotificationDialog._unchecked_dialog.focus_force()
|
|
return
|
|
|
|
super().__init__(controller.root)
|
|
self.controller = controller
|
|
self.voc_id = voc_id
|
|
self.is_unchecked = is_unchecked
|
|
|
|
# 미확인 알림이면 싱글톤 참조 저장
|
|
if is_unchecked:
|
|
NotificationDialog._unchecked_dialog = self
|
|
|
|
self.title(title)
|
|
self.attributes("-topmost", True) # 항상 위
|
|
self.resizable(False, False)
|
|
|
|
# UI 구성
|
|
self.width = 460
|
|
self.height = 400
|
|
self._center_window()
|
|
|
|
# 프레임
|
|
self.frame = ctk.CTkFrame(self)
|
|
self.frame.pack(fill="both", expand=True, padx=20, pady=20)
|
|
|
|
# 제목 (부서 정보 등)
|
|
self.lbl_title = ctk.CTkLabel(
|
|
self.frame, text=title,
|
|
font=theme_manager.get_font(14, "bold"),
|
|
text_color=theme_manager.MAIN_COLOR if hasattr(theme_manager, 'MAIN_COLOR') else "#1F6AA5"
|
|
)
|
|
self.lbl_title.pack(pady=(0, 10))
|
|
|
|
# 메시지 (VOC 제목)
|
|
self.lbl_msg = ctk.CTkLabel(
|
|
self.frame, text=msg,
|
|
font=theme_manager.get_font(12),
|
|
wraplength=350
|
|
)
|
|
self.lbl_msg.pack(pady=(0, 20), expand=True)
|
|
|
|
# 버튼 영역
|
|
self.btn_frame = ctk.CTkFrame(self.frame, fg_color="transparent")
|
|
self.btn_frame.pack(fill="x", side="bottom")
|
|
|
|
self.btn_close = ctk.CTkButton(
|
|
self.btn_frame, text="닫기", width=100,
|
|
fg_color="gray", command=self._on_close
|
|
)
|
|
self.btn_close.pack(side="right", padx=5)
|
|
|
|
self.btn_list = ctk.CTkButton(
|
|
self.btn_frame, text="전체내역 보기", width=120,
|
|
command=self._on_open_list
|
|
)
|
|
self.btn_list.pack(side="right", padx=5)
|
|
|
|
self.btn_view = ctk.CTkButton(
|
|
self.btn_frame, text="상세보기", width=100,
|
|
command=self._on_view
|
|
)
|
|
self.btn_view.pack(side="right", padx=5)
|
|
|
|
# 단건 알림이 아닐 경우 상세보기 비활성화
|
|
if not self.voc_id:
|
|
self.btn_view.configure(state="disabled")
|
|
|
|
# 포커스 강제
|
|
self.lift()
|
|
self.focus_force()
|
|
|
|
# 다이얼로그 종료 시 싱글톤 참조 정리
|
|
self.protocol("WM_DELETE_WINDOW", self._on_close)
|
|
|
|
def _on_view(self):
|
|
if self.voc_id:
|
|
self.controller.open_list_view(focus_id=self.voc_id)
|
|
self._on_close()
|
|
|
|
def _on_open_list(self):
|
|
self.controller.open_list_view()
|
|
self._on_close()
|
|
|
|
def _on_close(self):
|
|
"""다이얼로그 종료 시 싱글톤 참조 정리"""
|
|
if self.is_unchecked and NotificationDialog._unchecked_dialog is self:
|
|
NotificationDialog._unchecked_dialog = None
|
|
self.destroy()
|
|
|
|
def _center_window(self):
|
|
self.update_idletasks()
|
|
x = (self.winfo_screenwidth() // 2) - (self.width // 2)
|
|
y = (self.winfo_screenheight() // 2) - (self.height // 2)
|
|
self.geometry(f"{self.width}x{self.height}+{x}+{y}")
|