summaryrefslogtreecommitdiff
path: root/calendar_gui.py
diff options
context:
space:
mode:
Diffstat (limited to 'calendar_gui.py')
-rw-r--r--calendar_gui.py273
1 files changed, 103 insertions, 170 deletions
diff --git a/calendar_gui.py b/calendar_gui.py
index 7aeb159..c111db5 100644
--- a/calendar_gui.py
+++ b/calendar_gui.py
@@ -3,93 +3,102 @@ from PyQt5.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout, QH
QLabel, QLineEdit, QPushButton, QDateEdit, QTableWidget,
QTableWidgetItem, QHeaderView, QDialog, QFormLayout, QComboBox,
QMessageBox, QSpinBox, QAction, QFileDialog, QMenuBar)
-from PyQt5.QtCore import Qt, QDate, QLocale
-from PyQt5.QtGui import QFont, QFontDatabase
+from PyQt5.QtCore import Qt, QDate
+from PyQt5.QtGui import QFont
from datetime import datetime, timedelta
-from dateutil.relativedelta import relativedelta
from calendar_manager import CalendarManager
from date_calculator import DateCalculator
from prediction_controller import PredictionController
-class EventDialog(QDialog):
- def __init__(self, keyword_list, entry=None, parent=None):
+class AddEventDialog(QDialog):
+ def __init__(self, keyword_list, parent=None):
super().__init__(parent)
-
+ self.setWindowTitle("Add New Event")
self.keyword_list = keyword_list
- self.entry = entry
-
- # Set title based on mode
- self.setWindowTitle("Neuer Eintrag" if not entry else "Eintrag editieren")
self.init_ui()
def init_ui(self):
layout = QFormLayout()
- # Apply Arial font
- font = QFont("Arial", 12)
- self.setFont(font)
-
# Start date selector
self.start_date = QDateEdit()
self.start_date.setCalendarPopup(True)
- self.start_date.setFont(font)
+ 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)
- # Set initial date based on mode
- if self.entry:
- entry_start = QDate(self.entry.start_date.year,
- self.entry.start_date.month,
- self.entry.start_date.day)
- self.start_date.setDate(entry_start)
- else:
- self.start_date.setDate(QDate.currentDate())
-
+ button_layout.addWidget(self.save_button)
+ button_layout.addWidget(self.cancel_button)
+ layout.addRow("", button_layout)
- # Connect start date change to validate end date
- self.start_date.dateChanged.connect(self.validate_end_date)
+ self.setLayout(layout)
- layout.addRow("Startdatum:", self.start_date)
+ 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)
- self.end_date.setFont(font)
-
- # Set initial date based on mode
- if self.entry:
- entry_end = QDate(self.entry.end_date.year,
- self.entry.end_date.month,
- self.entry.end_date.day)
- self.end_date.setDate(entry_end)
- else:
- self.end_date.setDate(QDate.currentDate().addDays(1))
-
- layout.addRow("Enddatum:", self.end_date)
+ 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.setFont(font)
self.keyword.addItems(self.keyword_list)
-
- # Set initial keyword based on mode
- if self.entry and self.entry.keyword in self.keyword_list:
- current_index = self.keyword_list.index(self.entry.keyword)
- self.keyword.setCurrentIndex(current_index)
-
- self.keyword.currentTextChanged.connect(self.on_keyword_changed)
- layout.addRow("Art:", self.keyword)
-
- # Store layout for later access
- self.layout = layout
- self.end_date_row = 1 # Index of end date row in the form layout
+ 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("Speichern")
- self.save_button.setFont(font)
+ self.save_button = QPushButton("Save")
self.save_button.clicked.connect(self.accept)
-
- self.cancel_button = QPushButton("Abbrechen")
- self.cancel_button.setFont(font)
+ self.cancel_button = QPushButton("Cancel")
self.cancel_button.clicked.connect(self.reject)
button_layout.addWidget(self.save_button)
@@ -98,62 +107,22 @@ class EventDialog(QDialog):
self.setLayout(layout)
- # Handle initial keyword selection
- self.on_keyword_changed(self.keyword.currentText())
-
- def on_keyword_changed(self, keyword):
- """Handle visibility of the end_date field based on keyword"""
- # Get the widgets from the form layout
- end_date_label = self.layout.itemAt(self.end_date_row, QFormLayout.LabelRole).widget()
- end_date_field = self.layout.itemAt(self.end_date_row, QFormLayout.FieldRole).widget()
-
- if keyword == "EZ pauschal":
- # Hide end date field for EZ pauschals since they have fixed 4-week duration
- end_date_label.setVisible(False)
- end_date_field.setVisible(False)
-
- # Update end date automatically if changing to EZ pauschal
- start_dt = self.start_date.date().toPyDate()
- end_dt = start_dt + relativedelta(years = 2, days = -1)
- self.end_date.setDate(QDate(end_dt.year, end_dt.month, end_dt.day))
- else:
- # Show end date field for other event types
- end_date_label.setVisible(True)
- end_date_field.setVisible(True)
-
- def validate_end_date(self):
- """Ensure end date is not before start date"""
- if self.end_date.date() < self.start_date.date():
- self.end_date.setDate(self.start_date.date())
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()
- if keyword == "EZ pauschal":
- # For EZ pauschals, calculate end date as start + 4 weeks
- start_dt = datetime.fromisoformat(start_date)
- end_dt = start_dt + relativedelta(years = 2, days = -1)
- end_date = end_dt.strftime("%Y-%m-%d")
- else:
- end_date = self.end_date.date().toString("yyyy-MM-dd")
return start_date, end_date, keyword
class CalendarManagerGUI(QMainWindow):
def __init__(self):
super().__init__()
- self.setWindowTitle("Ausfallzeitenrechner")
+ self.setWindowTitle("Calendar Manager")
self.setMinimumSize(800, 600)
- # Set application font
- self.app_font = QFont("Arial", 12)
- QApplication.setFont(self.app_font)
-
- # Get system locale for consistent date formatting
- self.locale = QLocale.system()
-
# Initialize backend components
- self.keyword_list = ["EZ 100%", "EZ 50%", "EZ pauschal", "Sonstige"]
+ self.keyword_list = ["full_project", "half_project", "event"]
self.calendar_manager = CalendarManager()
self.date_calculator = DateCalculator()
self.prediction_controller = PredictionController(
@@ -168,7 +137,6 @@ class CalendarManagerGUI(QMainWindow):
def create_menus(self):
# Create menu bar
menubar = self.menuBar()
- menubar.setFont(self.app_font)
# File menu
file_menu = menubar.addMenu('File')
@@ -197,7 +165,10 @@ class CalendarManagerGUI(QMainWindow):
exit_action.triggered.connect(self.close)
file_menu.addAction(exit_action)
- def init_ui(self):
+ def init_ui(self):
+ self.setWindowTitle('Calendar Manager GUI')
+ self.setMinimumSize(800, 600)
+
central_widget = QWidget()
main_layout = QVBoxLayout()
@@ -205,10 +176,8 @@ class CalendarManagerGUI(QMainWindow):
# Launch date input
launch_date_layout = QVBoxLayout()
- launch_date_label = QLabel("Promotionsdatum:")
- launch_date_label.setFont(self.app_font)
+ launch_date_label = QLabel("Launch Date:")
self.launch_date_edit = QDateEdit()
- self.launch_date_edit.setFont(self.app_font)
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
@@ -218,10 +187,8 @@ class CalendarManagerGUI(QMainWindow):
# Duration input
duration_layout = QVBoxLayout()
- duration_label = QLabel("Bewerbungszeitraum (Jahre):")
- duration_label.setFont(self.app_font)
+ duration_label = QLabel("Duration (years):")
self.duration_spin = QSpinBox()
- self.duration_spin.setFont(self.app_font)
self.duration_spin.setRange(1, 99)
self.duration_spin.setValue(1)
self.duration_spin.valueChanged.connect(self.update_prediction) # Auto-update on change
@@ -231,10 +198,8 @@ class CalendarManagerGUI(QMainWindow):
# Prediction result
prediction_result_layout = QVBoxLayout()
- prediction_result_label = QLabel("Bewerbungsfrist:")
- prediction_result_label.setFont(self.app_font)
+ prediction_result_label = QLabel("Predicted Completion Date:")
self.prediction_result = QDateEdit()
- self.prediction_result.setFont(self.app_font)
self.prediction_result.setReadOnly(True)
self.prediction_result.setButtonSymbols(QDateEdit.ButtonSymbols.NoButtons)
prediction_result_layout.addWidget(prediction_result_label)
@@ -246,23 +211,19 @@ class CalendarManagerGUI(QMainWindow):
# Events section
events_layout = QVBoxLayout()
- events_title = QLabel("<h3>Ausfallzeiten</h3>")
- events_title.setFont(self.app_font)
+ events_title = QLabel("<h3>Calendar Events</h3>")
events_layout.addWidget(events_title)
# Add event button
- add_event_button = QPushButton("Eintrag hinzufügen")
- add_event_button.setFont(self.app_font)
+ add_event_button = QPushButton("Add Event")
add_event_button.clicked.connect(self.add_event)
events_layout.addWidget(add_event_button)
# Events table
self.events_table = QTableWidget()
- self.events_table.setFont(self.app_font)
self.events_table.setColumnCount(7) # ID (hidden), Start, End, Keyword, CorrectedStart, CorrectedEnd, Actions
- self.events_table.setHorizontalHeaderLabels(["ID", "Anfangsdatum", "Enddatum", "Art", "Korr. Start", "Korr. Ende", "Aktionen"])
+ self.events_table.setHorizontalHeaderLabels(["ID", "Start Date", "End Date", "Keyword", "Corrected Start", "Corrected End", "Actions"])
self.events_table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
- self.events_table.horizontalHeader().setFont(self.app_font)
self.events_table.setColumnHidden(0, True) # Hide ID column
events_layout.addWidget(self.events_table)
@@ -296,7 +257,7 @@ class CalendarManagerGUI(QMainWindow):
print(f"Error calculating prediction: {str(e)}")
def add_event(self):
- dialog = EventDialog(self.keyword_list, parent=self)
+ dialog = AddEventDialog(self.keyword_list, self)
if dialog.exec_():
start_date, end_date, keyword = dialog.get_data()
try:
@@ -309,7 +270,7 @@ class CalendarManagerGUI(QMainWindow):
def modify_event(self, event_id):
entry = self.calendar_manager.get_entry_by_id(event_id)
if entry:
- dialog = EventDialog(self.keyword_list, entry=entry, parent=self)
+ dialog = ModifyEventDialog(entry, self.keyword_list, self)
if dialog.exec_():
start_date, end_date, keyword = dialog.get_data()
try:
@@ -323,8 +284,8 @@ class CalendarManagerGUI(QMainWindow):
QMessageBox.critical(self, "Error", f"Error modifying event: {str(e)}")
def delete_event(self, event_id):
- reply = QMessageBox.question(self, "Eintrag löschen",
- "Wollen Sie diesen Eintrag löschen?",
+ reply = QMessageBox.question(self, "Delete Event",
+ "Are you sure you want to delete this event?",
QMessageBox.Yes | QMessageBox.No)
if reply == QMessageBox.Yes:
try:
@@ -345,49 +306,23 @@ class CalendarManagerGUI(QMainWindow):
# Set item data
self.events_table.setItem(i, 0, QTableWidgetItem(entry.id))
-
- # Format dates using system locale for display
- start_date_qdate = QDate(entry.start_date.year, entry.start_date.month, entry.start_date.day)
- end_date_qdate = QDate(entry.end_date.year, entry.end_date.month, entry.end_date.day)
-
- start_date_text = self.locale.toString(start_date_qdate, QLocale.ShortFormat)
- end_date_text = self.locale.toString(end_date_qdate, QLocale.ShortFormat)
- self.events_table.setItem(i, 1, QTableWidgetItem(start_date_text))
- self.events_table.setItem(i, 2, QTableWidgetItem(end_date_text))
+ self.events_table.setItem(i, 1, QTableWidgetItem(entry.start_date.strftime("%Y-%m-%d")))
+ self.events_table.setItem(i, 2, QTableWidgetItem(entry.end_date.strftime("%Y-%m-%d")))
self.events_table.setItem(i, 3, QTableWidgetItem(entry.keyword))
- # Corrected dates with system locale formatting
- if entry.corrected_start_date:
- corrected_start_qdate = QDate(
- entry.corrected_start_date.year,
- entry.corrected_start_date.month,
- entry.corrected_start_date.day
- )
- corrected_start_text = self.locale.toString(corrected_start_qdate, QLocale.ShortFormat)
- else:
- corrected_start_text = ""
-
- if entry.corrected_end_date:
- corrected_end_qdate = QDate(
- entry.corrected_end_date.year,
- entry.corrected_end_date.month,
- entry.corrected_end_date.day
- )
- corrected_end_text = self.locale.toString(corrected_end_qdate, QLocale.ShortFormat)
- else:
- corrected_end_text = ""
- self.events_table.setItem(i, 4, QTableWidgetItem(corrected_start_text))
- self.events_table.setItem(i, 5, QTableWidgetItem(corrected_end_text))
+ # Corrected dates
+ corrected_start = entry.corrected_start_date.strftime("%Y-%m-%d") if entry.corrected_start_date else ""
+ corrected_end = entry.corrected_end_date.strftime("%Y-%m-%d") if entry.corrected_end_date else ""
+ self.events_table.setItem(i, 4, QTableWidgetItem(corrected_start))
+ self.events_table.setItem(i, 5, QTableWidgetItem(corrected_end))
# Action buttons
actions_widget = QWidget()
actions_layout = QHBoxLayout()
actions_layout.setContentsMargins(0, 0, 0, 0)
- modify_button = QPushButton("Editieren")
- modify_button.setFont(self.app_font)
- delete_button = QPushButton("Löschen")
- delete_button.setFont(self.app_font)
+ modify_button = QPushButton("Modify")
+ delete_button = QPushButton("Delete")
# Use lambda with default argument to capture the correct event_id
modify_button.clicked.connect(lambda checked, eid=entry.id: self.modify_event(eid))
@@ -401,21 +336,21 @@ class CalendarManagerGUI(QMainWindow):
def save_file(self):
"""Save calendar entries to a JSON file"""
- # if not self.calendar_manager.filename:
- file_path, _ = QFileDialog.getSaveFileName(self, "Einträge speichern", "", "JSON Files (*.json)")
- if not file_path:
- return
- self.calendar_manager.switch_file(file_path)
+ if not self.calendar_manager.filename:
+ file_path, _ = QFileDialog.getSaveFileName(self, "Save Calendar", "", "JSON Files (*.json)")
+ if not file_path:
+ return
+ self.calendar_manager.switch_file(file_path)
try:
self.calendar_manager.save_entries()
- QMessageBox.information(self, "Speichern erfolgreich", f"Einträge gespeichert in {self.calendar_manager.filename}")
+ QMessageBox.information(self, "Save Successful", f"Calendar saved to {self.calendar_manager.filename}")
except Exception as e:
QMessageBox.critical(self, "Error", f"Failed to save calendar: {str(e)}")
def load_file(self):
"""Load calendar entries from a JSON file"""
- file_path, _ = QFileDialog.getOpenFileName(self, "Einträge laden", "", "JSON Files (*.json)")
+ file_path, _ = QFileDialog.getOpenFileName(self, "Load Calendar", "", "JSON Files (*.json)")
if not file_path:
return
@@ -423,21 +358,21 @@ class CalendarManagerGUI(QMainWindow):
self.calendar_manager.load_file(file_path)
self.update_events_table()
self.update_prediction() # Auto-update prediction
- QMessageBox.information(self, "Laden erfolgreich", f"Einträge erfolgreich von {file_path} geladen")
+ QMessageBox.information(self, "Load Successful", f"Calendar loaded from {file_path}")
except Exception as e:
QMessageBox.critical(self, "Error", f"Failed to load calendar: {str(e)}")
def clear_entries(self):
"""Clear all calendar entries"""
- reply = QMessageBox.question(self, "Einträge löschen",
- "Alle Einträge löschen?",
+ reply = QMessageBox.question(self, "Clear Calendar",
+ "Are you sure you want to clear all events?",
QMessageBox.Yes | QMessageBox.No)
if reply == QMessageBox.Yes:
try:
self.calendar_manager.clear_entries()
self.update_events_table()
self.update_prediction() # Auto-update prediction
- QMessageBox.information(self, "Erfolg", "Alle Einträge gelöscht!")
+ QMessageBox.information(self, "Success", "Calendar cleared successfully")
except Exception as e:
QMessageBox.critical(self, "Error", f"Failed to clear calendar: {str(e)}")
@@ -445,8 +380,6 @@ class CalendarManagerGUI(QMainWindow):
def main():
app = QApplication(sys.argv)
app.setStyle('Fusion')
- # Ensure Arial is available
- QFontDatabase.addApplicationFont("Arial")
window = CalendarManagerGUI()
window.show()
sys.exit(app.exec_())