Files
lazarus-ccr/components/jvcllaz/run/JvTimeFramework/jvtfalarm.pas

340 lines
8.7 KiB
ObjectPascal
Raw Normal View History

{-----------------------------------------------------------------------------
The contents of this file are subject to the Mozilla Public License
Version 1.1 (the "License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/MPL-1.1.html
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See the License for
the specific language governing rights and limitations under the License.
The Original Code is: JvTFAlarm.PAS, released on 2003-08-01.
The Initial Developer of the Original Code is Unlimited Intelligence Limited.
Portions created by Unlimited Intelligence Limited are Copyright (C) 1999-2002 Unlimited Intelligence Limited.
All Rights Reserved.
Contributor(s):
Mike Kolter (original code)
You may retrieve the latest version of this file at the Project JEDI's JVCL home page,
located at http://jvcl.delphi-jedi.org
Known Issues:
-----------------------------------------------------------------------------}
// $Id$
unit JvTFAlarm;
{$mode objfpc}{$H+}
interface
uses
SysUtils, Classes, Controls, ExtCtrls,
JvTFManager;
type
TJvTFAlarm = class;
TJvTFAlarmInfo = class(TObject)
private
FAppt: TJvTFAppt;
FSnoozeMins: Integer;
FDismiss: Boolean;
FNextAlarmTime: TTime;
protected
property NextAlarmTime: TTime read FNextAlarmTime write FNextAlarmTime;
public
constructor Create(AAppt: TJvTFAppt); virtual;
property Appt: TJvTFAppt read FAppt;
property SnoozeMins: Integer read FSnoozeMins write FSnoozeMins;
property Dismiss: Boolean read FDismiss write FDismiss;
end;
TJvTFAlarmList = class(TStringList)
private
FOwner: TJvTFAlarm;
public
procedure Clear; override;
function GetAlarmForAppt(AAppt: TJvTFAppt): TJvTFAlarmInfo;
function GetAlarmForApptID(const ID: string): TJvTFAlarmInfo;
function IndexOfAppt(AAppt: TJvTFAppt): Integer;
procedure AddAppt(AAppt: TJvTFAppt);
procedure DeleteAppt(AAppt: TJvTFAppt);
property Owner: TJvTFAlarm read FOwner write FOwner;
end;
TJvTFAlarmEvent = procedure(Sender: TObject; AAppt: TJvTFAppt;
var SnoozeMins: Integer; var Dismiss: Boolean) of object;
TJvTFAlarm = class(TJvTFComponent)
private
FResources: TStringList;
FTimer: TTimer;
FCurrentDate: TDate;
FAlarmList: TJvTFAlarmList;
FOnAlarm: TJvTFAlarmEvent;
FDefaultSnoozeMins: Integer;
function GetResources: TStrings;
procedure SetResources(Value: TStrings);
function GetTimerInterval: Integer;
procedure SetTimerInterval(Value: Integer);
function GetEnabled: Boolean;
procedure SetEnabled(Value: Boolean);
procedure InternalTimer(Sender: TObject);
protected
procedure DestroyApptNotification(AAppt: TJvTFAppt); override;
procedure ConnectSchedules; virtual;
procedure DisconnectSchedules; virtual;
procedure TimerCheck; virtual;
procedure AlarmCheck; virtual;
procedure Loaded; override;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
published
property Resources: TStrings read GetResources write SetResources;
property TimerInterval: Integer read GetTimerInterval write SetTimerInterval default 30000;
property Enabled: Boolean read GetEnabled write SetEnabled default True;
property DefaultSnoozeMins: Integer read FDefaultSnoozeMins write FDefaultSnoozeMins default 5;
property OnAlarm: TJvTFAlarmEvent read FOnAlarm write FOnAlarm;
end;
implementation
uses
JvTFUtils;
//=== { TJvTFAlarm } =========================================================
constructor TJvTFAlarm.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FDefaultSnoozeMins := 5;
FCurrentDate := Date;
FResources := TStringList.Create;
FTimer := TTimer.Create(Self);
FTimer.Interval := 30000;
FTimer.Enabled := True;
FTimer.OnTimer := @InternalTimer;
FAlarmList := TJvTFAlarmList.Create;
FAlarmList.Owner := Self;
end;
destructor TJvTFAlarm.Destroy;
begin
DisconnectSchedules;
FTimer.Free;
FResources.Free;
FAlarmList.Create;
FAlarmList.Free;
inherited Destroy;
end;
procedure TJvTFAlarm.Loaded;
begin
inherited Loaded;
ConnectSchedules;
end;
procedure TJvTFAlarm.AlarmCheck;
var
I, J, SnoozeMins: Integer;
Dismiss: Boolean;
Sched: TJvTFSched;
Appt: TJvTFAppt;
AlarmInfo: TJvTFAlarmInfo;
AlarmTime: TTime;
begin
// 1. Roll through all schedules and add an alarm for each appt with a start
// time that is less than the current time. (Duplicate appts will be ignored.)
// 2. Roll through the alarm list and fire an OnAlarm event when appropriate.
// 1.
for I := 0 to ScheduleCount - 1 do
begin
Sched := Schedules[I];
for J := 0 to Sched.ApptCount - 1 do
begin
Appt := Sched.Appts[J];
AlarmTime := Appt.StartTime - Appt.AlarmAdvance * ONE_MINUTE;
if (AlarmTime < Frac(Time)) and Appt.AlarmEnabled then
FAlarmList.AddAppt(Appt);
end;
end;
// 2.
for I := 0 to FAlarmList.Count - 1 do
begin
AlarmInfo := TJvTFAlarmInfo(FAlarmList.Objects[I]);
if not AlarmInfo.Dismiss and (AlarmInfo.NextAlarmTime < Frac(Time)) then
begin
SnoozeMins := AlarmInfo.SnoozeMins;
Dismiss := False;
if Assigned(FOnAlarm) then
begin
FOnAlarm(Self, AlarmInfo.Appt, SnoozeMins, Dismiss);
AlarmInfo.SnoozeMins := SnoozeMins;
AlarmInfo.Dismiss := Dismiss;
end;
AlarmInfo.NextAlarmTime := Time + SnoozeMins * ONE_MINUTE;
end;
end;
end;
procedure TJvTFAlarm.ConnectSchedules;
var
I: Integer;
CurrentSchedules: TStringList;
Schedule: TJvTFSched;
begin
CurrentSchedules := TStringList.Create;
try
FTimer.Enabled := False;
// request all appropriate schedules. Store in temporary list so that
// we can release all schedules no longer needed.
for I := 0 to Resources.Count - 1 do
begin
Schedule := RetrieveSchedule(Resources[I], Date);
CurrentSchedules.AddObject('', Schedule);
end;
// Now release all schedules no longer needed. (Cross check CurrentSchedules
// against Schedules list.)
for I := 0 to ScheduleCount - 1 do
begin
Schedule := Schedules[I];
if CurrentSchedules.IndexOfObject(Schedule) = -1 then
ReleaseSchedule(Schedule.SchedName, Schedule.SchedDate);
end;
finally
CurrentSchedules.Free;
FTimer.Enabled := True;
end;
end;
procedure TJvTFAlarm.DestroyApptNotification(AAppt: TJvTFAppt);
begin
FAlarmList.DeleteAppt(AAppt);
inherited DestroyApptNotification(AAppt);
end;
procedure TJvTFAlarm.DisconnectSchedules;
begin
ReleaseSchedules;
end;
function TJvTFAlarm.GetEnabled: Boolean;
begin
Result := FTimer.Enabled;
end;
function TJvTFAlarm.GetTimerInterval: Integer;
begin
Result := FTimer.Interval;
end;
function TJvTFAlarm.GetResources: TStrings;
begin
Result := FResources;
end;
procedure TJvTFAlarm.InternalTimer(Sender: TObject);
begin
if Trunc(Date) <> Trunc(FCurrentDate) then
begin
FCurrentDate := Date;
ConnectSchedules;
end;
TimerCheck;
end;
procedure TJvTFAlarm.SetEnabled(Value: Boolean);
begin
FTimer.Enabled := Value;
end;
procedure TJvTFAlarm.SetResources(Value: TStrings);
begin
FResources.Assign(Value);
ConnectSchedules;
end;
procedure TJvTFAlarm.SetTimerInterval(Value: Integer);
begin
FTimer.Interval := Value;
end;
procedure TJvTFAlarm.TimerCheck;
begin
AlarmCheck;
end;
//=== { TJvTFAlarmInfo } =====================================================
constructor TJvTFAlarmInfo.Create(AAppt: TJvTFAppt);
begin
inherited Create;
FAppt := AAppt;
end;
//=== { TJvTFAlarmList } =====================================================
procedure TJvTFAlarmList.AddAppt(AAppt: TJvTFAppt);
var
AlarmInfo: TJvTFAlarmInfo;
begin
if Assigned(AAppt) and (IndexOfAppt(AAppt) = -1) then
begin
AlarmInfo := TJvTFAlarmInfo.Create(AAppt);
AlarmInfo.SnoozeMins := Owner.DefaultSnoozeMins;
AlarmInfo.NextAlarmTime := AAppt.StartTime - AAppt.AlarmAdvance * ONE_MINUTE;
AddObject(AAppt.ID, AlarmInfo);
end;
end;
procedure TJvTFAlarmList.Clear;
var
I: Integer;
begin
for I := 0 to Count - 1 do
Objects[I].Free;
inherited Clear;
end;
procedure TJvTFAlarmList.DeleteAppt(AAppt: TJvTFAppt);
var
I: Integer;
begin
I := IndexOfAppt(AAppt);
if I > -1 then
begin
Objects[I].Free;
Delete(I);
end;
end;
function TJvTFAlarmList.GetAlarmForAppt(AAppt: TJvTFAppt): TJvTFAlarmInfo;
begin
Result := GetAlarmForApptID(AAppt.ID);
end;
function TJvTFAlarmList.GetAlarmForApptID(const ID: string): TJvTFAlarmInfo;
var
I: Integer;
begin
Result := nil;
I := IndexOf(ID);
if I > -1 then
Result := TJvTFAlarmInfo(Objects[I]);
end;
function TJvTFAlarmList.IndexOfAppt(AAppt: TJvTFAppt): Integer;
begin
Result := IndexOf(AAppt.ID);
end;
end.