Componentes.Terceros.DevExp.../internal/x.44/1/ExpressScheduler 2/Sources/cxSchedulerOutlookExchange.pas
2009-06-29 12:09:02 +00:00

1446 lines
48 KiB
ObjectPascal

{********************************************************************}
{ }
{ Developer Express Visual Component Library }
{ ExpressScheduler }
{ }
{ Copyright (c) 2003-2009 Developer Express Inc. }
{ ALL RIGHTS RESERVED }
{ }
{ The entire contents of this file is protected by U.S. and }
{ International Copyright Laws. Unauthorized reproduction, }
{ reverse-engineering, and distribution of all or any portion of }
{ the code contained in this file is strictly prohibited and may }
{ result in severe civil and criminal penalties and will be }
{ prosecuted to the maximum extent possible under the law. }
{ }
{ RESTRICTIONS }
{ }
{ THIS SOURCE CODE AND ALL RESULTING INTERMEDIATE FILES }
{ (DCU, OBJ, DLL, ETC.) ARE CONFIDENTIAL AND PROPRIETARY TRADE }
{ SECRETS OF DEVELOPER EXPRESS INC. THE REGISTERED DEVELOPER IS }
{ LICENSED TO DISTRIBUTE THE EXPRESSSCHEDULER AND ALL ACCOMPANYING }
{ VCL CONTROLS AS PART OF AN EXECUTABLE PROGRAM ONLY. }
{ }
{ THE SOURCE CODE CONTAINED WITHIN THIS FILE AND ALL RELATED }
{ FILES OR ANY PORTION OF ITS CONTENTS SHALL AT NO TIME BE }
{ COPIED, TRANSFERRED, SOLD, DISTRIBUTED, OR OTHERWISE MADE }
{ AVAILABLE TO OTHER INDIVIDUALS WITHOUT EXPRESS WRITTEN CONSENT }
{ AND PERMISSION FROM DEVELOPER EXPRESS INC. }
{ }
{ CONSULT THE END USER LICENSE AGREEMENT FOR INFORMATION ON }
{ ADDITIONAL RESTRICTIONS. }
{ }
{********************************************************************}
unit cxSchedulerOutlookExchange;
{$I cxVer.inc}
interface
uses
{$IFDEF DELPHI6}
Variants,
{$ENDIF}
Classes, cxSchedulerStorage, ComObj, cxClasses, cxDateUtils;
type
TcxSchedulerExchangeProgressProc = procedure(ACurrent, ACount: Integer; var Abort: Boolean);
TcxAcceptEventExportFunc = function(AEvent: TcxSchedulerEvent): Boolean;
TcxAcceptAppointmentItemImportFunc = function(const AppointmentItem: OleVariant): Boolean;
TcxAppointmentItemToEventProc = procedure(const AppointmentItem: OleVariant; AEvent: TcxSchedulerEvent);
TcxEventToAppointmentItemProc = procedure(AEvent: TcxSchedulerEvent; const AppointmentItem: OleVariant);
{ TcxAppointmentInfo }
TcxAppointmentInfo = class
private
FAppointmentItem: OleVariant;
FEntryID: string;
public
constructor Create(const AAppointmentItem: OleVariant);
property AppointmentItem: OleVariant read FAppointmentItem;
property EntryID: string read FEntryID;
end;
{ TcxAppointmentEntryIDList }
TcxAppointmentEntryIDList = class(TcxObjectList)
private
function GetItems(Index: Integer): TcxAppointmentInfo;
public
procedure Add(const AppointmentItem: OleVariant);
function ExtractAppointmentItem(AIndex: Integer): OleVariant;
function FindEntryID(const AEntryID: string; var Index: Integer): Boolean;
function IndexOfEntryID(const AEntryID: string): Integer;
procedure Populate(ACalendarFolder: OleVariant);
property Items[Index: Integer]: TcxAppointmentInfo read GetItems; default;
end;
{ TcxEventInfo }
TcxEventInfo = class
private
FEvent: TcxSchedulerEvent;
FEntryID: string;
public
constructor Create(AEvent: TcxSchedulerEvent; AEntryIDField: TcxCustomSchedulerStorageField);
property Event: TcxSchedulerEvent read FEvent;
property EntryID: string read FEntryID;
end;
{ TcxEventEntryIDList }
TcxEventEntryIDList = class(TcxObjectList)
private
function GetItems(Index: Integer): TcxEventInfo;
public
procedure Add(AEvent: TcxSchedulerEvent; AEntryIDField: TcxCustomSchedulerStorageField);
procedure DeleteEvent(AEvent: TcxSchedulerEvent);
function ExtractEvent(AIndex: Integer): TcxSchedulerEvent;
function FindEntryID(const AEntryID: string; var Index: Integer): Boolean;
function IndexOfEntryID(const AEntryID: string): Integer;
procedure Populate(AStorage: TcxCustomSchedulerStorage;
AEntryIDField: TcxCustomSchedulerStorageField);
property Items[Index: Integer]: TcxEventInfo read GetItems; default;
end;
{ TcxOutlookExchange }
TcxOutlookExchange = class
private
FCalendarFolder: OleVariant;
FOleInitialized: Boolean;
FOutlookApp: OleVariant;
FStorage: TcxCustomSchedulerStorage;
FWasCreated: Boolean;
FOnAcceptAppointmentItem: TcxAcceptAppointmentItemImportFunc;
FOnAcceptEvent: TcxAcceptEventExportFunc;
FOnConvertAppointmentItemToEvent: TcxAppointmentItemToEventProc;
FOnConvertEventToAppointmentItem: TcxEventToAppointmentItemProc;
FOnProgress: TcxSchedulerExchangeProgressProc;
function GetAllDayEvent(const AppointmentItem: OleVariant): Boolean;
function GetDaysOfWeekFromMask(AMask: Integer): TDays;
function GetDayTypeFromMask(AMask: Integer): TcxDayType;
function GetMaskFromDaysOfWeek(ADays: TDays): Integer;
function GetMaskFromDayType(ADayType: TcxDayType): Integer;
protected
function CanAcceptAppointmentItem(const AppointmentItem: OleVariant): Boolean;
function CanAcceptEvent(AEvent: TcxSchedulerEvent): Boolean;
function CanImportAppointmentItem(const AppointmentItem: OleVariant): Boolean; virtual;
procedure ConvertAppointmentItemToEvent(const AppointmentItem: OleVariant;
AEvent: TcxSchedulerEvent);
procedure ConvertEventToAppointmentItem(AEvent: TcxSchedulerEvent;
const AppointmentItem: OleVariant);
procedure ImportRecurrenceChain(APatternEvent: TcxSchedulerEvent;
const ARecurrencePattern: OleVariant);
procedure CheckRecurrencePatternExceptions(
const ARecurrencePattern: OleVariant;
APatternEvent: TcxSchedulerEvent);
procedure ExportRecurrenceChain(APatternEvent: TcxSchedulerEvent; const AppointmentItem: OleVariant);
function GetIsValid: Boolean; virtual;
function InitOleObject: Boolean;
procedure PostRecurrenceExeption(AOccurrence: TcxSchedulerEvent); virtual;
function RoundTime(ATime: TDateTime; ASaveDate: Boolean): TDateTime; virtual;
procedure SetAppointmentItemRecurrence(
const ARecurrencePattern: OleVariant; AEvent: TcxSchedulerEvent);
procedure SetupAppointmentItemInfo(const AppointmentItem: OleVariant;
const AEvent: TcxSchedulerEvent; ASetTime: Boolean = True);
procedure SetupEventInfo(AEvent: TcxSchedulerEvent;
const AppointmentItem: OleVariant);
procedure SetupEventRecurrenceInfo(AEvent: TcxSchedulerEvent;
const ARecurrencePattern: OleVariant);
procedure UpdateAppointmentItem(const AppointmentItem: OleVariant;
AEvent: TcxSchedulerEvent); virtual;
procedure UpdateEvent(AEvent: TcxSchedulerEvent;
const AppointmentItem: OleVariant; APostData: Boolean = True); virtual;
procedure UpdateEventWithRecurrenceInfo(AEvent: TcxSchedulerEvent;
const AppointmentItem: OleVariant);
function DoProgress(ACurrent, ACount: Integer): Boolean;
property CalendarFolder: OleVariant read FCalendarFolder;
property IsValid: Boolean read GetIsValid;
property OutlookApp: OleVariant read FOutlookApp;
property Storage: TcxCustomSchedulerStorage read FStorage;
public
constructor Create(AStorage: TcxCustomSchedulerStorage); virtual;
destructor Destroy; override;
procedure ExportEventToOutlook(AEvent: TcxSchedulerEvent);
procedure ExportToOutlook;
procedure ImportAppointmentItemFromOutlook(const AppointmentItem: OleVariant);
procedure ImportFromOutlook;
property OnAcceptAppointmentItem: TcxAcceptAppointmentItemImportFunc
read FOnAcceptAppointmentItem write FOnAcceptAppointmentItem;
property OnAcceptEvent: TcxAcceptEventExportFunc
read FOnAcceptEvent write FOnAcceptEvent;
property OnConvertAppointmentItemToEvent: TcxAppointmentItemToEventProc
read FOnConvertAppointmentItemToEvent write FOnConvertAppointmentItemToEvent;
property OnConvertEventToAppointmentItem: TcxEventToAppointmentItemProc
read FOnConvertEventToAppointmentItem write FOnConvertEventToAppointmentItem;
property OnProgress: TcxSchedulerExchangeProgressProc
read FOnProgress write FOnProgress;
end;
{ TcxOutlookSynchronize }
TcxOutlookSynchronize = class(TcxOutlookExchange)
private
FEntryIDField: TcxCustomSchedulerStorageField;
protected
procedure DeleteUnsynchronizedAppointments(AEntryIDs: TcxAppointmentEntryIDList);
procedure DeleteUnsynchronizedEvents(AEntryIDs: TcxEventEntryIDList);
function GetEntryIDFromEvent(AEvent: TcxSchedulerEvent): string;
function GetIsValid: Boolean; override;
function IsEqualRecurrencePattern(const AppointmentItem: OleVariant;
AEvent: TcxSchedulerEvent): Boolean;
procedure PostRecurrenceExeption(AOccurrence: TcxSchedulerEvent); override;
procedure PurgeDeletedOccurrences(APatternEvent: TcxSchedulerEvent;
AEntryIDs: TcxEventEntryIDList);
procedure UpdateAppointmentItem(const AppointmentItem: OleVariant;
AEvent: TcxSchedulerEvent); override;
procedure UpdateExistingAppointmentItem(const AppointmentItem: OleVariant;
AEvent: TcxSchedulerEvent);
procedure UpdateExistingEvent(AEvent: TcxSchedulerEvent;
const AppointmentItem: OleVariant; AEntryIDs: TcxEventEntryIDList);
procedure UpdateEvent(AEvent: TcxSchedulerEvent;
const AppointmentItem: OleVariant; APostData: Boolean = True); override;
procedure SynchronizeRecurrenceChainWithOutlook(
APatternEvent: TcxSchedulerEvent; const ARecurrencePattern: OleVariant;
AEntryIDs: TcxEventEntryIDList);
public
procedure SynchronizeWithOutlook(ADeleteUnsynchronizedEvents: Boolean = False);
procedure SynchronizeWithStorage(ADeleteUnsynchronizedAppointments: Boolean = False);
property EntryIDField: TcxCustomSchedulerStorageField
read FEntryIDField write FEntryIDField;
end;
procedure cxSchedulerExportToOutlook(AStorage: TcxCustomSchedulerStorage;
AcceptFunc: TcxAcceptEventExportFunc = nil;
AConvertProc: TcxEventToAppointmentItemProc = nil;
AProgressProc: TcxSchedulerExchangeProgressProc = nil);
procedure cxSchedulerImportFromOutlook(AStorage: TcxCustomSchedulerStorage;
AcceptFunc: TcxAcceptAppointmentItemImportFunc = nil;
AConvertProc: TcxAppointmentItemToEventProc = nil;
AProgressProc: TcxSchedulerExchangeProgressProc = nil);
procedure cxSchedulerSynchronizeOutlookWithStorage(AStorage: TcxCustomSchedulerStorage;
AppointmentItemIDField: TcxCustomSchedulerStorageField;
ADeleteUnsynchronizedAppointments: Boolean = False;
AcceptFunc: TcxAcceptEventExportFunc = nil;
AConvertProc: TcxEventToAppointmentItemProc = nil;
AProgressProc: TcxSchedulerExchangeProgressProc = nil);
procedure cxSchedulerSynchronizeStorageWithOutlook(AStorage: TcxCustomSchedulerStorage;
AppointmentItemIDField: TcxCustomSchedulerStorageField;
ADeleteUnsynchronizedEvents: Boolean = False;
AcceptFunc: TcxAcceptAppointmentItemImportFunc = nil;
AConvertProc: TcxAppointmentItemToEventProc = nil;
AProgressProc: TcxSchedulerExchangeProgressProc = nil);
implementation
uses
Windows, SysUtils, cxSchedulerUtils, cxVariants, Forms;
const
olFolderCalendar = $00000009;
olAppointmentItem = $00000001;
//recurrence
olRecursDaily = $00000000;
olRecursWeekly = $00000001;
olRecursMonthly = $00000002;
olRecursMonthNth = $00000003;
olRecursYearly = $00000005;
olRecursYearNth = $00000006;
// Constants for enum OlDaysOfWeek
olSunday = $00000001;
olMonday = $00000002;
olTuesday = $00000004;
olWednesday = $00000008;
olThursday = $00000010;
olFriday = $00000020;
olSaturday = $00000040;
olWeekDay = olMonday + olTuesday + olWednesday + olThursday + olFriday;
olWeekEndDay = olSunday + olSaturday;
olEveryDay = olWeekDay + olWeekEndDay;
// Constants for enum OlBusyStatus
olFree = $00000000;
olTentative = $00000001;
olBusy = $00000002;
olOutOfOffice = $00000003;
scxOutlookApp = 'outlook.application';
scxNameSpace = 'MAPI';
NullEntryID = '0000000000000000000000000000000000000000';
{ TcxAppointmentInfo }
constructor TcxAppointmentInfo.Create(const AAppointmentItem: OleVariant);
begin
FAppointmentItem := AAppointmentItem;
FEntryID := UpperCase(AAppointmentItem.EntryID);
end;
{ TcxAppointmentEntryIDList }
procedure TcxAppointmentEntryIDList.Add(const AppointmentItem: OleVariant);
begin
inherited Add(TcxAppointmentInfo.Create(AppointmentItem));
end;
function TcxAppointmentEntryIDList.ExtractAppointmentItem(
AIndex: Integer): OleVariant;
var
AppointmentInfo: TcxAppointmentInfo;
begin
AppointmentInfo := Items[AIndex];
Result := AppointmentInfo.AppointmentItem;
AppointmentInfo.Free;
Delete(AIndex);
end;
function TcxAppointmentEntryIDList.FindEntryID(const AEntryID: string; var Index: Integer): Boolean;
var
L, H, I, C: Integer;
begin
Result := False;
if Length(AEntryID) = 0 then Exit;
L := 0;
H := Count - 1;
while L <= H do
begin
I := (L + H) shr 1;
C := CompareStr(Items[I].EntryID, AEntryID);
if C < 0 then L := I + 1 else
begin
H := I - 1;
if C = 0 then
begin
Result := True;
L := I;
end;
end;
end;
Index := L;
end;
function TcxAppointmentEntryIDList.IndexOfEntryID(const AEntryID: string): Integer;
begin
if not FindEntryID(AEntryID, Result) then
Result := -1;
end;
function CompareAppointments(Item1, Item2: Pointer): Integer;
begin
Result := CompareStr(TcxAppointmentInfo(Item1).EntryID, TcxAppointmentInfo(Item2).EntryID);
end;
procedure TcxAppointmentEntryIDList.Populate(ACalendarFolder: OleVariant);
var
I: Integer;
begin
Capacity := ACalendarFolder.Items.Count;
for I := 1 to ACalendarFolder.Items.Count do
Add(ACalendarFolder.Items(I));
Sort(CompareAppointments);
end;
function TcxAppointmentEntryIDList.GetItems(Index: Integer): TcxAppointmentInfo;
begin
Result := TcxAppointmentInfo(List^[Index]);
end;
{ TcxEventInfo }
constructor TcxEventInfo.Create(AEvent: TcxSchedulerEvent; AEntryIDField: TcxCustomSchedulerStorageField);
begin
FEvent := AEvent;
if AEvent.EventType in [etNone, etPattern] then
FEntryID := Trim(VarToStr(AEvent.GetCustomFieldValue(AEntryIDField)))
else
FEntryID := NullEntryID;
end;
{ TcxEventEntryIDList }
procedure TcxEventEntryIDList.Add(AEvent: TcxSchedulerEvent;
AEntryIDField: TcxCustomSchedulerStorageField);
begin
inherited Add(TcxEventInfo.Create(AEvent, AEntryIDField));
end;
procedure TcxEventEntryIDList.DeleteEvent(AEvent: TcxSchedulerEvent);
var
I: Integer;
begin
for I := 0 to Count - 1 do
if Items[I].Event = AEvent then
begin
Items[I].Free;
Delete(I);
break;
end;
end;
function TcxEventEntryIDList.ExtractEvent(AIndex: Integer): TcxSchedulerEvent;
var
AEventInfo: TcxEventInfo;
begin
AEventInfo := Items[AIndex];
Result := AEventInfo.Event;
AEventInfo.Free;
Delete(AIndex);
end;
function TcxEventEntryIDList.FindEntryID(const AEntryID: string;
var Index: Integer): Boolean;
var
L, H, I, C: Integer;
begin
Result := False;
if Length(AEntryID) = 0 then Exit;
L := 0;
H := Count - 1;
while L <= H do
begin
I := (L + H) shr 1;
C := CompareStr(Items[I].EntryID, AEntryID);
if C < 0 then L := I + 1 else
begin
H := I - 1;
if C = 0 then
begin
Result := True;
L := I;
end;
end;
end;
Index := L;
end;
function TcxEventEntryIDList.IndexOfEntryID(
const AEntryID: string): Integer;
begin
if not FindEntryID(AEntryID, Result) then
Result := -1;
end;
function CompareEvents(Item1, Item2: Pointer): Integer;
begin
Result := CompareStr(TcxEventInfo(Item1).EntryID, TcxEventInfo(Item2).EntryID);
end;
procedure TcxEventEntryIDList.Populate(AStorage: TcxCustomSchedulerStorage;
AEntryIDField: TcxCustomSchedulerStorageField);
var
I: Integer;
begin
Capacity := AStorage.EventCount;
for I := 0 to AStorage.EventCount - 1 do
Add(AStorage.Events[I], AEntryIDField);
Sort(CompareEvents);
end;
function TcxEventEntryIDList.GetItems(Index: Integer): TcxEventInfo;
begin
Result := TcxEventInfo(List^[Index]);
end;
{ TcxOutlookExchange }
constructor TcxOutlookExchange.Create(AStorage: TcxCustomSchedulerStorage);
begin
inherited Create;
FStorage := AStorage;
FOleInitialized := InitOleObject;
end;
destructor TcxOutlookExchange.Destroy;
begin
if FWasCreated then
FOutlookApp := Unassigned;
inherited Destroy;
end;
procedure TcxOutlookExchange.ExportEventToOutlook(AEvent: TcxSchedulerEvent);
var
AppointmentItem: OleVariant;
begin
if AEvent.EventType in [etNone, etPattern] then
begin
AppointmentItem := OutlookApp.CreateItem(olAppointmentItem);
SetupAppointmentItemInfo(AppointmentItem, AEvent);
if AEvent.IsRecurring then
ExportRecurrenceChain(AEvent, AppointmentItem)
else
UpdateAppointmentItem(AppointmentItem, AEvent);
end;
end;
procedure TcxOutlookExchange.ExportToOutlook;
var
AEvent: TcxSchedulerEvent;
I, ACount: Integer;
begin
if not IsValid then Exit;
Storage.BeginUpdate;
try
ACount := Storage.EventCount;
for I := 0 to ACount - 1 do
begin
AEvent := Storage.Events[I];
if CanAcceptEvent(AEvent) then
ExportEventToOutlook(AEvent);
if not DoProgress(I + 1, ACount) then
Break;
Application.ProcessMessages;
end;
finally
Storage.EndUpdate;
end;
end;
procedure TcxOutlookExchange.ImportAppointmentItemFromOutlook(
const AppointmentItem: OleVariant);
var
AEvent: TcxSchedulerEvent;
ARecurrencePattern: OleVariant;
begin
AEvent := Storage.CreateEvent;
SetupEventInfo(AEvent, AppointmentItem);
if AppointmentItem.IsRecurring then
begin
ARecurrencePattern := AppointmentItem.GetRecurrencePattern;
UpdateEventWithRecurrenceInfo(AEvent, AppointmentItem);
ImportRecurrenceChain(AEvent, ARecurrencePattern);
end
else
UpdateEvent(AEvent, AppointmentItem);
end;
procedure TcxOutlookExchange.ImportFromOutlook;
var
I, ACount: Integer;
AppointmentItem: OleVariant;
begin
if not IsValid then Exit;
ACount := CalendarFolder.Items.Count;
for I := 1 to ACount do
begin
AppointmentItem := CalendarFolder.Items(I);
if CanImportAppointmentItem(AppointmentItem) and CanAcceptAppointmentItem(AppointmentItem) then
ImportAppointmentItemFromOutlook(AppointmentItem);
if not DoProgress(I, ACount) then
Break;
Application.ProcessMessages;
end;
end;
function TcxOutlookExchange.CanAcceptAppointmentItem(
const AppointmentItem: OleVariant): Boolean;
begin
Result := not Assigned(FOnAcceptAppointmentItem) or
FOnAcceptAppointmentItem(AppointmentItem);
end;
function TcxOutlookExchange.CanAcceptEvent(AEvent: TcxSchedulerEvent): Boolean;
begin
Result := not Assigned(FOnAcceptEvent) or FOnAcceptEvent(AEvent);
end;
function TcxOutlookExchange.CanImportAppointmentItem(
const AppointmentItem: OleVariant): Boolean;
begin
Result := not (AppointmentItem.IsRecurring and not Storage.IsRecurrenceAvailable);
end;
procedure TcxOutlookExchange.ConvertAppointmentItemToEvent(
const AppointmentItem: OleVariant; AEvent: TcxSchedulerEvent);
begin
if Assigned(FOnConvertAppointmentItemToEvent) then
FOnConvertAppointmentItemToEvent(AppointmentItem, AEvent);
end;
procedure TcxOutlookExchange.ConvertEventToAppointmentItem(
AEvent: TcxSchedulerEvent; const AppointmentItem: OleVariant);
begin
if Assigned(FOnConvertEventToAppointmentItem) then
FOnConvertEventToAppointmentItem(AEvent, AppointmentItem);
end;
procedure TcxOutlookExchange.ImportRecurrenceChain(
APatternEvent: TcxSchedulerEvent; const ARecurrencePattern: OleVariant);
const
ExceptionType: array[Boolean] of TcxEventType = (etCustom, etException);
var
I: Integer;
AException: OleVariant;
ADeleted: Boolean;
AOccurrence: TcxSchedulerEvent;
begin
for I := 1 to ARecurrencePattern.Exceptions.Count do
begin
AException := ARecurrencePattern.Exceptions.Item(I);
ADeleted := AException.Deleted;
if not ADeleted and not CanAcceptAppointmentItem(AException.AppointmentItem) then
continue;
AOccurrence := Storage.CreateOccurrence(APatternEvent,
AException.OriginalDate, ExceptionType[ADeleted]);
if not ADeleted then
begin
SetupEventInfo(AOccurrence, AException.AppointmentItem);
UpdateEvent(AOccurrence, AException.AppointmentItem);
end
else
PostRecurrenceExeption(AOccurrence);
end;
end;
procedure TcxOutlookExchange.SetupEventRecurrenceInfo(AEvent: TcxSchedulerEvent;
const ARecurrencePattern: OleVariant);
var
AType, AInterval: Integer;
ADate: TDateTime;
begin
AEvent.EventType := etPattern;
ADate := ARecurrencePattern.PatternStartDate;
if not AEvent.AllDayEvent then
ADate := ADate + RoundTime(ARecurrencePattern.StartTime, False);
AEvent.RecurrenceInfo.Start := ADate;
if ARecurrencePattern.NoEndDate then
AEvent.RecurrenceInfo.Count := -1
else
begin
ADate := ARecurrencePattern.PatternEndDate;
if not AEvent.AllDayEvent then
ADate := ADate + RoundTime(ARecurrencePattern.EndTime, False);
AEvent.RecurrenceInfo.Finish := ADate;
AEvent.RecurrenceInfo.Count := ARecurrencePattern.Occurrences;
end;
AType := ARecurrencePattern.RecurrenceType;
case AType of
olRecursDaily:
begin
AEvent.RecurrenceInfo.Recurrence := cxreDaily;
AEvent.RecurrenceInfo.DayType := cxdtEveryDay;
AEvent.RecurrenceInfo.Periodicity := ARecurrencePattern.Interval;
end;
olRecursWeekly:
begin
AInterval := ARecurrencePattern.Interval;
if AInterval = 0 then
begin
AEvent.RecurrenceInfo.Recurrence := cxreDaily;
AEvent.RecurrenceInfo.DayType := cxdtWeekDay;
end
else
begin
AEvent.RecurrenceInfo.Recurrence := cxreWeekly;
AEvent.RecurrenceInfo.Periodicity := AInterval;
end;
AEvent.RecurrenceInfo.OccurDays :=
GetDaysOfWeekFromMask(ARecurrencePattern.DayOfWeekMask);
end;
olRecursMonthly:
begin
AEvent.RecurrenceInfo.DayType := cxdtDay;
AEvent.RecurrenceInfo.Recurrence := cxreMonthly;
AEvent.RecurrenceInfo.Periodicity := ARecurrencePattern.Interval;
AEvent.RecurrenceInfo.DayNumber := ARecurrencePattern.DayOfMonth
end;
olRecursMonthNth:
begin
AEvent.RecurrenceInfo.DayType := GetDayTypeFromMask(ARecurrencePattern.DayOfWeekMask);
AEvent.RecurrenceInfo.Recurrence := cxreMonthly;
AEvent.RecurrenceInfo.Periodicity := ARecurrencePattern.Interval;
AEvent.RecurrenceInfo.DayNumber := ARecurrencePattern.Instance;
end;
olRecursYearly:
begin
AEvent.RecurrenceInfo.DayType := cxdtDay;
AEvent.RecurrenceInfo.Recurrence := cxreYearly;
AEvent.RecurrenceInfo.Periodicity := ARecurrencePattern.MonthOfYear;
AEvent.RecurrenceInfo.DayNumber := ARecurrencePattern.DayOfMonth
end;
olRecursYearNth:
begin
AEvent.RecurrenceInfo.DayType := GetDayTypeFromMask(ARecurrencePattern.DayOfWeekMask);
AEvent.RecurrenceInfo.Recurrence := cxreYearly;
AEvent.RecurrenceInfo.Periodicity := ARecurrencePattern.MonthOfYear;
AEvent.RecurrenceInfo.DayNumber := ARecurrencePattern.Instance;
end;
end;
end;
function TcxOutlookExchange.GetIsValid: Boolean;
begin
Result := (FStorage <> nil) and FOleInitialized;
end;
{$HINTS OFF}
function TcxOutlookExchange.InitOleObject: Boolean;
var
ANameSpace: OleVariant;
begin
Result := False;
FWasCreated := False;
try
FOutlookApp := GetActiveOleObject(scxOutlookApp);
Result := True;
except
FOutlookApp := CreateOleObject(scxOutlookApp);
FWasCreated := True;
Result := True;
end;
if Result then
begin
ANameSpace := OutlookApp.GetNamespace(scxNameSpace);
FCalendarFolder := ANameSpace.GetDefaultFolder(olFolderCalendar);
end;
end;
{$HINTS ON}
procedure TcxOutlookExchange.PostRecurrenceExeption(
AOccurrence: TcxSchedulerEvent);
begin
AOccurrence.Post;
end;
function TcxOutlookExchange.RoundTime(ATime: TDateTime; ASaveDate: Boolean): TDateTime;
begin
if ASaveDate then
Result := DateTimeHelper.RoundTime(ATime)
else
Result := DateTimeHelper.RoundTime(TimeOf(ATime));
end;
procedure TcxOutlookExchange.UpdateAppointmentItem(
const AppointmentItem: OleVariant; AEvent: TcxSchedulerEvent);
begin
ConvertEventToAppointmentItem(AEvent, AppointmentItem);
try
AppointmentItem.Save;
except
end;
end;
procedure TcxOutlookExchange.UpdateEvent(AEvent: TcxSchedulerEvent;
const AppointmentItem: OleVariant; APostData: Boolean = True);
begin
ConvertAppointmentItemToEvent(AppointmentItem, AEvent);
if APostData then AEvent.Post;
end;
procedure TcxOutlookExchange.UpdateEventWithRecurrenceInfo(AEvent: TcxSchedulerEvent;
const AppointmentItem: OleVariant);
begin
AEvent.BeginEditing;
try
SetupEventRecurrenceInfo(AEvent, AppointmentItem.GetRecurrencePattern);
UpdateEvent(AEvent, AppointmentItem, False);
finally
AEvent.EndEditing;
end;
AEvent.Post;
end;
function TcxOutlookExchange.DoProgress(ACurrent, ACount: Integer): Boolean;
var
Abort: Boolean;
begin
Abort := False;
if Assigned(FOnProgress) then
FOnProgress(ACurrent, ACount, Abort);
Result := not Abort;
end;
procedure TcxOutlookExchange.CheckRecurrencePatternExceptions(
const ARecurrencePattern: OleVariant;
APatternEvent: TcxSchedulerEvent);
var
I: Integer;
AEvent: TcxSchedulerEvent;
AppointmentItem: OleVariant;
begin
with APatternEvent.GetRecurrenceChain do
try
for I := 0 to Count - 1 do
begin
AEvent := Items[I];
try
AppointmentItem := ARecurrencePattern.GetOccurrence(AEvent.GetOriginalDate);
if AEvent.EventType = etException then
AppointmentItem.Delete
else
if (AEvent.EventType = etCustom) and CanAcceptEvent(AEvent) then
begin
SetupAppointmentItemInfo(AppointmentItem, AEvent);
UpdateAppointmentItem(AppointmentItem, AEvent);
end;
except
end;
end;
finally
Free;
end;
end;
procedure TcxOutlookExchange.ExportRecurrenceChain(
APatternEvent: TcxSchedulerEvent; const AppointmentItem: OleVariant);
var
ARecurrencePattern: OleVariant;
begin
if APatternEvent.EventType = etPattern then
begin
ARecurrencePattern := AppointmentItem.GetRecurrencePattern;
SetAppointmentItemRecurrence(ARecurrencePattern, APatternEvent);
UpdateAppointmentItem(AppointmentItem, APatternEvent);
CheckRecurrencePatternExceptions(ARecurrencePattern, APatternEvent);
end;
end;
procedure TcxOutlookExchange.SetAppointmentItemRecurrence(
const ARecurrencePattern: OleVariant; AEvent: TcxSchedulerEvent);
begin
with AEvent.RecurrenceInfo do
begin
ARecurrencePattern.PatternStartDate := DateOf(AEvent.Start);
ARecurrencePattern.StartTime := RoundTime(AEvent.Start, False);
ARecurrencePattern.EndTime := RoundTime(AEvent.Finish, False);
case Recurrence of
cxreDaily:
begin
if DayType = cxdtEveryDay then
begin
ARecurrencePattern.RecurrenceType := olRecursDaily;
ARecurrencePattern.Interval := Periodicity;
end
else
if DayType = cxdtWeekDay then
begin
ARecurrencePattern.RecurrenceType := olRecursWeekly;
ARecurrencePattern.DayOfWeekMask := olWeekDay;
end;
end;
cxreWeekly:
begin
ARecurrencePattern.RecurrenceType := olRecursWeekly;
ARecurrencePattern.DayOfWeekMask := GetMaskFromDaysOfWeek(OccurDays);
ARecurrencePattern.Interval := Periodicity;
end;
cxreMonthly:
begin
if DayType = cxdtDay then
begin
ARecurrencePattern.RecurrenceType := olRecursMonthly;
ARecurrencePattern.DayOfMonth := DayNumber;
ARecurrencePattern.Interval := Periodicity;
end
else
begin
ARecurrencePattern.RecurrenceType := olRecursMonthNth;
ARecurrencePattern.Interval := Periodicity;
ARecurrencePattern.DayOfWeekMask := GetMaskFromDayType(DayType);
ARecurrencePattern.Instance := DayNumber;
end;
end;
cxreYearly:
begin
if DayType = cxdtDay then
begin
ARecurrencePattern.RecurrenceType := olRecursYearly;
ARecurrencePattern.DayOfMonth := DayNumber;
ARecurrencePattern.MonthOfYear := Periodicity;
end
else
begin
ARecurrencePattern.RecurrenceType := olRecursYearNth;
ARecurrencePattern.MonthOfYear := Periodicity;
ARecurrencePattern.DayOfWeekMask := GetMaskFromDayType(DayType);
ARecurrencePattern.Instance := DayNumber;
end;
end;
end;
if Count = -1 then
ARecurrencePattern.NoEndDate := True
else
if Count = 0 then
ARecurrencePattern.PatternEndDate := Finish
else
ARecurrencePattern.Occurrences := Count;
end;
end;
function TcxOutlookExchange.GetAllDayEvent(const AppointmentItem: OleVariant): Boolean;
var
ARecurrencePattern: OleVariant;
begin
Result := AppointmentItem.AllDayEvent;
if Result then
begin
if AppointmentItem.IsRecurring then
begin
ARecurrencePattern := AppointmentItem.GetRecurrencePattern;
if Integer(ARecurrencePattern.RecurrenceType) in
[olRecursMonthly, olRecursMonthNth, olRecursYearly, olRecursYearNth] then
begin
Result := (RoundTime(ARecurrencePattern.StartTime, False) = 0) and
(RoundTime(ARecurrencePattern.EndTime, False) = 0);
end;
end;
end;
end;
function TcxOutlookExchange.GetDaysOfWeekFromMask(AMask: Integer): TDays;
var
I: Integer;
begin
Result := [];
for I := 0 to 6 do
if (1 shl I) and AMask <> 0 then
Include(Result, TDay(I));
end;
function TcxOutlookExchange.GetDayTypeFromMask(AMask: Integer): TcxDayType;
begin
case AMask of
olSunday : Result := cxdtSunday;
olMonday : Result := cxdtMonday;
olTuesday : Result := cxdtTuesday;
olWednesday : Result := cxdtWednesday;
olThursday: Result := cxdtThursday;
olFriday: Result := cxdtFriday;
olSaturday: Result := cxdtSaturday;
olWeekDay : Result := cxdtWeekDay;
olWeekEndDay: Result := cxdtWeekEndDay;
else
Result := cxdtEveryDay;
end;
end;
function TcxOutlookExchange.GetMaskFromDaysOfWeek(ADays: TDays): Integer;
var
I: TDay;
begin
Result := 0;
for I := dSunday to dSaturday do
if I in ADays then
Result := Result or (1 shl Ord(I));
end;
function TcxOutlookExchange.GetMaskFromDayType(ADayType: TcxDayType): Integer;
const
Masks: array[TcxDayType] of Byte = (olEveryDay, olEveryDay, olWeekDay,
olWeekEndDay, olSunday, olMonday, olTuesday, olWednesday, olThursday,
olFriday, olSaturday);
begin
Result := Masks[ADayType];
end;
{ TcxOutlookSynchronize }
procedure TcxOutlookSynchronize.SynchronizeWithOutlook(
ADeleteUnsynchronizedEvents: Boolean = False);
var
I, AIndex, ACount: Integer;
AppointmentItem: OleVariant;
AEvent: TcxSchedulerEvent;
AEntryIDs: TcxEventEntryIDList;
begin
if not IsValid then Exit;
AEntryIDs := TcxEventEntryIDList.Create;
try
AEntryIDs.Populate(Storage, EntryIDField);
ACount := CalendarFolder.Items.Count;
for I := 1 to ACount do
begin
AppointmentItem := CalendarFolder.Items(I);
if CanImportAppointmentItem(AppointmentItem) and CanAcceptAppointmentItem(AppointmentItem) then
begin
if AEntryIDs.FindEntryID(AppointmentItem.EntryID, AIndex) then
begin
AEvent := AEntryIDs.ExtractEvent(AIndex);
UpdateExistingEvent(AEvent, AppointmentItem, AEntryIDs);
end
else
ImportAppointmentItemFromOutlook(AppointmentItem);
end;
if not DoProgress(I, ACount) then
Exit;
Application.ProcessMessages;
end;
if ADeleteUnsynchronizedEvents then
DeleteUnsynchronizedEvents(AEntryIDs);
finally
AEntryIDs.Free;
end;
end;
procedure TcxOutlookSynchronize.SynchronizeWithStorage(
ADeleteUnsynchronizedAppointments: Boolean = False);
var
AppointmentItem: OleVariant;
AEntryIDs: TcxAppointmentEntryIDList;
AEvent: TcxSchedulerEvent;
I, AIndex, ACount: Integer;
begin
if not IsValid then Exit;
AEntryIDs := TcxAppointmentEntryIDList.Create;
try
AEntryIDs.Populate(CalendarFolder);
Storage.BeginUpdate;
try
ACount := Storage.EventCount;
for I := 0 to ACount - 1 do
begin
AEvent := Storage.Events[I];
if CanAcceptEvent(AEvent) then
begin
if AEntryIDs.FindEntryID(GetEntryIDFromEvent(AEvent), AIndex) then
begin
AppointmentItem := AEntryIDs.ExtractAppointmentItem(AIndex);
UpdateExistingAppointmentItem(AppointmentItem, AEvent);
end
else
ExportEventToOutlook(AEvent);
end;
if not DoProgress(I + 1, ACount) then
Exit;
Application.ProcessMessages;
end;
if ADeleteUnsynchronizedAppointments then
DeleteUnsynchronizedAppointments(AEntryIDs);
finally
Storage.EndUpdate;
end;
finally
AEntryIDs.Free;
end;
end;
procedure TcxOutlookSynchronize.UpdateAppointmentItem(
const AppointmentItem: OleVariant; AEvent: TcxSchedulerEvent);
var
AEntryID: OleVariant;
begin
ConvertEventToAppointmentItem(AEvent, AppointmentItem);
try
AppointmentItem.Save;
AEntryID := AppointmentItem.EntryID;
if not VarEqualsSoft(AEvent.GetCustomFieldValue(EntryIDField), AEntryID) then
begin
AEvent.SetCustomFieldValue(EntryIDField, AEntryID);
AEvent.Post;
end;
except
end;
end;
procedure TcxOutlookSynchronize.UpdateExistingAppointmentItem(
const AppointmentItem: OleVariant; AEvent: TcxSchedulerEvent);
begin
if AppointmentItem.IsRecurring then
AppointmentItem.ClearRecurrencePattern;
SetupAppointmentItemInfo(AppointmentItem, AEvent);
if AEvent.IsRecurring then
ExportRecurrenceChain(AEvent, AppointmentItem)
else
UpdateAppointmentItem(AppointmentItem, AEvent);
end;
procedure TcxOutlookSynchronize.SynchronizeRecurrenceChainWithOutlook(
APatternEvent: TcxSchedulerEvent;
const ARecurrencePattern: OleVariant;
AEntryIDs: TcxEventEntryIDList);
var
I, J: Integer;
AppointmentItem: OleVariant;
AException: OleVariant;
AOccurrence: TcxSchedulerEvent;
AOriginalDate: TDateTime;
ARecurrenceChain: TcxSchedulerEventList;
begin
PurgeDeletedOccurrences(APatternEvent, AEntryIDs);
ARecurrenceChain := APatternEvent.GetRecurrenceChain;
try
for I := 1 to ARecurrencePattern.Exceptions.Count do
begin
AException := ARecurrencePattern.Exceptions.Item(I);
AOriginalDate := DateOf(AException.OriginalDate);
AOccurrence := nil;
for J := 0 to ARecurrenceChain.Count - 1 do
begin
if DateOf(ARecurrenceChain[J].GetOriginalDate) = AOriginalDate then
begin
AOccurrence := ARecurrenceChain[J];
AEntryIDs.DeleteEvent(AOccurrence);
ARecurrenceChain.Delete(J);
break;
end;
end;
if not AException.Deleted then
begin
AppointmentItem := AException.AppointmentItem;
if not CanAcceptAppointmentItem(AppointmentItem) then
continue;
if AOccurrence = nil then
AOccurrence := Storage.CreateOccurrence(APatternEvent, AOriginalDate, etCustom);
SetupEventInfo(AOccurrence, AppointmentItem);
ConvertAppointmentItemToEvent(AppointmentItem, AOccurrence);
AOccurrence.Post;
end
else
begin
if AOccurrence = nil then
AOccurrence := APatternEvent.GetOccurrence(AOriginalDate);
if AOccurrence <> nil then
begin
AOccurrence.EventType := etException;
PostRecurrenceExeption(AOccurrence);
end;
end;
end;
for I := 0 to ARecurrenceChain.Count - 1 do
begin
AOccurrence := ARecurrenceChain[I];
AEntryIDs.DeleteEvent(AOccurrence);
AOccurrence.EventType := etNone;
AOccurrence.Delete;
end;
finally
ARecurrenceChain.Free;
end;
end;
procedure TcxOutlookSynchronize.UpdateExistingEvent(AEvent: TcxSchedulerEvent;
const AppointmentItem: OleVariant; AEntryIDs: TcxEventEntryIDList);
var
ARecurrencePattern: OleVariant;
begin
SetupEventInfo(AEvent, AppointmentItem);
if AppointmentItem.IsRecurring then
begin
ARecurrencePattern := AppointmentItem.GetRecurrencePattern;
if AEvent.IsRecurring then
begin
if not IsEqualRecurrencePattern(AppointmentItem, AEvent) then
AEvent.DeleteExceptions;
UpdateEventWithRecurrenceInfo(AEvent, AppointmentItem);
SynchronizeRecurrenceChainWithOutlook(AEvent, ARecurrencePattern, AEntryIDs);
end
else
begin
UpdateEventWithRecurrenceInfo(AEvent, AppointmentItem);
ImportRecurrenceChain(AEvent, AppointmentItem.GetRecurrencePattern);
end;
end
else
begin
AEvent.RemoveRecurrence;
UpdateEvent(AEvent, AppointmentItem);
end;
end;
procedure TcxOutlookSynchronize.UpdateEvent(AEvent: TcxSchedulerEvent;
const AppointmentItem: OleVariant; APostData: Boolean = True);
var
AEntryID: string;
begin
if AEvent.EventType in [etPattern, etNone] then
AEntryID := AppointmentItem.EntryID
else
AEntryID := NullEntryID;
AEvent.SetCustomFieldValue(EntryIDField, AEntryID);
inherited UpdateEvent(AEvent, AppointmentItem, APostData);
end;
procedure TcxOutlookSynchronize.DeleteUnsynchronizedAppointments(
AEntryIDs: TcxAppointmentEntryIDList);
var
I: Integer;
begin
for I := 0 to AEntryIDs.Count - 1 do
try
AEntryIDs[I].AppointmentItem.Delete;
except
end;
end;
procedure TcxOutlookSynchronize.DeleteUnsynchronizedEvents(
AEntryIDs: TcxEventEntryIDList);
var
I: Integer;
AEvent: TcxSchedulerEvent;
begin
Storage.BeginUpdate;
try
for I := 0 to AEntryIDs.Count - 1 do
begin
AEvent := AEntryIDs[I].Event;
AEvent.EventType := etNone;
AEvent.Delete;
end;
finally
Storage.EndUpdate;
end;
end;
function TcxOutlookSynchronize.GetEntryIDFromEvent(
AEvent: TcxSchedulerEvent): string;
begin
Result := UpperCase(VarToStr(AEvent.GetCustomFieldValue(EntryIDField)))
end;
function TcxOutlookSynchronize.GetIsValid: Boolean;
begin
Result := inherited GetIsValid and (FEntryIDField <> nil)
end;
procedure TcxOutlookSynchronize.PostRecurrenceExeption(
AOccurrence: TcxSchedulerEvent);
begin
AOccurrence.SetCustomFieldValue(EntryIDField, NullEntryID);
AOccurrence.Post;
end;
procedure TcxOutlookSynchronize.PurgeDeletedOccurrences(
APatternEvent: TcxSchedulerEvent; AEntryIDs: TcxEventEntryIDList);
var
AEvent: TcxSchedulerEvent;
L: TcxSchedulerEventList;
I: Integer;
begin
Storage.BeginUpdate;
try
L := APatternEvent.GetRecurrenceChain;
try
for I := 0 to L.Count - 1 do
begin
AEvent := L[I];
if AEvent.EventType = etException then
begin
AEntryIDs.DeleteEvent(AEvent);
AEvent.Delete;
end;
end;
finally
L.Free;
end;
finally
Storage.EndUpdate;
end;
end;
function TcxOutlookSynchronize.IsEqualRecurrencePattern(
const AppointmentItem: OleVariant; AEvent: TcxSchedulerEvent): Boolean;
var
ARecurrencePattern: OleVariant;
begin
with AEvent do
begin
Result := (AllDayEvent = GetAllDayEvent(AppointmentItem)) and
(RoundTime(Start, True) = RoundTime(AppointmentItem.Start, True)) and
(RoundTime(Finish, True) = RoundTime(AppointmentItem.End, True));
end;
if Result then
begin
ARecurrencePattern := AppointmentItem.GetRecurrencePattern;
with AEvent.RecurrenceInfo do
begin
Result := (ARecurrencePattern.PatternStartDate = DateOf(AEvent.Start)) and
(RoundTime(ARecurrencePattern.StartTime, False) = RoundTime(AEvent.Start, False)) and
(RoundTime(ARecurrencePattern.EndTime, False) = RoundTime(AEvent.Finish, False));
if not Result then Exit;
case Recurrence of
cxreDaily:
if DayType = cxdtEveryDay then
Result := (ARecurrencePattern.RecurrenceType = olRecursDaily) and
(ARecurrencePattern.Interval = Periodicity)
else
if DayType = cxdtWeekDay then
Result := (ARecurrencePattern.RecurrenceType = olRecursWeekly) and
(ARecurrencePattern.DayOfWeekMask = olWeekDay)
else
Result := False; //unknown status
cxreWeekly:
Result := (ARecurrencePattern.RecurrenceType = olRecursWeekly) and
(ARecurrencePattern.DayOfWeekMask = GetMaskFromDaysOfWeek(OccurDays)) and
(ARecurrencePattern.Interval = Periodicity);
cxreMonthly:
if DayType = cxdtDay then
Result := (ARecurrencePattern.RecurrenceType = olRecursMonthly) and
(ARecurrencePattern.DayOfMonth = DayNumber) and
(ARecurrencePattern.Interval = Periodicity)
else
Result := (ARecurrencePattern.RecurrenceType = olRecursMonthNth) and
(ARecurrencePattern.Interval = Periodicity) and
(ARecurrencePattern.DayOfWeekMask = GetMaskFromDayType(DayType)) and
(ARecurrencePattern.Instance = DayNumber);
cxreYearly:
if DayType = cxdtDay then
Result := (ARecurrencePattern.RecurrenceType = olRecursYearly) and
(ARecurrencePattern.DayOfMonth = DayNumber) and
(ARecurrencePattern.MonthOfYear = Periodicity)
else
Result := (ARecurrencePattern.RecurrenceType = olRecursYearNth) and
(ARecurrencePattern.MonthOfYear = Periodicity) and
(ARecurrencePattern.DayOfWeekMask = GetMaskFromDayType(DayType)) and
(ARecurrencePattern.Instance = DayNumber);
end;
if Result then
begin
if Count = -1 then
Result := ARecurrencePattern.NoEndDate
else
if Count = 0 then
Result := (ARecurrencePattern.PatternEndDate = DateOf(Finish))
else
Result := (ARecurrencePattern.Occurrences = Count);
end;
end;
end;
end;
//moved to the end because a bug in the delphi parser
procedure TcxOutlookExchange.SetupAppointmentItemInfo(const AppointmentItem: OleVariant;
const AEvent: TcxSchedulerEvent; ASetTime: Boolean = True);
var
AControlEvent: TcxSchedulerControlEvent;
begin
AControlEvent := TcxSchedulerControlEvent.Create(AEvent);
try
with AControlEvent do
begin
if AEvent.EventType = etCustom then
Pattern := AEvent.Pattern
else
Pattern := nil;
if ASetTime then
begin
AppointmentItem.AllDayEvent := AllDayEvent;
AppointmentItem.Start := Start;
AppointmentItem.End := Finish;
end;
AppointmentItem.Subject := Caption;
AppointmentItem.Body := Message;
AppointmentItem.BusyStatus := State;
AppointmentItem.Location := Location;
AppointmentItem.ReminderSet := Reminder;
if Reminder then
AppointmentItem.ReminderMinutesBeforeStart := ReminderMinutesBeforeStart;
end;
finally
AControlEvent.Free;
end;
end;
procedure TcxOutlookExchange.SetupEventInfo(AEvent: TcxSchedulerEvent;
const AppointmentItem: OleVariant);
begin
with AEvent do
begin
BeginEditing;
try
AllDayEvent := GetAllDayEvent(AppointmentItem);
Start := AppointmentItem.Start;
Finish := AppointmentItem.End;
Caption := AppointmentItem.Subject;
Message := AppointmentItem.Body;
State := AppointmentItem.BusyStatus;
Location := AppointmentItem.Location;
Reminder := AppointmentItem.ReminderSet;
if Reminder then
ReminderMinutesBeforeStart := AppointmentItem.ReminderMinutesBeforeStart;
finally
EndEditing;
end;
end;
end;
// import/export/synchronization
procedure cxSchedulerExportToOutlook(AStorage: TcxCustomSchedulerStorage;
AcceptFunc: TcxAcceptEventExportFunc = nil;
AConvertProc: TcxEventToAppointmentItemProc = nil;
AProgressProc: TcxSchedulerExchangeProgressProc = nil);
begin
with TcxOutlookExchange.Create(AStorage) do
try
OnAcceptEvent := AcceptFunc;
OnConvertEventToAppointmentItem := AConvertProc;
OnProgress := AProgressProc;
ExportToOutlook;
finally
Free;
end;
end;
procedure cxSchedulerImportFromOutlook(AStorage: TcxCustomSchedulerStorage;
AcceptFunc: TcxAcceptAppointmentItemImportFunc = nil;
AConvertProc: TcxAppointmentItemToEventProc = nil;
AProgressProc: TcxSchedulerExchangeProgressProc = nil);
begin
with TcxOutlookExchange.Create(AStorage) do
try
OnAcceptAppointmentItem := AcceptFunc;
OnConvertAppointmentItemToEvent := AConvertProc;
OnProgress := AProgressProc;
ImportFromOutlook;
finally
Free;
end;
end;
procedure cxSchedulerSynchronizeOutlookWithStorage(AStorage: TcxCustomSchedulerStorage;
AppointmentItemIDField: TcxCustomSchedulerStorageField;
ADeleteUnsynchronizedAppointments: Boolean = False;
AcceptFunc: TcxAcceptEventExportFunc = nil;
AConvertProc: TcxEventToAppointmentItemProc = nil;
AProgressProc: TcxSchedulerExchangeProgressProc = nil);
begin
with TcxOutlookSynchronize.Create(AStorage) do
try
EntryIDField := AppointmentItemIDField;
OnAcceptEvent := AcceptFunc;
OnConvertEventToAppointmentItem := AConvertProc;
OnProgress := AProgressProc;
SynchronizeWithStorage(ADeleteUnsynchronizedAppointments);
finally
Free;
end;
end;
procedure cxSchedulerSynchronizeStorageWithOutlook(AStorage: TcxCustomSchedulerStorage;
AppointmentItemIDField: TcxCustomSchedulerStorageField;
ADeleteUnsynchronizedEvents: Boolean = False;
AcceptFunc: TcxAcceptAppointmentItemImportFunc = nil;
AConvertProc: TcxAppointmentItemToEventProc = nil;
AProgressProc: TcxSchedulerExchangeProgressProc = nil);
begin
with TcxOutlookSynchronize.Create(AStorage) do
try
EntryIDField := AppointmentItemIDField;
OnAcceptAppointmentItem := AcceptFunc;
OnConvertAppointmentItemToEvent := AConvertProc;
OnProgress := AProgressProc;
SynchronizeWithOutlook(ADeleteUnsynchronizedEvents);
finally
Free;
end;
end;
end.