Mycar_SMS_Sender/gui/template_management_dialog.py

183 lines
8.5 KiB
Python

# gui/template_management_dialog.py
from PySide6.QtWidgets import (QDialog, QHBoxLayout, QVBoxLayout, QListWidget, QScrollArea, QWidget, QMessageBox)
from PySide6.QtCore import Qt, QSettings, Slot
from gui.template_card import TemplateCard
from src.database_module import DatabaseManager
from gui.template_card import ORDER_STEPS # 또는 별도로 ORDER_STEPS 상수를 정의
class TemplateManagementDialog(QDialog):
def __init__(self, logger, parent=None):
super().__init__(parent)
self.logger = logger
self.setWindowTitle("템플릿 관리")
self.resize(800, 600)
self.settings = QSettings("MyCompany", "MySMSApp")
self.current_stage = 1
self.selected_template_id = None
self.db_manager = DatabaseManager()
self.plus_card = None # 플러스 카드는 한 번만 생성하도록 함
self.setup_ui()
self.apply_styles()
self.load_order_steps()
self.load_templates_for_stage(self.current_stage)
self.restore_settings()
def setup_ui(self):
main_layout = QHBoxLayout(self)
from PySide6.QtWidgets import QListWidget
self.step_list = QListWidget()
self.step_list.setToolTip("주문 단계별 템플릿을 확인하려면 단계를 선택하세요.")
for stage, name in ORDER_STEPS.items():
self.step_list.addItem(f"{stage}: {name}")
self.step_list.currentRowChanged.connect(self.on_step_changed)
main_layout.addWidget(self.step_list, 1)
self.scroll_area = QScrollArea()
self.scroll_area.setWidgetResizable(True)
self.card_container = QWidget()
self.card_layout = QVBoxLayout(self.card_container)
self.card_layout.setSpacing(10)
self.scroll_area.setWidget(self.card_container)
main_layout.addWidget(self.scroll_area, 3)
def apply_styles(self):
style = """
QDialog { background-color: #fafafa; }
QListWidget { border: 1px solid #ccc; border-radius: 4px; font-size: 14px; padding: 4px; }
QListWidget::item:selected { background-color: #1976D2; color: white; border: 1px solid #115293; }
QScrollArea { background-color: #ffffff; }
"""
self.setStyleSheet(style)
def load_order_steps(self):
self.step_list.setCurrentRow(0)
def load_templates_for_stage(self, stage: int):
self.current_stage = stage
# 기존 카드 레이아웃의 모든 위젯 삭제
while self.card_layout.count():
item = self.card_layout.takeAt(0)
widget = item.widget()
if widget is not None:
widget.deleteLater()
self.template_cards = {}
# DB에서 해당 단계의 템플릿 불러오기
templates = self.db_manager.get_templates_by_stage(stage)
for tpl in templates:
card = TemplateCard(tpl.id, tpl.name, tpl.content, is_plus=False)
card.clicked.connect(self.on_template_selected)
card.edit_completed.connect(self.on_template_edited)
card.delete_requested.connect(self.on_template_deleted)
self.card_layout.addWidget(card)
self.template_cards[tpl.id] = card
# 플러스 카드 추가: plus_card은 단 한 번만 생성
if self.plus_card is None:
self.plus_card = TemplateCard(is_plus=True)
self.plus_card.clicked.connect(self.on_add_template)
self.plus_card.edit_completed.connect(self.on_new_template_added)
self.card_layout.addWidget(self.plus_card)
@Slot(int)
def on_step_changed(self, row: int):
stage = row + 1
# 현재 수정 모드에 있는 카드가 있으면 수정 취소를 시도
if TemplateCard.currently_editing is not None:
editing_card = TemplateCard.currently_editing
try:
editing_card.cancel_edit_mode()
except Exception as e:
self.logger.log(f"수정 모드 취소 중 오류 발생: {e}", level=1)
finally:
TemplateCard.currently_editing = None
self.logger.log(f"주문 단계 변경: {stage} - {ORDER_STEPS.get(stage)}", level=1)
self.load_templates_for_stage(stage)
last_template = self.settings.value(f"selected_template_stage_{stage}", None)
if last_template is not None:
try:
last_template = int(last_template)
self.select_template(last_template)
except ValueError:
pass
@Slot(int)
def on_template_deleted(self, template_id: int):
# 삭제 요청이 들어오면 DB에서 삭제 후 UI 갱신
from PySide6.QtWidgets import QMessageBox
reply = QMessageBox.question(self, "템플릿 삭제", "이 템플릿을 삭제하시겠습니까?",
QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
if reply == QMessageBox.Yes:
self.db_manager.delete_template(template_id)
self.logger.log(f"템플릿 삭제됨: ID {template_id}", level=1)
self.load_templates_for_stage(self.current_stage)
@Slot(int)
def on_template_selected(self, template_id: int):
# 현재 수정 모드에 있는 카드가 있다면
if TemplateCard.currently_editing is not None:
editing_card = TemplateCard.currently_editing
# 이미 편집 중인 카드가 선택하려는 카드와 다르면
if editing_card.template_id != template_id:
reply = QMessageBox.question(
self,
"편집 취소",
"현재 템플릿을 편집 중입니다. 편집을 취소하고 다른 템플릿을 선택하시겠습니까?",
QMessageBox.Yes | QMessageBox.No,
QMessageBox.No
)
if reply == QMessageBox.Yes:
editing_card.cancel_edit_mode() # 수정 취소 처리
else:
return # 선택 전환 취소
# 모든 카드의 선택 해제 시도 (이미 삭제된 위젯은 예외로 제거)
for tpl_id, card in list(self.template_cards.items()):
try:
if not card.edit_mode:
card.set_selected(False)
except RuntimeError:
del self.template_cards[tpl_id]
# 선택하려는 템플릿 카드가 존재하면 선택 처리
if template_id in self.template_cards:
try:
self.template_cards[template_id].set_selected(True)
except RuntimeError:
pass
self.selected_template_id = template_id
self.settings.setValue(f"selected_template_stage_{self.current_stage}", template_id)
self.logger.log(f"템플릿 선택됨: ID {template_id}", level=1)
@Slot()
def on_add_template(self):
# 플러스 카드가 클릭되면, 해당 PlusCard를 수정 모드로 전환하여 새 템플릿 추가를 시작합니다.
sender = self.sender()
if sender:
sender.enter_edit_mode()
@Slot(int, str, str)
def on_new_template_added(self, template_id: int, name: str, content: str):
# 새 템플릿 추가 완료 후 DB에 저장하고 UI 갱신
new_template = self.db_manager.insert_template(stage=self.current_stage, name=name, content=content, is_default=False)
self.logger.log(f"새 템플릿 추가됨: {new_template.name}", level=1)
self.load_templates_for_stage(self.current_stage)
@Slot(int, str, str)
def on_template_edited(self, template_id: int, name: str, content: str):
# 기존 템플릿 수정 완료 시 DB 업데이트
self.db_manager.update_template(template_id, name=name, content=content)
self.logger.log(f"템플릿 수정됨: ID {template_id}", level=1)
self.load_templates_for_stage(self.current_stage)
def select_template(self, template_id: int):
if template_id in self.template_cards:
self.on_template_selected(template_id)
def restore_settings(self):
last_step = self.settings.value("last_selected_step", 1)
self.step_list.setCurrentRow(int(last_step) - 1)
self.logger.log("템플릿 설정 복원 완료", level=1)
def closeEvent(self, event):
# 다이얼로그가 닫힐 때 현재 수정 모드에 있는 카드가 있다면 초기화
TemplateCard.currently_editing = None
super().closeEvent(event)