handOver2/ui/sections/misc_section.py

843 lines
33 KiB
Python

# -*- coding: utf-8 -*-
"""
기타 섹션 모듈
전동차 관련 작업 외 나머지 사항을 관리하는 섹션입니다.
"""
from datetime import date
from typing import List, Optional, Any
from PySide6.QtWidgets import QDialog
from PySide6.QtCore import Qt, QPoint
from ui.base.base_section import BaseSection, FieldConfig
from ui.dialogs.input_dialog import SectionInputDialog
from ui.widgets.clickableLabel import ClickableLabel
from ui.components.popup_widget import PopupWidget
from database.models import Misc
from core.logger import get_logger
logger = get_logger(__name__)
class MiscSection(BaseSection):
"""
기타 섹션
전동차 관련 작업 외 나머지 사항을 표시하고 관리합니다.
필드:
- 전달자, 전달내용, 특이사항, 관련문서, 팀확인, 완료
"""
def __init__(self, parent=None):
super().__init__(parent, "miscs", Misc)
# 필드 설정
self._setup_fields()
# 초기화 후 처리 (설정 로드)
self._post_init()
# 팝업 추적용
self._current_popup: Optional[PopupWidget] = None
self._current_team_popup: Optional[PopupWidget] = None
# 초기 데이터 로드
self.load_data()
logger.info("기타 섹션 초기화 완료")
def _setup_fields(self):
"""필드 설정"""
self.fields = [
FieldConfig("created_date", "생성일", width=80, required=True, editable=False, field_type="date"),
FieldConfig("created_team", "생성팀", width=60, required=True, editable=False),
FieldConfig("reporter", "전달자", width=80),
FieldConfig("report_content", "전달내용", width=350),
FieldConfig("remarks", "특이사항", width=180),
FieldConfig("related_document", "관련문서", width=100),
FieldConfig("team_confirmations", "확인팀", width=110),
FieldConfig("is_completed", "완료", width=40, field_type="checkbox"),
]
def _fetch_data(self, **filters) -> List[Misc]:
"""데이터 조회"""
return self.crud.get_all_miscs()
def on_add_clicked(self):
"""추가 버튼 클릭"""
dialog = MiscInputDialog(self)
if dialog.exec() == QDialog.Accepted:
data = dialog.get_data()
self.crud.create_misc(**data)
self.refresh_data()
def on_edit_clicked(self, record_id: int):
"""편집 버튼 클릭"""
record = self.crud.get_misc(record_id)
if record:
dialog = MiscInputDialog(self, record)
if dialog.exec() == QDialog.Accepted:
data = dialog.get_data()
self.crud.update_misc(record_id, **data)
self.refresh_data()
def _delete_record(self, record_id: int):
"""레코드 삭제"""
self.crud.delete_misc(record_id)
self.refresh_data()
def on_search_changed(self, text: str):
"""검색어 변경"""
if text:
results = self.crud._search(
"miscs",
Misc,
["reporter", "report_content", "remarks"],
text
)
self.current_records = results
self._update_table()
else:
self.load_data()
def _update_team_confirmations(self, record_id: int, confirmations: dict):
"""팀확인 상태 업데이트"""
import json
self.crud.update_misc(record_id, team_confirmations=json.dumps(confirmations, ensure_ascii=False))
self.signals.data_changed.emit(self.table_name)
def _mark_as_completed(self, record_id: int):
"""레코드를 완료로 표시"""
from datetime import datetime
self.crud.update_misc(record_id, is_completed=True, completed_at=datetime.now())
self.signals.data_changed.emit(self.table_name)
def _on_double_clicked(self, item):
"""더블클릭 이벤트 오버라이드"""
row = item.row()
col = item.column()
# 위젯인 경우 (ClickableLabel 등)
widget = self.table.cellWidget(row, col)
if widget:
record_id = widget.property("record_id")
if not record_id:
# 첫 번째 셀에서 레코드 ID 가져오기
first_item = self.table.item(row, 0)
if first_item:
record_id = first_item.data(Qt.UserRole)
if record_id:
visible_fields = [f for f in self.fields if f.visible]
if col < len(visible_fields):
field = visible_fields[col]
record = self.crud.get_misc(record_id)
if record:
self._edit_field_inline(row, col, field, record)
return
# 일반 아이템인 경우 부모 클래스 처리
super()._on_double_clicked(item)
def _edit_field_inline(self, row: int, col: int, field: FieldConfig, record: Misc):
"""인라인 필드 편집"""
if field.name == "reporter":
self._edit_reporter(row, col, record)
elif field.name == "report_content":
self._edit_report_content(row, col, record)
elif field.name == "remarks":
self._edit_remarks(row, col, record)
elif field.name == "related_document":
self._edit_related_document(row, col, record)
elif field.name == "team_confirmations":
self._edit_team_confirmations(row, col, record)
elif field.name == "created_team":
self._edit_created_team(row, col, record)
else:
# 기본 편집 모드
self._enable_cell_editing(row, col, field)
def _edit_reporter(self, row: int, col: int, record: Misc):
"""전달자 편집"""
from ui.components.custom_input import CustomLineEdit
from PySide6.QtWidgets import QDialog, QVBoxLayout, QDialogButtonBox
dialog = QDialog(self)
dialog.setWindowTitle("전달자 입력")
dialog.setModal(True)
layout = QVBoxLayout(dialog)
input_field = CustomLineEdit(placeholder="전달자 이름")
if record.reporter:
input_field.setText(record.reporter)
layout.addWidget(input_field)
buttons = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
buttons.accepted.connect(dialog.accept)
buttons.rejected.connect(dialog.reject)
layout.addWidget(buttons)
if dialog.exec() == QDialog.Accepted:
reporter = input_field.text()
self.crud.update_misc(record.id, reporter=reporter)
self.refresh_data()
def _edit_report_content(self, row: int, col: int, record: Misc):
"""전달내용 편집"""
from ui.components.custom_input import CustomTextEdit, LabeledInput
from PySide6.QtWidgets import QDialog, QVBoxLayout, QDialogButtonBox
dialog = QDialog(self)
dialog.setWindowTitle("전달내용 편집")
dialog.setModal(True)
layout = QVBoxLayout(dialog)
text_input = CustomTextEdit(placeholder="전달 내용을 입력하세요", min_height=150)
text_input.set_text(record.report_content or "")
layout.addWidget(LabeledInput("전달내용", text_input, required=True))
buttons = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
buttons.accepted.connect(dialog.accept)
buttons.rejected.connect(dialog.reject)
layout.addWidget(buttons)
if dialog.exec() == QDialog.Accepted:
new_content = text_input.get_text()
self.crud.update_misc(record.id, report_content=new_content)
self.refresh_data()
def _edit_remarks(self, row: int, col: int, record: Misc):
"""특이사항 편집"""
from ui.components.custom_input import CustomTextEdit, LabeledInput
from PySide6.QtWidgets import QDialog, QVBoxLayout, QDialogButtonBox
dialog = QDialog(self)
dialog.setWindowTitle("특이사항 편집")
dialog.setModal(True)
layout = QVBoxLayout(dialog)
text_input = CustomTextEdit(placeholder="특이사항을 입력하세요", min_height=100)
text_input.set_text(record.remarks or "")
layout.addWidget(LabeledInput("특이사항", text_input))
buttons = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
buttons.accepted.connect(dialog.accept)
buttons.rejected.connect(dialog.reject)
layout.addWidget(buttons)
if dialog.exec() == QDialog.Accepted:
new_remarks = text_input.get_text()
self.crud.update_misc(record.id, remarks=new_remarks)
self.refresh_data()
def _edit_related_document(self, row: int, col: int, record: Misc):
"""관련문서 편집"""
from ui.components.custom_input import CustomLineEdit
from PySide6.QtWidgets import QDialog, QVBoxLayout, QDialogButtonBox
dialog = QDialog(self)
dialog.setWindowTitle("관련문서 입력")
dialog.setModal(True)
layout = QVBoxLayout(dialog)
input_field = CustomLineEdit(placeholder="관련 문서 (파일명 또는 링크)")
if record.related_document:
input_field.setText(record.related_document)
layout.addWidget(input_field)
buttons = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
buttons.accepted.connect(dialog.accept)
buttons.rejected.connect(dialog.reject)
layout.addWidget(buttons)
if dialog.exec() == QDialog.Accepted:
related_document = input_field.text()
self.crud.update_misc(record.id, related_document=related_document)
self.refresh_data()
def _edit_team_confirmations(self, row: int, col: int, record: Misc):
"""확인팀 편집 (다중선택)"""
widget = self.table.cellWidget(row, col)
if widget:
label = widget.findChild(ClickableLabel)
if label:
self._show_team_confirmations_popup(record, label)
def _edit_created_team(self, row: int, col: int, record: Misc):
"""생성팀 편집"""
widget = self.table.cellWidget(row, col)
if widget:
label = widget.findChild(ClickableLabel)
if label:
self._show_created_team_popup(record, label)
def _update_table(self):
"""테이블 업데이트 (오버라이드)"""
self.table.setRowCount(0)
# 표시할 필드만 필터링
visible_fields = [f for f in self.fields if f.visible]
# 컬럼 설정
self.table.setColumnCount(len(visible_fields))
self.table.setHorizontalHeaderLabels([f.label for f in visible_fields])
# 컬럼 너비 설정
for i, field in enumerate(visible_fields):
self.table.setColumnWidth(i, field.width)
# 데이터 채우기 (완료된 레코드는 제외)
for record in self.current_records:
# 완료된 레코드는 섹션에서 숨김 (DB에는 유지)
if hasattr(record, 'is_completed') and record.is_completed:
continue
row = self.table.rowCount()
self.table.insertRow(row)
max_height = int(40 * 1.15) # 기본 높이 15% 증가 (46px)
for col, field in enumerate(visible_fields):
value = getattr(record, field.name, "")
# 완료 필드는 버튼 위젯으로 표시
if field.name == "is_completed":
self._set_completion_button(row, col, record)
# 확인팀은 ClickableLabel로 표시
elif field.name == "team_confirmations":
self._set_team_label(row, col, field, value, record)
# 생성팀, 전달자, 관련문서는 ClickableLabel로 표시
elif field.name in ["created_team", "reporter", "related_document"]:
self._set_clickable_label(row, col, field, value, record)
# 날짜 필드는 ClickableLabel로 표시
elif field.name == "created_date":
self._set_clickable_label(row, col, field, value, record)
# 전달내용, 특이사항은 줄바꿈이 가능한 위젯으로 표시
elif field.name in ["report_content", "remarks"]:
content_height = self._set_content_label(row, col, field, value, record)
if content_height:
max_height = max(max_height, content_height)
else:
item = self._create_table_item(field, value, record)
self.table.setItem(row, col, item)
# 행 높이 설정
self.table.setRowHeight(row, max_height)
# 레코드 ID 저장 (첫 번째 셀에)
first_item = self.table.item(row, 0)
if first_item:
first_item.setData(Qt.UserRole, record.id)
else:
# 첫 번째 셀이 위젯인 경우
widget = self.table.cellWidget(row, 0)
if widget:
widget.setProperty("record_id", record.id)
def _set_clickable_label(self, row: int, col: int, field: FieldConfig, value: Any, record: Misc):
"""ClickableLabel 설정"""
from PySide6.QtWidgets import QWidget, QHBoxLayout
display_value = self._format_value(field, value) if value else ""
# ClickableLabel 생성
label = ClickableLabel(display_value or "미지정", enable_hover=True)
label.setAlignment(Qt.AlignCenter)
label.setWordWrap(True)
# 통일된 색상 적용
theme = self.config.theme
unified_color = "#64748b"
if theme == 'dark':
label.setStyleSheet(f"""
QLabel {{
background-color: {unified_color};
color: #ffffff;
border: 1px solid rgba(255,255,255,0.2);
border-radius: 0px;
padding: 0px;
margin: 0px;
font-weight: 600;
font-size: 12px;
}}
QLabel:hover {{
background-color: {unified_color};
border-color: rgba(255,255,255,0.4);
}}
""")
else:
label.setStyleSheet(f"""
QLabel {{
background-color: {unified_color};
color: #ffffff;
border: 1px solid rgba(0,0,0,0.1);
border-radius: 0px;
padding: 0px;
margin: 0px;
font-weight: 600;
font-size: 12px;
}}
QLabel:hover {{
background-color: {unified_color};
border-color: rgba(0,0,0,0.2);
}}
""")
# 더블클릭 시 편집
def on_double_clicked():
self._edit_field_inline(row, col, field, record)
label.double_clicked.connect(on_double_clicked)
# 레코드 정보 저장
label.setProperty("record_id", record.id)
label.setProperty("field_name", field.name)
label.setProperty("field_value", value or "")
# 컨테이너 위젯으로 감싸서 구분선 적용
container = QWidget()
container_layout = QHBoxLayout(container)
container_layout.setContentsMargins(0, 0, 0, 0)
container_layout.setSpacing(0)
container_layout.addWidget(label)
# 구분선 스타일 적용
gridline_color = "#475569" if theme == 'dark' else "#cbd5e1"
container.setStyleSheet(f"border-right: 1px solid {gridline_color};")
# 셀에 위젯 설정
self.table.setCellWidget(row, col, container)
def _set_team_label(self, row: int, col: int, field: FieldConfig, value: Any, record: Misc):
"""확인팀 라벨 설정 (공간 효율 최대화)"""
from PySide6.QtWidgets import QWidget, QHBoxLayout
import json
theme = self.config.theme
unified_color = "#64748b"
# 확인팀: 확인된 팀 숫자만 표시 (예: "1 2 4")
try:
confirmations = json.loads(value) if isinstance(value, str) else value
if isinstance(confirmations, dict):
# 팀 이름에서 숫자만 추출하여 정렬
confirmed_nums = sorted([
team.replace("", "")
for team, confirmed in confirmations.items()
if confirmed
])
display_value = " ".join(confirmed_nums) if confirmed_nums else "-"
else:
display_value = "-"
except Exception:
display_value = "-"
# ClickableLabel 생성
label = ClickableLabel(display_value, enable_hover=False)
label.setAlignment(Qt.AlignCenter)
# 통일된 스타일 적용
if theme == 'dark':
label.setStyleSheet(f"""
QLabel {{
background-color: {unified_color};
color: #ffffff;
border: 1px solid rgba(255,255,255,0.2);
border-radius: 0px;
padding: 0px;
margin: 0px;
font-weight: 600;
font-size: 12px;
}}
QLabel:hover {{
background-color: {unified_color};
border-color: rgba(255,255,255,0.4);
}}
""")
else:
label.setStyleSheet(f"""
QLabel {{
background-color: {unified_color};
color: #ffffff;
border: 1px solid rgba(0,0,0,0.1);
border-radius: 0px;
padding: 0px;
margin: 0px;
font-weight: 600;
font-size: 12px;
}}
QLabel:hover {{
background-color: {unified_color};
border-color: rgba(0,0,0,0.2);
}}
""")
# 클릭/더블클릭 이벤트 연결
def on_clicked():
self._show_team_confirmations_popup(record, label)
def on_double_clicked():
self._edit_field_inline(row, col, field, record)
label.clicked.connect(on_clicked)
label.double_clicked.connect(on_double_clicked)
# 레코드 정보 저장
label.setProperty("record_id", record.id)
label.setProperty("field_name", field.name)
# 컨테이너 위젯으로 감싸기
container = QWidget()
container_layout = QHBoxLayout(container)
container_layout.setContentsMargins(0, 0, 0, 0)
container_layout.setSpacing(0)
container_layout.addWidget(label)
# 구분선 스타일 적용
gridline_color = "#475569" if theme == 'dark' else "#cbd5e1"
container.setStyleSheet(f"border-right: 1px solid {gridline_color};")
# 셀에 위젯 설정
self.table.setCellWidget(row, col, container)
def _set_content_label(self, row: int, col: int, field: FieldConfig, value: Any, record: Misc) -> int:
"""전달내용/특이사항 라벨 설정 (줄바꿈 지원)
Returns:
계산된 셀 높이 (픽셀)
"""
from PySide6.QtWidgets import QWidget, QVBoxLayout
display_value = self._format_value(field, value) if value else ""
# ClickableLabel 생성 (줄바꿈 지원)
label = ClickableLabel(display_value or "", enable_hover=False, enable_double_click=True, enable_right_click=True)
label.setWordWrap(True)
label.setAlignment(Qt.AlignLeft | Qt.AlignTop)
label.setTextInteractionFlags(Qt.TextSelectableByMouse)
# 레코드 정보 저장
label.setProperty("record_id", record.id)
label.setProperty("field_name", field.name)
label.setProperty("field_value", value or "")
# 더블클릭 시 편집
def on_double_clicked():
self._edit_field_inline(row, col, field, record)
label.double_clicked.connect(on_double_clicked)
# 우클릭 컨텍스트 메뉴
def on_right_clicked(pos):
from PySide6.QtWidgets import QMenu
menu = QMenu(self)
edit_action = menu.addAction("편집")
edit_action.triggered.connect(lambda: self._edit_field_inline(row, col, field, record))
menu.exec_(label.mapToGlobal(pos))
label.right_clicked.connect(on_right_clicked)
# 컨테이너 위젯으로 감싸기
container = QWidget()
container_layout = QVBoxLayout(container)
container_layout.setContentsMargins(8, 4, 8, 4)
container_layout.setSpacing(0)
container_layout.addWidget(label)
# 구분선 및 텍스트 색상 스타일 적용
theme = self.config.theme
gridline_color = "#475569" if theme == 'dark' else "#cbd5e1"
text_color = "#f8fafc" if theme == 'dark' else "#1e293b"
# 높이 계산
font_metrics = self.table.fontMetrics()
base_font_size = 13
col_width = self.table.columnWidth(col)
needs_wrap = False
calculated_height = int(40 * 1.15)
if display_value and col_width > 0:
available_width = col_width - 16
text_width = font_metrics.horizontalAdvance(display_value)
if text_width > available_width:
needs_wrap = True
wrap_font_size = base_font_size - 2
from PySide6.QtGui import QFont, QFontMetrics
small_font = QFont(self.table.font())
small_font.setPointSize(wrap_font_size)
small_font_metrics = QFontMetrics(small_font)
chars_per_line = max(1, available_width // small_font_metrics.averageCharWidth())
lines = max(1, (len(display_value) // chars_per_line) + 1)
line_height = small_font_metrics.height() + 6
calculated_height = max(int(40 * 1.15), lines * line_height + 8)
else:
calculated_height = int(40 * 1.15)
# 라벨에 스타일 적용
if needs_wrap:
wrap_font_size = base_font_size - 2
label.setStyleSheet(f"""
QLabel {{
color: {text_color};
background-color: transparent;
font-size: {wrap_font_size}px;
}}
""")
else:
label.setStyleSheet(f"""
QLabel {{
color: {text_color};
background-color: transparent;
}}
""")
container.setStyleSheet(f"border-right: 1px solid {gridline_color};")
# 셀에 위젯 설정
self.table.setCellWidget(row, col, container)
return calculated_height
def _show_team_confirmations_popup(self, record: Misc, label: ClickableLabel):
"""확인팀 선택 팝업 표시 (다중선택)"""
from ui.components.chips.choice_chip_button import ChoiceChipButton
from ui.components.popup_widget import PopupWidget
from core.constants import TEAMS
from PySide6.QtWidgets import QHBoxLayout, QWidget
import json
# 기존 팝업이 있으면 닫기
if self._current_team_popup:
self._current_team_popup.hide_popup()
self._current_team_popup = None
# 현재 확인된 팀 찾기
current_confirmations = {}
try:
confirmations = json.loads(record.team_confirmations) if isinstance(record.team_confirmations, str) else record.team_confirmations
if isinstance(confirmations, dict):
current_confirmations = confirmations
except Exception:
pass
# 팝업 생성
popup = PopupWidget(self, title="확인팀 선택", width=320, auto_hide=False)
self._current_team_popup = popup
# 칩 그룹 생성 (다중선택용)
chip_group = {}
chip_container = QWidget()
chip_layout = QHBoxLayout(chip_container)
chip_layout.setContentsMargins(0, 0, 0, 0)
chip_layout.setSpacing(8)
def update_confirmations():
"""확인 상태 업데이트"""
confirmations = {team: chip.isChecked() for team, chip in chip_group.items()}
self._update_team_confirmations(record.id, confirmations)
self.refresh_data()
for team in TEAMS:
is_checked = current_confirmations.get(team, False)
chip_bg = "#64748b" if is_checked else "#00bfa5"
chip = ChoiceChipButton(
text=team,
key=team,
bg=chip_bg
)
chip_group[team] = chip
chip_layout.addWidget(chip)
if is_checked:
chip.setChecked(True)
def make_toggle_handler(team_key: str):
def handler(_key: str, checked: bool):
chip = chip_group[team_key]
if checked:
chip.set_bg("#64748b")
else:
chip.set_bg("#00bfa5")
update_confirmations()
return handler
chip.toggled_key.connect(make_toggle_handler(team))
chip_layout.addStretch()
popup.content_layout.addWidget(chip_container)
# 팝업 크기 자동 조정
chip_container.adjustSize()
chip_width = chip_container.sizeHint().width()
popup_width = max(200, min(400, chip_width + 40))
popup.container.setFixedWidth(popup_width)
# 팝업이 마우스 밖으로 나가면 닫기
original_leave_event = popup.leaveEvent
def on_popup_leave(event):
if self._current_team_popup == popup:
popup.hide_popup()
self._current_team_popup = None
original_leave_event(event)
popup.leaveEvent = on_popup_leave
# 마우스 추적 활성화
popup.setMouseTracking(True)
popup.container.setMouseTracking(True)
# 라벨 위치 기준으로 팝업 위치 계산
label_pos = label.mapToGlobal(QPoint(0, 0))
popup_pos = QPoint(label_pos.x(), label_pos.y() + label.height() + 5)
popup.show_at(popup_pos)
def _show_created_team_popup(self, record: Misc, label: ClickableLabel):
"""생성팀 선택 팝업 표시 (단일선택)"""
from ui.components.chips.choice_chip_button import ChoiceChipButton
from ui.components.popup_widget import PopupWidget
from core.constants import TEAMS
from PySide6.QtWidgets import QHBoxLayout, QWidget, QButtonGroup
# 기존 팝업이 있으면 닫기
if self._current_team_popup:
self._current_team_popup.hide_popup()
self._current_team_popup = None
current_team = record.created_team or ""
# 팝업 생성
popup = PopupWidget(self, title="생성팀 선택", width=400, auto_hide=False)
self._current_team_popup = popup
# 칩 그룹 생성 (단일선택용)
button_group = QButtonGroup()
button_group.setExclusive(True)
chip_container = QWidget()
chip_layout = QHBoxLayout(chip_container)
chip_layout.setContentsMargins(0, 0, 0, 0)
chip_layout.setSpacing(8)
def on_team_selected(team_key: str):
self.crud.update_misc(record.id, created_team=team_key)
self.refresh_data()
popup.hide_popup()
self._current_team_popup = None
for team in TEAMS:
chip_bg = "#64748b" if team == current_team else "#2979ff"
chip = ChoiceChipButton(
text=team,
key=team,
bg=chip_bg
)
button_group.addButton(chip)
chip_layout.addWidget(chip)
if team == current_team:
chip.setChecked(True)
def make_chip_handler(team_key: str):
def handler():
for btn in button_group.buttons():
if isinstance(btn, ChoiceChipButton):
if btn.key == team_key:
btn.set_bg("#64748b")
else:
btn.set_bg("#2979ff")
on_team_selected(team_key)
return handler
chip.clicked_key.connect(make_chip_handler(team))
chip_layout.addStretch()
popup.content_layout.addWidget(chip_container)
# 팝업 크기 자동 조정
chip_container.adjustSize()
chip_width = chip_container.sizeHint().width()
popup_width = max(200, min(400, chip_width + 40))
popup.container.setFixedWidth(popup_width)
# 팝업이 마우스 밖으로 나가면 닫기
original_leave_event = popup.leaveEvent
def on_popup_leave(event):
if self._current_team_popup == popup:
popup.hide_popup()
self._current_team_popup = None
original_leave_event(event)
popup.leaveEvent = on_popup_leave
popup.setMouseTracking(True)
popup.container.setMouseTracking(True)
label_pos = label.mapToGlobal(QPoint(0, 0))
popup_pos = QPoint(label_pos.x(), label_pos.y() + label.height() + 5)
popup.show_at(popup_pos)
class MiscInputDialog(SectionInputDialog):
"""기타 입력 다이얼로그"""
def __init__(self, parent=None, record: Misc = None):
super().__init__(
parent,
title="기타 추가" if record is None else "기타 편집",
record=record,
width=450,
height=650
)
self._setup_misc_fields()
if record:
self._load_record(record)
def _setup_misc_fields(self):
"""기타 필드 설정"""
from ui.components.custom_input import CustomLineEdit, CustomTextEdit, LabeledInput
# 전달자
self.reporter_input = CustomLineEdit(placeholder="전달자 이름")
self.content_layout.addWidget(LabeledInput("전달자", self.reporter_input))
# 전달내용
self.content_input = CustomTextEdit(placeholder="전달 내용을 입력하세요", min_height=80)
self.content_layout.addWidget(LabeledInput("전달내용", self.content_input, required=True))
# 특이사항
self.remarks_input = CustomTextEdit(placeholder="특이사항을 입력하세요", min_height=60)
self.content_layout.addWidget(LabeledInput("특이사항", self.remarks_input))
# 관련문서
self.document_input = CustomLineEdit(placeholder="관련 문서 (파일명 또는 링크)")
self.content_layout.addWidget(LabeledInput("관련문서", self.document_input))
def _load_record(self, record: Misc):
"""레코드 데이터 로드"""
self.reporter_input.setText(record.reporter or "")
self.content_input.set_text(record.report_content or "")
self.remarks_input.set_text(record.remarks or "")
self.document_input.setText(record.related_document or "")
def get_data(self) -> dict:
"""입력 데이터 반환"""
return {
"created_date": date.today().isoformat(),
"created_team": self.config.current_team,
"reporter": self.reporter_input.text(),
"report_content": self.content_input.get_text(),
"remarks": self.remarks_input.get_text(),
"related_document": self.document_input.text(),
}