""" 외출 관리 화면 """ from PyQt5.QtWidgets import (QDialog, QVBoxLayout, QHBoxLayout, QLabel, QPushButton, QTableWidget, QTableWidgetItem, QHeaderView, QMessageBox, QTimeEdit, QLineEdit, QWidget) from PyQt5.QtCore import Qt, QTime from datetime import datetime from core.i18n import tr from ui.styles import apply_dark_titlebar class BreakEditDialog(QDialog): """외출 기록 수정 다이얼로그""" def __init__(self, parent=None, break_record=None): super().__init__(parent) self.break_record = break_record self.init_ui() apply_dark_titlebar(self) def init_ui(self): """UI 초기화""" self.setWindowTitle("외출 기록 수정") self.setFixedSize(380, 180) layout = QVBoxLayout() layout.setSpacing(8) layout.setContentsMargins(12, 10, 12, 10) # 외출 시간 out_layout = QHBoxLayout() out_label = QLabel("외출 시간:") out_label.setFixedWidth(80) self.out_time_edit = QTimeEdit() self.out_time_edit.setDisplayFormat("HH:mm:ss") out_layout.addWidget(out_label) out_layout.addWidget(self.out_time_edit) layout.addLayout(out_layout) # 복귀 시간 in_layout = QHBoxLayout() in_label = QLabel("복귀 시간:") in_label.setFixedWidth(80) self.in_time_edit = QTimeEdit() self.in_time_edit.setDisplayFormat("HH:mm:ss") in_layout.addWidget(in_label) in_layout.addWidget(self.in_time_edit) layout.addLayout(in_layout) # 사유 reason_layout = QHBoxLayout() reason_label = QLabel("사유:") reason_label.setFixedWidth(80) self.reason_edit = QLineEdit() reason_layout.addWidget(reason_label) reason_layout.addWidget(self.reason_edit) layout.addLayout(reason_layout) # 기존 데이터 로드 if self.break_record: break_out = self.break_record.get('break_out', '00:00:00') h, m, s = map(int, break_out.split(':')) self.out_time_edit.setTime(QTime(h, m, s)) break_in = self.break_record.get('break_in') if break_in: h, m, s = map(int, break_in.split(':')) self.in_time_edit.setTime(QTime(h, m, s)) reason = self.break_record.get('reason', '') if reason: self.reason_edit.setText(reason) # 버튼 button_layout = QHBoxLayout() save_button = QPushButton("저장") cancel_button = QPushButton("취소") save_button.clicked.connect(self.accept) cancel_button.clicked.connect(self.reject) button_layout.addWidget(save_button) button_layout.addWidget(cancel_button) layout.addLayout(button_layout) self.setLayout(layout) def get_data(self): """입력된 데이터 반환""" out_time = self.out_time_edit.time() in_time = self.in_time_edit.time() reason = self.reason_edit.text() # 복귀 시간 처리: 기존 기록에 복귀 시간이 없으면 None 유지 # 자정(00:00:00)도 유효한 시간으로 처리 break_in_str = in_time.toString("HH:mm:ss") if self.break_record and not self.break_record.get('break_in'): # 기존에 복귀 시간이 없었고, 수정에서도 00:00:00이면 아직 복귀 안 한 것으로 간주 if break_in_str == "00:00:00": break_in_str = None return { 'break_out': out_time.toString("HH:mm:ss"), 'break_in': break_in_str, 'reason': reason } class BreakView(QDialog): """외출 관리 창""" def __init__(self, parent=None, db=None): super().__init__(parent) self.db = db self.parent_window = parent self.init_ui() self.load_break_records() apply_dark_titlebar(self) def init_ui(self): """UI 초기화""" self.setWindowTitle(tr('window.break_view')) self.setGeometry(200, 200, 550, 350) layout = QVBoxLayout() layout.setSpacing(6) layout.setContentsMargins(12, 10, 12, 10) # 제목 title = QLabel("오늘의 외출 기록") title.setObjectName("dialog_subtitle") title.setAlignment(Qt.AlignCenter) layout.addWidget(title) # 외출 리스트 테이블 self.table = QTableWidget() self.table.setColumnCount(5) self.table.setHorizontalHeaderLabels(["외출 시간", "복귀 시간", "소요 시간", "사유", ""]) # 테이블 설정 header = self.table.horizontalHeader() header.setSectionResizeMode(0, QHeaderView.ResizeToContents) header.setSectionResizeMode(1, QHeaderView.ResizeToContents) header.setSectionResizeMode(2, QHeaderView.ResizeToContents) header.setSectionResizeMode(3, QHeaderView.Stretch) header.setSectionResizeMode(4, QHeaderView.ResizeToContents) self.table.setSelectionBehavior(QTableWidget.SelectRows) self.table.setEditTriggers(QTableWidget.NoEditTriggers) layout.addWidget(self.table) # 총 외출 시간 표시 self.total_label = QLabel("총 외출 시간: 0분") self.total_label.setObjectName("section_title") self.total_label.setAlignment(Qt.AlignRight) layout.addWidget(self.total_label) # 버튼 button_layout = QHBoxLayout() self.refresh_button = QPushButton("새로고침") close_button = QPushButton("닫기") self.refresh_button.clicked.connect(self.load_break_records) close_button.clicked.connect(self.accept) button_layout.addStretch() button_layout.addWidget(self.refresh_button) button_layout.addWidget(close_button) layout.addLayout(button_layout) self.setLayout(layout) def load_break_records(self): """외출 기록 로드""" records = self.db.get_today_break_records() self.table.setRowCount(len(records)) for i, record in enumerate(records): # 외출 시간 break_out = record.get('break_out', '') self.table.setItem(i, 0, QTableWidgetItem(break_out)) # 복귀 시간 break_in = record.get('break_in', '') if break_in: self.table.setItem(i, 1, QTableWidgetItem(break_in)) else: item = QTableWidgetItem("진행중") item.setForeground(Qt.red) self.table.setItem(i, 1, item) # 소요 시간 total_minutes = record.get('total_minutes') if total_minutes: hours = total_minutes // 60 minutes = total_minutes % 60 duration_str = f"{hours}시간 {minutes}분" if hours > 0 else f"{minutes}분" self.table.setItem(i, 2, QTableWidgetItem(duration_str)) else: self.table.setItem(i, 2, QTableWidgetItem("-")) # 사유 reason = record.get('reason', '') self.table.setItem(i, 3, QTableWidgetItem(reason)) # 액션 버튼 action_widget = QWidget() action_layout = QHBoxLayout() action_layout.setContentsMargins(0, 0, 0, 0) action_layout.setSpacing(5) edit_button = QPushButton("수정") delete_button = QPushButton("삭제") edit_button.setFixedSize(50, 25) delete_button.setFixedSize(50, 25) # 클릭 이벤트에 record id 전달 record_id = record['id'] edit_button.clicked.connect(lambda checked, rid=record_id: self.edit_record(rid)) delete_button.clicked.connect(lambda checked, rid=record_id: self.delete_record(rid)) action_layout.addWidget(edit_button) action_layout.addWidget(delete_button) action_widget.setLayout(action_layout) self.table.setCellWidget(i, 4, action_widget) # 총 외출 시간 업데이트 total_minutes = self.db.get_total_break_minutes_today() hours = total_minutes // 60 minutes = total_minutes % 60 if hours > 0: self.total_label.setText(f"총 외출 시간: {hours}시간 {minutes}분") else: self.total_label.setText(f"총 외출 시간: {minutes}분") def edit_record(self, record_id): """외출 기록 수정""" # 기존 기록 조회 records = self.db.get_today_break_records() record = next((r for r in records if r['id'] == record_id), None) if not record: return # 수정 다이얼로그 표시 dialog = BreakEditDialog(self, record) if dialog.exec_() == QDialog.Accepted: data = dialog.get_data() # DB 업데이트 self.db.update_break_record( record_id, data['break_out'], data['break_in'], data['reason'] ) # 리스트 새로고침 self.load_break_records() # 부모 창 업데이트 if self.parent_window and hasattr(self.parent_window, 'update_break_status'): self.parent_window.update_break_status() if self.parent_window and hasattr(self.parent_window, 'update_times'): self.parent_window.update_times() def delete_record(self, record_id): """외출 기록 삭제""" reply = QMessageBox.question( self, "삭제 확인", "이 외출 기록을 삭제하시겠습니까?", QMessageBox.Yes | QMessageBox.No ) if reply == QMessageBox.Yes: self.db.delete_break_record(record_id) self.load_break_records() # 부모 창 업데이트 if self.parent_window and hasattr(self.parent_window, 'update_break_status'): self.parent_window.update_break_status() if self.parent_window and hasattr(self.parent_window, 'update_times'): self.parent_window.update_times()