Files
lazarus-ccr/components/tvplanit/source/vpevnteditdlg.pas
christian_u b6ccf41e4f Fixed some small bugs
fixed dayview
reworked event Edit Dlg

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@1084 8e941d3f-bd1b-0410-a28a-d453659cc2b4
2009-12-24 22:41:52 +00:00

733 lines
22 KiB
ObjectPascal

{*********************************************************}
{* VPEVNTEDITDLG.PAS 1.03 *}
{*********************************************************}
{* ***** BEGIN LICENSE BLOCK ***** *}
{* Version: MPL 1.1 *}
{* *}
{* 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/ *}
{* *}
{* Software distributed under the License is distributed on an "AS IS" basis, *}
{* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License *}
{* for the specific language governing rights and limitations under the *}
{* License. *}
{* *}
{* The Original Code is TurboPower Visual PlanIt *}
{* *}
{* The Initial Developer of the Original Code is TurboPower Software *}
{* *}
{* Portions created by TurboPower Software Inc. are Copyright (C) 2002 *}
{* TurboPower Software Inc. All Rights Reserved. *}
{* *}
{* Contributor(s): *}
{* *}
{* ***** END LICENSE BLOCK ***** *}
{$I Vp.INC}
unit VpEvntEditDlg;
{ The default event edit dialog }
interface
uses
{$IFDEF LCL}
LMessages,LCLProc,LCLType,LCLIntf,LResources,
{$ELSE}
Windows, Messages, Mask,
{$ENDIF}
SysUtils, {$IFDEF VERSION6}Variants,{$ENDIF} Classes,
Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls, VpData, VpEdPop,
VpDateEdit, ComCtrls, VpBase, VpClock, VpBaseDS, VpDlg, VpConst,
Buttons, EditBtn;
type
{ forward declarations }
TVpEventEditDialog = class;
TEventEditDlgRtnType = (rtCommit, rtAbandon);
TVpRightAlignedEdit = class(TEdit)
public
procedure CreateParams(var Params : TCreateParams); override;
end;
{ TDlgEventEdit }
TDlgEventEdit = class(TForm)
AlarmAdvance: TEdit;
NotesMemo: TMemo;
StartDate: TDateEdit;
EndDate: TDateEdit;
RepeatUntil: TDateEdit;
Panel1: TPanel;
OKBtn: TButton;
CancelBtn: TButton;
ResourceNameLbl: TLabel;
FileDialog: TOpenDialog;
pgEvent: TPageControl;
tabEvent: TTabSheet;
AppointmentGroupBox: TGroupBox;
DescriptionLbl: TLabel;
Bevel1: TBevel;
Bevel2: TBevel;
CategoryLbl: TLabel;
StartTimeLbl: TLabel;
EndTimeLbl: TLabel;
Image2: TImage;
RecurringLbl: TLabel;
Bevel3: TBevel;
IntervalLbl: TLabel;
Image1: TImage;
SpeedButton1: TSpeedButton;
DescriptionEdit: TEdit;
AlarmSet: TCheckBox;
StartTime: TComboBox;
EndTime: TComboBox;
Category: TComboBox;
RecurringType: TComboBox;
IntervalUpDown: TUpDown;
AlarmAdvType: TComboBox;
AdvanceUpDown: TUpDown;
CBAllDay: TCheckBox;
edtUnusedPlaceholder: TEdit;
imgClock: TImage;
RecurrenceEndsLbl: TLabel;
procedure CategoryDrawItem(Control: TWinControl; Index: Integer;
ARect: TRect; State: TOwnerDrawState);
procedure OKBtnClick(Sender: TObject);
procedure CancelBtnClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure StartDateChange(Sender: TObject);
procedure StartTimeChange(Sender: TObject);
procedure EndTimeChange(Sender: TObject);
procedure AlarmAdvanceChange(Sender: TObject);
procedure AdvanceUpDownClick(Sender: TObject; Button: TUDBtnType);
procedure CustomIntervalChange(Sender: TObject);
procedure IntervalUpDownClick(Sender: TObject; Button: TUDBtnType);
procedure RecurringTypeChange(Sender: TObject);
procedure AlarmSetClick(Sender: TObject);
procedure EndDateChange(Sender: TObject);
procedure CBAllDayClick(Sender: TObject);
procedure SpeedButton1Click(Sender: TObject);
procedure FormShow(Sender: TObject);
procedure StartTimeExit(Sender: TObject);
procedure EndTimeExit(Sender: TObject);
private { Private declarations }
AAVerifying: Boolean;
CIVerifying: Boolean;
FCustomInterval : TVpRightAlignedEdit;
procedure PopLists;
procedure LoadCaptions;
public { Public declarations }
Event: TVpEvent;
CatColorMap: TVpCategoryColorMap;
Resource: TVpResource;
ReturnCode: TEventEditDlgRtnType;
Conflicts : Integer;
TimeFormat: TVpTimeFormat;
AlarmWavPath: string;
FLastEndTime : TDateTime;
procedure PopulateDialog;
procedure DePopulateDialog;
end;
TVpEventEditDialog = class(TVpBaseDialog)
protected {private}
ceEditDlg : TDlgEventEdit;
FTimeFormat : TVpTimeFormat;
ceEvent : TVpEvent;
public
constructor Create(AOwner : TComponent); override;
function Execute(Event: TVpEvent;
TimeFormat: TVpTimeFormat = tf12Hour): Boolean; reintroduce;
function AddNewEvent(StartTime, EndTime: TDateTime): Boolean;
published
{properties}
property TimeFormat: TVpTimeFormat
read FTimeFormat write FTimeFormat default tf12Hour;
property DataStore;
property Options;
property Placement;
end;
implementation
uses
VpSR, VpWavDlg;
{$IFNDEF LCL}
{$R *.dfm}
{$ENDIF}
{ TVpRightAlignedEdit }
procedure TVpRightAlignedEdit.CreateParams(var Params: TCreateParams);
begin
inherited;
{$IFNDEF LCL}
Params.Style := Params.Style or ES_MULTILINE or ES_RIGHT;
{$ENDIF}
end;
{=====}
{ TDlgEventEdit }
procedure TDlgEventEdit.FormCreate(Sender: TObject);
begin
ReturnCode := rtAbandon;
PopLists;
LoadCaptions;
StartTime.ItemIndex := -1;
EndTime.ItemIndex := -1;
EndDate.Enabled := False;
FCustomInterval := TVpRightAlignedEdit.Create(Self);
with FCustomInterval do begin
Parent := AppointmentGroupbox;
Top := IntervalUpDown.Top + 1;
Left := IntervalUpDown.Left - 65;
Height := IntervalUpDown.Height - 1;
Width := 65;
MaxLength := 5;
OnChange := CustomIntervalChange;
TabOrder := edtUnusedPlaceholder.TabOrder;
end;
IntervalUpDown.Associate := FCustomInterval;
end;
{=====}
procedure TDlgEventEdit.OKBtnClick(Sender: TObject);
begin
ReturnCode := rtCommit;
Close;
end;
procedure TDlgEventEdit.CategoryDrawItem(Control: TWinControl; Index: Integer;
ARect: TRect; State: TOwnerDrawState);
var
Color, SaveColor: TColor;
Name: string;
ColorRect: TRect;
begin
Category.Canvas.FillRect(ARect);
Color := clBlack;
case Index of
0: begin
Color := CatColorMap.Category0.Color;
Name := CatColorMap.Category0.Description;
end;
1: begin
Color := CatColorMap.Category1.Color;
Name := CatColorMap.Category1.Description;
end;
2: begin
Color := CatColorMap.Category2.Color;
Name := CatColorMap.Category2.Description;
end;
3: begin
Color := CatColorMap.Category3.Color;
Name := CatColorMap.Category3.Description;
end;
4: begin
Color := CatColorMap.Category4.Color;
Name := CatColorMap.Category4.Description;
end;
5: begin
Color := CatColorMap.Category5.Color;
Name := CatColorMap.Category5.Description;
end;
6: begin
Color := CatColorMap.Category6.Color;
Name := CatColorMap.Category6.Description;
end;
7: begin
Color := CatColorMap.Category7.Color;
Name := CatColorMap.Category7.Description;
end;
8: begin
Color := CatColorMap.Category8.Color;
Name := CatColorMap.Category8.Description;
end;
9: begin
Color := CatColorMap.Category9.Color;
Name := CatColorMap.Category9.Description;
end;
end; {Case}
SaveColor := Category.Canvas.Brush.Color;
Category.Canvas.Brush.Color := Color;
Category.Canvas.Pen.Color := clBlack;
ColorRect.Left := ARect.Left + 3;
ColorRect.Top := ARect.Top + 2;
ColorRect.Bottom := ARect.Bottom - 2;
ColorRect.Right := ColorRect.Left + 20;
Category.Canvas.FillRect(ColorRect);
{$IFDEF VERSION5}
Category.Canvas.Rectangle(ColorRect);
{$ELSE}
Category.Canvas.Rectangle(ColorRect.Left, ColorRect.Top, ColorRect.Right,
ColorRect.Bottom);
{$ENDIF}
ARect.Left := ColorRect.Right + 5;
Category.Canvas.Brush.Color := SaveColor;
Category.Canvas.TextOut(ARect.Left, ARect.Top, Name);
end;
{=====}
procedure TDlgEventEdit.CancelBtnClick(Sender: TObject);
begin
Close;
end;
{=====}
procedure TDlgEventEdit.PopulateDialog;
var
I: Integer;
begin
{ Resource }
ResourceNameLbl.Caption := Resource.Description;
{ Events }
StartDate.Date := Event.StartTime;
EndDate.Date := Event.EndTime;
RepeatUntil.Date := Event.RepeatRangeEnd;
StartTime.Text := FormatDateTime('hh:mm',Event.StartTime);
EndTime.Text := FormatDateTime('hh:mm',Event.EndTime);
StartTimeChange(Self);
CBAllDay.Checked := Event.AllDayEvent;
AlarmWavPath := Event.AlarmWavPath;
StartDate.Enabled := not CBAllDay.Checked;
EndDate.Enabled := not CBAllDay.Checked;
EndTime.Enabled := not CBAllDay.Checked;
StartTime.Enabled := not CBAllDay.Checked;
DescriptionEdit.Text := Event.Description;
NotesMemo.Text := Event.Note;
AlarmSet.Checked := Event.AlarmSet;
AlarmSetClick(Self);
if not Event.AlarmSet then
AlarmAdvance.Text := '15'
else
AlarmAdvance.Text := IntToStr(Event.AlarmAdv);
AlarmAdvType.ItemIndex := Ord(Event.AlarmAdvType);
RecurringType.ItemIndex := Ord(Event.RepeatCode);
RecurringTypeChange(Self);
FCustomInterval.Text := IntToStr(Event.CustInterval);
Category.Items.Clear;
for I := 0 to 9 do
if (CatColorMap.GetName(I) <> '') then
Category.Items.Add(CatColorMap.GetName(I));
Category.ItemIndex := Event.Category;
FLastEndTime := Event.EndTime;
end;
{=====}
procedure TDlgEventEdit.DePopulateDialog;
begin
{ Events }
Event.StartTime := StartDate.Date + StrToTime(StartTime.Text);
Event.EndTime := EndDate.Date + StrToTime(EndTime.Text);
Event.RepeatRangeEnd := RepeatUntil.Date;
Event.Description := DescriptionEdit.Text;
Event.Note := NotesMemo.Text;
Event.Category := Category.ItemIndex;
Event.AlarmSet := AlarmSet.Checked;
Event.AlarmAdv := StrToIntDef(AlarmAdvance.Text, 0);
Event.AlarmAdvType := TVpAlarmAdvType(AlarmAdvType.ItemIndex);
Event.RepeatCode := TVpRepeatType(RecurringType.ItemIndex);
Event.CustInterval := StrToIntDef(FCustomInterval.Text, 0);
Event.AllDayEvent := CBAllDay.Checked;
Event.AlarmWavPath := AlarmWavPath;
end;
{=====}
procedure TDlgEventEdit.StartDateChange(Sender: TObject);
begin
if StartDate.Date > EndDate.Date then
EndDate.Date := StartDate.Date;
end;
{=====}
procedure TDlgEventEdit.EndDateChange(Sender: TObject);
begin
if StartDate.Date > EndDate.Date then
StartDate.Date := EndDate.Date;
end;
{=====}
procedure TDlgEventEdit.StartTimeChange(Sender: TObject);
var
ST: TDateTime;
begin
{ Verify the value is valid }
try
ST := StrToTime(StartTime.Text);
except
StartTime.Color := clRed;
if Visible then
StartTime.SetFocus;
Exit;
end;
StartTime.Color := clWindow;
{ if the end time is less than the start time then change the end time to }
{ follow the start time by 30 minutes }
if ST > StrToTime(EndTime.Text) then begin
if TimeFormat = tf24Hour then
EndTime.Text := FormatDateTime ('h:mm',
ST + (30/MinutesInDay))
else
EndTime.Text := FormatDateTime ('hh:mm AM/PM',
ST + (30/MinutesInDay));
end;
end;
{=====}
procedure TDlgEventEdit.EndTimeChange(Sender: TObject);
function IsMidnight (ATime : TDateTime) : Boolean;
begin
Result := ATime = Trunc (ATime);
end;
var
ET: TDateTime;
begin
{ Verify the value is valid }
try
ET := StrToTime (EndTime.Text);
if (IsMidnight (ET)) and (not IsMidnight (FLastEndTime)) then
EndDate.Date := EndDate.Date + 1
else if (not IsMidnight (ET)) and (IsMidnight (FLastEndTime)) then
EndDate.Date := EndDate.Date - 1;
FLastEndTime := ET;
except
EndTime.Color := clRed;
EndTime.SetFocus;
Exit;
end;
EndTime.Color := clWindow;
{ if the end time is less than the start time then change the start time to }
{ precede the end time by 30 minutes }
if ET < StrToTime(StartTime.Text) then begin
if TimeFormat = tf24Hour then
StartTime.Text := FormatDateTime ('h:mm',
ET - (30/MinutesInDay))
else
StartTime.Text := FormatDateTime ('h:mm AM/PM',
ET - (30/MinutesInDay));
end;
end;
{=====}
procedure TDlgEventEdit.PopLists;
var
StringList: TStringList;
I, Hour, Minute: Integer;
MinStr, AMPMStr: string;
begin
{ Time Lists }
StringList := TStringList.Create;
try
Minute := 0;
AMPMStr := ' AM';
for I := 0 to 96 do begin
if I > 0 then Inc(Minute, 15);
if Minute > 719 then
AMPMStr := ' PM';
if Minute = MinutesInDay then
AMPMStr := ' AM';
Hour := (Minute div 15) div 4;
MinStr := IntToStr(Minute mod 60);
if MinStr = '0' then MinStr := '00';
if TimeFormat = tf24Hour then
StringList.Add(IntToStr(Hour) + ':' + MinStr)
else begin
if Hour > 12 then Hour := Hour - 12;
if Hour = 0 then Hour := 12;
StringList.Add(IntToStr(Hour) + ':' + MinStr + AMPMStr);
end;
end;
StartTime.Items.Assign(StringList);
StartTime.ItemIndex := 0;
EndTime.Items.Assign(StringList);
EndTime.ItemIndex := 0;
finally
StringList.Free;
end;
{ RecurringList }
RecurringType.Items.Add(RSNone);
RecurringType.Items.Add(RSDaily);
RecurringType.Items.Add(RSWeekly);
RecurringType.Items.Add(RSMonthlyByDay);
RecurringType.Items.Add(RSMonthlyByDate);
RecurringType.Items.Add(RSYearlyByDay);
RecurringType.Items.Add(RSYearlyByDate);
RecurringType.Items.Add(RSCustom);
RecurringType.ItemIndex := 0;
{ Alarm Advance Type }
AlarmAdvType.Items.Add(RSMinutes);
AlarmAdvType.Items.Add(RSHours);
AlarmAdvType.Items.Add(RSDays);
AlarmAdvType.ItemIndex := 0;
end;
{=====}
procedure TDlgEventEdit.LoadCaptions;
begin
OKBtn.Caption := RSOKBtn;
CancelBtn.Caption := RSCancelBtn;
AppointmentGroupBox.Caption := RSAppointmentGroupBox;
DescriptionLbl.Caption := RSDescriptionLbl;
CategoryLbl.Caption := RSCategoryLbl;
StartTimeLbl.Caption := RSStartTimeLbl;
EndTimeLbl.Caption := RSEndTimeLbl;
AlarmSet.Caption := RSAlarmSet;
RecurringLbl.Caption := RSRecurringLbl;
IntervalLbl.Caption := RSIntervalLbl;
RecurrenceEndsLbl.Caption := RSRecurrenceEndsLbl;
CBAllDay.Caption := RSAllDayEvent;
end;
{=====}
procedure TDlgEventEdit.AlarmAdvanceChange(Sender: TObject);
var
I: Integer;
Str: string;
begin
if AAVerifying then exit;
AAVerifying := true;
{ Don't allow non numeric values. }
Str := AlarmAdvance.Text;
I := Length(Str);
if (Str[I] > #57) or (Str[I] < #48) then
Delete(Str, I, 1);
AlarmAdvance.Text := Str;
AAVerifying := false;
if Str <> '' then
AdvanceUpDown.Position := StrToInt(Str);
end;
{=====}
procedure TDlgEventEdit.AdvanceUpDownClick(Sender: TObject; Button: TUDBtnType);
begin
{ Inc or Dec AlarmAdvance according to which button was pressed }
{ case Button of
btNext:
AlarmAdvance.Text := IntToStr(StrToIntDef(AlarmAdvance.Text, 0) + 1);
btPrev:
AlarmAdvance.Text := IntToStr(StrToIntDef(AlarmAdvance.Text, 0) - 1);
end;}
AlarmAdvance.Text := IntToStr(AdvanceUpDown.Position);
end;
{=====}
procedure TDlgEventEdit.CustomIntervalChange(Sender: TObject);
var
I: Integer;
Str: string;
begin
{ Don't allow non numeric values. }
if CIVerifying then Exit;
CIVerifying := true;
Str := FCustomInterval.Text;
for I := 1 to Length(Str) do
if (Ord(Str[I]) in [48..57]) then
Continue
else
Delete(Str, I, 1);
FCustomInterval.Text := Str;
if Str <> '' then
IntervalUpDown.Position := StrToInt(Str);
CIVerifying := false;
end;
{=====}
procedure TDlgEventEdit.IntervalUpDownClick(Sender: TObject; Button: TUDBtnType);
begin
FCustomInterval.Text := IntToStr(IntervalUpDown.Position);
end;
{=====}
procedure TDlgEventEdit.RecurringTypeChange(Sender: TObject);
begin
if (RecurringType.ItemIndex > 0)
and (RepeatUntil.Date <= StartDate.Date)
then
RepeatUntil.Date := StartDate.Date + 365;
RecurrenceEndsLbl.Enabled := (RecurringType.ItemIndex > 0);
RepeatUntil.Enabled := RecurrenceEndsLbl.Enabled;
FCustomInterval.Enabled := RecurringType.ItemIndex = 7;
IntervalLbl.Enabled := FCustomInterval.Enabled;
IntervalUpDown.Enabled := FCustomInterval.Enabled;
if FCustomInterval.Enabled then begin
FCustomInterval.Text := IntToStr(IntervalUpDown.Position);
if Visible then
FCustomInterval.SetFocus;
end;
end;
{=====}
procedure TDlgEventEdit.AlarmSetClick(Sender: TObject);
begin
AlarmAdvance.Enabled := AlarmSet.Checked;
AlarmAdvType.Enabled := AlarmSet.Checked;
AdvanceUpDown.Enabled := AlarmSet.Checked;
Event.SnoozeTime := 0.0;
end;
{=====}
procedure TDlgEventEdit.CBAllDayClick(Sender: TObject);
begin
StartDate.Enabled := not CBAllDay.Checked;
EndDate.Enabled := not CBAllDay.Checked;
EndTime.Enabled := not CBAllDay.Checked;
StartTime.Enabled := not CBAllDay.Checked;
end;
{=====}
procedure TDlgEventEdit.SpeedButton1Click(Sender: TObject);
begin
ExecuteSoundFinder(AlarmWavPath);
end;
{=====}
procedure TDlgEventEdit.FormShow(Sender: TObject);
begin
DescriptionEdit.SetFocus;
end;
{=====}
{ TVpEventEditDialog }
constructor TVpEventEditDialog.Create(AOwner : TComponent);
begin
inherited Create(AOwner);
FPlacement.Position := mpCenterTop;
FPlacement.Height := 415;
FPlacement.Width := 710;
end;
{=====}
function TVpEventEditDialog.Execute(Event: TVpEvent;
TimeFormat: TVpTimeFormat = tf12Hour): Boolean;
var
DlgEventEdit: TDlgEventEdit;
begin
ceEvent := Event;
DlgEventEdit := TDlgEventEdit.Create(Self);
try
DoFormPlacement(DlgEventEdit);
SetFormCaption(DlgEventEdit, Event.Description, RSDlgEventEdit);
DlgEventEdit.Event := Event;
DlgEventEdit.TimeFormat := FTimeFormat;
DlgEventEdit.Resource := DataStore.Resource;
DlgEventEdit.CatColorMap := DataStore.CategoryColorMap;
DlgEventEdit.PopulateDialog;
DlgEventEdit.ShowModal;
result := (DlgEventEdit.ReturnCode = rtCommit);
if Result then begin
DlgEventEdit.DePopulateDialog;
DataStore.PostEvents;
end;
finally
DlgEventEdit.Release;
end;
end;
{=====}
function TVpEventEditDialog.AddNewEvent(StartTime, EndTime: TDateTime): Boolean;
begin
Result := false;
if DataStore <> nil then begin
ceEvent := DataStore.Resource.Schedule.AddEvent(
DataStore.GetNextID(EventsTableName), StartTime, EndTime);
if ceEvent <> nil then begin
Result := Execute(ceEvent);
if (not Result) or (ceEvent = nil) then
ceEvent.Free;
end;
end;
end;
{=====}
procedure TDlgEventEdit.StartTimeExit(Sender: TObject);
var
ST : TDateTime;
begin
{ Verify the value is valid }
try
ST := StartDate.Date +
StrToTime (StartTime.Text);
except
StartTime.Color := clRed;
StartTime.SetFocus;
Exit;
end;
StartTime.Color := clWindow;
{ if the end time is less than the start time then change the end }
{ time to follow the start time by 30 minutes }
if ST > EndDate.Date +
StrToTime (EndTime.Text) then begin
EndTime.Text := FormatDateTime('hh:mm',ST + (30/MinutesInDay));
end;
end;
procedure TDlgEventEdit.EndTimeExit(Sender: TObject);
var
ET : TDateTime;
begin
{ Verify the value is valid }
try
ET := EndDate.Date + StrToTime (EndTime.Text);
except
EndTime.Color := clRed;
EndTime.SetFocus;
Exit;
end;
EndTime.Color := clWindow;
{ if the end time is less than the start time then change the }
{ start time to precede the end time by 30 minutes }
if ET < StartDate.Date +
StrToTime (StartTime.Text) then begin
StartTime.Text := FormatDateTime('hh:mm',ET- (30/MinutesInDay));
end;
end;
initialization
{$I vpevnteditdlg.lrs}
end.