112 lines
4.5 KiB
C#
112 lines
4.5 KiB
C#
using Contime.data;
|
|
using Contime.model;
|
|
using Contime.view;
|
|
|
|
namespace Contime.controller {
|
|
public class TimeTrackerController {
|
|
private readonly TimeTrackerModel _model;
|
|
private readonly MainForm _view;
|
|
private readonly System.Windows.Forms.Timer _timer;
|
|
|
|
private const int IDLE_NOTIFICATION_MINUTES = 15;
|
|
private const int ACTIVE_TASK_NOTIFICATION_MINUTES = 60;
|
|
|
|
private bool _idleNotificationSent = false;
|
|
private bool _activeTaskNotificationSent = false;
|
|
|
|
public TimeTrackerController(TimeTrackerModel model, MainForm view) {
|
|
_model = model;
|
|
_view = view;
|
|
|
|
// Subscribe to model and view events
|
|
_model.StateChanged += OnModelStateChanged;
|
|
_model.MajorStateChanged += OnModelMajorStateChanged;
|
|
|
|
_view.WorkdayStartStopClicked += () => _model.StartStopWorkday();
|
|
_view.TaskStartStopClicked += () => _model.StartStopTask();
|
|
_view.GoOutOfContextClicked += () => _model.SwitchContext();
|
|
_view.ToggleTaskStatusClicked += () => _model.ToggleSelectedTaskStatus();
|
|
_view.AddTaskClicked += () => _model.AddTask(_view.NewTaskName);
|
|
_view.TaskSelected += (taskId) => _model.SelectTask(taskId);
|
|
_view.SaveContextClicked += () => _model.OutOfContextReason = _view.ContextText;
|
|
_view.ExportClicked += OnExportClicked;
|
|
|
|
// Setup the main timer
|
|
_timer = new System.Windows.Forms.Timer { Interval = 1000 };
|
|
_timer.Tick += OnTimerTick;
|
|
|
|
// Initial UI update
|
|
_view.UpdateView(_model);
|
|
}
|
|
|
|
private void OnTimerTick(object sender, EventArgs e) {
|
|
if (_model.CurrentState == TimeTrackerModel.AppState.Idle) {
|
|
_timer.Stop();
|
|
return;
|
|
}
|
|
|
|
_view.UpdateTimersAndState(_model);
|
|
CheckNotifications();
|
|
}
|
|
|
|
private void OnModelStateChanged() {
|
|
if (_model.CurrentState != TimeTrackerModel.AppState.Idle && !_timer.Enabled) {
|
|
_timer.Start();
|
|
}
|
|
_view.UpdateTimersAndState(_model);
|
|
|
|
// Reset notification flags on state change
|
|
_idleNotificationSent = false;
|
|
_activeTaskNotificationSent = false;
|
|
}
|
|
|
|
private void OnModelMajorStateChanged() {
|
|
// A major state change might require starting the timer (e.g., starting the workday)
|
|
if (_model.CurrentState != TimeTrackerModel.AppState.Idle && !_timer.Enabled) {
|
|
_timer.Start();
|
|
}
|
|
|
|
// This event is for when the task list needs a full refresh
|
|
_view.UpdateView(_model);
|
|
}
|
|
|
|
private void CheckNotifications() {
|
|
// Notification for being idle (workday active, no task)
|
|
if (_model.CurrentState == TimeTrackerModel.AppState.WorkdayActive &&
|
|
_model.IdleTime.TotalMinutes >= IDLE_NOTIFICATION_MINUTES &&
|
|
!_idleNotificationSent) {
|
|
_view.ShowNotification("Task Reminder", "You've been idle for over 15 minutes. Remember to select a task.");
|
|
_idleNotificationSent = true;
|
|
}
|
|
|
|
// Notification for a long-running task
|
|
if (_model.CurrentState == TimeTrackerModel.AppState.TaskActive &&
|
|
_model.ActiveTaskTime.TotalMinutes >= ACTIVE_TASK_NOTIFICATION_MINUTES &&
|
|
!_activeTaskNotificationSent) {
|
|
_view.ShowNotification("Task Check-in", $"The current task has been running for over an hour. Still on it?");
|
|
_activeTaskNotificationSent = true;
|
|
}
|
|
}
|
|
|
|
private void OnExportClicked() {
|
|
using (var sfd = new SaveFileDialog()) {
|
|
sfd.Filter = "Excel Workbook|*.xlsx";
|
|
sfd.ValidateNames = true;
|
|
sfd.FileName = $"Contime_Report_{DateTime.Now:yyyy-MM-dd}.xlsx";
|
|
|
|
if (sfd.ShowDialog() == DialogResult.OK) {
|
|
try {
|
|
var exporter = new ExcelExporter(_model.DataAccess);
|
|
exporter.Export(sfd.FileName);
|
|
_view.ShowNotification("Export Successful", $"Report saved to {sfd.FileName}");
|
|
}
|
|
catch (Exception ex) {
|
|
MessageBox.Show($"An error occurred during export: {ex.Message}", "Export Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|