import sys from PyQt5.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout, QLabel, QLineEdit, QPushButton, QDateEdit, QTableWidget, QTableWidgetItem, QHeaderView, QDialog, QFormLayout, QComboBox, QMessageBox, QSpinBox, QAction, QFileDialog, QMenuBar) from PyQt5.QtCore import Qt, QDate from PyQt5.QtGui import QFont from datetime import datetime, timedelta from calendar_manager import CalendarManager from date_calculator import DateCalculator from prediction_controller import PredictionController class AddEventDialog(QDialog): def __init__(self, keyword_list, parent=None): super().__init__(parent) self.setWindowTitle("Add New Event") self.keyword_list = keyword_list self.init_ui() def init_ui(self): layout = QFormLayout() # Start date selector self.start_date = QDateEdit() self.start_date.setCalendarPopup(True) self.start_date.setDate(QDate.currentDate()) layout.addRow("Start Date:", self.start_date) # End date selector self.end_date = QDateEdit() self.end_date.setCalendarPopup(True) self.end_date.setDate(QDate.currentDate().addDays(1)) layout.addRow("End Date:", self.end_date) # Keyword selector self.keyword = QComboBox() self.keyword.addItems(self.keyword_list) layout.addRow("Keyword:", self.keyword) # Buttons button_layout = QHBoxLayout() self.save_button = QPushButton("Save") self.save_button.clicked.connect(self.accept) self.cancel_button = QPushButton("Cancel") self.cancel_button.clicked.connect(self.reject) button_layout.addWidget(self.save_button) button_layout.addWidget(self.cancel_button) layout.addRow("", button_layout) self.setLayout(layout) def get_data(self): start_date = self.start_date.date().toString("yyyy-MM-dd") end_date = self.end_date.date().toString("yyyy-MM-dd") keyword = self.keyword.currentText() return start_date, end_date, keyword class ModifyEventDialog(QDialog): def __init__(self, entry, keyword_list, parent=None): super().__init__(parent) self.setWindowTitle("Modify Event") self.entry = entry self.keyword_list = keyword_list self.init_ui() def init_ui(self): layout = QFormLayout() # Start date selector self.start_date = QDateEdit() self.start_date.setCalendarPopup(True) entry_start = QDate(self.entry.start_date.year, self.entry.start_date.month, self.entry.start_date.day) self.start_date.setDate(entry_start) layout.addRow("Start Date:", self.start_date) # End date selector self.end_date = QDateEdit() self.end_date.setCalendarPopup(True) entry_end = QDate(self.entry.end_date.year, self.entry.end_date.month, self.entry.end_date.day) self.end_date.setDate(entry_end) layout.addRow("End Date:", self.end_date) # Keyword selector self.keyword = QComboBox() self.keyword.addItems(self.keyword_list) current_index = self.keyword_list.index(self.entry.keyword) if self.entry.keyword in self.keyword_list else 0 self.keyword.setCurrentIndex(current_index) layout.addRow("Keyword:", self.keyword) # Buttons button_layout = QHBoxLayout() self.save_button = QPushButton("Save") self.save_button.clicked.connect(self.accept) self.cancel_button = QPushButton("Cancel") self.cancel_button.clicked.connect(self.reject) button_layout.addWidget(self.save_button) button_layout.addWidget(self.cancel_button) layout.addRow("", button_layout) self.setLayout(layout) def get_data(self): start_date = self.start_date.date().toString("yyyy-MM-dd") end_date = self.end_date.date().toString("yyyy-MM-dd") keyword = self.keyword.currentText() return start_date, end_date, keyword class CalendarManagerGUI(QMainWindow): def __init__(self): super().__init__() self.setWindowTitle("Calendar Manager") self.setMinimumSize(800, 600) # Initialize backend components self.keyword_list = ["full_project", "half_project", "event"] self.calendar_manager = CalendarManager() self.date_calculator = DateCalculator() self.prediction_controller = PredictionController( self.calendar_manager, self.date_calculator, self.keyword_list ) self.init_ui() self.create_menus() def create_menus(self): # Create menu bar menubar = self.menuBar() # File menu file_menu = menubar.addMenu('File') # Save action save_action = QAction('Save', self) save_action.setShortcut('Ctrl+S') save_action.triggered.connect(self.save_file) file_menu.addAction(save_action) # Load action load_action = QAction('Load', self) load_action.setShortcut('Ctrl+O') load_action.triggered.connect(self.load_file) file_menu.addAction(load_action) # Clear action clear_action = QAction('Clear', self) clear_action.setShortcut('Ctrl+N') clear_action.triggered.connect(self.clear_entries) file_menu.addAction(clear_action) # Exit action exit_action = QAction('Exit', self) exit_action.setShortcut('Ctrl+Q') exit_action.triggered.connect(self.close) file_menu.addAction(exit_action) def init_ui(self): self.setWindowTitle('Calendar Manager GUI') self.setMinimumSize(800, 600) central_widget = QWidget() main_layout = QVBoxLayout() top_layout = QHBoxLayout() # Launch date input launch_date_layout = QVBoxLayout() launch_date_label = QLabel("Launch Date:") self.launch_date_edit = QDateEdit() self.launch_date_edit.setCalendarPopup(True) # Enable calendar popup self.launch_date_edit.setDate(QDate.currentDate()) self.launch_date_edit.dateChanged.connect(self.update_prediction) # Auto-update on change launch_date_layout.addWidget(launch_date_label) launch_date_layout.addWidget(self.launch_date_edit) top_layout.addLayout(launch_date_layout) # Duration input duration_layout = QVBoxLayout() duration_label = QLabel("Duration (years):") self.duration_spin = QSpinBox() self.duration_spin.setRange(1, 99) self.duration_spin.setValue(1) self.duration_spin.valueChanged.connect(self.update_prediction) # Auto-update on change duration_layout.addWidget(duration_label) duration_layout.addWidget(self.duration_spin) top_layout.addLayout(duration_layout) # Prediction result prediction_result_layout = QVBoxLayout() prediction_result_label = QLabel("Predicted Completion Date:") self.prediction_result = QDateEdit() self.prediction_result.setReadOnly(True) self.prediction_result.setButtonSymbols(QDateEdit.ButtonSymbols.NoButtons) prediction_result_layout.addWidget(prediction_result_label) prediction_result_layout.addWidget(self.prediction_result) top_layout.addLayout(prediction_result_layout) main_layout.addLayout(top_layout) # Events section events_layout = QVBoxLayout() events_title = QLabel("