handOver2/ui/dialogs/todo_input_dialog.py

206 lines
6.6 KiB
Python

# -*- coding: utf-8 -*-
"""
할일 입력 다이얼로그 모듈
할일 입력을 위한 다이얼로그입니다.
"""
from datetime import date, datetime, time
from typing import List, Optional
from PySide6.QtWidgets import (
QWidget, QHBoxLayout, QVBoxLayout, QLabel, QPushButton
)
from PySide6.QtCore import Qt, Signal
from PySide6.QtGui import QFont
from ui.base.base_dialog import BaseDialog
from ui.components.custom_input import CustomLineEdit, CustomTextEdit, LabeledInput
from database.models import Todo, TodoCategory
from core.config import ConfigManager
from core.logger import get_logger
logger = get_logger(__name__)
class CategoryChip(QPushButton):
"""카테고리 선택 칩"""
chip_selected = Signal(str) # category
def __init__(self, category: str, icon: str = "", parent=None):
super().__init__(parent)
self.config = ConfigManager()
self.category = category
self._is_selected = False
if category == TodoCategory.ARRIVAL_INSPECTION:
self.setText(f"🚃 {category}")
self.icon_color = "#8b5cf6"
elif category == TodoCategory.TASK:
self.setText(f"🔧 {category}")
self.icon_color = "#f59e0b"
else:
self.setText(f"📝 {category}")
self.icon_color = "#3b82f6"
self.setMinimumWidth(90)
self.setFixedHeight(36)
self.setCursor(Qt.PointingHandCursor)
self.setFont(QFont("GmarketSans", 11, QFont.Bold))
self.clicked.connect(self._on_clicked)
self._apply_style()
def _on_clicked(self):
"""클릭 이벤트"""
self.chip_selected.emit(self.category)
def set_selected(self, selected: bool):
"""선택 상태 설정"""
self._is_selected = selected
self._apply_style()
def _apply_style(self):
"""스타일 적용"""
theme = self.config.theme
if self._is_selected:
self.setStyleSheet(f"""
QPushButton {{
background-color: {self.icon_color};
color: white;
border: 3px solid {self.icon_color};
border-radius: 8px;
padding: 0 12px;
font-weight: bold;
}}
""")
else:
if theme == 'dark':
bg = "#334155"
text = "#94a3b8"
else:
bg = "#e2e8f0"
text = "#64748b"
self.setStyleSheet(f"""
QPushButton {{
background-color: {bg};
color: {text};
border: 2px solid transparent;
border-radius: 8px;
padding: 0 12px;
}}
QPushButton:hover {{
background-color: {self.icon_color};
color: white;
}}
""")
class TodoInputDialog(BaseDialog):
"""할일 입력 다이얼로그"""
def __init__(
self,
parent=None,
todo_date: date = None,
todo: Todo = None
):
title = "할일 추가" if todo is None else "할일 편집"
super().__init__(parent, title=title, width=450, height=500)
self.todo_date = todo_date or date.today()
self.todo = todo
self._selected_category: str = TodoCategory.GENERAL
self._category_chips: List[CategoryChip] = []
self._setup_fields()
self.add_confirm_cancel_buttons()
if todo:
self._load_todo(todo)
def _setup_fields(self):
"""필드 설정"""
theme = self.config.theme
text_color = "#f8fafc" if theme == 'dark' else "#1e293b"
# 카테고리 섹션
category_label = QLabel("카테고리")
category_label.setFont(QFont("GmarketSans", 12, QFont.Bold))
category_label.setStyleSheet(f"color: {text_color};")
self.content_layout.addWidget(category_label)
# 카테고리 칩 컨테이너
category_container = QWidget()
category_layout = QHBoxLayout(category_container)
category_layout.setContentsMargins(0, 0, 0, 0)
category_layout.setSpacing(8)
categories = [TodoCategory.GENERAL, TodoCategory.ARRIVAL_INSPECTION, TodoCategory.TASK]
for cat in categories:
chip = CategoryChip(cat)
chip.chip_selected.connect(self._on_category_selected)
self._category_chips.append(chip)
category_layout.addWidget(chip)
# 기본 선택: 일반
self._category_chips[0].set_selected(True)
category_layout.addStretch()
self.content_layout.addWidget(category_container)
# 내용
self.content_input = CustomTextEdit(
placeholder="할일 내용을 입력하세요",
min_height=80
)
self.content_layout.addWidget(
LabeledInput("내용", self.content_input, required=True)
)
# 대상편성
self.train_input = CustomLineEdit(placeholder="예: 151A (선택)")
self.content_layout.addWidget(
LabeledInput("대상편성", self.train_input)
)
# 일정
self.schedule_input = CustomLineEdit(placeholder="예: 오전 10시 (선택)")
self.content_layout.addWidget(
LabeledInput("일정", self.schedule_input)
)
self.content_layout.addStretch()
def _on_category_selected(self, category: str):
"""카테고리 선택"""
for chip in self._category_chips:
chip.set_selected(chip.category == category)
self._selected_category = category
def _load_todo(self, todo: Todo):
"""할일 데이터 로드"""
self.content_input.set_text(todo.content or "")
self.train_input.setText(todo.target_train or "")
self.schedule_input.setText(todo.schedule or "")
# 카테고리 선택
category = todo.category or TodoCategory.GENERAL
self._on_category_selected(category)
def get_data(self) -> dict:
"""입력 데이터 반환"""
return {
"todo_date": self.todo_date.isoformat(),
"category": self._selected_category,
"content": self.content_input.get_text(),
"target_train": self.train_input.text(),
"schedule": self.schedule_input.text(),
"is_completed": False,
}