Componentes.Terceros.DevExp.../internal/x.42/2/ExpressScheduler 3/Sources/cxSchedulercxGridConnection.pas

2199 lines
72 KiB
ObjectPascal

{********************************************************************}
{ }
{ Developer Express Visual Component Library }
{ ExpressScheduler }
{ }
{ Copyright (c) 2003-2009 Developer Express Inc. }
{ ALL RIGHTS RESERVED }
{ }
{ The entire contents of this file is protected by U.S. and }
{ International Copyright Laws. Unauthorized reproduction, }
{ reverse-engineering, and distribution of all or any portion of }
{ the code contained in this file is strictly prohibited and may }
{ result in severe civil and criminal penalties and will be }
{ prosecuted to the maximum extent possible under the law. }
{ }
{ RESTRICTIONS }
{ }
{ THIS SOURCE CODE AND ALL RESULTING INTERMEDIATE FILES }
{ (DCU, OBJ, DLL, ETC.) ARE CONFIDENTIAL AND PROPRIETARY TRADE }
{ SECRETS OF DEVELOPER EXPRESS INC. THE REGISTERED DEVELOPER IS }
{ LICENSED TO DISTRIBUTE THE EXPRESSSCHEDULER AND ALL ACCOMPANYING }
{ VCL CONTROLS AS PART OF AN EXECUTABLE PROGRAM ONLY. }
{ }
{ THE SOURCE CODE CONTAINED WITHIN THIS FILE AND ALL RELATED }
{ FILES OR ANY PORTION OF ITS CONTENTS SHALL AT NO TIME BE }
{ COPIED, TRANSFERRED, SOLD, DISTRIBUTED, OR OTHERWISE MADE }
{ AVAILABLE TO OTHER INDIVIDUALS WITHOUT EXPRESS WRITTEN CONSENT }
{ AND PERMISSION FROM DEVELOPER EXPRESS INC. }
{ }
{ CONSULT THE END USER LICENSE AGREEMENT FOR INFORMATION ON }
{ ADDITIONAL RESTRICTIONS. }
{ }
{********************************************************************}
unit cxSchedulercxGridConnection;
{$I cxVer.inc}
interface
uses
Classes, SysUtils, Windows, Forms, Math, Graphics, Variants, Menus,
cxClasses, cxControls, cxCustomData, cxDataStorage, cxVariants,
cxLookAndFeels, cxSchedulerStorage, cxGridCustomView, cxGridCustomTableView,
cxSchedulerUtils, cxSchedulerStrs, cxSchedulerDialogs, cxGridTableView,
cxTextEdit, cxMemo, cxDropDownEdit, cxImageCombobox, cxCalendar, cxEdit,
cxColorCombobox, cxSpinEdit, cxProgressBar, cxMaskEdit, cxCheckBox,
cxGridPopupMenu, cxGridCustomPopupMenu, cxGridLevel, cxGrid,
cxSchedulerCustomControls;
type
TcxSchedulerGridBuildInPopupMenu = class;
TcxSchedulerGridBuildInPopupMenuController = class;
TcxSchedulerGridConnection = class;
TcxSchedulerFieldAdapter = class;
{ TcxSchedulerStorageDataSource }
TcxSchedulerStorageDataSource = class(TcxCustomDataSource)
private
FConnection: TcxSchedulerGridConnection;
function GetStorage: TcxCustomSchedulerStorage;
protected
function AddNewEvent: TcxDataRecordHandle;
function AppendRecord: TcxDataRecordHandle; override;
procedure DeleteRecord(ARecordHandle: TcxDataRecordHandle); override;
function GetAdapter(AItemHandle: TcxDataItemHandle; out Adapter: TcxSchedulerFieldAdapter): Boolean;
function GetRecordCount: Integer; override;
function GetValue(ARecordHandle: TcxDataRecordHandle; AItemHandle: TcxDataItemHandle): Variant; override;
function InsertRecord(ARecordHandle: TcxDataRecordHandle): TcxDataRecordHandle; override;
procedure SetValue(ARecordHandle: TcxDataRecordHandle; AItemHandle: TcxDataItemHandle; const AValue: Variant); override;
public
property Connection: TcxSchedulerGridConnection read FConnection;
property Storage: TcxCustomSchedulerStorage read GetStorage;
end;
{ TcxSchedulerFieldAdapter }
TcxSchedulerFieldAdapter = class(TPersistent)
private
FConnection: TcxSchedulerGridConnection;
FEditProperties: TcxCustomEditProperties;
FField: TcxCustomSchedulerStorageField;
FItem: TcxCustomGridTableItem;
FLink: TCollectionItem;
function GetCaption: string;
function GetProperties: TcxCustomEditProperties;
function GetReadOnly: Boolean;
function GetStorage: TcxCustomSchedulerStorage;
function GetVisible: Boolean;
procedure SetCaption(AValue: string);
procedure SetItem(AValue: TcxCustomGridTableItem);
procedure SetReadOnly(const AValue: Boolean);
procedure SetVisible(const AValue: Boolean);
protected
procedure DeleteItem; virtual;
procedure DoGetPropertiesForEdit(Sender: TcxCustomGridTableItem;
ARecord: TcxCustomGridRecord; var AProperties: TcxCustomEditProperties); virtual;
function GetEvent(ARecordIndex: Integer): TcxSchedulerEvent;
function GetNativeValue(ARecordIndex: Integer): Variant; virtual;
function GetPropertiesClass: TcxCustomEditPropertiesClass; virtual;
function GetPropertiesForEditClass: TcxCustomEditPropertiesClass; virtual;
function GetValue(ARecordIndex: Integer): Variant; virtual;
function GetValueTypeClass: TcxValueTypeClass; virtual;
procedure Initialize; virtual;
procedure InitializeAdapter; virtual;
procedure InitializeEditProperties; virtual;
procedure SetValue(ARecordIndex: Integer; const AValue: Variant); virtual;
property Link: TCollectionItem read FLink write FLink;
public
constructor Create(AConnection: TcxSchedulerGridConnection;
ALink: TCollectionItem); virtual;
constructor CreateWithField(AConnection: TcxSchedulerGridConnection;
AField: TcxCustomSchedulerStorageField); virtual;
destructor Destroy; override;
class procedure Register;
class procedure Unregister;
property Caption: string read GetCaption write SetCaption;
property Connection: TcxSchedulerGridConnection read FConnection;
property EditProperties: TcxCustomEditProperties read FEditProperties write FEditProperties;
property Field: TcxCustomSchedulerStorageField read FField;
property Item: TcxCustomGridTableItem read FItem write SetItem;
property Properties: TcxCustomEditProperties read GetProperties;
property ReadOnly: Boolean read GetReadOnly write SetReadOnly;
property Storage: TcxCustomSchedulerStorage read GetStorage;
property Values[ARecordIndex: Integer]: Variant read GetValue write SetValue;
property Visible: Boolean read GetVisible write SetVisible;
end;
TcxSchedulerFieldAdapterClass = class of TcxSchedulerFieldAdapter;
{ TcxSchedulerNullAdapter }
TcxSchedulerNullAdapter = class(TcxSchedulerFieldAdapter)
protected
procedure DeleteItem; override;
function GetValue(ARecordIndex: Integer): Variant; override;
procedure SetValue(ARecordIndex: Integer; const AValue: Variant); override;
public
constructor CreateWithItem(AConnection: TcxSchedulerGridConnection; AItem: TcxCustomGridTableItem); virtual;
end;
{ TcxSchedulerIntegerFieldAdapter }
TcxSchedulerIntegerFieldAdapter = class(TcxSchedulerFieldAdapter)
protected
function GetPropertiesClass: TcxCustomEditPropertiesClass; override;
function GetValueTypeClass: TcxValueTypeClass; override;
end;
{ TcxSchedulerTextFieldAdapter }
TcxSchedulerTextFieldAdapter = class(TcxSchedulerFieldAdapter)
protected
function GetPropertiesClass: TcxCustomEditPropertiesClass; override;
end;
{ TcxSchedulerCheckFieldAdapter }
TcxSchedulerCheckFieldAdapter = class(TcxSchedulerFieldAdapter)
protected
function GetPropertiesClass: TcxCustomEditPropertiesClass; override;
function GetValueTypeClass: TcxValueTypeClass; override;
end;
{ TcxSchedulerDateTimeFieldAdapter }
TcxSchedulerDateTimeFieldAdapter = class(TcxSchedulerFieldAdapter)
protected
function GetPropertiesClass: TcxCustomEditPropertiesClass; override;
procedure Initialize; override;
end;
{ TcxSchedulerImageComboFieldAdapter }
TcxSchedulerImageComboFieldAdapter = class(TcxSchedulerFieldAdapter)
private
function GetProperties: TcxImageComboBoxProperties;
protected
procedure AddItems(const AItemsValues: array of Variant);
function GetPropertiesClass: TcxCustomEditPropertiesClass; override;
public
property Properties: TcxImageComboBoxProperties read GetProperties;
end;
{ TcxSchedulerIDFieldAdapter }
TcxSchedulerIDFieldAdapter = class(TcxSchedulerFieldAdapter)
protected
function GetValue(ARecordIndex: Integer): Variant; override;
procedure SetValue(ARecordIndex: Integer; const AValue: Variant); override;
end;
{ TcxSchedulerTypeFieldAdapter }
TcxSchedulerTypeFieldAdapter = class(TcxSchedulerImageComboFieldAdapter)
protected
procedure Initialize; override;
end;
{ TcxSchedulerAllDayFieldAdapter }
TcxSchedulerAllDayFieldAdapter = class(TcxSchedulerCheckFieldAdapter)
protected
function GetValue(ARecordIndex: Integer): Variant; override;
procedure SetValue(ARecordIndex: Integer; const AValue: Variant); override;
end;
{ TcxSchedulerEnabledFieldAdapter }
TcxSchedulerEnabledFieldAdapter = class(TcxSchedulerCheckFieldAdapter)
protected
function GetValue(ARecordIndex: Integer): Variant; override;
procedure SetValue(ARecordIndex: Integer; const AValue: Variant); override;
end;
{ TcxSchedulerReminderFieldAdapter }
TcxSchedulerReminderFieldAdapter = class(TcxSchedulerCheckFieldAdapter)
protected
function GetValue(ARecordIndex: Integer): Variant; override;
procedure SetValue(ARecordIndex: Integer; const AValue: Variant); override;
end;
{ TcxSchedulerLabelColorFieldAdapter }
TcxSchedulerLabelColorFieldAdapter = class(TcxSchedulerImageComboFieldAdapter)
protected
function GetPropertiesClass: TcxCustomEditPropertiesClass; override;
function GetValue(ARecordIndex: Integer): Variant; override;
procedure Initialize; override;
procedure SetValue(ARecordIndex: Integer; const AValue: Variant); override;
end;
{ TcxSchedulerRecurringFieldAdapter }
TcxSchedulerRecurringFieldAdapter = class(TcxSchedulerFieldAdapter)
protected
function GetValue(ARecordIndex: Integer): Variant; override;
function GetValueTypeClass: TcxValueTypeClass; override;
end;
{ TcxSchedulerStateFieldAdapter }
TcxSchedulerStateFieldAdapter = class(TcxSchedulerImageComboFieldAdapter)
protected
function GetValue(ARecordIndex: Integer): Variant; override;
procedure Initialize; override;
end;
{ TcxSchedulerResourceIDFieldAdapter }
TcxSchedulerResourceIDFieldAdapter = class(TcxSchedulerFieldAdapter)
protected
function GetValueTypeClass: TcxValueTypeClass; override;
procedure Initialize; override;
end;
{ TcxSchedulerCompleteFieldAdapter }
TcxSchedulerCompleteFieldAdapter = class(TcxSchedulerFieldAdapter)
protected
function GetPropertiesClass: TcxCustomEditPropertiesClass; override;
function GetPropertiesForEditClass: TcxCustomEditPropertiesClass; override;
function GetValue(ARecordIndex: Integer): Variant; override;
procedure InitializeEditProperties; override;
procedure SetValue(ARecordIndex: Integer; const AValue: Variant); override;
end;
{ TcxSchedulerLinksFieldAdapter }
TcxSchedulerLinksFieldAdapter = class(TcxSchedulerFieldAdapter)
protected
function GetValue(ARecordIndex: Integer): Variant; override;
end;
{ TcxSchedulerStatusFieldAdapter }
TcxSchedulerStatusFieldAdapter = class(TcxSchedulerImageComboFieldAdapter)
protected
function GetValue(ARecordIndex: Integer): Variant; override;
procedure Initialize; override;
procedure SetValue(ARecordIndex: Integer; const AValue: Variant); override;
end;
{ TcxSchedulerGridConnection }
TcxSchedulerInitializeGridItemEvent = procedure(Sender: TcxSchedulerGridConnection;
AField: TcxCustomSchedulerStorageField; AItem: TcxCustomGridTableItem; Adapter: TcxSchedulerFieldAdapter) of object;
TcxSchedulerGetFieldAdapterEvent = procedure(Sender: TcxSchedulerGridConnection;
AField: TcxCustomSchedulerStorageField; var AdapterClass: TcxSchedulerFieldAdapterClass) of object;
TcxSchedulerConnectionEditEventEvent = procedure(Sender: TcxSchedulerGridConnection;
AEvent: TcxSchedulerControlEvent; var AModified: Boolean; var AHandled: Boolean) of object;
TcxSchedulerConnectionGridViewDblClickEvent = procedure (Sender: TObject;
var AHandled: Boolean) of object;
TcxSchedulerConnectionNewEventEvent = procedure(Sender: TcxSchedulerGridConnection;
var AEvent: TcxSchedulerControlEvent; var AHandled: Boolean) of object;
TcxSchedulerGridConnection = class(TComponent, IUnknown, IcxSchedulerStorageListener)
private
FActive: Boolean;
FAdapters: TCollection;
FEventEditInfo: TcxSchedulerEventEditInfo;
FGridPopupMenu: TcxSchedulerGridBuildInPopupMenu;
FGridPopupMenuEvents: TNotifyEvent;
FGridPopupMenuController: TcxSchedulerGridBuildInPopupMenuController;
FGridView: TcxCustomGridTableView;
FIsChanged: Boolean;
FLockCount: Integer;
FProvider: TcxSchedulerStorageDataSource;
FStorage: TcxCustomSchedulerStorage;
FOnEditEvent: TcxSchedulerConnectionEditEventEvent;
FOnGetFieldAdapter: TcxSchedulerGetFieldAdapterEvent;
FOnGridViewDblClick: TcxSchedulerConnectionGridViewDblClickEvent;
FOnInitializeItem: TcxSchedulerInitializeGridItemEvent;
FOnNewEvent: TcxSchedulerConnectionNewEventEvent;
function GetAdapter(AIndex: Integer): TcxSchedulerFieldAdapter;
function GetCount: Integer;
function GetDataController: TcxCustomDataController;
function GetEvent(ARowIndex: Integer): TcxSchedulerEvent;
function GetEventCount: Integer;
function GetIsDestroying: Boolean;
function GetIsLoading: Boolean;
function GetIsLocked: Boolean;
procedure SetActive(AValue: Boolean);
procedure SetGridPopupMenu(AValue: TcxSchedulerGridBuildInPopupMenu);
procedure SetGridView(AValue: TcxCustomGridTableView);
procedure SetStorage(AValue: TcxCustomSchedulerStorage);
procedure SetupBuildInPopupMenu;
procedure ReadLinks(Reader: TReader);
procedure WriteLinks(Writer: TWriter);
protected
function AddNewEvent(ARecurrence: Boolean = False;
AnAllDayEvent: Boolean = False): TcxSchedulerEvent; virtual;
function AdapterByItem(AItem: TcxCustomGridTableItem): TcxSchedulerFieldAdapter;
function AddAdapterLink(Adapter: TcxSchedulerFieldAdapter): TCollectionItem;
function AddAdapter(AField: TcxCustomSchedulerStorageField;
AdapterClass: TcxSchedulerFieldAdapterClass; ACaption: Pointer;
AVisible, ACanEdit: Boolean): TcxSchedulerFieldAdapter;
function AddAdapterEx(ALink: TCollectionItem;
AdapterClass: TcxSchedulerFieldAdapterClass): TcxSchedulerFieldAdapter;
function AddAdapterForCustomField(
AField: TcxCustomSchedulerStorageField): TcxSchedulerFieldAdapter;
procedure BeginUpdate;
function CreateDataSource: TcxSchedulerStorageDataSource;
procedure DefineProperties(Filer: TFiler); override;
procedure DblClickGridHandler(Sender: TObject); virtual;
function DoGridViewDblClick(Sender: TObject): Boolean;
procedure DoInitializeItem(AField: TcxCustomSchedulerStorageField;
AItem: TcxCustomGridTableItem; AAdapter: TcxSchedulerFieldAdapter); virtual;
procedure DoEditEventUsingDialog(AEvent: TcxSchedulerEvent;
ARecurrence: Boolean = False; AReadOnly: Boolean = False;
AForcePatternEditing: Boolean = False); virtual;
procedure DoGetItemAdapter(AField: TcxCustomSchedulerStorageField;
var AdapterClass: TcxSchedulerFieldAdapterClass); virtual;
procedure EndUpdate;
function GetEventEditInfo(AEvent: TcxSchedulerControlEvent;
ARecurrence: Boolean = False): TcxSchedulerEventEditInfo;
function GetFocusedEvent: TcxSchedulerEvent;
function GetIsFieldActive(AField: TcxCustomSchedulerStorageField): Boolean;
procedure Loaded; override;
procedure Notification(AComponent: TComponent; Operation: TOperation); override;
procedure OpenEventEditDialog(AForcePatternEditing: Boolean = False;
AReadOnly: Boolean = False);
procedure Reactivate;
procedure SetupView; virtual;
// IcxSchedulerStorageListener
procedure StorageChanged(Sender: TObject); virtual;
procedure StorageRemoved(Sender: TObject); virtual;
property Adapters[Index: Integer]: TcxSchedulerFieldAdapter read GetAdapter;
property Count: Integer read GetCount;
property DataController: TcxCustomDataController read GetDataController;
property EventCount: Integer read GetEventCount;
property Events[ARowIndex: Integer]: TcxSchedulerEvent read GetEvent;
property IsDestroying: Boolean read GetIsDestroying;
property IsLoading: Boolean read GetIsLoading;
property IsLocked: Boolean read GetIsLocked;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
// procedure Assign(Source: TPersistent); override;
procedure Refresh;
property Provider: TcxSchedulerStorageDataSource read FProvider;
published
property GridPopupMenu: TcxSchedulerGridBuildInPopupMenu read FGridPopupMenu write SetGridPopupMenu;
property GridPopupMenuEvents: TNotifyEvent read FGridPopupMenuEvents write FGridPopupMenuEvents;
property GridView: TcxCustomGridTableView read FGridView write SetGridView;
property Storage: TcxCustomSchedulerStorage read FStorage write SetStorage;
property Active: Boolean read FActive write SetActive default False;
property OnEditEvent: TcxSchedulerConnectionEditEventEvent read FOnEditEvent write FOnEditEvent;
property OnGetFieldAdapter: TcxSchedulerGetFieldAdapterEvent read FOnGetFieldAdapter write FOnGetFieldAdapter;
property OnGridViewDblClick: TcxSchedulerConnectionGridViewDblClickEvent read FOnGridViewDblClick write FOnGridViewDblClick;
property OnInitializeItem: TcxSchedulerInitializeGridItemEvent read FOnInitializeItem write FOnInitializeItem;
property OnNewEvent: TcxSchedulerConnectionNewEventEvent read FOnNewEvent write FOnNewEvent;
end;
{ TcxSchedulerGridBuildInPopupMenu }
TcxSchedulerGridBuildInPopupMenuItem = (bpmiNewEvent, bpmiNewAllDayEvent,
bpmiNewReccuringEvent, bpmiOpen, bpmiEditSeries,
bpmiShowTimeAs, bpmiLabel, bpmiDelete);
TcxSchedulerGridBuildInPopupMenuItems = set of TcxSchedulerGridBuildInPopupMenuItem;
TcxSchedulerGridBuildInPopupMenuPopupEvent = procedure (Sender: TcxSchedulerGridBuildInPopupMenu;
ABuiltInMenu: TPopupMenu; var AHandled: Boolean) of object;
TcxSchedulerGridBuildInPopupMenuClickEvent = procedure (Sender: TcxSchedulerGridBuildInPopupMenu;
AItem: TcxSchedulerGridBuildInPopupMenuItem; ASubItemIndex: Integer;
var AHandled: Boolean) of object;
TcxSchedulerGridBuildInPopupMenu = class(TPersistent)
private
FItems: TcxSchedulerGridBuildInPopupMenuItems;
FOwner: TcxSchedulerGridConnection;
FPopupMenu: TComponent;
FUseBuiltInPopupMenu: Boolean;
FOnPopup: TcxSchedulerGridBuildInPopupMenuPopupEvent;
FOnClick: TcxSchedulerGridBuildInPopupMenuClickEvent;
procedure SetPopupMenu(AValue: TComponent);
protected
procedure Notification(AComponent: TComponent; Operation: TOperation);
public
constructor Create(ASchedulerGridConnection: TcxSchedulerGridConnection);
destructor Destroy; override;
procedure Assign(Source: TPersistent); override;
published
property Items: TcxSchedulerGridBuildInPopupMenuItems
read FItems write FItems default [bpmiNewEvent, bpmiNewAllDayEvent,
bpmiNewReccuringEvent, bpmiOpen, bpmiEditSeries,
bpmiShowTimeAs, bpmiLabel, bpmiDelete];
property PopupMenu: TComponent read FPopupMenu write SetPopupMenu;
property UseBuiltInPopupMenu: Boolean read FUseBuiltInPopupMenu write FUseBuiltInPopupMenu default True;
property OnClick: TcxSchedulerGridBuildInPopupMenuClickEvent read FOnClick write FOnClick;
property OnPopup: TcxSchedulerGridBuildInPopupMenuPopupEvent read FOnPopup write FOnPopup;
end;
TcxSchedulerGridBuildInPopupMenuController = class
private
FEvent: TcxSchedulerEvent;
FGridPopupMenu: TcxGridPopupMenu;
FInternalMenu: TPopupMenu;
FMenuInfo: TcxPopupMenuInfo;
FOwner: TcxSchedulerGridConnection;
function CanEventEdit: Boolean;
procedure CreateLabelItems;
procedure CreateTimeItems;
procedure DeleteEvent;
procedure EditEvent;
procedure EditSeries;
function GetBuildInPopupMenu: TcxSchedulerGridBuildInPopupMenu;
function GetCommand(AItem: TcxSchedulerGridBuildInPopupMenuItem;
ASubItemIndex: Integer): Integer;
function GetItems: TcxSchedulerGridBuildInPopupMenuItems;
function GetStorage: TcxCustomSchedulerStorage;
procedure GridMenuPopup(ASenderMenu: TComponent;
AHitTest: TcxCustomGridHitTest; X, Y: Integer);
function IsEventsReadOnly: Boolean;
procedure NewAllDayEvent;
procedure NewEvent;
procedure NewRecurrence;
procedure SetEvent;
procedure SetEventLabelColor(AColor: Integer);
procedure SetEventState(AState: Integer);
procedure UnpackCommand(ACommand: Integer;
out AItem: TcxSchedulerGridBuildInPopupMenuItem; out ASubItemIndex: Integer);
protected
function AddValidSeparator(AOwner: TMenuItem): TMenuItem;
procedure CreateInternalMenu;
procedure CreateItems;
function CreateSubItem(AOwner: TMenuItem; const ACaption: string; ACommand: Integer = -1;
AImageIndex: Integer = -1; AEnabled: Boolean = True; AChecked: Boolean = False): TMenuItem;
function DoOnClick(ACommand: Integer): Boolean;
function DoOnPopup: Boolean;
function IsValidCommand(ACommand: Integer): Boolean;
procedure OnItemClickHandler(Sender: TObject);
property BuildInPopupMenu: TcxSchedulerGridBuildInPopupMenu read GetBuildInPopupMenu;
property Items: TcxSchedulerGridBuildInPopupMenuItems read GetItems;
property Storage: TcxCustomSchedulerStorage read GetStorage;
public
constructor Create(ASchedulerGridConnection: TcxSchedulerGridConnection);
destructor Destroy; override;
function Popup(X, Y: Integer): Boolean;
end;
implementation
type
TStorageAccess = class(TcxSchedulerStorage);
TStorageFieldAccess = class(TcxCustomSchedulerStorageField);
{ TcxSchedulerFieldAdapters }
TcxSchedulerFieldAdapters = class(TCollection)
private
FOwner: TPersistent;
protected
function GetOwner: TPersistent; override;
public
constructor Create(AOwner: TcxSchedulerGridConnection); reintroduce; overload;
end;
{ TcxSchedulerFieldAdapterItemLink }
TcxSchedulerFieldAdapterItemLink = class(TCollectionItem)
private
FFieldIndex: Integer;
FLink: TcxSchedulerFieldAdapter;
function GetAdapterClass: string;
function GetConnection: TcxSchedulerGridConnection;
function GetFieldIndex: Integer;
function GetItem: TcxCustomGridTableItem;
procedure SetAdapterClass(AValue: string);
procedure SetFieldIndex(AValue: Integer);
procedure SetItem(AValue: TcxCustomGridTableItem);
protected
procedure AssignFieldByIndex;
public
destructor Destroy; override;
property Connection: TcxSchedulerGridConnection read GetConnection;
property Link: TcxSchedulerFieldAdapter read FLink write FLink;
published
property AdapterClass: string read GetAdapterClass write SetAdapterClass;
property FieldIndex: Integer read GetFieldIndex write SetFieldIndex default -1;
property Item: TcxCustomGridTableItem read GetItem write SetItem;
end;
function IsPopupMenuPossible(AGridView: TcxCustomGridTableView;
out AGrid: TcxGrid): Boolean;
var
ALevel: TComponent;
AControl: TcxControl;
begin
Result := False;
AGrid := nil;
if AGridView <> nil then
begin
ALevel := AGridView.Level;
if (ALevel <> nil) and (ALevel is TcxGridLevel) then
begin
AControl := TcxGridLevel(ALevel).Control;
if (AControl <> nil) and (AControl is TcxGrid) then
begin
AGrid := TcxGrid(AControl);
Result := True;
end;
end;
end;
end;
{ TcxSchedulerStorageDataSource }
function TcxSchedulerStorageDataSource.AddNewEvent: TcxDataRecordHandle;
var
AEvent: TcxSchedulerEvent;
begin
Result := nil;
AEvent := Connection.AddNewEvent();
if AEvent <> nil then
Result := GetRecordHandleByIndex(AEvent.RecordIndex);
end;
function TcxSchedulerStorageDataSource.AppendRecord: TcxDataRecordHandle;
begin
Result := AddNewEvent;
end;
procedure TcxSchedulerStorageDataSource.DeleteRecord(
ARecordHandle: TcxDataRecordHandle);
var
AEvent: TcxSchedulerEvent;
begin
Connection.Storage.BeginUpdate;
try
AEvent := Connection.Storage.Events[GetRecordIndexByHandle(ARecordHandle)];
if AEvent.EventType in [etCustom, etOccurrence] then
AEvent.Delete;
AEvent.Delete;
finally
Connection.Storage.EndUpdate;
end;
end;
function TcxSchedulerStorageDataSource.GetAdapter(
AItemHandle: TcxDataItemHandle; out Adapter: TcxSchedulerFieldAdapter): Boolean;
begin
Adapter := Connection.AdapterByItem(
DataController.GetItem(Integer(AItemHandle)) as TcxCustomGridTableItem);
Result := Adapter <> nil;
end;
function TcxSchedulerStorageDataSource.GetRecordCount: Integer;
begin
if Storage = nil then
Result := 0
else
Result := Storage.EventCount;
end;
function TcxSchedulerStorageDataSource.GetValue(
ARecordHandle: TcxDataRecordHandle; AItemHandle: TcxDataItemHandle): Variant;
var
Adapter: TcxSchedulerFieldAdapter;
begin
if (Storage <> nil) and GetAdapter(AItemHandle, Adapter) then
Result := Adapter.GetValue(GetRecordIndexByHandle(ARecordHandle))
else
Result := Null;
end;
function TcxSchedulerStorageDataSource.InsertRecord(
ARecordHandle: TcxDataRecordHandle): TcxDataRecordHandle;
begin
Result := AddNewEvent;
end;
procedure TcxSchedulerStorageDataSource.SetValue(
ARecordHandle: TcxDataRecordHandle; AItemHandle: TcxDataItemHandle; const AValue: Variant);
var
Adapter: TcxSchedulerFieldAdapter;
begin
Connection.BeginUpdate;
try
if (Storage <> nil) and GetAdapter(AItemHandle, Adapter) then
Adapter.SetValue(GetRecordIndexByHandle(ARecordHandle), AValue);
finally
Connection.EndUpdate;
end;
end;
function TcxSchedulerStorageDataSource.GetStorage: TcxCustomSchedulerStorage;
begin
Result := FConnection.Storage;
end;
{ TcxSchedulerFieldAdapter }
constructor TcxSchedulerFieldAdapter.Create(
AConnection: TcxSchedulerGridConnection; ALink: TCollectionItem);
begin
FConnection := AConnection;
FLink := ALink;
end;
constructor TcxSchedulerFieldAdapter.CreateWithField(
AConnection: TcxSchedulerGridConnection; AField: TcxCustomSchedulerStorageField);
begin
Create(AConnection, AConnection.AddAdapterLink(Self));
FField := AField;
with Connection do
begin
FItem := GridView.CreateItem as TcxCustomGridTableItem;
FItem.Name := CreateUniqueName(GridView.Owner, GridView, FItem,
Copy(FItem.ClassName, 1, Pos('Item', FItem.ClassName) - 1), '');
end;
FItem.DataBinding.ValueTypeClass := GetValueTypeClass;
FItem.PropertiesClass := GetPropertiesClass;
InitializeAdapter;
end;
destructor TcxSchedulerFieldAdapter.Destroy;
begin
FreeAndNil(FEditProperties);
if FItem <> nil then
FItem.RemoveFreeNotification(Connection);
DeleteItem;
inherited Destroy;
end;
class procedure TcxSchedulerFieldAdapter.Register;
begin
Classes.RegisterClass(Self);
end;
class procedure TcxSchedulerFieldAdapter.Unregister;
begin
Classes.UnRegisterClass(Self);
end;
procedure TcxSchedulerFieldAdapter.DeleteItem;
begin
if (FItem <> nil) and ([csDestroying, csLoading] *
(FItem.ComponentState + Connection.ComponentState) = []) then
FreeAndNil(FItem);
end;
procedure TcxSchedulerFieldAdapter.DoGetPropertiesForEdit(
Sender: TcxCustomGridTableItem; ARecord: TcxCustomGridRecord;
var AProperties: TcxCustomEditProperties);
begin
if EditProperties <> nil then
AProperties := EditProperties;
end;
function TcxSchedulerFieldAdapter.GetEvent(
ARecordIndex: Integer): TcxSchedulerEvent;
begin
Result := Storage.Events[ARecordIndex];
end;
function TcxSchedulerFieldAdapter.GetNativeValue(ARecordIndex: Integer): Variant;
var
AEvent: TcxSchedulerEvent;
begin
Result := Storage.Values[ARecordIndex, Field.Index];
if VarIsNull(Result) then
begin
AEvent := GetEvent(ARecordIndex);
Result := AEvent.Values[Field.Index];
end;
end;
function TcxSchedulerFieldAdapter.GetPropertiesClass: TcxCustomEditPropertiesClass;
begin
Result := TcxTextEditProperties;
end;
function TcxSchedulerFieldAdapter.GetPropertiesForEditClass: TcxCustomEditPropertiesClass;
begin
Result := nil;
end;
function TcxSchedulerFieldAdapter.GetValue(ARecordIndex: Integer): Variant;
begin
Result := GetNativeValue(ARecordIndex);
end;
function TcxSchedulerFieldAdapter.GetValueTypeClass: TcxValueTypeClass;
begin
Result := TStorageAccess(Storage).GetFieldValueTypeClass(Field)
end;
procedure TcxSchedulerFieldAdapter.Initialize;
begin
end;
procedure TcxSchedulerFieldAdapter.InitializeAdapter;
begin
Initialize;
InitializeEditProperties;
end;
procedure TcxSchedulerFieldAdapter.InitializeEditProperties;
begin
if csDesigning in Connection.ComponentState then Exit;
if GetPropertiesForEditClass <> nil then
begin
FreeAndNil(FEditProperties);
FEditProperties := GetPropertiesForEditClass.Create(FConnection);
end;
if (FEditProperties <> nil) and not Assigned(FItem.OnGetPropertiesForEdit) then
FItem.OnGetPropertiesForEdit := DoGetPropertiesForEdit;
end;
procedure TcxSchedulerFieldAdapter.SetValue(
ARecordIndex: Integer; const AValue: Variant);
begin
Storage.Events[ARecordIndex].Values[Field.Index] := AValue;
end;
function TcxSchedulerFieldAdapter.GetCaption: string;
begin
Result := Item.Caption;
end;
function TcxSchedulerFieldAdapter.GetProperties: TcxCustomEditProperties;
begin
Result := Item.Properties;
end;
function TcxSchedulerFieldAdapter.GetReadOnly: Boolean;
begin
Result := Item.Options.Editing;
end;
function TcxSchedulerFieldAdapter.GetStorage: TcxCustomSchedulerStorage;
begin
Result := Connection.Storage;
end;
function TcxSchedulerFieldAdapter.GetVisible: Boolean;
begin
Result := Item.Visible;
end;
procedure TcxSchedulerFieldAdapter.SetCaption(AValue: string);
begin
Item.Caption := AValue;
end;
procedure TcxSchedulerFieldAdapter.SetItem(AValue: TcxCustomGridTableItem);
begin
if FItem = AValue then Exit;
if FItem <> nil then
Item.RemoveFreeNotification(Connection);
FItem := AValue;
if Item <> nil then
begin
Item.FreeNotification(Connection);
InitializeEditProperties;
end;
end;
procedure TcxSchedulerFieldAdapter.SetReadOnly(const AValue: Boolean);
begin
Item.Options.Editing := not AValue;
end;
procedure TcxSchedulerFieldAdapter.SetVisible(const AValue: Boolean);
begin
Item.Visible := AValue;
end;
{ TcxSchedulerNullAdapter }
constructor TcxSchedulerNullAdapter.CreateWithItem(
AConnection: TcxSchedulerGridConnection; AItem: TcxCustomGridTableItem);
begin
inherited CreateWithField(AConnection, nil);
Item := AItem;
end;
procedure TcxSchedulerNullAdapter.DeleteItem;
begin
end;
function TcxSchedulerNullAdapter.GetValue(ARecordIndex: Integer): Variant;
begin
Result := Null;
end;
procedure TcxSchedulerNullAdapter.SetValue(ARecordIndex: Integer; const AValue: Variant);
begin
end;
{ TcxSchedulerIntegerFieldAdapter }
function TcxSchedulerIntegerFieldAdapter.GetPropertiesClass: TcxCustomEditPropertiesClass;
begin
Result := inherited GetPropertiesClass;
end;
function TcxSchedulerIntegerFieldAdapter.GetValueTypeClass: TcxValueTypeClass;
begin
Result := TcxIntegerValueType;
end;
{ TcxSchedulerEventTextFieldAdapter }
function TcxSchedulerTextFieldAdapter.GetPropertiesClass: TcxCustomEditPropertiesClass;
begin
Result := TcxMemoProperties;
end;
{ TcxSchedulerCheckFieldAdapter }
function TcxSchedulerCheckFieldAdapter.GetPropertiesClass: TcxCustomEditPropertiesClass;
begin
Result := TcxCheckBoxProperties;
end;
function TcxSchedulerCheckFieldAdapter.GetValueTypeClass: TcxValueTypeClass;
begin
Result := TcxBooleanValueType;
end;
{ TcxSchedulerDateTimeFieldAdapter }
function TcxSchedulerDateTimeFieldAdapter.GetPropertiesClass: TcxCustomEditPropertiesClass;
begin
Result := TcxDateEditProperties;
end;
procedure TcxSchedulerDateTimeFieldAdapter.Initialize;
begin
TcxDateEditProperties(Properties).Kind := ckDateTime;
end;
{ TcxSchedulerImageComboFieldAdapter }
procedure TcxSchedulerImageComboFieldAdapter.AddItems(
const AItemsValues: array of Variant);
var
AIndex: Integer;
begin
Properties.Items.Clear;
for AIndex := Low(AItemsValues) to High(AItemsValues) div 3 do
if AItemsValues[AIndex * 3 + 2] <> -1 then
with Properties.Items.Add() do
begin
Description := AItemsValues[AIndex * 3];
Value := AItemsValues[AIndex * 3 + 1];
ImageIndex := AItemsValues[AIndex * 3 + 2];
end;
ReadOnly := True;
end;
function TcxSchedulerImageComboFieldAdapter.GetPropertiesClass: TcxCustomEditPropertiesClass;
begin
Result := TcxImageComboBoxProperties;
end;
function TcxSchedulerImageComboFieldAdapter.GetProperties: TcxImageComboBoxProperties;
begin
Result := TcxImageComboBoxProperties(inherited Properties);
end;
{ TcxSchedulerIDFieldAdapter }
function TcxSchedulerIDFieldAdapter.GetValue(ARecordIndex: Integer): Variant;
begin
if Field = nil then
Result := GetEvent(ARecordIndex).ID
else
begin
Result := GetEvent(ARecordIndex).ParentID;
if VarIsNumeric(Result) and (Result = -2) then
Result := Null;
end;
end;
procedure TcxSchedulerIDFieldAdapter.SetValue(
ARecordIndex: Integer; const AValue: Variant);
begin
end;
{ TcxSchedulerTypeFieldAdapter }
procedure TcxSchedulerTypeFieldAdapter.Initialize;
begin
Properties.Images := EventImages;
Properties.ShowDescriptions := False;
AddItems([cxGetResourceString(@scxNone), Integer(etNone), -1,// MaxInt,
cxGetResourceString(@scxPattern), Integer(etPattern), Integer(2),
cxGetResourceString(@scxOccurrence), Integer(etOccurrence), -1,//MaxInt - 1,
cxGetResourceString(@scxException), Integer(etException), -1,// MaxInt - 2,
cxGetResourceString(@scxCustom), Integer(etCustom), Integer(3)]);
Properties.Buttons.Clear;
end;
{ TcxSchedulerAllDayFieldAdapter }
function TcxSchedulerAllDayFieldAdapter.GetValue(
ARecordIndex: Integer): Variant;
begin
Result := GetEvent(ARecordIndex).AllDayEvent;
end;
procedure TcxSchedulerAllDayFieldAdapter.SetValue(
ARecordIndex: Integer; const AValue: Variant);
begin
GetEvent(ARecordIndex).AllDayEvent := AValue;
end;
{ TcxSchedulerEnabledFieldAdapter }
function TcxSchedulerEnabledFieldAdapter.GetValue(
ARecordIndex: Integer): Variant;
begin
Result := GetEvent(ARecordIndex).Enabled;
end;
procedure TcxSchedulerEnabledFieldAdapter.SetValue(
ARecordIndex: Integer; const AValue: Variant);
begin
GetEvent(ARecordIndex).Enabled := AValue;
end;
{ TcxSchedulerReminderFieldAdapter }
function TcxSchedulerReminderFieldAdapter.GetValue(
ARecordIndex: Integer): Variant;
begin
Result := GetEvent(ARecordIndex).Reminder;
end;
procedure TcxSchedulerReminderFieldAdapter.SetValue(
ARecordIndex: Integer; const AValue: Variant);
begin
GetEvent(ARecordIndex).Reminder := AValue;
end;
{ TcxSchedulerLabelColorFieldAdapter }
function TcxSchedulerLabelColorFieldAdapter.GetPropertiesClass: TcxCustomEditPropertiesClass;
begin
Result := TcxColorComboBoxProperties;
end;
function TcxSchedulerLabelColorFieldAdapter.GetValue(
ARecordIndex: Integer): Variant;
begin
Result := inherited GetValue(ARecordIndex);
if VarIsNumeric(Result) and (Result = clDefault) then
Result := Null;
end;
procedure TcxSchedulerLabelColorFieldAdapter.Initialize;
var
I: Integer;
begin
with TcxColorComboBoxProperties(Properties) do
try
BeginUpdate();
Items.ClearNonCustom;
for I := 1 to EventLabels.Count - 1 do
Items.AddColor(EventLabels[I].Color, EventLabels[I].Caption);
DefaultColor := EventLabels[0].Color;
DefaultDescription := EventLabels[0].Caption;
DefaultColorStyle := cxdcClear;
NamingConvention := cxncNone;
finally
EndUpdate();
end;
end;
procedure TcxSchedulerLabelColorFieldAdapter.SetValue(
ARecordIndex: Integer; const AValue: Variant);
begin
if VarIsNull(AValue) then
inherited SetValue(ARecordIndex, clDefault)
else
inherited SetValue(ARecordIndex, AValue);
end;
{ TcxSchedulerRecurringFieldAdapter }
function TcxSchedulerRecurringFieldAdapter.GetValue(ARecordIndex: Integer): Variant;
begin
if Assigned(cxGetRecurrenceDescriptionStringProc) then
Result := cxGetRecurrenceDescriptionStringProc(GetEvent(ARecordIndex).RecurrenceInfo)
else
Result := '';
end;
function TcxSchedulerRecurringFieldAdapter.GetValueTypeClass: TcxValueTypeClass;
begin
Result := TcxStringValueType;
end;
{ TcxSchedulerStateFieldAdapter }
function TcxSchedulerStateFieldAdapter.GetValue(ARecordIndex: Integer): Variant;
begin
Result := inherited GetValue(ARecordIndex);
with GetEvent(ARecordIndex) do
begin
if EventType = etCustom then
Result := State
else
Result := State;
end;
end;
procedure TcxSchedulerStateFieldAdapter.Initialize;
begin
AddItems([
cxGetResourceString(@scxFree), tlsFree, 0,
cxGetResourceString(@scxTentative), tlsTentative, 1,
cxGetResourceString(@scxBusy), tlsBusy, 2,
cxGetResourceString(@scxOutOfOffice), tlsOutOfOffice, 3]);
Properties.Images := TimeLinePatterns;
end;
{ TcxSchedulerResourceIDFieldAdapter }
function TcxSchedulerResourceIDFieldAdapter.GetValueTypeClass: TcxValueTypeClass;
begin
Result := TcxStringValueType;
end;
procedure TcxSchedulerResourceIDFieldAdapter.Initialize;
begin
end;
{ TcxSchedulerCompleteFieldAdapter }
function TcxSchedulerCompleteFieldAdapter.GetPropertiesClass: TcxCustomEditPropertiesClass;
begin
Result := TcxProgressBarProperties;
end;
function TcxSchedulerCompleteFieldAdapter.GetPropertiesForEditClass: TcxCustomEditPropertiesClass;
begin
Result := TcxSpinEditProperties;
end;
function TcxSchedulerCompleteFieldAdapter.GetValue(ARecordIndex: Integer): Variant;
begin
Result := inherited GetValue(ARecordIndex);
if VarIsNumeric(Result) then
Result := Min(100, Max(0, Result))
else
Result := 0;
end;
procedure TcxSchedulerCompleteFieldAdapter.InitializeEditProperties;
begin
inherited InitializeEditProperties;
if EditProperties = nil then Exit;
with TcxSpinEditProperties(EditProperties) do
begin
DisplayFormat := cxGetResourceString(@scxCompleteDisplayFormat);
MaxValue := 100;
MinValue := 0;
end;
end;
procedure TcxSchedulerCompleteFieldAdapter.SetValue(
ARecordIndex: Integer; const AValue: Variant);
begin
if VarIsNull(AValue) then
GetEvent(ARecordIndex).TaskComplete := 0
else
GetEvent(ARecordIndex).TaskComplete := AValue
end;
{ TcxSchedulerLinksFieldAdapter }
function TcxSchedulerLinksFieldAdapter.GetValue(
ARecordIndex: Integer): Variant;
begin
Result := GetEvent(ARecordIndex).TaskLinks.DisplayText;
end;
{ TcxSchedulerStatusFieldAdapter }
function TcxSchedulerStatusFieldAdapter.GetValue(ARecordIndex: Integer): Variant;
begin
Result := GetEvent(ARecordIndex).TaskStatus;
end;
procedure TcxSchedulerStatusFieldAdapter.Initialize;
begin
inherited Initialize;
AddItems([cxGetResourceString(@scxNotStarted), Integer(tsNotStarted), -1,//MaxInt,
cxGetResourceString(@scxInProgress), Integer(tsInProgress), -1,// MaxInt - 1,
cxGetResourceString(@scxComplete), Integer(tsComplete), -1,// MaxInt - 2,
cxGetResourceString(@scxWaiting), Integer(tsWaiting), -1,// MaxInt - 3,
cxGetResourceString(@scxDeferred), Integer(tsDeferred), -1]); // MaxInt - 4
end;
procedure TcxSchedulerStatusFieldAdapter.SetValue(
ARecordIndex: Integer; const AValue: Variant);
begin
if VarIsNull(AValue) then
GetEvent(ARecordIndex).TaskStatus := tsNotStarted
else
GetEvent(ARecordIndex).TaskStatus := AValue;
end;
{ TcxSchedulerFieldAdapters }
constructor TcxSchedulerFieldAdapters.Create(AOwner: TcxSchedulerGridConnection);
begin
inherited Create(TcxSchedulerFieldAdapterItemLink);
FOwner := AOwner;
end;
function TcxSchedulerFieldAdapters.GetOwner: TPersistent;
begin
Result := FOwner;
end;
{ TcxSchedulerFieldAdapterItemLink }
destructor TcxSchedulerFieldAdapterItemLink.Destroy;
begin
FLink.Free;
inherited Destroy;
end;
procedure TcxSchedulerFieldAdapterItemLink.AssignFieldByIndex;
begin
if FFieldIndex < 0 then
FLink.FField := nil
else
FLink.FField := TStorageAccess(Connection.Storage).DataFields[FFieldIndex];
end;
function TcxSchedulerFieldAdapterItemLink.GetAdapterClass: string;
begin
Result := FLink.ClassName;
end;
function TcxSchedulerFieldAdapterItemLink.GetConnection: TcxSchedulerGridConnection;
begin
Result := Collection.Owner as TcxSchedulerGridConnection;
end;
function TcxSchedulerFieldAdapterItemLink.GetFieldIndex: Integer;
begin
if FLink.FField <> nil then
Result := FLink.FField.Index
else
Result := -1;
end;
function TcxSchedulerFieldAdapterItemLink.GetItem: TcxCustomGridTableItem;
begin
Result := FLink.Item;
end;
procedure TcxSchedulerFieldAdapterItemLink.SetAdapterClass(AValue: string);
begin
FLink := Connection.AddAdapterEx(Self, TcxSchedulerFieldAdapterClass(FindClass(AValue)));
end;
procedure TcxSchedulerFieldAdapterItemLink.SetFieldIndex(AValue: Integer);
begin
FFieldIndex := AValue;
end;
procedure TcxSchedulerFieldAdapterItemLink.SetItem(AValue: TcxCustomGridTableItem);
begin
FLink.Item := AValue;
end;
{ TcxSchedulerGridConnection }
constructor TcxSchedulerGridConnection.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FAdapters := TcxSchedulerFieldAdapters.Create(Self);
FGridPopupMenu := TcxSchedulerGridBuildInPopupMenu.Create(Self);
FEventEditInfo := TcxSchedulerEventEditInfo.Create;
FProvider := CreateDataSource;
FProvider.FConnection := Self;
end;
destructor TcxSchedulerGridConnection.Destroy;
begin
GridView := nil;
Storage := nil;
FProvider.Free;
FEventEditInfo.Free;
FGridPopupMenu.Free;
FAdapters.Free;
FGridPopupMenuController.Free;
inherited Destroy;
end;
{procedure TcxSchedulerGridConnection.Assign(Source: TPersistent);
begin
if Source is TcxSchedulerGridConnection then
begin
GridPopupMenu := TcxSchedulerGridConnection(Source).GridPopupMenu;
end;
inherited Assign(Source);
end;}
procedure TcxSchedulerGridConnection.Refresh;
var
APrevActive: Boolean;
begin
APrevActive := Active;
Active := False;
Active := APrevActive;
end;
function TcxSchedulerGridConnection.AddNewEvent(
ARecurrence: Boolean = False; AnAllDayEvent: Boolean = False): TcxSchedulerEvent;
var
AEvent: TcxSchedulerControlEvent;
AHandled, AModified: Boolean;
begin
Result := nil;
AEvent := TcxSchedulerControlEvent.Create(Storage);
try
AHandled := False;
if Assigned(FOnNewEvent) then
FOnNewEvent(Self, AEvent, AHandled);
if not AHandled and (AEvent <> nil) then
begin
AEvent.AllDayEvent := AnAllDayEvent;
cxShowEventEditorEx(GetEventEditInfo(AEvent, ARecurrence),
AModified);
end;
finally
AEvent.Free;
end;
end;
function TcxSchedulerGridConnection.AdapterByItem(
AItem: TcxCustomGridTableItem): TcxSchedulerFieldAdapter;
var
I: Integer;
begin
for I := 0 to Count - 1 do
begin
Result := Adapters[I];
if Result.Item = AItem then Exit;
end;
Result := nil;
end;
function TcxSchedulerGridConnection.AddAdapterLink(
Adapter: TcxSchedulerFieldAdapter): TCollectionItem;
begin
Result := FAdapters.Add;
TcxSchedulerFieldAdapterItemLink(Result).Link := Adapter;
end;
function TcxSchedulerGridConnection.AddAdapter(AField: TcxCustomSchedulerStorageField;
AdapterClass: TcxSchedulerFieldAdapterClass; ACaption: Pointer;
AVisible, ACanEdit: Boolean): TcxSchedulerFieldAdapter;
begin
DoGetItemAdapter(AField, AdapterClass);
if AdapterClass = nil then
begin
Result := nil;
Exit;
end;
Result := AdapterClass.CreateWithField(Self, AField);
Result.Caption := cxGetResourceString(ACaption);
Result.ReadOnly := not ACanEdit and GetIsFieldActive(AField);
Result.Visible := AVisible and GetIsFieldActive(AField);
DoInitializeItem(AField, Result.Item, Result);
end;
function TcxSchedulerGridConnection.AddAdapterEx(ALink: TCollectionItem;
AdapterClass: TcxSchedulerFieldAdapterClass): TcxSchedulerFieldAdapter;
begin
Result := AdapterClass.Create(Self, ALink);
end;
function TcxSchedulerGridConnection.AddAdapterForCustomField(
AField: TcxCustomSchedulerStorageField): TcxSchedulerFieldAdapter;
var
AClass: TcxSchedulerFieldAdapterClass;
begin
AClass := TcxSchedulerFieldAdapter;
DoGetItemAdapter(AField, AClass);
if AClass = nil then
begin
Result := nil;
Exit;
end;
Result := AClass.CreateWithField(Self, AField);
DoInitializeItem(AField, Result.Item, Result);
Result.Caption := TStorageFieldAccess(AField).Name;
Result.ReadOnly := True;
Result.Visible := False;
DoInitializeItem(AField, Result.Item, Result);
end;
procedure TcxSchedulerGridConnection.BeginUpdate;
begin
Inc(FLockCount);
end;
function TcxSchedulerGridConnection.CreateDataSource(): TcxSchedulerStorageDataSource;
begin
Result := TcxSchedulerStorageDataSource.Create;
end;
procedure TcxSchedulerGridConnection.DefineProperties(Filer: TFiler);
begin
inherited DefineProperties(Filer);
Filer.DefineProperty('Links', ReadLinks, WriteLinks, Count > 0);
end;
procedure TcxSchedulerGridConnection.DblClickGridHandler(Sender: TObject);
var
AHitTest: TcxCustomGridHitTest;
begin
if not DoGridViewDblClick(Sender) then
with GridView.Controller do
begin
with Site.ScreenToClient(GetMouseCursorPos) do
AHitTest := Site.ViewInfo.GetHitTest(X, Y);
if AHitTest is TcxGridRecordHitTest and (FocusedRecordIndex >= 0) and
(TcxGridRecordHitTest(AHitTest).GridRecord is TcxGridDataRow) then
OpenEventEditDialog;
end;
end;
function TcxSchedulerGridConnection.DoGridViewDblClick(Sender: TObject): Boolean;
begin
Result := False;
if Assigned(FOnGridViewDblClick) then
FOnGridViewDblClick(Sender, Result);
end;
procedure TcxSchedulerGridConnection.DoInitializeItem(
AField: TcxCustomSchedulerStorageField; AItem: TcxCustomGridTableItem;
AAdapter: TcxSchedulerFieldAdapter);
begin
if Assigned(FOnInitializeItem) then
FOnInitializeItem(Self, AField, AItem, AAdapter);
end;
procedure TcxSchedulerGridConnection.DoEditEventUsingDialog(
AEvent: TcxSchedulerEvent; ARecurrence: Boolean = False; AReadOnly: Boolean = False;
AForcePatternEditing: Boolean = False);
var
AModified, AHandled, AllowDelete, ARecurrenceButton: Boolean;
AControlEvent: TcxSchedulerControlEvent;
AOnDeleteFunc: TcxOnDeleteEventFunc;
begin
AControlEvent := TcxSchedulerControlEvent.Create(AEvent);
try
AControlEvent.Pattern := AEvent.Pattern;
AModified := False;
AHandled := False;
AllowDelete := True;
ARecurrenceButton := True;
AOnDeleteFunc := nil;
if Assigned(FOnEditEvent) then
FOnEditEvent(Self, AControlEvent, AModified, AHandled);
if not AHandled then
cxShowEventEditor(AControlEvent, RootLookAndFeel,
ARecurrence, AModified, AReadOnly, AllowDelete, ARecurrenceButton,
AOnDeleteFunc, AForcePatternEditing or (AEvent.EventType = etPattern) , 0, True);
finally
AControlEvent.Free;
end;
end;
procedure TcxSchedulerGridConnection.DoGetItemAdapter(
AField: TcxCustomSchedulerStorageField;
var AdapterClass: TcxSchedulerFieldAdapterClass);
begin
if Assigned(FOnGetFieldAdapter) then
FOnGetFieldAdapter(Self, AField, AdapterClass);
end;
procedure TcxSchedulerGridConnection.EndUpdate;
begin
Dec(FLockCount);
if (FLockCount = 0) and FIsChanged then
StorageChanged(nil);
end;
function TcxSchedulerGridConnection.GetEventEditInfo(AEvent: TcxSchedulerControlEvent;
ARecurrence: Boolean = False): TcxSchedulerEventEditInfo;
begin
Result := FEventEditInfo;
Result.Event := AEvent;
Result.Recurrence := ARecurrence;
Result.RecurrenceButton := True;
Result.ShowResources := True;
Result.ForcePatternEditing := AEvent.EventType = etPattern;
end;
function TcxSchedulerGridConnection.GetFocusedEvent;
begin
if (GridView.DataController.RecordCount = 0) or (GridView.Controller.FocusedRecordIndex < 0) then
Result := nil
else
with GridView.DataController do
Result := Storage.Events[GetRowInfo(FocusedRowIndex).RecordIndex];
end;
function TcxSchedulerGridConnection.GetIsFieldActive(
AField: TcxCustomSchedulerStorageField): Boolean;
begin
Result := (AField = nil) or
TStorageFieldAccess(AField).GetIsActive;
end;
procedure TcxSchedulerGridConnection.Loaded;
var
AIndex: Integer;
begin
inherited Loaded;
for AIndex := 0 to FAdapters.Count - 1 do
TcxSchedulerFieldAdapterItemLink(FAdapters.Items[AIndex]).AssignFieldByIndex;
Reactivate;
end;
procedure TcxSchedulerGridConnection.Notification(
AComponent: TComponent; Operation: TOperation);
var
Adapter: TcxSchedulerFieldAdapter;
begin
if Operation = opRemove then
begin
if AComponent = GridView then
begin
Active := False;
GridView := nil;
end;
if AComponent = Storage then
begin
Active := False;
Storage := nil;
end;
if AComponent is TcxCustomGridTableItem then
begin
Adapter := AdapterByItem(TcxCustomGridTableItem(AComponent));
if Adapter <> nil then
begin
Adapter.Item := nil;
Adapter.Link.Free;
end;
end;
end;
FGridPopupMenu.Notification(AComponent, Operation);
inherited Notification(AComponent, Operation);
end;
procedure TcxSchedulerGridConnection.OpenEventEditDialog(
AForcePatternEditing: Boolean = False; AReadOnly: Boolean = False);
begin
DoEditEventUsingDialog(GetFocusedEvent, False, AReadOnly,
AForcePatternEditing);
end;
procedure TcxSchedulerGridConnection.Reactivate;
var
I: Integer;
begin
for I := 0 to Count - 1 do
begin
Adapters[I].InitializeAdapter;
DoInitializeItem(Adapters[I].Field, Adapters[I].Item, Adapters[I]);
end;
if (Count > 0) and (DataController <> nil) then
GridView.DataController.CustomDataSource := Provider;
Provider.DataChanged;
end;
procedure TcxSchedulerGridConnection.SetupView;
var
I: Integer;
begin
if (Storage = nil) or (GridView = nil) or (Count <> 0) then Exit;
if IsLoading then Exit;
GridView.BeginUpdate;
try
with TStorageAccess(Storage) do
begin
AddAdapter(nil, TcxSchedulerIDFieldAdapter, @scxIDField, False, False);
AddAdapter(FParentIDField, TcxSchedulerIDFieldAdapter, @scxParentIDField, False, False);
AddAdapter(FStateField, TcxSchedulerStateFieldAdapter, @scxStateField, True, True);
AddAdapter(FCaptionField, TcxSchedulerTextFieldAdapter, @scxCaptionField, True, True);
AddAdapter(FLocationField, TcxSchedulerTextFieldAdapter, @scxLocationField, True, True);
AddAdapter(FActualFinishField, TcxSchedulerDateTimeFieldAdapter, @scxActualFinishField, False, False);
AddAdapter(FActualStartField, TcxSchedulerDateTimeFieldAdapter, @scxActualStartField, False, False);
AddAdapter(FFinishField, TcxSchedulerDateTimeFieldAdapter, @scxFinishField, True, True);
AddAdapter(FStartField, TcxSchedulerDateTimeFieldAdapter, @scxStartField, True, True);
AddAdapter(FMessageField, TcxSchedulerTextFieldAdapter, @scxMessageField, False, True);
AddAdapter(FEventTypeField, TcxSchedulerTypeFieldAdapter, @scxEventTypeField, False, False);
AddAdapter(FOptionsField, TcxSchedulerReminderFieldAdapter, @scxReminderField, True, True);
AddAdapter(FOptionsField, TcxSchedulerAllDayFieldAdapter, @scxAllDayEventField, True, True);
AddAdapter(FOptionsField, TcxSchedulerEnabledFieldAdapter, @scxEnabledField, True, True);
AddAdapter(FLabelColorField, TcxSchedulerLabelColorFieldAdapter, @scxLabelField, True, True);
AddAdapter(FRecurrenceInfoField, TcxSchedulerRecurringFieldAdapter, @scxRecurrenceField, True, False);
AddAdapter(FRecurrenceIndexField, TcxSchedulerIntegerFieldAdapter, @scxRecurrenceIndexField, False, False);
AddAdapter(FReminderDateField, TcxSchedulerDateTimeFieldAdapter, @scxReminderDateField, False, False);
AddAdapter(FReminderMinutesBeforeStartField, TcxSchedulerIntegerFieldAdapter, @scxReminderMinutesBeforeStartField, False, False);
AddAdapter(FResourceIDField, TcxSchedulerResourceIDFieldAdapter, @scxResourceField, False, False);
AddAdapter(FTaskCompleteField, TcxSchedulerCompleteFieldAdapter, @scxTaskCompleteField, False, True);
AddAdapter(FTaskLinksField, TcxSchedulerLinksFieldAdapter, @scxTaskLinksField, False, False);
AddAdapter(FTaskIndexField, TcxSchedulerIntegerFieldAdapter, @scxTaskIndexField, False, False);
AddAdapter(FTaskStatusField, TcxSchedulerStatusFieldAdapter, @scxTaskStatusField, False, True);
for I := 0 to CustomFields.Count - 1 do
AddAdapterForCustomField(CustomFields.Items[I]);
end;
finally
GridView.EndUpdate;
GridView.BeginUpdate;
try
for I := 0 to Count - 1 do
if Adapters[I].Item.ActuallyVisible then
Adapters[I].Item.ApplyBestFit();
finally
GridView.EndUpdate;
end;
end;
end;
procedure TcxSchedulerGridConnection.StorageChanged(Sender: TObject);
begin
if IsLocked then
begin
FIsChanged := True;
Exit;
end;
Provider.DataChanged;
end;
procedure TcxSchedulerGridConnection.StorageRemoved(Sender: TObject);
begin
Storage := nil;
end;
function TcxSchedulerGridConnection.GetAdapter(
AIndex: Integer): TcxSchedulerFieldAdapter;
begin
Result := TcxSchedulerFieldAdapterItemLink(FAdapters.Items[AIndex]).Link;
end;
function TcxSchedulerGridConnection.GetCount: Integer;
begin
Result := FAdapters.Count;
end;
function TcxSchedulerGridConnection.GetDataController: TcxCustomDataController;
begin
Result := nil;
if GridView <> nil then
Result := GridView.DataController;
end;
function TcxSchedulerGridConnection.GetEvent(ARowIndex: Integer): TcxSchedulerEvent;
begin
with GridView.DataController.GetRowInfo(ARowIndex) do
Result := Storage.Events[RecordIndex];
end;
function TcxSchedulerGridConnection.GetEventCount: Integer;
begin
Result := GridView.DataController.RowCount;
end;
function TcxSchedulerGridConnection.GetIsDestroying: Boolean;
begin
Result := csDestroying in ComponentState
end;
function TcxSchedulerGridConnection.GetIsLoading: Boolean;
begin
Result := csLoading in ComponentState
end;
function TcxSchedulerGridConnection.GetIsLocked: Boolean;
begin
Result := FLockCount <> 0;
end;
procedure TcxSchedulerGridConnection.SetActive(AValue: Boolean);
begin
if not AValue and IsLoading then Exit;
if FActive and not AValue and (DataController <> nil) then
DataController.CustomDataSource := nil;
FActive := AValue;
if (DataController <> nil) and AValue then
DataController.CustomDataSource := Provider;
if IsLoading and not AValue then Exit;
if not Active then
FAdapters.Clear
else
begin
if (GridView <> nil) and (Storage <> nil) and Storage.IsActive then
SetupView
else
Active := False;
end;
end;
procedure TcxSchedulerGridConnection.SetGridPopupMenu(
AValue: TcxSchedulerGridBuildInPopupMenu);
begin
if FGridPopupMenu <> AValue then
FGridPopupMenu := AValue;
end;
procedure TcxSchedulerGridConnection.SetGridView(AValue: TcxCustomGridTableView);
begin
if AValue = GridView then Exit;
Active := False;
if GridView <> nil then
begin
GridView.RemoveFreeNotification(Self);
if GridView.DataController <> nil then
GridView.DataController.CustomDataSource := nil;
end;
FGridView := AValue;
if GridView <> nil then
begin
GridView.FreeNotification(Self);
GridView.OptionsBehavior.AlwaysShowEditor := False;
GridView.OptionsBehavior.ImmediateEditor := False;
GridView.OptionsBehavior.CellHints := True;
GridView.OnDblClick := DblClickGridHandler;
end;
SetupBuildInPopupMenu;
end;
procedure TcxSchedulerGridConnection.SetStorage(AValue: TcxCustomSchedulerStorage);
begin
if AValue = Storage then Exit;
Active := False;
if Storage <> nil then
begin
Storage.RemoveListener(Self);
Storage.RemoveFreeNotification(Self);
end;
FStorage := AValue;
if Storage <> nil then
begin
Storage.AddListener(Self);
Storage.FreeNotification(Self);
end;
SetupBuildInPopupMenu;
end;
procedure TcxSchedulerGridConnection.SetupBuildInPopupMenu;
begin
if csDesigning in ComponentState then Exit;
if FGridPopupMenuController <> nil then
FGridPopupMenuController.Free;
FGridPopupMenuController := TcxSchedulerGridBuildInPopupMenuController.Create(Self);
end;
procedure TcxSchedulerGridConnection.ReadLinks(Reader: TReader);
begin
Reader.ReadValue;
Reader.ReadCollection(FAdapters);
end;
procedure TcxSchedulerGridConnection.WriteLinks(Writer: TWriter);
begin
Writer.WriteCollection(FAdapters);
end;
{ TcxSchedulerGridBuildInPopupMenu }
constructor TcxSchedulerGridBuildInPopupMenu.Create(
ASchedulerGridConnection: TcxSchedulerGridConnection);
begin
FOwner := ASchedulerGridConnection;
FUseBuiltInPopupMenu := True;
FItems := [bpmiNewEvent, bpmiNewAllDayEvent, bpmiNewReccuringEvent,
bpmiOpen, bpmiEditSeries, bpmiShowTimeAs, bpmiLabel, bpmiDelete];
end;
destructor TcxSchedulerGridBuildInPopupMenu.Destroy;
begin
PopupMenu := nil;
inherited Destroy;
end;
procedure TcxSchedulerGridBuildInPopupMenu.Assign(Source: TPersistent);
begin
if Source is TcxSchedulerGridBuildInPopupMenu then
begin
PopupMenu := TcxSchedulerGridBuildInPopupMenu(Source).PopupMenu;
UseBuiltInPopupMenu := TcxSchedulerGridBuildInPopupMenu(Source).UseBuiltInPopupMenu;
Items := TcxSchedulerGridBuildInPopupMenu(Source).Items;
OnClick := TcxSchedulerGridBuildInPopupMenu(Source).OnClick;
OnPopup := TcxSchedulerGridBuildInPopupMenu(Source).OnPopup;
end;
end;
procedure TcxSchedulerGridBuildInPopupMenu.Notification(AComponent: TComponent;
Operation: TOperation);
begin
if (Operation = opRemove) and (AComponent = PopupMenu) then
PopupMenu := nil;
end;
procedure TcxSchedulerGridBuildInPopupMenu.SetPopupMenu(AValue: TComponent);
begin
if FPopupMenu <> AValue then
begin
if (FPopupMenu <> nil) and not (csDestroying in FPopupMenu.ComponentState) then
FPopupMenu.RemoveFreeNotification(FOwner);
FPopupMenu := AValue;
if FPopupMenu <> nil then
FPopupMenu.FreeNotification(FOwner);
end;
end;
{ TcxSchedulerGridBuildInPopupMenuController }
constructor TcxSchedulerGridBuildInPopupMenuController.Create(
ASchedulerGridConnection: TcxSchedulerGridConnection);
var
AGrid: TcxGrid;
begin
inherited Create;
FOwner := ASchedulerGridConnection;
if IsPopupMenuPossible(FOwner.GridView, AGrid) then
begin
FGridPopupMenu := TcxGridPopupMenu.Create(FOwner);
FInternalMenu := TPopupMenu.Create(FOwner);
FGridPopupMenu.Grid := AGrid;
FMenuInfo := TcxPopupMenuInfo(FGridPopupMenu.PopupMenus.Add);
FMenuInfo.GridView := FOwner.GridView;
FMenuInfo.HitTypes := [gvhtCell, gvhtNone];
FMenuInfo.OnPopup := GridMenuPopup;
FMenuInfo.PopupMenu := FInternalMenu;
end;
end;
destructor TcxSchedulerGridBuildInPopupMenuController.Destroy;
begin
FreeAndNil(FGridPopupMenu);
FreeAndNil(FInternalMenu);
inherited Destroy;
end;
function TcxSchedulerGridBuildInPopupMenuController.Popup(X, Y: Integer): Boolean;
var
AGrid: TcxGrid;
begin
Result := False;
SetEvent;
if not IsPopupMenuPossible(FOwner.GridView, AGrid){ or (FEvent = nil)} then Exit;
CreateInternalMenu;
Result := DoOnPopup;
if not Result then
begin
if BuildInPopupMenu.UseBuiltInPopupMenu then
Result := ShowPopupMenu(FOwner, FInternalMenu, X, Y)
else
Result := ShowPopupMenu(FOwner, BuildInPopupMenu.FPopupMenu, X, Y);
end;
end;
function TcxSchedulerGridBuildInPopupMenuController.AddValidSeparator(
AOwner: TMenuItem): TMenuItem;
begin
if AOwner.Count > 0 then
Result := CreateSubItem(AOwner, '-')
else
Result := nil
end;
procedure TcxSchedulerGridBuildInPopupMenuController.CreateInternalMenu;
begin
FreeAndNil(FInternalMenu);
FInternalMenu := TPopupMenu.Create(nil);
FInternalMenu.Images := MenuImages;
FMenuInfo.PopupMenu := FInternalMenu;
CreateItems;
end;
procedure TcxSchedulerGridBuildInPopupMenuController.CreateItems;
begin
if bpmiNewEvent in Items then
CreateSubItem(FInternalMenu.Items,
cxGetResourceString(@scxpmNewEvent), Ord(bpmiNewEvent), 2);
if bpmiNewAllDayEvent in Items then
CreateSubItem(FInternalMenu.Items,
cxGetResourceString(@scxpmNewAllDayEvent), Ord(bpmiNewAllDayEvent), -1);
if (bpmiNewReccuringEvent in Items) and (Storage.IsRecurrenceAvailable) then
CreateSubItem(FInternalMenu.Items,
cxGetResourceString(@scxpmNewRecurringEvent), Ord(bpmiNewReccuringEvent), 3);
if FEvent <> nil then
begin
if (bpmiOpen in Items) and not (FEvent.EventType = etPattern) then
begin
AddValidSeparator(FInternalMenu.Items);
CreateSubItem(FInternalMenu.Items, cxGetResourceString(@scxpmOpen),
Ord(bpmiOpen));
end;
if FEvent.EventType = etPattern then
AddValidSeparator(FInternalMenu.Items);
if (bpmiEditSeries in Items) and (FEvent.EventType <> etNone) then
CreateSubItem(FInternalMenu.Items, cxGetResourceString(@scxpmEditSeries),
Ord(bpmiEditSeries), 8);
if Items * [bpmiLabel, bpmiShowTimeAs] <> [] then
AddValidSeparator(FInternalMenu.Items);
CreateTimeItems;
CreateLabelItems;
if bpmiDelete in Items then
begin
AddValidSeparator(FInternalMenu.Items);
CreateSubItem(FInternalMenu.Items, cxGetResourceString(@scxpmDelete),
Ord(bpmiDelete), 10).Enabled := not IsEventsReadOnly;
end;
end;
end;
function TcxSchedulerGridBuildInPopupMenuController.CreateSubItem(AOwner: TMenuItem;
const ACaption: string; ACommand: Integer = -1; AImageIndex: Integer = -1;
AEnabled: Boolean = True; AChecked: Boolean = False): TMenuItem;
begin
Result := TMenuItem.Create(nil);
Result.Caption := ACaption;
Result.Enabled := AEnabled;
Result.ImageIndex := AImageIndex;
Result.Checked := AChecked;
Result.Tag := ACommand;
Result.OnClick := OnItemClickHandler;
AOwner.Add(Result);
end;
function TcxSchedulerGridBuildInPopupMenuController.DoOnClick(ACommand: Integer): Boolean;
var
AItem: TcxSchedulerGridBuildInPopupMenuItem;
ASubItemIndex: Integer;
begin
Result := False;
UnpackCommand(ACommand, AItem, ASubItemIndex);
if Assigned(BuildInPopupMenu.FOnClick) then
BuildInPopupMenu.FOnClick(BuildInPopupMenu,
TcxSchedulerGridBuildInPopupMenuItem(ACommand), ASubItemIndex, Result);
end;
function TcxSchedulerGridBuildInPopupMenuController.DoOnPopup: Boolean;
begin
Result := False;
if Assigned(BuildInPopupMenu.FOnPopup) then
BuildInPopupMenu.FOnPopup(BuildInPopupMenu, FInternalMenu, Result);
end;
function TcxSchedulerGridBuildInPopupMenuController.IsValidCommand(ACommand: Integer): Boolean;
begin
Result := (ACommand >= Ord(bpmiNewEvent)) and (ACommand <= Ord(bpmiDelete)) or
(ACommand in [20..20 + EventLabels.Count - 1]) or //Label
(ACommand in [10..13]); //TimeLine
end;
procedure TcxSchedulerGridBuildInPopupMenuController.OnItemClickHandler(Sender: TObject);
var
ACommand: Integer;
begin
if (Sender <> nil) and (Sender is TComponent) then
begin
ACommand := TComponent(Sender).Tag;
if IsValidCommand(ACommand) and not DoOnClick(ACommand) then
case ACommand of
Ord(bpmiNewEvent): NewEvent;
Ord(bpmiNewAllDayEvent): NewAllDayEvent;
Ord(bpmiNewReccuringEvent): NewRecurrence;
Ord(bpmiDelete): DeleteEvent;
Ord(bpmiOpen): EditEvent;
Ord(bpmiEditSeries): EditSeries;
10..13:
SetEventState(ACommand - 10);
else
if (ACommand >= 20) and (ACommand < 20 + EventLabels.Count) then
SetEventLabelColor(EventLabels[ACommand - 20].Color);
end;
end;
end;
function TcxSchedulerGridBuildInPopupMenuController.CanEventEdit: Boolean;
begin
Result := (FEvent <> nil) and not FEvent.ReadOnly;
end;
procedure TcxSchedulerGridBuildInPopupMenuController.CreateLabelItems;
var
AOwner: TMenuItem;
I: Integer;
function GetColorChecked(AColor: TColor): Boolean;
begin
if FEvent = nil then
Result := False
else
Result := ColorToRgb(FEvent.LabelColor) = ColorToRgb(AColor);
end;
procedure CreateEventColorItem(ALabel: TcxSchedulerEventLabel);
var
AChecked: Boolean;
AItem: TMenuItem;
begin
AChecked := GetColorChecked(ALabel.Color);
AItem := CreateSubItem(AOwner, ALabel.Caption,
GetCommand(bpmiLabel, ALabel.Index), -1, CanEventEdit, AChecked);
AItem.Default := AChecked;
EventLabels.Images.GetBitmap(ALabel.Index, AItem.Bitmap);
end;
begin
if not (bpmiLabel in Items) or not Storage.IsLabelColorAvailable or
(EventLabels.Count = 0) then Exit;
AOwner := CreateSubItem(FInternalMenu.Items, cxGetResourceString(@scxpmLabel),
Ord(bpmiLabel));
//label colors
CreateEventColorItem(EventLabels[0]);
if EventLabels.Count > 1 then
begin
AddValidSeparator(AOwner);
for I := 1 to EventLabels.Count - 1 do
CreateEventColorItem(EventLabels[I]);
end;
end;
procedure TcxSchedulerGridBuildInPopupMenuController.CreateTimeItems;
var
AOwner: TMenuItem;
function GetTimeLineChecked(AIndex: Integer): Boolean;
begin
if FEvent = nil then
Result := False
else
Result := Integer(FEvent.State) = AIndex;
end;
procedure CreateTimeLineItem(const ACaption: string; AIndex: Integer);
var
AChecked: Boolean;
begin
AChecked := GetTimeLineChecked(AIndex);
CreateSubItem(AOwner, ACaption, GetCommand(bpmiShowTimeAs, AIndex), AIndex,
CanEventEdit, AChecked).Default := AChecked;
end;
begin
if not (bpmiShowTimeAs in Items) or not Storage.IsStateAvailable then Exit;
AOwner := CreateSubItem(FInternalMenu.Items,
cxGetResourceString(@scxpmShowTimeAs), Ord(bpmiShowTimeAs));
AOwner.SubMenuImages := TimeLinePatterns;
// TimeLine styles
CreateTimeLineItem(cxGetResourceString(@scxpmFree), 0);
CreateTimeLineItem(cxGetResourceString(@scxpmTentative), 1);
CreateTimeLineItem(cxGetResourceString(@scxpmBusy), 2);
CreateTimeLineItem(cxGetResourceString(@scxpmOutOfOffice), 3);
end;
procedure TcxSchedulerGridBuildInPopupMenuController.DeleteEvent;
begin
FOwner.FGridView.Controller.DeleteSelection;
end;
procedure TcxSchedulerGridBuildInPopupMenuController.EditEvent;
begin
FOwner.OpenEventEditDialog(False, IsEventsReadOnly);
end;
procedure TcxSchedulerGridBuildInPopupMenuController.EditSeries;
begin
FOwner.OpenEventEditDialog(True, IsEventsReadOnly);
end;
function TcxSchedulerGridBuildInPopupMenuController.GetBuildInPopupMenu: TcxSchedulerGridBuildInPopupMenu;
begin
Result := FOwner.GridPopupMenu;
end;
function TcxSchedulerGridBuildInPopupMenuController.GetCommand(
AItem: TcxSchedulerGridBuildInPopupMenuItem; ASubItemIndex: Integer): Integer;
begin
Result := Ord(AItem);
case AItem of
bpmiShowTimeAs:
if (ASubItemIndex >= 0) and (ASubItemIndex <= 3) then
Result := 10 + ASubItemIndex;
bpmiLabel:
if (ASubItemIndex >= 0) and (ASubItemIndex < EventLabels.Count) then
Result := 20 + ASubItemIndex;
end;
end;
function TcxSchedulerGridBuildInPopupMenuController.GetItems: TcxSchedulerGridBuildInPopupMenuItems;
begin
Result := BuildInPopupMenu.Items;
end;
function TcxSchedulerGridBuildInPopupMenuController.GetStorage: TcxCustomSchedulerStorage;
begin
Result := FOwner.Storage;
end;
procedure TcxSchedulerGridBuildInPopupMenuController.GridMenuPopup(ASenderMenu: TComponent;
AHitTest: TcxCustomGridHitTest; X, Y: Integer);
begin
Popup(X, Y);
end;
function TcxSchedulerGridBuildInPopupMenuController.IsEventsReadOnly: Boolean;
var
I, ACount: Integer;
begin
Result := False;
ACount := FOwner.FGridView.Controller.SelectedRecordCount;
I := 0;
while not Result and (I < ACount) do
begin
Result := GetStorage.Events[FOwner.FGridView.Controller.SelectedRecords[I].Index].ReadOnly;
Inc(I);
end;
end;
procedure TcxSchedulerGridBuildInPopupMenuController.NewAllDayEvent;
begin
FOwner.AddNewEvent(False, True);
end;
procedure TcxSchedulerGridBuildInPopupMenuController.NewEvent;
begin
FOwner.AddNewEvent;
end;
procedure TcxSchedulerGridBuildInPopupMenuController.NewRecurrence;
begin
FOwner.AddNewEvent(True);
end;
procedure TcxSchedulerGridBuildInPopupMenuController.SetEvent;
begin
FEvent := FOwner.GetFocusedEvent;
end;
procedure TcxSchedulerGridBuildInPopupMenuController.SetEventLabelColor(AColor: Integer);
begin
if FEvent = nil then Exit;
if FEvent.EventType = etOccurrence then
FEvent.Pattern.LabelColor := AColor
else
FEvent.LabelColor := AColor;
end;
procedure TcxSchedulerGridBuildInPopupMenuController.SetEventState(AState: Integer);
begin
if FEvent = nil then Exit;
FEvent.State := AState;
end;
procedure TcxSchedulerGridBuildInPopupMenuController.UnpackCommand(ACommand: Integer;
out AItem: TcxSchedulerGridBuildInPopupMenuItem; out ASubItemIndex: Integer);
begin
AItem := bpmiOpen;
ASubItemIndex := -1;
if not IsValidCommand(ACommand) then Exit;
if ACommand in [20..20 + EventLabels.Count - 1] then
begin
AItem := bpmiLabel;
ASubItemIndex := ACommand - 20;
end
else
if ACommand in [10..13] then
begin
AItem := bpmiShowTimeAs;
ASubItemIndex := ACommand - 10;
end
else
AItem := TcxSchedulerGridBuildInPopupMenuItem(ACommand);
end;
procedure RegisterAssistants;
begin
TcxSchedulerNullAdapter.Register;
TcxSchedulerIntegerFieldAdapter.Register;
TcxSchedulerTextFieldAdapter.Register;
TcxSchedulerCheckFieldAdapter.Register;
TcxSchedulerDateTimeFieldAdapter.Register;
TcxSchedulerImageComboFieldAdapter.Register;
TcxSchedulerIDFieldAdapter.Register;
TcxSchedulerTypeFieldAdapter.Register;
TcxSchedulerAllDayFieldAdapter.Register;
TcxSchedulerEnabledFieldAdapter.Register;
TcxSchedulerReminderFieldAdapter.Register;
TcxSchedulerLabelColorFieldAdapter.Register;
TcxSchedulerRecurringFieldAdapter.Register;
TcxSchedulerStateFieldAdapter.Register;
TcxSchedulerResourceIDFieldAdapter.Register;
TcxSchedulerCompleteFieldAdapter.Register;
TcxSchedulerLinksFieldAdapter.Register;
TcxSchedulerStatusFieldAdapter.Register;
RegisterClasses([TcxSchedulerFieldAdapterItemLink]);
end;
procedure UnregisterAssistants;
begin
TcxSchedulerNullAdapter.Unregister;
TcxSchedulerIntegerFieldAdapter.Unregister;
TcxSchedulerTextFieldAdapter.Unregister;
TcxSchedulerCheckFieldAdapter.Unregister;
TcxSchedulerDateTimeFieldAdapter.Unregister;
TcxSchedulerImageComboFieldAdapter.Unregister;
TcxSchedulerIDFieldAdapter.Unregister;
TcxSchedulerTypeFieldAdapter.Unregister;
TcxSchedulerAllDayFieldAdapter.Unregister;
TcxSchedulerEnabledFieldAdapter.Unregister;
TcxSchedulerReminderFieldAdapter.Unregister;
TcxSchedulerLabelColorFieldAdapter.Unregister;
TcxSchedulerRecurringFieldAdapter.Unregister;
TcxSchedulerStateFieldAdapter.Unregister;
TcxSchedulerResourceIDFieldAdapter.Unregister;
TcxSchedulerCompleteFieldAdapter.Unregister;
TcxSchedulerLinksFieldAdapter.Unregister;
TcxSchedulerStatusFieldAdapter.Unregister;
end;
initialization
RegisterAssistants;
finalization
UnregisterAssistants;
end.