2008-02-03 12:05:55 +00:00
|
|
|
{*********************************************************}
|
|
|
|
{* VPDATA.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 ***** *}
|
|
|
|
|
2018-06-15 23:40:18 +00:00
|
|
|
{$MODE ObjFPC}{$H+}
|
|
|
|
|
|
|
|
//{$I vp.inc}
|
2008-02-03 12:05:55 +00:00
|
|
|
|
|
|
|
unit VpData;
|
|
|
|
{ Data classes for Visual PlanIt's resources, events, tasks, contacts, etc... }
|
|
|
|
|
|
|
|
interface
|
|
|
|
|
|
|
|
uses
|
2016-06-22 07:59:17 +00:00
|
|
|
LCLProc, LCLType,
|
2022-08-10 10:20:56 +00:00
|
|
|
SysUtils, Classes, Dialogs, Graphics, Forms,
|
2018-06-15 23:40:18 +00:00
|
|
|
VpSR, VpVCard, VpICal;
|
2008-02-03 12:05:55 +00:00
|
|
|
|
|
|
|
type
|
|
|
|
TVpEventRec = packed record
|
2016-09-10 14:19:31 +00:00
|
|
|
Rec: TRect;
|
|
|
|
IconRect: TRect;
|
|
|
|
Event: Pointer;
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
type
|
|
|
|
TVpEventArray = array of TVpEventRec;
|
|
|
|
|
|
|
|
TVpAlarmAdvType = (atMinutes, atHours, atDays);
|
|
|
|
|
2009-12-24 22:41:52 +00:00
|
|
|
TVpRepeatType = (rtNone=0, rtDaily, rtWeekly, rtMonthlyByDay, rtMonthlyByDate,
|
2008-02-03 12:05:55 +00:00
|
|
|
rtYearlyByDay, rtYearlyByDate, rtCustom);
|
|
|
|
|
|
|
|
TVpContactSort = (csLastFirst, csFirstLast);
|
|
|
|
|
2016-09-17 15:14:53 +00:00
|
|
|
TVpTaskPriority = (tpLow=-1, tpNormal=0, tpHigh=1);
|
|
|
|
|
2016-09-11 13:35:19 +00:00
|
|
|
TVpOverlayPattern = (opSolid, opClear, opHorizontal, opVertical,
|
|
|
|
opFDiagonal, opBDiagonal, opCross, opDiagCross);
|
|
|
|
|
|
|
|
TVpOverlayDetail = (odResource, odEventDescription, odEventCategory);
|
|
|
|
TVpOverlayDetails = set of TVpOverlayDetail;
|
|
|
|
|
2008-02-03 12:05:55 +00:00
|
|
|
{ forward declarations }
|
|
|
|
TVpResource = class;
|
2016-09-10 14:19:31 +00:00
|
|
|
TVpResourceGroup = class;
|
2021-12-04 19:01:07 +00:00
|
|
|
TVpResourceArray = array of TVpResource;
|
2016-09-10 14:19:31 +00:00
|
|
|
TVpTasks = class;
|
2008-02-03 12:05:55 +00:00
|
|
|
TVpSchedule = class;
|
2016-09-10 14:19:31 +00:00
|
|
|
TVpEvent = class;
|
2008-02-03 12:05:55 +00:00
|
|
|
TVpContacts = class;
|
2016-09-10 14:19:31 +00:00
|
|
|
TVpContact = class;
|
|
|
|
TVpTask = class;
|
2008-02-03 12:05:55 +00:00
|
|
|
|
2022-08-05 20:12:52 +00:00
|
|
|
TVpEventArr = array of TVpEvent;
|
|
|
|
TVpTaskArr = array of TVpTask;
|
2022-08-11 20:32:13 +00:00
|
|
|
TVpContactArr = array of TVpContact;
|
2022-08-05 18:48:09 +00:00
|
|
|
|
2008-02-03 12:05:55 +00:00
|
|
|
TVpResources = class
|
2016-09-06 19:59:25 +00:00
|
|
|
private
|
2018-06-16 23:07:26 +00:00
|
|
|
FOwner: TObject; // This is the Datastore.
|
2016-09-10 14:19:31 +00:00
|
|
|
FResourceGroups: TList;
|
2008-02-03 12:05:55 +00:00
|
|
|
function GetCount: Integer;
|
2016-09-06 19:59:25 +00:00
|
|
|
function GetItem(Index: Integer): TVpResource;
|
2016-09-10 14:19:31 +00:00
|
|
|
function GetResourceGroup(Index: Integer): TVpResourceGroup;
|
|
|
|
function GetResourceGroupCount: Integer;
|
2016-09-06 19:59:25 +00:00
|
|
|
protected
|
|
|
|
FResourceList: TList;
|
2016-06-28 13:43:32 +00:00
|
|
|
function NextResourceID: Integer;
|
2008-02-03 12:05:55 +00:00
|
|
|
public
|
|
|
|
constructor Create(Owner: TObject);
|
|
|
|
destructor Destroy; override;
|
2016-06-28 13:43:32 +00:00
|
|
|
function AddResource(ResID: Integer): TVpResource;
|
2016-09-11 08:14:11 +00:00
|
|
|
function AddResourceGroup(const AResIDs: array of Integer;
|
|
|
|
ACaption: String = ''): TVpResourceGroup;
|
2016-09-06 19:59:25 +00:00
|
|
|
procedure ClearResources;
|
2016-09-10 14:19:31 +00:00
|
|
|
procedure ClearResourceGroups;
|
2016-06-27 22:43:15 +00:00
|
|
|
function FindResourceByName(AName : string) : TVpResource;
|
2016-09-10 14:19:31 +00:00
|
|
|
function FindResourceGroupByName(AName: String): TVpResourceGroup;
|
2012-09-24 19:30:17 +00:00
|
|
|
function GetResource(ID: Integer): TVpResource;
|
2008-02-03 12:05:55 +00:00
|
|
|
procedure RemoveResource(Resource: TVpResource);
|
2016-09-10 14:19:31 +00:00
|
|
|
procedure RemoveResourceGroup(AGroup: TVpResourceGroup);
|
2008-02-03 12:05:55 +00:00
|
|
|
procedure Sort;
|
|
|
|
property Count: Integer read GetCount;
|
2016-06-28 13:43:32 +00:00
|
|
|
property Items[Index: Integer]: TVpResource read GetItem;
|
2008-02-03 12:05:55 +00:00
|
|
|
property Owner: TObject read FOwner;
|
2016-09-10 14:19:31 +00:00
|
|
|
property ResourceGroupCount: Integer read GetResourceGroupCount;
|
|
|
|
property ResourceGroups[Index: Integer]: TVpResourceGroup read GetResourceGroup;
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
TVpResource = class
|
2016-09-06 19:59:25 +00:00
|
|
|
private
|
2008-02-03 12:05:55 +00:00
|
|
|
FOwner: TVpResources;
|
|
|
|
FChanged: Boolean;
|
|
|
|
FDeleted: Boolean;
|
|
|
|
FEventsDirty: Boolean;
|
|
|
|
FContactsDirty: Boolean;
|
2016-09-06 19:59:25 +00:00
|
|
|
FLoading : Boolean;
|
2008-02-03 12:05:55 +00:00
|
|
|
FTasksDirty: Boolean;
|
|
|
|
FSchedule: TVpSchedule;
|
|
|
|
FTasks: TVpTasks;
|
2016-09-06 19:59:25 +00:00
|
|
|
FContacts: TVpContacts;
|
2016-09-10 18:27:50 +00:00
|
|
|
FGroup: TVpResourceGroup;
|
2016-09-06 19:59:25 +00:00
|
|
|
FActive: Boolean; // Internal flag whether to display this resource
|
2008-02-03 12:05:55 +00:00
|
|
|
FNotes: string;
|
|
|
|
FDescription: string;
|
|
|
|
{ reserved for your use }
|
|
|
|
FUserField0: string;
|
|
|
|
FUserField1: string;
|
|
|
|
FUserField2: string;
|
|
|
|
FUserField3: string;
|
|
|
|
FUserField4: string;
|
|
|
|
FUserField5: string;
|
|
|
|
FUserField6: string;
|
|
|
|
FUserField7: string;
|
|
|
|
FUserField8: string;
|
|
|
|
FUserField9: string;
|
|
|
|
FResourceID: Integer;
|
|
|
|
function GetSchedule: TVpSchedule;
|
|
|
|
procedure SetChanged(Value: Boolean);
|
2016-09-06 19:59:25 +00:00
|
|
|
procedure SetContacts(const Value: TVpContacts);
|
2008-02-03 12:05:55 +00:00
|
|
|
procedure SetDeleted(Value: Boolean);
|
|
|
|
procedure SetDescription(const Value: string);
|
2016-09-10 18:27:50 +00:00
|
|
|
procedure SetGroup(const AValue: TVpResourceGroup);
|
2016-09-06 19:59:25 +00:00
|
|
|
procedure SetNotes(const Value: string);
|
2008-02-03 12:05:55 +00:00
|
|
|
procedure SetResourceID(const Value: Integer);
|
|
|
|
procedure SetSchedule(const Value: TVpSchedule);
|
|
|
|
procedure SetTasks(const Value: TVpTasks);
|
2016-09-10 14:19:31 +00:00
|
|
|
|
2008-02-03 12:05:55 +00:00
|
|
|
public
|
|
|
|
constructor Create(Owner: TVpResources);
|
|
|
|
destructor Destroy; override;
|
2016-09-10 17:26:42 +00:00
|
|
|
procedure GetResourceGroups(AList: TList);
|
2021-12-04 19:01:07 +00:00
|
|
|
function OverlayResources(const AResources: TVpResourceArray;
|
|
|
|
ACaption: String = ''): TVpResourceGroup;
|
2008-02-03 12:05:55 +00:00
|
|
|
property Loading: Boolean read FLoading write FLoading;
|
|
|
|
property Changed: Boolean read FChanged write SetChanged;
|
|
|
|
property Deleted: Boolean read FDeleted write SetDeleted;
|
|
|
|
property EventsDirty: Boolean read FEventsDirty write FEventsDirty;
|
|
|
|
property ContactsDirty: Boolean read FContactsDirty write FContactsDirty;
|
|
|
|
property TasksDirty: Boolean read FTasksDirty write FTasksDirty;
|
2016-06-12 12:53:26 +00:00
|
|
|
property Active: Boolean read FActive write FActive; deprecated 'Use "ResourceActive" instead';
|
2008-02-03 12:05:55 +00:00
|
|
|
property Owner: TVpResources read FOwner;
|
2016-09-05 14:04:22 +00:00
|
|
|
// property ItemIndex: integer read FItemIndex;
|
2008-02-03 12:05:55 +00:00
|
|
|
property Schedule: TVpSchedule read GetSchedule write SetSchedule;
|
|
|
|
property Tasks: TVpTasks read FTasks write SetTasks;
|
|
|
|
property Contacts: TVpContacts read FContacts write SetContacts;
|
2016-09-10 18:27:50 +00:00
|
|
|
property Group: TVpResourceGroup read FGroup write SetGroup;
|
2016-09-10 14:19:31 +00:00
|
|
|
|
2016-09-01 09:56:46 +00:00
|
|
|
{$ifdef WITHRTTI}
|
|
|
|
published
|
|
|
|
{$else}
|
|
|
|
public
|
|
|
|
{$endif}
|
|
|
|
property ResourceID: Integer read FResourceID write SetResourceID;
|
|
|
|
property Description: string read FDescription write SetDescription;
|
|
|
|
property Notes: string read FNotes write SetNotes;
|
|
|
|
property ResourceActive: Boolean read FActive write FActive;
|
2008-02-03 12:05:55 +00:00
|
|
|
property UserField0: string read FUserField0 write FUserField0;
|
|
|
|
property UserField1: string read FUserField1 write FUserField1;
|
|
|
|
property UserField2: string read FUserField2 write FUserField2;
|
|
|
|
property UserField3: string read FUserField3 write FUserField3;
|
|
|
|
property UserField4: string read FUserField4 write FUserField4;
|
|
|
|
property UserField5: string read FUserField5 write FUserField5;
|
|
|
|
property UserField6: string read FUserField6 write FUserField6;
|
|
|
|
property UserField7: string read FUserField7 write FUserField7;
|
|
|
|
property UserField8: string read FUserField8 write FUserField8;
|
|
|
|
property UserField9: string read FUserField9 write FUserField9;
|
|
|
|
end;
|
|
|
|
|
2016-09-10 14:19:31 +00:00
|
|
|
TVpResourceGroup = class
|
|
|
|
private
|
|
|
|
FOwner: TVpResources;
|
|
|
|
FResourceID: Integer;
|
|
|
|
FCaption: String;
|
|
|
|
FIDs: Array of Integer;
|
2016-09-10 19:06:41 +00:00
|
|
|
FReadOnly: Boolean;
|
2016-09-10 20:08:06 +00:00
|
|
|
FPattern: TVpOverlayPattern;
|
2016-09-11 13:35:19 +00:00
|
|
|
FShowDetails: TVpOverlayDetails;
|
2016-09-10 14:19:31 +00:00
|
|
|
function GetCount: integer;
|
|
|
|
function GetItem(AIndex: Integer): TVpResource;
|
2016-09-10 20:08:06 +00:00
|
|
|
procedure SetPattern(AValue: TVpOverlayPattern);
|
2016-09-11 13:35:19 +00:00
|
|
|
procedure SetShowDetails(AValue: TVpOverlayDetails);
|
2016-09-10 14:19:31 +00:00
|
|
|
public
|
2016-09-11 08:14:11 +00:00
|
|
|
constructor Create(AOwner: TVpResources; AResourceID: Integer; ACaption: String);
|
2016-09-10 14:19:31 +00:00
|
|
|
destructor Destroy; override;
|
|
|
|
function AddID(AResourceID: Integer): Integer;
|
|
|
|
function AsString(ASeparator: Char = ';'): String;
|
|
|
|
procedure Clear;
|
|
|
|
function IndexOfID(AResourceID: Integer): Integer;
|
|
|
|
procedure Remove(AResourceID: Integer);
|
|
|
|
property Caption: String read FCaption;
|
|
|
|
property Count: Integer read GetCount;
|
|
|
|
property Items[AIndex: Integer]: TVpResource read GetItem; default;
|
2016-09-11 13:35:19 +00:00
|
|
|
property Pattern: TVpOverlayPattern read FPattern write SetPattern;
|
2016-09-10 14:19:31 +00:00
|
|
|
property ResourceID: Integer read FResourceID;
|
2016-09-10 19:06:41 +00:00
|
|
|
property ReadOnly: boolean read FReadOnly write FReadOnly;
|
2016-09-11 13:35:19 +00:00
|
|
|
property ShowDetails: TVpOverlayDetails read FShowDetails write SetShowDetails;
|
2016-09-10 14:19:31 +00:00
|
|
|
end;
|
|
|
|
|
2008-02-03 12:05:55 +00:00
|
|
|
TVpSchedule = class
|
2016-09-06 19:59:25 +00:00
|
|
|
private
|
|
|
|
FOwner: TVpResource;
|
|
|
|
function GetCount: Integer;
|
|
|
|
protected
|
2008-02-03 12:05:55 +00:00
|
|
|
FEventList: TList;
|
|
|
|
FBatchUpdate: Integer;
|
2016-06-30 18:45:39 +00:00
|
|
|
// function FindTimeSlot(StartTime, EndTime: TDateTime): Boolean;
|
2008-02-03 12:05:55 +00:00
|
|
|
public
|
|
|
|
constructor Create(Owner: TVpResource);
|
|
|
|
destructor Destroy; override;
|
2016-06-28 13:43:32 +00:00
|
|
|
function AddEvent(RecordID: Integer; StartTime, EndTime: TDateTime): TVpEvent;
|
2016-09-06 19:59:25 +00:00
|
|
|
procedure AllDayEventsByDate(Date: TDateTime; EventList: TList);
|
|
|
|
procedure BatchUpdate(Value: Boolean);
|
|
|
|
procedure ClearEvents;
|
2016-09-10 15:09:23 +00:00
|
|
|
procedure ClearGroupEvents;
|
2008-02-03 12:05:55 +00:00
|
|
|
procedure DeleteEvent(Event: TVpEvent);
|
2016-09-06 19:59:25 +00:00
|
|
|
function EventCountByDay(Value: TDateTime): Integer;
|
|
|
|
procedure EventsByDate(Date: TDateTime; EventList: TList);
|
2022-08-20 17:06:03 +00:00
|
|
|
procedure ExportICalFile(const AFileName: String; const AEvents: TVpEventArr);
|
2016-06-28 13:43:32 +00:00
|
|
|
function GetEvent(Index: Integer): TVpEvent;
|
2022-08-10 10:20:56 +00:00
|
|
|
function ImportICalFile(const AFileName: String; APreview: Boolean = false;
|
|
|
|
ADefaultCategory: Integer = -1): TVpEventArr;
|
2008-02-03 12:05:55 +00:00
|
|
|
function RepeatsOn(Event: TVpEvent; Day: TDateTime): Boolean;
|
|
|
|
procedure Sort;
|
|
|
|
property Owner: TVpResource read FOwner;
|
|
|
|
property EventCount: Integer read GetCount;
|
|
|
|
end;
|
|
|
|
|
2009-12-24 22:41:52 +00:00
|
|
|
{ TVpEvent }
|
|
|
|
|
2008-02-03 12:05:55 +00:00
|
|
|
TVpEvent = class
|
2016-09-06 19:59:25 +00:00
|
|
|
private
|
2008-02-03 12:05:55 +00:00
|
|
|
FOwner: TVpSchedule;
|
|
|
|
FChanged: Boolean;
|
|
|
|
FDeleted: Boolean;
|
|
|
|
FLoading: Boolean;
|
2016-11-21 17:12:05 +00:00
|
|
|
//FPrivateEvent: Boolean;
|
2008-02-03 12:05:55 +00:00
|
|
|
FAlarmSet: Boolean;
|
|
|
|
FDingPath: string;
|
|
|
|
FAllDayEvent: Boolean;
|
|
|
|
FCategory: Integer;
|
|
|
|
FAlarmAdv: Integer;
|
|
|
|
FAlertDisplayed: Boolean;
|
|
|
|
FAlarmAdvType: TVpAlarmAdvType;
|
2016-06-28 13:43:32 +00:00
|
|
|
FRecordID: Integer;
|
2016-09-10 15:09:23 +00:00
|
|
|
FResourceID: Integer;
|
2016-06-11 14:09:10 +00:00
|
|
|
FLocation: string;
|
|
|
|
FNotes: string;
|
2008-02-03 12:05:55 +00:00
|
|
|
FDescription: string;
|
|
|
|
FStartTime: TDateTime;
|
|
|
|
FEndTime: TDateTime;
|
|
|
|
FSnoozeTime: TDateTime;
|
|
|
|
FRepeatCode: TVpRepeatType;
|
|
|
|
FRepeatRangeEnd: TDateTime;
|
|
|
|
FCustInterval: Integer;
|
|
|
|
{ reserved for your use }
|
|
|
|
FUserField0: string;
|
|
|
|
FUserField1: string;
|
|
|
|
FUserField2: string;
|
|
|
|
FUserField3: string;
|
|
|
|
FUserField4: string;
|
|
|
|
FUserField5: string;
|
|
|
|
FUserField6: string;
|
|
|
|
FUserField7: string;
|
|
|
|
FUserField8: string;
|
|
|
|
FUserField9: string;
|
|
|
|
procedure SetAllDayEvent(Value: Boolean);
|
2016-09-05 14:04:22 +00:00
|
|
|
// procedure SetItemIndex(Value: Integer);
|
2008-02-03 12:05:55 +00:00
|
|
|
procedure SetChanged(Value: Boolean);
|
|
|
|
procedure SetDeleted(Value: Boolean);
|
|
|
|
procedure SetDingPath(Value: string);
|
|
|
|
procedure SetAlarmAdv(Value: Integer);
|
|
|
|
procedure SetAlarmAdvType(Value: TVpAlarmAdvType);
|
|
|
|
procedure SetSnoozeTime(Value: TDateTime);
|
|
|
|
procedure SetAlarmSet(Value: Boolean);
|
|
|
|
procedure SetCategory(Value: Integer);
|
|
|
|
procedure SetDescription(const Value: string);
|
|
|
|
procedure SetEndTime(Value: TDateTime);
|
2016-06-11 14:09:10 +00:00
|
|
|
procedure SetLocation(const Value: String);
|
|
|
|
procedure SetNotes(const Value: string);
|
2016-06-28 13:43:32 +00:00
|
|
|
procedure SetRecordID(Value: Integer);
|
2008-02-03 12:05:55 +00:00
|
|
|
procedure SetStartTime(Value: TDateTime);
|
|
|
|
procedure SetCustInterval(Value: Integer);
|
|
|
|
procedure SetRepeatCode(Value: TVpRepeatType);
|
|
|
|
procedure SetRepeatRangeEnd(Value: TDateTime);
|
|
|
|
public
|
|
|
|
constructor Create(Owner: TVpSchedule);
|
|
|
|
destructor Destroy; override;
|
2016-09-10 19:06:41 +00:00
|
|
|
function CanEdit: Boolean;
|
2021-12-06 22:34:33 +00:00
|
|
|
function CopyToSchedule(ASchedule: TVpSchedule): TVpEvent;
|
2022-08-20 17:06:03 +00:00
|
|
|
function CreateICalEvent(ACalendar: TVpICalendar): TVpICalEvent;
|
2022-08-12 13:47:03 +00:00
|
|
|
class procedure GetAlarmParams(ATrigger: TDateTime; out AdvTime: Integer;
|
|
|
|
out AdvTimeUnits: TVpAlarmAdvType);
|
2022-08-20 19:11:37 +00:00
|
|
|
function GetCategoryName: String;
|
2016-09-10 19:06:41 +00:00
|
|
|
function GetResource: TVpResource;
|
2016-09-10 15:09:23 +00:00
|
|
|
function IsOverlayed: Boolean;
|
2018-06-15 23:40:18 +00:00
|
|
|
procedure LoadFromICalendar(AEntry: TVpICalEvent);
|
2016-09-01 09:56:46 +00:00
|
|
|
property Owner: TVpSchedule read FOwner;
|
2016-09-10 15:09:23 +00:00
|
|
|
property ResourceID: Integer read FResourceID write FResourceID;
|
2016-09-01 09:56:46 +00:00
|
|
|
property Loading : Boolean read FLoading write FLoading;
|
2008-02-10 19:17:45 +00:00
|
|
|
property Changed: Boolean read FChanged write SetChanged;
|
|
|
|
property Deleted: Boolean read FDeleted write SetDeleted;
|
2016-09-01 09:56:46 +00:00
|
|
|
{$ifdef WITHRTTI}
|
|
|
|
published
|
|
|
|
{$else}
|
|
|
|
public
|
|
|
|
{$endif}
|
2016-09-06 19:59:25 +00:00
|
|
|
property RecordID: Integer read FRecordID write SetRecordID;
|
2016-09-01 09:56:46 +00:00
|
|
|
property DingPath: string read FDingPath write SetDingPath;
|
|
|
|
property AlarmWavPath: string read FDingPath write SetDingPath; deprecated 'Use "DingPath" instead';
|
|
|
|
property AlertDisplayed: Boolean read FAlertDisplayed write FAlertDisplayed;
|
|
|
|
property AllDayEvent: Boolean read FAllDayEvent write SetAllDayEvent;
|
2016-09-06 19:59:25 +00:00
|
|
|
property StartTime: TDateTime read FStartTime write SetStartTime;
|
|
|
|
property EndTime: TDateTime read FEndTime write SetEndTime;
|
|
|
|
property Description: string read FDescription write SetDescription;
|
|
|
|
property Notes: string read FNotes write SetNotes;
|
2016-06-11 14:09:10 +00:00
|
|
|
property Note: String read FNotes write SetNotes; deprecated 'Use "Notes" instead';
|
2016-09-06 19:59:25 +00:00
|
|
|
property Category: Integer read FCategory write SetCategory;
|
|
|
|
property AlarmSet: Boolean read FAlarmSet write SetAlarmSet;
|
2016-06-12 12:53:26 +00:00
|
|
|
property AlarmAdvance: Integer read FAlarmAdv write SetAlarmAdv;
|
2016-09-06 19:59:25 +00:00
|
|
|
property AlarmAdv: Integer read FAlarmAdv write SetAlarmAdv; deprecated 'Use "AlarmAdvance" instead';
|
2016-06-11 14:09:10 +00:00
|
|
|
property Location: string read FLocation write SetLocation;
|
2008-02-03 12:05:55 +00:00
|
|
|
{ 0=Minutes, 1=Hours, 2=Days }
|
2016-06-12 12:53:26 +00:00
|
|
|
property AlarmAdvanceType: TVpAlarmAdvType read FAlarmAdvType write SetAlarmAdvType;
|
2016-09-06 19:59:25 +00:00
|
|
|
property AlarmAdvType: TVpAlarmAdvType read FAlarmAdvType write SetAlarmAdvType; deprecated 'Use "AlarmAdvanceType" instead';
|
|
|
|
property SnoozeTime: TDateTime read FSnoozeTime write SetSnoozeTime;
|
2008-02-03 12:05:55 +00:00
|
|
|
{ rtNone, rtDaily, rtWeekly, rtMonthlyByDay, rtMonthlyByDate, }
|
|
|
|
{ rtYearlyByDay, rtYearlyByDate, rtCustom }
|
2016-06-12 12:53:26 +00:00
|
|
|
property RepeatCode: TVpRepeatType read FRepeatCode write SetRepeatCode;
|
2008-02-10 19:17:45 +00:00
|
|
|
property RepeatRangeEnd: TDateTime read FRepeatRangeEnd write SetRepeatRangeEnd;
|
2008-02-03 12:05:55 +00:00
|
|
|
{ Custom Repeat Interval in seconds }
|
|
|
|
{ is Zero if IntervalCode <> 7 }
|
2016-09-06 19:59:25 +00:00
|
|
|
property CustomInterval: Integer read FCustInterval write SetCustInterval;
|
|
|
|
property CustInterval: Integer read FCustInterval write SetCustInterval; deprecated 'Use "CustomInterval" instead';
|
2008-02-03 12:05:55 +00:00
|
|
|
{ Reserved for your use }
|
|
|
|
property UserField0: string read FUserField0 write FUserField0;
|
|
|
|
property UserField1: string read FUserField1 write FUserField1;
|
|
|
|
property UserField2: string read FUserField2 write FUserField2;
|
|
|
|
property UserField3: string read FUserField3 write FUserField3;
|
|
|
|
property UserField4: string read FUserField4 write FUserField4;
|
|
|
|
property UserField5: string read FUserField5 write FUserField5;
|
|
|
|
property UserField6: string read FUserField6 write FUserField6;
|
|
|
|
property UserField7: string read FUserField7 write FUserField7;
|
|
|
|
property UserField8: string read FUserField8 write FUserField8;
|
|
|
|
property UserField9: string read FUserField9 write FUserField9;
|
|
|
|
end;
|
|
|
|
|
|
|
|
TVpTasks = class
|
2016-09-06 19:59:25 +00:00
|
|
|
private
|
2008-02-03 12:05:55 +00:00
|
|
|
FOwner: TVpResource;
|
2016-09-06 19:59:25 +00:00
|
|
|
protected
|
2008-02-03 12:05:55 +00:00
|
|
|
FTaskList: TList;
|
|
|
|
FBatchUpdate: Integer;
|
|
|
|
public
|
|
|
|
constructor Create(Owner: TVpResource);
|
|
|
|
destructor Destroy; override;
|
2016-09-05 14:04:22 +00:00
|
|
|
function AddTask(RecordID: Integer): TVpTask;
|
2008-02-03 12:05:55 +00:00
|
|
|
procedure BatchUpdate(value: Boolean);
|
2016-09-06 19:59:25 +00:00
|
|
|
procedure ClearTasks;
|
|
|
|
function Count: Integer;
|
2008-02-03 12:05:55 +00:00
|
|
|
function CountByDay(Date: TDateTime): Integer;
|
2016-09-06 19:59:25 +00:00
|
|
|
procedure DeleteTask(Task: TVpTask);
|
|
|
|
function First: TVpTask;
|
|
|
|
function FirstByDay(Date: TDateTime): TVpTask;
|
2022-08-20 21:21:14 +00:00
|
|
|
procedure ExportICalFile(const AFileName: String; const ATasks: TVpTaskArr);
|
2022-08-10 21:21:17 +00:00
|
|
|
function ImportICalFile(const AFileName: String; APreview: Boolean = false;
|
|
|
|
ADefaultCategory: Integer = -1): TVpTaskArr;
|
2016-09-05 14:04:22 +00:00
|
|
|
function IndexOf(ATask: TVpTask): Integer;
|
2008-02-03 12:05:55 +00:00
|
|
|
function Last: TVpTask;
|
|
|
|
function LastByDay(Date: TDateTime): TVpTask;
|
2016-09-05 14:04:22 +00:00
|
|
|
procedure Sort;
|
2008-02-03 12:05:55 +00:00
|
|
|
function GetTask(Index: Integer): TVpTask;
|
2022-08-11 20:32:13 +00:00
|
|
|
property Owner: TVpResource read FOwner;
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
TVpTask = class
|
2016-09-06 19:59:25 +00:00
|
|
|
private
|
2008-02-03 12:05:55 +00:00
|
|
|
FOwner: TVpTasks;
|
2016-09-06 19:59:25 +00:00
|
|
|
FLoading: Boolean;
|
2008-02-03 12:05:55 +00:00
|
|
|
FChanged: Boolean;
|
|
|
|
FDeleted: Boolean;
|
|
|
|
FItemIndex: Integer;
|
|
|
|
FPriority: Integer;
|
|
|
|
FCategory: Integer;
|
|
|
|
FComplete: Boolean;
|
|
|
|
FDescription: string;
|
|
|
|
FDetails: string;
|
|
|
|
FCreatedOn: TDateTime;
|
|
|
|
FCompletedOn: TDateTIme;
|
|
|
|
FRecordID: Integer;
|
|
|
|
FDueDate: TDateTime;
|
|
|
|
{ reserved for your use }
|
|
|
|
FUserField0: string;
|
|
|
|
FUserField1: string;
|
|
|
|
FUserField2: string;
|
|
|
|
FUserField3: string;
|
|
|
|
FUserField4: string;
|
|
|
|
FUserField5: string;
|
|
|
|
FUserField6: string;
|
|
|
|
FUserField7: string;
|
|
|
|
FUserField8: string;
|
|
|
|
FUserField9: string;
|
|
|
|
|
|
|
|
procedure SetCategory(const Value: Integer);
|
|
|
|
procedure SetChanged(const Value: Boolean);
|
|
|
|
procedure SetComplete(const Value: Boolean);
|
|
|
|
procedure SetCompletedOn(const Value: TDateTime);
|
|
|
|
procedure SetCreatedOn(const Value: TDateTime);
|
|
|
|
procedure SetDescription(const Value: string);
|
|
|
|
procedure SetDetails(const Value: string);
|
|
|
|
procedure SetDueDate(const Value: TDateTime);
|
|
|
|
procedure SetPriority(const Value: Integer);
|
2016-09-06 19:59:25 +00:00
|
|
|
protected
|
2008-02-03 12:05:55 +00:00
|
|
|
function IsOverdue: Boolean;
|
|
|
|
public
|
|
|
|
constructor Create(Owner: TVpTasks);
|
|
|
|
destructor Destroy; override;
|
2022-08-20 21:21:14 +00:00
|
|
|
function CreateICalTask(ACalendar: TVpICalendar): TVpICalToDo;
|
2018-06-17 20:27:58 +00:00
|
|
|
procedure LoadFromICalendar(AEntry: TVpICalToDo);
|
2022-08-10 21:21:17 +00:00
|
|
|
class function GetTaskPriority(APriority:Integer): TVpTaskPriority;
|
2008-02-03 12:05:55 +00:00
|
|
|
property Loading: Boolean read FLoading write FLoading;
|
|
|
|
property Changed: Boolean read FChanged write SetChanged;
|
|
|
|
property Deleted: Boolean read FDeleted write FDeleted;
|
2016-09-01 09:56:46 +00:00
|
|
|
property Owner: TVpTasks read FOwner;
|
|
|
|
{$ifdef WITHRTTI}
|
|
|
|
published
|
|
|
|
{$else}
|
|
|
|
public
|
|
|
|
{$endif}
|
|
|
|
property RecordID: Integer read FRecordID write FRecordID;
|
2008-02-03 12:05:55 +00:00
|
|
|
property DueDate: TDateTime read FDueDate write SetDueDate;
|
|
|
|
property Description: string read FDescription write SetDescription;
|
|
|
|
property ItemIndex: Integer read FItemIndex;
|
|
|
|
property Details: string read FDetails write SetDetails;
|
|
|
|
property Complete: Boolean read FComplete write SetComplete;
|
|
|
|
property CreatedOn: TDateTime read FCreatedOn write SetCreatedOn;
|
|
|
|
property CompletedOn: TDateTIme read FCompletedOn write SetCompletedOn;
|
2018-06-17 20:27:58 +00:00
|
|
|
property Priority: Integer read FPriority write SetPriority; // --> TVpTaskPriority
|
|
|
|
property Category: Integer read FCategory write SetCategory; // --> TVpCategoryType
|
2008-02-03 12:05:55 +00:00
|
|
|
|
|
|
|
{ Reserved for your use }
|
|
|
|
property UserField0: string read FUserField0 write FUserField0;
|
|
|
|
property UserField1: string read FUserField1 write FUserField1;
|
|
|
|
property UserField2: string read FUserField2 write FUserField2;
|
|
|
|
property UserField3: string read FUserField3 write FUserField3;
|
|
|
|
property UserField4: string read FUserField4 write FUserField4;
|
|
|
|
property UserField5: string read FUserField5 write FUserField5;
|
|
|
|
property UserField6: string read FUserField6 write FUserField6;
|
|
|
|
property UserField7: string read FUserField7 write FUserField7;
|
|
|
|
property UserField8: string read FUserField8 write FUserField8;
|
|
|
|
property UserField9: string read FUserField9 write FUserField9;
|
|
|
|
end;
|
|
|
|
|
|
|
|
TVpContacts = class
|
2016-09-06 19:59:25 +00:00
|
|
|
private
|
|
|
|
FOwner: TVpResource;
|
|
|
|
FContactsList: TList;
|
|
|
|
FContactSort: TVpContactSort;
|
|
|
|
procedure SetContactSort(const v: TVpContactSort);
|
2008-02-03 12:05:55 +00:00
|
|
|
protected
|
2016-09-06 19:59:25 +00:00
|
|
|
FBatchUpdate: Integer;
|
2008-02-03 12:05:55 +00:00
|
|
|
public
|
|
|
|
constructor Create(Owner: TVpResource);
|
|
|
|
destructor Destroy; override;
|
2016-09-06 19:59:25 +00:00
|
|
|
function AddContact(RecordID: Integer): TVpContact;
|
2008-02-03 12:05:55 +00:00
|
|
|
procedure BatchUpdate(Value: Boolean);
|
2016-09-06 19:59:25 +00:00
|
|
|
procedure ClearContacts;
|
2008-02-03 12:05:55 +00:00
|
|
|
function Count: Integer;
|
|
|
|
procedure DeleteContact(Contact: TVpContact);
|
2016-09-06 19:59:25 +00:00
|
|
|
function First: TVpContact;
|
2018-12-04 11:34:23 +00:00
|
|
|
function FindContactByName(const AName: string;
|
2016-09-06 19:59:25 +00:00
|
|
|
CaseInsensitive: Boolean = True): TVpContact;
|
|
|
|
function FindContactIndexByName(const Name: string;
|
|
|
|
CaseInsensitive: Boolean = True): Integer;
|
2008-02-03 12:05:55 +00:00
|
|
|
function GetContact(Index: Integer): TVpContact;
|
2016-09-06 19:59:25 +00:00
|
|
|
function Last:TVpContact;
|
2022-08-19 10:53:49 +00:00
|
|
|
function ImportVCardFile(const AFileName: String; const APreview: Boolean = false;
|
|
|
|
ADefaultCategory: Integer = -1): TVpContactArr;
|
2022-08-18 17:44:47 +00:00
|
|
|
procedure ExportVCardFile(const AFileName: String; const AContacts: TVpContactArr);
|
2016-09-06 19:59:25 +00:00
|
|
|
procedure Sort;
|
2008-02-03 12:05:55 +00:00
|
|
|
|
2016-09-06 19:59:25 +00:00
|
|
|
property ContactsList: TList
|
|
|
|
read FContactsList;
|
|
|
|
property ContactSort: TVpContactSort
|
|
|
|
read FContactSort write SetContactSort default csLastFirst;
|
2022-08-11 20:32:13 +00:00
|
|
|
property Owner: TVpResource read FOwner;
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
TVpContact = class
|
2016-09-16 23:42:31 +00:00
|
|
|
private
|
2016-09-06 19:59:25 +00:00
|
|
|
FOwner: TVpContacts;
|
|
|
|
FLoading: Boolean;
|
|
|
|
FChanged: Boolean;
|
|
|
|
FRecordID: Integer;
|
|
|
|
FDeleted: Boolean;
|
|
|
|
FPosition: string;
|
|
|
|
FLastName: string;
|
|
|
|
FFirstName: string;
|
|
|
|
FBirthDate: TDateTime;
|
|
|
|
FAnniversary: TDateTime;
|
|
|
|
FTitle: string;
|
|
|
|
FCompany: string;
|
2016-09-16 23:42:31 +00:00
|
|
|
FDepartment: String;
|
2016-09-15 11:40:14 +00:00
|
|
|
FEMail1: string;
|
|
|
|
FEMail2: String;
|
|
|
|
FEMail3: String;
|
|
|
|
FEMailType1: integer;
|
|
|
|
FEMailType2: integer;
|
|
|
|
FEMailType3: integer;
|
2016-09-06 19:59:25 +00:00
|
|
|
FPhone1: string;
|
|
|
|
FPhone2: string;
|
|
|
|
FPhone3: string;
|
|
|
|
FPhone4: string;
|
|
|
|
FPhone5: string;
|
|
|
|
FPhoneType1: integer;
|
|
|
|
FPhoneType2: integer;
|
|
|
|
FPhoneType3: integer;
|
|
|
|
FPhoneType4: integer;
|
|
|
|
FPhoneType5: integer;
|
2016-09-15 11:40:14 +00:00
|
|
|
FWebsite1: String;
|
|
|
|
FWebsite2: String;
|
|
|
|
FWebsiteType1: Integer;
|
|
|
|
FWebsiteType2: Integer;
|
|
|
|
FAddressType1: Integer;
|
|
|
|
FAddressType2: Integer;
|
|
|
|
FAddress1: string;
|
|
|
|
FAddress2: String;
|
|
|
|
FCity1: string;
|
|
|
|
FCity2: String;
|
|
|
|
FState1: string;
|
|
|
|
FState2: String;
|
|
|
|
FZip1: string;
|
|
|
|
FZip2: String;
|
|
|
|
FCountry1: string;
|
|
|
|
FCountry2: String;
|
2016-09-06 19:59:25 +00:00
|
|
|
FNotes: string;
|
2016-11-21 17:12:05 +00:00
|
|
|
//FPrivateRec: boolean;
|
2016-09-06 19:59:25 +00:00
|
|
|
FCategory: integer;
|
2022-08-19 10:53:49 +00:00
|
|
|
FPickedCategory: Integer;
|
2016-09-06 19:59:25 +00:00
|
|
|
FCustom1: string;
|
|
|
|
FCustom2: string;
|
|
|
|
FCustom3: string;
|
|
|
|
FCustom4: string;
|
2008-02-03 12:05:55 +00:00
|
|
|
{ reserved for your use }
|
2016-09-06 19:59:25 +00:00
|
|
|
FUserField0: string;
|
|
|
|
FUserField1: string;
|
|
|
|
FUserField2: string;
|
|
|
|
FUserField3: string;
|
|
|
|
FUserField4: string;
|
|
|
|
FUserField5: string;
|
|
|
|
FUserField6: string;
|
|
|
|
FUserField7: string;
|
|
|
|
FUserField8: string;
|
|
|
|
FUserField9: string;
|
2016-09-15 11:40:14 +00:00
|
|
|
procedure SetAddress1(const Value: string);
|
|
|
|
procedure SetAddress2(const Value: String);
|
|
|
|
procedure SetAddressType1(Value: Integer);
|
|
|
|
procedure SetAddressType2(Value: Integer);
|
2008-02-03 12:05:55 +00:00
|
|
|
procedure SetBirthDate(Value: TDateTime);
|
|
|
|
procedure SetAnniversary(Value: TDateTime);
|
2016-09-06 19:59:25 +00:00
|
|
|
procedure SetCategory(Value: integer);
|
2008-02-03 12:05:55 +00:00
|
|
|
procedure SetChanged(Value: Boolean);
|
2016-09-15 11:40:14 +00:00
|
|
|
procedure SetCity1(const Value: string);
|
|
|
|
procedure SetCity2(const Value: String);
|
2008-02-03 12:05:55 +00:00
|
|
|
procedure SetCompany(const Value: string);
|
2016-09-15 11:40:14 +00:00
|
|
|
procedure SetCountry1(const Value: string);
|
|
|
|
procedure SetCountry2(const Value: string);
|
2008-02-03 12:05:55 +00:00
|
|
|
procedure SetCustom1(const Value: string);
|
|
|
|
procedure SetCustom2(const Value: string);
|
|
|
|
procedure SetCustom3(const Value: string);
|
|
|
|
procedure SetCustom4(const Value: string);
|
|
|
|
procedure SetDeleted(Value: Boolean);
|
2016-09-16 23:42:31 +00:00
|
|
|
procedure SetDepartment(const Value: String);
|
2016-09-15 11:40:14 +00:00
|
|
|
procedure SetEMail1(const Value: string);
|
|
|
|
procedure SetEMail2(const Value: string);
|
|
|
|
procedure SetEMail3(const Value: string);
|
|
|
|
procedure SetEMailType1(const Value: Integer);
|
|
|
|
procedure SetEMailType2(const Value: Integer);
|
|
|
|
procedure SetEMailType3(const Value: Integer);
|
2008-02-03 12:05:55 +00:00
|
|
|
procedure SetFirstName(const Value: string);
|
|
|
|
procedure SetLastName(const Value: string);
|
2016-06-11 14:09:10 +00:00
|
|
|
procedure SetNotes(const Value: string);
|
2008-02-03 12:05:55 +00:00
|
|
|
procedure SetPhone1(const Value: string);
|
|
|
|
procedure SetPhone2(const Value: string);
|
|
|
|
procedure SetPhone3(const Value: string);
|
|
|
|
procedure SetPhone4(const Value: string);
|
|
|
|
procedure SetPhone5(const Value: string);
|
|
|
|
procedure SetPhoneType1(Value: integer);
|
|
|
|
procedure SetPhoneType2(Value: integer);
|
|
|
|
procedure SetPhoneType3(Value: integer);
|
|
|
|
procedure SetPhoneType4(Value: integer);
|
|
|
|
procedure SetPhoneType5(Value: integer);
|
|
|
|
procedure SetPosition(const Value: string);
|
|
|
|
procedure SetRecordID(Value: Integer);
|
2016-09-15 11:40:14 +00:00
|
|
|
procedure SetState1(const Value: string);
|
|
|
|
procedure SetState2(const Value: string);
|
2008-02-03 12:05:55 +00:00
|
|
|
procedure SetTitle(const Value: string);
|
2016-09-15 11:40:14 +00:00
|
|
|
procedure SetWebsite1(Value: String);
|
|
|
|
procedure SetWebsite2(Value: String);
|
|
|
|
procedure SetWebsiteType1(Value: integer);
|
|
|
|
procedure SetWebsiteType2(Value: integer);
|
|
|
|
procedure SetZip1(const Value: string);
|
|
|
|
procedure SetZip2(const Value: string);
|
2016-09-16 23:42:31 +00:00
|
|
|
|
2008-02-03 12:05:55 +00:00
|
|
|
public
|
|
|
|
constructor Create(Owner: TVpContacts);
|
|
|
|
destructor Destroy; override;
|
2016-09-20 09:54:00 +00:00
|
|
|
function ContainsContactData: Boolean;
|
|
|
|
function ContainsWorkData: Boolean;
|
|
|
|
function ContainsHomeData: Boolean;
|
2016-09-06 19:59:25 +00:00
|
|
|
function FullName: string;
|
2022-08-18 17:44:47 +00:00
|
|
|
|
|
|
|
// VCards
|
|
|
|
function CreateVCard: TVpVCard;
|
2018-06-08 20:03:23 +00:00
|
|
|
procedure LoadFromVCard(ACard: TVpVCard);
|
2016-09-20 09:54:00 +00:00
|
|
|
|
2016-09-06 19:59:25 +00:00
|
|
|
property Loading: Boolean read FLoading write FLoading;
|
|
|
|
property Changed: Boolean read FChanged write SetChanged;
|
|
|
|
property Deleted: Boolean read FDeleted write SetDeleted;
|
|
|
|
property Owner: TVpContacts read FOwner write FOwner;
|
2022-08-19 10:53:49 +00:00
|
|
|
property PickedCategory: Integer read FPickedCategory write FPickedCategory;
|
2016-09-15 20:27:13 +00:00
|
|
|
|
2016-09-01 09:56:46 +00:00
|
|
|
{$ifdef WITHRTTI}
|
|
|
|
published
|
|
|
|
{$else}
|
|
|
|
public
|
|
|
|
{$endif}
|
2016-09-06 19:59:25 +00:00
|
|
|
property RecordID: Integer read FRecordID write SetRecordID;
|
|
|
|
property Job_Position: string read FPosition write SetPosition;
|
|
|
|
property Position: string read FPosition write SetPosition; deprecated 'Use "Job_Position" instead';
|
|
|
|
property FirstName: string read FFirstName write SetFirstName;
|
|
|
|
property LastName: string read FLastName write SetLastName;
|
|
|
|
property BirthDate: TDateTime read FBirthdate write SetBirthdate;
|
|
|
|
property Anniversary: TDateTime read FAnniversary write SetAnniversary;
|
|
|
|
property Title: string read FTitle write SetTitle;
|
|
|
|
property Company: string read FCompany write SetCompany;
|
2016-09-16 23:42:31 +00:00
|
|
|
property Department: String read FDepartment write SetDepartment;
|
2016-09-15 11:40:14 +00:00
|
|
|
property EMail: string read FEmail1 write SetEMail1; deprecated 'Use "EMail1" instead';
|
|
|
|
property EMail1: String read FEmail1 write SetEMail1;
|
|
|
|
property EMail2: String read FEmail2 write SetEmail2;
|
|
|
|
property EMail3: String read FEmail3 write SetEmail3;
|
|
|
|
property EMailType1: integer read FEMailType1 write SetEMailType1;
|
|
|
|
property EMailType2: integer read FEMailType2 write SetEMailType2;
|
|
|
|
property EMailType3: integer read FEMailType3 write SetEMailType3;
|
2016-09-06 19:59:25 +00:00
|
|
|
property Phone1: string read FPhone1 write SetPhone1;
|
|
|
|
property Phone2: string read FPhone2 write SetPhone2;
|
|
|
|
property Phone3: string read FPhone3 write SetPhone3;
|
|
|
|
property Phone4: string read FPhone4 write SetPhone4;
|
|
|
|
property Phone5: string read FPhone5 write SetPhone5;
|
|
|
|
property PhoneType1: integer read FPhoneType1 write SetPhoneType1;
|
|
|
|
property PhoneType2: integer read FPhoneType2 write SetPhoneType2;
|
|
|
|
property PhoneType3: integer read FPhoneType3 write SetPhoneType3;
|
|
|
|
property PhoneType4: integer read FPhoneType4 write SetPhoneType4;
|
|
|
|
property PhoneType5: integer read FPhoneType5 write SetPhoneType5;
|
2016-09-15 11:40:14 +00:00
|
|
|
property Website1: string read FWebsite1 write SetWebsite1;
|
|
|
|
property Website2: string read FWebsite2 write SetWebsite2;
|
|
|
|
property WebsiteType1: integer read FWebsiteType1 write SetWebsiteType1;
|
|
|
|
property WebsiteType2: integer read FWebsiteType2 write SetWebsiteType2;
|
|
|
|
property Address: string read FAddress1 write SetAddress1; deprecated 'Use "Address1" instead';
|
|
|
|
property Address1: string read FAddress1 write SetAddress1;
|
|
|
|
property Address2: string read FAddress2 write SetAddress2;
|
|
|
|
property City: string read FCity1 write SetCity1; deprecated 'Use "City1" instead';
|
|
|
|
property City1: string read FCity1 write SetCity1;
|
|
|
|
property City2: string read FCity2 write SetCity2;
|
|
|
|
property State: string read FState1 write SetState1; deprecated 'Use "State1" instead';
|
|
|
|
property State1: string read FState1 write SetState1;
|
|
|
|
property State2: string read FState2 write SetState2;
|
|
|
|
property Zip: string read FZip1 write SetZip1; deprecated 'Use "Zip1" instead';
|
|
|
|
property Zip1: string read FZip1 write SetZip1;
|
|
|
|
property Zip2: string read FZip2 write SetZip2;
|
|
|
|
property Country: string read FCountry1 write SetCountry1; deprecated 'Use "Country1" instead';
|
|
|
|
property Country1: string read FCountry1 write SetCountry1;
|
|
|
|
property Country2: string read FCountry2 write SetCountry2;
|
|
|
|
property AddressType1: integer read FAddressType1 write SetAddressType1;
|
|
|
|
property AddressType2: integer read FAddressType2 write SetAddressType2;
|
2016-09-06 19:59:25 +00:00
|
|
|
property Note: string read FNotes write SetNotes; deprecated 'Use "Notes" instead';
|
|
|
|
property Notes: string read FNotes write SetNotes;
|
|
|
|
property Category: integer read FCategory write SetCategory;
|
|
|
|
property Custom1: string read FCustom1 write SetCustom1;
|
|
|
|
property Custom2: string read FCustom2 write SetCustom2;
|
|
|
|
property Custom3: string read FCustom3 write SetCustom3;
|
|
|
|
property Custom4: string read FCustom4 write SetCustom4;
|
2008-02-03 12:05:55 +00:00
|
|
|
{ Reserved for your use }
|
2016-09-06 19:59:25 +00:00
|
|
|
property UserField0: string read FUserField0 write FUserField0;
|
|
|
|
property UserField1: string read FUserField1 write FUserField1;
|
|
|
|
property UserField2: string read FUserField2 write FUserField2;
|
|
|
|
property UserField3: string read FUserField3 write FUserField3;
|
|
|
|
property UserField4: string read FUserField4 write FUserField4;
|
|
|
|
property UserField5: string read FUserField5 write FUserField5;
|
|
|
|
property UserField6: string read FUserField6 write FUserField6;
|
|
|
|
property UserField7: string read FUserField7 write FUserField7;
|
|
|
|
property UserField8: string read FUserField8 write FUserField8;
|
|
|
|
property UserField9: string read FUserField9 write FUserField9;
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
2016-09-06 19:59:25 +00:00
|
|
|
function CompareEventsByTimeOnly(Item1, Item2: Pointer): Integer;
|
2016-06-30 18:45:39 +00:00
|
|
|
|
|
|
|
|
2008-02-03 12:05:55 +00:00
|
|
|
implementation
|
|
|
|
|
|
|
|
uses
|
2018-06-15 23:40:18 +00:00
|
|
|
Math, DateUtils,
|
2022-08-11 16:46:32 +00:00
|
|
|
VpException, VpConst, VpMisc, VpBaseDS,
|
2022-08-11 20:32:13 +00:00
|
|
|
VpImportPreview_ICalEvent, VpImportPreview_ICalTask, VpImportPreview_VCard;
|
2016-09-06 19:59:25 +00:00
|
|
|
|
|
|
|
const
|
|
|
|
TIME_EPS = 1.0 / SecondsInDay; // Epsilon for comparing times
|
|
|
|
|
|
|
|
{ Compare function for sorting resources: Compares the resource descriptions }
|
|
|
|
function CompareResources(Item1, Item2: Pointer): Integer;
|
|
|
|
begin
|
|
|
|
Result := CompareText(TVpResource(Item1).Description, TVpResource(Item2).Description);
|
|
|
|
// CompareTEXT --> ignore case
|
|
|
|
end;
|
|
|
|
|
|
|
|
{ Compare function for sorting events: Compares the start times of two events.
|
|
|
|
If the times are equal (within 1 seconds) then end times are compared. }
|
|
|
|
function CompareEvents(Item1, Item2: Pointer): Integer;
|
|
|
|
begin
|
|
|
|
if SameValue(TVpEvent(Item1).StartTime, TVpEvent(Item2).StartTime, TIME_EPS) then
|
|
|
|
Result := CompareValue(TVpEvent(Item1).EndTime, TVpEvent(Item2).EndTime)
|
|
|
|
else
|
|
|
|
Result := CompareValue(TVpEvent(Item1).StartTime, TVpEvent(Item2).StartTime);
|
|
|
|
end;
|
|
|
|
|
|
|
|
{ Call back function for TList.Sort. Sorting of events by time only, date part
|
|
|
|
is ignored. }
|
|
|
|
function CompareEventsByTimeOnly(Item1, Item2: Pointer): Integer;
|
|
|
|
var
|
|
|
|
event1, event2: TVpEvent;
|
|
|
|
begin
|
|
|
|
event1 := TVpEvent(Item1);
|
|
|
|
event2 := TVpEvent(Item2);
|
|
|
|
Result := CompareValue(frac(event1.StartTime), frac(event2.StartTime));
|
|
|
|
if Result = 0 then
|
|
|
|
Result := CompareValue(frac(event1.EndTime), frac(event2.EndTime));
|
|
|
|
end;
|
|
|
|
|
|
|
|
{ Compare function for sorting tasks: Compares the due dates. If they are equal
|
|
|
|
then the task descriptions are used. }
|
|
|
|
function CompareTasks(Item1, Item2: Pointer): Integer;
|
|
|
|
begin
|
|
|
|
if SameValue(TVpTask(Item1).DueDate, TVpTask(Item2).DueDate, TIME_EPS) then
|
|
|
|
Result := CompareText(TVpTask(Item1).Description, TVpTask(Item2).Description)
|
|
|
|
else
|
|
|
|
Result := CompareValue(TVpTask(Item1).DueDate, TVpTask(Item2).DueDate);
|
|
|
|
end;
|
|
|
|
|
2018-06-09 22:57:50 +00:00
|
|
|
function CompareContacts_Minors(Item1, Item2: Pointer): Integer;
|
|
|
|
begin
|
|
|
|
Result := CompareText(TVpContact(Item1).Email1, TVpContact(Item2).EMail1);
|
|
|
|
if Result = 0 then
|
|
|
|
Result := CompareText(TVpContact(Item1).Phone1, TVpContact(Item2).Phone1);
|
|
|
|
if Result = 0 then
|
|
|
|
Result := CompareText(TVpContact(Item1).Phone2, TVpContact(Item2).Phone2);
|
|
|
|
if Result = 0 then
|
|
|
|
Result := CompareText(TVpContact(Item1).Phone3, TVpContact(Item2).Phone3);
|
|
|
|
if Result = 0 then
|
|
|
|
Result := CompareText(TVpContact(Item1).Phone4, TVpContact(Item2).Phone4);
|
|
|
|
if Result = 0 then
|
|
|
|
Result := CompareText(TVpContact(Item1).Phone5, TVpContact(Item2).Phone5);
|
|
|
|
end;
|
|
|
|
|
2016-09-06 19:59:25 +00:00
|
|
|
{ Compare function for sorting contacts: Compare the first names of the contacts,
|
|
|
|
if equal compare the last names. }
|
|
|
|
function CompareContacts_FirstLast(Item1, Item2: Pointer): Integer;
|
|
|
|
begin
|
|
|
|
Result := CompareText(TVpContact(Item1).FirstName, TVpContact(Item2).Firstname);
|
|
|
|
if Result = 0 then
|
|
|
|
Result := CompareText(TVpContact(Item1).LastName, TVpContact(Item2).LastName);
|
2016-09-20 09:54:00 +00:00
|
|
|
if Result = 0 then
|
|
|
|
Result := CompareText(TVpContact(Item1).Company, TVpContact(Item2).Company);
|
2018-06-09 22:57:50 +00:00
|
|
|
if Result = 0 then
|
|
|
|
Result := CompareContacts_Minors(Item1, Item2);
|
2016-09-06 19:59:25 +00:00
|
|
|
end;
|
2008-02-03 12:05:55 +00:00
|
|
|
|
2016-09-06 19:59:25 +00:00
|
|
|
{ Compare function for sorting contacts: Compare the last names of the contacts,
|
|
|
|
if equal compare the first names. }
|
|
|
|
function CompareContacts_LastFirst(Item1, Item2: Pointer): Integer;
|
|
|
|
begin
|
|
|
|
Result := CompareText(TVpContact(Item1).LastName, TVpContact(Item2).Lastname);
|
|
|
|
if Result = 0 then
|
|
|
|
Result := CompareText(TVpContact(Item1).FirstName, TVpContact(Item2).FirstName);
|
2016-09-20 09:54:00 +00:00
|
|
|
if Result = 0 then
|
|
|
|
Result := CompareText(TVpContact(Item1).Company, TVpContact(Item2).Company);
|
2018-06-09 22:57:50 +00:00
|
|
|
if Result = 0 then
|
|
|
|
Result := CompareContacts_Minors(Item1, Item2);
|
2016-09-06 19:59:25 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
|
|
(*****************************************************************************)
|
2008-02-03 12:05:55 +00:00
|
|
|
{ TVpResources }
|
|
|
|
(*****************************************************************************)
|
|
|
|
|
|
|
|
constructor TVpResources.Create(Owner: TObject);
|
|
|
|
begin
|
|
|
|
inherited Create;
|
|
|
|
FOwner := Owner;
|
|
|
|
FResourceList := TList.Create;
|
2016-09-10 14:19:31 +00:00
|
|
|
FResourceGroups := TList.Create;
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
destructor TVpResources.Destroy;
|
|
|
|
begin
|
2016-09-10 14:19:31 +00:00
|
|
|
ClearResourceGroups;
|
|
|
|
FResourceGroups.Free;
|
|
|
|
|
2008-02-03 12:05:55 +00:00
|
|
|
ClearResources;
|
|
|
|
FResourceList.Free;
|
|
|
|
|
2016-09-10 14:19:31 +00:00
|
|
|
inherited;
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
2016-06-28 13:43:32 +00:00
|
|
|
function TVpResources.AddResource(ResID: Integer): TVpResource;
|
2008-02-03 12:05:55 +00:00
|
|
|
var
|
2016-09-06 19:59:25 +00:00
|
|
|
Resource: TVpResource;
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
|
|
|
Resource := TVpResource.Create(Self);
|
|
|
|
try
|
|
|
|
Resource.Loading := true;
|
2016-09-05 14:04:22 +00:00
|
|
|
FResourceList.Add(Resource);
|
2008-02-03 12:05:55 +00:00
|
|
|
Resource.ResourceID := ResID;
|
2016-06-12 12:53:26 +00:00
|
|
|
Resource.ResourceActive := true;
|
2008-02-03 12:05:55 +00:00
|
|
|
Resource.Loading := false;
|
2016-09-05 14:04:22 +00:00
|
|
|
Result := Resource;
|
2008-02-03 12:05:55 +00:00
|
|
|
except
|
|
|
|
Resource.Free;
|
|
|
|
raise EFailToCreateResource.Create;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2016-09-11 08:14:11 +00:00
|
|
|
function TVpResources.AddResourceGroup(const AResIDs: Array of Integer;
|
|
|
|
ACaption: String = ''): TVpResourceGroup;
|
2016-09-10 14:19:31 +00:00
|
|
|
var
|
|
|
|
grp: TVpResourceGroup;
|
2016-09-11 08:14:11 +00:00
|
|
|
res: TVpResource;
|
2016-09-10 14:19:31 +00:00
|
|
|
i: Integer;
|
|
|
|
begin
|
|
|
|
if Length(AResIDs) < 2 then
|
|
|
|
raise Exception.Create('Resource group must contain at least one additional resource.');
|
|
|
|
|
2016-09-11 08:14:11 +00:00
|
|
|
// Use resource descriptions if ACaption is not specified or empty.
|
|
|
|
if ACaption = '' then begin
|
|
|
|
for i:=Low(AResIDs) + 1 to High(AResIDs) do begin
|
|
|
|
res := GetResource(AResIDs[i]);
|
2016-09-14 22:39:33 +00:00
|
|
|
if res <> nil then
|
|
|
|
ACaption := ACaption + ', ' + res.Description;
|
2016-09-11 08:14:11 +00:00
|
|
|
end;
|
|
|
|
if ACaption <> '' then Delete(ACaption, 1, 2);
|
|
|
|
end;
|
|
|
|
|
2016-09-10 14:19:31 +00:00
|
|
|
// Enforce unique group name.
|
|
|
|
grp := FindResourceGroupByName(ACaption);
|
|
|
|
if grp = nil then begin
|
|
|
|
// Index 0 refers to the resource to which the other resources are added.
|
2016-09-11 08:14:11 +00:00
|
|
|
Result := TVpResourceGroup.Create(Self, AResIDs[0], ACaption);
|
2016-09-10 14:19:31 +00:00
|
|
|
FResourceGroups.Add(Result);
|
|
|
|
end else begin
|
|
|
|
grp.Clear; // Make sure that the group is empty before adding overlayed resources
|
|
|
|
Result := grp;
|
|
|
|
end;
|
|
|
|
for i:=1 to High(AResIDs) do
|
|
|
|
Result.AddID(AResIDs[i]);
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpResources.ClearResources;
|
|
|
|
begin
|
|
|
|
while FResourceList.Count > 0 do
|
|
|
|
TVpResource(FResourceList.Last).Free;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpResources.ClearResourceGroups;
|
|
|
|
begin
|
|
|
|
while FResourceGroups.Count > 0 do
|
|
|
|
TVpResourceGroup(FResourceGroups.Last).Free;
|
|
|
|
end;
|
|
|
|
|
2008-02-03 12:05:55 +00:00
|
|
|
function TVpResources.FindResourceByName (AName : string) : TVpResource;
|
|
|
|
var
|
2016-09-06 19:59:25 +00:00
|
|
|
i: Integer;
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
|
|
|
Result := nil;
|
2016-06-27 22:43:15 +00:00
|
|
|
AName := LowerCase(AName);
|
2008-02-03 12:05:55 +00:00
|
|
|
for i := 0 to Count - 1 do
|
2016-09-06 19:59:25 +00:00
|
|
|
if LowerCase(Items[i].Description) = AName then begin
|
2008-02-03 12:05:55 +00:00
|
|
|
Result := Items[i];
|
|
|
|
Break;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2016-09-10 14:19:31 +00:00
|
|
|
function TVpResources.FindResourceGroupByName(AName: String): TVpResourceGroup;
|
|
|
|
var
|
|
|
|
i: Integer;
|
|
|
|
begin
|
|
|
|
for i:=0 to FResourceGroups.Count-1 do begin
|
|
|
|
Result := TVpResourceGroup(FResourceGroups.Items[i]);
|
|
|
|
if Result.Caption = AName then
|
|
|
|
exit;
|
|
|
|
end;
|
|
|
|
Result := nil;
|
|
|
|
end;
|
|
|
|
|
|
|
|
function TVpResources.GetCount: Integer;
|
|
|
|
begin
|
|
|
|
Result := FResourceList.Count;
|
|
|
|
end;
|
|
|
|
|
|
|
|
function TVpResources.GetItem(Index: Integer): TVpResource;
|
|
|
|
begin
|
|
|
|
Result := TVpResource(FResourceList.List^[Index]);
|
|
|
|
end;
|
|
|
|
|
2008-02-03 12:05:55 +00:00
|
|
|
function TVpResources.GetResource(ID: integer): TVpResource;
|
|
|
|
var
|
|
|
|
I: Integer;
|
|
|
|
Res: TVpResource;
|
|
|
|
begin
|
|
|
|
result := nil;
|
|
|
|
for I := 0 to pred(FResourceList.Count) do begin
|
2018-06-15 23:40:18 +00:00
|
|
|
res := TVpResource(FResourceList.Items[I]);
|
2008-02-03 12:05:55 +00:00
|
|
|
if Res.ResourceID = ID then begin
|
|
|
|
result := Res;
|
|
|
|
Exit;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2016-09-10 14:19:31 +00:00
|
|
|
function TVpResources.GetResourceGroupCount: Integer;
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
2016-09-10 14:19:31 +00:00
|
|
|
Result := FResourceGroups.Count;
|
|
|
|
end;
|
|
|
|
|
|
|
|
function TVpResources.GetResourceGroup(Index: Integer): TVpResourceGroup;
|
|
|
|
begin
|
|
|
|
Result := TVpResourceGroup(FResourceGroups[Index]);
|
|
|
|
end;
|
|
|
|
|
|
|
|
function TVpResources.NextResourceID: Integer;
|
|
|
|
var
|
|
|
|
I : Integer;
|
|
|
|
ID: Integer;
|
|
|
|
Res: TVpResource;
|
|
|
|
begin
|
|
|
|
ID := 0;
|
|
|
|
for I := 0 to pred(FResourceList.Count) do begin
|
|
|
|
Res := GetResource(I);
|
|
|
|
if (Res <> nil)
|
|
|
|
and (ID <= Res.ResourceID) then
|
|
|
|
Inc(ID);
|
|
|
|
end;
|
|
|
|
Result := ID;
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpResources.RemoveResource(Resource: TVpREsource);
|
|
|
|
begin
|
2016-09-06 19:59:25 +00:00
|
|
|
// The resource removes the list entry in its destructor
|
2008-02-03 12:05:55 +00:00
|
|
|
Resource.Free;
|
|
|
|
end;
|
|
|
|
|
2016-09-10 14:19:31 +00:00
|
|
|
procedure TVpResources.RemoveResourceGroup(AGroup: TVpResourceGroup);
|
|
|
|
begin
|
|
|
|
// The resource group removes the list entry in its destructor.
|
|
|
|
AGroup.Free;
|
|
|
|
end;
|
|
|
|
|
2008-02-03 12:05:55 +00:00
|
|
|
procedure TVpResources.Sort;
|
|
|
|
begin
|
2016-09-06 19:59:25 +00:00
|
|
|
FResourceList.Sort(@CompareResources);
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
|
2016-09-06 19:59:25 +00:00
|
|
|
(*****************************************************************************)
|
2008-02-03 12:05:55 +00:00
|
|
|
{ TVpResource }
|
|
|
|
(*****************************************************************************)
|
2016-09-06 19:59:25 +00:00
|
|
|
|
2008-02-03 12:05:55 +00:00
|
|
|
constructor TVpResource.Create(Owner: TVpResources);
|
|
|
|
begin
|
|
|
|
inherited Create;
|
|
|
|
FOwner := Owner;
|
|
|
|
FSchedule := TVpSchedule.Create(Self);
|
|
|
|
FTasks := TVpTasks.Create(Self);
|
|
|
|
FContacts := TVpContacts.Create(Self);
|
|
|
|
FActive := false;
|
|
|
|
end;
|
|
|
|
|
|
|
|
destructor TVpResource.Destroy;
|
2016-09-05 14:04:22 +00:00
|
|
|
var
|
|
|
|
idx: Integer;
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
|
|
|
{ Clear and free the schedule, tasks and contacts }
|
|
|
|
FSchedule.ClearEvents;
|
|
|
|
FSchedule.Free;
|
|
|
|
FTasks.ClearTasks;
|
|
|
|
FTasks.Free;
|
|
|
|
FContacts.ClearContacts;
|
|
|
|
FContacts.Free;
|
|
|
|
|
|
|
|
{ remove self from Resources list }
|
2016-09-05 14:04:22 +00:00
|
|
|
if FOwner <> nil then begin
|
|
|
|
idx := FOwner.FResourceList.IndexOf(self);
|
|
|
|
if idx > -1 then FOwner.FResourceList.Delete(idx);
|
|
|
|
end;
|
2016-09-06 19:59:25 +00:00
|
|
|
|
2008-02-03 12:05:55 +00:00
|
|
|
inherited;
|
|
|
|
end;
|
|
|
|
|
2016-09-10 17:26:42 +00:00
|
|
|
{ Returns all resource groups attached to this resource }
|
|
|
|
procedure TVpResource.GetResourceGroups(AList: TList);
|
|
|
|
var
|
|
|
|
i: Integer;
|
|
|
|
grp: TVpResourceGroup;
|
|
|
|
begin
|
|
|
|
for i:=0 to Owner.ResourceGroupCount - 1 do begin
|
|
|
|
grp := Owner.ResourceGroups[i];
|
|
|
|
if grp.ResourceID = FResourceID then
|
|
|
|
AList.Add(grp);
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2021-12-04 19:01:07 +00:00
|
|
|
{ Overlays the resources listed in the array AResources and creates a
|
|
|
|
resource group named according to ACaption (or, if ACaption is empty, the
|
|
|
|
comma-separated list of the individual resource names).
|
|
|
|
If a resource group if this name already exists its contained resources are
|
|
|
|
replaced by the new ones.
|
|
|
|
When the array is empty, the overlay group with this caption is cleared. }
|
|
|
|
function TVpResource.OverlayResources(const AResources: TVpResourceArray;
|
|
|
|
ACaption: String = ''): TVpResourceGroup;
|
|
|
|
var
|
|
|
|
grp: TVpResourceGroup;
|
|
|
|
i: Integer;
|
|
|
|
begin
|
|
|
|
// Use resource descriptions if ACaption is not specified or empty.
|
|
|
|
if ACaption = '' then
|
|
|
|
begin
|
|
|
|
ACaption := FDescription;
|
|
|
|
for i := Low(AResources) to High(AResources) do
|
|
|
|
if AResources[i] <> nil then
|
|
|
|
ACaption := ACaption + ', ' + AResources[i].Description;
|
|
|
|
end;
|
|
|
|
|
|
|
|
// Enforce unique group name
|
|
|
|
grp := FOwner.FindResourceGroupByName(ACaption);
|
|
|
|
if grp = nil then
|
|
|
|
begin
|
|
|
|
grp := TVpResourceGroup.Create(FOwner, FResourceID, ACaption);
|
|
|
|
FOwner.FResourceGroups.Add(grp);
|
|
|
|
end else
|
|
|
|
grp.Clear; // Make sure that the group is empty before overlaying resources
|
|
|
|
|
|
|
|
// Add resources to group
|
|
|
|
for i := Low(AResources) to High(AResources) do
|
|
|
|
grp.AddID(AResources[i].ResourceID);
|
|
|
|
|
2021-12-06 22:34:33 +00:00
|
|
|
if grp.Count > 0 then
|
|
|
|
FGroup := grp
|
|
|
|
else
|
|
|
|
FGroup := nil;
|
|
|
|
Result := FGroup;
|
2021-12-04 19:01:07 +00:00
|
|
|
|
|
|
|
// Repaint the events
|
|
|
|
TVpCustomDatastore(FOwner.FOwner).RefreshEvents;
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
2008-02-03 12:05:55 +00:00
|
|
|
procedure TVpResource.SetContacts(const Value: TVpContacts);
|
|
|
|
begin
|
|
|
|
FContacts := Value;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpResource.SetChanged(Value: Boolean);
|
|
|
|
begin
|
|
|
|
if Loading then Exit;
|
|
|
|
|
|
|
|
if Value <> FChanged then begin
|
|
|
|
FChanged := Value;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpResource.SetDeleted(Value: Boolean);
|
|
|
|
begin
|
|
|
|
if FDeleted <> Value then begin
|
|
|
|
FDeleted := Value;
|
|
|
|
Changed := true;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
function TVpResource.GetSchedule: TVpSchedule;
|
|
|
|
begin
|
|
|
|
if FSchedule = nil then
|
|
|
|
FSchedule := TVpSchedule.Create(self);
|
|
|
|
result := FSchedule;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpResource.SetDescription(const Value: string);
|
|
|
|
begin
|
|
|
|
if Value <> FDescription then begin
|
2016-07-25 16:55:32 +00:00
|
|
|
if Assigned(Owner) then begin
|
|
|
|
if Owner.FindResourceByName(Value) <> nil then
|
2008-02-03 12:05:55 +00:00
|
|
|
raise EDuplicateResource.Create;
|
|
|
|
end;
|
|
|
|
|
|
|
|
FDescription := Value;
|
|
|
|
FChanged := true;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2016-09-10 18:27:50 +00:00
|
|
|
procedure TVpResource.SetGroup(const AValue: TVpResourceGroup);
|
2016-09-10 14:19:31 +00:00
|
|
|
begin
|
|
|
|
FGroup := AValue;
|
|
|
|
end;
|
|
|
|
|
2008-02-03 12:05:55 +00:00
|
|
|
procedure TVpResource.SetNotes(const Value: string);
|
|
|
|
begin
|
|
|
|
FNotes := Value;
|
|
|
|
FChanged := true;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpResource.SetResourceID(const Value: Integer);
|
|
|
|
begin
|
|
|
|
FResourceID := Value;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpResource.SetSchedule(const Value: TVpSchedule);
|
|
|
|
begin
|
|
|
|
FSchedule := Value;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpResource.SetTasks(const Value: TVpTasks);
|
|
|
|
begin
|
|
|
|
FTasks := Value;
|
|
|
|
end;
|
2016-09-06 19:59:25 +00:00
|
|
|
|
2008-02-03 12:05:55 +00:00
|
|
|
|
2016-09-10 14:19:31 +00:00
|
|
|
(*****************************************************************************)
|
|
|
|
{ TVpResourceGroup }
|
|
|
|
(*****************************************************************************)
|
2016-09-11 08:14:11 +00:00
|
|
|
constructor TVpResourceGroup.Create(AOwner: TVpResources; AResourceID: Integer;
|
|
|
|
ACaption: String);
|
2016-09-10 14:19:31 +00:00
|
|
|
begin
|
|
|
|
inherited Create;
|
|
|
|
FOwner := AOwner;
|
|
|
|
FResourceID := AResourceID;
|
|
|
|
FCaption := ACaption;
|
2016-09-10 20:08:06 +00:00
|
|
|
FPattern := opBDiagonal;
|
2016-09-11 08:14:11 +00:00
|
|
|
FReadOnly := true;
|
2021-12-04 19:01:07 +00:00
|
|
|
FShowDetails := [odResource, odEventDescription];
|
2016-09-10 14:19:31 +00:00
|
|
|
Clear;
|
|
|
|
end;
|
|
|
|
|
|
|
|
destructor TVpResourceGroup.Destroy;
|
|
|
|
var
|
|
|
|
idx: Integer;
|
|
|
|
begin
|
|
|
|
Clear;
|
|
|
|
{ remove self from Owner's resource group list }
|
|
|
|
if FOwner <> nil then begin
|
|
|
|
idx := FOwner.FResourceGroups.IndexOf(self);
|
|
|
|
if idx > -1 then FOwner.FResourceGroups.Delete(idx);
|
|
|
|
end;
|
|
|
|
inherited Destroy;
|
|
|
|
end;
|
|
|
|
|
|
|
|
function TVpResourceGroup.AddID(AResourceID: Integer): Integer;
|
|
|
|
begin
|
|
|
|
Result := -1;
|
|
|
|
if (AResourceID = FResourceID) then
|
|
|
|
exit;
|
|
|
|
Result := IndexOfID(AResourceID);
|
|
|
|
if Result = -1 then begin
|
|
|
|
SetLength(FIDs, Length(FIDs) + 1);
|
|
|
|
FIDs[High(FIDs)] := AResourceID;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
function TVpResourceGroup.AsString(ASeparator: Char = ';'): String;
|
|
|
|
var
|
|
|
|
list: TStrings;
|
|
|
|
i: Integer;
|
|
|
|
begin
|
|
|
|
list := TStringList.Create;
|
|
|
|
try
|
|
|
|
list.Delimiter := ASeparator;
|
|
|
|
list.StrictDelimiter := true;
|
|
|
|
list.Add(IntToStr(FResourceID));
|
|
|
|
for i:=0 to High(FIDs) do
|
|
|
|
list.Add(IntToStr(FIDs[i]));
|
|
|
|
Result := list.DelimitedText;
|
|
|
|
finally
|
|
|
|
list.Free;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpResourceGroup.Clear;
|
|
|
|
begin
|
|
|
|
SetLength(FIDs, 0);
|
|
|
|
end;
|
|
|
|
|
|
|
|
function TVpResourceGroup.GetCount: Integer;
|
|
|
|
begin
|
|
|
|
Result := Length(FIDs);
|
|
|
|
end;
|
|
|
|
|
|
|
|
function TVpResourceGroup.GetItem(AIndex: Integer): TVpResource;
|
|
|
|
begin
|
|
|
|
Result := FOwner.GetResource(FIDs[AIndex]);
|
|
|
|
end;
|
|
|
|
|
|
|
|
function TVpResourceGroup.IndexOfID(AResourceID: Integer): Integer;
|
|
|
|
var
|
|
|
|
i: Integer;
|
|
|
|
begin
|
|
|
|
for i := 0 to High(FIDs) do
|
|
|
|
if FIDs[i] = AResourceID then begin
|
|
|
|
Result := i;
|
|
|
|
exit;
|
|
|
|
end;
|
|
|
|
Result := -1;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpResourceGroup.Remove(AResourceID: Integer);
|
|
|
|
var
|
|
|
|
i: Integer;
|
|
|
|
begin
|
|
|
|
i := 0;
|
|
|
|
while i < Length(FIDs) do begin
|
|
|
|
if FIDs[i] = AResourceID then begin
|
|
|
|
inc(i);
|
|
|
|
while i < Length(FIDs) do begin
|
|
|
|
FIDs[i-1] := FIDs[i];
|
|
|
|
inc(i);
|
|
|
|
end;
|
|
|
|
SetLength(FIDs, Length(FIDs)-1);
|
|
|
|
exit;
|
|
|
|
end;
|
|
|
|
inc(i);
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2016-09-10 20:08:06 +00:00
|
|
|
procedure TVpResourceGroup.SetPattern(AValue: TVpOverlayPattern);
|
|
|
|
begin
|
|
|
|
if FPattern = AValue then
|
|
|
|
exit;
|
|
|
|
FPattern := AValue;
|
2016-09-11 13:35:19 +00:00
|
|
|
// to do: repaint the controls
|
2016-09-10 20:08:06 +00:00
|
|
|
end;
|
|
|
|
|
2016-09-11 13:35:19 +00:00
|
|
|
procedure TVpResourceGroup.SetShowDetails(AValue: TVpOverlayDetails);
|
|
|
|
begin
|
|
|
|
if FShowDetails = AValue then
|
|
|
|
exit;
|
|
|
|
FShowDetails := AValue;
|
|
|
|
// To do: repaint the controls
|
|
|
|
end;
|
2016-09-10 14:19:31 +00:00
|
|
|
|
|
|
|
(*****************************************************************************)
|
2008-02-03 12:05:55 +00:00
|
|
|
{ TVpEvent }
|
|
|
|
(*****************************************************************************)
|
|
|
|
constructor TVpEvent.Create(Owner: TVpSchedule);
|
|
|
|
begin
|
|
|
|
inherited Create;
|
|
|
|
FAlertDisplayed := false;
|
|
|
|
FOwner := Owner;
|
|
|
|
FChanged := false;
|
|
|
|
FSnoozeTime := 0.0;
|
|
|
|
end;
|
|
|
|
|
|
|
|
destructor TVpEvent.Destroy;
|
2016-09-05 14:04:22 +00:00
|
|
|
var
|
|
|
|
idx: Integer;
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
2016-09-05 14:04:22 +00:00
|
|
|
if (FOwner <> nil) then begin
|
|
|
|
idx := FOwner.FEventList.IndexOf(self);
|
2016-09-06 19:59:25 +00:00
|
|
|
if idx > -1 then FOwner.FEventList.Delete(idx);
|
2016-09-05 14:04:22 +00:00
|
|
|
end;
|
2008-02-03 12:05:55 +00:00
|
|
|
inherited;
|
|
|
|
end;
|
|
|
|
|
2016-09-10 19:06:41 +00:00
|
|
|
{ Returs false if the event cannot be edited. This is happens if the event is
|
|
|
|
overlayed and its resourcegroup is readonly }
|
|
|
|
function TVpEvent.CanEdit: Boolean;
|
|
|
|
var
|
|
|
|
res: TVpResource;
|
|
|
|
grp: TVpResourceGroup;
|
|
|
|
begin
|
|
|
|
Result := true;
|
|
|
|
if IsOverlayed then begin
|
|
|
|
res := GetResource;
|
|
|
|
if res <> nil then begin
|
|
|
|
grp := res.Group;
|
|
|
|
if grp.ReadOnly then Result := false;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2021-12-06 22:34:33 +00:00
|
|
|
function TVpEvent.CopyToSchedule(ASchedule: TVpSchedule): TVpEvent;
|
|
|
|
begin
|
|
|
|
Result := ASchedule.AddEvent(FResourceID, FStartTime, FEndTime);
|
|
|
|
// ResourceID will be assigned outside
|
|
|
|
Result.RecordID := FRecordID;
|
|
|
|
Result.DingPath := FDingPath;
|
|
|
|
Result.AlertDisplayed := FAlertDisplayed;
|
|
|
|
Result.AllDayEvent := FAllDayEvent;
|
|
|
|
Result.Description := FDescription;
|
|
|
|
Result.Notes := FNotes;
|
|
|
|
Result.Category := FCategory;
|
|
|
|
Result.AlarmSet := FAlarmSet;
|
|
|
|
Result.AlarmAdvance := FAlarmAdv;
|
|
|
|
Result.Location := FLocation;
|
|
|
|
Result.AlarmAdvanceType := FAlarmAdvType;
|
|
|
|
Result.SnoozeTime := FSnoozeTime;
|
|
|
|
Result.RepeatCode := FRepeatCode;
|
|
|
|
Result.RepeatRangeEnd := FRepeatRangeEnd;
|
|
|
|
Result.CustomInterval := FCustInterval;
|
|
|
|
Result.UserField0 := FUserField0;
|
|
|
|
Result.UserField1 := FUserField1;
|
|
|
|
Result.UserField2 := FUserField2;
|
|
|
|
Result.UserField3 := FUserField3;
|
|
|
|
Result.UserField4 := FUserField4;
|
|
|
|
Result.UserField5 := FUserField5;
|
|
|
|
Result.UserField6 := FUserField6;
|
|
|
|
Result.UserField7 := FUserField7;
|
|
|
|
Result.UserField8 := FUserField8;
|
|
|
|
Result.UserField8 := FUserField9;
|
|
|
|
end;
|
|
|
|
|
2022-08-20 17:06:03 +00:00
|
|
|
{ Warning: Recurrence and Alarm poorly tested... }
|
|
|
|
function TVpEvent.CreateICalEvent(ACalendar: TVpICalendar): TVpICalEvent;
|
|
|
|
var
|
|
|
|
datastore: TVpCustomDatastore;
|
|
|
|
begin
|
|
|
|
Result := TVpICalEvent.Create(ACalendar);
|
|
|
|
Result.Summary := FDescription;
|
|
|
|
Result.Description := FNotes;
|
|
|
|
Result.Location := FLocation;
|
|
|
|
|
|
|
|
Result.StartTime[false] := FStartTime;
|
|
|
|
Result.EndTime[false] := FEndTime + OneSecond;
|
|
|
|
|
|
|
|
datastore := TVpCustomDatastore(GetResource.Owner.Owner);
|
|
|
|
Result.Categories.Text := datastore.CategoryColorMap.GetCategoryName(FCategory);
|
|
|
|
|
|
|
|
Result.RecurrenceFrequency := '';
|
|
|
|
Result.RecurrenceInterval := 0;
|
|
|
|
Result.RecurrenceCount := 0;
|
|
|
|
Result.RecurrenceByXXX := '';
|
|
|
|
case FRepeatCode of
|
|
|
|
rtDaily:
|
|
|
|
begin
|
|
|
|
Result.RecurrenceFrequency := 'DAILY';
|
|
|
|
Result.RecurrenceInterval := 1;
|
|
|
|
if FRepeatRangeEnd <> FOREVER_DATE then
|
|
|
|
Result.RecurrenceCount := DaysBetween(DayOf(FRepeatRangeEnd), DayOf(FStartTime));
|
|
|
|
end;
|
|
|
|
rtWeekly:
|
|
|
|
begin
|
|
|
|
Result.RecurrenceFrequency := 'WEEKLY';
|
|
|
|
Result.RecurrenceInterval := 1;
|
|
|
|
if FRepeatRangeEnd <> FOREVER_DATE then
|
|
|
|
Result.RecurrenceCount := DaysBetween(DayOf(FRepeatRangeEnd), DayOf(FStartTime)) div 7;
|
|
|
|
end;
|
|
|
|
rtMonthlyByDay:
|
|
|
|
begin
|
|
|
|
Result.RecurrenceFrequency := 'MONTHLY';
|
|
|
|
Result.RecurrenceInterval := 1;
|
|
|
|
if FRepeatRangeEnd <> FOREVER_DATE then
|
|
|
|
Result.RecurrenceCount := DaysBetween(DayOf(FRepeatRangeEnd), DayOf(FStartTime)) div 30;
|
|
|
|
end;
|
|
|
|
rtMonthlyByDate:
|
|
|
|
begin
|
|
|
|
Result.RecurrenceFrequency := 'MONTHLY';
|
|
|
|
Result.RecurrenceInterval := 1;
|
|
|
|
if FRepeatRangeEnd <> FOREVER_DATE then
|
|
|
|
Result.RecurrenceCount := DaysBetween(DayOf(FRepeatRangeEnd), DayOf(FStartTime)) div 30;
|
|
|
|
end;
|
|
|
|
rtYearlyByDay:
|
|
|
|
begin
|
|
|
|
Result.RecurrenceFrequency := 'YEARLY';
|
|
|
|
Result.RecurrenceInterval := 1;
|
|
|
|
if FRepeatRangeEnd <> FOREVER_DATE then
|
|
|
|
Result.RecurrenceCount := DaysBetween(DayOf(FRepeatRangeEnd), DayOf(FStartTime)) div 365;
|
|
|
|
end;
|
|
|
|
rtYearlyByDate:
|
|
|
|
begin
|
|
|
|
Result.RecurrenceFrequency := 'YEARLY';
|
|
|
|
Result.RecurrenceInterval := 1;
|
|
|
|
if FRepeatRangeEnd <> FOREVER_DATE then
|
|
|
|
Result.RecurrenceCount := DaysBetween(DayOf(FRepeatRangeEnd), DayOf(FStartTime)) div 365;
|
|
|
|
end;
|
|
|
|
rtCustom:
|
|
|
|
begin
|
|
|
|
Result.RecurrenceFrequency := 'DAILY';
|
|
|
|
Result.RecurrenceInterval := FCustInterval;
|
|
|
|
if FRepeatRangeEnd <> FOREVER_DATE then
|
|
|
|
Result.RecurrenceCount := DaysBetween(DayOf(FRepeatRangeEnd), DayOf(FStartTime));
|
|
|
|
end;
|
|
|
|
else
|
|
|
|
;
|
|
|
|
end;
|
|
|
|
|
|
|
|
if AlarmSet then
|
|
|
|
begin
|
|
|
|
Result.UseAlarm(true);
|
|
|
|
Result.Alarm.Audio := (FDingPath <> '') and FileExists(FDingPath);
|
|
|
|
Result.Alarm.AudioSrc := FDingPath;
|
|
|
|
case FAlarmAdvType of
|
|
|
|
atMinutes: Result.Alarm.Trigger := FAlarmAdv * OneMinute;
|
|
|
|
atHours: Result.Alarm.Trigger := FAlarmAdv * OneHour;
|
|
|
|
atDays: Result.Alarm.Trigger := FAlarmAdv;
|
|
|
|
end;
|
|
|
|
Result.Alarm.RepeatCount := 1;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2022-08-20 19:11:37 +00:00
|
|
|
{ Returns the Description of the categoy associated with the event. }
|
|
|
|
function TVpEvent.GetCategoryName: String;
|
|
|
|
var
|
|
|
|
res: TVpResource;
|
|
|
|
store: TVpCustomDatastore;
|
|
|
|
begin
|
|
|
|
Result := '';
|
|
|
|
if (FCategory < 0) or (FCategory > 9) then
|
|
|
|
exit;
|
|
|
|
res := GetResource;
|
|
|
|
if res = nil then
|
|
|
|
exit;
|
|
|
|
store := TVpCustomDatastore(res.Owner.Owner);
|
|
|
|
if store = nil then
|
|
|
|
exit;
|
|
|
|
Result := store.CategoryColorMap.GetCategoryName(FCategory);
|
|
|
|
end;
|
|
|
|
|
2016-09-10 19:06:41 +00:00
|
|
|
{ Returns the resource to which the event belongs. }
|
|
|
|
function TVpEvent.GetResource: TVpResource;
|
|
|
|
begin
|
|
|
|
Result := FOwner.Owner;
|
|
|
|
end;
|
|
|
|
|
2016-09-10 15:09:23 +00:00
|
|
|
{ The event is overlayed if its ResourceID is different from that of the
|
|
|
|
resource to which it belongs. }
|
|
|
|
function TVpEvent.IsOverlayed: Boolean;
|
|
|
|
var
|
|
|
|
res: TVpResource; // resource to which the event belongs
|
|
|
|
begin
|
|
|
|
Result := false;
|
2016-09-11 08:23:51 +00:00
|
|
|
if (FOwner <> nil) and (FResourceID > 0) then begin
|
2016-09-10 15:09:23 +00:00
|
|
|
res := FOwner.FOwner;
|
|
|
|
if (res <> nil) and (res.ResourceID <> FResourceID) then
|
|
|
|
Result := true;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2018-06-15 23:40:18 +00:00
|
|
|
function IsInteger(d, Epsilon: Double): Boolean;
|
|
|
|
begin
|
|
|
|
Result := abs(d - round(d)) < Epsilon;
|
|
|
|
end;
|
|
|
|
|
2022-08-10 10:20:56 +00:00
|
|
|
class procedure TVpEvent.GetAlarmParams(ATrigger: TDateTime; out AdvTime: Integer;
|
|
|
|
out AdvTimeUnits: TVpAlarmAdvType);
|
|
|
|
var
|
|
|
|
dt: TDateTime;
|
|
|
|
begin
|
|
|
|
dt := abs(ATrigger);
|
|
|
|
if IsInteger(dt, 1.0 / SecondsInDay) then begin
|
|
|
|
AdvTimeUnits := atDays;
|
|
|
|
AdvTime := round(dt);
|
|
|
|
end else
|
|
|
|
if IsInteger(dt*HoursInDay, HoursInDay / SecondsInDay) then begin
|
|
|
|
AdvTimeUnits := atHours;
|
|
|
|
AdvTime := round(dt * HoursInDay);
|
|
|
|
end else begin
|
|
|
|
AdvTimeUnits := atMinutes;
|
|
|
|
AdvTime := round(dt * MinutesInDay);
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2018-06-15 23:40:18 +00:00
|
|
|
procedure TVpEvent.LoadFromICalendar(AEntry: TVpICalEvent);
|
|
|
|
var
|
2018-06-16 23:07:26 +00:00
|
|
|
cat: String;
|
|
|
|
i, j, k: Integer;
|
|
|
|
datastore: TVpCustomDatastore;
|
2018-06-15 23:40:18 +00:00
|
|
|
begin
|
|
|
|
if AEntry = nil then
|
|
|
|
exit;
|
|
|
|
|
|
|
|
{ Standard event properties }
|
|
|
|
FDescription := AEntry.Summary;
|
|
|
|
FNotes := AEntry.Description;
|
|
|
|
FLocation := AEntry.Location;
|
|
|
|
// Start and end time already have been set --> Skip .
|
|
|
|
|
2018-06-16 23:07:26 +00:00
|
|
|
{ Category }
|
|
|
|
{ tvplanit has only 1 category, ical may have several. We pick the first one
|
|
|
|
defined in the datastore. If none is defined we create the first one. }
|
2022-08-12 09:50:18 +00:00
|
|
|
if AEntry.PickedCategory > -1 then
|
|
|
|
FCategory := AEntry.PickedCategory
|
|
|
|
else
|
2018-06-16 23:07:26 +00:00
|
|
|
if AEntry.CategoryCount > 0 then begin
|
|
|
|
datastore := TVpCustomDatastore(Owner.Owner.Owner.Owner);
|
|
|
|
k := -1;
|
|
|
|
for i := 0 to AEntry.CategoryCount-1 do begin
|
2022-08-10 21:21:17 +00:00
|
|
|
cat := AEntry.Category[i];
|
2018-06-16 23:07:26 +00:00
|
|
|
j := datastore.CategoryColorMap.IndexOfCategory(cat);
|
|
|
|
if j <> -1 then begin
|
|
|
|
k := j;
|
|
|
|
break;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
if k = -1 then begin // category not found in data store
|
|
|
|
k := datastore.CategoryColorMap.IndexOfFirstUnusedCategory;
|
|
|
|
if k <> -1 then
|
|
|
|
datastore.CategoryColorMap.SetCategoryName(k, AEntry.Category[0]);
|
|
|
|
end;
|
|
|
|
if k <> -1 then
|
|
|
|
FCategory := k;
|
|
|
|
end;
|
|
|
|
|
2018-06-15 23:40:18 +00:00
|
|
|
{ All-day event }
|
2022-08-12 10:34:40 +00:00
|
|
|
FAllDayEvent := AEntry.IsAllDayEvent;
|
2018-06-15 23:40:18 +00:00
|
|
|
|
|
|
|
{ Alarm properties }
|
|
|
|
if AEntry.Alarm <> nil then begin
|
|
|
|
FAlarmSet := true;
|
2022-08-10 10:20:56 +00:00
|
|
|
GetAlarmParams(AEntry.Alarm.Trigger, FAlarmAdv, FAlarmAdvType);
|
2018-06-15 23:40:18 +00:00
|
|
|
FDingPath := AEntry.Alarm.AudioSrc;
|
|
|
|
if not FileExists(FDingPath) then FDingPath := '';
|
|
|
|
end else
|
|
|
|
FAlarmSet := false;
|
|
|
|
|
|
|
|
{ Recurrence }
|
|
|
|
FRepeatCode := rtNone;
|
|
|
|
FRepeatRangeEnd := 0;
|
|
|
|
case AEntry.RecurrenceFrequency of
|
|
|
|
'YEARLY':
|
|
|
|
if AEntry.RecurrenceInterval = 0 then
|
|
|
|
FRepeatCode := rtYearlyByDate // or rtYearlyByDay ?
|
|
|
|
else begin
|
|
|
|
FRepeatCode := rtCustom;
|
|
|
|
FCustInterval := AEntry.RecurrenceInterval * 365; // * SecondsInDay;
|
|
|
|
end;
|
|
|
|
'MONTHLY':
|
|
|
|
if AEntry.RecurrenceInterval = 0 then
|
|
|
|
FRepeatCode := rtMonthlyByDate // or rtMonthlyByDay ?
|
|
|
|
else begin
|
|
|
|
FRepeatCode := rtCustom;
|
|
|
|
FCustInterval := AEntry.RecurrenceInterval * 30; // * SecondsInDay;
|
|
|
|
end;
|
|
|
|
'WEEKLY':
|
|
|
|
if AEntry.RecurrenceInterval = 0 then
|
|
|
|
FRepeatCode := rtWeekly
|
|
|
|
else begin
|
|
|
|
FRepeatCode := rtCustom;
|
|
|
|
FCustInterval := AEntry.RecurrenceInterval * 7; // * SecondsInDay;
|
|
|
|
end;
|
|
|
|
'DAILY':
|
|
|
|
if AEntry.RecurrenceInterval = 0 then
|
|
|
|
FRepeatCode := rtDaily
|
|
|
|
else begin
|
|
|
|
FRepeatCode := rtCustom;
|
|
|
|
FCustInterval := AEntry.RecurrenceInterval; // * SecondsInDay;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
if (AEntry.RecurrenceEndDate = 0) and (AEntry.RecurrenceCount > 0) then begin
|
|
|
|
FRepeatRangeEnd := trunc(FStartTime);
|
|
|
|
case FRepeatCode of
|
|
|
|
rtYearlyByDate:
|
|
|
|
FRepeatRangeEnd := IncYear(FRepeatRangeEnd, AEntry.RecurrenceCount);
|
|
|
|
rtMonthlyByDate:
|
|
|
|
FRepeatRangeEnd := IncMonth(FRepeatRangeEnd, AEntry.RecurrenceCount);
|
|
|
|
rtWeekly:
|
|
|
|
FRepeatRangeEnd := FRepeatRangeEnd + 7 * AEntry.RecurrenceCount;
|
|
|
|
rtDaily:
|
|
|
|
FRepeatRangeEnd := FRepeatRangeEnd + AEntry.RecurrenceCount;
|
|
|
|
end;
|
|
|
|
end else
|
|
|
|
FRepeatRangeEnd := AEntry.RecurrenceEndDate;
|
|
|
|
end;
|
|
|
|
|
2008-02-03 12:05:55 +00:00
|
|
|
procedure TVpEvent.SetAlarmAdv(Value: Integer);
|
|
|
|
begin
|
|
|
|
if Value <> FAlarmAdv then begin
|
|
|
|
FAlarmAdv := Value;
|
|
|
|
Changed := true;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpEvent.SetAlarmAdvType(Value: TVpAlarmAdvType);
|
|
|
|
begin
|
|
|
|
if Value <> FAlarmAdvType then begin
|
|
|
|
FAlarmAdvType := Value;
|
|
|
|
Changed := true;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpEvent.SetSnoozeTime(Value: TDateTime);
|
|
|
|
begin
|
|
|
|
if Value <> FSnoozeTime then begin
|
|
|
|
FSnoozeTime := Value;
|
|
|
|
Changed := true;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpEvent.SetAlarmSet(Value: Boolean);
|
|
|
|
begin
|
|
|
|
if Value <> FAlarmSet then begin
|
|
|
|
FAlarmSet := Value;
|
|
|
|
Changed := true;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpEvent.SetCategory(Value: Integer);
|
|
|
|
begin
|
|
|
|
if Value <> FCategory then begin
|
|
|
|
FCategory := Value;
|
|
|
|
Changed := true;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpEvent.SetDescription(const Value: string);
|
|
|
|
begin
|
|
|
|
if Value <> FDescription then begin
|
|
|
|
FDescription := Value;
|
|
|
|
Changed := true;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpEvent.SetEndTime(Value: TDateTime);
|
|
|
|
begin
|
|
|
|
if Value <> FEndTIme then begin
|
|
|
|
FEndTime := Value;
|
|
|
|
Changed := true;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpEvent.SetAllDayEvent(Value: Boolean);
|
|
|
|
begin
|
2009-12-24 22:41:52 +00:00
|
|
|
if Value <> FAllDayEvent then
|
2022-08-20 19:11:37 +00:00
|
|
|
begin
|
|
|
|
FAllDayEvent := Value;
|
|
|
|
Changed := true;
|
|
|
|
end;
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpEvent.SetChanged(Value: Boolean);
|
|
|
|
begin
|
|
|
|
if Loading then Exit;
|
|
|
|
|
|
|
|
if Value <> FChanged then begin
|
|
|
|
FChanged := Value;
|
|
|
|
if FChanged then
|
|
|
|
Owner.FOwner.EventsDirty := true;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpEvent.SetDeleted(Value: Boolean);
|
|
|
|
begin
|
|
|
|
if Value <> FDeleted then begin
|
|
|
|
FDeleted := Value;
|
|
|
|
Changed := true;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpEvent.SetDingPath(Value: string);
|
|
|
|
begin
|
|
|
|
if Value <> FDingPath then begin
|
|
|
|
FDingPath := Value;
|
|
|
|
Changed := true;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2016-06-11 14:09:10 +00:00
|
|
|
procedure TVpEvent.SetLocation(const Value: String);
|
|
|
|
begin
|
|
|
|
if Value <> FLocation then begin
|
|
|
|
FLocation := Value;
|
|
|
|
Changed := true;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpEvent.SetNotes(const Value: string);
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
2016-06-11 14:09:10 +00:00
|
|
|
if Value <> FNotes then begin
|
|
|
|
FNotes := Value;
|
2008-02-03 12:05:55 +00:00
|
|
|
Changed := true;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2016-06-28 13:43:32 +00:00
|
|
|
procedure TVpEvent.SetRecordID(Value: Integer);
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
|
|
|
if Value <> FRecordID then begin
|
|
|
|
FRecordID := Value;
|
|
|
|
Changed := true;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpEvent.SetRepeatCode(Value: TVpRepeatType);
|
|
|
|
begin
|
|
|
|
{ rtNone, rtDaily, rtWeekly, rtMonthlyByDay, rtMonthlyByDate, }
|
|
|
|
{ rtYearlyByDay, rtYearlyByDate, rtCustom }
|
|
|
|
if Value <> FRepeatCode then begin
|
|
|
|
FRepeatCode := Value;
|
|
|
|
if value <> rtCustom then
|
|
|
|
SetCustInterval(0);
|
|
|
|
Changed := true;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpEvent.SetRepeatRangeEnd(Value: TDateTime);
|
|
|
|
begin
|
|
|
|
if Value > StartTime then begin
|
|
|
|
FRepeatRangeEnd := Value;
|
|
|
|
Changed := true;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpEvent.SetCustInterval(Value: Integer);
|
|
|
|
begin
|
|
|
|
if Value <> FCustInterval then begin
|
|
|
|
if RepeatCode = rtCustom then
|
|
|
|
FCustInterval := Value
|
|
|
|
else
|
|
|
|
FCustInterval := 0;
|
|
|
|
Changed := true;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpEvent.SetStartTime(Value: TDateTime);
|
|
|
|
begin
|
|
|
|
if Value <> FStartTIme then begin
|
|
|
|
FStartTime := Value;
|
|
|
|
Changed := true;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2016-09-06 19:59:25 +00:00
|
|
|
|
|
|
|
(*****************************************************************************)
|
2008-02-03 12:05:55 +00:00
|
|
|
{ TVpSchedule }
|
|
|
|
(*****************************************************************************)
|
2016-09-06 19:59:25 +00:00
|
|
|
|
2008-02-03 12:05:55 +00:00
|
|
|
constructor TVpSchedule.Create(Owner: TVpResource);
|
|
|
|
begin
|
|
|
|
inherited Create;
|
|
|
|
FOwner := Owner;
|
|
|
|
FBatchUpdate := 0;
|
|
|
|
FEventList := TList.Create;
|
|
|
|
end;
|
|
|
|
|
|
|
|
destructor TVpSchedule.Destroy;
|
|
|
|
begin
|
|
|
|
ClearEvents;
|
|
|
|
FEventList.Free;
|
|
|
|
inherited;
|
|
|
|
end;
|
|
|
|
|
2016-09-06 19:59:25 +00:00
|
|
|
procedure TVpSchedule.Sort;
|
|
|
|
begin
|
|
|
|
{ for greater performance, we don't sort while doing batch updates. }
|
|
|
|
if FBatchUpdate > 0 then
|
|
|
|
exit;
|
|
|
|
|
|
|
|
{ WARNING!! The DayView component is heavily dependent upon the events
|
|
|
|
being properly sorted. Sorting is based on the CompareEventTimes function.
|
|
|
|
If you change the way this procedure works, you WILL break the DayView
|
|
|
|
component!!! }
|
|
|
|
FEventList.Sort(@CompareEvents);
|
|
|
|
end;
|
|
|
|
|
2008-02-03 12:05:55 +00:00
|
|
|
{Adds the event to the eventlist and returns a pointer to it, or nil on failure}
|
2016-06-28 13:43:32 +00:00
|
|
|
function TVpSchedule.AddEvent(RecordID: Integer; StartTime,
|
2008-02-03 12:05:55 +00:00
|
|
|
EndTime: TDateTime): TVpEvent;
|
|
|
|
begin
|
2018-06-15 23:40:18 +00:00
|
|
|
Result := TVpEvent.Create(Self);
|
|
|
|
try
|
|
|
|
Result.Loading := true;
|
|
|
|
FEventList.Add(Result);
|
|
|
|
Result.RecordID := RecordID;
|
|
|
|
Result.StartTime := StartTime;
|
|
|
|
Result.EndTime := EndTime;
|
|
|
|
Result.Loading := false;
|
|
|
|
Sort;
|
|
|
|
except
|
|
|
|
Result.Free;
|
|
|
|
raise EFailToCreateEvent.Create;
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpSchedule.ClearEvents;
|
|
|
|
begin
|
|
|
|
BatchUpdate(true);
|
|
|
|
try
|
|
|
|
while FEventList.Count > 0 do
|
|
|
|
TVpEvent(FEventList.Last).Free;
|
|
|
|
finally
|
|
|
|
BatchUpdate(false);
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2016-09-10 15:09:23 +00:00
|
|
|
procedure TVpSchedule.ClearGroupEvents;
|
|
|
|
var
|
|
|
|
i: Integer;
|
|
|
|
event: TVpEvent;
|
|
|
|
begin
|
|
|
|
for i := FEventList.Count-1 downto 0 do begin
|
|
|
|
event := TVpEvent(FEventList[i]);
|
|
|
|
if event.IsOverlayed then begin
|
|
|
|
FEventList.Delete(i);
|
|
|
|
event.Free;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2008-02-03 12:05:55 +00:00
|
|
|
procedure TVpSchedule.BatchUpdate(Value: Boolean);
|
|
|
|
begin
|
|
|
|
if Value then
|
|
|
|
FBatchUpdate := FBatchUpdate + 1
|
|
|
|
else
|
|
|
|
FBatchUpdate := FBatchUpdate - 1;
|
|
|
|
|
|
|
|
if FBatchUpdate < 1 then begin
|
|
|
|
FBatchUpdate := 0;
|
|
|
|
Sort;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2016-09-06 19:59:25 +00:00
|
|
|
{ Initiates destruction of the specified event which also removes it from the
|
|
|
|
list. }
|
2008-02-03 12:05:55 +00:00
|
|
|
procedure TVpSchedule.DeleteEvent(Event: TVpEvent);
|
|
|
|
begin
|
|
|
|
Event.Deleted := true;
|
|
|
|
Owner.EventsDirty := true;
|
|
|
|
end;
|
|
|
|
|
2016-06-28 13:43:32 +00:00
|
|
|
function TVpSchedule.GetEvent(Index: Integer): TVpEvent;
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
|
|
|
{ Returns an event on success or nil on failure }
|
2018-06-15 23:40:18 +00:00
|
|
|
result := TVpEvent(FEventList[Index]);
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
2022-08-20 17:06:03 +00:00
|
|
|
procedure TVpSchedule.ExportICalFile(const AFileName: String;
|
|
|
|
const AEvents: TVpEventArr);
|
|
|
|
var
|
|
|
|
cal: TVpICalendar;
|
|
|
|
lEvent: TVpEvent;
|
|
|
|
begin
|
|
|
|
cal := TVpICalendar.Create;
|
|
|
|
try
|
|
|
|
for lEvent in AEvents do
|
|
|
|
if lEvent <> nil then
|
|
|
|
cal.Add(lEvent.CreateICalEvent(cal));
|
|
|
|
cal.SaveToFile(AFileName);
|
|
|
|
finally
|
|
|
|
cal.Free;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2022-08-10 10:20:56 +00:00
|
|
|
function TVpSchedule.ImportICalFile(const AFileName: String;
|
|
|
|
APreview: Boolean = false; ADefaultCategory: Integer = -1): TVpEventArr;
|
2022-08-05 20:12:52 +00:00
|
|
|
const
|
|
|
|
BLOCK_SIZE = 10;
|
|
|
|
var
|
|
|
|
ical: TVpICalendar;
|
|
|
|
startTime, endTime: TDateTime;
|
|
|
|
i: Integer;
|
|
|
|
id: Integer;
|
|
|
|
event: TVpEvent;
|
|
|
|
eventCounter: Integer;
|
|
|
|
datastore: TVpCustomDatastore;
|
2022-08-11 16:46:32 +00:00
|
|
|
previewForm: TVpImportPreviewICalEventForm = nil;
|
2022-08-05 20:12:52 +00:00
|
|
|
begin
|
|
|
|
Result := nil;
|
|
|
|
SetLength(Result, BLOCK_SIZE);
|
|
|
|
datastore := Owner.Owner.Owner as TVpCustomDatastore;
|
2022-08-10 10:20:56 +00:00
|
|
|
eventCounter := 0;
|
|
|
|
|
2022-08-05 20:12:52 +00:00
|
|
|
ical := TVpICalendar.Create;
|
|
|
|
try
|
|
|
|
ical.LoadFromFile(AFileName);
|
2022-08-10 21:21:17 +00:00
|
|
|
if ical.EventCount = 0 then
|
|
|
|
begin
|
|
|
|
MessageDlg(Format(RSNoEventItemsFoundInICAL, [AFileName]), mtInformation, [mbOK], 0);
|
|
|
|
exit;
|
|
|
|
end;
|
2022-08-10 10:20:56 +00:00
|
|
|
if APreview then
|
|
|
|
begin
|
2022-08-11 16:46:32 +00:00
|
|
|
previewForm := TVpImportPreviewICalEventForm.Create(nil);
|
2022-08-10 10:20:56 +00:00
|
|
|
previewForm.Position := poMainFormCenter;
|
|
|
|
previewForm.Datastore := datastore;
|
2022-08-12 09:50:18 +00:00
|
|
|
previewForm.Calendar := ical;
|
2022-08-10 10:20:56 +00:00
|
|
|
if ADefaultCategory <> -1 then
|
|
|
|
previewForm.DefaultCategory := datastore.CategoryColorMap.GetCategoryName(ADefaultCategory);
|
|
|
|
if not previewForm.Execute then
|
2022-08-10 21:21:17 +00:00
|
|
|
begin
|
|
|
|
SetLength(Result, 0);
|
2022-08-10 10:20:56 +00:00
|
|
|
exit;
|
2022-08-10 21:21:17 +00:00
|
|
|
end;
|
2022-08-10 10:20:56 +00:00
|
|
|
end;
|
|
|
|
|
2022-08-05 20:12:52 +00:00
|
|
|
for i := 0 to ical.Count-1 do begin
|
2022-08-19 14:06:54 +00:00
|
|
|
if (not ical[i].Checked) or (not (ical[i] is TVpICalEvent)) then
|
2022-08-05 20:12:52 +00:00
|
|
|
Continue;
|
|
|
|
startTime := TVpICalEvent(ical[i]).StartTime[false]; // use local times
|
|
|
|
endTime := TVpICalEvent(ical[i]).EndTime[false];
|
2022-08-12 10:34:40 +00:00
|
|
|
if startTime = NO_DATE then
|
2022-08-05 20:12:52 +00:00
|
|
|
continue;
|
|
|
|
id := dataStore.GetNextID(EventsTableName);
|
2022-08-12 10:34:40 +00:00
|
|
|
event := AddEvent(id, starttime, endtime - OneSecond);
|
2022-08-05 20:12:52 +00:00
|
|
|
event.Changed := true;
|
|
|
|
event.LoadFromICalendar(TVpICalEvent(ical[i]));
|
|
|
|
if (event.Category = 0) and (ADefaultCategory <> -1) then
|
|
|
|
event.Category := ADefaultCategory;
|
|
|
|
Result[eventCounter] := event;
|
|
|
|
inc(eventCounter);
|
|
|
|
if eventCounter mod BLOCK_SIZE = 0 then
|
|
|
|
SetLength(Result, eventCounter + BLOCK_SIZE);
|
|
|
|
end;
|
2022-08-10 10:20:56 +00:00
|
|
|
SetLength(Result, eventCounter);
|
2022-08-10 21:21:17 +00:00
|
|
|
if Length(Result) = 0 then
|
|
|
|
MessageDlg(Format(RSNoEventItemsFoundInICAL, [AFileName]), mtInformation, [mbOK], 0);
|
|
|
|
finally
|
2022-08-10 10:20:56 +00:00
|
|
|
if APreview then
|
|
|
|
previewForm.Free;
|
2022-08-05 20:12:52 +00:00
|
|
|
ical.Free;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2008-02-03 12:05:55 +00:00
|
|
|
function TVpSchedule.RepeatsOn(Event: TVpEvent; Day: TDateTime): Boolean;
|
|
|
|
var
|
|
|
|
EY, EM, ED: Word;
|
|
|
|
NY, NM, ND: Word;
|
|
|
|
EventWkDay, EventDayCount: Word;
|
|
|
|
ThisWkDay, ThisDayCount: Word;
|
|
|
|
EventJulian, ThisJulian: Word;
|
2018-06-15 23:40:18 +00:00
|
|
|
DayInRepeatRange: Boolean;
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
|
|
|
result := false;
|
|
|
|
|
2018-06-15 23:40:18 +00:00
|
|
|
DayInRepeatRange := (Day > trunc(Event.StartTime)) and
|
|
|
|
((Event.RepeatRangeEnd = 0) or (Day < trunc(Event.RepeatRangeEnd) + 1));
|
|
|
|
|
|
|
|
if (Event.RepeatCode <> rtNone) and
|
|
|
|
((Event.RepeatRangeEnd = 0) or (trunc(Event.RepeatRangeEnd + 1) > now)) then
|
2016-07-04 09:55:08 +00:00
|
|
|
begin
|
2008-02-03 12:05:55 +00:00
|
|
|
case Event.RepeatCode of
|
|
|
|
rtDaily:
|
2018-06-15 23:40:18 +00:00
|
|
|
if DayInRepeatRange then
|
|
|
|
// if (Day < trunc(Event.RepeatRangeEnd) + 1) and (Day > trunc(Event.StartTime)) then
|
2008-02-03 12:05:55 +00:00
|
|
|
result := true;
|
|
|
|
|
|
|
|
rtWeekly:
|
2018-06-15 23:40:18 +00:00
|
|
|
if DayInRepeatRange then
|
|
|
|
// if (Day < trunc(Event.RepeatRangeEnd) + 1) and (Day > trunc(Event.StartTime)) then
|
2008-02-03 12:05:55 +00:00
|
|
|
result := (Trunc(Day) - Trunc(Event.StartTime)) mod 7 = 0;
|
|
|
|
|
|
|
|
rtMonthlyByDay:
|
2018-06-15 23:40:18 +00:00
|
|
|
if DayInRepeatRange then
|
|
|
|
//if (Day < trunc(Event.RepeatRangeEnd) + 1) and (Day > trunc(Event.StartTime)) then
|
2016-07-04 09:55:08 +00:00
|
|
|
begin
|
2016-09-06 19:59:25 +00:00
|
|
|
// Get the year, month and day of the first event in the series
|
2008-02-03 12:05:55 +00:00
|
|
|
DecodeDate(Event.StartTime, EY, EM, ED);
|
2016-09-06 19:59:25 +00:00
|
|
|
// Get the weekday of the first event in the series
|
2008-02-03 12:05:55 +00:00
|
|
|
EventWkDay := DayOfWeek(Event.StartTime);
|
2016-09-06 19:59:25 +00:00
|
|
|
// Get the occurence of the first event in the series (First Monday, Third Monday, etc...)
|
2008-02-03 12:05:55 +00:00
|
|
|
EventDayCount := ED div 7 + 1;
|
2016-09-06 19:59:25 +00:00
|
|
|
// Get the year, month and day of the "Day" parameter
|
2008-02-03 12:05:55 +00:00
|
|
|
DecodeDate(Day, NY, NM, ND);
|
2016-09-06 19:59:25 +00:00
|
|
|
// Get the weekday of the "Day" parameter
|
2008-02-03 12:05:55 +00:00
|
|
|
ThisWkDay := DayOfWeek(Day);
|
2016-09-06 19:59:25 +00:00
|
|
|
// Get the weekday occurence of the "Day" parameter (First Monday, Third Monday, etc...)
|
2008-02-03 12:05:55 +00:00
|
|
|
ThisDayCount := ND div 7 + 1;
|
2016-09-06 19:59:25 +00:00
|
|
|
// If (ThisWeekDay is equal to EventWkDay) and (ThisDayCount is equal to EventDayCount)
|
|
|
|
// then we have a recurrence on this day
|
2008-02-03 12:05:55 +00:00
|
|
|
result := (ThisWkDay = EventWkDay) and (ThisDayCount = EventDayCount);
|
|
|
|
end;
|
|
|
|
|
|
|
|
rtMonthlyByDate:
|
2018-06-15 23:40:18 +00:00
|
|
|
if DayInRepeatRange then
|
|
|
|
// if (Day < trunc(Event.RepeatRangeEnd) + 1) and (Day > trunc(Event.StartTime)) then
|
2016-07-04 09:55:08 +00:00
|
|
|
begin
|
2016-09-06 19:59:25 +00:00
|
|
|
// Get the year, month and day of the first event in the series
|
2008-02-03 12:05:55 +00:00
|
|
|
DecodeDate(Event.StartTime, EY, EM, ED);
|
2016-09-06 19:59:25 +00:00
|
|
|
// Get the year, month and day of the "Day" parameter
|
2008-02-03 12:05:55 +00:00
|
|
|
DecodeDate(Day, NY, NM, ND);
|
2016-09-06 19:59:25 +00:00
|
|
|
// If the day values are equal then we have a recurrence on this day
|
2008-02-03 12:05:55 +00:00
|
|
|
result := ED = ND;
|
|
|
|
end;
|
|
|
|
|
|
|
|
rtYearlyByDay:
|
2018-06-15 23:40:18 +00:00
|
|
|
if DayInRepeatRange then
|
|
|
|
// if (Day < trunc(Event.RepeatRangeEnd) + 1) and (Day > trunc(Event.StartTime)) then
|
2016-07-04 09:55:08 +00:00
|
|
|
begin
|
2016-09-06 19:59:25 +00:00
|
|
|
// Get the julian date of the first event in the series
|
2008-02-03 12:05:55 +00:00
|
|
|
EventJulian := GetJulianDate(Event.StartTime);
|
2016-09-06 19:59:25 +00:00
|
|
|
// Get the julian date of the "Day" parameter
|
2008-02-03 12:05:55 +00:00
|
|
|
ThisJulian := GetJulianDate(Day);
|
2016-09-06 19:59:25 +00:00
|
|
|
// Ff the julian values are equal then we have a recurrence on this day
|
2008-02-03 12:05:55 +00:00
|
|
|
result := EventJulian = ThisJulian;
|
|
|
|
end;
|
|
|
|
|
|
|
|
rtYearlyByDate:
|
2018-06-15 23:40:18 +00:00
|
|
|
if DayInRepeatRange then
|
|
|
|
// if (Day < trunc(Event.RepeatRangeEnd) + 1) and (Day > trunc(Event.StartTime)) then
|
2016-07-04 09:55:08 +00:00
|
|
|
begin
|
2016-09-06 19:59:25 +00:00
|
|
|
// Get the year, month and day of the first event in the series.
|
2008-02-03 12:05:55 +00:00
|
|
|
DecodeDate(Event.StartTime, EY, EM, ED);
|
2016-09-06 19:59:25 +00:00
|
|
|
// Get the year, month and day of the "Day" parameter.
|
2008-02-03 12:05:55 +00:00
|
|
|
DecodeDate(Day, NY, NM, ND);
|
2016-09-06 19:59:25 +00:00
|
|
|
// If the day values and month values are equal then we have a recurrence on this day
|
2008-02-03 12:05:55 +00:00
|
|
|
result := (ED = ND) and (EM = NM);
|
|
|
|
end;
|
|
|
|
|
|
|
|
rtCustom:
|
2018-06-15 23:40:18 +00:00
|
|
|
if DayInRepeatRange and (Event.CustomInterval > 0) then
|
|
|
|
// if (Day < trunc(Event.RepeatRangeEnd) + 1) and (Day > trunc(Event.StartTime)) then
|
2016-07-04 09:55:08 +00:00
|
|
|
begin
|
2016-09-06 19:59:25 +00:00
|
|
|
// If the number of elapsed days between the "Day" parameter and
|
|
|
|
// the event start time is evenly divisible by the event's custom
|
|
|
|
// interval, then we have a recurrence on this day
|
|
|
|
result := (Trunc(Day) - Trunc(Event.StartTime)) mod Event.CustomInterval = 0;
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
{=====}
|
|
|
|
|
|
|
|
function TVpSchedule.EventCountByDay(Value: TDateTime): Integer;
|
|
|
|
var
|
|
|
|
I: Integer;
|
2009-12-24 22:41:52 +00:00
|
|
|
Event: TVpEvent;
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
|
|
|
result := 0;
|
|
|
|
for I := 0 to pred(EventCount) do begin
|
2009-12-24 22:41:52 +00:00
|
|
|
Event := GetEvent(I);
|
2016-09-06 19:59:25 +00:00
|
|
|
// If this is a repeating event and it falls on today then inc result
|
2016-07-04 09:55:08 +00:00
|
|
|
if (Event.RepeatCode > rtNone) and RepeatsOn(Event, Value) then
|
2008-02-03 12:05:55 +00:00
|
|
|
Inc(Result)
|
2016-09-06 19:59:25 +00:00
|
|
|
// Otherwise if it is an event that naturally falls on today, then inc result
|
2016-07-04 09:55:08 +00:00
|
|
|
else
|
|
|
|
if DateInRange(Value, Event.StartTime, Event.EndTime, true) then
|
2008-02-03 12:05:55 +00:00
|
|
|
Inc(Result);
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
{=====}
|
|
|
|
|
|
|
|
procedure TVpSchedule.EventsByDate(Date: TDateTime; EventList: TList);
|
|
|
|
var
|
|
|
|
I: Integer;
|
|
|
|
Event: TVpEvent;
|
|
|
|
begin
|
|
|
|
if EventCountByDay(Date) = 0 then
|
|
|
|
EventList.Clear
|
|
|
|
|
|
|
|
else begin
|
2016-09-06 19:59:25 +00:00
|
|
|
// Add this day's events to the Event List.
|
2008-02-03 12:05:55 +00:00
|
|
|
for I := 0 to pred(EventCount) do begin
|
|
|
|
Event := GetEvent(I);
|
|
|
|
|
2016-09-06 19:59:25 +00:00
|
|
|
// If this is a repeating event and it falls on "Date" then add it to the list.
|
2016-06-30 21:29:02 +00:00
|
|
|
if (Event.RepeatCode > rtNone) and RepeatsOn(Event, Date) then
|
2008-02-03 12:05:55 +00:00
|
|
|
EventList.Add(Event)
|
2016-06-30 21:29:02 +00:00
|
|
|
else
|
2016-09-06 19:59:25 +00:00
|
|
|
// otherwise if this event naturally falls on "Date" then add it to the list.
|
2016-06-30 21:29:02 +00:00
|
|
|
if DateInRange(Date, Event.StartTime, Event.EndTime, true) then
|
2008-02-03 12:05:55 +00:00
|
|
|
EventList.Add(Event);
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
{=====}
|
|
|
|
|
|
|
|
procedure TVpSchedule.AllDayEventsByDate(Date: TDateTime; EventList: TList);
|
|
|
|
var
|
|
|
|
I: Integer;
|
|
|
|
Event: TVpEvent;
|
|
|
|
begin
|
|
|
|
EventList.Clear;
|
|
|
|
|
|
|
|
if EventCountByDay(Date) = 0 then
|
|
|
|
Exit
|
|
|
|
|
|
|
|
else begin
|
2016-09-06 19:59:25 +00:00
|
|
|
// Add this days events to the Event List.
|
2008-02-03 12:05:55 +00:00
|
|
|
for I := 0 to pred(EventCount) do begin
|
|
|
|
Event := GetEvent(I);
|
2016-07-04 09:55:08 +00:00
|
|
|
if Event.AllDayEvent and
|
|
|
|
(DateInRange(Date, Event.StartTime, Event.EndTime, true) or RepeatsOn(Event, Date))
|
|
|
|
then
|
2008-02-03 12:05:55 +00:00
|
|
|
EventList.Add(Event);
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
{=====}
|
|
|
|
|
2016-06-30 18:45:39 +00:00
|
|
|
(* wp: Commented because it is not called from anywhere...
|
2008-02-03 12:05:55 +00:00
|
|
|
|
|
|
|
{ binary search }
|
|
|
|
function TVpSchedule.FindTimeSlot(StartTime, EndTime: TDateTime): Boolean;
|
|
|
|
var
|
|
|
|
L, R, M: Integer;
|
|
|
|
CStart, CEnd, CompStart, CompEnd: integer; { comparison results }
|
|
|
|
HitStart, HitEnd, HitStraddle: Boolean;
|
|
|
|
begin
|
|
|
|
HitStart := false;
|
|
|
|
HitEnd := false;
|
|
|
|
HItStraddle := false;
|
|
|
|
{ Set left and right indexes }
|
|
|
|
L := 0;
|
|
|
|
R := Pred(FEventList.Count);
|
|
|
|
while (L <= R) do begin
|
|
|
|
{ Calculate the middle index }
|
|
|
|
M := (L + R) div 2;
|
|
|
|
|
|
|
|
{ Check to see if the middle item straddles our start time }
|
|
|
|
{ Compare the the middle item's starttime against the passed in times }
|
|
|
|
CStart := Compare(TVpEvent(FEventList.List^[M]).StartTime, StartTime);
|
|
|
|
CEnd := Compare(TVpEvent(FEventList.List^[M]).EndTime, StartTime);
|
|
|
|
{ if the middle item's starttime is less than or equal to the given }
|
|
|
|
{ starttime AND the middle item's endtime is greater than or equal to the }
|
|
|
|
{ given starttime then we've hit at the start time }
|
|
|
|
if ((CStart <= 0) and (CEnd >= 0)) then HitStart := true;
|
|
|
|
|
|
|
|
{ Check to see if the middle item straddles our end time }
|
|
|
|
{ Compare the the middle item's Endtime against the passed in times }
|
|
|
|
CStart := Compare(TVpEvent(FEventList.List^[M]).StartTime, EndTime);
|
|
|
|
CEnd := Compare(TVpEvent(FEventList.List^[M]).EndTime, EndTime);
|
|
|
|
{ if the middle item's starttime is less than or equal to the given }
|
|
|
|
{ endtime AND the middle item's endtime is greater than or equal to the }
|
|
|
|
{ given endtime then we've hit at the end time }
|
|
|
|
if ((CStart <= 0) and (CEnd >= 0)) then HitEnd := true;
|
|
|
|
|
|
|
|
if (not HitStart) and (not HitEnd) then begin
|
|
|
|
{ Check to see if our times fall completely within the middle item }
|
|
|
|
CompStart := Compare(TVpEvent(FEventList.List^[M]).StartTime, StartTime);
|
|
|
|
CompEnd := Compare(TVpEvent(FEventList.List^[M]).EndTime, EndTime);
|
|
|
|
{ if the middle item's starttime is less than our starttime AND its }
|
|
|
|
{ endtime is greater than our endtime, then teh middle item straddles }
|
|
|
|
{ our times }
|
|
|
|
if ((CompStart <= 0) and (CompEnd >= 0)) then HitStraddle := true;
|
|
|
|
|
|
|
|
if not HItStraddle then
|
|
|
|
{ Check to see if the middle item falls completely inside our times }
|
2016-06-30 18:45:39 +00:00
|
|
|
CompStart := Compare(TVpEvent(FEventList.List^[M]).StartTime, StartTime); // wp: Is this correct? Strange indentation!
|
2008-02-03 12:05:55 +00:00
|
|
|
CompEnd := Compare(TVpEvent(FEventList.List^[M]).EndTime, EndTime);
|
|
|
|
{ if the middle item's starttime is less than our starttime AND its }
|
|
|
|
{ endtime is greater than our endtime, then teh middle item straddles }
|
|
|
|
{ our times }
|
|
|
|
if ((CompStart >= 0) and (CompEnd <= 0)) then HitStraddle := true;
|
|
|
|
end;
|
|
|
|
|
|
|
|
if (HitStart or HitEnd or HitStraddle) then begin
|
|
|
|
result := true;
|
|
|
|
exit;
|
|
|
|
end
|
|
|
|
else begin
|
|
|
|
{ No hit so keep going }
|
|
|
|
CStart := Compare(TVpEvent(FEventList.List^[M]).StartTime, StartTime);
|
|
|
|
{ if the middle item's starttime is less than or equal to the given }
|
|
|
|
{ starttime AND the middle item's endtime is greater than or equal to the }
|
|
|
|
{ given starttime then we've hit at the start time }
|
|
|
|
if (CStart < 0) then
|
|
|
|
L := Succ(M)
|
|
|
|
else
|
|
|
|
R := Pred(M);
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
{ if we got here then we didn't hit an existing item }
|
|
|
|
result := false;
|
|
|
|
end;
|
2016-06-30 18:45:39 +00:00
|
|
|
{=====} *)
|
2008-02-03 12:05:55 +00:00
|
|
|
|
|
|
|
function TVpSchedule.GetCount: Integer;
|
|
|
|
begin
|
|
|
|
result := FEventList.Count;
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
2016-09-06 19:59:25 +00:00
|
|
|
(*****************************************************************************)
|
2008-02-03 12:05:55 +00:00
|
|
|
{ TVpContact }
|
|
|
|
(*****************************************************************************)
|
|
|
|
constructor TVpContact.Create(Owner: TVpContacts);
|
|
|
|
begin
|
|
|
|
inherited Create;
|
2016-09-16 23:42:31 +00:00
|
|
|
|
2008-02-03 12:05:55 +00:00
|
|
|
FChanged := false;
|
|
|
|
FOwner := Owner;
|
2016-09-15 20:27:13 +00:00
|
|
|
|
2008-02-03 12:05:55 +00:00
|
|
|
FPhoneType1 := Ord(ptWork);
|
|
|
|
FPhoneType2 := Ord(ptHome);
|
|
|
|
FPhoneType3 := Ord(ptWorkFax);
|
|
|
|
FPhoneType4 := Ord(ptMobile);
|
|
|
|
FPhoneType5 := Ord(ptAssistant);
|
2016-09-15 20:27:13 +00:00
|
|
|
|
|
|
|
FEMailType1 := ord(mtWork);
|
|
|
|
FEMailType2 := ord(mtHome);
|
|
|
|
FEMailType3 := ord(mtOther);
|
|
|
|
|
|
|
|
FWebsiteType1 := ord(wtBusiness);
|
|
|
|
FWebsiteType2 := ord(wtPersonal);
|
|
|
|
|
|
|
|
FAddressType1 := ord(atWork);
|
|
|
|
FAddressType2 := ord(atHome);
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
destructor TVpContact.Destroy;
|
2016-09-05 14:04:22 +00:00
|
|
|
var
|
|
|
|
idx: Integer;
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
2016-09-06 19:59:25 +00:00
|
|
|
// Remove self from owners list
|
2016-09-05 14:04:22 +00:00
|
|
|
if (FOwner <> nil) then begin
|
|
|
|
idx := FOwner.FContactsList.IndexOf(self);
|
|
|
|
if idx > -1 then FOwner.FContactsList.Delete(idx);
|
|
|
|
end;
|
2008-02-03 12:05:55 +00:00
|
|
|
inherited;
|
|
|
|
end;
|
|
|
|
|
2016-09-20 09:54:00 +00:00
|
|
|
function TVpContact.ContainsContactData: Boolean;
|
|
|
|
begin
|
|
|
|
Result := (FPhone1 <> '') or (FPhone3 <> '') or (FPhone3 <> '') or
|
|
|
|
(FPhone4 <> '') or (FPhone5 <> '') or
|
|
|
|
(FEMail1 <> '') or (FEMail2 <> '') or (FEMail3 <> '') or
|
|
|
|
(FWebsite1 <> '') or (FWebsite2 <> '');
|
|
|
|
end;
|
|
|
|
|
|
|
|
function TVpContact.ContainsHomeData: Boolean;
|
|
|
|
begin
|
|
|
|
Result := (FAddress2 <> '') or (FCity2 <> '') or (FState2 <> '') or (FCountry2 <> '');
|
|
|
|
end;
|
|
|
|
|
|
|
|
function TVpContact.ContainsWorkData: Boolean;
|
|
|
|
begin
|
|
|
|
Result := (Address1 <> '') or (FCity1 <> '') or (FState1 <> '') or (FCountry1 <> '');
|
|
|
|
end;
|
|
|
|
|
2022-08-18 17:44:47 +00:00
|
|
|
function TVpContact.CreateVCard: TVpVCard;
|
|
|
|
|
|
|
|
function FirstOrSecond(Which, KeyFirst, KeySecond: Integer; First, Second: String): String;
|
|
|
|
begin
|
|
|
|
if Which = KeyFirst then
|
|
|
|
Result := First
|
|
|
|
else if Which = KeySecond then
|
|
|
|
Result := Second
|
|
|
|
else
|
|
|
|
Result := '';
|
|
|
|
end;
|
|
|
|
|
|
|
|
function GetAddressDetail(AddrType: TVpAddressType; What: String): String;
|
|
|
|
var
|
|
|
|
at: integer;
|
|
|
|
begin
|
|
|
|
at := ord(AddrType);
|
|
|
|
case What of
|
|
|
|
'Address':
|
|
|
|
Result := FirstOrSecond(at, FAddressType1, FAddressType2, FAddress1, FAddress2);
|
|
|
|
'City':
|
|
|
|
Result := FirstOrSecond(at, FAddressType1, FAddressType2, FCity1, FCity2);
|
|
|
|
'Zip':
|
|
|
|
Result := FirstOrSecond(at, FAddressType1, FAddressType2, FZip1, FZip2);
|
|
|
|
'State':
|
|
|
|
Result := FirstOrSecond(at, FAddressType1, FAddressType2, FState1, FState2);
|
|
|
|
'Country':
|
|
|
|
Result := FirstOrSecond(at, FAddressType1, FAddressType2, FCountry1, FCountry2);
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
function GetEMail(AEMailType: TVpEMailType): String;
|
|
|
|
begin
|
|
|
|
if ord(AEMailType) = FEMailType1 then
|
|
|
|
Result := FEMail1
|
|
|
|
else if ord(AEMailType) = FEMailType2 then
|
|
|
|
Result := FEMail2
|
|
|
|
else if ord(AEMailType) = FEMailType3 then
|
|
|
|
Result := FEMail3
|
|
|
|
else
|
|
|
|
Result := '';
|
|
|
|
end;
|
|
|
|
|
|
|
|
function GetPhone(APhoneType: TVpPhoneType): String;
|
|
|
|
begin
|
|
|
|
if ord(APhoneType) = FPhoneType1 then
|
|
|
|
Result := FPhone1
|
|
|
|
else if ord(APhoneType) = FPhoneType2 then
|
|
|
|
Result := FPhone2
|
|
|
|
else if ord(APhoneType) = FPhoneType3 then
|
|
|
|
Result := FPhone3
|
|
|
|
else if ord(APhoneType) = FPhoneType4 then
|
|
|
|
Result := FPhone4
|
|
|
|
else if ord(APhoneType) = FPhoneType5 then
|
|
|
|
Result := FPhone5
|
|
|
|
else
|
|
|
|
Result := '';
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
|
|
begin
|
|
|
|
Result := TVpVCard.Create;
|
|
|
|
Result.LastName := FLastName;
|
|
|
|
Result.FirstName := FFirstName;
|
|
|
|
Result.Title := FTitle;
|
|
|
|
|
|
|
|
Result.Company := FCompany;
|
|
|
|
Result.WorkAddress := GetAddressDetail(atWork, 'Address');
|
|
|
|
Result.WorkCity := GetAddressDetail(atWork, 'City');
|
|
|
|
Result.WorkZip := GetAddressDetail(atWork, 'Zip');
|
|
|
|
Result.WorkState := GetAddressDetail(atWork, 'State');
|
|
|
|
Result.WorkCountry := GetAddressDetail(atWork, 'Country');
|
|
|
|
Result.WorkPhone := GetPhone(ptWork);
|
|
|
|
Result.WorkFax := GetPhone(ptWorkFax);
|
|
|
|
Result.WorkEMail := GetEMail(mtWork);
|
|
|
|
|
|
|
|
Result.WorkAddress := GetAddressDetail(atHome, 'Address');
|
|
|
|
Result.WorkCity := GetAddressDetail(atHome, 'City');
|
|
|
|
Result.WorkZip := GetAddressDetail(atHome, 'Zip');
|
|
|
|
Result.WorkState := GetAddressDetail(atHome, 'State');
|
|
|
|
Result.WorkCountry := GetAddressDetail(atHome, 'Country');
|
|
|
|
Result.HomePhone := GetPhone(ptHome);
|
|
|
|
Result.HomeFax := GetPhone(ptHomeFax);
|
|
|
|
Result.HomeEMail := GetEMail(mtHome);
|
|
|
|
|
|
|
|
Result.CarPhone := GetPhone(ptCar);
|
|
|
|
Result.Mobile := GetPhone(ptMobile);
|
|
|
|
Result.ISDN := GetPhone(ptISDN);
|
|
|
|
Result.Pager := GetPhone(ptPager);
|
|
|
|
|
|
|
|
Result.BirthDay := FBirthdate;
|
|
|
|
Result.Anniversary := FAnniversary;
|
|
|
|
end;
|
|
|
|
|
2008-02-03 12:05:55 +00:00
|
|
|
function TVpContact.FullName : string;
|
|
|
|
begin
|
|
|
|
if (FFirstName = '') and (FLastName = '') then
|
|
|
|
Result := ''
|
|
|
|
else
|
|
|
|
Result := FFirstName + ' ' + FLastName;
|
|
|
|
end;
|
|
|
|
|
2018-06-08 20:03:23 +00:00
|
|
|
procedure TVpContact.LoadFromVCard(ACard: TVpVCard);
|
|
|
|
const
|
|
|
|
NUM_PHONES = 5;
|
|
|
|
var
|
|
|
|
s: String;
|
|
|
|
dt: TDateTime;
|
|
|
|
phoneIdx: Integer;
|
|
|
|
phones: array[1..NUM_PHONES] of ^String;
|
|
|
|
phonetypes: array[1..NUM_PHONES] of ^Integer;
|
2022-08-19 10:53:49 +00:00
|
|
|
datastore: TVpCustomDatastore;
|
|
|
|
cat: String;
|
|
|
|
ct: TVpCategoryType;
|
2018-06-08 20:03:23 +00:00
|
|
|
begin
|
|
|
|
phones[1] := @FPhone1; phonetypes[1] := @FPhoneType1;
|
|
|
|
phones[2] := @FPhone2; phonetypes[2] := @FPhoneType2;
|
|
|
|
phones[3] := @FPhone3; phonetypes[3] := @FPhoneType3;
|
|
|
|
phones[4] := @FPhone4; phonetypes[4] := @FPhoneType4;
|
|
|
|
phones[5] := @FPhone5; phonetypes[5] := @FPhoneType5;
|
|
|
|
|
|
|
|
FLastName := ACard.LastName;
|
|
|
|
FFirstName := ACard.FirstName;
|
|
|
|
FTitle := ACard.Title;
|
|
|
|
|
|
|
|
FCompany := ACard.Company;
|
|
|
|
FAddress1 := ACard.WorkAddress;
|
|
|
|
FCity1 := ACard.WorkCity;
|
|
|
|
FZip1 := ACard.WorkZip;
|
|
|
|
FState1 := ACard.WorkState;
|
|
|
|
FCountry1 := ACard.WorkCountry;
|
|
|
|
FAddressType1 := ord(atWork);
|
|
|
|
|
|
|
|
FAddress2 := ACard.HomeAddress;
|
|
|
|
FCity2 := ACard.HomeCity;
|
|
|
|
FZip2 := ACard.HomeZip;
|
|
|
|
FState2 := ACard.HomeState;
|
|
|
|
FCountry2 := ACard.HomeCountry;
|
|
|
|
FAddressType2 := ord(atHome);
|
|
|
|
|
|
|
|
FEmail1 := ACard.WorkEMail;
|
|
|
|
FEMailType1 := ord(mtWork);
|
|
|
|
FEmail2 := ACard.HomeEMail;
|
|
|
|
FEMailType2 := ord(mtHome);
|
|
|
|
|
|
|
|
phoneIdx := 1;
|
|
|
|
s := ACard.Mobile;
|
|
|
|
if s <> '' then begin
|
|
|
|
phones[phoneidx]^ := s;
|
|
|
|
phonetypes[phoneidx]^ := ord(ptMobile);
|
|
|
|
inc(phoneidx);
|
|
|
|
end;
|
|
|
|
s := ACard.WorkPhone;
|
|
|
|
if s <> '' then begin
|
|
|
|
phones[phoneidx]^ := s;
|
|
|
|
phonetypes[phoneidx]^ := ord(ptWork);
|
|
|
|
inc(phoneidx);
|
|
|
|
end;
|
|
|
|
s := ACard.WorkFax;
|
|
|
|
if s <> '' then begin
|
|
|
|
phones[phoneidx]^ := s;
|
|
|
|
phonetypes[phoneidx]^ := ord(ptWorkFax);
|
|
|
|
inc(phoneidx);
|
|
|
|
end;
|
|
|
|
s := ACard.Pager;
|
|
|
|
if s <> '' then begin
|
|
|
|
phones[phoneidx]^ := s;
|
|
|
|
phonetypes[phoneidx]^ := ord(ptPager);
|
|
|
|
inc(phoneidx);
|
|
|
|
end;
|
|
|
|
s := ACard.CarPhone;
|
|
|
|
if (s <> '') and (phoneIdx <= NUM_PHONES) then begin
|
|
|
|
phones[phoneidx]^ := s;
|
|
|
|
phonetypes[phoneidx]^ := ord(ptCar);
|
|
|
|
inc(phoneidx);
|
|
|
|
end;
|
|
|
|
s := ACard.HomePhone;
|
|
|
|
if (s <> '') and (phoneIdx <= NUM_PHONES) then begin
|
|
|
|
phones[phoneidx]^ := s;
|
|
|
|
phonetypes[phoneidx]^ := ord(ptHome);
|
|
|
|
inc(phoneidx);
|
|
|
|
end;
|
|
|
|
s := ACard.HomeFax;
|
|
|
|
if (s <> '') and (phoneIdx <= NUM_PHONES) then begin
|
|
|
|
phones[phoneidx]^ := s;
|
|
|
|
phonetypes[phoneidx]^ := ord(ptHomeFax);
|
|
|
|
inc(phoneidx);
|
|
|
|
end;
|
|
|
|
s := ACard.ISDN;
|
|
|
|
if (s <> '') and (phoneIdx <= NUM_PHONES) then begin
|
|
|
|
phones[phoneidx]^ := s;
|
|
|
|
phonetypes[phoneidx]^ := ord(ptISDN);
|
|
|
|
inc(phoneidx);
|
|
|
|
end;
|
|
|
|
|
|
|
|
s := ACard.Value['BDAY', ''];
|
|
|
|
if s <> '' then begin
|
|
|
|
dt := VCardDate(s);
|
|
|
|
if dt > -1 then FBirthdate := dt;
|
|
|
|
end;
|
|
|
|
|
|
|
|
s := ACard.Value['ANNIVERSARY', ''];
|
|
|
|
if s <> '' then begin
|
|
|
|
dt := VCardDate(s);
|
|
|
|
if dt > -1 then FAnniversary := dt;
|
|
|
|
end;
|
|
|
|
|
|
|
|
FNotes := ACard.Value['NOTE', ''];
|
|
|
|
|
|
|
|
FPosition := ACard.Value['TITLE', ''];
|
|
|
|
s := ACard.Value['ROLE', ''];
|
|
|
|
if s <> '' then begin
|
|
|
|
if FPosition = '' then
|
|
|
|
FPosition := s
|
|
|
|
else
|
|
|
|
FPosition := FPosition + '; ' + s;
|
|
|
|
end;
|
|
|
|
|
2022-08-19 10:53:49 +00:00
|
|
|
{ Category }
|
|
|
|
{ tvplanit has only 1 category, vcard may have several. We pick the first one
|
|
|
|
defined by TVpCategorytype. If none is found we select ctOther. }
|
|
|
|
if ACard.PickedCategory > -1 then
|
|
|
|
FCategory := ACard.PickedCategory
|
|
|
|
else
|
|
|
|
begin
|
|
|
|
FCategory := ord(ctOther);
|
|
|
|
datastore := TVpCustomDatastore(Owner.Owner.Owner.Owner);
|
|
|
|
cat := datastore.FindBestCategory(ACard.Categories);
|
|
|
|
for ct in TVpCategoryType do
|
|
|
|
if cat = CategoryLabel(ct) then
|
|
|
|
begin
|
|
|
|
FCategory := ord(ct);
|
|
|
|
break;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2018-06-08 20:03:23 +00:00
|
|
|
FOwner.FOwner.ContactsDirty := true;
|
|
|
|
FChanged := true;
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
2008-02-03 12:05:55 +00:00
|
|
|
procedure TVpContact.SetBirthDate(Value: TDateTIme);
|
|
|
|
begin
|
|
|
|
if Value <> FBirthdate then begin
|
|
|
|
FBirthdate := Value;
|
|
|
|
Changed := true;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpContact.SetAnniversary(Value: TDateTIme);
|
|
|
|
begin
|
|
|
|
if Value <> FAnniversary then begin
|
|
|
|
FAnniversary := Value;
|
|
|
|
Changed := true;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2016-09-15 11:40:14 +00:00
|
|
|
procedure TVpContact.SetAddress1(const Value: string);
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
2016-09-15 11:40:14 +00:00
|
|
|
if Value <> FAddress1 then begin
|
|
|
|
FAddress1 := Value;
|
|
|
|
Changed := true;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpContact.SetAddress2(const Value: string);
|
|
|
|
begin
|
|
|
|
if Value <> FAddress2 then begin
|
|
|
|
FAddress2 := Value;
|
|
|
|
Changed := true;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpContact.SetAddressType1(Value: integer);
|
|
|
|
begin
|
|
|
|
if Value <> FAddressType1 then begin
|
|
|
|
FAddressType1 := Value;
|
|
|
|
Changed := true;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpContact.SetAddressType2(Value: integer);
|
|
|
|
begin
|
|
|
|
if Value <> FAddressType2 then begin
|
|
|
|
FAddressType2 := Value;
|
2008-02-03 12:05:55 +00:00
|
|
|
Changed := true;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpContact.SetCategory(Value: integer);
|
|
|
|
begin
|
|
|
|
if Value <> FCategory then begin
|
|
|
|
FCategory := Value;
|
|
|
|
Changed := true;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpContact.SetChanged(Value: Boolean);
|
|
|
|
begin
|
|
|
|
if Loading then Exit;
|
|
|
|
|
|
|
|
if Value <> FChanged then begin
|
|
|
|
FChanged := Value;
|
|
|
|
if FChanged then
|
|
|
|
FOwner.FOwner.ContactsDirty := true;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2016-09-15 11:40:14 +00:00
|
|
|
procedure TVpContact.SetCity1(const Value: string);
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
2016-09-15 11:40:14 +00:00
|
|
|
if Value <> FCity1 then begin
|
|
|
|
FCity1 := Value;
|
|
|
|
Changed := true;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpContact.SetCity2(const Value: string);
|
|
|
|
begin
|
|
|
|
if Value <> FCity2 then begin
|
|
|
|
FCity2 := Value;
|
2008-02-03 12:05:55 +00:00
|
|
|
Changed := true;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpContact.SetCompany(const Value: string);
|
|
|
|
begin
|
|
|
|
if Value <> FCompany then begin
|
|
|
|
FCompany := Value;
|
|
|
|
Changed := true;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2016-09-15 11:40:14 +00:00
|
|
|
procedure TVpContact.SetCountry1(const Value: string);
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
2016-09-15 11:40:14 +00:00
|
|
|
if Value <> FCountry1 then begin
|
|
|
|
FCountry1 := Value;
|
|
|
|
Changed := true;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpContact.SetCountry2(const Value: string);
|
|
|
|
begin
|
|
|
|
if Value <> FCountry2 then begin
|
|
|
|
FCountry2 := Value;
|
2008-02-03 12:05:55 +00:00
|
|
|
Changed := true;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpContact.SetCustom1(const Value: string);
|
|
|
|
begin
|
|
|
|
if Value <> FCustom1 then begin
|
|
|
|
FCustom1 := Value;
|
|
|
|
Changed := true;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpContact.SetCustom2(const Value: string);
|
|
|
|
begin
|
|
|
|
if Value <> FCustom2 then begin
|
|
|
|
FCustom2 := Value;
|
|
|
|
Changed := true;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpContact.SetCustom3(const Value: string);
|
|
|
|
begin
|
|
|
|
if Value <> FCustom3 then begin
|
|
|
|
FCustom3 := Value;
|
|
|
|
Changed := true;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpContact.SetCustom4(const Value: string);
|
|
|
|
begin
|
|
|
|
if Value <> FCustom4 then begin
|
|
|
|
FCustom4 := Value;
|
|
|
|
Changed := true;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpContact.SetDeleted(Value: Boolean);
|
|
|
|
begin
|
|
|
|
if Value <> FDeleted then begin
|
|
|
|
FDeleted := Value;
|
|
|
|
Changed := true;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2016-09-16 23:42:31 +00:00
|
|
|
procedure TVpContact.SetDepartment(const Value: String);
|
|
|
|
begin
|
|
|
|
if Value <> FDepartment then begin
|
|
|
|
FDepartment := Value;
|
|
|
|
Changed := True;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2016-09-15 11:40:14 +00:00
|
|
|
procedure TVpContact.SetEMail1(const Value: string);
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
2016-09-15 11:40:14 +00:00
|
|
|
if Value <> FEMail1 then begin
|
|
|
|
FEMail1 := Value;
|
|
|
|
Changed := true;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpContact.SetEMail2(const Value: string);
|
|
|
|
begin
|
|
|
|
if Value <> FEMail2 then begin
|
|
|
|
FEMail2 := Value;
|
|
|
|
Changed := true;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpContact.SetEMail3(const Value: string);
|
|
|
|
begin
|
|
|
|
if Value <> FEMail3 then begin
|
|
|
|
FEMail3 := Value;
|
|
|
|
Changed := true;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpContact.SetEMailType1(const Value: Integer);
|
|
|
|
begin
|
|
|
|
if Value <> FEMailType1 then begin
|
|
|
|
FEMailType1 := Value;
|
|
|
|
Changed := true;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpContact.SetEMailType2(const Value: Integer);
|
|
|
|
begin
|
|
|
|
if Value <> FEMailType2 then begin
|
|
|
|
FEMailType2 := Value;
|
|
|
|
Changed := true;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpContact.SetEMailType3(const Value: Integer);
|
|
|
|
begin
|
|
|
|
if Value <> FEMailType3 then begin
|
|
|
|
FEMailType3 := Value;
|
2008-02-03 12:05:55 +00:00
|
|
|
Changed := true;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpContact.SetFirstName(const Value: string);
|
|
|
|
begin
|
|
|
|
if Value <> FFirstName then begin
|
|
|
|
FFirstName := Value;
|
|
|
|
Changed := true;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpContact.SetLastName(const Value: string);
|
|
|
|
begin
|
|
|
|
if Value <> FLastName then begin
|
|
|
|
FLastName := Value;
|
|
|
|
Changed := true;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2016-06-11 14:09:10 +00:00
|
|
|
procedure TVpContact.SetNotes(const Value: string);
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
2016-06-11 14:09:10 +00:00
|
|
|
if Value <> FNotes then begin
|
|
|
|
FNotes := Value;
|
2008-02-03 12:05:55 +00:00
|
|
|
Changed := true;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpContact.SetPhone1(const Value: string);
|
|
|
|
begin
|
|
|
|
if Value <> FPhone1 then begin
|
|
|
|
FPhone1 := Value;
|
|
|
|
Changed := true;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpContact.SetPhone2(const Value: string);
|
|
|
|
begin
|
|
|
|
if Value <> FPhone2 then begin
|
|
|
|
FPhone2 := Value;
|
|
|
|
Changed := true;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpContact.SetPhone3(const Value: string);
|
|
|
|
begin
|
|
|
|
if Value <> FPhone3 then begin
|
|
|
|
FPhone3 := Value;
|
|
|
|
Changed := true;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpContact.SetPhone4(const Value: string);
|
|
|
|
begin
|
|
|
|
if Value <> FPhone4 then begin
|
|
|
|
FPhone4 := Value;
|
|
|
|
Changed := true;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpContact.SetPhone5(const Value: string);
|
|
|
|
begin
|
|
|
|
if Value <> FPhone5 then begin
|
|
|
|
FPhone5 := Value;
|
|
|
|
Changed := true;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpContact.SetPhoneType1(Value: Integer);
|
|
|
|
begin
|
|
|
|
if Value <> FPhoneType1 then begin
|
|
|
|
FPhoneType1 := Value;
|
|
|
|
Changed := true;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpContact.SetPhoneType2(Value: Integer);
|
|
|
|
begin
|
|
|
|
if Value <> FPhoneType2 then begin
|
|
|
|
FPhoneType2 := Value;
|
|
|
|
Changed := true;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpContact.SetPhoneType3(Value: Integer);
|
|
|
|
begin
|
|
|
|
if Value <> FPhoneType3 then begin
|
|
|
|
FPhoneType3 := Value;
|
|
|
|
Changed := true;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpContact.SetPhoneType4(Value: Integer);
|
|
|
|
begin
|
|
|
|
if Value <> FPhoneType4 then begin
|
|
|
|
FPhoneType4 := Value;
|
|
|
|
Changed := true;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpContact.SetPhoneType5(Value: Integer);
|
|
|
|
begin
|
|
|
|
if Value <> FPhoneType5 then begin
|
|
|
|
FPhoneType5 := Value;
|
|
|
|
Changed := true;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpContact.SetPosition(const Value: string);
|
|
|
|
begin
|
|
|
|
if Value <> FPosition then begin
|
|
|
|
FPosition := Value;
|
|
|
|
Changed := true;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpContact.SetRecordID(Value: Integer);
|
|
|
|
begin
|
|
|
|
if Value <> FRecordID then begin
|
|
|
|
FRecordID := Value;
|
|
|
|
Changed := true;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2016-09-15 11:40:14 +00:00
|
|
|
procedure TVpContact.SetState1(const Value: string);
|
|
|
|
begin
|
|
|
|
if Value <> FState1 then begin
|
|
|
|
FState1 := Value;
|
|
|
|
Changed := true;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpContact.SetState2(const Value: string);
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
2016-09-15 11:40:14 +00:00
|
|
|
if Value <> FState2 then begin
|
|
|
|
FState2 := Value;
|
2008-02-03 12:05:55 +00:00
|
|
|
Changed := true;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpContact.SetTitle(const Value: string);
|
|
|
|
begin
|
|
|
|
if Value <> FTitle then begin
|
|
|
|
FTitle := Value;
|
|
|
|
Changed := true;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2016-09-15 11:40:14 +00:00
|
|
|
procedure TVpContact.SetWebsite1(Value: String);
|
|
|
|
begin
|
|
|
|
if Value <> FWebsite1 then begin
|
|
|
|
FWebsite1 := Value;
|
|
|
|
Changed := true;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpContact.SetWebsite2(Value: String);
|
|
|
|
begin
|
2016-09-18 09:50:12 +00:00
|
|
|
if Value <> FWebsite2 then begin
|
2016-09-15 11:40:14 +00:00
|
|
|
FWebsite2 := Value;
|
|
|
|
Changed := true;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpContact.SetWebsiteType1(Value: Integer);
|
|
|
|
begin
|
|
|
|
if Value <> FWebsiteType1 then begin
|
|
|
|
FWebsiteType1 := Value;
|
|
|
|
Changed := true;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpContact.SetWebsiteType2(Value: Integer);
|
|
|
|
begin
|
|
|
|
if Value <> FWebsiteType2 then begin
|
2016-09-18 09:50:12 +00:00
|
|
|
FWebsiteType2 := Value;
|
2016-09-15 11:40:14 +00:00
|
|
|
Changed := true;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpContact.SetZip1(const Value: string);
|
|
|
|
begin
|
|
|
|
if Value <> FZip1 then begin
|
|
|
|
FZip1 := Value;
|
|
|
|
Changed := true;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpContact.SetZip2(const Value: string);
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
2016-09-15 11:40:14 +00:00
|
|
|
if Value <> FZip2 then begin
|
|
|
|
FZip2 := Value;
|
2008-02-03 12:05:55 +00:00
|
|
|
Changed := true;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2016-09-06 19:59:25 +00:00
|
|
|
|
|
|
|
(*****************************************************************************)
|
2008-02-03 12:05:55 +00:00
|
|
|
{ TVpContacts }
|
|
|
|
(*****************************************************************************)
|
2016-09-06 19:59:25 +00:00
|
|
|
|
2008-02-03 12:05:55 +00:00
|
|
|
constructor TVpContacts.Create(Owner: TVpResource);
|
|
|
|
begin
|
|
|
|
inherited Create;
|
|
|
|
FOwner := Owner;
|
|
|
|
FContactsList := TList.Create;
|
|
|
|
|
|
|
|
FContactSort := csLastFirst;
|
|
|
|
end;
|
|
|
|
|
|
|
|
destructor TVpContacts.Destroy;
|
|
|
|
begin
|
|
|
|
ClearContacts;
|
|
|
|
FContactsList.Free;
|
|
|
|
inherited;
|
|
|
|
end;
|
|
|
|
|
|
|
|
function TVpContacts.AddContact(RecordID: Integer): TVpContact;
|
|
|
|
var
|
|
|
|
Contact: TVpContact;
|
|
|
|
begin
|
|
|
|
Contact := TVpContact.Create(Self);
|
|
|
|
try
|
|
|
|
Contact.Loading := true;
|
2016-09-05 14:04:22 +00:00
|
|
|
FContactsList.Add(Contact);
|
2008-02-03 12:05:55 +00:00
|
|
|
Contact.RecordID := RecordID;
|
|
|
|
Contact.Loading := false;
|
|
|
|
result := Contact;
|
|
|
|
except
|
|
|
|
Contact.Free;
|
|
|
|
raise EFailToCreateContact.Create;
|
|
|
|
end;
|
|
|
|
end;
|
2016-09-06 19:59:25 +00:00
|
|
|
|
|
|
|
procedure TVpContacts.BatchUpdate(Value: Boolean);
|
|
|
|
begin
|
|
|
|
if Value then
|
|
|
|
Inc(FBatchUpdate)
|
|
|
|
else
|
|
|
|
Dec(FBatchUpdate);
|
|
|
|
|
|
|
|
if FBatchUpdate < 1 then begin
|
|
|
|
FBatchUpdate := 0;
|
|
|
|
Sort;
|
|
|
|
end;
|
|
|
|
end;
|
2008-02-03 12:05:55 +00:00
|
|
|
|
|
|
|
function TVpContacts.Count: Integer;
|
|
|
|
begin
|
|
|
|
result := FContactsList.Count;
|
|
|
|
end;
|
2016-09-06 19:59:25 +00:00
|
|
|
|
|
|
|
procedure TVpContacts.Sort;
|
|
|
|
begin
|
|
|
|
// For greater performance, we don't sort while doing batch updates.
|
|
|
|
if FBatchUpdate > 0 then
|
|
|
|
exit;
|
|
|
|
|
|
|
|
// Do the sort
|
|
|
|
if ContactSort = csFirstLast then
|
|
|
|
FContactsList.Sort(@CompareContacts_FirstLast)
|
|
|
|
else
|
|
|
|
FContactsList.Sort(@CompareContacts_LastFirst);
|
|
|
|
end;
|
2008-02-03 12:05:55 +00:00
|
|
|
|
|
|
|
function TVpContacts.Last: TVpContact;
|
|
|
|
begin
|
2018-06-15 23:40:18 +00:00
|
|
|
result := TVpContact(FContactsList[FContactsList.Count - 1]);
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
function TVpContacts.First: TVpContact;
|
|
|
|
begin
|
2018-06-15 23:40:18 +00:00
|
|
|
result := TVpContact(FContactsList[0]);
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpContacts.DeleteContact(Contact: TVpContact);
|
|
|
|
begin
|
2016-09-06 19:59:25 +00:00
|
|
|
// Contacts automatically remove themselves from the list in their destructor
|
2008-02-03 12:05:55 +00:00
|
|
|
Contact.Free;
|
|
|
|
end;
|
|
|
|
|
|
|
|
function TVpContacts.GetContact(Index: Integer): TVpContact;
|
|
|
|
begin
|
2018-06-15 23:40:18 +00:00
|
|
|
result := TVpContact(FContactsList[Index]);
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpContacts.ClearContacts;
|
|
|
|
begin
|
|
|
|
BatchUpdate(true);
|
|
|
|
try
|
|
|
|
while FContactsList.Count > 0 do
|
|
|
|
TVpContact(FContactsList.Last).Free;
|
|
|
|
finally
|
|
|
|
BatchUpdate(false);
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2018-12-04 11:34:23 +00:00
|
|
|
{ new function introduced to support the new buttonbar component. }
|
|
|
|
function TVpContacts.FindContactByName(const AName: string;
|
|
|
|
CaseInsensitive: Boolean): TVpContact;
|
2008-02-03 12:05:55 +00:00
|
|
|
var
|
|
|
|
I: Integer;
|
|
|
|
SearchStr: String;
|
2018-12-04 11:34:23 +00:00
|
|
|
SearchLength: Integer;
|
|
|
|
SearchName: String;
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
|
|
|
Result := nil;
|
|
|
|
|
2016-09-06 19:59:25 +00:00
|
|
|
// To enhance performance, uppercase the input name and get its length only once
|
2008-02-03 12:05:55 +00:00
|
|
|
if CaseInsensitive then
|
2018-12-04 11:34:23 +00:00
|
|
|
SearchStr := UpperCase(AName)
|
2008-02-03 12:05:55 +00:00
|
|
|
else
|
2018-12-04 11:34:23 +00:00
|
|
|
SearchStr := AName;
|
2008-02-03 12:05:55 +00:00
|
|
|
SearchLength := Length(SearchStr);
|
2018-12-04 11:34:23 +00:00
|
|
|
|
2016-09-06 19:59:25 +00:00
|
|
|
// Iterate the contacts looking for a match
|
2018-12-04 11:34:23 +00:00
|
|
|
for I := 0 to FContactsList.Count - 1 do begin
|
|
|
|
SearchName := Copy(TVpContact(FContactsList[I]).LastName, 1, SearchLength);
|
|
|
|
if CaseInsensitive then
|
|
|
|
SearchName := Uppercase(SearchName);
|
|
|
|
// We found a match, so return it and bail out
|
|
|
|
if SearchName = SearchStr then begin
|
|
|
|
Result := TVpContact(FContactsList[I]);
|
|
|
|
exit;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
end;
|
2008-02-03 12:05:55 +00:00
|
|
|
|
|
|
|
{ new function introduced to support the new buttonbar component }
|
|
|
|
function TVpContacts.FindContactIndexByName(const Name: string;
|
|
|
|
CaseInsensitive: Boolean): Integer;
|
|
|
|
var
|
|
|
|
Contact: TVpContact;
|
|
|
|
begin
|
|
|
|
result := -1;
|
|
|
|
Contact := FindContactByName(Name, CaseInsensitive);
|
|
|
|
if Contact <> nil then
|
|
|
|
Result := FContactsList.IndexOf(Contact);
|
|
|
|
end;
|
|
|
|
|
2018-06-10 16:42:16 +00:00
|
|
|
procedure TVpContacts.SetContactSort(const v: TVpContactSort);
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
|
|
|
if v <> FContactSort then begin
|
|
|
|
FContactSort := v;
|
|
|
|
Sort;
|
|
|
|
end;
|
|
|
|
end;
|
2016-09-06 19:59:25 +00:00
|
|
|
|
2022-08-18 17:44:47 +00:00
|
|
|
procedure TVpContacts.ExportVCardFile(const AFileName: String;
|
|
|
|
const AContacts: TVpContactArr);
|
|
|
|
var
|
|
|
|
vCards: TVpVCards;
|
|
|
|
lContact: TVpContact;
|
|
|
|
begin
|
|
|
|
vCards := TVpVCards.Create;
|
|
|
|
try
|
|
|
|
for lContact in AContacts do
|
|
|
|
if lContact <> nil then
|
|
|
|
vCards.Add(lContact.CreateVCard);
|
|
|
|
vCards.SaveToFile(AFileName);
|
|
|
|
finally
|
|
|
|
vCards.Free;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2022-08-11 20:32:13 +00:00
|
|
|
function TVpContacts.ImportVCardFile(const AFileName: String;
|
2022-08-19 10:53:49 +00:00
|
|
|
const APreview: Boolean = false; ADefaultCategory: Integer = -1): TVpContactArr;
|
2022-08-11 20:32:13 +00:00
|
|
|
const
|
|
|
|
BLOCK_SIZE = 10;
|
|
|
|
var
|
|
|
|
vCards: TVpVCards;
|
|
|
|
lContact: TVpContact;
|
|
|
|
contactCounter: Integer;
|
|
|
|
i: Integer;
|
|
|
|
id: Integer;
|
|
|
|
datastore: TVpCustomDatastore;
|
|
|
|
previewForm: TVpImportPreviewVCardForm;
|
|
|
|
begin
|
|
|
|
Result := nil;
|
|
|
|
SetLength(Result, BLOCK_SIZE);
|
|
|
|
contactCounter := 0;
|
|
|
|
|
|
|
|
datastore := Owner.Owner.Owner as TVpCustomDatastore;
|
|
|
|
|
|
|
|
vcards := TVpVCards.Create;
|
|
|
|
try
|
|
|
|
vCards.LoadFromFile(AFileName);
|
|
|
|
if vCards.Count = 0 then
|
|
|
|
begin
|
|
|
|
MessageDlg(Format(RSNoContactsFoundInVCARD, [AFileName]), mtInformation, [mbOK], 0);
|
|
|
|
SetLength(Result, 0);
|
|
|
|
exit;
|
|
|
|
end;
|
|
|
|
if APreview then
|
|
|
|
begin
|
|
|
|
previewForm := TVPImportPreviewVCardForm.Create(nil);
|
|
|
|
previewForm.Position := poMainFormcenter;
|
2022-08-19 10:53:49 +00:00
|
|
|
previewForm.Datastore := datastore;
|
2022-08-11 20:32:13 +00:00
|
|
|
previewForm.VCards := vCards;
|
|
|
|
if not previewForm.Execute then
|
|
|
|
begin
|
|
|
|
SetLength(Result, 0);
|
|
|
|
exit;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
for i := 0 to vcards.Count-1 do begin
|
2022-08-19 14:06:54 +00:00
|
|
|
if (not vCards[i].Checked) then
|
2022-08-11 20:32:13 +00:00
|
|
|
Continue;
|
|
|
|
id := datastore.GetNextID(ContactsTableName);
|
|
|
|
lContact := AddContact(id);
|
|
|
|
lContact.LoadFromVCard(vcards[i]);
|
|
|
|
Result[contactCounter] := lContact;
|
|
|
|
inc(contactCounter);
|
|
|
|
if contactCounter mod BLOCK_SIZE = 0 then
|
|
|
|
SetLength(Result, contactCounter + BLOCK_SIZE);
|
|
|
|
end;
|
|
|
|
|
|
|
|
SetLength(Result, contactCounter);
|
|
|
|
if Length(Result) = 0 then
|
|
|
|
MessageDlg(Format(RSNoContactsFoundInVCARD, [AFileName]), mtInformation, [mbOK], 0);
|
|
|
|
finally
|
|
|
|
if APreview then
|
|
|
|
previewForm.Free;
|
|
|
|
vCards.Free;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2008-02-03 12:05:55 +00:00
|
|
|
|
|
|
|
(*****************************************************************************)
|
|
|
|
{ TVpTask }
|
2016-09-06 19:59:25 +00:00
|
|
|
(*****************************************************************************)
|
2008-02-03 12:05:55 +00:00
|
|
|
|
|
|
|
constructor TVpTask.Create(Owner: TVpTasks);
|
|
|
|
begin
|
|
|
|
inherited Create;
|
|
|
|
FChanged := false;
|
|
|
|
FOwner := Owner;
|
|
|
|
SetCreatedOn(Now);
|
|
|
|
FDescription := '';
|
2016-09-05 14:04:22 +00:00
|
|
|
FItemIndex := -1;
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
destructor TVpTask.Destroy;
|
2016-09-05 14:04:22 +00:00
|
|
|
var
|
|
|
|
idx: Integer;
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
2016-09-06 19:59:25 +00:00
|
|
|
// Remove self from owners list
|
2016-09-05 14:04:22 +00:00
|
|
|
if (FOwner <> nil) then begin
|
|
|
|
idx := FOwner.FTaskList.IndexOf(Self);
|
|
|
|
if idx > -1 then FOwner.FTasklist.Delete(idx);
|
|
|
|
FOwner.Sort;
|
|
|
|
end;
|
2008-02-03 12:05:55 +00:00
|
|
|
inherited;
|
|
|
|
end;
|
|
|
|
|
2022-08-20 21:21:14 +00:00
|
|
|
function TVpTask.CreateICalTask(ACalendar: TVpICalendar): TVpICalToDo;
|
|
|
|
begin
|
|
|
|
Result := TVpICalToDo.Create(ACalendar);
|
|
|
|
Result.Summary := FDescription;
|
|
|
|
Result.Comment := FDetails;
|
|
|
|
Result.CreatedTime[false] := FCreatedOn;
|
|
|
|
Result.StartTime[false] := FCreatedOn;
|
|
|
|
Result.DueTime[false] := FDueDate;
|
|
|
|
if FComplete then
|
|
|
|
Result.CompletedTime[false] := FCompletedOn
|
|
|
|
else
|
|
|
|
Result.CompletedTime[false] := 0;
|
|
|
|
Result.Categories.Add(CategoryLabel(TVpCategoryType(FCategory)));
|
|
|
|
case TVpTaskPriority(FPriority) of
|
|
|
|
tpHigh: Result.Priority := 1;
|
|
|
|
tpNormal: Result.Priority := 5;
|
|
|
|
tpLow: Result.Priority := 9;
|
|
|
|
end;
|
|
|
|
if FComplete then
|
|
|
|
Result.Status := 'COMPLETED'
|
|
|
|
else
|
|
|
|
Result.Status := 'NEEDS-ACTION';
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
2022-08-10 21:21:17 +00:00
|
|
|
{ Converts the priority numbers from ical files (1=highest ... 9=lowest) to the
|
|
|
|
TvPlanit type TVpTaskPriority. }
|
|
|
|
class function TVpTask.GetTaskPriority(APriority:Integer): TVpTaskPriority;
|
|
|
|
begin
|
|
|
|
if APriority <= 3 then
|
|
|
|
Result := tpHigh
|
|
|
|
else if APriority >= 7 then
|
|
|
|
Result := tpLow
|
|
|
|
else
|
|
|
|
Result := tpNormal;
|
|
|
|
end;
|
|
|
|
|
2008-02-03 12:05:55 +00:00
|
|
|
function TVpTask.IsOverdue: Boolean;
|
|
|
|
begin
|
|
|
|
result := (Trunc(DueDate) < now + 1);
|
|
|
|
end;
|
|
|
|
|
2018-06-17 20:27:58 +00:00
|
|
|
procedure TVpTask.LoadFromICalendar(AEntry: TVpICalToDo);
|
|
|
|
var
|
|
|
|
cat: String;
|
|
|
|
ct: TVpCategoryType;
|
2022-08-10 21:21:17 +00:00
|
|
|
datastore: TVpCustomDatastore;
|
2018-06-17 20:27:58 +00:00
|
|
|
begin
|
|
|
|
if AEntry = nil then
|
|
|
|
exit;
|
|
|
|
|
|
|
|
{ Standard event properties }
|
|
|
|
FDescription := AEntry.Summary;
|
|
|
|
FDetails := AEntry.Comment;
|
|
|
|
FCreatedOn := AEntry.StartTime[false];
|
|
|
|
FDueDate := AEntry.DueTime[false];
|
|
|
|
FCompletedOn := AEntry.CompletedTime[false];
|
|
|
|
|
|
|
|
{ Status }
|
|
|
|
FComplete := SameText(AEntry.Status, 'COMPLETED');
|
|
|
|
|
|
|
|
{ Priority }
|
2022-08-10 21:21:17 +00:00
|
|
|
FPriority := ord(GetTaskPriority(AEntry.Priority));
|
2018-06-17 20:27:58 +00:00
|
|
|
|
|
|
|
{ Category }
|
|
|
|
{ tvplanit has only 1 category, ical may have several. We pick the first one
|
|
|
|
defined by TVpCategorytype. If none is found we select ctOther. }
|
2022-08-12 13:47:03 +00:00
|
|
|
if AEntry.PickedCategory > -1 then
|
|
|
|
FCategory := AEntry.PickedCategory
|
|
|
|
else
|
|
|
|
begin
|
|
|
|
FCategory :=ord(ctOther);
|
|
|
|
datastore := TVpCustomDatastore(Owner.Owner.Owner.Owner);
|
2022-08-19 10:53:49 +00:00
|
|
|
cat := datastore.FindBestCategory(AEntry.Categories);
|
2022-08-12 13:47:03 +00:00
|
|
|
for ct in TVpCategoryType do
|
|
|
|
if cat = CategoryLabel(ct) then
|
|
|
|
begin
|
|
|
|
FCategory := ord(ct);
|
|
|
|
break;
|
|
|
|
end;
|
|
|
|
end;
|
2018-06-17 20:27:58 +00:00
|
|
|
end;
|
|
|
|
|
2008-02-03 12:05:55 +00:00
|
|
|
procedure TVpTask.SetCategory(const Value: Integer);
|
|
|
|
begin
|
|
|
|
if Value <> FCategory then begin
|
|
|
|
FCategory := Value;
|
|
|
|
Changed := true;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpTask.SetChanged(const Value: Boolean);
|
|
|
|
begin
|
|
|
|
if Loading then Exit;
|
|
|
|
|
|
|
|
if Value <> FChanged then begin
|
|
|
|
FChanged := Value;
|
|
|
|
if FChanged then
|
|
|
|
Owner.FOwner.TasksDirty := true;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpTask.SetComplete(const Value: Boolean);
|
|
|
|
begin
|
|
|
|
if Value <> FComplete then begin
|
|
|
|
FComplete := Value;
|
|
|
|
if FComplete then
|
|
|
|
SetCompletedOn(Now)
|
|
|
|
else
|
|
|
|
SetCompletedOn(0.0);
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpTask.SetCompletedOn(const Value: TDateTIme);
|
|
|
|
begin
|
|
|
|
if Value <> FCompletedOn then begin
|
|
|
|
FCompletedOn := Value;
|
|
|
|
Changed := true;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpTask.SetCreatedOn(const Value: TDateTime);
|
|
|
|
begin
|
|
|
|
if Value <> FCreatedOn then begin
|
|
|
|
FCreatedOn := Value;
|
|
|
|
Changed := true;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpTask.SetDescription(const Value: string);
|
|
|
|
begin
|
|
|
|
if Value <> FDescription then begin
|
|
|
|
FDescription := Value;
|
|
|
|
Changed := true;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpTask.SetPriority(const Value: Integer);
|
|
|
|
begin
|
|
|
|
if Value <> FPriority then begin
|
|
|
|
FPriority := Value;
|
|
|
|
Changed := true;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpTask.SetDetails(const Value: string);
|
|
|
|
begin
|
|
|
|
if Value <> FDetails then begin
|
|
|
|
FDetails := Value;
|
|
|
|
Changed := true;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpTask.SetDueDate(const Value: TDateTime);
|
|
|
|
begin
|
2016-09-06 19:59:25 +00:00
|
|
|
// Trunc the time element from the DueDate value so that it reflects the Date only.
|
2008-02-03 12:05:55 +00:00
|
|
|
if FDueDate <> Trunc(Value) then begin
|
|
|
|
FDueDate := Trunc(Value);
|
|
|
|
Changed := true;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
|
|
(*****************************************************************************)
|
|
|
|
{ TVpTaskList }
|
2016-09-06 19:59:25 +00:00
|
|
|
(*****************************************************************************)
|
2008-02-03 12:05:55 +00:00
|
|
|
|
|
|
|
constructor TVpTasks.Create(Owner: TVpResource);
|
|
|
|
begin
|
|
|
|
inherited Create;
|
|
|
|
FOwner := Owner;
|
|
|
|
FTaskList := TList.Create;
|
2016-09-06 19:59:25 +00:00
|
|
|
FTaskList.Clear;
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
destructor TVpTasks.Destroy;
|
|
|
|
begin
|
|
|
|
ClearTasks;
|
|
|
|
FTaskList.Free;
|
|
|
|
inherited;
|
|
|
|
end;
|
|
|
|
|
2016-06-28 13:43:32 +00:00
|
|
|
function TVpTasks.AddTask(RecordID: Integer): TVpTask;
|
2008-02-03 12:05:55 +00:00
|
|
|
var
|
|
|
|
Task: TVpTask;
|
|
|
|
begin
|
|
|
|
Task := TVpTask.Create(Self);
|
|
|
|
try
|
2016-09-05 14:04:22 +00:00
|
|
|
Result := Task;
|
2008-02-03 12:05:55 +00:00
|
|
|
Task.Loading := true;
|
|
|
|
Task.FItemIndex := FTaskList.Add(result);
|
|
|
|
Task.RecordID := RecordID;
|
|
|
|
FOwner.TasksDirty := true;
|
|
|
|
Task.Loading := false;
|
|
|
|
{the data which to sort by has not yet been added to the object}
|
|
|
|
// Sort;
|
|
|
|
except
|
|
|
|
Task.Free;
|
|
|
|
raise EFailToCreateTask.Create;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2016-09-05 14:04:22 +00:00
|
|
|
function TVpTasks.Count: Integer;
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
|
|
|
result := FTaskList.Count;
|
|
|
|
end;
|
2022-08-20 21:21:14 +00:00
|
|
|
|
|
|
|
procedure TVpTasks.ExportICalFile(const AFileName: String;
|
|
|
|
const ATasks: TVpTaskArr);
|
|
|
|
var
|
|
|
|
cal: TVpICalendar;
|
|
|
|
lTask: TVpTask;
|
|
|
|
begin
|
|
|
|
cal := TVpICalendar.Create;
|
|
|
|
try
|
|
|
|
for lTask in ATasks do
|
|
|
|
if lTask <> nil then
|
|
|
|
cal.Add(lTask.CreateICalTask(cal));
|
|
|
|
cal.SaveToFile(AFileName);
|
|
|
|
finally
|
|
|
|
cal.Free;
|
|
|
|
end;
|
|
|
|
end;
|
2008-02-03 12:05:55 +00:00
|
|
|
|
2022-08-10 21:21:17 +00:00
|
|
|
function TVpTasks.ImportICalFile(const AFileName: String;
|
|
|
|
APreview: Boolean = false; ADefaultCategory: Integer = -1): TVpTaskArr;
|
2022-08-05 20:12:52 +00:00
|
|
|
const
|
|
|
|
BLOCK_SIZE = 10;
|
|
|
|
var
|
|
|
|
ical: TVpICalendar;
|
|
|
|
i: Integer;
|
|
|
|
id: Integer;
|
|
|
|
task: TVpTask;
|
|
|
|
taskCounter: Integer;
|
|
|
|
datastore: TVpCustomDatastore;
|
2022-08-11 16:46:32 +00:00
|
|
|
previewForm: TVpImportPreviewICalTaskForm = nil;
|
2022-08-05 20:12:52 +00:00
|
|
|
begin
|
|
|
|
Result := nil;
|
|
|
|
SetLength(Result, BLOCK_SIZE);
|
|
|
|
taskCounter := 0;
|
|
|
|
|
|
|
|
datastore := Owner.Owner.Owner as TVpCustomDatastore;
|
|
|
|
|
|
|
|
ical := TVpICalendar.Create;
|
|
|
|
try
|
|
|
|
ical.LoadFromFile(AFileName);
|
2022-08-10 21:21:17 +00:00
|
|
|
if ical.ToDoCount = 0 then
|
|
|
|
begin
|
|
|
|
MessageDlg(Format(RSNoTaskItemsFoundInICAL, [AFileName]), mtInformation, [mbOK], 0);
|
2022-08-11 20:32:13 +00:00
|
|
|
SetLength(Result, 0);
|
2022-08-10 21:21:17 +00:00
|
|
|
exit;
|
|
|
|
end;
|
|
|
|
if APreview then
|
|
|
|
begin
|
2022-08-11 16:46:32 +00:00
|
|
|
previewForm := TVpImportPreviewICalTaskForm.Create(nil);
|
2022-08-10 21:21:17 +00:00
|
|
|
previewForm.Position := poMainFormCenter;
|
|
|
|
previewForm.Datastore := datastore;
|
2022-08-12 13:47:03 +00:00
|
|
|
previewForm.Calendar := ical;
|
2022-08-10 21:21:17 +00:00
|
|
|
if ADefaultCategory <> -1 then
|
|
|
|
previewForm.DefaultCategory := CategoryLabel(TVpCategoryType(ADefaultCategory));
|
|
|
|
if not previewForm.Execute then
|
|
|
|
begin
|
|
|
|
SetLength(Result, 0);
|
|
|
|
exit;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2022-08-05 20:12:52 +00:00
|
|
|
for i := 0 to ical.Count-1 do begin
|
2022-08-19 14:06:54 +00:00
|
|
|
if (not ical[i].Checked) or (not (ical[i] is TVpICalToDo)) then
|
2022-08-05 20:12:52 +00:00
|
|
|
Continue;
|
2022-08-10 21:21:17 +00:00
|
|
|
|
2022-08-05 20:12:52 +00:00
|
|
|
id := dataStore.GetNextID(TasksTableName);
|
|
|
|
task := AddTask(id);
|
|
|
|
task.Changed := true;
|
|
|
|
task.LoadFromICalendar(TVpICalToDo(ical[i]));
|
|
|
|
if (task.Category = ord(ctOther)) and (ADefaultCategory <> -1) then
|
|
|
|
task.Category := ADefaultCategory;
|
|
|
|
Result[taskCounter] := task;
|
|
|
|
inc(taskCounter);
|
|
|
|
if taskCounter mod BLOCK_SIZE = 0 then
|
|
|
|
SetLength(Result, taskCounter + BLOCK_SIZE);
|
|
|
|
end;
|
|
|
|
SetLength(Result, taskCounter);
|
2022-08-10 21:21:17 +00:00
|
|
|
if Length(Result) = 0 then
|
|
|
|
MessageDlg(Format(RSNoTaskItemsFoundInICAL, [AFileName]), mtInformation, [mbOK], 0);
|
2022-08-05 20:12:52 +00:00
|
|
|
finally
|
2022-08-10 21:21:17 +00:00
|
|
|
if APreview then
|
|
|
|
previewForm.Free;
|
2022-08-05 20:12:52 +00:00
|
|
|
ical.Free;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2016-09-05 14:04:22 +00:00
|
|
|
function TVpTasks.IndexOf(ATask: TVpTask): Integer;
|
|
|
|
begin
|
|
|
|
Result := FTaskList.IndexOf(ATask);
|
|
|
|
end;
|
|
|
|
|
2008-02-03 12:05:55 +00:00
|
|
|
function TVpTasks.Last: TVpTask;
|
|
|
|
begin
|
2018-06-15 23:40:18 +00:00
|
|
|
result := TVpTask(FTaskList.Last);
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
function TVpTasks.First: TVpTask;
|
|
|
|
begin
|
2018-06-15 23:40:18 +00:00
|
|
|
result := TVpTask(FTaskList.First);
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
function TVpTasks.CountByDay(Date: TDateTime): Integer;
|
|
|
|
var
|
2016-09-06 19:59:25 +00:00
|
|
|
i: Integer;
|
|
|
|
ATask: TVpTask;
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
|
|
|
Result := 0;
|
|
|
|
|
2016-09-06 19:59:25 +00:00
|
|
|
for i := 0 to pred(Count) do begin
|
|
|
|
ATask := GetTask(i);
|
|
|
|
if Trunc(ATask.DueDate) = Trunc(Date) then
|
|
|
|
Inc(Result);
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
function TVpTasks.LastByDay(Date: TDateTime): TVpTask;
|
|
|
|
var
|
2016-09-06 19:59:25 +00:00
|
|
|
i: Integer;
|
|
|
|
ATask: TVpTask;
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
|
|
|
result := nil;
|
2016-09-06 19:59:25 +00:00
|
|
|
for i := 0 to pred(Count) do begin
|
|
|
|
ATask := GetTask(i);
|
|
|
|
if Trunc(ATask.CreatedOn) = Trunc(Date) then begin
|
2008-02-03 12:05:55 +00:00
|
|
|
Result := ATask;
|
2016-09-06 19:59:25 +00:00
|
|
|
break;
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
function TVpTasks.FirstByDay(Date: TDateTime): TVpTask;
|
|
|
|
var
|
2016-09-06 19:59:25 +00:00
|
|
|
i: Integer;
|
|
|
|
ATask: TVpTask;
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
|
|
|
result := nil;
|
2016-09-06 19:59:25 +00:00
|
|
|
for i := 0 to pred(Count) do begin
|
|
|
|
ATask := GetTask(i);
|
|
|
|
if Trunc(ATask.CreatedOn) = Trunc(Date) then begin
|
2008-02-03 12:05:55 +00:00
|
|
|
Result := ATask;
|
|
|
|
Break;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpTasks.ClearTasks;
|
|
|
|
begin
|
|
|
|
BatchUpdate(true);
|
|
|
|
try
|
|
|
|
while FTaskList.Count > 0 do
|
|
|
|
TVpTask(FTaskList.Last).Free;
|
|
|
|
finally
|
|
|
|
BatchUpdate(False);
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpTasks.BatchUpdate(value: Boolean);
|
|
|
|
begin
|
|
|
|
if Value then
|
|
|
|
Inc(FBatchUpdate)
|
|
|
|
else
|
|
|
|
Dec(FBatchUpdate);
|
|
|
|
|
|
|
|
if FBatchUpdate < 1 then begin
|
|
|
|
FBatchUpdate := 0;
|
|
|
|
Sort;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpTasks.Sort;
|
|
|
|
var
|
2016-09-06 19:59:25 +00:00
|
|
|
i: Integer;
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
2016-09-06 19:59:25 +00:00
|
|
|
// For greater performance, we don't sort while doing batch updates.
|
|
|
|
if FBatchUpdate > 0 then
|
|
|
|
exit;
|
|
|
|
FTaskList.Sort(@CompareTasks);
|
|
|
|
// Fix object embedded ItemIndexes // wp --- maybe this can be removed
|
|
|
|
for i:=0 to FTaskList.Count-1 do
|
|
|
|
TVpTask(FTaskList[i]).FItemIndex := i;
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpTasks.DeleteTask(Task: TVpTask);
|
|
|
|
begin
|
2016-09-06 19:59:25 +00:00
|
|
|
// Tasks automatically remove themselves from the list in their destructor
|
2008-02-03 12:05:55 +00:00
|
|
|
Task.Free;
|
|
|
|
end;
|
|
|
|
|
|
|
|
function TVpTasks.GetTask(Index: Integer): TVpTask;
|
|
|
|
begin
|
2018-06-15 23:40:18 +00:00
|
|
|
result := TVpTask(FTaskList[Index]);
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
2016-06-30 18:45:39 +00:00
|
|
|
|
2008-02-03 12:05:55 +00:00
|
|
|
end.
|