11875 lines
368 KiB
ObjectPascal
11875 lines
368 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 cxSchedulerCustomControls;
|
|
|
|
{$I cxVer.inc}
|
|
|
|
interface
|
|
uses
|
|
{$IFDEF DELPHI6}
|
|
Types,
|
|
{$ENDIF}
|
|
Classes, SysUtils, Windows, Messages, Forms, StdCtrls, Controls, Graphics, ImgList,
|
|
dxCore, cxControls, Math, cxGraphics, cxGeometry, cxLookAndFeels, cxLookAndFeelPainters,
|
|
cxFormats, cxSchedulerUtils, cxSchedulerStorage, cxStyles, cxClasses, cxEdit,
|
|
cxDateUtils, ExtCtrls, Menus, cxStorage, cxTextEdit, cxNavigator, cxVariants,
|
|
Clipbrd;
|
|
|
|
const
|
|
LastAvailableDate = $2D2462;
|
|
|
|
// resize bitmap capacity
|
|
cxSizeDelta = 32;
|
|
|
|
//
|
|
cxDefaultTimeScale = 30;
|
|
|
|
//hittest codes
|
|
//base class
|
|
htcControl = $0;
|
|
htcTime = $1;
|
|
//custom viewinfo
|
|
htcResource = $2;
|
|
|
|
// style indexes
|
|
cxcsBackground = 0;
|
|
cxcsContent = 1;
|
|
cxcsEvent = 2;
|
|
cxcsGroupSeparator = 3;
|
|
cxcsDayHeader = 4;
|
|
cxcsSelection = 5;
|
|
cxcsHSplitter = 6;
|
|
cxcsVSplitter = 7;
|
|
cxcsResourceHeader = 8;
|
|
cxcsMaxValue = cxcsResourceHeader;
|
|
// for PS
|
|
cxcsSchedulerStyleFirst = cxcsBackground;
|
|
cxcsSchedulerStyleLast = cxcsMaxValue;
|
|
|
|
// default property values
|
|
cxDefaultSchedulerHeight = 250;
|
|
cxDefaultSchedulerWidth = 350;
|
|
cxDefaultSplitterWidth = 5;
|
|
cxDefaultGroupSeparatorWidth = 11;
|
|
cxDefaultResourcesPerPage = 0;
|
|
|
|
// minimal property values
|
|
cxMinSplitterWidth = 3;
|
|
|
|
// hint timings
|
|
cxscMinHintWidth: Integer = 150;
|
|
cxscMaxHintWidth: Integer = 1000;
|
|
|
|
//
|
|
cxScrollInterval = 25;
|
|
cxScrollZoneSize = 10;
|
|
//
|
|
cxNavigatorStartTimer = 300;
|
|
|
|
// navigator's buttons
|
|
cxSchedulerFirstButton = 0;
|
|
cxSchedulerPrevPageButton = 1;
|
|
cxSchedulerPrevButton = 2;
|
|
cxSchedulerNextButton = 3;
|
|
cxSchedulerNextPageButton = 4;
|
|
cxSchedulerLastButton = 5;
|
|
cxSchedulerShowMoreResourcesButton = 6;
|
|
cxSchedulerShowFewerResourcesButton = 7;
|
|
|
|
cxSchedulerNavigatorVisibility: array[0..7] of Boolean =
|
|
(True, False, False, False, False, True, True, True);
|
|
|
|
SCF_SCHEDULERCLIPBOARDFORMAT = 'ExpressScheduler 2.0';
|
|
|
|
type
|
|
TcxCustomScheduler = class;
|
|
|
|
TcxSchedulerSubControl = class;
|
|
TcxSchedulerSubControlController = class;
|
|
TcxSchedulerSubControlHitTest = class;
|
|
TcxSchedulerSubControlPainter = class;
|
|
TcxSchedulerSubControlViewInfo = class;
|
|
TcxSchedulerSplitter = class;
|
|
TcxSchedulerStyles = class;
|
|
// popup menus
|
|
TcxSchedulerContentPopupMenu = class;
|
|
TcxSchedulerEventPopupMenu = class;
|
|
|
|
TcxSchedulerViewController = class;
|
|
TcxSchedulerCustomView = class;
|
|
TcxSchedulerCustomViewClass = class of TcxSchedulerCustomView;
|
|
TcxSchedulerCustomViewViewInfo = class;
|
|
TcxDragHelper = class;
|
|
TcxDragEventHelper = class;
|
|
TcxEventSizingHelper = class;
|
|
TcxSchedulerCustomDateNavigator = class;
|
|
|
|
TcxSchedulerNavigatorButton = class;
|
|
TcxSchedulerResourceNavigator = class;
|
|
|
|
TcxSchedulerOptionsView = class;
|
|
|
|
TcxSchedulerHintController = class;
|
|
|
|
TcxControlFlag = (cfInvalidLayout, cfLocked, cfImageValid, cfViewValid);
|
|
TcxControlFlags = set of TcxControlFlag;
|
|
|
|
TcxSchedulerSplitterKind = (skHorizontal, skVertical);
|
|
TcxSchedulerViewPosition = (vpRight, vpLeft, vpTop, vpBottom);
|
|
|
|
TcxSchedulerGroupingKind = (gkDefault, gkNone, gkByDate, gkByResource);
|
|
TcxSchedulerViewMode = (vmDay, vmWeek, vmMonth, vmWorkWeek);
|
|
|
|
TcxOnDeleteEventFunc = function (AEvent: TcxSchedulerControlEvent): Boolean of object;
|
|
TcxSchedulerDragAndDropObject = class;
|
|
|
|
TcxSchedulerContentPopupMenuItem = (cpmiNewEvent, cpmiNewAllDayEvent,
|
|
cpmiNewReccuringEvent, cpmiToday, cpmiGoToDate, cpmiGoToThisDay, cpmiResourcesLayout);
|
|
TcxSchedulerContentPopupMenuItems = set of TcxSchedulerContentPopupMenuItem;
|
|
|
|
{ TcxSchedulerEventEditInfo }
|
|
|
|
TcxSchedulerEventEditInfo = class
|
|
public
|
|
AllowDelete: Boolean;
|
|
AllowHiddenEvents: Boolean;
|
|
BiasTime: TDateTime;
|
|
DisableShare: Boolean;
|
|
Intersection: Boolean;
|
|
Event: TcxSchedulerControlEvent;
|
|
ForcePatternEditing: Boolean;
|
|
LookAndFeel: TcxLookAndFeel;
|
|
OnDeleteFunc: TcxOnDeleteEventFunc;
|
|
ReadOnly: Boolean;
|
|
Recurrence: Boolean;
|
|
RecurrenceButton: Boolean;
|
|
ShowResources: Boolean;
|
|
ShowTaskComplete: Boolean;
|
|
end;
|
|
|
|
{ TcxSchedulerSubControl }
|
|
|
|
TcxSchedulerSubControl = class(TPersistent)
|
|
private
|
|
FCanvas: TcxCanvas;
|
|
FController: TcxSchedulerSubControlController;
|
|
FCursor: TCursor;
|
|
FHeight: Integer;
|
|
FHitTest: TcxSchedulerSubControlHitTest;
|
|
FLeft: Integer;
|
|
FPainter: TcxSchedulerSubControlPainter;
|
|
FScheduler: TcxCustomScheduler;
|
|
FTop: Integer;
|
|
FViewInfo: TcxSchedulerSubControlViewInfo;
|
|
FVisible: Boolean;
|
|
FWidth: Integer;
|
|
{$IFNDEF DEBUGPAINT}
|
|
function GetBitmap: TBitmap;
|
|
{$ENDIF}
|
|
function GetBottom: Integer;
|
|
function GetBounds: TRect;
|
|
function GetDateTimeHelperClass: TcxSchedulerDateTimeHelperClass;
|
|
function GetIsScrollingContent: Boolean;
|
|
function GetLookAndFeelPainter: TcxCustomLookAndFeelPainterClass;
|
|
function GetPainterHelperClass: TcxSchedulerPainterHelperClass;
|
|
function GetRight: Integer;
|
|
function GetStyles: TcxSchedulerStyles;
|
|
procedure InternalSetBounds(const AValue: TRect);
|
|
procedure SetBottom(const Value: Integer);
|
|
procedure SetHeight(AValue: Integer);
|
|
procedure SetLeft(AValue: Integer);
|
|
procedure SetRight(Value: Integer);
|
|
procedure SetTop(AValue: Integer);
|
|
procedure SetVisible(AValue: Boolean);
|
|
procedure SetWidth(AValue: Integer);
|
|
protected
|
|
// store interface
|
|
procedure GetProperties(AProperties: TStrings); virtual;
|
|
procedure GetPropertyValue(const AName: string; var AValue: Variant); virtual;
|
|
procedure SetPropertyValue(const AName: string; const AValue: Variant); virtual;
|
|
//
|
|
function AllowDesignHitTest(X, Y: Integer; AShift: TShiftState): Boolean; virtual;
|
|
procedure BoundsChanged; virtual;
|
|
procedure CalculateViewInfo; virtual;
|
|
function CanCapture(const APoint: TPoint): Boolean; virtual;
|
|
procedure Changed; virtual;
|
|
procedure ClearCachedData; virtual;
|
|
function CreateController: TcxSchedulerSubControlController; virtual;
|
|
function CreateHitTest: TcxSchedulerSubControlHitTest; virtual;
|
|
function CreatePainter: TcxSchedulerSubControlPainter; virtual;
|
|
function CreateViewInfo: TcxSchedulerSubControlViewInfo; virtual;
|
|
|
|
procedure BoundsChanging; virtual;
|
|
procedure CreateSubClasses; virtual;
|
|
procedure DestroySubClasses; virtual;
|
|
procedure DoBeforeMouseDown(AButton: TMouseButton; AShift: TShiftState; X, Y: Integer);
|
|
procedure DoCancelMode; virtual;
|
|
procedure DoLayoutChanged; virtual;
|
|
procedure DoMouseDown(AButton: TMouseButton; AShift: TShiftState; X, Y: Integer); virtual;
|
|
procedure DoMouseMove(AShift: TShiftState; X, Y: Integer);
|
|
procedure DoMouseUp(AButton: TMouseButton; AShift: TShiftState; X, Y: Integer);
|
|
procedure DoPaint; virtual;
|
|
procedure DoScaleScroll; virtual;
|
|
procedure FormatChanged; virtual;
|
|
function GetClientRect: TRect; virtual;
|
|
function GetOwner: TPersistent; override;
|
|
function GetHScrollBarBounds: TRect; virtual;
|
|
function GetScrollBar(AKind: TScrollBarKind): TcxControlScrollBar;
|
|
function GetSizeGripBounds: TRect; virtual;
|
|
function GetStartOfWeek: TDay; virtual;
|
|
function GetVScrollBarBounds: TRect; virtual;
|
|
procedure InitScrollBarsParameters; virtual;
|
|
function IsSpecialPaint: Boolean; virtual;
|
|
procedure LookAndFeelChanged(Sender: TcxLookAndFeel; AChangedValues: TcxLookAndFeelValues); virtual;
|
|
procedure MousePositionChanged(var X, Y: Integer);
|
|
procedure Notification(AComponent: TComponent; Operation: TOperation); virtual;
|
|
procedure Paint;
|
|
procedure PeriodChanged; virtual;
|
|
procedure SetScrollBarInfo(AScrollBarKind: TScrollBarKind;
|
|
AMin, AMax, AStep, APage, APos: Integer; AAllowShow, AAllowHide: Boolean);
|
|
procedure VisibleChanged; virtual;
|
|
|
|
property Canvas: TcxCanvas read FCanvas;
|
|
{$IFNDEF DEBUGPAINT}
|
|
property Bitmap: TBitmap read GetBitmap;
|
|
{$ENDIF}
|
|
property Bottom: Integer read GetBottom write SetBottom;
|
|
property ClientRect: TRect read GetClientRect;
|
|
property Controller: TcxSchedulerSubControlController read FController;
|
|
property Cursor: TCursor read FCursor write FCursor;
|
|
property DateTimeHelper: TcxSchedulerDateTimeHelperClass read GetDateTimeHelperClass;
|
|
property HitTest: TcxSchedulerSubControlHitTest read FHitTest;
|
|
property IsScrollingContent: Boolean read GetIsScrollingContent;
|
|
property Left: Integer read FLeft write SetLeft;
|
|
property LookAndFeelPainter: TcxCustomLookAndFeelPainterClass read GetLookAndFeelPainter;
|
|
property Painter: TcxSchedulerSubControlPainter read FPainter;
|
|
property PainterHelper: TcxSchedulerPainterHelperClass read GetPainterHelperClass;
|
|
property Right: Integer read GetRight write SetRight;
|
|
property Scheduler: TcxCustomScheduler read FScheduler;
|
|
property StartOfWeek: TDay read GetStartOfWeek;
|
|
property Styles: TcxSchedulerStyles read GetStyles;
|
|
property Top: Integer read FTop write SetTop;
|
|
property ViewInfo: TcxSchedulerSubControlViewInfo read FViewInfo;
|
|
property Visible: Boolean read FVisible write SetVisible;
|
|
public
|
|
constructor Create(AOwner: TcxCustomScheduler); virtual;
|
|
destructor Destroy; override;
|
|
procedure Invalidate;
|
|
procedure InvalidateRect(const ARect: TRect);
|
|
procedure LayoutChanged;
|
|
procedure Refresh;
|
|
procedure Repaint;
|
|
procedure RepaintRect(const ARect: TRect);
|
|
function ScreenToClient(const APos: TPoint): TPoint;
|
|
procedure SetBounds(ALeft, ATop, AWidth, AHeight: Integer);
|
|
|
|
property Bounds: TRect read GetBounds write InternalSetBounds;
|
|
property Height: Integer read FHeight write SetHeight;
|
|
property Width: Integer read FWidth write SetWidth;
|
|
end;
|
|
|
|
{ TcxSchedulerSubControlController }
|
|
|
|
TcxSchedulerSubControlController = class(TcxIUnknownObject)
|
|
private
|
|
FCanProcessMouseMove: Boolean;
|
|
FOwner: TcxSchedulerSubControl;
|
|
function GetHitTest: TcxSchedulerSubControlHitTest;
|
|
function GetStartOfWeek: TDay;
|
|
protected
|
|
// drag'n'drop
|
|
procedure BeginDragAndDrop; virtual;
|
|
function CanDrag(X, Y: Integer): Boolean; virtual;
|
|
procedure DragAndDrop(const P: TPoint; var Accepted: Boolean); virtual;
|
|
procedure DragDrop(Source: TObject; X, Y: Integer); virtual;
|
|
procedure DragOver(Source: TObject; X, Y: Integer; State: TDragState;
|
|
var Accept: Boolean); virtual;
|
|
procedure EndDrag(Target: TObject; X, Y: Integer); virtual;
|
|
procedure EndDragAndDrop(Accepted: Boolean); virtual;
|
|
function GetDragAndDropObjectClass: TcxDragAndDropObjectClass; virtual;
|
|
procedure StartDrag(var DragObject: TDragObject); virtual;
|
|
function StartDragAndDrop(const P: TPoint): Boolean; virtual;
|
|
// virtuals
|
|
procedure BeforeMouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); virtual;
|
|
procedure DoCancelMode; virtual;
|
|
function GetCursor(X, Y: Integer): TCursor; virtual;
|
|
procedure KeyDown(var Key: Word; Shift: TShiftState); virtual;
|
|
procedure KeyPress(var Key: Char); virtual;
|
|
procedure KeyUp(var Key: Word; Shift: TShiftState); virtual;
|
|
procedure MouseEnter; virtual;
|
|
procedure MouseLeave; virtual;
|
|
procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); virtual;
|
|
procedure MouseMove(Shift: TShiftState; X, Y: Integer); virtual;
|
|
procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); virtual;
|
|
procedure Reset; virtual;
|
|
|
|
property CanProcessMouseMove: Boolean read FCanProcessMouseMove;
|
|
public
|
|
constructor Create(AOwner: TcxSchedulerSubControl); virtual;
|
|
|
|
property HitTest: TcxSchedulerSubControlHitTest read GetHitTest;
|
|
property Owner: TcxSchedulerSubControl read FOwner;
|
|
property StartOfWeek: TDay read GetStartOfWeek;
|
|
end;
|
|
|
|
{ TcxSchedulerSubControlHitTest }
|
|
|
|
TcxSchedulerSubControlHitTest = class
|
|
private
|
|
FOwner: TcxSchedulerSubControl;
|
|
FHitPoint: TPoint;
|
|
function GetPosValue(AIndex: Integer): Integer;
|
|
function GetScheduler: TcxCustomScheduler;
|
|
procedure SetHitPoint(const APoint: TPoint);
|
|
procedure SetPosValue(AIndex, AValue: Integer);
|
|
protected
|
|
FTime: TDateTime;
|
|
Flags: Int64;
|
|
procedure Clear; virtual;
|
|
procedure DoCalculate; virtual;
|
|
function GetBitState(AIndex: Integer): Boolean;
|
|
function GetMaskState(AMask: Integer): Boolean;
|
|
function GetMaskStateEx(AMask: Integer): Boolean;
|
|
procedure SetBitState(AIndex: Integer; AValue: Boolean);
|
|
procedure SetMaskState(AMask: Integer; AValue: Boolean);
|
|
property Owner: TcxSchedulerSubControl read FOwner;
|
|
property Scheduler: TcxCustomScheduler read GetScheduler;
|
|
public
|
|
constructor Create(AOwner: TcxSchedulerSubControl); virtual;
|
|
destructor Destroy; override;
|
|
procedure Recalculate;
|
|
|
|
property HitPoint: TPoint read FHitPoint write SetHitPoint;
|
|
property HitX: Integer index 0 read GetPosValue write SetPosValue;
|
|
property HitY: Integer index 1 read GetPosValue write SetPosValue;
|
|
property HitAtControl: Boolean index htcControl read GetBitState;
|
|
property HitAtTime: Boolean index htcTime read GetBitState;
|
|
property Time: TDateTime read FTime;
|
|
end;
|
|
|
|
{ TcxSchedulerSubControlPainter }
|
|
|
|
TcxSchedulerSubControlPainter = class
|
|
private
|
|
FOwner: TcxSchedulerSubControl;
|
|
{$IFNDEF DEBUGPAINT}
|
|
function GetBitmap: TBitmap;
|
|
{$ENDIF}
|
|
function GetCanvas: TcxCanvas;
|
|
function GetViewInfo: TcxSchedulerSubControlViewInfo;
|
|
protected
|
|
property Owner: TcxSchedulerSubControl read FOwner;
|
|
property ViewInfo: TcxSchedulerSubControlViewInfo read GetViewInfo;
|
|
public
|
|
constructor Create(AOwner: TcxSchedulerSubControl); virtual;
|
|
procedure AfterPaint; virtual;
|
|
procedure BeforePaint; virtual;
|
|
procedure InitializePainter; virtual;
|
|
procedure Paint; virtual;
|
|
|
|
property Canvas: TcxCanvas read GetCanvas;
|
|
{$IFNDEF DEBUGPAINT}
|
|
property Bitmap: TBitmap read GetBitmap;
|
|
{$ENDIF}
|
|
end;
|
|
|
|
{ TcxSchedulerSubControlViewInfo }
|
|
|
|
TcxSchedulerSubControlViewInfo = class(TcxIUnknownObject)
|
|
private
|
|
FOwner: TcxSchedulerSubControl;
|
|
function GetDateTimeHelperClass: TcxSchedulerDateTimeHelperClass;
|
|
function GetDefaultFont: TFont;
|
|
function GetIsSchedulerCreated: Boolean;
|
|
function GetLookAndFeelPainter: TcxCustomLookAndFeelPainterClass;
|
|
function GetPainterHelperClass: TcxSchedulerPainterHelperClass;
|
|
function GetStyles: TcxSchedulerStyles;
|
|
protected
|
|
FBounds: TRect;
|
|
procedure AfterCalculate; virtual;
|
|
procedure Clear; virtual;
|
|
procedure DoCalculate; virtual;
|
|
function GetBounds: TRect; virtual;
|
|
|
|
property DateTimeHelper: TcxSchedulerDateTimeHelperClass read GetDateTimeHelperClass;
|
|
property DefaultFont: TFont read GetDefaultFont;
|
|
property IsSchedulerCreated: Boolean read GetIsSchedulerCreated;
|
|
property LookAndFeelPainter: TcxCustomLookAndFeelPainterClass read GetLookAndFeelPainter;
|
|
property Bounds: TRect read FBounds;
|
|
property Owner: TcxSchedulerSubControl read FOwner;
|
|
property PainterHelper: TcxSchedulerPainterHelperClass read GetPainterHelperClass;
|
|
property Styles: TcxSchedulerStyles read GetStyles;
|
|
public
|
|
constructor Create(AOwner: TcxSchedulerSubControl); virtual;
|
|
procedure Calculate; virtual;
|
|
end;
|
|
|
|
{ TcxSchedulerBackground }
|
|
|
|
TcxSchedulerBackground = class(TcxSchedulerSubControl)
|
|
protected
|
|
function IsSpecialPaint: Boolean; override;
|
|
end;
|
|
|
|
{ TcxSchedulerControlBox }
|
|
|
|
TcxSchedulerControlBox = class(TcxSchedulerSubControl)
|
|
private
|
|
FContainer: TWinControl;
|
|
FControlAlign: TAlign;
|
|
FControlParent: TWinControl;
|
|
FControlRect: TRect;
|
|
FControl: TControl;
|
|
FViewParams: TcxViewParams;
|
|
procedure RestorePosition;
|
|
procedure SetControl(AValue: TControl);
|
|
procedure StorePosition;
|
|
protected
|
|
// store interface
|
|
procedure GetProperties(AProperties: TStrings); override;
|
|
procedure GetPropertyValue(const AName: string; var AValue: Variant); override;
|
|
procedure SetPropertyValue(const AName: string; const AValue: Variant); override;
|
|
//
|
|
procedure BoundsChanged; override;
|
|
function CreateWndContainerControl: TWinControl; virtual;
|
|
procedure DoPaint; override;
|
|
procedure DoLayoutChanged; override;
|
|
function HasAsParent(AValue: TControl): Boolean;
|
|
procedure VisibleChanged; override;
|
|
|
|
property ViewParams: TcxViewParams read FViewParams;
|
|
public
|
|
constructor Create(AOwner: TcxCustomScheduler); override;
|
|
procedure Assign(Source: TPersistent); override;
|
|
|
|
property Container: TWinControl read FContainer;
|
|
property Height;
|
|
property Width;
|
|
published
|
|
property Control: TControl read FControl write SetControl;
|
|
property Visible default True;
|
|
end;
|
|
|
|
{ TcxSchedulerSplitterController }
|
|
|
|
TcxSchedulerSplitterController = class(TcxSchedulerSubControlController)
|
|
private
|
|
FHitPoint: TPoint;
|
|
FPrevInvertRect: TRect;
|
|
FPrevRect: TRect;
|
|
FSaveKeyboardListener: TcxSchedulerSubControl;
|
|
FSizingBoundsRect: TRect;
|
|
FStartBounds: TRect;
|
|
FScreenCanvasClipRect: TRect;
|
|
function GetDrawClipRect: TRect;
|
|
function GetHorzSizingRect(const P: TPoint): TRect;
|
|
function GetScheduler: TcxCustomScheduler;
|
|
function GetScreenOffset: TPoint;
|
|
function GetSplitter: TcxSchedulerSplitter;
|
|
function GetVertSizingRect(const P: TPoint): TRect;
|
|
procedure SetHorzBounds(var R: TRect);
|
|
procedure SetHorzDelta(ADelta: Integer);
|
|
procedure SetVertBounds(var R: TRect);
|
|
procedure SetVertDelta(ADelta: Integer);
|
|
protected
|
|
// override
|
|
procedure DoCancelMode; override;
|
|
procedure KeyDown(var Key: Word; Shift: TShiftState); override;
|
|
procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
|
|
procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
|
|
procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
|
|
// methods
|
|
procedure DrawInvertRect(const R: TRect);
|
|
procedure EraseInvertRect;
|
|
function GetMonthSize: TSize;
|
|
function GetOwnerMousePos(X, Y: Integer): TPoint;
|
|
function GetSizingBoundsRect: TRect;
|
|
function GetSizingIncrement: Integer;
|
|
function GetSizingRect(const P: TPoint): TRect;
|
|
procedure InvertRect(ACanvas: TcxCanvas; R: TRect);
|
|
function IsIntegralSizing: Boolean;
|
|
function IsDynamicUpdate: Boolean;
|
|
procedure SetSizeDelta(ADelta: Integer);
|
|
procedure UpdateSizing(const R: TRect);
|
|
|
|
property Scheduler: TcxCustomScheduler read GetScheduler;
|
|
property ScreenCanvasClipRect: TRect read FScreenCanvasClipRect;
|
|
property ScreenOffset: TPoint read GetScreenOffset;
|
|
property SizingBoundsRect: TRect read FSizingBoundsRect;
|
|
property Splitter: TcxSchedulerSplitter read GetSplitter;
|
|
end;
|
|
|
|
{ TcxSchedulerSplitterHitTest }
|
|
|
|
TcxSchedulerSplitterHitTest = class(TcxSchedulerSubControlHitTest)
|
|
private
|
|
function GetSplitter: TcxSchedulerSplitter;
|
|
public
|
|
property Splitter: TcxSchedulerSplitter read GetSplitter;
|
|
end;
|
|
|
|
{ TcxSchedulerSplitter }
|
|
|
|
TcxSchedulerSplitter = class(TcxSchedulerBackground)
|
|
private
|
|
FKind: TcxSchedulerSplitterKind;
|
|
FViewParams: TcxViewParams;
|
|
function GetHitTest: TcxSchedulerSplitterHitTest;
|
|
protected
|
|
function AllowDesignHitTest(X, Y: Integer; AShift: TShiftState): Boolean; override;
|
|
function CreateController: TcxSchedulerSubControlController; override;
|
|
function CreateHitTest: TcxSchedulerSubControlHitTest; override;
|
|
procedure DoLayoutChanged; override;
|
|
procedure DoPaint; override;
|
|
procedure SetKind(AKind: TcxSchedulerSplitterKind); virtual;
|
|
procedure UpdateCursor;
|
|
|
|
property HitTest: TcxSchedulerSplitterHitTest read GetHitTest;
|
|
property ViewParams: TcxViewParams read FViewParams;
|
|
public
|
|
property Kind: TcxSchedulerSplitterKind read FKind;
|
|
end;
|
|
|
|
{ TcxSchedulerNavigatorButton }
|
|
|
|
TcxSchedulerNavigatorButtonClickEvent = procedure(Sender: TcxSchedulerResourceNavigator;
|
|
AButton: TcxSchedulerNavigatorButton; var AHandled: Boolean) of object;
|
|
|
|
TcxSchedulerNavigatorButton = class(TCollectionItem)
|
|
private
|
|
FCommand: Integer;
|
|
FEnabled: Boolean;
|
|
FHint: string;
|
|
FImageIndex: Integer;
|
|
FVisible: Boolean;
|
|
function GetScheduler: TcxCustomScheduler;
|
|
procedure SetEnabled(AValue: Boolean);
|
|
procedure SetImageIndex(AValue: Integer);
|
|
procedure SetVisible(AValue: Boolean);
|
|
function IsHintStored: Boolean;
|
|
function IsEnabledStored: Boolean;
|
|
function IsVisibleStored: Boolean;
|
|
protected
|
|
FBounds: TRect;
|
|
FRotated: Boolean;
|
|
FState: TcxButtonState;
|
|
FVisibleIndex: Integer;
|
|
procedure Changed; virtual;
|
|
procedure Click; virtual;
|
|
function GetDisplayName: string; override;
|
|
function GetHintText: string;
|
|
procedure Draw(APainter: TcxCustomLookAndFeelPainterClass; ACanvas: TcxCanvas); virtual;
|
|
function GetActualImageIndex: Integer; virtual;
|
|
function GetActualImageList: TCustomImageList; virtual;
|
|
function GetState(ACanDisabled: Boolean = True): TcxButtonState;
|
|
function GetIsStandard: Boolean; virtual;
|
|
|
|
property Command: Integer read FCommand write FCommand;
|
|
public
|
|
constructor Create(Collection: TCollection); override;
|
|
procedure Assign(Source: TPersistent); override;
|
|
|
|
property ActualImageIndex: Integer read GetActualImageIndex;
|
|
property ActualImageList: TCustomImageList read GetActualImageList;
|
|
property Bounds: TRect read FBounds;
|
|
property Enabled: Boolean read FEnabled write SetEnabled stored IsEnabledStored;
|
|
property Rotated: Boolean read FRotated;
|
|
property Scheduler: TcxCustomScheduler read GetScheduler;
|
|
property IsStandard: Boolean read GetIsStandard;
|
|
property State: TcxButtonState read FState;
|
|
property VisibleIndex: Integer read FVisibleIndex;
|
|
published
|
|
property Hint: string read FHint write FHint stored IsHintStored;
|
|
property ImageIndex: Integer read FImageIndex write SetImageIndex default -1;
|
|
property Visible: Boolean read FVisible write SetVisible stored IsVisibleStored;
|
|
end;
|
|
|
|
{ TcxSchedulerNavigatorCustomButton }
|
|
|
|
TcxSchedulerNavigatorCustomButton = class(TcxSchedulerNavigatorButton)
|
|
published
|
|
property Enabled;
|
|
end;
|
|
|
|
TcxSchedulerNavigatorButtonClass = class of TcxSchedulerNavigatorButton;
|
|
|
|
{ TcxSchedulerNavigatorCustomButtons }
|
|
|
|
TcxSchedulerNavigatorCustomButtons = class(TCollection)
|
|
private
|
|
FOwner: TPersistent;
|
|
FScheduler: TcxCustomScheduler;
|
|
function GetItem(AIndex: Integer): TcxSchedulerNavigatorCustomButton;
|
|
function GetVisibleCount: Integer;
|
|
procedure SetItem(AIndex: Integer; AValue: TcxSchedulerNavigatorCustomButton);
|
|
protected
|
|
function GetOwner: TPersistent; override;
|
|
procedure Update(Item: TCollectionItem); override;
|
|
|
|
property Scheduler: TcxCustomScheduler read FScheduler;
|
|
public
|
|
constructor CreateEx(AOwner: TPersistent; AItemClass: TCollectionItemClass); virtual;
|
|
|
|
property VisibleCount: Integer read GetVisibleCount;
|
|
property Items[AIndex: Integer]: TcxSchedulerNavigatorCustomButton read GetItem write SetItem; default;
|
|
end;
|
|
|
|
{ TcxSchedulerNavigatorButtons }
|
|
|
|
TcxSchedulerNavigatorButtons = class(TPersistent)
|
|
private
|
|
FButtons: TcxSchedulerNavigatorCustomButtons;
|
|
FOwner: TcxSchedulerResourceNavigator;
|
|
function GetButtonByIndex(AIndex: Integer): TcxSchedulerNavigatorButton;
|
|
procedure SetButtonByIndex(AIndex: Integer; AValue: TcxSchedulerNavigatorButton);
|
|
protected
|
|
function AddButton(ACommand: Integer; AVisible: Boolean = True): TcxSchedulerNavigatorButton;
|
|
procedure CreateButtons; virtual;
|
|
function GetOwner: TPersistent; override;
|
|
public
|
|
constructor Create(AOwner: TcxSchedulerResourceNavigator); virtual;
|
|
destructor Destroy; override;
|
|
procedure Assign(Source: TPersistent); override;
|
|
|
|
property Buttons: TcxSchedulerNavigatorCustomButtons read FButtons;
|
|
property ResourceNavigator: TcxSchedulerResourceNavigator read FOwner;
|
|
published
|
|
property First: TcxSchedulerNavigatorButton index cxSchedulerFirstButton read GetButtonByIndex write SetButtonByIndex;
|
|
property PrevPage: TcxSchedulerNavigatorButton index cxSchedulerPrevPageButton read GetButtonByIndex write SetButtonByIndex;
|
|
property Prev: TcxSchedulerNavigatorButton index cxSchedulerPrevButton read GetButtonByIndex write SetButtonByIndex;
|
|
property Next: TcxSchedulerNavigatorButton index cxSchedulerNextButton read GetButtonByIndex write SetButtonByIndex;
|
|
property NextPage: TcxSchedulerNavigatorButton index cxSchedulerNextPageButton read GetButtonByIndex write SetButtonByIndex;
|
|
property Last: TcxSchedulerNavigatorButton index cxSchedulerLastButton read GetButtonByIndex write SetButtonByIndex;
|
|
property ShowFewerResources: TcxSchedulerNavigatorButton index cxSchedulerShowFewerResourcesButton read GetButtonByIndex write SetButtonByIndex;
|
|
property ShowMoreResources: TcxSchedulerNavigatorButton index cxSchedulerShowMoreResourcesButton read GetButtonByIndex write SetButtonByIndex;
|
|
end;
|
|
|
|
{ TcxSchedulerResourceNavigatorController }
|
|
|
|
TcxSchedulerResourceNavigatorController = class(TcxSchedulerSubControlController)
|
|
private
|
|
FHotTrackButton: TcxSchedulerNavigatorButton;
|
|
function GetHintController: TcxSchedulerHintController;
|
|
function GetResourceNavigator: TcxSchedulerResourceNavigator;
|
|
procedure SetHotTrackButton(Value: TcxSchedulerNavigatorButton);
|
|
protected
|
|
procedure BeforeMouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
|
|
procedure CheckButtonDown(Button: TMouseButton; Shift: TShiftState); virtual;
|
|
function GetHotTrackButton(ACanDisabled: Boolean = True): TcxSchedulerNavigatorButton;
|
|
procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
|
|
procedure MouseMove(AShift: TShiftState; X, Y: Integer); override;
|
|
procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
|
|
procedure MouseEnter; override;
|
|
procedure MouseLeave; override;
|
|
|
|
property HintController: TcxSchedulerHintController read GetHintController;
|
|
property HotTrackButton: TcxSchedulerNavigatorButton read FHotTrackButton write SetHotTrackButton;
|
|
property ResourceNavigator: TcxSchedulerResourceNavigator read GetResourceNavigator;
|
|
end;
|
|
|
|
{ TcxSchedulerResourceNavigatorHitTest }
|
|
|
|
TcxSchedulerResourceNavigatorHitTest = class(TcxSchedulerSubControlHitTest)
|
|
private
|
|
function GetCurrentButton(AButtons: TcxSchedulerNavigatorCustomButtons): TcxSchedulerNavigatorButton;
|
|
function GetHitAtButton: Boolean;
|
|
function GetHitButton: TcxSchedulerNavigatorButton;
|
|
function GetResourceNavigator: TcxSchedulerResourceNavigator;
|
|
public
|
|
property HitAtButton: Boolean read GetHitAtButton;
|
|
property HitButton: TcxSchedulerNavigatorButton read GetHitButton;
|
|
property ResourceNavigator: TcxSchedulerResourceNavigator read GetResourceNavigator;
|
|
end;
|
|
|
|
{ TcxSchedulerResourceNavigator }
|
|
|
|
TcxSchedulerNavigatorCustomDrawButtonEvent = procedure(Sender: TcxSchedulerResourceNavigator;
|
|
ACanvas: TcxCanvas; AButton: TcxSchedulerNavigatorButton; var ADone: Boolean) of object;
|
|
|
|
TcxSchedulerNavigatorVisibilityMode = (snvNever, snvAlways, snvAuto);
|
|
|
|
TcxSchedulerResourceNavigator = class(TcxSchedulerSubControl)
|
|
private
|
|
FButtons: TcxSchedulerNavigatorButtons;
|
|
FButtonImages: TCustomImageList;
|
|
FCustomButtons: TcxSchedulerNavigatorCustomButtons;
|
|
FShowButtons: Boolean;
|
|
FTimer: TTimer;
|
|
FScrollBarKind: TScrollBarKind;
|
|
FVisibility: TcxSchedulerNavigatorVisibilityMode;
|
|
FOnButtonClick: TcxSchedulerNavigatorButtonClickEvent;
|
|
FOnCustomDrawButton: TcxSchedulerNavigatorCustomDrawButtonEvent;
|
|
function GetFirstVisibleResourceIndex: Integer;
|
|
function GetHitTest: TcxSchedulerResourceNavigatorHitTest;
|
|
function GetItem(AIndex: Integer): TcxSchedulerNavigatorButton;
|
|
function GetItemCount: Integer;
|
|
function GetResourceCount: Integer;
|
|
function GetResourcesPerPage: Integer;
|
|
function GetVisibleButtonCount: Integer;
|
|
procedure SetButtonImages(Value: TCustomImageList);
|
|
procedure SetButtons(Value: TcxSchedulerNavigatorButtons);
|
|
procedure SetCustomButtons(Value: TcxSchedulerNavigatorCustomButtons);
|
|
procedure SetFirstVisibleResourceIndex(AValue: Integer);
|
|
procedure SetResourcesPerPage(AValue: Integer);
|
|
procedure SetShowButtons(AValue: Boolean);
|
|
procedure SetVisibility(AValue: TcxSchedulerNavigatorVisibilityMode);
|
|
function IsCustomButtonsStored: Boolean;
|
|
protected
|
|
FPressedButton: TcxSchedulerNavigatorButton;
|
|
FVisibleButtonCount: Integer;
|
|
procedure BoundsChanged; override;
|
|
procedure ButtonClickHandler(AButton: TcxSchedulerNavigatorButton); virtual;
|
|
procedure CalculateBounds; virtual;
|
|
procedure CheckButtonsState; virtual;
|
|
procedure Click(Sender: TcxSchedulerNavigatorButton);
|
|
function CreateController: TcxSchedulerSubControlController; override;
|
|
function CreateHitTest: TcxSchedulerSubControlHitTest; override;
|
|
function CreateButtons: TcxSchedulerNavigatorCustomButtons; virtual;
|
|
function CreateStandardButtons: TcxSchedulerNavigatorButtons; virtual;
|
|
function DoCustomDrawButton(AButton: TcxSchedulerNavigatorButton): Boolean; virtual;
|
|
function DoOnClick(Sender: TcxSchedulerNavigatorButton): Boolean; virtual;
|
|
procedure DoPaint; override;
|
|
procedure FirstVisibleResourceChanged;
|
|
function GetCustomButtonClass: TcxSchedulerNavigatorButtonClass; virtual;
|
|
function GetScrollerHint: string;
|
|
procedure InitScrollBarsParameters; override;
|
|
procedure InvalidateButton(AButton: TcxSchedulerNavigatorButton);
|
|
procedure Scroll(AScrollCode: TScrollCode; var AScrollPos: Integer); virtual;
|
|
//
|
|
function ActualCountPerPage: Integer;
|
|
function ActualFirstResourceIndex: Integer;
|
|
function ButtonSize: TSize;
|
|
function MeasureHeight: Integer; virtual;
|
|
function MeasureWidth: Integer; virtual;
|
|
|
|
property FirstVisibleResourceIndex: Integer read GetFirstVisibleResourceIndex write SetFirstVisibleResourceIndex;
|
|
property HitTest: TcxSchedulerResourceNavigatorHitTest read GetHitTest;
|
|
property ResourcesPerPage: Integer read GetResourcesPerPage write SetResourcesPerPage;
|
|
property Timer: TTimer read FTimer;
|
|
public
|
|
constructor Create(AOwner: TcxCustomScheduler); override;
|
|
destructor Destroy; override;
|
|
procedure Assign(Source: TPersistent); override;
|
|
function NeedScrollBar: Boolean; virtual;
|
|
|
|
property ItemCount: Integer read GetItemCount;
|
|
property Items[Index: Integer]: TcxSchedulerNavigatorButton read GetItem;
|
|
property ResourceCount: Integer read GetResourceCount;
|
|
property Scheduler;
|
|
property ScrollBarKind: TScrollBarKind read FScrollBarKind;
|
|
property VisibleButtonCount: Integer read FVisibleButtonCount;
|
|
published
|
|
property ButtonImages: TCustomImageList read FButtonImages write SetButtonImages;
|
|
property Buttons: TcxSchedulerNavigatorButtons read FButtons write SetButtons;
|
|
property CustomButtons: TcxSchedulerNavigatorCustomButtons read FCustomButtons write SetCustomButtons stored IsCustomButtonsStored;
|
|
property ShowButtons: Boolean read FShowButtons write SetShowButtons default True;
|
|
property Visibility: TcxSchedulerNavigatorVisibilityMode read FVisibility write SetVisibility default snvAuto;
|
|
property OnButtonClick: TcxSchedulerNavigatorButtonClickEvent read FOnButtonClick write FOnButtonClick;
|
|
property OnCustomDrawButton: TcxSchedulerNavigatorCustomDrawButtonEvent read FOnCustomDrawButton write FOnCustomDrawButton;
|
|
end;
|
|
|
|
{ TcxSchedulerOptionsData }
|
|
|
|
TcxSchedulerEventOperations = class(TPersistent)
|
|
private
|
|
FScheduler: TcxCustomScheduler;
|
|
FCreating: Boolean;
|
|
FDeleting: Boolean;
|
|
FDialogEditing: Boolean;
|
|
FDialogShowing: Boolean;
|
|
FInplaceEditing: Boolean;
|
|
FIntersection: Boolean;
|
|
FMoving: Boolean;
|
|
FMovingBetweenResources: Boolean;
|
|
FReadOnly: Boolean;
|
|
FRecurrence: Boolean;
|
|
FSharingBetweenResources: Boolean;
|
|
FSizing: Boolean;
|
|
function GetCreating: Boolean;
|
|
function GetCreatingStored: Boolean;
|
|
function GetDeleting: Boolean;
|
|
function GetDeletingStored: Boolean;
|
|
function GetDialogEditing: Boolean;
|
|
function GetDialogEditingStored: Boolean;
|
|
function GetInplaceEditing: Boolean;
|
|
function GetInplaceEditingStored: Boolean;
|
|
function GetMoving: Boolean;
|
|
function GetMovingBetweenResources: Boolean;
|
|
function GetMovingBetweenResourcesStored: Boolean;
|
|
function GetMovingStored: Boolean;
|
|
function GetSizing: Boolean;
|
|
function GetSizingStored: Boolean;
|
|
protected
|
|
function GetOwner: TPersistent; override;
|
|
|
|
property Scheduler: TcxCustomScheduler read FScheduler;
|
|
public
|
|
constructor Create(AOwner: TcxCustomScheduler); virtual;
|
|
procedure Assign(Source: TPersistent); override;
|
|
published
|
|
property Creating: Boolean
|
|
read GetCreating write FCreating stored GetCreatingStored;
|
|
property Deleting: Boolean
|
|
read GetDeleting write FDeleting stored GetDeletingStored;
|
|
property DialogEditing: Boolean
|
|
read GetDialogEditing write FDialogEditing stored GetDialogEditingStored;
|
|
property DialogShowing: Boolean read FDialogShowing write FDialogShowing default True;
|
|
property InplaceEditing: Boolean
|
|
read GetInplaceEditing write FInplaceEditing stored GetInplaceEditingStored;
|
|
property Intersection: Boolean read FIntersection write FIntersection default True;
|
|
property MovingBetweenResources: Boolean
|
|
read GetMovingBetweenResources write FMovingBetweenResources
|
|
stored GetMovingBetweenResourcesStored;
|
|
property Moving: Boolean
|
|
read GetMoving write FMoving stored GetMovingStored;
|
|
property ReadOnly: Boolean read FReadOnly write FReadOnly default False;
|
|
property Recurrence: Boolean read FRecurrence write FRecurrence default True;
|
|
property SharingBetweenResources: Boolean read FSharingBetweenResources write FSharingBetweenResources default False;
|
|
property Sizing: Boolean read GetSizing write FSizing stored GetSizingStored;
|
|
end;
|
|
|
|
{ TcxSchedulerOptionsCustomize }
|
|
|
|
TcxSchedulerOptionsCustomize = class(TPersistent)
|
|
private
|
|
FControlsSizing: Boolean;
|
|
FDynamicSizing: Boolean;
|
|
FIntegralSizing: Boolean;
|
|
FScheduler: TcxCustomScheduler;
|
|
procedure SetControlsSizing(AValue: Boolean);
|
|
procedure SetIntegralSizing(AValue: Boolean);
|
|
protected
|
|
procedure Changed; virtual;
|
|
function GetOwner: TPersistent; override;
|
|
public
|
|
constructor Create(AOwner: TcxCustomScheduler); virtual;
|
|
procedure Assign(Source: TPersistent); override;
|
|
|
|
property Scheduler: TcxCustomScheduler read FScheduler;
|
|
published
|
|
property ControlsSizing: Boolean read FControlsSizing write SetControlsSizing default True;
|
|
property DynamicSizing: Boolean read FDynamicSizing write FDynamicSizing default False;
|
|
property IntegralSizing: Boolean read FIntegralSizing write SetIntegralSizing default True;
|
|
end;
|
|
|
|
{ TcxSchedulerResourceHeaders }
|
|
|
|
TcxSchedulerHeaderImagePosition = (ipLeft, ipTop, ipRight, ipBottom);
|
|
|
|
TcxSchedulerResourceHeaders = class(TPersistent)
|
|
private
|
|
FHeight: Integer;
|
|
FImagePosition: TcxSchedulerHeaderImagePosition;
|
|
FMultilineCaptions: Boolean;
|
|
FOwner: TcxSchedulerOptionsView;
|
|
FRotateCaptions: Boolean;
|
|
procedure SetHeight(AValue: Integer);
|
|
procedure SetImagePosition(AValue: TcxSchedulerHeaderImagePosition);
|
|
procedure SetMultilineCaptions(AValue: Boolean);
|
|
procedure SetRotateCations(AValue: Boolean);
|
|
function IsImagePositionStored: Boolean;
|
|
protected
|
|
procedure Changed;
|
|
function GetOwner: TPersistent; override;
|
|
property Owner: TcxSchedulerOptionsView read FOwner;
|
|
public
|
|
constructor Create(AOwner: TcxSchedulerOptionsView); virtual;
|
|
procedure Assign(Source: TPersistent); override;
|
|
published
|
|
property Height: Integer read FHeight write SetHeight default 0;
|
|
property MultilineCaptions: Boolean read FMultilineCaptions write SetMultilineCaptions default False;
|
|
property ImagePosition: TcxSchedulerHeaderImagePosition read FImagePosition write SetImagePosition stored IsImagePositionStored;
|
|
property RotateCaptions: Boolean read FRotateCaptions write SetRotateCations default True;
|
|
end;
|
|
|
|
{ TcxSchedulerOptionsView }
|
|
|
|
TcxSchedulerOptionsView = class(TPersistent)
|
|
private
|
|
FActualStartOfWeek: TDay;
|
|
FAdditionalTimeZoneDaylightSaving: Boolean;
|
|
FCurrentTimeZoneDaylightSaving: Boolean;
|
|
FDayBorderColor: TColor;
|
|
FEventBorderColor: TColor;
|
|
FEventHeight: Integer;
|
|
FGroupingKind: TcxSchedulerGroupingKind;
|
|
FGroupSeparatorWidth: Integer;
|
|
FHideSelection: Boolean;
|
|
FHorzSplitterWidth: Integer;
|
|
FHotTrack: Boolean;
|
|
FResourceHeaders: TcxSchedulerResourceHeaders;
|
|
FResourcesPerPage: Integer;
|
|
FScheduler: TcxCustomScheduler;
|
|
FShowAdditionalTimeZone: Boolean;
|
|
FShowEventsWithoutResource: Boolean;
|
|
FShowHints: Boolean;
|
|
FShowNavigationButtons: Boolean;
|
|
FStartOfWeek: TcxStartOfWeek;
|
|
FTimeZoneLabels: array[0..1] of string;
|
|
FTimeZones: array[0..1] of Integer;
|
|
FVertSplitterWidth: Integer;
|
|
FViewPosition: TcxSchedulerViewPosition;
|
|
FWorkDays: TDays;
|
|
FWorkFinish: TTime;
|
|
FWorkFinishAssigned: Boolean;
|
|
FWorkStart: TTime;
|
|
FWorkStartAssigned: Boolean;
|
|
function GetDateTimeHelperClass: TcxSchedulerDateTimeHelperClass;
|
|
function GetRotateResourceCaptions: Boolean;
|
|
function GetTimeZone(AIndex: Integer): Integer;
|
|
function GetTimeZoneLabel(AIndex: Integer): string;
|
|
function IsTimeZoneLabelStored(AIndex: Integer): Boolean;
|
|
procedure SetATZDaylightSaving(AValue: Boolean);
|
|
procedure SetCTZDaylightSaving(AValue: Boolean);
|
|
procedure SetDayBorderColor(AValue: TColor);
|
|
procedure SetEventBorderColor(AValue: TColor);
|
|
procedure SetEventHeight(AValue: Integer);
|
|
procedure SetGroupingKind(AValue: TcxSchedulerGroupingKind);
|
|
procedure SetGroupSeparatorWidth(AValue: Integer);
|
|
procedure SetHideSelection(AValue: Boolean);
|
|
procedure SetHorzSplitterWidth(AValue: Integer);
|
|
procedure SetResourceHeaders(AValue: TcxSchedulerResourceHeaders);
|
|
procedure SetResourcesPerPage(AValue: Integer);
|
|
procedure SetRotateResourceCaptions(AValue: Boolean);
|
|
procedure SetShowAdditionalTimeZone(AValue: Boolean);
|
|
procedure SetShowEventsWithoutResource(AValue: Boolean);
|
|
procedure SetShowNavigationButtons(AValue: Boolean);
|
|
procedure SetSplitterWidth(AValue: Integer; var AWidth: Integer);
|
|
procedure SetStartOfWeek(AValue: TcxStartOfWeek);
|
|
procedure SetTimeZone(AIndex, AValue: Integer);
|
|
procedure SetTimeZoneLabel(AIndex: Integer; const AValue: string);
|
|
procedure SetVertSplitterWidth(AValue: Integer);
|
|
procedure SetViewPosition(AValue: TcxSchedulerViewPosition);
|
|
procedure SetWorkDays(AValue: TDays);
|
|
procedure SetWorkFinish(AValue: TTime);
|
|
procedure SetWorkStart(AValue: TTime);
|
|
//
|
|
procedure ReadWorkFinish(AReader: TReader);
|
|
procedure ReadWorkStart(AReader: TReader);
|
|
procedure WriteWorkFinish(AWriter: TWriter);
|
|
procedure WriteWorkStart(AWriter: TWriter);
|
|
protected
|
|
procedure CalculateActualStartOfWeek;
|
|
procedure Changed; virtual;
|
|
procedure DefineProperties(Filer: TFiler); override;
|
|
function GetOwner: TPersistent; override;
|
|
function IsWorkDaysStored: Boolean;
|
|
function IsWorkTime(AResourceItem: TcxSchedulerStorageResourceItem; const ADateTime: TDateTime): Boolean;
|
|
|
|
property DateTimeHelper: TcxSchedulerDateTimeHelperClass read GetDateTimeHelperClass;
|
|
property HotTrack: Boolean read FHotTrack write FHotTrack default False;//True;
|
|
public
|
|
constructor Create(AOwner: TcxCustomScheduler); virtual;
|
|
destructor Destroy; override;
|
|
procedure Assign(Source: TPersistent); override;
|
|
|
|
property ActualStartOfWeek: TDay read FActualStartOfWeek;
|
|
property Scheduler: TcxCustomScheduler read FScheduler;
|
|
published
|
|
property AdditionalTimeZone: Integer index 0 read GetTimeZone write SetTimeZone default -1;
|
|
property AdditionalTimeZoneDaylightSaving: Boolean read FAdditionalTimeZoneDaylightSaving write SetATZDaylightSaving default False;
|
|
property AdditionalTimeZoneLabel: string index 0 read GetTimeZoneLabel write SetTimeZoneLabel stored IsTimeZoneLabelStored;
|
|
property CurrentTimeZone: Integer index 1 read GetTimeZone write SetTimeZone default -1;
|
|
property CurrentTimeZoneDaylightSaving: Boolean read FCurrentTimeZoneDaylightSaving write SetCTZDaylightSaving default False;
|
|
property CurrentTimeZoneLabel: string index 1 read GetTimeZoneLabel write SetTimeZoneLabel stored IsTimeZoneLabelStored;
|
|
property DayBorderColor: TColor read FDayBorderColor write SetDayBorderColor default clDefault;
|
|
property EventBorderColor: TColor read FEventBorderColor write SetEventBorderColor default clBlack;
|
|
property EventHeight: Integer read FEventHeight write SetEventHeight default 0;
|
|
property GroupingKind: TcxSchedulerGroupingKind read FGroupingKind write SetGroupingKind default gkDefault;
|
|
property GroupSeparatorWidth: Integer read FGroupSeparatorWidth write SetGroupSeparatorWidth default cxDefaultGroupSeparatorWidth;
|
|
property HideSelection: Boolean read FHideSelection write SetHideSelection default False;
|
|
property HorzSplitterWidth: Integer read FHorzSplitterWidth write SetHorzSplitterWidth default cxDefaultSplitterWidth;
|
|
property ResourceHeaders: TcxSchedulerResourceHeaders read FResourceHeaders write SetResourceHeaders;
|
|
property ResourcesPerPage: Integer read FResourcesPerPage write SetResourcesPerPage default cxDefaultResourcesPerPage;
|
|
property RotateResourceCaptions: Boolean read GetRotateResourceCaptions write SetRotateResourceCaptions default True;
|
|
property ShowAdditionalTimeZone: Boolean read FShowAdditionalTimeZone write SetShowAdditionalTimeZone default False;
|
|
property ShowEventsWithoutResource: Boolean read FShowEventsWithoutResource write SetShowEventsWithoutResource default False;
|
|
property ShowHints: Boolean read FShowHints write FShowHints default True;
|
|
property ShowNavigationButtons: Boolean read FShowNavigationButtons write SetShowNavigationButtons default True;
|
|
property StartOfWeek: TcxStartOfWeek read FStartOfWeek write SetStartOfWeek default swSystem;
|
|
property VertSplitterWidth: Integer read FVertSplitterWidth write SetVertSplitterWidth default cxDefaultSplitterWidth;
|
|
property ViewPosition: TcxSchedulerViewPosition read FViewPosition write SetViewPosition default vpLeft;
|
|
property WorkDays: TDays read FWorkDays write SetWorkDays stored IsWorkDaysStored;
|
|
property WorkFinish: TTime read FWorkFinish write SetWorkFinish stored False;
|
|
property WorkStart: TTime read FWorkStart write SetWorkStart stored False;
|
|
end;
|
|
|
|
{ TcxSchedulerViewHitTest }
|
|
|
|
TcxEventDragKind = (edkNone, edkEventDragRect, edkMoveEvent, edkResizeStart, edkResizeEnd);
|
|
|
|
TcxSchedulerViewHitTest = class(TcxSchedulerSubControlHitTest)
|
|
private
|
|
function GetHitAtEvent: Boolean;
|
|
function GetNeedShowHint: Boolean;
|
|
protected
|
|
FNeedShowHint: Boolean;
|
|
FEventBounds: TRect;
|
|
FResource: TcxSchedulerStorageResourceItem;
|
|
procedure Clear; override;
|
|
function GetHitEvent: TcxSchedulerControlEvent; virtual;
|
|
property NeedShowHint: Boolean read GetNeedShowHint;
|
|
public
|
|
function GetDragKind: TcxEventDragKind; virtual;
|
|
|
|
property HitAtEvent: Boolean read GetHitAtEvent;
|
|
property HitAtResource: Boolean index htcResource read GetBitState;
|
|
property Event: TcxSchedulerControlEvent read GetHitEvent;
|
|
property Resource: TcxSchedulerStorageResourceItem read FResource;
|
|
end;
|
|
|
|
{ TcxSchedulerEditController }
|
|
|
|
TcxSchedulerEditController = class
|
|
private
|
|
FEdit: TcxCustomEdit;
|
|
FEditData: TcxCustomEditData;
|
|
FEditDate: TDateTime;
|
|
FEditList: TcxInplaceEditList;
|
|
FEditProperties: TcxCustomEditProperties;
|
|
FEditResource: TcxSchedulerStorageResourceItem;
|
|
FEvent: TcxSchedulerControlEvent;
|
|
FFocused: Boolean;
|
|
FIsEditing: Boolean;
|
|
FIsNewEvent: Boolean;
|
|
FOwner: TcxCustomScheduler;
|
|
function CanAccept: Boolean;
|
|
function GetController: TcxSchedulerViewController;
|
|
function GetEditVisible: Boolean;
|
|
function GetView: TcxSchedulerCustomView;
|
|
procedure SetEditVisible(Value: Boolean);
|
|
protected
|
|
function GetEditRect(var R: TRect; const ADate: TDateTime;
|
|
AResource: TcxSchedulerStorageResourceItem; AMakeVisible: Boolean = False): Boolean; virtual;
|
|
procedure EditAfterKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); virtual;
|
|
procedure EditExit(Sender: TObject); virtual;
|
|
procedure EditKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); virtual;
|
|
procedure EditKeyPress(Sender: TObject; var Key: Char); virtual;
|
|
procedure EditKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState); virtual;
|
|
procedure EditPostEditValue(Sender: TObject); virtual;
|
|
function InitEdit(AEvent: TcxSchedulerControlEvent): Boolean; virtual;
|
|
function IsKeyForControl(var AKey: Word; Shift: TShiftState): Boolean; virtual;
|
|
procedure PrepareEdit(AEdit: TcxCustomEdit); virtual;
|
|
|
|
property EditProperties: TcxCustomEditProperties read FEditProperties;
|
|
property EditData: TcxCustomEditData read FEditData;
|
|
property Event: TcxSchedulerControlEvent read FEvent;
|
|
public
|
|
constructor Create(AOwner: TcxCustomScheduler); virtual;
|
|
destructor Destroy; override;
|
|
procedure Activate(AEvent: TcxSchedulerControlEvent); overload;
|
|
procedure Activate(AEvent: TcxSchedulerControlEvent; const APos: TPoint; AShift: TShiftState); overload;
|
|
procedure Activate(AEvent: TcxSchedulerControlEvent; Key: Char); overload;
|
|
procedure CloseEdit(Accepted: Boolean); virtual;
|
|
procedure DeleteEvent(AEvent: TcxSchedulerControlEvent);
|
|
procedure Init(const AEditDate: TDateTime;
|
|
AResource: TcxSchedulerStorageResourceItem; AIsNewEvent: Boolean = False);
|
|
procedure UpdateEdit; virtual;
|
|
procedure UpdateValue; virtual;
|
|
|
|
property Controller: TcxSchedulerViewController read GetController;
|
|
property Edit: TcxCustomEdit read FEdit;
|
|
property EditVisible: Boolean read GetEditVisible write SetEditVisible;
|
|
property Focused: Boolean read FFocused write FFocused;
|
|
property IsEditing: Boolean read FIsEditing;
|
|
property Scheduler: TcxCustomScheduler read FOwner;
|
|
property View: TcxSchedulerCustomView read GetView;
|
|
end;
|
|
|
|
{ TcxSchedulerViewNavigation }
|
|
|
|
TcxSchedulerViewNavigation = class
|
|
private
|
|
FView: TcxSchedulerCustomView;
|
|
function GetResourceNavigator: TcxSchedulerResourceNavigator;
|
|
function GetScheduler: TcxCustomScheduler;
|
|
function GetSelAnchor: TDateTime;
|
|
function GetSelRealStart: TDateTime;
|
|
function GetSelFinish: TDateTime;
|
|
function GetSelResource: TcxSchedulerStorageResourceItem;
|
|
function GetSelStart: TDateTime;
|
|
function GetTimeIncrement: TDateTime;
|
|
function GetVisibleResource(AIndex: Integer): TcxSchedulerStorageResourceItem;
|
|
function GetVisibleResourceCount: Integer;
|
|
protected
|
|
FCurrentAnchor: TDateTime;
|
|
FCurrentResource: TcxSchedulerStorageResourceItem;
|
|
FShift: TShiftState;
|
|
procedure DoKeyDown(var AKey: Word; AShift: TShiftState); virtual;
|
|
function IsKeyNavigation(var AKey: Word; AShift: TShiftState): Boolean; virtual;
|
|
function IsSingleLine: Boolean;
|
|
function GetResourceItem: TcxSchedulerStorageResourceItem; virtual;
|
|
procedure KeyDown(var AKey: Word; AShift: TShiftState); virtual;
|
|
procedure ReplaceDate(ADate: TDateTime; AResource: TcxSchedulerStorageResourceItem = nil);
|
|
public
|
|
constructor Create(AView: TcxSchedulerCustomView);
|
|
procedure CheckSelection;
|
|
procedure ReplaceSelParams(const ASelStart, ASelFinish: TDateTime); overload;
|
|
procedure ReplaceSelParams(const ASelStart, ASelFinish: TDateTime;
|
|
AResource: TcxSchedulerStorageResourceItem); overload;
|
|
procedure ReplaceSelParams(AResource: TcxSchedulerStorageResourceItem); overload;
|
|
function ScrollResources(AGoForward: Boolean): Boolean;
|
|
function ScrollResourcesCycled(AGoForward: Boolean; var AResource: TcxSchedulerStorageResourceItem): Boolean;
|
|
function ScrollResourcesEx(AGoForward: Boolean; var AResource: TcxSchedulerStorageResourceItem): Boolean; virtual;
|
|
procedure SetSelAnchor(const Anchor: TDateTime; AShift: TShiftState); overload;
|
|
procedure SetSelAnchor(const Anchor: TDateTime; AShift: TShiftState;
|
|
AResource: TcxSchedulerStorageResourceItem); overload;
|
|
procedure ValidateSelection(var ASelStart, ASelFinish: TDateTime;
|
|
var AResource: TcxSchedulerStorageResourceItem); virtual;
|
|
|
|
property ResourceNavigator: TcxSchedulerResourceNavigator read GetResourceNavigator;
|
|
property SelAnchor: TDateTime read GetSelAnchor;
|
|
property SelFinish: TDateTime read GetSelFinish;
|
|
property SelRealStart: TDateTime read GetSelRealStart;
|
|
property SelResource: TcxSchedulerStorageResourceItem read GetSelResource;
|
|
property SelStart: TDateTime read GetSelStart;
|
|
property Scheduler: TcxCustomScheduler read GetScheduler;
|
|
property TimeIncrement: TDateTime read GetTimeIncrement;
|
|
property View: TcxSchedulerCustomView read FView;
|
|
property VisibleResourceCount: Integer read GetVisibleResourceCount;
|
|
property VisibleResources[AIndex: Integer]: TcxSchedulerStorageResourceItem read GetVisibleResource;
|
|
end;
|
|
|
|
{ TcxSchedulerViewController }
|
|
|
|
TcxSchedulerViewController = class(TcxSchedulerSubControlController)
|
|
private
|
|
FEditShowingTimer: TTimer;
|
|
FEditShowingTimerItem: TcxSchedulerControlEvent;
|
|
FDragEventHelper: TcxDragEventHelper;
|
|
FDragEvent: TcxSchedulerControlEvent;
|
|
FDragKind: TcxEventDragKind;
|
|
FNavigation: TcxSchedulerViewNavigation;
|
|
FStartDragFlags: Int64;
|
|
FStartDragHitTime: TDateTime;
|
|
FStartDragResource: TcxSchedulerStorageResourceItem;
|
|
procedure EditShowingTimerHandler(Sender: TObject);
|
|
function GetEditController: TcxSchedulerEditController;
|
|
function GetHitTest: TcxSchedulerViewHitTest;
|
|
function GetIsEditing: Boolean;
|
|
function GetNavigatorTimer: TTimer;
|
|
function GetScheduler: TcxCustomScheduler;
|
|
function GetView: TcxSchedulerCustomView;
|
|
procedure ShowEventEditor(AEvent: TcxSchedulerControlEvent);
|
|
procedure StartEditShowingTimer(AEvent: TcxSchedulerControlEvent);
|
|
procedure StopEditShowingTimer;
|
|
protected
|
|
DragAndDropObject: TcxSchedulerDragAndDropObject;
|
|
FDownScrollArea: TRect;
|
|
FBeforeFocusedEvent: TcxSchedulerControlEvent;
|
|
FStartSelAnchor: TDateTime;
|
|
FUpScrollArea: TRect;
|
|
procedure BeforeMouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
|
|
procedure CancelScroll; virtual;
|
|
function CanDrag(X, Y: Integer): Boolean; override;
|
|
procedure CheckOpenInplaceEditorOnMouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); virtual;
|
|
procedure CheckScrolling(const APos: TPoint); virtual;
|
|
procedure CheckScrollOnDragOver(const P: TPoint; State: TDragState);
|
|
procedure CheckUpdateEventBounds;
|
|
procedure CloseInplaceEdit;
|
|
function ConsiderHiddenEvents: Boolean; virtual;
|
|
function CreateDragEventHelper: TcxDragEventHelper; virtual;
|
|
function CreateNavigation: TcxSchedulerViewNavigation; virtual;
|
|
function CreateResizeEventHelper: TcxEventSizingHelper; virtual;
|
|
procedure DoSchedulerDragOver(const P: TPoint; AState: TDragState;
|
|
var AAccept: Boolean);
|
|
procedure DragOver(Source: TObject; X, Y: Integer; State: TDragState;
|
|
var Accept: Boolean); override;
|
|
procedure EndDrag(Target: TObject; X, Y: Integer); override;
|
|
function GetDragAndDropObjectClass: TcxDragAndDropObjectClass; override;
|
|
function GetResourceReadOnly: Boolean;
|
|
function IsCaptionAvailable: Boolean;
|
|
function IsCopyDragDrop: Boolean;
|
|
function IsDragOperation: Boolean;
|
|
procedure KeyDown(var Key: Word; Shift: TShiftState); override;
|
|
procedure KeyPress(var Key: Char); override;
|
|
procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
|
|
procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
|
|
procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
|
|
procedure RecreateNavigation;
|
|
procedure SelectNextEvent(AForward: Boolean); virtual;
|
|
procedure StartDrag(var DragObject: TDragObject); override;
|
|
function StartDragAndDrop(const P: TPoint): Boolean; override;
|
|
procedure SyncEventSelection(AEvent: TcxSchedulerControlEvent); virtual;
|
|
procedure UnselectEvents;
|
|
procedure UpdateEventSelection(AEvent: TcxSchedulerControlEvent;
|
|
Button: TMouseButton; Shift: TShiftState);
|
|
|
|
// resource scrolling on event drag
|
|
procedure CheckNavigatorScrollArea(const APoint: TPoint); virtual;
|
|
procedure DoneNavigatorScrollArea; virtual;
|
|
procedure InitNavigatorScrollArea; virtual;
|
|
procedure NavigatorTimerHandler(Sender: TObject); virtual;
|
|
function PtInArea(const ARect: TRect; const P: TPoint; IsUpArea: Boolean): Boolean;
|
|
|
|
property EditController: TcxSchedulerEditController read GetEditController;
|
|
property DragEventHelper: TcxDragEventHelper read FDragEventHelper;
|
|
property HitTest: TcxSchedulerViewHitTest read GetHitTest;
|
|
property NavigatorTimer: TTimer read GetNavigatorTimer;
|
|
property View: TcxSchedulerCustomView read GetView;
|
|
public
|
|
constructor Create(AOwner: TcxSchedulerSubControl); override;
|
|
destructor Destroy; override;
|
|
function CanCreateEventUsingDialog: Boolean; virtual;
|
|
function CanCreateEventUsingInplaceEdit: Boolean; virtual;
|
|
function CanEditEvent(AEvent: TcxSchedulerControlEvent; AInplace: Boolean): Boolean; virtual;
|
|
function CanShowEventDialog: Boolean; virtual;
|
|
procedure DeleteSelectedEvents;
|
|
function IsEventEditing(AEvent: TcxSchedulerControlEvent; AResource: TcxSchedulerStorageResourceItem): Boolean;
|
|
procedure SelectSingleEvent(AEvent: TcxSchedulerControlEvent; ADate: TDateTime; AMakeVisible: Boolean = True);
|
|
|
|
property DragEvent: TcxSchedulerControlEvent read FDragEvent;
|
|
property DragKind: TcxEventDragKind read FDragKind;
|
|
property IsEditing: Boolean read GetIsEditing;
|
|
property Navigation: TcxSchedulerViewNavigation read FNavigation;
|
|
property Scheduler: TcxCustomScheduler read GetScheduler;
|
|
property StartDragFlags: Int64 read FStartDragFlags;
|
|
property StartDragHitTime: TDateTime read FStartDragHitTime;
|
|
property StartDragResource: TcxSchedulerStorageResourceItem read FStartDragResource;
|
|
end;
|
|
|
|
{ TcxDragHelper }
|
|
|
|
TcxSchedulerDragOverDestination = (dodView, dodControlBox, dodDateNavigator, dodOther);
|
|
|
|
TcxDragHelper = class
|
|
private
|
|
FActualHitTime: TDateTime;
|
|
FAcceptedChanged: Boolean;
|
|
FDestination: TcxSchedulerDragOverDestination;
|
|
FSaveCursor: TCursor;
|
|
FScheduler: TcxCustomScheduler;
|
|
function GetActualHitTime: TDateTime;
|
|
function GetController: TcxSchedulerViewController;
|
|
function GetDateNavigator: TcxSchedulerCustomDateNavigator;
|
|
function GetEvents: TcxSchedulerCachedEventList;
|
|
function GetHitTest: TcxSchedulerViewHitTest;
|
|
protected
|
|
FHasConflicts: Boolean;
|
|
FPrevAccepted: Boolean;
|
|
FPrevHitFlags: Int64;
|
|
FPrevHitTime: TDateTime;
|
|
FPrevHitResource: TcxSchedulerStorageResourceItem;
|
|
FStartHitTime: TDateTime;
|
|
FStartHitFlags: Int64;
|
|
FStartResource: TcxSchedulerStorageResourceItem;
|
|
// virtuals
|
|
procedure BeginDrag; virtual;
|
|
procedure CalculateConflicts;
|
|
procedure CalculateDestination;
|
|
function CanUpdateEventState(AEvent: TcxSchedulerControlEvent): Boolean;
|
|
procedure CheckAccepted(var Accepted: Boolean); virtual;
|
|
procedure CheckEventState(AEvent: TcxSchedulerControlEvent);
|
|
procedure DragOver(const P: TPoint; State: TDragState; var Accepted: Boolean); virtual;
|
|
procedure EndDrag(Accepted: Boolean); virtual;
|
|
function GetOriginHitTestMask: Int64; virtual;
|
|
procedure GetOriginState; virtual;
|
|
function HasChangedState: Boolean; virtual;
|
|
function IsAtOrigin: Boolean; virtual;
|
|
function IsShowResources: Boolean;
|
|
function IsValidTime: Boolean; virtual;
|
|
procedure RefreshCurrentView; virtual;
|
|
procedure SetSelection; virtual;
|
|
procedure UpdateHelperState(Accepted: Boolean); virtual;
|
|
|
|
property SaveCursor: TCursor read FSaveCursor;
|
|
public
|
|
constructor Create(AScheduler: TcxCustomScheduler); virtual;
|
|
|
|
property ActualHitTime: TDateTime read FActualHitTime;
|
|
property Controller: TcxSchedulerViewController read GetController;
|
|
property DateNavigator: TcxSchedulerCustomDateNavigator read GetDateNavigator;
|
|
property Destination: TcxSchedulerDragOverDestination read FDestination;
|
|
property Events: TcxSchedulerCachedEventList read GetEvents;
|
|
property HasConflicts: Boolean read FHasConflicts;
|
|
property HitTest: TcxSchedulerViewHitTest read GetHitTest;
|
|
property Scheduler: TcxCustomScheduler read FScheduler;
|
|
end;
|
|
|
|
{ TcxDragEventHelper }
|
|
|
|
TcxSchedulerDragObject = class(TcxDragControlObject)
|
|
private
|
|
FUseInternalCursors: Boolean;
|
|
function GetDragEventHelper: TcxDragEventHelper;
|
|
function GetDragEvents: TcxSchedulerFilteredEventList;
|
|
function GetHasConflicts: Boolean;
|
|
function GetScheduler: TcxCustomScheduler;
|
|
protected
|
|
procedure Finished(Target: TObject; X, Y: Integer; Accepted: Boolean); override;
|
|
function GetDragCursor(Accepted: Boolean; X, Y: Integer): TCursor; override;
|
|
public
|
|
constructor Create(AControl: TControl); override;
|
|
procedure CalculateConflictsForDateNavigator(ADateNavigator: TcxSchedulerCustomDateNavigator);
|
|
procedure DropToDateNavigator(ADateNavigator: TcxSchedulerCustomDateNavigator);
|
|
|
|
property DragEventHelper: TcxDragEventHelper read GetDragEventHelper;
|
|
property DragEvents: TcxSchedulerFilteredEventList read GetDragEvents;
|
|
property HasConflicts: Boolean read GetHasConflicts;
|
|
property Scheduler: TcxCustomScheduler read GetScheduler;
|
|
end;
|
|
|
|
TcxDragEventHelper = class(TcxDragHelper)
|
|
private
|
|
FDragObject: TDragObject;
|
|
function GetClones: TcxSchedulerFilteredEventList;
|
|
function GetViewInfo: TcxSchedulerCustomViewViewInfo;
|
|
protected
|
|
FPrevIsDragCopy: Boolean;
|
|
FTarget: TObject;
|
|
procedure ApplyChanges; virtual;
|
|
procedure BeginDrag; override;
|
|
procedure CheckAccepted(var Accepted: Boolean); override;
|
|
procedure CheckVisibility(Accepted: Boolean);
|
|
procedure DragOver(const P: TPoint; State: TDragState; var Accepted: Boolean); override;
|
|
procedure EndDrag(Accepted: Boolean); override;
|
|
procedure DateNavigatorEndDrag;
|
|
function GetClonesVisible(Accepted: Boolean): Boolean; virtual;
|
|
function GetIsDragCopy: Boolean; virtual;
|
|
procedure GetOriginState; override;
|
|
function GetSourcesVisible(Accepted: Boolean): Boolean; virtual;
|
|
function HasChangedState: Boolean; override;
|
|
function IsValidNavigatorDate: Boolean; virtual;
|
|
function IsValidTime: Boolean; override;
|
|
procedure PrepareClones;
|
|
procedure ProcessDateNavigator(ADateNavigator: TcxSchedulerCustomDateNavigator);
|
|
procedure SetSelection; override;
|
|
procedure Update(Accepted: Boolean = True);
|
|
procedure UpdateClones;
|
|
procedure UpdateHelperState(Accepted: Boolean); override;
|
|
//datenavigator processing
|
|
procedure UpdateDateNavigatorClones(ADateNavigator: TcxSchedulerCustomDateNavigator); virtual;
|
|
procedure UpdateDateNavigator(var Accepted: Boolean); virtual;
|
|
//current view processing
|
|
procedure UpdateViewClones; virtual;
|
|
procedure UpdateViewClonesResources;
|
|
procedure UpdateViewClonesTime; virtual;
|
|
|
|
property Clones: TcxSchedulerFilteredEventList read GetClones;
|
|
property DragObject: TDragObject read FDragObject;
|
|
property IsDragCopy: Boolean read GetIsDragCopy;
|
|
property ViewInfo: TcxSchedulerCustomViewViewInfo read GetViewInfo;
|
|
end;
|
|
|
|
{ TcxEventSizingHelper }
|
|
|
|
TcxEventSizingHelper = class(TcxDragHelper)
|
|
private
|
|
function GetEvent: TcxSchedulerControlEvent;
|
|
function GetHitTest: TcxSchedulerViewHitTest;
|
|
protected
|
|
procedure BeginDrag; override;
|
|
procedure DragOver(const P: TPoint; State: TDragState; var Accepted: Boolean); override;
|
|
procedure EndDrag(Accepted: Boolean); override;
|
|
function GetDragCursor(Accepted: Boolean): TCursor; virtual;
|
|
function IsValidTime: Boolean; override;
|
|
// Event handling
|
|
procedure CalcAllDayEvent; virtual;
|
|
function GetFinishTime: TDateTime; virtual;
|
|
function GetStartTime: TDateTime; virtual;
|
|
procedure UpdateEventBounds; virtual;
|
|
|
|
property Event: TcxSchedulerControlEvent read GetEvent;
|
|
property HitTest: TcxSchedulerViewHitTest read GetHitTest;
|
|
end;
|
|
|
|
{ TcxSchedulerDragAndDropObject }
|
|
|
|
TcxSchedulerDragAndDropObject = class(TcxDragAndDropObject)
|
|
private
|
|
FSizingHelper: TcxEventSizingHelper;
|
|
FScheduler: TcxCustomScheduler;
|
|
function GetController: TcxSchedulerViewController;
|
|
function GetHitTest: TcxSchedulerViewHitTest;
|
|
protected
|
|
procedure BeginDragAndDrop; override;
|
|
procedure DragAndDrop(const P: TPoint; var Accepted: Boolean); override;
|
|
procedure EndDragAndDrop(Accepted: Boolean); override;
|
|
function GetDragAndDropCursor(Accepted: Boolean): TCursor; override;
|
|
public
|
|
constructor Create(AControl: TcxControl); override;
|
|
destructor Destroy; override;
|
|
|
|
property Controller: TcxSchedulerViewController read GetController;
|
|
property SizingHelper: TcxEventSizingHelper read FSizingHelper;
|
|
property HitTest: TcxSchedulerViewHitTest read GetHitTest;
|
|
property Scheduler: TcxCustomScheduler read FScheduler;
|
|
end;
|
|
|
|
{ TcxSchedulerHintController }
|
|
|
|
TcxSchedulerHintController = class(TcxIUnknownObject, IUnknown,
|
|
IcxMouseTrackingCaller)
|
|
protected
|
|
FAutoHide: Boolean;
|
|
FHintWindow: THintWindow;
|
|
FOwner: TcxCustomScheduler;
|
|
FHintFlags: Integer;
|
|
FHintRect: TRect;
|
|
FHintText: string;
|
|
FLockHint: Boolean;
|
|
FShowing: Boolean;
|
|
FTimer: TTimer;
|
|
FViewMode: Boolean;
|
|
// IcxMouseTrackingCaller
|
|
procedure MouseLeave;
|
|
// methods
|
|
function CanShowHint: Boolean; virtual;
|
|
procedure CheckHintClass;
|
|
procedure HideHint; virtual;
|
|
procedure ShowHint; virtual;
|
|
procedure StartHideHintTimer;
|
|
procedure StartShowHintTimer;
|
|
procedure StopTimer;
|
|
procedure TimerHandler(Sender: TObject);
|
|
public
|
|
constructor Create(AOwner: TcxCustomScheduler); virtual;
|
|
destructor Destroy; override;
|
|
procedure Activate(const AHintRect: TRect;
|
|
const AHintText: string; AImmediateHint: Boolean = False;
|
|
AAutoHide: Boolean = True); virtual;
|
|
function CalcHintRect(AMaxWidth: Integer;
|
|
const AHintText: string; AFlags: Integer): TRect;
|
|
procedure Hide;
|
|
procedure Reset;
|
|
property Scheduler: TcxCustomScheduler read FOwner;
|
|
property ViewMode: Boolean read FViewMode write FViewMode;
|
|
property Showing: Boolean read FShowing;
|
|
end;
|
|
|
|
{ TcxSchedulerEventHitTestController }
|
|
|
|
TcxSchedulerEventHitTestController = class
|
|
private
|
|
function GetHintController: TcxSchedulerHintController;
|
|
function GetHitTest: TcxSchedulerViewHitTest;
|
|
protected
|
|
FOwner: TcxCustomScheduler;
|
|
FPrevHintEvent: TcxSchedulerControlEvent;
|
|
public
|
|
constructor Create(AOwner: TcxCustomScheduler); virtual;
|
|
procedure HideEventHint;
|
|
procedure MouseMove(X, Y: Integer; AShift: TShiftState); virtual;
|
|
|
|
property HitTest: TcxSchedulerViewHitTest read GetHitTest;
|
|
property HintController: TcxSchedulerHintController read GetHintController;
|
|
property Scheduler: TcxCustomScheduler read FOwner;
|
|
end;
|
|
|
|
{ TcxSchedulerCustomView }
|
|
|
|
TcxSchedulerCustomView = class(TcxSchedulerSubControl)
|
|
private
|
|
FCalculatedHintBounds: Boolean;
|
|
FCanShow: Boolean;
|
|
function GetActive: Boolean;
|
|
function GetCanShow: Boolean;
|
|
function GetController: TcxSchedulerViewController;
|
|
function GetDragCloneEventList: TcxSchedulerFilteredEventList;
|
|
function GetEventList: TcxSchedulerCachedEventList;
|
|
function GetHitTest: TcxSchedulerViewHitTest;
|
|
function GetOptionsView: TcxSchedulerOptionsView;
|
|
function GetResources: TcxSchedulerStorageResourceItems;
|
|
function GetSelectedDays: TcxSchedulerDateList;
|
|
function GetWorkDays: TDays;
|
|
function GetWorkFinish: TDateTime;
|
|
function GetWorkStart: TDateTime;
|
|
procedure SetActive(AValue: Boolean);
|
|
procedure SetCanShow(AValue: Boolean);
|
|
protected
|
|
function CanDeactivateOnDateNavigatorSelectionChange: Boolean; virtual;
|
|
function CanSelectPeriod: Boolean; virtual;
|
|
function CheckEventsVisibility: Boolean; virtual;
|
|
function CreateController: TcxSchedulerSubControlController; override;
|
|
function CreateHitTest: TcxSchedulerSubControlHitTest; override;
|
|
procedure DateChanged; virtual;
|
|
procedure DeactivateView; virtual;
|
|
procedure DoLayoutChanged; override;
|
|
function DoShowPopupMenu(X, Y: Integer): Boolean; virtual;
|
|
function EventContentSelected(AEvent: TcxSchedulerControlEvent): Boolean; virtual;
|
|
function GetClientRect: TRect; override;
|
|
function GetControlCanvas: TcxCanvas; virtual;
|
|
function GetDateOffset: Integer;
|
|
function GetDragObjectClass: TDragControlObjectClass; virtual;
|
|
function GetGroupingKind: TcxSchedulerGroupingKind; virtual;
|
|
function GetHScrollBarBounds: TRect; override;
|
|
function GetEditRectForEvent(AEvent: TcxSchedulerControlEvent;
|
|
const ADate: TDateTime; AResource: TcxSchedulerStorageResourceItem): TRect; virtual;
|
|
function GetEditStyle(AEvent: TcxSchedulerControlEvent): TcxCustomEditStyle; virtual;
|
|
function GetEditProperties(AEvent: TcxSchedulerControlEvent): TcxCustomEditProperties; virtual;
|
|
function GetEditWithSingleLineEditor(AEvent: TcxSchedulerControlEvent): Boolean; virtual;
|
|
function GetEventHintText(AEvent: TcxSchedulerControlEvent): string; virtual;
|
|
function GetEventVisibility(AEvent: TcxSchedulerControlEvent): Boolean; virtual;
|
|
function GetFirstVisibleDate: TDateTime; virtual;
|
|
function GetFirstVisibleTime: TDateTime; virtual;
|
|
function GetLastVisibleDate: TDateTime; virtual;
|
|
function GetLastVisibleTime: TDateTime; virtual;
|
|
function GetSchedulerLookAndFeel(ADialogs: Boolean = False): TcxLookAndFeel;
|
|
function GetScrollTimeHint: string; virtual;
|
|
function GetSizeGripBounds: TRect; override;
|
|
function GetTimeIncrement: TDateTime; virtual;
|
|
function GetVScrollBarBounds: TRect; override;
|
|
function GetViewContentRect: TRect; virtual;
|
|
function GetVisibleDaysRange: Integer; virtual;
|
|
procedure InitEventBySelectedTime(AEvent: TcxSchedulerEvent; AllDay: Boolean;
|
|
ARecurrence: Boolean; AInplaceEditing: Boolean); virtual;
|
|
function IsAllDaySelection: Boolean;
|
|
function IsDayView: Boolean; virtual;
|
|
function IsInplaceEditingEnabled: Boolean; virtual;
|
|
function IsShowResources: Boolean; virtual;
|
|
function IsWorkTime(AResourceItem: TcxSchedulerStorageResourceItem; const ADateTime: TDateTime): Boolean;
|
|
procedure MakeEventVisible(AEvent: TcxSchedulerControlEvent;
|
|
const ADate: TDateTime; AResource: TcxSchedulerStorageResourceItem); virtual;
|
|
procedure PeriodChanged; override;
|
|
procedure Scroll(AScrollBarKind: TScrollBarKind;
|
|
AScrollCode: TScrollCode; var AScrollPos: Integer); virtual;
|
|
procedure ScrollSelectedDays(AScrollDelta: Integer); overload; virtual;
|
|
procedure ScrollSelectedDays(AForward: Boolean;
|
|
ANeedDate: TDateTime; AIsByPage: Boolean); overload; virtual;
|
|
procedure ScrollVisibleDays(AScrollUp: Boolean); virtual;
|
|
procedure SelectedDaysChanged; virtual;
|
|
function ShowTaskComplete: Boolean; virtual;
|
|
procedure TimeChanged; virtual;
|
|
procedure UpdateDateNavigatorSelection;
|
|
procedure ValidateContentPopupMenuItems(var AItems: TcxSchedulerContentPopupMenuItems); virtual;
|
|
procedure ValidateSelectionFinishTime(var ADateTime: TDateTime); virtual;
|
|
procedure VisibleChanged; override;
|
|
// hint
|
|
procedure HideHintOnScroll(AScrollCode: TScrollCode); virtual;
|
|
procedure ShowHintOnScroll(const ADate: TDateTime); overload; virtual;
|
|
procedure ShowHintOnScroll(const AHintText: string; AScrollBarKind: TScrollBarKind); overload; virtual;
|
|
|
|
property CalculatedHintBounds: Boolean read FCalculatedHintBounds;
|
|
property Controller: TcxSchedulerViewController read GetController;
|
|
property EventList: TcxSchedulerCachedEventList read GetEventList;
|
|
property FirstVisibleTime: TDateTime read GetFirstVisibleTime;
|
|
property LastVisibleTime: TDateTime read GetLastVisibleTime;
|
|
property OptionsView: TcxSchedulerOptionsView read GetOptionsView;
|
|
property Resources: TcxSchedulerStorageResourceItems read GetResources;
|
|
property WorkDays: TDays read GetWorkDays;
|
|
property WorkStart: TDateTime read GetWorkStart;
|
|
property WorkFinish: TDateTime read GetWorkFinish;
|
|
public
|
|
constructor Create(AOwner: TcxCustomScheduler); override;
|
|
procedure Assign(Source: TPersistent); override;
|
|
|
|
property Active: Boolean read GetActive write SetActive default False;
|
|
property CanShow: Boolean read GetCanShow write SetCanShow default True;
|
|
property DragCloneEventList: TcxSchedulerFilteredEventList read GetDragCloneEventList;
|
|
property FirstVisibleDate: TDateTime read GetFirstVisibleDate;
|
|
property HitTest: TcxSchedulerViewHitTest read GetHitTest;
|
|
property LastVisibleDate: TDateTime read GetLastVisibleDate;
|
|
property SelectedDays: TcxSchedulerDateList read GetSelectedDays;
|
|
property StartOfWeek;
|
|
end;
|
|
|
|
{ TcxSchedulerCustomViewViewInfo }
|
|
|
|
TcxSchedulerCustomViewViewInfo = class(TcxSchedulerSubControlViewInfo)
|
|
private
|
|
function GetResourceNavigator: TcxSchedulerResourceNavigator;
|
|
function GetScheduler: TcxCustomScheduler;
|
|
protected
|
|
FEvents: TcxSchedulerCachedEventList;
|
|
FSelectedDays: TcxSchedulerDateList;
|
|
procedure CheckResourceNavigator; virtual;
|
|
function DoGetEventDisplayText(AEvent: TcxSchedulerControlEvent): string; virtual;
|
|
function DoSchedulerMoreEventsButtonClick: Boolean;
|
|
function DoSchedulerNavigationButtonClick(AnInterval: TDateTime;
|
|
AResource: TcxSchedulerStorageResourceItem): Boolean;
|
|
function GetEventHint(AEvent: TcxSchedulerControlEvent): string;
|
|
function GetResourceScrollBarKind: TScrollBarKind; virtual;
|
|
function GetSchedulerEventsList: TcxSchedulerCachedEventList;
|
|
procedure SetEventsVisibility(AShowSources, AShowClones: Boolean;
|
|
AForceRepaint: Boolean = False); virtual;
|
|
|
|
property Events: TcxSchedulerCachedEventList read FEvents;
|
|
property ResourceNavigator: TcxSchedulerResourceNavigator read GetResourceNavigator;
|
|
property Scheduler: TcxCustomScheduler read GetScheduler;
|
|
property SelectedDays: TcxSchedulerDateList read FSelectedDays;
|
|
end;
|
|
|
|
{ TcxSchedulerCustomDataNavigator }
|
|
|
|
IcxExternalDateNavigatorListener = interface
|
|
['{32293211-4D89-4383-A95C-23B95C3A783D}']
|
|
procedure StorageChanged;
|
|
procedure SchedulerChanged;
|
|
procedure SchedulerRemoved;
|
|
end;
|
|
|
|
TcxSchedulerCustomDateNavigator = class(TcxSchedulerSubControl)
|
|
private
|
|
FLockCount: Integer;
|
|
FPrevColCount: Integer;
|
|
FPrevRowCount: Integer;
|
|
FSaveRealFirstDate: TDateTime;
|
|
FSaveRealLastDate: TDateTime;
|
|
FSaveSelectionList: TcxSchedulerDateList;
|
|
function GetEventDays: TcxSchedulerDateList;
|
|
function GetHintController: TcxSchedulerHintController;
|
|
function GetHolidayDays: TcxSchedulerDateList;
|
|
protected
|
|
FSavedSize: TSize;
|
|
procedure BoundsChanging; override;
|
|
procedure BoundsChanged; override;
|
|
function CanMultiSelect: Boolean; virtual;
|
|
procedure CheckSizes; virtual; abstract;
|
|
procedure CheckChanges; virtual;
|
|
procedure CheckCurrentDate; virtual;
|
|
procedure ClearDragging; virtual; abstract;
|
|
procedure DoPeriodChangedEvent; virtual; abstract;
|
|
procedure DoSelectionChangedEvent; virtual; abstract;
|
|
procedure DoScrollSelection(AForward: Boolean; ANeedDate: TDateTime; AIsByPage: Boolean); overload; virtual; abstract;
|
|
procedure DoScrollSelection(AScrollDelta: Integer); overload; virtual; abstract;
|
|
procedure GetCalendarDimension(out AColCount, ARowCount: Integer); virtual; abstract;
|
|
function GetMonthSize: TSize; virtual;
|
|
function GetSelection: TcxSchedulerDateList; virtual;
|
|
function GetShowDatesContainingEventsInBold: Boolean; virtual; abstract;
|
|
function GetShowDatesContainingHolidaysInColor: Boolean; virtual; abstract;
|
|
function GetRealFirstDate: TDateTime; virtual; abstract;
|
|
function GetRealLastDate: TDateTime; virtual; abstract;
|
|
function IsSchedulerLocked: Boolean;
|
|
procedure Loaded; virtual;
|
|
procedure MakeSelectionVisible; virtual; abstract;
|
|
procedure PeriodChanged; override;
|
|
procedure RefreshDays; virtual; abstract;
|
|
procedure SaveSize;
|
|
procedure SaveState; virtual;
|
|
procedure ScrollSelection(AForward: Boolean; ANeedDate: TDateTime; AIsByPage: Boolean); overload;
|
|
procedure ScrollSelection(AScrollDelta: Integer); overload;
|
|
procedure SetIntegralSizes; virtual; abstract;
|
|
procedure UpdateDragging; virtual; abstract;
|
|
procedure UpdateSelection; virtual; abstract;
|
|
|
|
property EventDays: TcxSchedulerDateList read GetEventDays;
|
|
property HintController: TcxSchedulerHintController read GetHintController;
|
|
property HolidayDays: TcxSchedulerDateList read GetHolidayDays;
|
|
public
|
|
constructor Create(AOwner: TcxCustomScheduler); override;
|
|
destructor Destroy; override;
|
|
procedure BeginUpdate;
|
|
procedure CancelUpdates;
|
|
procedure EndUpdate;
|
|
end;
|
|
|
|
{ TcxSchedulerClipboardController }
|
|
|
|
TcxSchedulerClipboardController = class
|
|
private
|
|
FScheduler: TcxCustomScheduler;
|
|
FStream: TMemoryStream;
|
|
FStreamReader: TcxReader;
|
|
FStreamWriter: TcxWriter;
|
|
function GetStorage: TcxCustomSchedulerStorage;
|
|
procedure RegisterClipboardFormat;
|
|
protected
|
|
procedure CalculateAnchorForResource(AEvents: TcxSchedulerFilteredEventList;
|
|
const AResourceID: Variant; var Anchor: TDateTime);
|
|
procedure DeleteSelectedEvents; virtual;
|
|
function GetClipboard: TClipboard; virtual;
|
|
function GetClipboardToStream: Boolean;
|
|
function GetSelectionAsStream: Boolean;
|
|
function GetStreamAsEvents(AEvents: TcxSchedulerFilteredEventList; var Anchor: TDateTime): Boolean;
|
|
procedure InsertEvents(AEvents: TcxSchedulerFilteredEventList; Anchor: TDateTime);
|
|
function KeyDown(var AKey: Word; AShift: TShiftState): Boolean;
|
|
function KeyPress(var AKey: Char): Boolean;
|
|
procedure RestoreEvent(var AEvent: TcxSchedulerControlEvent);
|
|
procedure SaveEvent(AEvent: TcxSchedulerControlEvent);
|
|
procedure SetStreamToClipboard;
|
|
function ValidateStream: Boolean;
|
|
|
|
property Stream: TMemoryStream read FStream;
|
|
property StreamReader: TcxReader read FStreamReader;
|
|
property StreamWriter: TcxWriter read FStreamWriter;
|
|
public
|
|
constructor Create(AScheduler: TcxCustomScheduler); virtual;
|
|
destructor Destroy; override;
|
|
function CanCopy: Boolean; virtual;
|
|
function CanPaste: Boolean; virtual;
|
|
procedure Copy;
|
|
procedure Cut;
|
|
procedure Paste;
|
|
|
|
property Clipboard: TClipboard read GetClipboard;
|
|
property Scheduler: TcxCustomScheduler read FScheduler;
|
|
property Storage: TcxCustomSchedulerStorage read GetStorage;
|
|
end;
|
|
|
|
{ IcxSchedulerStylesAdapter }
|
|
|
|
IcxSchedulerStylesAdapter = interface
|
|
['{0BFEA90D-0CE8-4ED1-88E8-71A3396186F3}']
|
|
function GetContentParams(const ADateTime: TDateTime;
|
|
AResource: TcxSchedulerStorageResourceItem): TcxViewParams; overload;
|
|
function GetContentParams(const ADateTime: TDateTime; ALightColor: Boolean;
|
|
AResource: TcxSchedulerStorageResourceItem): TcxViewParams; overload;
|
|
function GetDayHeaderParams(const ADateTime: TDateTime): TcxViewParams;
|
|
function GetEventParams(AEvent: TcxSchedulerEvent): TcxViewParams;
|
|
function GetResourceHeaderParams(AResource: TcxSchedulerStorageResourceItem): TcxViewParams;
|
|
// hard style
|
|
function GetDayHeaderStyle: TcxStyle;
|
|
function GetResourceHeaderStyle: TcxStyle;
|
|
end;
|
|
|
|
{ TcxSchedulerStyles }
|
|
|
|
TcxSchedulerOnGetDayHeaderStyleEvent = procedure(Sender: TObject;
|
|
const ADate: TDateTime; var AStyle: TcxStyle) of object;
|
|
TcxSchedulerOnGetResourceHeaderStyleEvent = procedure(Sender: TObject;
|
|
AResource: TcxSchedulerStorageResourceItem; var AStyle: TcxStyle) of object;
|
|
TcxSchedulerOnGetContentStyleEvent = procedure(Sender: TObject;
|
|
AResource: TcxSchedulerStorageResourceItem; const ADateTime: TDateTime;
|
|
var AStyle: TcxStyle) of object;
|
|
TcxSchedulerOnGetEventStyleEvent = procedure(Sender: TObject;
|
|
AEvent: TcxSchedulerEvent; var AStyle: TcxStyle) of object;
|
|
|
|
TcxSchedulerStyles = class(TcxStyles, IcxSchedulerStylesAdapter)
|
|
private
|
|
FScheduler: TcxCustomScheduler;
|
|
FOnGetContentStyle: TcxSchedulerOnGetContentStyleEvent;
|
|
FOnGetDayHeaderStyle: TcxSchedulerOnGetDayHeaderStyleEvent;
|
|
FOnGetEventStyle: TcxSchedulerOnGetEventStyleEvent;
|
|
FOnGetResourceHeaderStyle: TcxSchedulerOnGetResourceHeaderStyleEvent;
|
|
function GetPainter: TcxCustomLookAndFeelPainterClass;
|
|
function GetPainterHelperClass: TcxSchedulerPainterHelperClass;
|
|
function GetResources: TcxSchedulerStorageResourceItems;
|
|
protected
|
|
procedure Changed(AIndex: Integer); override;
|
|
|
|
function EventContentSelected(AEvent: TcxSchedulerControlEvent): Boolean;
|
|
procedure GetDefaultViewParams(Index: Integer; AData: TObject; out AParams: TcxViewParams); override;
|
|
|
|
// IcxSchedulerStylesAdapter
|
|
function GetDayHeaderStyle: TcxStyle;
|
|
function GetEventParams(AEvent: TcxSchedulerEvent): TcxViewParams;
|
|
function GetResourceHeaderStyle: TcxStyle;
|
|
|
|
property Painter: TcxCustomLookAndFeelPainterClass read GetPainter;
|
|
property PainterHelper: TcxSchedulerPainterHelperClass read GetPainterHelperClass;
|
|
property Resources: TcxSchedulerStorageResourceItems read GetResources;
|
|
public
|
|
constructor Create(AOwner: TPersistent); override;
|
|
procedure Assign(Source: TPersistent); override;
|
|
function GetBackgroundParams: TcxViewParams;
|
|
function GetContentParams(const ADateTime: TDateTime; AResource: TcxSchedulerStorageResourceItem = nil): TcxViewParams; overload;
|
|
function GetContentParams(const ADateTime: TDateTime; ALightColor: Boolean; AResource: TcxSchedulerStorageResourceItem = nil): TcxViewParams; overload;
|
|
function GetDayHeaderParams(const ADate: TDateTime): TcxViewParams;
|
|
function GetGroupSeparatorParams: TcxViewParams;
|
|
function GetResourceHeaderParams(AResource: TcxSchedulerStorageResourceItem): TcxViewParams;
|
|
function GetSelectionParams: TcxViewParams;
|
|
function GetSplitterParams(AKind: TcxSchedulerSplitterKind): TcxViewParams;
|
|
function GetEventContentParams(AEvent: TcxSchedulerEvent): TcxViewParams;
|
|
function IsEventStyleAssigned(AEvent: TcxSchedulerEvent): Boolean;
|
|
// define colors functions
|
|
property Scheduler: TcxCustomScheduler read FScheduler;
|
|
published
|
|
property Background: TcxStyle index cxcsBackground read GetValue write SetValue;
|
|
property Content: TcxStyle index cxcsContent read GetValue write SetValue;
|
|
property Event: TcxStyle index cxcsEvent read GetValue write SetValue;
|
|
property GroupSeparator: TcxStyle index cxcsGroupSeparator read GetValue write SetValue;
|
|
property DayHeader: TcxStyle index cxcsDayHeader read GetValue write SetValue;
|
|
property HorzSplitter: TcxStyle index cxcsHSplitter read GetValue write SetValue;
|
|
property ResourceHeader: TcxStyle index cxcsResourceHeader read GetValue write SetValue;
|
|
property Selection: TcxStyle index cxcsSelection read GetValue write SetValue;
|
|
property VertSplitter: TcxStyle index cxcsVSplitter read GetValue write SetValue;
|
|
|
|
property OnGetContentStyle: TcxSchedulerOnGetContentStyleEvent read FOnGetContentStyle write FOnGetContentStyle;
|
|
property OnGetDayHeaderStyle: TcxSchedulerOnGetDayHeaderStyleEvent read FOnGetDayHeaderStyle write FOnGetDayHeaderStyle;
|
|
property OnGetEventStyle: TcxSchedulerOnGetEventStyleEvent read FOnGetEventStyle write FOnGetEventStyle;
|
|
property OnGetResourceHeaderStyle: TcxSchedulerOnGetResourceHeaderStyleEvent read FOnGetResourceHeaderStyle write FOnGetResourceHeaderStyle;
|
|
end;
|
|
|
|
{ TcxSchedulerOptionsBehavior }
|
|
|
|
TcxSchedulerOptionsBehavior = class(TPersistent)
|
|
private
|
|
FHotTrack: Boolean;
|
|
FOwner: TcxCustomScheduler;
|
|
FSelectOnRightClick: Boolean;
|
|
protected
|
|
function GetOwner: TPersistent; override;
|
|
public
|
|
constructor Create(AOwner: TcxCustomScheduler);
|
|
|
|
procedure Assign(Source: TPersistent); override;
|
|
published
|
|
property SelectOnRightClick: Boolean read FSelectOnRightClick
|
|
write FSelectOnRightClick default False;
|
|
property HotTrack: Boolean read FHotTrack write FHotTrack default True;
|
|
end;
|
|
|
|
{ TcxCustomScheduler }
|
|
|
|
TcxSchedulerCanShowViewEvent = procedure(Sender: TObject;
|
|
AView: TcxSchedulerCustomView; var Allow: Boolean) of object;
|
|
TcxSchedulerGetEventEditPropertiesEvent = procedure(Sender: TObject;
|
|
AEvent: TcxSchedulerControlEvent; var AProperties: TcxCustomEditProperties) of object;
|
|
TcxSchedulerGetEventText = procedure(Sender: TObject;
|
|
AEvent: TcxSchedulerControlEvent; var AText: string) of object;
|
|
TcxSchedulerInitEditEvent = procedure(Sender: TObject; AEdit: TcxCustomEdit) of object;
|
|
TcxSchedulerViewTypeChangedEvent = procedure(Sender: TObject;
|
|
APrevView, ANewView: TcxSchedulerCustomView) of object;
|
|
TcxSchedulerIsWorkTimeEvent = procedure(Sender: TObject; AResource: TcxSchedulerStorageResourceItem;
|
|
const ATime: TDateTime; var AIsWork: Boolean) of object;
|
|
TcxSchedulerBeforeDeleting = procedure (Sender: TcxCustomScheduler;
|
|
AEvent: TcxSchedulerControlEvent; var Allow: Boolean) of object;
|
|
TcxSchedulerBeforeDragEvent = procedure (Sender: TcxCustomScheduler;
|
|
AEvent: TcxSchedulerControlEvent; X, Y: Integer; var Allow: Boolean) of object;
|
|
TcxSchedulerBeforeEditing = procedure (Sender: TcxCustomScheduler;
|
|
AEvent: TcxSchedulerControlEvent; AInplace: Boolean; var Allow: Boolean) of object;
|
|
TcxSchedulerAfterDragEvent = procedure (Sender: TcxCustomScheduler;
|
|
Target: TObject; X, Y: Integer; var Accept: Boolean) of object;
|
|
TcxSchedulerBeforeSizingEvent = procedure (Sender: TcxCustomScheduler;
|
|
AEvent: TcxSchedulerControlEvent; X, Y: Integer; var Allow: Boolean) of object;
|
|
TcxSchedulerAfterSizingEvent = procedure (Sender: TcxCustomScheduler;
|
|
AEvent: TcxSchedulerControlEvent; X, Y: Integer; var Accept: Boolean) of object;
|
|
TcxSchedulerAfterEditing = procedure (Sender: TcxCustomScheduler;
|
|
AEvent: TcxSchedulerControlEvent) of object;
|
|
TcxSchedulerMoreEventsButtonClickEvent = procedure (Sender: TcxCustomScheduler;
|
|
var AHandled: Boolean) of object;
|
|
TcxSchedulerNavigationButtonClickEvent = procedure (Sender: TcxCustomScheduler;
|
|
AnInterval: TDateTime; AResource: TcxSchedulerStorageResourceItem;
|
|
var AHandled: Boolean) of object;
|
|
TcxSchedulerScaleScrollEvent = procedure (Sender: TcxCustomScheduler;
|
|
AStartDateTime, AFinishDateTime: TDateTime) of object;
|
|
TcxSchedulerEventSelectionChangedEvent = procedure (Sender: TcxCustomScheduler;
|
|
AEvent: TcxSchedulerControlEvent) of object;
|
|
TcxSchedulerShowDateHintEvent = procedure (Sender: TObject; const ADate: TDateTime;
|
|
var AHintText: string; var AAllow: Boolean) of object;
|
|
|
|
TcxCustomScheduler = class(TcxControl,
|
|
IcxSchedulerStorageListener,
|
|
IcxFormatControllerListener,
|
|
IcxFormatControllerListener2,
|
|
IcxStoredObject, IdxSkinSupport)
|
|
private
|
|
FActiveControl: TcxSchedulerSubControl;
|
|
FAligningSubControls: Boolean;
|
|
FBackground: TcxSchedulerSubControl;
|
|
{$IFNDEF DEBUGPAINT}
|
|
FBitmap: TBitmap;
|
|
FBitmapCanvas: TcxCanvas;
|
|
{$ENDIF}
|
|
FBoundsChanging: Boolean;
|
|
FCanModified: Boolean;
|
|
FCanvas: TcxCanvas;
|
|
FCaptureControl: TcxSchedulerSubControl;
|
|
FClipboardController: TcxSchedulerClipboardController;
|
|
FContentPopupMenu: TcxSchedulerContentPopupMenu;
|
|
FContentPopupMenuEvents: TNotifyEvent;
|
|
FControlBox: TcxSchedulerControlBox;
|
|
FControlFlags: TcxControlFlags;
|
|
FCurrentView: TcxSchedulerCustomView;
|
|
FDateNavigator: TcxSchedulerCustomDateNavigator;
|
|
FDefaultProperties: TcxCustomEditProperties;
|
|
FDialogsLookAndFeel: TcxLookAndFeel;
|
|
FEditController: TcxSchedulerEditController;
|
|
FEditStyle: TcxCustomEditStyle;
|
|
FEventDays: TcxSchedulerDateList;
|
|
FEventEditInfo: TcxSchedulerEventEditInfo;
|
|
FEventHitTestController: TcxSchedulerEventHitTestController;
|
|
FEventImages: TCustomImageList;
|
|
FEventList: TcxSchedulerCachedEventList;
|
|
FEventOperations: TcxSchedulerEventOperations;
|
|
FEventPopupMenu: TcxSchedulerEventPopupMenu;
|
|
FEventPopupMenuEvents: TNotifyEvent;
|
|
FFirstVisibleResourceIndex: Integer;
|
|
FHintController: TcxSchedulerHintController;
|
|
FHolidayDays: TcxSchedulerDateList;
|
|
FHorzSplitter: TcxSchedulerSplitter;
|
|
FHorzSplitterShowing: Boolean;
|
|
FIsDragCanceled: Boolean;
|
|
FKeyboardListener: TcxSchedulerSubControl;
|
|
FListeners: TInterfaceList;
|
|
FLockCount: Integer;
|
|
FLockRefresh: Integer;
|
|
FOnInitEdit: TcxSchedulerInitEditEvent;
|
|
FOptionsBehavior: TcxSchedulerOptionsBehavior;
|
|
FOptionsCustomize: TcxSchedulerOptionsCustomize;
|
|
FOptionsView: TcxSchedulerOptionsView;
|
|
FPrevBounds: TRect;
|
|
FPrevCopyDragDrop: Boolean;
|
|
FPrevMousePos: TPoint;
|
|
FResourceNavigator: TcxSchedulerResourceNavigator;
|
|
FResourceNavigatorEvents: TNotifyEvent;
|
|
FSelectedDays: TcxSchedulerDateList;
|
|
FSelFinish: TDateTime;
|
|
FSelResource: TcxSchedulerStorageResourceItem;
|
|
FSelStart: TDateTime;
|
|
FStorage: TcxCustomSchedulerStorage;
|
|
FStoringName: string;
|
|
FStyles: TcxSchedulerStyles;
|
|
FStylesEvents: TNotifyEvent;
|
|
FSubControls: TList;
|
|
FSubControlsCreated: Boolean;
|
|
FTabOrdersList: TcxSchedulerEventList;
|
|
FTextEditProperties: TcxTextEditProperties;
|
|
FVertSplitter: TcxSchedulerSplitter;
|
|
FVertSplitterShowing: Boolean;
|
|
FVisibleChangedCount: Integer;
|
|
FUpdateTimeTimer: TTimer;
|
|
FOnAfterDragEvent: TcxSchedulerAfterDragEvent;
|
|
FOnAfterEditing: TcxSchedulerAfterEditing;
|
|
FOnAfterSizingEvent: TcxSchedulerAfterSizingEvent;
|
|
FOnBeforeDeleting: TcxSchedulerBeforeDeleting;
|
|
FOnBeforeDragEvent: TcxSchedulerBeforeDragEvent;
|
|
FOnBeforeEditing: TcxSchedulerBeforeEditing;
|
|
FOnBeforeSizingEvent: TcxSchedulerBeforeSizingEvent;
|
|
FOnCanShowView: TcxSchedulerCanShowViewEvent;
|
|
FOnEventSelectionChanged: TcxSchedulerEventSelectionChangedEvent;
|
|
FOnFirstVisibleResourceChanged: TNotifyEvent;
|
|
FOnGetEventDisplayText: TcxSchedulerGetEventText;
|
|
FOnGetEventEditProperties: TcxSchedulerGetEventEditPropertiesEvent;
|
|
FOnGetEventHintText: TcxSchedulerGetEventText;
|
|
FOnIsWorkTime: TcxSchedulerIsWorkTimeEvent;
|
|
FOnLayoutChanged: TNotifyEvent;
|
|
FOnMoreEventsButtonClick: TcxSchedulerMoreEventsButtonClickEvent;
|
|
FOnNavigationButtonClick: TcxSchedulerNavigationButtonClickEvent;
|
|
FOnSelectionChanged: TNotifyEvent;
|
|
FOnScaleScroll: TcxSchedulerScaleScrollEvent;
|
|
FOnShowDateHint: TcxSchedulerShowDateHintEvent;
|
|
FOnViewTypeChanged: TcxSchedulerViewTypeChangedEvent;
|
|
procedure CreateUpdateTimeTimer;
|
|
function GetActiveHitTest: TcxSchedulerSubControlHitTest;
|
|
function GetCaptureControl: TcxSchedulerSubControl;
|
|
function GetCaptureController: TcxSchedulerSubControlController;
|
|
function GetSelectedEventCount: Integer;
|
|
function GetSelectedEvent(AIndex: Integer): TcxSchedulerControlEvent;
|
|
function GetSelFinish: TDateTime;
|
|
function GetSelStart: TDateTime;
|
|
function GetIsDynamicUpdate: Boolean;
|
|
function GetStartOfWeek: TDay;
|
|
function GetStorageActive: Boolean;
|
|
function GetStorageValid: Boolean;
|
|
function GetSubControl(AIndex: Integer): TcxSchedulerSubControl;
|
|
function GetSubControlCount: Integer;
|
|
function GetVisibleEventCount: Integer;
|
|
function GetVisibleEvent(AIndex: Integer): TcxSchedulerControlEvent;
|
|
procedure InitEventBySelection(AEvent: TcxSchedulerEvent;
|
|
AllDay: Boolean; ARecurrence: Boolean; AInplaceEditing: Boolean);
|
|
procedure SetCaptureControl(AValue: TcxSchedulerSubControl);
|
|
procedure SetContentPopupMenu(AValue: TcxSchedulerContentPopupMenu);
|
|
procedure SetControlBox(AValue: TcxSchedulerControlBox);
|
|
procedure SetDialogsLookAndFeel(AValue: TcxLookAndFeel);
|
|
procedure SetEventImages(AValue: TCustomImageList);
|
|
procedure SetEventOperations(AValue: TcxSchedulerEventOperations);
|
|
procedure SetEventPopupMenu(AValue: TcxSchedulerEventPopupMenu);
|
|
procedure SetFirstVisibleResourceIndex(AValue: Integer);
|
|
procedure SetOptionsBehavior(AValue: TcxSchedulerOptionsBehavior);
|
|
procedure SetOptionsCustomize(AValue: TcxSchedulerOptionsCustomize);
|
|
procedure SetOptionsView(AValue: TcxSchedulerOptionsView);
|
|
procedure SetResourceNavigator(AValue: TcxSchedulerResourceNavigator);
|
|
procedure SetStyles(AValue: TcxSchedulerStyles);
|
|
procedure SetStorage(AValue: TcxCustomSchedulerStorage);
|
|
procedure UpdateTimeHandler(Sender: TObject);
|
|
procedure WMCancelMode(var Message: TWMCancelMode); message WM_CANCELMODE;
|
|
procedure WMSetCursor(var Message: TWMSetCursor); message WM_SETCURSOR;
|
|
procedure WMTimeChange(var Message: TWMTimeChange); message WM_TIMECHANGE;
|
|
procedure ReadSelectionData(AReader: TReader);
|
|
procedure WriteSelectionData(AWriter: TWriter);
|
|
protected
|
|
FStoredClientBounds: TRect;
|
|
// IcxSchedulerStorageListener
|
|
procedure StorageChanged(Sender: TObject);
|
|
procedure StorageRemoved(Sender: TObject);
|
|
// IcxFormatControllerListener
|
|
procedure DoStartOfWeekChanged(AOldStartOfWeek, ANewStartOfWeek: TDay); virtual;
|
|
procedure FormatChanged; virtual;
|
|
// IcxFormatControllerListener2
|
|
procedure TimeChanged;
|
|
// IcxStoredObject
|
|
function GetObjectName: string; virtual;
|
|
function GetProperties(AProperties: TStrings): Boolean; virtual;
|
|
procedure GetPropertyValue(const AName: string; var AValue: Variant); virtual;
|
|
procedure SetPropertyValue(const AName: string; const AValue: Variant); virtual;
|
|
// from TControl
|
|
procedure AlignControls(AControl: TControl; var Rect: TRect); override;
|
|
procedure DefineProperties(Filer: TFiler); override;
|
|
{$IFNDEF DELPHI12}
|
|
procedure GetChildren(Proc: TGetChildProc; Root: TComponent); override;
|
|
{$ENDIF}
|
|
procedure Notification(AComponent: TComponent; Operation: TOperation); override;
|
|
// IcxExternalDateNavigatorListener
|
|
procedure AddListener(AListener: IcxExternalDateNavigatorListener);
|
|
procedure NotififySchedulerChanged;
|
|
procedure NotififySchedulerRemoved;
|
|
procedure NotififyStorageChanged;
|
|
procedure RemoveListener(AListener: IcxExternalDateNavigatorListener);
|
|
|
|
// methods
|
|
|
|
//layout
|
|
procedure AlignSubControls(Sender: TcxSchedulerSubControl = nil); virtual;
|
|
procedure BoundsChanged; override;
|
|
procedure CalcHorizontalSplitterBounds; virtual;
|
|
procedure CalcVerticalSplitterBounds; virtual;
|
|
procedure CalcLayout; virtual;
|
|
procedure CalcLayoutViewRight; virtual;
|
|
procedure CalcLayoutViewLeft; virtual;
|
|
procedure CalcLayoutViewTop; virtual;
|
|
procedure CalcLayoutViewBottom; virtual;
|
|
procedure CalcSplittersBounds;
|
|
procedure CheckHorzSplitterBounds;
|
|
procedure CheckSplittersVisibilityChanging; virtual;
|
|
procedure ClearAllCachedData; virtual;
|
|
function IsHorzSplitterVisible: Boolean; virtual;
|
|
function IsVertSplitterVisible: Boolean; virtual;
|
|
procedure UpdateControlsBoundsOnHorzSplitterShowing;
|
|
procedure UpdateControlsBoundsOnVertSplitterShowing;
|
|
|
|
function CanDeactivateOnSelectionChanged(AView: TcxSchedulerCustomView): Boolean; virtual;
|
|
function CanIntersect(AEvent: TcxSchedulerControlEvent): Boolean; virtual;
|
|
function CanModified: Boolean; virtual;
|
|
function CanSelectPeriod: Boolean; virtual;
|
|
function CanShowEventDialog: Boolean;
|
|
function CreateBackground: TcxSchedulerSubControl; virtual;
|
|
function CreateClipboardController: TcxSchedulerClipboardController; virtual;
|
|
function CreateContentPopupMenu: TcxSchedulerContentPopupMenu; virtual;
|
|
function CreateControlBox: TcxSchedulerControlBox; virtual;
|
|
function CreateDateNavigator: TcxSchedulerCustomDateNavigator; virtual;
|
|
function CreateDefaultView: TcxSchedulerCustomView; virtual;
|
|
function CreateDefaultEditProperties: TcxCustomEditProperties; virtual;
|
|
function CreateEditController: TcxSchedulerEditController; virtual;
|
|
function CreateEventHitTestController: TcxSchedulerEventHitTestController; virtual;
|
|
function CreateEventList: TcxSchedulerCachedEventList; virtual;
|
|
function CreateEventOperations: TcxSchedulerEventOperations; virtual;
|
|
function CreateEventPopupMenu: TcxSchedulerEventPopupMenu; virtual;
|
|
function CreateHintController: TcxSchedulerHintController; virtual;
|
|
function CreateOptionsCustomize: TcxSchedulerOptionsCustomize; virtual;
|
|
function CreateOptionsView: TcxSchedulerOptionsView; virtual;
|
|
function CreateResourceNavigator: TcxSchedulerResourceNavigator; virtual;
|
|
function CreateSplitter(AKind: TcxSchedulerSplitterKind): TcxSchedulerSplitter; virtual;
|
|
function CreateStyles: TcxSchedulerStyles; virtual;
|
|
procedure CreateSubClasses; virtual;
|
|
procedure DateNavigatorSelectionChanged; virtual;
|
|
procedure DblClick; override;
|
|
procedure DestroySubClasses; virtual;
|
|
procedure DoAfterDragEvent(Target: TObject; X, Y: Integer; var Accept: Boolean); virtual;
|
|
procedure DoAfterEditing(AEvent: TcxSchedulerControlEvent); virtual;
|
|
procedure DoAfterSizingEvent(AEvent: TcxSchedulerControlEvent; X, Y: Integer; var Accept: Boolean); virtual;
|
|
function DoBeforeDeleting(AEvent: TcxSchedulerControlEvent): Boolean; virtual;
|
|
function DoBeforeDragEvent(AEvent: TcxSchedulerControlEvent; X, Y: Integer): Boolean; virtual;
|
|
function DoBeforeEditing(AEvent: TcxSchedulerControlEvent; AInplace: Boolean): Boolean; virtual;
|
|
function DoBeforeSizingEvent(AEvent: TcxSchedulerControlEvent; X, Y: Integer): Boolean; virtual;
|
|
procedure DoCalculateLayout(AControl: TcxSchedulerSubControl); virtual;
|
|
procedure DoCancelMode; override;
|
|
procedure DoControllerReset(AControl: TcxSchedulerSubControl); virtual;
|
|
procedure DoCreateEventUsingInplaceEdit(AKey: Char = #0); virtual;
|
|
procedure DoEventSelectionChanged(AEvent: TcxSchedulerControlEvent);
|
|
procedure DoFirstVisibleResourceChanged; virtual;
|
|
procedure DoGetEventDisplayText(AEvent: TcxSchedulerControlEvent; var AText: string); virtual;
|
|
procedure DoGetEventEditProperties(AEvent: TcxSchedulerControlEvent; var AProperties: TcxCustomEditProperties); virtual;
|
|
procedure DoHitTestRecalculate(AControl: TcxSchedulerSubControl); virtual;
|
|
procedure DoInitEdit(AEdit: TcxCustomEdit); virtual;
|
|
function DoIsWorkTime(AResourceItem: TcxSchedulerStorageResourceItem; const ADateTime: TDateTime): Boolean;
|
|
procedure DoCanShowView(AView: TcxSchedulerCustomView; var Allow: Boolean); virtual;
|
|
procedure DoLayoutChanged; virtual;
|
|
procedure DoLayoutChangedEvent; virtual;
|
|
function DoMoreEventsButtonClick: Boolean; virtual;
|
|
function DoNavigationButtonClick(AnInterval: TDateTime; AResource: TcxSchedulerStorageResourceItem): Boolean; virtual;
|
|
procedure DoSelectionChanged; virtual;
|
|
procedure DoScaleScroll; virtual;
|
|
function DoShowDateHint(const ADate: TDateTime; var AHintText: string): Boolean; virtual;
|
|
function DoShowPopupMenu(AMenu: TComponent; X, Y: Integer): Boolean; override;
|
|
procedure DoViewTypeChanged(ANewView: TcxSchedulerCustomView); virtual;
|
|
procedure DoUpdateTime; virtual;
|
|
procedure DragCanceled; override;
|
|
procedure DrawSplitters; virtual;
|
|
procedure FirstVisibleResourceChanged; virtual;
|
|
procedure FontChanged; override;
|
|
procedure FocusChanged; override;
|
|
function GetClientBounds: TRect; override;
|
|
function GetControlCanvas: TcxCanvas;
|
|
function GetControlFromPoint(const APoint: TPoint): TcxSchedulerSubControl; virtual;
|
|
function GetCursor(X, Y: Integer): TCursor; override;
|
|
function GetDateTimeHelper: TcxSchedulerDateTimeHelperClass; virtual;
|
|
function GetDateNavigatorLoadedSize: TSize;
|
|
function GetDesignHitTest(X, Y: Integer; Shift: TShiftState): Boolean; override;
|
|
function GetEventEditInfo(AEvent: TcxSchedulerControlEvent;
|
|
ARecurrence: Boolean = False; AReadOnly: Boolean = False): TcxSchedulerEventEditInfo;
|
|
function GetEventHintText(AEvent: TcxSchedulerControlEvent): string; virtual;
|
|
function GetEventUserHintText(AEvent: TcxSchedulerControlEvent; var AText: string): Boolean; virtual;
|
|
function GetHScrollBarBounds: TRect; override;
|
|
function GetInternalCanvas: TcxCanvas; virtual;
|
|
function GetIsLocked: Boolean; virtual;
|
|
function GetNextView(AView: TcxSchedulerCustomView): TcxSchedulerCustomView; virtual;
|
|
function GetOnShowDateHint: TcxSchedulerShowDateHintEvent; virtual;
|
|
function GetPainterHelper: TcxSchedulerPainterHelperClass; virtual;
|
|
function GetSizeGripBounds: TRect; override;
|
|
function GetTimeBias(AStart: TDateTime): Double; virtual;
|
|
function GetVScrollBarBounds: TRect; override;
|
|
function HasConflict(AStartDrag: Boolean): Boolean;
|
|
function HasResources: Boolean;
|
|
procedure InitControl; override;
|
|
procedure InitScrollBarsParameters; override;
|
|
procedure InternalDeleteEvent(AEvent: TcxSchedulerControlEvent; AIgnoreRecurring: Boolean);
|
|
procedure InternalDeleteSelectedEvents(AForceDelete, ACheckReadOnly: Boolean);
|
|
procedure InternalPaint(const AClipRect: TRect);
|
|
function IsViewAtLeft: Boolean;
|
|
procedure KeyDown(var Key: Word; Shift: TShiftState); override;
|
|
procedure KeyPress(var Key: Char); override;
|
|
procedure KeyUp(var Key: Word; Shift: TShiftState); override;
|
|
procedure Loaded; override;
|
|
procedure LookAndFeelChanged(Sender: TcxLookAndFeel; AChangedValues: TcxLookAndFeelValues); override;
|
|
procedure LockUpdateChanged(ALocking: Boolean); virtual;
|
|
procedure Modified; override;
|
|
procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
|
|
procedure MouseLeave(AControl: TControl); override;
|
|
procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
|
|
procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
|
|
function NeedShowHint(AEvent: TcxSchedulerControlEvent; var AHintText: string;
|
|
AllowShow: Boolean): Boolean; virtual;
|
|
procedure Paint; override;
|
|
procedure PeriodChanged; virtual;
|
|
procedure RemoveSubControl(AControl: TcxSchedulerSubControl);
|
|
procedure ReplaceSelParams(ASelStart, ASelFinish: TDateTime;
|
|
AResource: TcxSchedulerStorageResourceItem); virtual;
|
|
procedure Scroll(AScrollBarKind: TScrollBarKind;
|
|
AScrollCode: TScrollCode; var AScrollPos: Integer); override;
|
|
procedure SelectedDaysChanged(AView: TcxSchedulerCustomView);
|
|
procedure SetCurrentView(AView: TcxSchedulerCustomView); virtual;
|
|
procedure SubControlAdd(AControl: TcxSchedulerSubControl);
|
|
procedure SubControlRemove(AControl: TcxSchedulerSubControl);
|
|
procedure SynchronizeVisibleDays; virtual;
|
|
procedure UpdateDateNavigatorDragging(Accept: Boolean);
|
|
procedure UpdateHolidayDays(ABegin, AEnd: TDate);
|
|
procedure UpdateEventsCache(ACheckDaysInterval: Boolean); virtual;
|
|
procedure ValidateSelection(ASelection: TcxSchedulerDateList); virtual;
|
|
procedure ValidateState;
|
|
procedure ViewVisibleChanged(AView: TcxSchedulerCustomView); virtual;
|
|
function VisibleGroupingKind: TcxSchedulerGroupingKind;
|
|
// drag'n'drop support
|
|
function CanDrag(X, Y: Integer): Boolean; override;
|
|
procedure DoEndDrag(Target: TObject; X, Y: Integer); override;
|
|
procedure DoStartDrag(var DragObject: TDragObject); override;
|
|
procedure DragAndDrop(const P: TPoint; var Accepted: Boolean); override;
|
|
procedure DragOver(Source: TObject; X, Y: Integer; State: TDragState; var Accept: Boolean); override;
|
|
procedure EndDragAndDrop(Accepted: Boolean); override;
|
|
function GetDragAndDropObjectClass: TcxDragAndDropObjectClass; override;
|
|
function GetDragObjectClass: TDragControlObjectClass; override;
|
|
function StartDragAndDrop(const P: TPoint): Boolean; override;
|
|
|
|
property Background: TcxSchedulerSubControl read FBackground;
|
|
{$IFNDEF DEBUGPAINT}
|
|
property Bitmap: TBitmap read FBitmap;
|
|
property BitmapCanvas: TcxCanvas read FBitmapCanvas;
|
|
{$ENDIF}
|
|
property AligningSubControls: Boolean read FAligningSubControls;
|
|
property BoundsChanging: Boolean read FBoundsChanging;
|
|
property Canvas: TcxCanvas read FCanvas;
|
|
property Capture: TcxSchedulerSubControl read GetCaptureControl write SetCaptureControl;
|
|
property CaptureController: TcxSchedulerSubControlController read GetCaptureController;
|
|
property ClipboardController: TcxSchedulerClipboardController read FClipboardController;
|
|
property ControlFlags: TcxControlFlags read FControlFlags write FControlFlags;
|
|
property DefaultProperties: TcxCustomEditProperties read FDefaultProperties;
|
|
property EditController: TcxSchedulerEditController read FEditController;
|
|
property EditStyle: TcxCustomEditStyle read FEditStyle; //remove to EditingController
|
|
property EventHitTestController: TcxSchedulerEventHitTestController read FEventHitTestController write FEventHitTestController;
|
|
property EventList: TcxSchedulerCachedEventList read FEventList;
|
|
property HintController: TcxSchedulerHintController read FHintController;
|
|
property HorzSplitter: TcxSchedulerSplitter read FHorzSplitter;
|
|
property IsDragCanceled: Boolean read FIsDragCanceled;
|
|
property IsDynamicUpdate: Boolean read GetIsDynamicUpdate;
|
|
property IsLocked: Boolean read GetIsLocked;
|
|
property KeyboardListener: TcxSchedulerSubControl read FKeyboardListener write FKeyboardListener;
|
|
property LockCount: Integer read FLockCount;
|
|
property PainterHelper: TcxSchedulerPainterHelperClass read GetPainterHelper;
|
|
property ParentFont default False;
|
|
property StartOfWeek: TDay read GetStartOfWeek;
|
|
property StorageActive: Boolean read GetStorageActive;
|
|
property StorageValid: Boolean read GetStorageValid;
|
|
property SubControlCount: Integer read GetSubControlCount;
|
|
property SubControlsCreated: Boolean read FSubControlsCreated;
|
|
property SubControls[Index: Integer]: TcxSchedulerSubControl read GetSubControl;
|
|
property TabOrdersList: TcxSchedulerEventList read FTabOrdersList;
|
|
property VertSplitter: TcxSchedulerSplitter read FVertSplitter;
|
|
property DragMode default dmAutomatic;
|
|
property BorderStyle default cxcbsDefault;
|
|
|
|
property OnAfterDragEvent: TcxSchedulerAfterDragEvent read FOnAfterDragEvent write FOnAfterDragEvent;
|
|
property OnAfterEditing: TcxSchedulerAfterEditing read FOnAfterEditing write FOnAfterEditing;
|
|
property OnAfterSizingEvent: TcxSchedulerAfterSizingEvent read FOnAfterSizingEvent write FOnAfterSizingEvent;
|
|
property OnBeforeDeleting: TcxSchedulerBeforeDeleting read FOnBeforeDeleting write FOnBeforeDeleting;
|
|
property OnBeforeDragEvent: TcxSchedulerBeforeDragEvent read FOnBeforeDragEvent write FOnBeforeDragEvent;
|
|
property OnBeforeEditing: TcxSchedulerBeforeEditing read FOnBeforeEditing write FOnBeforeEditing;
|
|
property OnBeforeSizingEvent: TcxSchedulerBeforeSizingEvent read FOnBeforeSizingEvent write FOnBeforeSizingEvent;
|
|
property OnCanShowView: TcxSchedulerCanShowViewEvent read FOnCanShowView write FOnCanShowView;
|
|
property OnEventSelectionChanged: TcxSchedulerEventSelectionChangedEvent read FOnEventSelectionChanged write FOnEventSelectionChanged;
|
|
property OnFirstVisibleResourceChanged: TNotifyEvent read FOnFirstVisibleResourceChanged write FOnFirstVisibleResourceChanged;
|
|
property OnGetEventDisplayText: TcxSchedulerGetEventText read FOnGetEventDisplayText write FOnGetEventDisplayText;
|
|
property OnGetEventHintText: TcxSchedulerGetEventText read FOnGetEventHintText write FOnGetEventHintText;
|
|
property OnGetEventEditProperties: TcxSchedulerGetEventEditPropertiesEvent read FOnGetEventEditProperties write FOnGetEventEditProperties;
|
|
property OnInitEdit: TcxSchedulerInitEditEvent read FOnInitEdit write FOnInitEdit;
|
|
property OnIsWorkTime: TcxSchedulerIsWorkTimeEvent read FOnIsWorkTime write FOnIsWorkTime;
|
|
property OnLayoutChanged: TNotifyEvent read FOnLayoutChanged write FOnLayoutChanged;
|
|
property OnMoreEventsButtonClick: TcxSchedulerMoreEventsButtonClickEvent read FOnMoreEventsButtonClick write FOnMoreEventsButtonClick;
|
|
property OnNavigationButtonClick: TcxSchedulerNavigationButtonClickEvent read FOnNavigationButtonClick write FOnNavigationButtonClick;
|
|
property OnScaleScroll: TcxSchedulerScaleScrollEvent read FOnScaleScroll write FOnScaleScroll;
|
|
property OnSelectionChanged: TNotifyEvent read FOnSelectionChanged write FOnSelectionChanged;
|
|
property OnShowDateHint: TcxSchedulerShowDateHintEvent read GetOnShowDateHint write FOnShowDateHint;
|
|
property OnViewTypeChanged: TcxSchedulerViewTypeChangedEvent read FOnViewTypeChanged write FOnViewTypeChanged;
|
|
public
|
|
constructor Create(AOwner: TComponent); override;
|
|
destructor Destroy; override;
|
|
procedure BeginUpdate;
|
|
procedure CopyToClipboard;
|
|
procedure CreateEventUsingDialog(AllDay: Boolean = False; ARecurrence: Boolean = False); virtual;
|
|
procedure CreateEventUsingInplaceEdit;
|
|
procedure CutToClipboard;
|
|
procedure DeleteEvent(AEvent: TcxSchedulerControlEvent); virtual;
|
|
procedure DeleteSelectedEvents(ACheckReadOnly: Boolean = True);
|
|
procedure DragDrop(Source: TObject; X, Y: Integer); override;
|
|
procedure EditEventUsingDialog(AEvent: TcxSchedulerControlEvent;
|
|
ACheckReadOnly: Boolean = True; AForcePatternEditing: Boolean = False);
|
|
procedure EditEventUsingInplaceEdit(AEvent: TcxSchedulerControlEvent);
|
|
procedure EndUpdate;
|
|
procedure FullRefresh; virtual;
|
|
{$IFDEF DELPHI12}
|
|
procedure GetChildren(Proc: TGetChildProc; Root: TComponent); override;
|
|
{$ENDIF}
|
|
function GoToDate(ADate: TDateTime): Boolean; overload; virtual;
|
|
function GoToDate(ADate: TDateTime; AViewMode: TcxSchedulerViewMode): Boolean; overload; virtual;
|
|
procedure LayoutChanged;
|
|
procedure MakeEventVisible(AEvent: TcxSchedulerControlEvent;
|
|
const ADate: TDateTime = NullDate; AResource: TcxSchedulerStorageResourceItem = nil);
|
|
procedure MakeResourceVisible(AResource: TcxSchedulerStorageResourceItem);
|
|
procedure PasteFromClipboard;
|
|
procedure SelectEvent(AEvent: TcxSchedulerControlEvent; AShift: TShiftState = []);
|
|
procedure SelectTime(const ASelStart, ASelFinish: TDateTime;
|
|
AResource: TcxSchedulerStorageResourceItem);
|
|
procedure UnselectEvents;
|
|
procedure ValidateFirstVisibleResourceIndex;
|
|
// store/load
|
|
procedure RestoreFromIniFile(const AStorageName: string; ARestoreResources: Boolean = True);
|
|
procedure RestoreFromRegistry(const AStorageName: string; ARestoreResources: Boolean = True);
|
|
procedure RestoreFromStream(AStream: TStream; ARestoreResources: Boolean = True);
|
|
procedure StoreToIniFile(const AStorageName: string; AReCreate: Boolean = True; AStoreResources: Boolean = True);
|
|
procedure StoreToRegistry(const AStorageName: string; AReCreate: Boolean = True; AStoreResources: Boolean = True);
|
|
procedure StoreToStream(AStream: TStream; AStoreResources: Boolean = True);
|
|
// IdxLocalizerListener
|
|
procedure TranslationChanged; override;
|
|
|
|
property ActiveHitTest: TcxSchedulerSubControlHitTest read GetActiveHitTest;
|
|
property Color;
|
|
property ContentPopupMenu: TcxSchedulerContentPopupMenu read FContentPopupMenu write SetContentPopupMenu;
|
|
property ControlBox: TcxSchedulerControlBox read FControlBox write SetControlBox;
|
|
property CurrentView: TcxSchedulerCustomView read FCurrentView write SetCurrentView;
|
|
property DateNavigator: TcxSchedulerCustomDateNavigator read FDateNavigator;
|
|
property DateTimeHelper: TcxSchedulerDateTimeHelperClass read GetDateTimeHelper;
|
|
property DialogsLookAndFeel: TcxLookAndFeel read FDialogsLookAndFeel write SetDialogsLookAndFeel;
|
|
property EventDays: TcxSchedulerDateList read FEventDays;
|
|
property EventImages: TCustomImageList read FEventImages write SetEventImages;
|
|
property EventOperations: TcxSchedulerEventOperations read FEventOperations write SetEventOperations;
|
|
property EventPopupMenu: TcxSchedulerEventPopupMenu read FEventPopupMenu write SetEventPopupMenu;
|
|
property FirstVisibleResourceIndex: Integer read FFirstVisibleResourceIndex write SetFirstVisibleResourceIndex default 0;
|
|
property HolidayDays: TcxSchedulerDateList read FHolidayDays;
|
|
property OptionsBehavior: TcxSchedulerOptionsBehavior read FOptionsBehavior write SetOptionsBehavior;
|
|
property OptionsCustomize: TcxSchedulerOptionsCustomize read FOptionsCustomize write SetOptionsCustomize;
|
|
property OptionsView: TcxSchedulerOptionsView read FOptionsView write SetOptionsView;
|
|
property ResourceNavigator: TcxSchedulerResourceNavigator read FResourceNavigator write SetResourceNavigator;
|
|
property SelectedDays: TcxSchedulerDateList read FSelectedDays;
|
|
property SelectedEventCount: Integer read GetSelectedEventCount;
|
|
property SelectedEvents[Index: Integer]: TcxSchedulerControlEvent read GetSelectedEvent;
|
|
property SelFinish: TDateTime read GetSelFinish;
|
|
property SelResource: TcxSchedulerStorageResourceItem read FSelResource;
|
|
property SelStart: TDateTime read GetSelStart;
|
|
property Storage: TcxCustomSchedulerStorage read FStorage write SetStorage;
|
|
property StoringName: string read FStoringName write FStoringName;
|
|
property Styles: TcxSchedulerStyles read FStyles write SetStyles;
|
|
property VisibleEventCount: Integer read GetVisibleEventCount;
|
|
property VisibleEvents[AIndex: Integer]: TcxSchedulerControlEvent read GetVisibleEvent;
|
|
property TabStop default True;
|
|
property Font;
|
|
published
|
|
property StylesEvents: TNotifyEvent read FStylesEvents write FStylesEvents;
|
|
property ResourceNavigatorEvents: TNotifyEvent read FResourceNavigatorEvents write FResourceNavigatorEvents;
|
|
property ContentPopupMenuEvents: TNotifyEvent read FContentPopupMenuEvents write FContentPopupMenuEvents;
|
|
property EventPopupMenuEvents: TNotifyEvent read FEventPopupMenuEvents write FEventPopupMenuEvents;
|
|
end;
|
|
|
|
{ TcxSchedulerPopupMenu }
|
|
|
|
TcxSchedulerPopupMenu = class(TPersistent)
|
|
private
|
|
FScheduler: TcxCustomScheduler;
|
|
FPopupMenu: TComponent;
|
|
FInternalMenu: TPopupMenu;
|
|
FUseBuiltInPopupMenu: Boolean;
|
|
function GetRoot: TMenuItem;
|
|
procedure SetPopupMenu(const Value: TComponent);
|
|
protected
|
|
function AddValidSeparator(AOwner: TMenuItem): TMenuItem;
|
|
procedure CreateInternalMenu;
|
|
procedure CreateItems; virtual;
|
|
function CreateSeparator(AOwner: TMenuItem): TMenuItem;
|
|
function CreateSubItem(AOwner: TMenuItem; const ACaption: string; ACommand: Integer = -1;
|
|
AImageIndex: Integer = -1; AEnabled: Boolean = True; AChecked: Boolean = False): TMenuItem;
|
|
procedure DoExecute(ACommand: Integer); virtual;
|
|
function DoOnClick(ACommand: Integer): Boolean; virtual;
|
|
function DoOnPopup: Boolean; virtual;
|
|
procedure ExecuteCommand(ACommand: Integer);
|
|
function FindItemByCommand(AOwnerItem: TMenuItem; ACommand: Integer): TMenuItem;
|
|
function IsValidCommand(ACommand: Integer): Boolean; virtual;
|
|
procedure Notification(AComponent: TComponent; Operation: TOperation);
|
|
procedure OnItemClickHandler(Sender: TObject);
|
|
function Storage: TcxCustomSchedulerStorage;
|
|
|
|
property InternalMenu: TPopupMenu read FInternalMenu;
|
|
property Root: TMenuItem read GetRoot;
|
|
public
|
|
constructor Create(AScheduler: TcxCustomScheduler); virtual;
|
|
destructor Destroy; override;
|
|
procedure Assign(Source: TPersistent); override;
|
|
function Popup(X, Y: Integer): Boolean; virtual;
|
|
|
|
property Scheduler: TcxCustomScheduler read FScheduler;
|
|
published
|
|
property PopupMenu: TComponent read FPopupMenu write SetPopupMenu;
|
|
property UseBuiltInPopupMenu: Boolean read FUseBuiltInPopupMenu write FUseBuiltInPopupMenu default True;
|
|
end;
|
|
|
|
{ TcxSchedulerCustomContentPopupMenu }
|
|
|
|
TcxSchedulerCustomContentPopupMenu = class(TcxSchedulerPopupMenu)
|
|
private
|
|
FNewID: Integer;
|
|
FAllDayID: Integer;
|
|
FReccurenceID: Integer;
|
|
protected
|
|
function CanCreateEvent: Boolean;
|
|
procedure CreateNewEventItems(ANew, AllDay, AReccurence: Boolean;
|
|
ANewID, AllDayID, AReccurenceID: Integer);
|
|
procedure DoExecute(ACommand: Integer); override;
|
|
public
|
|
constructor Create(AScheduler: TcxCustomScheduler); override;
|
|
end;
|
|
|
|
{ TcxSchedulerContentPopupMenu }
|
|
|
|
TcxSchedulerContentPopupMenuPopupEvent = procedure (Sender: TcxSchedulerContentPopupMenu;
|
|
ABuiltInMenu: TPopupMenu; var AHandled: Boolean) of object;
|
|
TcxSchedulerContentPopupMenuClickEvent = procedure (Sender: TcxSchedulerContentPopupMenu;
|
|
AItem: TcxSchedulerContentPopupMenuItem; var AHandled: Boolean) of object;
|
|
|
|
TcxSchedulerContentPopupMenu = class(TcxSchedulerCustomContentPopupMenu)
|
|
private
|
|
FActualItems: TcxSchedulerContentPopupMenuItems;
|
|
FItems: TcxSchedulerContentPopupMenuItems;
|
|
FSavedDate: TDateTime;
|
|
FOnPopup: TcxSchedulerContentPopupMenuPopupEvent;
|
|
FOnClick: TcxSchedulerContentPopupMenuClickEvent;
|
|
procedure CreateGoToThisDayItem;
|
|
protected
|
|
procedure CreateItems; override;
|
|
procedure DoExecute(ACommand: Integer); override;
|
|
function DoOnClick(ACommand: Integer): Boolean; override;
|
|
function DoOnPopup: Boolean; override;
|
|
function IsValidCommand(ACommand: Integer): Boolean; override;
|
|
|
|
property ActualItems: TcxSchedulerContentPopupMenuItems read FActualItems;
|
|
public
|
|
constructor Create(AScheduler: TcxCustomScheduler); override;
|
|
procedure Assign(Source: TPersistent); override;
|
|
procedure Execute(AItem: TcxSchedulerContentPopupMenuItem);
|
|
function GetMenuItem(AItem: TcxSchedulerContentPopupMenuItem): TMenuItem;
|
|
published
|
|
property Items: TcxSchedulerContentPopupMenuItems
|
|
read FItems write FItems default [cpmiNewEvent, cpmiNewAllDayEvent,
|
|
cpmiNewReccuringEvent, cpmiToday, cpmiGoToDate, cpmiGoToThisDay,
|
|
cpmiResourcesLayout];
|
|
property PopupMenu;
|
|
property UseBuiltInPopupMenu;
|
|
|
|
property OnClick: TcxSchedulerContentPopupMenuClickEvent read FOnClick write FOnClick;
|
|
property OnPopup: TcxSchedulerContentPopupMenuPopupEvent read FOnPopup write FOnPopup;
|
|
end;
|
|
|
|
{ TcxSchedulerEventPopupMenu }
|
|
|
|
TcxSchedulerEventPopupMenuItem = (epmiOpen, epmiEditSeries,
|
|
epmiShowTimeAs, epmiLabel, epmiDelete);
|
|
TcxSchedulerEventPopupMenuItems = set of TcxSchedulerEventPopupMenuItem;
|
|
|
|
TcxSchedulerEventPopupMenuPopupEvent = procedure (Sender: TcxSchedulerEventPopupMenu;
|
|
ABuiltInMenu: TPopupMenu; var AHandled: Boolean) of object;
|
|
TcxSchedulerEventPopupMenuClickEvent = procedure (Sender: TcxSchedulerEventPopupMenu;
|
|
AItem: TcxSchedulerEventPopupMenuItem; ASubItemIndex: Integer;
|
|
var AHandled: Boolean) of object;
|
|
|
|
TcxSchedulerEventPopupMenu = class(TcxSchedulerPopupMenu)
|
|
private
|
|
FEvent: TcxSchedulerControlEvent;
|
|
FItems: TcxSchedulerEventPopupMenuItems;
|
|
FOnPopup: TcxSchedulerEventPopupMenuPopupEvent;
|
|
FOnClick: TcxSchedulerEventPopupMenuClickEvent;
|
|
procedure CreateDeleteItem;
|
|
procedure CreateLabelItems;
|
|
procedure CreateTimeItems;
|
|
function GetCommand(AItem: TcxSchedulerEventPopupMenuItem;
|
|
ASubItemIndex: Integer): Integer;
|
|
function CanEdit: Boolean;
|
|
function GetEvent: TcxSchedulerControlEvent;
|
|
procedure UnpackCommand(ACommand: Integer;
|
|
out AItem: TcxSchedulerEventPopupMenuItem; out ASubItemIndex: Integer);
|
|
protected
|
|
procedure CreateItems; override;
|
|
procedure DoExecute(ACommand: Integer); override;
|
|
function DoOnClick(ACommand: Integer): Boolean; override;
|
|
function DoOnPopup: Boolean; override;
|
|
function IsValidCommand(ACommand: Integer): Boolean; override;
|
|
procedure SetEventLabelColor(AColor: Integer);
|
|
procedure SetEventState(AState: Integer);
|
|
public
|
|
constructor Create(AScheduler: TcxCustomScheduler); override;
|
|
procedure Assign(Source: TPersistent); override;
|
|
function GetMenuItem(AItem: TcxSchedulerEventPopupMenuItem;
|
|
ASubItemIndex: Integer = -1): TMenuItem;
|
|
property Event: TcxSchedulerControlEvent read FEvent;
|
|
published
|
|
property Items: TcxSchedulerEventPopupMenuItems
|
|
read FItems write FItems default [epmiOpen, epmiEditSeries,
|
|
epmiShowTimeAs, epmiLabel, epmiDelete];
|
|
property PopupMenu;
|
|
property UseBuiltInPopupMenu;
|
|
|
|
property OnClick: TcxSchedulerEventPopupMenuClickEvent read FOnClick write FOnClick;
|
|
property OnPopup: TcxSchedulerEventPopupMenuPopupEvent read FOnPopup write FOnPopup;
|
|
end;
|
|
|
|
function IsHeaderEvent(AEvent: TcxSchedulerEvent): Boolean;
|
|
|
|
var
|
|
CF_SCHEDULERDATA: Integer;
|
|
|
|
implementation
|
|
|
|
uses
|
|
{$IFDEF DELPHI6}
|
|
DateUtils, Variants,
|
|
{$ENDIF}
|
|
cxSchedulerDialogs, cxMemo, cxSchedulerStrs,
|
|
cxSchedulerRecurrenceSelectionDialog, cxLibraryConsts;
|
|
|
|
const
|
|
EventContentColors: array[Boolean] of TColor = (clWindow, clWhite);
|
|
|
|
function cxCompareTabOrders(
|
|
AEvent1, AEvent2: TcxSchedulerControlEvent): Integer;
|
|
var
|
|
AAllDay1, AAllDay2: Boolean;
|
|
begin
|
|
Result := 0;
|
|
AAllDay1 := AEvent1.AllDayEvent or (AEvent1.Duration >= 1);
|
|
AAllDay2 := AEvent2.AllDayEvent or (AEvent2.Duration >= 1);
|
|
if DateOf(AEvent1.Start) = DateOf(AEvent2.Start) then
|
|
Result := Byte(AAllDay2) - Byte(AAllDay1);
|
|
if Result <> 0 then Exit;
|
|
if AEvent1.Start < AEvent2.Start then
|
|
Result := -1
|
|
else
|
|
if AEvent1.Start > AEvent2.Start then
|
|
Result := 1
|
|
else
|
|
if AEvent1.Finish > AEvent2.Finish then
|
|
Result := -1
|
|
else
|
|
if AEvent1.Finish < AEvent2.Finish then
|
|
Result := 1
|
|
else
|
|
if AEvent1.RecordIndex < AEvent2.RecordIndex then
|
|
Result := -1
|
|
else
|
|
if AEvent1.RecordIndex > AEvent2.RecordIndex then
|
|
Result := 1
|
|
else
|
|
Result := 0;
|
|
end;
|
|
|
|
function IsHeaderEvent(AEvent: TcxSchedulerEvent): Boolean;
|
|
begin
|
|
Result := AEvent.AllDayEvent or (AEvent.Duration >= 1);
|
|
end;
|
|
|
|
{ TcxSchedulerSubControl }
|
|
|
|
constructor TcxSchedulerSubControl.Create(
|
|
AOwner: TcxCustomScheduler);
|
|
begin
|
|
FScheduler := AOwner;
|
|
FVisible := True;
|
|
CreateSubClasses;
|
|
FCursor := crDefault;
|
|
Scheduler.SubControlAdd(Self);
|
|
end;
|
|
|
|
destructor TcxSchedulerSubControl.Destroy;
|
|
begin
|
|
DestroySubClasses;
|
|
Scheduler.SubControlRemove(Self);
|
|
inherited Destroy;
|
|
end;
|
|
|
|
procedure TcxSchedulerSubControl.Invalidate;
|
|
begin
|
|
InvalidateRect(ClientRect);
|
|
end;
|
|
|
|
procedure TcxSchedulerSubControl.InvalidateRect(
|
|
const ARect: TRect);
|
|
begin
|
|
Scheduler.InvalidateRect(cxRectOffset(ARect, Left, Top), False);
|
|
Exclude(Scheduler.FControlFlags, cfImageValid);
|
|
end;
|
|
|
|
procedure TcxSchedulerSubControl.LayoutChanged;
|
|
begin
|
|
FCanvas := Scheduler.FCanvas;
|
|
if not Visible then
|
|
ViewInfo.Clear
|
|
else
|
|
Painter.InitializePainter;
|
|
if not Visible or (Controller = nil) then Exit;
|
|
Exclude(Scheduler.FControlFlags, cfImageValid);
|
|
Controller.Reset;
|
|
DoLayoutChanged;
|
|
if not Scheduler.AligningSubControls then
|
|
begin
|
|
HitTest.Recalculate;
|
|
Invalidate;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerSubControl.Refresh;
|
|
begin
|
|
LayoutChanged;
|
|
end;
|
|
|
|
procedure TcxSchedulerSubControl.Repaint;
|
|
begin
|
|
Invalidate;
|
|
Scheduler.Update;
|
|
end;
|
|
|
|
procedure TcxSchedulerSubControl.RepaintRect(const ARect: TRect);
|
|
begin
|
|
InvalidateRect(ARect);
|
|
Scheduler.Update;
|
|
end;
|
|
|
|
function TcxSchedulerSubControl.ScreenToClient(const APos: TPoint): TPoint;
|
|
begin
|
|
Result := Scheduler.ScreenToClient(APos);
|
|
Dec(Result.X, Left);
|
|
Dec(Result.Y, Top);
|
|
end;
|
|
|
|
procedure TcxSchedulerSubControl.SetBounds(
|
|
ALeft, ATop, AWidth, AHeight: Integer);
|
|
begin
|
|
if (ALeft <> FLeft) or (ATop <> FTop) or (AWidth <> FWidth) or
|
|
(AHeight <> FHeight) then
|
|
begin
|
|
BoundsChanging;
|
|
FLeft := ALeft;
|
|
FTop := ATop;
|
|
FWidth := AWidth;
|
|
FHeight := AHeight;
|
|
BoundsChanged;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerSubControl.GetProperties(AProperties: TStrings);
|
|
begin
|
|
end;
|
|
|
|
procedure TcxSchedulerSubControl.GetPropertyValue(const AName: string;
|
|
var AValue: Variant);
|
|
begin
|
|
end;
|
|
|
|
procedure TcxSchedulerSubControl.SetPropertyValue(const AName: string;
|
|
const AValue: Variant);
|
|
begin
|
|
end;
|
|
|
|
function TcxSchedulerSubControl.AllowDesignHitTest(
|
|
X, Y: Integer; AShift: TShiftState): Boolean;
|
|
begin
|
|
MousePositionChanged(X, Y);
|
|
Result := False;
|
|
end;
|
|
|
|
procedure TcxSchedulerSubControl.BoundsChanged;
|
|
begin
|
|
Scheduler.AlignSubControls(Self);
|
|
Changed;
|
|
end;
|
|
|
|
procedure TcxSchedulerSubControl.CalculateViewInfo;
|
|
begin
|
|
ViewInfo.Calculate;
|
|
end;
|
|
|
|
function TcxSchedulerSubControl.CanCapture(
|
|
const APoint: TPoint): Boolean;
|
|
begin
|
|
Result := Visible and cxRectPtIn(Bounds, APoint);
|
|
end;
|
|
|
|
procedure TcxSchedulerSubControl.Changed;
|
|
begin
|
|
Scheduler.LayoutChanged;
|
|
end;
|
|
|
|
procedure TcxSchedulerSubControl.ClearCachedData;
|
|
begin
|
|
end;
|
|
|
|
function TcxSchedulerSubControl.CreateController: TcxSchedulerSubControlController;
|
|
begin
|
|
Result := TcxSchedulerSubControlController.Create(Self);
|
|
end;
|
|
|
|
function TcxSchedulerSubControl.CreateHitTest: TcxSchedulerSubControlHitTest;
|
|
begin
|
|
Result := TcxSchedulerSubControlHitTest.Create(Self);
|
|
end;
|
|
|
|
function TcxSchedulerSubControl.CreatePainter: TcxSchedulerSubControlPainter;
|
|
begin
|
|
Result := TcxSchedulerSubControlPainter.Create(Self);
|
|
end;
|
|
|
|
function TcxSchedulerSubControl.CreateViewInfo: TcxSchedulerSubControlViewInfo;
|
|
begin
|
|
Result := TcxSchedulerSubControlViewInfo.Create(Self);
|
|
end;
|
|
|
|
procedure TcxSchedulerSubControl.BoundsChanging;
|
|
begin
|
|
end;
|
|
|
|
procedure TcxSchedulerSubControl.CreateSubClasses;
|
|
begin
|
|
FViewInfo := CreateViewInfo;
|
|
FHitTest := CreateHitTest;
|
|
FController := CreateController;
|
|
FPainter := CreatePainter;
|
|
end;
|
|
|
|
procedure TcxSchedulerSubControl.DestroySubClasses;
|
|
begin
|
|
FPainter.Free;
|
|
FHitTest.Free;
|
|
FController.Free;
|
|
FViewInfo.Free;
|
|
end;
|
|
|
|
procedure TcxSchedulerSubControl.DoBeforeMouseDown(AButton: TMouseButton;
|
|
AShift: TShiftState; X, Y: Integer);
|
|
begin
|
|
MousePositionChanged(X, Y);
|
|
Controller.BeforeMouseDown(AButton, AShift, X, Y);
|
|
end;
|
|
|
|
procedure TcxSchedulerSubControl.DoCancelMode;
|
|
begin
|
|
Mouse.Capture := 0;
|
|
end;
|
|
|
|
procedure TcxSchedulerSubControl.DoLayoutChanged;
|
|
begin
|
|
CalculateViewInfo;
|
|
end;
|
|
|
|
procedure TcxSchedulerSubControl.DoMouseDown(
|
|
AButton: TMouseButton; AShift: TShiftState; X, Y: Integer);
|
|
begin
|
|
MousePositionChanged(X, Y);
|
|
Controller.MouseDown(AButton, AShift, X, Y);
|
|
end;
|
|
|
|
procedure TcxSchedulerSubControl.DoMouseMove(
|
|
AShift: TShiftState; X, Y: Integer);
|
|
begin
|
|
MousePositionChanged(X, Y);
|
|
Controller.MouseMove(AShift, X, Y);
|
|
end;
|
|
|
|
procedure TcxSchedulerSubControl.DoMouseUp(
|
|
AButton: TMouseButton; AShift: TShiftState; X, Y: Integer);
|
|
begin
|
|
MousePositionChanged(X, Y);
|
|
Controller.MouseUp(AButton, AShift, X, Y);
|
|
end;
|
|
|
|
procedure TcxSchedulerSubControl.DoPaint;
|
|
var
|
|
AClipRgn: TcxRegion;
|
|
begin
|
|
AClipRgn := Canvas.GetClipRegion;
|
|
Canvas.IntersectClipRect(ClientRect);
|
|
Painter.BeforePaint;
|
|
Painter.Paint;
|
|
Painter.AfterPaint;
|
|
Canvas.SetClipRegion(AClipRgn, roSet);
|
|
end;
|
|
|
|
procedure TcxSchedulerSubControl.DoScaleScroll;
|
|
begin
|
|
Scheduler.DoScaleScroll;
|
|
end;
|
|
|
|
procedure TcxSchedulerSubControl.FormatChanged;
|
|
begin
|
|
end;
|
|
|
|
function TcxSchedulerSubControl.GetClientRect: TRect;
|
|
begin
|
|
Result := cxRectBounds(0, 0, FWidth, FHeight);
|
|
end;
|
|
|
|
function TcxSchedulerSubControl.GetOwner: TPersistent;
|
|
begin
|
|
Result := FScheduler;
|
|
end;
|
|
|
|
function TcxSchedulerSubControl.GetHScrollBarBounds: TRect;
|
|
begin
|
|
Result := cxNullRect;
|
|
end;
|
|
|
|
function TcxSchedulerSubControl.GetScrollBar(
|
|
AKind: TScrollBarKind): TcxControlScrollBar;
|
|
begin
|
|
if AKind = sbHorizontal then
|
|
Result := Scheduler.HScrollBar
|
|
else
|
|
Result := Scheduler.VScrollBar;
|
|
end;
|
|
|
|
function TcxSchedulerSubControl.GetSizeGripBounds: TRect;
|
|
begin
|
|
Result := cxNullRect;
|
|
end;
|
|
|
|
function TcxSchedulerSubControl.GetStartOfWeek: TDay;
|
|
begin
|
|
Result := Scheduler.OptionsView.ActualStartOfWeek;
|
|
end;
|
|
|
|
function TcxSchedulerSubControl.GetVScrollBarBounds: TRect;
|
|
begin
|
|
Result := cxNullRect;
|
|
end;
|
|
|
|
procedure TcxSchedulerSubControl.InitScrollBarsParameters;
|
|
begin
|
|
end;
|
|
|
|
function TcxSchedulerSubControl.IsSpecialPaint: Boolean;
|
|
begin
|
|
Result := False;
|
|
end;
|
|
|
|
procedure TcxSchedulerSubControl.LookAndFeelChanged(Sender: TcxLookAndFeel;
|
|
AChangedValues: TcxLookAndFeelValues);
|
|
begin
|
|
end;
|
|
|
|
procedure TcxSchedulerSubControl.MousePositionChanged(
|
|
var X, Y: Integer);
|
|
begin
|
|
Dec(X, FLeft);
|
|
Dec(Y, FTop);
|
|
HitTest.HitPoint := cxPoint(X, Y);
|
|
end;
|
|
|
|
procedure TcxSchedulerSubControl.Notification(AComponent: TComponent;
|
|
Operation: TOperation);
|
|
begin
|
|
end;
|
|
|
|
procedure TcxSchedulerSubControl.Paint;
|
|
var
|
|
ASavePos: TPoint;
|
|
begin
|
|
if not Visible or cxRectIsEmpty(Bounds) then Exit;
|
|
ASavePos := Canvas.WindowOrg;
|
|
Canvas.WindowOrg := cxPoint(-Left, -Top);
|
|
try
|
|
DoPaint;
|
|
finally
|
|
Canvas.WindowOrg := ASavePos;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerSubControl.PeriodChanged;
|
|
begin
|
|
Scheduler.PeriodChanged;
|
|
end;
|
|
|
|
procedure TcxSchedulerSubControl.SetScrollBarInfo(
|
|
AScrollBarKind: TScrollBarKind; AMin, AMax, AStep, APage, APos: Integer;
|
|
AAllowShow, AAllowHide: Boolean);
|
|
begin
|
|
Scheduler.SetScrollBarInfo(AScrollBarKind, AMin, AMax,
|
|
AStep, APage, APos, AAllowShow and Visible, AAllowHide);
|
|
end;
|
|
|
|
procedure TcxSchedulerSubControl.VisibleChanged;
|
|
begin
|
|
Scheduler.AlignSubControls(Self);
|
|
Changed;
|
|
end;
|
|
|
|
function TcxSchedulerSubControl.GetBottom: Integer;
|
|
begin
|
|
Result := FTop + FHeight;
|
|
end;
|
|
|
|
{$IFNDEF DEBUGPAINT}
|
|
function TcxSchedulerSubControl.GetBitmap: TBitmap;
|
|
begin
|
|
Result := Scheduler.FBitmap;
|
|
end;
|
|
{$ENDIF}
|
|
|
|
function TcxSchedulerSubControl.GetBounds: TRect;
|
|
begin
|
|
Result := cxRectBounds(FLeft, FTop, FWidth, FHeight);
|
|
end;
|
|
|
|
function TcxSchedulerSubControl.GetDateTimeHelperClass: TcxSchedulerDateTimeHelperClass;
|
|
begin
|
|
Result := Scheduler.DateTimeHelper;
|
|
end;
|
|
|
|
function TcxSchedulerSubControl.GetIsScrollingContent: Boolean;
|
|
begin
|
|
Result := Scheduler.IsScrollingContent;
|
|
end;
|
|
|
|
function TcxSchedulerSubControl.GetLookAndFeelPainter: TcxCustomLookAndFeelPainterClass;
|
|
begin
|
|
Result := Scheduler.LookAndFeelPainter;
|
|
end;
|
|
|
|
function TcxSchedulerSubControl.GetPainterHelperClass: TcxSchedulerPainterHelperClass;
|
|
begin
|
|
Result := Scheduler.PainterHelper;
|
|
end;
|
|
|
|
function TcxSchedulerSubControl.GetRight: Integer;
|
|
begin
|
|
Result := FLeft + FWidth;
|
|
end;
|
|
|
|
function TcxSchedulerSubControl.GetStyles: TcxSchedulerStyles;
|
|
begin
|
|
Result := Scheduler.Styles;
|
|
end;
|
|
|
|
procedure TcxSchedulerSubControl.InternalSetBounds(const AValue: TRect);
|
|
begin
|
|
SetBounds(AValue.Left, AValue.Top, AValue.Right - AValue.Left,
|
|
AValue.Bottom - AValue.Top);
|
|
end;
|
|
|
|
procedure TcxSchedulerSubControl.SetBottom(const Value: Integer);
|
|
begin
|
|
InternalSetBounds(cxRectSetBottom(Bounds, Value));
|
|
end;
|
|
|
|
procedure TcxSchedulerSubControl.SetHeight(AValue: Integer);
|
|
begin
|
|
SetBounds(FLeft, FTop, FWidth, AValue);
|
|
end;
|
|
|
|
procedure TcxSchedulerSubControl.SetLeft(AValue: Integer);
|
|
begin
|
|
SetBounds(AValue, FTop, FWidth, FHeight);
|
|
end;
|
|
|
|
procedure TcxSchedulerSubControl.SetRight(Value: Integer);
|
|
begin
|
|
InternalSetBounds(cxRectSetRight(Bounds, Value));
|
|
end;
|
|
|
|
procedure TcxSchedulerSubControl.SetTop(AValue: Integer);
|
|
begin
|
|
SetBounds(FLeft, AValue, FWidth, FHeight);
|
|
end;
|
|
|
|
procedure TcxSchedulerSubControl.SetVisible(
|
|
AValue: Boolean);
|
|
begin
|
|
if AValue <> FVisible then
|
|
begin
|
|
FVisible := AValue;
|
|
VisibleChanged;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerSubControl.SetWidth(AValue: Integer);
|
|
begin
|
|
SetBounds(FLeft, FTop, AValue, FHeight);
|
|
end;
|
|
|
|
{ TcxSchedulerSubControlController }
|
|
|
|
constructor TcxSchedulerSubControlController.Create(
|
|
AOwner: TcxSchedulerSubControl);
|
|
begin
|
|
FOwner := AOwner;
|
|
end;
|
|
|
|
procedure TcxSchedulerSubControlController.BeginDragAndDrop;
|
|
begin
|
|
end;
|
|
|
|
function TcxSchedulerSubControlController.CanDrag(
|
|
X, Y: Integer): Boolean;
|
|
begin
|
|
Result := False;
|
|
end;
|
|
|
|
procedure TcxSchedulerSubControlController.DragAndDrop(
|
|
const P: TPoint; var Accepted: Boolean);
|
|
begin
|
|
end;
|
|
|
|
procedure TcxSchedulerSubControlController.DragDrop(
|
|
Source: TObject; X, Y: Integer);
|
|
begin
|
|
end;
|
|
|
|
procedure TcxSchedulerSubControlController.DragOver(
|
|
Source: TObject; X, Y: Integer; State: TDragState; var Accept: Boolean);
|
|
begin
|
|
Accept := False;
|
|
end;
|
|
|
|
procedure TcxSchedulerSubControlController.EndDrag(
|
|
Target: TObject; X, Y: Integer);
|
|
begin
|
|
end;
|
|
|
|
procedure TcxSchedulerSubControlController.EndDragAndDrop(
|
|
Accepted: Boolean);
|
|
begin
|
|
end;
|
|
|
|
function TcxSchedulerSubControlController.GetDragAndDropObjectClass: TcxDragAndDropObjectClass;
|
|
begin
|
|
Result := nil;
|
|
end;
|
|
|
|
procedure TcxSchedulerSubControlController.StartDrag(
|
|
var DragObject: TDragObject);
|
|
begin
|
|
end;
|
|
|
|
function TcxSchedulerSubControlController.StartDragAndDrop(
|
|
const P: TPoint): Boolean;
|
|
begin
|
|
Result := False;
|
|
end;
|
|
|
|
procedure TcxSchedulerSubControlController.BeforeMouseDown(
|
|
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
|
|
begin
|
|
FCanProcessMouseMove := Button = mbLeft;
|
|
end;
|
|
|
|
procedure TcxSchedulerSubControlController.DoCancelMode;
|
|
begin
|
|
FCanProcessMouseMove := False;
|
|
end;
|
|
|
|
function TcxSchedulerSubControlController.GetCursor(
|
|
X, Y: Integer): TCursor;
|
|
begin
|
|
Result := Owner.Cursor;
|
|
end;
|
|
|
|
procedure TcxSchedulerSubControlController.KeyDown(
|
|
var Key: Word; Shift: TShiftState);
|
|
begin
|
|
end;
|
|
|
|
procedure TcxSchedulerSubControlController.KeyPress(
|
|
var Key: Char);
|
|
begin
|
|
end;
|
|
|
|
procedure TcxSchedulerSubControlController.KeyUp(
|
|
var Key: Word; Shift: TShiftState);
|
|
begin
|
|
end;
|
|
|
|
procedure TcxSchedulerSubControlController.MouseEnter;
|
|
begin
|
|
end;
|
|
|
|
procedure TcxSchedulerSubControlController.MouseLeave;
|
|
begin
|
|
end;
|
|
|
|
procedure TcxSchedulerSubControlController.MouseDown(
|
|
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
|
|
begin
|
|
end;
|
|
|
|
procedure TcxSchedulerSubControlController.MouseMove(
|
|
Shift: TShiftState; X, Y: Integer);
|
|
begin
|
|
end;
|
|
|
|
procedure TcxSchedulerSubControlController.MouseUp(
|
|
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
|
|
begin
|
|
if Button = mbLeft then
|
|
FCanProcessMouseMove := False;
|
|
end;
|
|
|
|
procedure TcxSchedulerSubControlController.Reset;
|
|
begin
|
|
end;
|
|
|
|
function TcxSchedulerSubControlController.GetHitTest: TcxSchedulerSubControlHitTest;
|
|
begin
|
|
Result := Owner.HitTest;
|
|
end;
|
|
|
|
function TcxSchedulerSubControlController.GetStartOfWeek: TDay;
|
|
begin
|
|
Result := Owner.StartOfWeek;
|
|
end;
|
|
|
|
{ TcxSchedulerSubControlHitTest }
|
|
|
|
constructor TcxSchedulerSubControlHitTest.Create(
|
|
AOwner: TcxSchedulerSubControl);
|
|
begin
|
|
FOwner := AOwner;
|
|
end;
|
|
|
|
destructor TcxSchedulerSubControlHitTest.Destroy;
|
|
begin
|
|
inherited Destroy;
|
|
end;
|
|
|
|
procedure TcxSchedulerSubControlHitTest.Recalculate;
|
|
begin
|
|
if Scheduler.HandleAllocated then
|
|
DoCalculate;
|
|
end;
|
|
|
|
procedure TcxSchedulerSubControlHitTest.Clear;
|
|
begin
|
|
Flags := 0;
|
|
FTime := NullDate;
|
|
end;
|
|
|
|
procedure TcxSchedulerSubControlHitTest.DoCalculate;
|
|
begin
|
|
Clear;
|
|
SetBitState(htcControl, cxRectPtIn(Owner.Bounds,
|
|
cxPointOffset(HitPoint, Owner.Left, Owner.Top)));
|
|
end;
|
|
|
|
function TcxSchedulerSubControlHitTest.GetBitState(
|
|
AIndex: Integer): Boolean;
|
|
begin
|
|
Result := (Flags and (1 shl AIndex)) <> 0
|
|
end;
|
|
|
|
function TcxSchedulerSubControlHitTest.GetMaskState(
|
|
AMask: Integer): Boolean;
|
|
begin
|
|
Result := Flags and AMask = AMask;
|
|
end;
|
|
|
|
function TcxSchedulerSubControlHitTest.GetMaskStateEx(
|
|
AMask: Integer): Boolean;
|
|
begin
|
|
Result := Flags and AMask <> 0;
|
|
end;
|
|
|
|
procedure TcxSchedulerSubControlHitTest.SetBitState(
|
|
AIndex: Integer; AValue: Boolean);
|
|
begin
|
|
if AValue then
|
|
Flags := Flags or (1 shl AIndex)
|
|
else
|
|
Flags := Flags and not (1 shl AIndex);
|
|
end;
|
|
|
|
procedure TcxSchedulerSubControlHitTest.SetMaskState(
|
|
AMask: Integer; AValue: Boolean);
|
|
begin
|
|
if AValue then
|
|
Flags := Flags or AMask
|
|
else
|
|
Flags := Flags and not AMask;
|
|
end;
|
|
|
|
function TcxSchedulerSubControlHitTest.GetPosValue(
|
|
AIndex: Integer): Integer;
|
|
begin
|
|
Result := cxPointGetItem(FHitPoint, AIndex);
|
|
end;
|
|
|
|
function TcxSchedulerSubControlHitTest.GetScheduler: TcxCustomScheduler;
|
|
begin
|
|
Result := FOwner.FScheduler;
|
|
end;
|
|
|
|
procedure TcxSchedulerSubControlHitTest.SetHitPoint(
|
|
const APoint: TPoint);
|
|
begin
|
|
FHitPoint := APoint;
|
|
Recalculate;
|
|
end;
|
|
|
|
procedure TcxSchedulerSubControlHitTest.SetPosValue(
|
|
AIndex, AValue: Integer);
|
|
begin
|
|
FHitPoint := cxPointReplaceItem(FHitPoint, AIndex, AValue);
|
|
Recalculate;
|
|
end;
|
|
|
|
{ TcxSchedulerSubControlPainter }
|
|
|
|
constructor TcxSchedulerSubControlPainter.Create(
|
|
AOwner: TcxSchedulerSubControl);
|
|
begin
|
|
FOwner := AOwner;
|
|
end;
|
|
|
|
procedure TcxSchedulerSubControlPainter.AfterPaint;
|
|
begin
|
|
end;
|
|
|
|
procedure TcxSchedulerSubControlPainter.BeforePaint;
|
|
begin
|
|
end;
|
|
|
|
procedure TcxSchedulerSubControlPainter.InitializePainter;
|
|
begin
|
|
end;
|
|
|
|
procedure TcxSchedulerSubControlPainter.Paint;
|
|
begin
|
|
end;
|
|
|
|
{$IFNDEF DEBUGPAINT}
|
|
function TcxSchedulerSubControlPainter.GetBitmap: TBitmap;
|
|
begin
|
|
Result := FOwner.Bitmap;
|
|
end;
|
|
{$ENDIF}
|
|
|
|
function TcxSchedulerSubControlPainter.GetCanvas: TcxCanvas;
|
|
begin
|
|
Result := FOwner.FCanvas;
|
|
end;
|
|
|
|
function TcxSchedulerSubControlPainter.GetViewInfo: TcxSchedulerSubControlViewInfo;
|
|
begin
|
|
Result := Owner.ViewInfo;
|
|
end;
|
|
|
|
{ TcxSchedulerSubControlViewInfo }
|
|
|
|
constructor TcxSchedulerSubControlViewInfo.Create(
|
|
AOwner: TcxSchedulerSubControl);
|
|
begin
|
|
FOwner := AOwner;
|
|
end;
|
|
|
|
procedure TcxSchedulerSubControlViewInfo.Calculate;
|
|
begin
|
|
if not IsSchedulerCreated then Exit;
|
|
FBounds := GetBounds;
|
|
Clear;
|
|
DoCalculate;
|
|
AfterCalculate;
|
|
end;
|
|
|
|
procedure TcxSchedulerSubControlViewInfo.AfterCalculate;
|
|
begin
|
|
end;
|
|
|
|
procedure TcxSchedulerSubControlViewInfo.Clear;
|
|
begin
|
|
end;
|
|
|
|
procedure TcxSchedulerSubControlViewInfo.DoCalculate;
|
|
begin
|
|
end;
|
|
|
|
function TcxSchedulerSubControlViewInfo.GetBounds: TRect;
|
|
begin
|
|
Result := Owner.ClientRect;
|
|
end;
|
|
|
|
function TcxSchedulerSubControlViewInfo.GetDateTimeHelperClass: TcxSchedulerDateTimeHelperClass;
|
|
begin
|
|
Result := Owner.DateTimeHelper;
|
|
end;
|
|
|
|
function TcxSchedulerSubControlViewInfo.GetDefaultFont: TFont;
|
|
begin
|
|
Result := Owner.Scheduler.Font;
|
|
end;
|
|
|
|
function TcxSchedulerSubControlViewInfo.GetIsSchedulerCreated: Boolean;
|
|
begin
|
|
Result := Owner.Scheduler.FSubControlsCreated;
|
|
end;
|
|
|
|
function TcxSchedulerSubControlViewInfo.GetLookAndFeelPainter: TcxCustomLookAndFeelPainterClass;
|
|
begin
|
|
Result := Owner.Scheduler.LookAndFeelPainter;
|
|
end;
|
|
|
|
function TcxSchedulerSubControlViewInfo.GetPainterHelperClass: TcxSchedulerPainterHelperClass;
|
|
begin
|
|
Result := Owner.PainterHelper;
|
|
end;
|
|
|
|
function TcxSchedulerSubControlViewInfo.GetStyles: TcxSchedulerStyles;
|
|
begin
|
|
Result := Owner.Styles;
|
|
end;
|
|
|
|
type
|
|
TContainer = class(TWinControl)
|
|
protected
|
|
procedure CreateParams(var Params: TCreateParams); override;
|
|
public
|
|
constructor Create(AOwner: TComponent); override;
|
|
end;
|
|
|
|
{ TContainer }
|
|
|
|
constructor TContainer.Create(AOwner: TComponent);
|
|
begin
|
|
inherited Create(AOwner);
|
|
ControlStyle := ControlStyle + [csAcceptsControls] + [csNoDesignVisible];
|
|
Visible := False;
|
|
TabStop := False;
|
|
end;
|
|
|
|
procedure TContainer.CreateParams(var Params: TCreateParams);
|
|
begin
|
|
inherited CreateParams(Params);
|
|
with Params do
|
|
begin
|
|
Style := WS_CHILD or WS_CLIPCHILDREN or WS_CLIPSIBLINGS;
|
|
ExStyle := WS_EX_CONTROLPARENT;
|
|
WindowClass.Style := CS_DBLCLKS;
|
|
end;
|
|
end;
|
|
|
|
{ TcxSchedulerBackground }
|
|
|
|
function TcxSchedulerBackground.IsSpecialPaint: Boolean;
|
|
begin
|
|
Result := True;
|
|
end;
|
|
|
|
{ TcxSchedulerControlBox }
|
|
|
|
constructor TcxSchedulerControlBox.Create(AOwner: TcxCustomScheduler);
|
|
begin
|
|
inherited Create(AOwner);
|
|
FContainer := CreateWndContainerControl;
|
|
end;
|
|
|
|
procedure TcxSchedulerControlBox.Assign(Source: TPersistent);
|
|
begin
|
|
if Source is TcxSchedulerControlBox then
|
|
with TcxSchedulerControlBox(Source) do
|
|
begin
|
|
Self.Control := Control;
|
|
Self.Visible := Visible;
|
|
end
|
|
else inherited Assign(Source);
|
|
end;
|
|
|
|
function TcxSchedulerControlBox.HasAsParent(
|
|
AValue: TControl): Boolean;
|
|
var
|
|
AParent: TWinControl;
|
|
begin
|
|
Result := False;
|
|
AParent := Scheduler;
|
|
while not Result and (AParent <> nil) do
|
|
begin
|
|
Result := AValue = AParent;
|
|
AParent := AParent.Parent;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerControlBox.VisibleChanged;
|
|
begin
|
|
FContainer.Visible := Visible;
|
|
inherited VisibleChanged;
|
|
end;
|
|
|
|
procedure TcxSchedulerControlBox.DoLayoutChanged;
|
|
begin
|
|
FViewParams := Styles.GetBackgroundParams;
|
|
inherited DoLayoutChanged;
|
|
end;
|
|
|
|
procedure TcxSchedulerControlBox.GetProperties(AProperties: TStrings);
|
|
begin
|
|
if Scheduler.DateNavigator.Visible then Exit;
|
|
AProperties.Add('DNWidth');
|
|
end;
|
|
|
|
procedure TcxSchedulerControlBox.GetPropertyValue(const AName: string;
|
|
var AValue: Variant);
|
|
begin
|
|
if Scheduler.DateNavigator.Visible then Exit;
|
|
if AName = 'DNWidth' then
|
|
AValue := Width
|
|
end;
|
|
|
|
procedure TcxSchedulerControlBox.SetPropertyValue(const AName: string;
|
|
const AValue: Variant);
|
|
begin
|
|
if Scheduler.DateNavigator.Visible then Exit;
|
|
if AName = 'DNWidth' then
|
|
begin
|
|
Scheduler.DateNavigator.Width := AValue;
|
|
Scheduler.DateNavigator.DoLayoutChanged;
|
|
Width := AValue;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerControlBox.BoundsChanged;
|
|
begin
|
|
FContainer.BoundsRect := Bounds;
|
|
inherited BoundsChanged;
|
|
FContainer.Update;
|
|
end;
|
|
|
|
function TcxSchedulerControlBox.CreateWndContainerControl: TWinControl;
|
|
begin
|
|
Result := TContainer.Create(Scheduler);
|
|
Result.Parent := Scheduler;
|
|
end;
|
|
|
|
procedure TcxSchedulerControlBox.DoPaint;
|
|
begin
|
|
Canvas.FillRect(ClientRect, ViewParams);
|
|
end;
|
|
|
|
procedure TcxSchedulerControlBox.RestorePosition;
|
|
begin
|
|
if (FControl = nil) or
|
|
(csDestroying in Control.ComponentState) then Exit;
|
|
Control.RemoveFreeNotification(Scheduler);
|
|
Control.Align := FControlAlign;
|
|
Control.Parent := FControlParent;
|
|
Control.BoundsRect := FControlRect;
|
|
end;
|
|
|
|
procedure TcxSchedulerControlBox.SetControl(
|
|
AValue: TControl);
|
|
begin
|
|
if HasAsParent(AValue) then Exit;
|
|
if FControl <> AValue then
|
|
begin
|
|
RestorePosition;
|
|
FControl := AValue;
|
|
StorePosition;
|
|
FContainer.BoundsRect := Bounds;
|
|
FContainer.Visible := Visible and (Control <> nil);
|
|
Changed;
|
|
end
|
|
else
|
|
FContainer.Visible := False;
|
|
end;
|
|
|
|
procedure TcxSchedulerControlBox.StorePosition;
|
|
begin
|
|
if Control = nil then Exit;
|
|
FControlAlign := Control.Align;
|
|
FControlParent := Control.Parent;
|
|
FControlRect := Control.BoundsRect;
|
|
Control.FreeNotification(Scheduler);
|
|
Control.Parent := FContainer;
|
|
Control.Align := alClient;
|
|
end;
|
|
|
|
{ TcxSchedulerSplitterController }
|
|
|
|
procedure TcxSchedulerSplitterController.DoCancelMode;
|
|
begin
|
|
EraseInvertRect;
|
|
Scheduler.FCaptureControl := nil;
|
|
Scheduler.FKeyboardListener := FSaveKeyboardListener;
|
|
end;
|
|
|
|
procedure TcxSchedulerSplitterController.KeyDown(var Key: Word;
|
|
Shift: TShiftState);
|
|
begin
|
|
if Scheduler.OptionsCustomize.ControlsSizing and Scheduler.IsDragCanceled then
|
|
begin
|
|
DoCancelMode;
|
|
Mouse.Capture := 0;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerSplitterController.MouseDown(Button: TMouseButton;
|
|
Shift: TShiftState; X, Y: Integer);
|
|
begin
|
|
if Scheduler.OptionsCustomize.ControlsSizing and (ssLeft in Shift) then
|
|
begin
|
|
FSaveKeyboardListener := Scheduler.KeyboardListener;
|
|
Scheduler.KeyboardListener := Splitter;
|
|
FHitPoint := GetOwnerMousePos(X, Y);
|
|
FStartBounds := Splitter.Bounds;
|
|
FSizingBoundsRect := GetSizingBoundsRect;
|
|
FScreenCanvasClipRect := GetDrawClipRect;
|
|
if not IsDynamicUpdate then
|
|
begin
|
|
Scheduler.Update; //force repaint before on-screen drawing
|
|
DrawInvertRect(FStartBounds);
|
|
end;
|
|
FPrevRect := FStartBounds;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerSplitterController.MouseMove(Shift: TShiftState;
|
|
X, Y: Integer);
|
|
var
|
|
R: TRect;
|
|
begin
|
|
if not Scheduler.OptionsCustomize.ControlsSizing or
|
|
(Scheduler.CaptureController <> Self) or Scheduler.IsLocked then Exit;
|
|
R := GetSizingRect(GetOwnerMousePos(X, Y));
|
|
if not cxRectIsEqual(R, FPrevRect) then
|
|
begin
|
|
if IsDynamicUpdate then
|
|
UpdateSizing(R)
|
|
else
|
|
DrawInvertRect(R);
|
|
FPrevRect := R;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerSplitterController.MouseUp(Button: TMouseButton;
|
|
Shift: TShiftState; X, Y: Integer);
|
|
begin
|
|
if not Scheduler.OptionsCustomize.ControlsSizing then Exit;
|
|
Scheduler.KeyboardListener := FSaveKeyboardListener;
|
|
EraseInvertRect;
|
|
UpdateSizing(GetSizingRect(GetOwnerMousePos(X, Y)));
|
|
end;
|
|
|
|
procedure TcxSchedulerSplitterController.DrawInvertRect(const R: TRect);
|
|
var
|
|
Temp: TRect;
|
|
AOffset: TPoint;
|
|
ACanvas: TcxCanvas;
|
|
begin
|
|
if not cxRectIsEmpty(FPrevInvertRect) and cxRectIntersect(Temp, R, FPrevInvertRect) then
|
|
begin
|
|
SubtractRect(FPrevInvertRect, FPrevInvertRect, Temp);
|
|
SubtractRect(Temp, R, Temp);
|
|
end
|
|
else
|
|
Temp := R;
|
|
AOffset := ScreenOffset;
|
|
ACanvas := TcxScreenCanvas.Create;
|
|
InvertRect(ACanvas, cxRectOffset(FPrevInvertRect, AOffset));
|
|
InvertRect(ACanvas, cxRectOffset(Temp, AOffset));
|
|
ACanvas.Free;
|
|
FPrevInvertRect := R;
|
|
end;
|
|
|
|
procedure TcxSchedulerSplitterController.EraseInvertRect;
|
|
var
|
|
ACanvas: TcxCanvas;
|
|
begin
|
|
if cxRectIsEmpty(FPrevInvertRect) then Exit;
|
|
ACanvas := TcxScreenCanvas.Create;
|
|
InvertRect(ACanvas, cxRectOffset(FPrevInvertRect, ScreenOffset));
|
|
FPrevInvertRect := cxNullRect;
|
|
ACanvas.Free;
|
|
end;
|
|
|
|
function TcxSchedulerSplitterController.GetMonthSize: TSize;
|
|
begin
|
|
Result := Scheduler.DateNavigator.GetMonthSize;
|
|
end;
|
|
|
|
function TcxSchedulerSplitterController.GetOwnerMousePos(X, Y: Integer): TPoint;
|
|
begin
|
|
Result := cxPoint(X + Owner.Bounds.Left, Y + Owner.Bounds.Top);
|
|
end;
|
|
|
|
function TcxSchedulerSplitterController.GetSizingBoundsRect: TRect;
|
|
begin
|
|
Result := Scheduler.ClientBounds;
|
|
if Splitter.Kind = skHorizontal then
|
|
SetVertBounds(Result)
|
|
else
|
|
SetHorzBounds(Result);
|
|
end;
|
|
|
|
function TcxSchedulerSplitterController.GetSizingIncrement: Integer;
|
|
begin
|
|
if not IsIntegralSizing then
|
|
Result := 1
|
|
else
|
|
if Splitter.Kind = skVertical then
|
|
Result := GetMonthSize.cx
|
|
else
|
|
Result := GetMonthSize.cy;
|
|
end;
|
|
|
|
function TcxSchedulerSplitterController.GetSizingRect(const P: TPoint): TRect;
|
|
begin
|
|
if Splitter.Kind = skHorizontal then
|
|
Result := GetVertSizingRect(P)
|
|
else
|
|
Result := GetHorzSizingRect(P);
|
|
with SizingBoundsRect do
|
|
begin
|
|
if Result.Left < Left then
|
|
Result := cxRectSetLeft(Result, Left);
|
|
if Result.Top < Top then
|
|
Result := cxRectSetTop(Result, Top);
|
|
if Result.Right > Right then
|
|
Result := cxRectSetRight(Result, Right);
|
|
if Result.Bottom > Bottom then
|
|
Result := cxRectSetBottom(Result, Bottom);
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerSplitterController.InvertRect(ACanvas: TcxCanvas;
|
|
R: TRect);
|
|
begin
|
|
if cxRectIsEmpty(R) then Exit;
|
|
if Splitter.Kind = skHorizontal then
|
|
begin
|
|
R.Left := Max(R.Left, ScreenCanvasClipRect.Left);
|
|
R.Right := Min(R.Right, ScreenCanvasClipRect.Right);
|
|
end
|
|
else
|
|
begin
|
|
R.Top := Max(R.Top, ScreenCanvasClipRect.Top);
|
|
R.Bottom := Min(R.Bottom, ScreenCanvasClipRect.Bottom);
|
|
end;
|
|
if not cxRectIsEmpty(R) then
|
|
ACanvas.InvertRect(R);
|
|
end;
|
|
|
|
function TcxSchedulerSplitterController.IsIntegralSizing: Boolean;
|
|
begin
|
|
Result := Scheduler.OptionsCustomize.IntegralSizing;
|
|
end;
|
|
|
|
function TcxSchedulerSplitterController.IsDynamicUpdate: Boolean;
|
|
begin
|
|
Result := Scheduler.IsDynamicUpdate;
|
|
end;
|
|
|
|
procedure TcxSchedulerSplitterController.SetSizeDelta(ADelta: Integer);
|
|
begin
|
|
if Splitter.Kind = skHorizontal then
|
|
SetVertDelta(ADelta)
|
|
else
|
|
SetHorzDelta(ADelta);
|
|
Scheduler.Modified;
|
|
end;
|
|
|
|
procedure TcxSchedulerSplitterController.UpdateSizing(const R: TRect);
|
|
|
|
function GetDelta: Integer;
|
|
begin
|
|
if Splitter.Kind = skHorizontal then
|
|
Result := Splitter.Top - R.Top
|
|
else
|
|
Result := Splitter.Left - R.Left;
|
|
end;
|
|
|
|
var
|
|
ADelta: Integer;
|
|
begin
|
|
ADelta := GetDelta;
|
|
if ADelta <> 0 then
|
|
begin
|
|
SetSizeDelta(ADelta);
|
|
if IsDynamicUpdate then
|
|
Scheduler.Update;
|
|
Scheduler.DateNavigator.SaveSize;
|
|
end;
|
|
end;
|
|
|
|
function TcxSchedulerSplitterController.GetDrawClipRect: TRect;
|
|
var
|
|
AParent: TControl;
|
|
R: TRect;
|
|
begin
|
|
with Scheduler do
|
|
begin
|
|
Result := cxRectOffset(ClientBounds, ClientToScreen(cxNullPoint));
|
|
AParent := Parent;
|
|
end;
|
|
while AParent <> nil do
|
|
begin
|
|
R := cxRectOffset(AParent.ClientRect, AParent.ClientOrigin);
|
|
if AParent.Parent <> nil then
|
|
cxRectOffset(R, AParent.ClientToScreen(cxNullPoint));
|
|
cxRectIntersect(Result, Result, R);
|
|
AParent := AParent.Parent;
|
|
end;
|
|
end;
|
|
|
|
function TcxSchedulerSplitterController.GetHorzSizingRect(
|
|
const P: TPoint): TRect;
|
|
var
|
|
AStep, ANewPos: Integer;
|
|
begin
|
|
AStep := GetSizingIncrement;
|
|
ANewPos := FStartBounds.Left - Round((FHitPoint.X - P.X) / AStep) * AStep;
|
|
Result := cxRectSetLeft(FStartBounds, ANewPos);
|
|
end;
|
|
|
|
function TcxSchedulerSplitterController.GetScheduler: TcxCustomScheduler;
|
|
begin
|
|
Result := Owner.Scheduler;
|
|
end;
|
|
|
|
function TcxSchedulerSplitterController.GetScreenOffset: TPoint;
|
|
begin
|
|
Result := Scheduler.ClientToScreen(cxNullPoint);
|
|
end;
|
|
|
|
function TcxSchedulerSplitterController.GetSplitter: TcxSchedulerSplitter;
|
|
begin
|
|
Result := TcxSchedulerSplitter(inherited Owner);
|
|
end;
|
|
|
|
function TcxSchedulerSplitterController.GetVertSizingRect(
|
|
const P: TPoint): TRect;
|
|
var
|
|
AStep, ANewPos: Integer;
|
|
begin
|
|
AStep := GetSizingIncrement;
|
|
ANewPos := FStartBounds.Top - Round((FHitPoint.Y - P.Y) / AStep) * AStep;
|
|
Result := cxRectSetTop(FStartBounds, ANewPos);
|
|
end;
|
|
|
|
procedure TcxSchedulerSplitterController.SetHorzBounds(var R: TRect);
|
|
var
|
|
W: Integer;
|
|
begin
|
|
W := ((R.Right - R.Left - Splitter.Width) div GetMonthSize.cx) *
|
|
GetMonthSize.cx + Splitter.Width;
|
|
if Scheduler.IsViewAtLeft then
|
|
begin
|
|
if IsIntegralSizing then
|
|
R.Left := R.Right - W;
|
|
Dec(R.Right, GetMonthSize.cx);
|
|
end
|
|
else
|
|
begin
|
|
if IsIntegralSizing then
|
|
R.Right := R.Left + W;
|
|
Inc(R.Left, GetMonthSize.cx);
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerSplitterController.SetHorzDelta(ADelta: Integer);
|
|
begin
|
|
with Scheduler do
|
|
begin
|
|
case OptionsView.ViewPosition of
|
|
vpLeft:
|
|
DateNavigator.Width := DateNavigator.Width + ADelta;
|
|
else
|
|
DateNavigator.Width := DateNavigator.Width - ADelta;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerSplitterController.SetVertBounds(var R: TRect);
|
|
begin
|
|
if IsIntegralSizing then
|
|
R.Bottom := R.Top + ((R.Bottom - R.Top - Splitter.Height) div GetMonthSize.cy) *
|
|
GetMonthSize.cy + Splitter.Height;
|
|
Inc(R.Top, GetMonthSize.cy);
|
|
end;
|
|
|
|
procedure TcxSchedulerSplitterController.SetVertDelta(ADelta: Integer);
|
|
begin
|
|
with Scheduler do
|
|
begin
|
|
case OptionsView.ViewPosition of
|
|
vpLeft, vpRight, vpBottom:
|
|
DateNavigator.Height := DateNavigator.Height - ADelta;
|
|
vpTop:
|
|
DateNavigator.Height := DateNavigator.Height + ADelta;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
{ TcxSchedulerSplitterHitTest }
|
|
|
|
function TcxSchedulerSplitterHitTest.GetSplitter: TcxSchedulerSplitter;
|
|
begin
|
|
Result := TcxSchedulerSplitter(Owner);
|
|
end;
|
|
|
|
{ TcxSchedulerSplitter }
|
|
|
|
function TcxSchedulerSplitter.AllowDesignHitTest(
|
|
X, Y: Integer; AShift: TShiftState): Boolean;
|
|
begin
|
|
Result := True;
|
|
end;
|
|
|
|
function TcxSchedulerSplitter.CreateController: TcxSchedulerSubControlController;
|
|
begin
|
|
Result := TcxSchedulerSplitterController.Create(Self);
|
|
end;
|
|
|
|
function TcxSchedulerSplitter.CreateHitTest: TcxSchedulerSubControlHitTest;
|
|
begin
|
|
Result := TcxSchedulerSplitterHitTest.Create(Self);
|
|
end;
|
|
|
|
procedure TcxSchedulerSplitter.DoLayoutChanged;
|
|
begin
|
|
FViewParams := Styles.GetSplitterParams(Kind);
|
|
inherited DoLayoutChanged;
|
|
end;
|
|
|
|
procedure TcxSchedulerSplitter.DoPaint;
|
|
begin
|
|
LookAndFeelPainter.DrawSchedulerSplitterBorder(Canvas, ClientRect,
|
|
ViewParams, Kind = skHorizontal);
|
|
end;
|
|
|
|
function TcxSchedulerSplitter.GetHitTest: TcxSchedulerSplitterHitTest;
|
|
begin
|
|
Result := TcxSchedulerSplitterHitTest(inherited HitTest);
|
|
end;
|
|
|
|
procedure TcxSchedulerSplitter.UpdateCursor;
|
|
const
|
|
Cursors: array[TcxSchedulerSplitterKind] of TCursor = (
|
|
crSchedulerVertSplit, crSchedulerHorzSplit);
|
|
begin
|
|
if Scheduler.OptionsCustomize.ControlsSizing then
|
|
Cursor := Cursors[Kind]
|
|
else
|
|
Cursor := crDefault;
|
|
end;
|
|
|
|
procedure TcxSchedulerSplitter.SetKind(AKind: TcxSchedulerSplitterKind);
|
|
begin
|
|
FKind := AKind;
|
|
UpdateCursor;
|
|
end;
|
|
|
|
{ TcxSchedulerNavigatorButton }
|
|
|
|
constructor TcxSchedulerNavigatorButton.Create(Collection: TCollection);
|
|
begin
|
|
inherited Create(Collection);
|
|
FEnabled := True;
|
|
FCommand := -1;
|
|
FImageIndex := -1;
|
|
FVisible := True
|
|
end;
|
|
|
|
procedure TcxSchedulerNavigatorButton.Assign(Source: TPersistent);
|
|
begin
|
|
if Source is TcxSchedulerNavigatorButton then
|
|
with TcxSchedulerNavigatorButton(Source) do
|
|
begin
|
|
Self.Enabled := FEnabled;
|
|
Self.Hint := FHint;
|
|
Self.FCommand := FCommand;
|
|
Self.FImageIndex := FImageIndex;
|
|
Self.FVisible := FVisible;
|
|
end
|
|
else
|
|
inherited Assign(Source);
|
|
end;
|
|
|
|
procedure TcxSchedulerNavigatorButton.Changed;
|
|
begin
|
|
if (Scheduler <> nil) and (Scheduler.ResourceNavigator <> nil) and
|
|
Scheduler.ResourceNavigator.NeedScrollBar then Scheduler.LayoutChanged;
|
|
end;
|
|
|
|
procedure TcxSchedulerNavigatorButton.Click;
|
|
begin
|
|
Scheduler.ResourceNavigator.Click(Self);
|
|
end;
|
|
|
|
function TcxSchedulerNavigatorButton.GetDisplayName: string;
|
|
begin
|
|
Result := GetHintText;
|
|
if Result = '' then
|
|
Result := ClassName;
|
|
end;
|
|
|
|
function TcxSchedulerNavigatorButton.GetHintText: string;
|
|
const
|
|
InternalHint: array[0..7] of Pointer =
|
|
(@scxFirstButtonHint, @scxPrevPageButtonHint, @scxPrevButtonHint,
|
|
@scxNextButtonHint, @scxNextPageButtonHint, @scxLastButtonHint,
|
|
@scxShowMoreResourcesButtonHint, @scxShowFewerResourcesButtonHint);
|
|
begin
|
|
Result := Hint;
|
|
if (Result = '') and IsStandard then
|
|
Result := cxGetResourceString(InternalHint[Command]);
|
|
end;
|
|
|
|
procedure TcxSchedulerNavigatorButton.Draw(
|
|
APainter: TcxCustomLookAndFeelPainterClass; ACanvas: TcxCanvas);
|
|
var
|
|
AGlyphRect: TRect;
|
|
AImages: TCustomImageList;
|
|
AImageIndex: Integer;
|
|
begin
|
|
APainter.DrawSchedulerNavigatorButton(ACanvas, Bounds, State);
|
|
AImages := GetActualImageList;
|
|
AImageIndex := GetActualImageIndex;
|
|
if (AImages <> nil) and (AImageIndex >=0) then
|
|
begin
|
|
AGlyphRect := cxRectCenter(Bounds, cxSize(AImages.Width, AImages.Height));
|
|
if State = cxbsPressed then OffsetRect(AGlyphRect, 1, 1);
|
|
ACanvas.SaveState;
|
|
try
|
|
APainter.DrawNavigatorGlyph(ACanvas, AImages, AImageIndex, Command,
|
|
AGlyphRect, Enabled, not IsStandard or (ImageIndex >= 0));
|
|
finally
|
|
ACanvas.RestoreState;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TcxSchedulerNavigatorButton.GetState(
|
|
ACanDisabled: Boolean = True): TcxButtonState;
|
|
var
|
|
ANavigator: TcxSChedulerResourceNavigator;
|
|
begin
|
|
if not Enabled and ACanDisabled then
|
|
Result := cxbsDisabled
|
|
else
|
|
begin
|
|
ANavigator := Scheduler.ResourceNavigator;
|
|
if PtInRect(FBounds, ANavigator.ScreenToClient(GetMouseCursorPos)) and Application.Active then
|
|
begin
|
|
if ANavigator.FPressedButton = Self then
|
|
Result := cxbsPressed
|
|
else
|
|
Result := cxbsHot
|
|
end
|
|
else
|
|
Result := cxbsNormal;
|
|
end;
|
|
end;
|
|
|
|
function TcxSchedulerNavigatorButton.GetActualImageIndex: Integer;
|
|
const
|
|
AImageIndexMap: array[0..7] of Integer = (NBDI_FIRST, NBDI_PRIORPAGE,
|
|
NBDI_PRIOR, NBDI_NEXT, NBDI_NEXTPAGE, NBDI_LAST, NBDI_INSERT, NBDI_DELETE);
|
|
begin
|
|
if IsStandard and (ImageIndex < 0) then
|
|
begin
|
|
Result := AImageIndexMap[Command];
|
|
if FRotated and (Result < 6) then
|
|
Inc(Result, NavigatorButtonCount);
|
|
end
|
|
else
|
|
Result := ImageIndex;
|
|
end;
|
|
|
|
function TcxSchedulerNavigatorButton.GetActualImageList: TCustomImageList;
|
|
begin
|
|
if IsStandard and (ImageIndex < 0) then
|
|
Result := NavigatorImages
|
|
else
|
|
Result := Scheduler.ResourceNavigator.ButtonImages;
|
|
end;
|
|
|
|
function TcxSchedulerNavigatorButton.GetIsStandard: Boolean;
|
|
begin
|
|
Result := (Command >= cxSchedulerFirstButton) and
|
|
(Command <= cxSchedulerShowFewerResourcesButton);
|
|
end;
|
|
|
|
function TcxSchedulerNavigatorButton.GetScheduler: TcxCustomScheduler;
|
|
begin
|
|
if GetOwner <> nil then
|
|
Result := TcxSchedulerNavigatorCustomButtons(GetOwner).Scheduler
|
|
else
|
|
Result := nil;
|
|
end;
|
|
|
|
procedure TcxSchedulerNavigatorButton.SetEnabled(AValue: Boolean);
|
|
begin
|
|
if AValue <> FEnabled then
|
|
begin
|
|
FEnabled := AValue;
|
|
Scheduler.ResourceNavigator.InvalidateButton(Self);
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerNavigatorButton.SetImageIndex(AValue: Integer);
|
|
begin
|
|
AValue := Max(-1, AValue);
|
|
if AValue <> FImageIndex then
|
|
begin
|
|
FImageIndex := AValue;
|
|
Changed;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerNavigatorButton.SetVisible(AValue: Boolean);
|
|
begin
|
|
if AValue <> FVisible then
|
|
begin
|
|
FVisible := AValue;
|
|
Changed;
|
|
end;
|
|
end;
|
|
|
|
function TcxSchedulerNavigatorButton.IsHintStored: Boolean;
|
|
begin
|
|
Result := FHint <> '';
|
|
end;
|
|
|
|
function TcxSchedulerNavigatorButton.IsEnabledStored: Boolean;
|
|
begin
|
|
Result := not IsStandard and not Enabled;
|
|
end;
|
|
|
|
function TcxSchedulerNavigatorButton.IsVisibleStored: Boolean;
|
|
begin
|
|
if not IsStandard then
|
|
Result := not Visible
|
|
else
|
|
Result := Visible <> cxSchedulerNavigatorVisibility[Command];
|
|
end;
|
|
|
|
{ TcxSchedulerNavigatorCustomButtons }
|
|
|
|
constructor TcxSchedulerNavigatorCustomButtons.CreateEx(
|
|
AOwner: TPersistent; AItemClass: TCollectionItemClass);
|
|
begin
|
|
FOwner := AOwner;
|
|
inherited Create(AItemClass);
|
|
end;
|
|
|
|
function TcxSchedulerNavigatorCustomButtons.GetOwner: TPersistent;
|
|
begin
|
|
Result := FOwner;
|
|
end;
|
|
|
|
procedure TcxSchedulerNavigatorCustomButtons.Update(
|
|
Item: TCollectionItem);
|
|
begin
|
|
if (Scheduler <> nil) and not Scheduler.IsLocked then
|
|
Scheduler.LayoutChanged;
|
|
end;
|
|
|
|
function TcxSchedulerNavigatorCustomButtons.GetItem(
|
|
AIndex: Integer): TcxSchedulerNavigatorCustomButton;
|
|
begin
|
|
Result := TcxSchedulerNavigatorCustomButton(inherited Items[AIndex]);
|
|
end;
|
|
|
|
function TcxSchedulerNavigatorCustomButtons.GetVisibleCount: Integer;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
Result := 0;
|
|
for I := 0 to Count - 1 do
|
|
if Items[I].Visible then Inc(Result);
|
|
end;
|
|
|
|
procedure TcxSchedulerNavigatorCustomButtons.SetItem(
|
|
AIndex: Integer; AValue: TcxSchedulerNavigatorCustomButton);
|
|
begin
|
|
Items[AIndex].Assign(AValue);
|
|
end;
|
|
|
|
{ TcxSchedulerNavigatorButtons }
|
|
|
|
constructor TcxSchedulerNavigatorButtons.Create(
|
|
AOwner: TcxSchedulerResourceNavigator);
|
|
begin
|
|
FOwner := AOwner;
|
|
FButtons := TcxSchedulerNavigatorCustomButtons.CreateEx(AOwner,
|
|
TcxSchedulerNavigatorButton);
|
|
FButtons.FScheduler := FOwner.Scheduler;
|
|
CreateButtons;
|
|
end;
|
|
|
|
destructor TcxSchedulerNavigatorButtons.Destroy;
|
|
begin
|
|
FButtons.Free;
|
|
inherited Destroy;
|
|
end;
|
|
|
|
procedure TcxSchedulerNavigatorButtons.Assign(Source: TPersistent);
|
|
begin
|
|
if Source is TcxSchedulerNavigatorButtons then
|
|
FButtons.Assign(TcxSchedulerNavigatorButtons(Source).Buttons)
|
|
else
|
|
inherited Assign(Source);
|
|
end;
|
|
|
|
function TcxSchedulerNavigatorButtons.AddButton(
|
|
ACommand: Integer; AVisible: Boolean = True): TcxSchedulerNavigatorButton;
|
|
begin
|
|
Result := TcxSchedulerNavigatorButton(Buttons.Add);
|
|
Result.FCommand := ACommand;
|
|
Result.Visible := cxSchedulerNavigatorVisibility[ACommand];
|
|
end;
|
|
|
|
procedure TcxSchedulerNavigatorButtons.CreateButtons;
|
|
begin
|
|
AddButton(cxSchedulerFirstButton, True);
|
|
AddButton(cxSchedulerPrevPageButton);
|
|
AddButton(cxSchedulerPrevButton);
|
|
AddButton(cxSchedulerNextButton);
|
|
AddButton(cxSchedulerNextPageButton);
|
|
AddButton(cxSchedulerLastButton, True);
|
|
AddButton(cxSchedulerShowMoreResourcesButton);
|
|
AddButton(cxSchedulerShowFewerResourcesButton);
|
|
end;
|
|
|
|
function TcxSchedulerNavigatorButtons.GetOwner: TPersistent;
|
|
begin
|
|
Result := FOwner;
|
|
end;
|
|
|
|
function TcxSchedulerNavigatorButtons.GetButtonByIndex(
|
|
AIndex: Integer): TcxSchedulerNavigatorButton;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
Result := nil;
|
|
for I := 0 to Buttons.Count - 1 do
|
|
begin
|
|
Result := Buttons[I];
|
|
if Result.Command = AIndex then Break;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerNavigatorButtons.SetButtonByIndex(
|
|
AIndex: Integer; AValue: TcxSchedulerNavigatorButton);
|
|
begin
|
|
GetButtonByIndex(AIndex).Assign(AValue);
|
|
end;
|
|
|
|
{ TcxSchedulerResourceNavigatorController }
|
|
|
|
procedure TcxSchedulerResourceNavigatorController.BeforeMouseDown(
|
|
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
|
|
begin
|
|
HintController.HideHint;
|
|
inherited BeforeMouseDown(Button, Shift, X, Y);
|
|
end;
|
|
|
|
procedure TcxSchedulerResourceNavigatorController.CheckButtonDown(
|
|
Button: TMouseButton; Shift: TShiftState);
|
|
var
|
|
APressed: Boolean;
|
|
begin
|
|
HintController.ViewMode := False;
|
|
APressed := (Button = mbLeft) or (ssLeft in Shift);
|
|
if not APressed then
|
|
ResourceNavigator.FPressedButton := nil;
|
|
if APressed and (ResourceNavigator.FPressedButton = nil) then
|
|
ResourceNavigator.FPressedButton := GetHotTrackButton;
|
|
ResourceNavigator.Invalidate;
|
|
end;
|
|
|
|
function TcxSchedulerResourceNavigatorController.GetHotTrackButton(
|
|
ACanDisabled: Boolean = True): TcxSchedulerNavigatorButton;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
Result := nil;
|
|
for I := 0 to ResourceNavigator.ItemCount - 1 do
|
|
if ResourceNavigator.Items[I].GetState(ACanDisabled) = cxbsHot then
|
|
begin
|
|
Result := ResourceNavigator.Items[I];
|
|
Break;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerResourceNavigatorController.MouseDown(
|
|
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
|
|
begin
|
|
CheckButtonDown(Button, Shift);
|
|
inherited MouseDown(Button, Shift, X, Y);
|
|
end;
|
|
|
|
procedure TcxSchedulerResourceNavigatorController.MouseMove(
|
|
AShift: TShiftState; X, Y: Integer);
|
|
begin
|
|
HotTrackButton := GetHotTrackButton(False);
|
|
if ssLeft in AShift then
|
|
CheckButtonDown(mbLeft, AShift)
|
|
else
|
|
CheckButtonDown(mbRight, AShift);
|
|
end;
|
|
|
|
procedure TcxSchedulerResourceNavigatorController.MouseUp(
|
|
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
|
|
begin
|
|
with ResourceNavigator do
|
|
begin
|
|
if (FPressedButton <> nil) and (FPressedButton.GetState = cxbsPressed) then
|
|
FPressedButton.Click;
|
|
end;
|
|
CheckButtonDown(mbRight, Shift);
|
|
inherited MouseUp(Button, Shift, X, Y);
|
|
end;
|
|
|
|
procedure TcxSchedulerResourceNavigatorController.MouseEnter;
|
|
begin
|
|
HotTrackButton := nil;
|
|
ResourceNavigator.Invalidate;
|
|
end;
|
|
|
|
procedure TcxSchedulerResourceNavigatorController.MouseLeave;
|
|
begin
|
|
HotTrackButton := nil;
|
|
ResourceNavigator.Invalidate;
|
|
end;
|
|
|
|
function TcxSchedulerResourceNavigatorController.GetHintController: TcxSchedulerHintController;
|
|
begin
|
|
Result := Owner.Scheduler.HintController;
|
|
end;
|
|
|
|
function TcxSchedulerResourceNavigatorController.GetResourceNavigator: TcxSchedulerResourceNavigator;
|
|
begin
|
|
Result := TcxSchedulerResourceNavigator(Owner);
|
|
end;
|
|
|
|
procedure TcxSchedulerResourceNavigatorController.SetHotTrackButton(
|
|
Value: TcxSchedulerNavigatorButton);
|
|
var
|
|
AHintText: string;
|
|
AImmediate: Boolean;
|
|
begin
|
|
if Value <> FHotTrackButton then
|
|
begin
|
|
AImmediate := (FHotTrackButton <> nil) and HintController.Showing;
|
|
FHotTrackButton := Value;
|
|
if HotTrackButton <> nil then
|
|
begin
|
|
AHintText := HotTrackButton.GetHintText;
|
|
if AHintText <> '' then
|
|
begin
|
|
HintController.Activate(HintController.CalcHintRect(
|
|
cxscMaxHintWidth, AHintText, cxAlignBottom), AHintText, AImmediate);
|
|
end;
|
|
end
|
|
else
|
|
begin
|
|
HintController.Hide;
|
|
HintController.ViewMode := True;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
{ TcxSchedulerResourceNavigatorHitTest }
|
|
|
|
function TcxSchedulerResourceNavigatorHitTest.GetCurrentButton(AButtons: TcxSchedulerNavigatorCustomButtons): TcxSchedulerNavigatorButton;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
Result := nil;
|
|
for I := 0 to AButtons.Count - 1 do
|
|
if cxRectPtIn(AButtons[I].Bounds, HitPoint) then
|
|
begin
|
|
Result := AButtons[I];
|
|
Exit;
|
|
end;
|
|
end;
|
|
|
|
function TcxSchedulerResourceNavigatorHitTest.GetHitAtButton: Boolean;
|
|
begin
|
|
Result := GetHitButton <> nil;
|
|
end;
|
|
|
|
function TcxSchedulerResourceNavigatorHitTest.GetHitButton: TcxSchedulerNavigatorButton;
|
|
begin
|
|
with TcxSchedulerResourceNavigator(Owner) do
|
|
begin
|
|
Result := GetCurrentButton(Buttons.Buttons);
|
|
if not Assigned(Result) then
|
|
Result := GetCurrentButton(CustomButtons);
|
|
end;
|
|
end;
|
|
|
|
function TcxSchedulerResourceNavigatorHitTest.GetResourceNavigator: TcxSchedulerResourceNavigator;
|
|
begin
|
|
Result := TcxSchedulerResourceNavigator(Owner);
|
|
end;
|
|
|
|
{ TcxSchedulerResourceNavigator }
|
|
|
|
constructor TcxSchedulerResourceNavigator.Create(AOwner: TcxCustomScheduler);
|
|
begin
|
|
inherited Create(AOwner);
|
|
FTimer := TTimer.Create(Scheduler);
|
|
FButtons := CreateStandardButtons;
|
|
FCustomButtons := CreateButtons;
|
|
FCustomButtons.FScheduler := Scheduler;
|
|
FShowButtons := True;
|
|
FVisibility := snvAuto;
|
|
end;
|
|
|
|
destructor TcxSchedulerResourceNavigator.Destroy;
|
|
begin
|
|
FTimer.Free;
|
|
FButtons.Free;
|
|
FCustomButtons.Free;
|
|
inherited Destroy;
|
|
end;
|
|
|
|
procedure TcxSchedulerResourceNavigator.Assign(Source: TPersistent);
|
|
begin
|
|
if Source is TcxSchedulerResourceNavigator then
|
|
with TcxSchedulerResourceNavigator(Source) do
|
|
begin
|
|
Self.FShowButtons := FShowButtons;
|
|
Self.FVisibility := FVisibility;
|
|
Self.FButtonImages := FButtonImages;
|
|
Self.Buttons := Buttons;
|
|
end;
|
|
inherited Assign(Source);
|
|
end;
|
|
|
|
function TcxSchedulerResourceNavigator.NeedScrollBar: Boolean;
|
|
begin
|
|
Result := Visibility <> snvNever;
|
|
if (Scheduler.CurrentView = nil) or (Scheduler.CurrentView.GetGroupingKind = gkNone) then
|
|
Result := False;
|
|
if not Result or (Visibility = snvAlways) then Exit;
|
|
Result := (ResourceCount > 0) and (ResourcesPerPage > 0);
|
|
end;
|
|
|
|
procedure TcxSchedulerResourceNavigator.BoundsChanged;
|
|
begin
|
|
end;
|
|
|
|
procedure TcxSchedulerResourceNavigator.ButtonClickHandler(
|
|
AButton: TcxSchedulerNavigatorButton);
|
|
var
|
|
APrevIndex: Integer;
|
|
begin
|
|
APrevIndex := FirstVisibleResourceIndex;
|
|
case AButton.Command of
|
|
cxSchedulerFirstButton:
|
|
FirstVisibleResourceIndex := 0;
|
|
cxSchedulerPrevPageButton:
|
|
FirstVisibleResourceIndex := FirstVisibleResourceIndex - ResourcesPerPage;
|
|
cxSchedulerPrevButton:
|
|
FirstVisibleResourceIndex := FirstVisibleResourceIndex - 1;
|
|
cxSchedulerNextButton:
|
|
FirstVisibleResourceIndex := FirstVisibleResourceIndex + 1;
|
|
cxSchedulerNextPageButton:
|
|
FirstVisibleResourceIndex := FirstVisibleResourceIndex + ResourcesPerPage;
|
|
cxSchedulerLastButton:
|
|
FirstVisibleResourceIndex := ResourceCount;
|
|
cxSchedulerShowMoreResourcesButton:
|
|
ResourcesPerPage := ResourcesPerPage + 1;
|
|
cxSchedulerShowFewerResourcesButton:
|
|
ResourcesPerPage := ResourcesPerPage - 1;
|
|
end;
|
|
if APrevIndex <> FirstVisibleResourceIndex then
|
|
Scheduler.FirstVisibleResourceChanged;
|
|
end;
|
|
|
|
procedure TcxSchedulerResourceNavigator.CalculateBounds;
|
|
var
|
|
R: TRect;
|
|
begin
|
|
if Scheduler.CurrentView = nil then Exit;
|
|
R := Scheduler.CurrentView.Bounds;
|
|
if ScrollBarKind = sbHorizontal then
|
|
begin
|
|
R.Top := R.Bottom - Scheduler.HScrollBar.Height;
|
|
R.Right := R.Left + MeasureWidth;
|
|
end
|
|
else
|
|
begin
|
|
R.Top := R.Bottom - MeasureHeight;
|
|
R.Left := R.Right - Scheduler.VScrollBar.Width;
|
|
if Scheduler.SizeGrip.Visible then
|
|
OffsetRect(R, 0, -Scheduler.SizeGrip.Height);
|
|
end;
|
|
Bounds := R;
|
|
end;
|
|
|
|
procedure TcxSchedulerResourceNavigator.CheckButtonsState;
|
|
var
|
|
I: Integer;
|
|
AButton: TcxSchedulerNavigatorButton;
|
|
begin
|
|
for I := 0 to Buttons.Buttons.Count - 1 do
|
|
begin
|
|
AButton := Buttons.Buttons[I];
|
|
case AButton.Command of
|
|
cxSchedulerFirstButton, cxSchedulerPrevPageButton, cxSchedulerPrevButton:
|
|
AButton.Enabled := (ResourcesPerPage > 0) and (FirstVisibleResourceIndex > 0);
|
|
cxSchedulerNextButton, cxSchedulerNextPageButton, cxSchedulerLastButton:
|
|
AButton.Enabled := (ResourcesPerPage > 0) and
|
|
(FirstVisibleResourceIndex + ResourcesPerPage < ResourceCount);
|
|
cxSchedulerShowMoreResourcesButton:
|
|
AButton.Enabled := (ResourcesPerPage > 0) and
|
|
(ResourcesPerPage < ResourceCount) and (ResourceCount > 1);
|
|
cxSchedulerShowFewerResourcesButton:
|
|
AButton.Enabled := (ResourcesPerPage > 1) and (ResourceCount > 1);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerResourceNavigator.Click(
|
|
Sender: TcxSchedulerNavigatorButton);
|
|
begin
|
|
if not DoOnClick(Sender) and Sender.IsStandard then
|
|
ButtonClickHandler(Sender);
|
|
end;
|
|
|
|
function TcxSchedulerResourceNavigator.CreateController: TcxSchedulerSubControlController;
|
|
begin
|
|
Result := TcxSchedulerResourceNavigatorController.Create(Self);
|
|
end;
|
|
|
|
function TcxSchedulerResourceNavigator.CreateHitTest: TcxSchedulerSubControlHitTest;
|
|
begin
|
|
Result := TcxSchedulerResourceNavigatorHitTest.Create(Self);
|
|
end;
|
|
|
|
function TcxSchedulerResourceNavigator.CreateButtons: TcxSchedulerNavigatorCustomButtons;
|
|
begin
|
|
Result := TcxSchedulerNavigatorCustomButtons.CreateEx(Self, GetCustomButtonClass);
|
|
end;
|
|
|
|
function TcxSchedulerResourceNavigator.CreateStandardButtons: TcxSchedulerNavigatorButtons;
|
|
begin
|
|
Result := TcxSchedulerNavigatorButtons.Create(Self);
|
|
end;
|
|
|
|
function TcxSchedulerResourceNavigator.DoCustomDrawButton(
|
|
AButton: TcxSchedulerNavigatorButton): Boolean;
|
|
begin
|
|
Result := False;
|
|
if Assigned(FOnCustomDrawButton) then
|
|
OnCustomDrawButton(Self, Canvas, AButton, Result);
|
|
end;
|
|
|
|
function TcxSchedulerResourceNavigator.DoOnClick(
|
|
Sender: TcxSchedulerNavigatorButton): Boolean;
|
|
begin
|
|
Result := False;
|
|
if Assigned(FOnButtonClick) then
|
|
FOnButtonClick(Self, Sender, Result);
|
|
end;
|
|
|
|
procedure TcxSchedulerResourceNavigator.DoPaint;
|
|
var
|
|
R: TRect;
|
|
ASize: TSize;
|
|
I, AIndex: Integer;
|
|
AButton: TcxSchedulerNavigatorButton;
|
|
begin
|
|
FVisibleButtonCount := GetVisibleButtonCount;
|
|
if VisibleButtonCount = 0 then Exit;
|
|
CheckButtonsState;
|
|
Canvas.Brush.Color := LookAndFeelPainter.DefaultSchedulerNavigatorColor;
|
|
Canvas.FillRect(ClientRect);
|
|
|
|
ASize := ButtonSize;
|
|
AIndex := 0;
|
|
R := Rect(0, 0, ASize.cx, ASize.cy);
|
|
if ScrollBarKind <> sbHorizontal then
|
|
OffsetRect(R, (VisibleButtonCount - 1) * ASize.cx, 0);
|
|
for I := 0 to ItemCount - 1 do
|
|
begin
|
|
AButton := Items[I];
|
|
if AButton.Visible then
|
|
begin
|
|
AButton.FVisibleIndex := AIndex;
|
|
AButton.FBounds := LookAndFeelPainter.AdjustGroupButtonDisplayRect(
|
|
R, AIndex, VisibleButtonCount);
|
|
AButton.FRotated := ScrollBarKind <> sbHorizontal;
|
|
if AButton.FRotated then
|
|
AButton.FBounds := Rect(0, ASize.cx * AIndex, ASize.cy, ASize.cx * (AIndex + 1))
|
|
else
|
|
AButton.FBounds := Rect(ASize.cx * AIndex, 0, ASize.cx * (AIndex + 1), ASize.cy);
|
|
OffsetRect(R, (Byte(ScrollBarKind = sbHorizontal) * 2 - 1) * ASize.cx, 0);
|
|
AButton.FState := AButton.GetState;
|
|
|
|
if not DoCustomDrawButton(AButton) then
|
|
AButton.Draw(LookAndFeelPainter, Canvas);
|
|
|
|
Inc(AIndex);
|
|
end
|
|
else
|
|
begin
|
|
AButton.FBounds := cxNullRect;
|
|
AButton.FVisibleIndex := -1;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerResourceNavigator.FirstVisibleResourceChanged;
|
|
begin
|
|
CheckButtonsState;
|
|
end;
|
|
|
|
function TcxSchedulerResourceNavigator.GetCustomButtonClass: TcxSchedulerNavigatorButtonClass;
|
|
begin
|
|
Result := TcxSchedulerNavigatorCustomButton;
|
|
end;
|
|
|
|
function TcxSchedulerResourceNavigator.GetScrollerHint: string;
|
|
var
|
|
AIndex1, AIndex2: Integer;
|
|
AResources: TcxSchedulerStorageResourceItems;
|
|
begin
|
|
AIndex1 := Max(0, FirstVisibleResourceIndex);
|
|
AIndex2 := Min(FirstVisibleResourceIndex + ResourcesPerPage - 1, ResourceCount - 1);
|
|
AResources := Scheduler.Storage.Resources.ResourceItems;
|
|
Result := AResources.VisibleResources[AIndex1].Name;
|
|
if AIndex2 > AIndex1 then
|
|
Result := Result + ' - ' + AResources.VisibleResources[AIndex2].Name;
|
|
end;
|
|
|
|
procedure TcxSchedulerResourceNavigator.InitScrollBarsParameters;
|
|
begin
|
|
inherited Visible := NeedScrollBar;
|
|
if not NeedScrollBar then
|
|
SetScrollBarInfo(ScrollBarKind, 0, 1, 1, 0, 1, False, True)
|
|
else
|
|
begin
|
|
if (ResourcesPerPage = 0) or (ResourceCount = 0) then
|
|
SetScrollBarInfo(ScrollBarKind, 0, 0, 1, 1, 0, True, Visibility = snvAuto)
|
|
else
|
|
SetScrollBarInfo(ScrollBarKind, 0, ResourceCount - 1, 1,
|
|
ResourcesPerPage, FirstVisibleResourceIndex, True, False);
|
|
CalculateBounds;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerResourceNavigator.InvalidateButton(
|
|
AButton: TcxSchedulerNavigatorButton);
|
|
begin
|
|
if AButton.Visible and (AButton.GetState <> AButton.State) then
|
|
InvalidateRect(AButton.Bounds);
|
|
end;
|
|
|
|
procedure TcxSchedulerResourceNavigator.Scroll(
|
|
AScrollCode: TScrollCode; var AScrollPos: Integer);
|
|
var
|
|
AFirstResourceChanged: Boolean;
|
|
begin
|
|
Scheduler.CurrentView.HideHintOnScroll(AScrollCode);
|
|
if AScrollCode = scEndScroll then Exit;
|
|
if not (AScrollCode in [scPosition, scTrack]) then
|
|
AScrollPos := FirstVisibleResourceIndex;
|
|
case AScrollCode of
|
|
scLineUp:
|
|
Dec(AScrollPos, 1);
|
|
scLineDown:
|
|
Inc(AScrollPos, 1);
|
|
scPageUp:
|
|
Dec(AScrollPos, ResourcesPerPage);
|
|
scPageDown:
|
|
Inc(AScrollPos, ResourcesPerPage);
|
|
scTop:
|
|
AScrollPos := 0;
|
|
scBottom:
|
|
AScrollPos := ResourceCount;
|
|
end;
|
|
if (AScrollPos + ResourcesPerPage) > (ResourceCount - 1) then
|
|
AScrollPos := ResourceCount - ResourcesPerPage;
|
|
if AScrollPos < 0 then
|
|
AScrollPos := 0;
|
|
if (AScrollPos <> FirstVisibleResourceIndex) or (AScrollCode = scTrack) then
|
|
begin
|
|
AFirstResourceChanged := AScrollPos <> FirstVisibleResourceIndex;
|
|
Scheduler.FFirstVisibleResourceIndex := AScrollPos;
|
|
if AScrollCode = scTrack then
|
|
Scheduler.CurrentView.ShowHintOnScroll(GetScrollerHint, ScrollBarKind);
|
|
if ScrollBarKind = sbHorizontal then
|
|
Scheduler.HScrollBar.Position := AScrollPos
|
|
else
|
|
Scheduler.VScrollBar.Position := AScrollPos;
|
|
Scheduler.CurrentView.Refresh;
|
|
if AFirstResourceChanged then
|
|
Scheduler.FirstVisibleResourceChanged;
|
|
end;
|
|
end;
|
|
|
|
function TcxSchedulerResourceNavigator.ActualCountPerPage: Integer;
|
|
begin
|
|
if ResourcesPerPage = 0 then
|
|
Result := Max(0, ResourceCount)
|
|
else
|
|
Result := Min(ResourcesPerPage, ResourceCount - 1);
|
|
end;
|
|
|
|
function TcxSchedulerResourceNavigator.ActualFirstResourceIndex: Integer;
|
|
begin
|
|
Result := Max(0, FirstVisibleResourceIndex);
|
|
Result := Min(Result - 1, ResourceCount);
|
|
end;
|
|
|
|
function TcxSchedulerResourceNavigator.ButtonSize: TSize;
|
|
begin
|
|
if ScrollBarKind = sbHorizontal then
|
|
begin
|
|
Result.cx := (Scheduler.HScrollBar.Height + cxTextOffset);
|
|
Result.cy := Scheduler.HScrollBar.Height {+ Scheduler.BorderSize};
|
|
end
|
|
else
|
|
begin
|
|
Result.cx := (Scheduler.VScrollBar.Width + cxTextOffset);
|
|
Result.cy := Scheduler.VScrollBar.Width {+ Scheduler.BorderSize};
|
|
end;
|
|
end;
|
|
|
|
function TcxSchedulerResourceNavigator.MeasureHeight: Integer;
|
|
begin
|
|
Result := GetVisibleButtonCount * ButtonSize.cx;
|
|
end;
|
|
|
|
function TcxSchedulerResourceNavigator.MeasureWidth: Integer;
|
|
begin
|
|
Result := GetVisibleButtonCount * ButtonSize.cx;
|
|
end;
|
|
|
|
function TcxSchedulerResourceNavigator.GetVisibleButtonCount: Integer;
|
|
begin
|
|
if ShowButtons then
|
|
Result := Buttons.Buttons.VisibleCount + CustomButtons.VisibleCount
|
|
else
|
|
Result := 0;
|
|
end;
|
|
|
|
function TcxSchedulerResourceNavigator.GetItemCount: Integer;
|
|
begin
|
|
Result := Buttons.Buttons.Count + CustomButtons.Count;
|
|
end;
|
|
|
|
function TcxSchedulerResourceNavigator.GetFirstVisibleResourceIndex: Integer;
|
|
begin
|
|
Result := Scheduler.FirstVisibleResourceIndex;
|
|
end;
|
|
|
|
function TcxSchedulerResourceNavigator.GetHitTest: TcxSchedulerResourceNavigatorHitTest;
|
|
begin
|
|
Result := TcxSchedulerResourceNavigatorHitTest(inherited HitTest);
|
|
end;
|
|
|
|
function TcxSchedulerResourceNavigator.GetItem(AIndex: Integer): TcxSchedulerNavigatorButton;
|
|
begin
|
|
if AIndex < Buttons.Buttons.Count then
|
|
Result := Buttons.Buttons[AIndex]
|
|
else
|
|
Result := CustomButtons[AIndex - Buttons.Buttons.Count];
|
|
end;
|
|
|
|
function TcxSchedulerResourceNavigator.GetResourceCount: Integer;
|
|
begin
|
|
with Scheduler do
|
|
begin
|
|
if (CurrentView <> nil) and (CurrentView.Resources <> nil) then
|
|
Result := CurrentView.Resources.VisibleResourceCount
|
|
else
|
|
Result := 0;
|
|
end;
|
|
end;
|
|
|
|
function TcxSchedulerResourceNavigator.GetResourcesPerPage: Integer;
|
|
begin
|
|
Result := Scheduler.OptionsView.ResourcesPerPage;
|
|
end;
|
|
|
|
procedure TcxSchedulerResourceNavigator.SetCustomButtons(
|
|
Value: TcxSchedulerNavigatorCustomButtons);
|
|
begin
|
|
FCustomButtons.Assign(Value);
|
|
end;
|
|
|
|
procedure TcxSchedulerResourceNavigator.SetButtonImages(Value: TCustomImageList);
|
|
begin
|
|
FButtonImages := Value;
|
|
Scheduler.LayoutChanged;
|
|
end;
|
|
|
|
procedure TcxSchedulerResourceNavigator.SetButtons(
|
|
Value: TcxSchedulerNavigatorButtons);
|
|
begin
|
|
FButtons.Assign(Value);
|
|
end;
|
|
|
|
procedure TcxSchedulerResourceNavigator.SetResourcesPerPage(AValue: Integer);
|
|
begin
|
|
Scheduler.OptionsView.ResourcesPerPage := AValue;
|
|
end;
|
|
|
|
procedure TcxSchedulerResourceNavigator.SetShowButtons(AValue: Boolean);
|
|
begin
|
|
if AValue <> FShowButtons then
|
|
begin
|
|
FShowButtons := AValue;
|
|
Scheduler.LayoutChanged;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerResourceNavigator.SetFirstVisibleResourceIndex(AValue: Integer);
|
|
begin
|
|
Scheduler.FirstVisibleResourceIndex := AValue;
|
|
end;
|
|
|
|
procedure TcxSchedulerResourceNavigator.SetVisibility(
|
|
AValue: TcxSchedulerNavigatorVisibilityMode);
|
|
begin
|
|
if AValue <> FVisibility then
|
|
begin
|
|
FVisibility := AValue;
|
|
Changed;
|
|
end;
|
|
end;
|
|
|
|
function TcxSchedulerResourceNavigator.IsCustomButtonsStored: Boolean;
|
|
begin
|
|
Result := CustomButtons.Count > 0;
|
|
end;
|
|
|
|
{ TcxSchedulerEventOperations }
|
|
|
|
constructor TcxSchedulerEventOperations.Create(
|
|
AOwner: TcxCustomScheduler);
|
|
begin
|
|
FScheduler := AOwner;
|
|
FCreating := True;
|
|
FDeleting := True;
|
|
FDialogEditing := True;
|
|
FDialogShowing := True;
|
|
FInplaceEditing := True;
|
|
FIntersection := True;
|
|
FMoving := True;
|
|
FMovingBetweenResources := True;
|
|
FReadOnly := False;
|
|
FRecurrence := True;
|
|
FSizing := True;
|
|
end;
|
|
|
|
procedure TcxSchedulerEventOperations.Assign(Source: TPersistent);
|
|
begin
|
|
if Source is TcxSchedulerEventOperations then
|
|
with TcxSchedulerEventOperations(Source) do
|
|
begin
|
|
Self.FCreating := FCreating;
|
|
Self.FDeleting := FDeleting;
|
|
Self.FDialogEditing := FDialogEditing;
|
|
Self.FDialogShowing := FDialogShowing;
|
|
Self.FInplaceEditing := FInplaceEditing;
|
|
Self.FMoving := FMoving;
|
|
Self.FMovingBetweenResources := FMovingBetweenResources;
|
|
Self.FReadOnly := FReadOnly;
|
|
Self.FRecurrence := FRecurrence;
|
|
Self.FSharingBetweenResources := FSharingBetweenResources;
|
|
Self.FSizing := FSizing;
|
|
Self.FIntersection := FIntersection;
|
|
end
|
|
else
|
|
inherited Assign(Source);
|
|
end;
|
|
|
|
function TcxSchedulerEventOperations.GetOwner: TPersistent;
|
|
begin
|
|
Result := FScheduler;
|
|
end;
|
|
|
|
function TcxSchedulerEventOperations.GetCreating: Boolean;
|
|
begin
|
|
Result := not FReadOnly and FCreating;
|
|
end;
|
|
|
|
function TcxSchedulerEventOperations.GetCreatingStored: Boolean;
|
|
begin
|
|
Result := not (FReadOnly or FCreating);
|
|
end;
|
|
|
|
function TcxSchedulerEventOperations.GetDeleting: Boolean;
|
|
begin
|
|
Result := not FReadOnly and FDeleting;
|
|
end;
|
|
|
|
function TcxSchedulerEventOperations.GetDeletingStored: Boolean;
|
|
begin
|
|
Result := not (FReadOnly or FDeleting);
|
|
end;
|
|
|
|
function TcxSchedulerEventOperations.GetDialogEditing: Boolean;
|
|
begin
|
|
Result := not FReadOnly and FDialogEditing;
|
|
end;
|
|
|
|
function TcxSchedulerEventOperations.GetDialogEditingStored: Boolean;
|
|
begin
|
|
Result := not (FReadOnly or FDialogEditing);
|
|
end;
|
|
|
|
function TcxSchedulerEventOperations.GetInplaceEditing: Boolean;
|
|
begin
|
|
Result := not FReadOnly and FInplaceEditing;
|
|
end;
|
|
|
|
function TcxSchedulerEventOperations.GetInplaceEditingStored: Boolean;
|
|
begin
|
|
Result := not (FReadOnly or FInplaceEditing);
|
|
end;
|
|
|
|
function TcxSchedulerEventOperations.GetMoving: Boolean;
|
|
begin
|
|
Result := not FReadOnly and FMoving;
|
|
end;
|
|
|
|
function TcxSchedulerEventOperations.GetMovingBetweenResources: Boolean;
|
|
begin
|
|
Result := not FReadOnly and FMovingBetweenResources;
|
|
end;
|
|
|
|
function TcxSchedulerEventOperations.GetMovingBetweenResourcesStored: Boolean;
|
|
begin
|
|
Result := not (FReadOnly or FMovingBetweenResources);
|
|
end;
|
|
|
|
function TcxSchedulerEventOperations.GetMovingStored: Boolean;
|
|
begin
|
|
Result := not (FReadOnly or FMoving);
|
|
end;
|
|
|
|
function TcxSchedulerEventOperations.GetSizing: Boolean;
|
|
begin
|
|
Result := not FReadOnly and FSizing;
|
|
end;
|
|
|
|
function TcxSchedulerEventOperations.GetSizingStored: Boolean;
|
|
begin
|
|
Result := not (FReadOnly or FSizing);
|
|
end;
|
|
|
|
{ TcxSchedulerOptionsCustomize }
|
|
|
|
constructor TcxSchedulerOptionsCustomize.Create(
|
|
AOwner: TcxCustomScheduler);
|
|
begin
|
|
FScheduler := AOwner;
|
|
FControlsSizing := True;
|
|
FIntegralSizing := True;
|
|
end;
|
|
|
|
procedure TcxSchedulerOptionsCustomize.Assign(Source: TPersistent);
|
|
var
|
|
ASourceOptionsCustomize: TcxSchedulerOptionsCustomize;
|
|
begin
|
|
if Source is TcxSchedulerOptionsCustomize then
|
|
begin
|
|
ASourceOptionsCustomize := TcxSchedulerOptionsCustomize(Source);
|
|
FControlsSizing := ASourceOptionsCustomize.ControlsSizing;
|
|
FDynamicSizing := ASourceOptionsCustomize.DynamicSizing;
|
|
IntegralSizing := ASourceOptionsCustomize.IntegralSizing;
|
|
end
|
|
else
|
|
inherited Assign(Source);
|
|
end;
|
|
|
|
procedure TcxSchedulerOptionsCustomize.Changed;
|
|
begin
|
|
FScheduler.LayoutChanged;
|
|
end;
|
|
|
|
function TcxSchedulerOptionsCustomize.GetOwner: TPersistent;
|
|
begin
|
|
Result := FScheduler;
|
|
end;
|
|
|
|
procedure TcxSchedulerOptionsCustomize.SetControlsSizing(AValue: Boolean);
|
|
begin
|
|
FControlsSizing := AValue;
|
|
Scheduler.HorzSplitter.UpdateCursor;
|
|
Scheduler.VertSplitter.UpdateCursor;
|
|
end;
|
|
|
|
procedure TcxSchedulerOptionsCustomize.SetIntegralSizing(AValue: Boolean);
|
|
begin
|
|
if AValue <> FIntegralSizing then
|
|
begin
|
|
FIntegralSizing := AValue;
|
|
if AValue then
|
|
Scheduler.DateNavigator.SetIntegralSizes;
|
|
Changed;
|
|
end;
|
|
end;
|
|
|
|
{ TcxSchedulerResourceHeaders }
|
|
|
|
constructor TcxSchedulerResourceHeaders.Create(AOwner: TcxSchedulerOptionsView);
|
|
begin
|
|
FRotateCaptions := True;
|
|
FOwner := AOwner;
|
|
end;
|
|
|
|
procedure TcxSchedulerResourceHeaders.Assign(Source: TPersistent);
|
|
begin
|
|
if Source is TcxSchedulerResourceHeaders then
|
|
begin
|
|
FHeight := TcxSchedulerResourceHeaders(Source).FHeight;
|
|
FImagePosition := TcxSchedulerResourceHeaders(Source).FImagePosition;
|
|
FMultilineCaptions := TcxSchedulerResourceHeaders(Source).FMultilineCaptions;
|
|
FRotateCaptions := TcxSchedulerResourceHeaders(Source).FRotateCaptions;
|
|
end
|
|
else
|
|
inherited;
|
|
end;
|
|
|
|
procedure TcxSchedulerResourceHeaders.Changed;
|
|
begin
|
|
FOwner.Changed;
|
|
end;
|
|
|
|
function TcxSchedulerResourceHeaders.GetOwner: TPersistent;
|
|
begin
|
|
Result := FOwner;
|
|
end;
|
|
|
|
procedure TcxSchedulerResourceHeaders.SetHeight(AValue: Integer);
|
|
begin
|
|
if AValue <> FHeight then
|
|
begin
|
|
FHeight := AValue;
|
|
Changed;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerResourceHeaders.SetImagePosition(
|
|
AValue: TcxSchedulerHeaderImagePosition);
|
|
begin
|
|
if AValue <> FImagePosition then
|
|
begin
|
|
FImagePosition := AValue;
|
|
Changed;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerResourceHeaders.SetMultilineCaptions(AValue: Boolean);
|
|
begin
|
|
if AValue <> FMultilineCaptions then
|
|
begin
|
|
FMultilineCaptions := AValue;
|
|
|
|
Changed;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerResourceHeaders.SetRotateCations(AValue: Boolean);
|
|
begin
|
|
if AValue <> FRotateCaptions then
|
|
begin
|
|
FRotateCaptions := AValue;
|
|
Changed;
|
|
end;
|
|
end;
|
|
|
|
function TcxSchedulerResourceHeaders.IsImagePositionStored: Boolean;
|
|
begin
|
|
Result := FImagePosition <> ipLeft;
|
|
end;
|
|
|
|
{ TcxSchedulerOptionsView }
|
|
|
|
constructor TcxSchedulerOptionsView.Create(
|
|
AOwner: TcxCustomScheduler);
|
|
begin
|
|
FScheduler := AOwner;
|
|
FTimeZones[0] := -1;
|
|
FTimeZones[1] := -1;
|
|
FDayBorderColor := clDefault;
|
|
FEventHeight := 0;
|
|
FEventBorderColor := clBlack;
|
|
FGroupSeparatorWidth := cxDefaultGroupSeparatorWidth;
|
|
FHorzSplitterWidth := cxDefaultSplitterWidth;
|
|
FVertSplitterWidth := cxDefaultSplitterWidth;
|
|
FHideSelection := False;
|
|
FHotTrack := False; //for the next version True;
|
|
FResourceHeaders := TcxSchedulerResourceHeaders.Create(Self);
|
|
FWorkDays := DateTimeHelper.WorkDays;
|
|
FStartOfWeek := swSystem;
|
|
CalculateActualStartOfWeek;
|
|
FWorkFinish := DateTimeHelper.WorkFinish;
|
|
FWorkStart := DateTimeHelper.WorkStart;
|
|
FViewPosition := vpLeft;
|
|
FResourcesPerPage := cxDefaultResourcesPerPage;
|
|
ShowHints := True;
|
|
ShowNavigationButtons := True;
|
|
end;
|
|
|
|
destructor TcxSchedulerOptionsView.Destroy;
|
|
begin
|
|
FResourceHeaders.Free;
|
|
inherited Destroy;
|
|
end;
|
|
|
|
procedure TcxSchedulerOptionsView.Assign(
|
|
Source: TPersistent);
|
|
var
|
|
AItem: Integer;
|
|
ASourceOptionsView: TcxSchedulerOptionsView;
|
|
begin
|
|
if Source is TcxSchedulerOptionsView then
|
|
begin
|
|
ASourceOptionsView := TcxSchedulerOptionsView(Source);
|
|
for AItem := 0 to 1 do
|
|
begin
|
|
FTimeZones[AItem] := ASourceOptionsView.FTimeZones[AItem];
|
|
FTimeZoneLabels[AItem] := ASourceOptionsView.FTimeZoneLabels[AItem];
|
|
end;
|
|
FResourcesPerPage := ASourceOptionsView.FResourcesPerPage;
|
|
FDayBorderColor := ASourceOptionsView.DayBorderColor;
|
|
FEventBorderColor := ASourceOptionsView.EventBorderColor;
|
|
FEventHeight := ASourceOptionsView.EventHeight;
|
|
FGroupingKind := ASourceOptionsView.FGroupingKind;
|
|
FGroupSeparatorWidth := ASourceOptionsView.FGroupSeparatorWidth;
|
|
FHideSelection := ASourceOptionsView.HideSelection;
|
|
FHorzSplitterWidth := ASourceOptionsView.FHorzSplitterWidth;
|
|
FHotTrack := ASourceOptionsView.HotTrack;
|
|
FResourceHeaders.Assign(ASourceOptionsView.ResourceHeaders);
|
|
FShowHints := ASourceOptionsView.ShowHints;
|
|
FShowNavigationButtons := ASourceOptionsView.FShowNavigationButtons;
|
|
FVertSplitterWidth := ASourceOptionsView.FVertSplitterWidth;
|
|
FViewPosition := ASourceOptionsView.ViewPosition;
|
|
FWorkDays := ASourceOptionsView.WorkDays;
|
|
FWorkFinish := ASourceOptionsView.WorkFinish;
|
|
FWorkStart := ASourceOptionsView.WorkStart;
|
|
end
|
|
else
|
|
inherited Assign(Source);
|
|
end;
|
|
|
|
procedure TcxSchedulerOptionsView.CalculateActualStartOfWeek;
|
|
begin
|
|
if FStartOfWeek = swSystem then
|
|
FActualStartOfWeek := TDay(DateTimeHelper.StartOfWeek)
|
|
else
|
|
FActualStartOfWeek := TDay(Pred(FStartOfWeek));
|
|
end;
|
|
|
|
procedure TcxSchedulerOptionsView.Changed;
|
|
begin
|
|
Scheduler.LayoutChanged;
|
|
end;
|
|
|
|
procedure TcxSchedulerOptionsView.DefineProperties(Filer: TFiler);
|
|
begin
|
|
inherited DefineProperties(Filer);
|
|
Filer.DefineProperty('WorkStart', ReadWorkStart, WriteWorkStart, FWorkStartAssigned);
|
|
Filer.DefineProperty('WorkFinish', ReadWorkFinish, WriteWorkFinish, FWorkFinishAssigned);
|
|
end;
|
|
|
|
function TcxSchedulerOptionsView.GetOwner: TPersistent;
|
|
begin
|
|
Result := FScheduler;
|
|
end;
|
|
|
|
function TcxSchedulerOptionsView.IsWorkDaysStored: Boolean;
|
|
begin
|
|
Result := FWorkDays <> DateTimeHelper.WorkDays;
|
|
end;
|
|
|
|
function TcxSchedulerOptionsView.IsWorkTime(AResourceItem: TcxSchedulerStorageResourceItem;
|
|
const ADateTime: TDateTime): Boolean;
|
|
var
|
|
AWorkDays: TDays;
|
|
AWorkFinish: TTime;
|
|
AWorkStart: TTime;
|
|
begin
|
|
if Assigned(AResourceItem) then
|
|
begin
|
|
AWorkDays := AResourceItem.WorkDays;
|
|
AWorkFinish := AResourceItem.WorkFinish;
|
|
AWorkStart := AResourceItem.WorkStart;
|
|
end
|
|
else
|
|
begin
|
|
AWorkDays := WorkDays;
|
|
AWorkStart := WorkStart;
|
|
AWorkFinish := WorkFinish;
|
|
end;
|
|
|
|
Result := (TDay(DayOfWeek(ADateTime) - 1) in AWorkDays);
|
|
if Result then
|
|
begin
|
|
if AWorkStart < AWorkFinish then
|
|
Result := ((DateTimeHelper.RoundTime(TimeOf(ADateTime)) >= AWorkStart) and
|
|
(DateTimeHelper.RoundTime(TimeOf(ADateTime)) < AWorkFinish))
|
|
else
|
|
Result := ((DateTimeHelper.RoundTime(TimeOf(ADateTime)) >= AWorkStart) or
|
|
(DateTimeHelper.RoundTime(TimeOf(ADateTime)) < AWorkFinish))
|
|
end;
|
|
end;
|
|
|
|
function TcxSchedulerOptionsView.GetDateTimeHelperClass: TcxSchedulerDateTimeHelperClass;
|
|
begin
|
|
Result := Scheduler.DateTimeHelper;
|
|
end;
|
|
|
|
function TcxSchedulerOptionsView.GetRotateResourceCaptions: Boolean;
|
|
begin
|
|
Result := FResourceHeaders.RotateCaptions;
|
|
end;
|
|
|
|
function TcxSchedulerOptionsView.GetTimeZone(
|
|
AIndex: Integer): Integer;
|
|
begin
|
|
Result := FTimeZones[AIndex];
|
|
if (Result < 0) or (Result >= DateTimeHelper.TimeZoneCount) then
|
|
Result := -1;
|
|
end;
|
|
|
|
function TcxSchedulerOptionsView.GetTimeZoneLabel(
|
|
AIndex: Integer): string;
|
|
begin
|
|
Result := FTimeZoneLabels[AIndex];
|
|
end;
|
|
|
|
function TcxSchedulerOptionsView.IsTimeZoneLabelStored(
|
|
AIndex: Integer): Boolean;
|
|
begin
|
|
Result := FTimeZoneLabels[AIndex] <> '';
|
|
end;
|
|
|
|
procedure TcxSchedulerOptionsView.SetATZDaylightSaving(AValue: Boolean);
|
|
begin
|
|
if AValue <> FAdditionalTimeZoneDaylightSaving then
|
|
begin
|
|
FAdditionalTimeZoneDaylightSaving := AValue;
|
|
Scheduler.FullRefresh;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerOptionsView.SetCTZDaylightSaving(AValue: Boolean);
|
|
begin
|
|
if AValue <> FCurrentTimeZoneDaylightSaving then
|
|
begin
|
|
FCurrentTimeZoneDaylightSaving := AValue;
|
|
Scheduler.FullRefresh;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerOptionsView.SetDayBorderColor(AValue: TColor);
|
|
begin
|
|
if AValue <> FDayBorderColor then
|
|
begin
|
|
FDayBorderColor := AValue;
|
|
Changed;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerOptionsView.SetEventBorderColor(AValue: TColor);
|
|
begin
|
|
if AValue <> FEventBorderColor then
|
|
begin
|
|
FEventBorderColor := AValue;
|
|
Changed;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerOptionsView.SetEventHeight(AValue: Integer);
|
|
begin
|
|
if AValue < 0 then AValue := 0;
|
|
if AValue <> FEventHeight then
|
|
begin
|
|
FEventHeight := AValue;
|
|
Changed;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerOptionsView.SetGroupingKind(
|
|
AValue: TcxSchedulerGroupingKind);
|
|
begin
|
|
if FGroupingKind <> AValue then
|
|
begin
|
|
FGroupingKind := AValue;
|
|
Changed;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerOptionsView.SetGroupSeparatorWidth(
|
|
AValue: Integer);
|
|
begin
|
|
FGroupSeparatorWidth := Max(0, AValue);
|
|
Changed;
|
|
end;
|
|
|
|
procedure TcxSchedulerOptionsView.SetHideSelection(AValue: Boolean);
|
|
begin
|
|
if FHideSelection <> AValue then
|
|
begin
|
|
FHideSelection := AValue;
|
|
Changed;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerOptionsView.SetHorzSplitterWidth(AValue: Integer);
|
|
begin
|
|
SetSplitterWidth(AValue, FHorzSplitterWidth);
|
|
end;
|
|
|
|
procedure TcxSchedulerOptionsView.SetResourceHeaders(
|
|
AValue: TcxSchedulerResourceHeaders);
|
|
begin
|
|
FResourceHeaders.Assign(AValue)
|
|
end;
|
|
|
|
procedure TcxSchedulerOptionsView.SetRotateResourceCaptions(AValue: Boolean);
|
|
begin
|
|
ResourceHeaders.RotateCaptions := AValue;
|
|
end;
|
|
|
|
procedure TcxSchedulerOptionsView.SetResourcesPerPage(
|
|
AValue: Integer);
|
|
begin
|
|
AValue := Max(AValue, 0);
|
|
if AValue <> FResourcesPerPage then
|
|
begin
|
|
FResourcesPerPage := AValue;
|
|
Changed;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerOptionsView.SetShowAdditionalTimeZone(AValue: Boolean);
|
|
begin
|
|
if FShowAdditionalTimeZone <> AValue then
|
|
begin
|
|
FShowAdditionalTimeZone := AValue;
|
|
Changed;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerOptionsView.SetShowEventsWithoutResource(
|
|
AValue: Boolean);
|
|
begin
|
|
if AValue <> FShowEventsWithoutResource then
|
|
begin
|
|
FShowEventsWithoutResource := AValue;
|
|
Scheduler.FullRefresh;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerOptionsView.SetShowNavigationButtons(AValue: Boolean);
|
|
begin
|
|
if AValue <> FShowNavigationButtons then
|
|
begin
|
|
FShowNavigationButtons := AValue;
|
|
Changed;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerOptionsView.SetSplitterWidth(
|
|
AValue: Integer; var AWidth: Integer);
|
|
begin
|
|
AValue := Max(AValue, cxMinSplitterWidth);
|
|
if AValue <> AWidth then
|
|
begin
|
|
AWidth := AValue;
|
|
Changed;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerOptionsView.SetStartOfWeek(AValue: TcxStartOfWeek);
|
|
var
|
|
AOldActualValue: TDay;
|
|
begin
|
|
if AValue <> FStartOfWeek then
|
|
begin
|
|
FStartOfWeek := AValue;
|
|
AOldActualValue := ActualStartOfWeek;
|
|
CalculateActualStartOfWeek;
|
|
if not Scheduler.IsLoading then
|
|
Scheduler.DoStartOfWeekChanged(AOldActualValue, ActualStartOfWeek);
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerOptionsView.SetTimeZone(
|
|
AIndex, AValue: Integer);
|
|
begin
|
|
AValue := Max(Min(AValue, DateTimeHelper.TimeZoneCount - 1), -1);
|
|
if AValue <> FTimeZones[AIndex] then
|
|
begin
|
|
FTimeZones[AIndex] := AValue;
|
|
Scheduler.FullRefresh;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerOptionsView.SetTimeZoneLabel(
|
|
AIndex: Integer; const AValue: string);
|
|
begin
|
|
if AValue <> FTimeZoneLabels[AIndex] then
|
|
begin
|
|
FTimeZoneLabels[AIndex] := AValue;
|
|
Changed;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerOptionsView.SetVertSplitterWidth(AValue: Integer);
|
|
begin
|
|
SetSplitterWidth(AValue, FVertSplitterWidth);
|
|
end;
|
|
|
|
procedure TcxSchedulerOptionsView.SetViewPosition(
|
|
AValue: TcxSchedulerViewPosition);
|
|
begin
|
|
if AValue <> FViewPosition then
|
|
begin
|
|
FViewPosition := AValue;
|
|
Changed;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerOptionsView.SetWorkDays(AValue: TDays);
|
|
begin
|
|
if AValue <> FWorkDays then
|
|
begin
|
|
FWorkDays := AValue;
|
|
Scheduler.PeriodChanged;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerOptionsView.SetWorkFinish(AValue: TTime);
|
|
begin
|
|
if AValue <> FWorkFinish then
|
|
begin
|
|
FWorkFinish := DateTimeHelper.RoundTime(AValue);
|
|
FWorkFinishAssigned := FWorkFinish <> DateTimeHelper.WorkFinish;
|
|
Scheduler.PeriodChanged;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerOptionsView.SetWorkStart(AValue: TTime);
|
|
begin
|
|
if AValue <> FWorkStart then
|
|
begin
|
|
FWorkStart := DateTimeHelper.RoundTime(AValue);
|
|
FWorkStartAssigned := FWorkStart <> DateTimeHelper.WorkStart;
|
|
Scheduler.PeriodChanged;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerOptionsView.ReadWorkFinish(AReader: TReader);
|
|
begin
|
|
FWorkFinish := AReader.ReadFloat;
|
|
end;
|
|
|
|
procedure TcxSchedulerOptionsView.ReadWorkStart(AReader: TReader);
|
|
begin
|
|
FWorkStart := AReader.ReadFloat;
|
|
end;
|
|
|
|
procedure TcxSchedulerOptionsView.WriteWorkFinish(AWriter: TWriter);
|
|
begin
|
|
AWriter.WriteFloat(FWorkFinish);
|
|
end;
|
|
|
|
procedure TcxSchedulerOptionsView.WriteWorkStart(AWriter: TWriter);
|
|
begin
|
|
AWriter.WriteFloat(FWorkStart);
|
|
end;
|
|
|
|
{ TcxSchedulerViewHitTest }
|
|
|
|
function TcxSchedulerViewHitTest.GetDragKind: TcxEventDragKind;
|
|
begin
|
|
Result := edkNone;
|
|
end;
|
|
|
|
procedure TcxSchedulerViewHitTest.Clear;
|
|
begin
|
|
inherited Clear;
|
|
FNeedShowHint := False;
|
|
FTime := NullDate;
|
|
end;
|
|
|
|
function TcxSchedulerViewHitTest.GetHitEvent: TcxSchedulerControlEvent;
|
|
begin
|
|
Result := nil;
|
|
end;
|
|
|
|
function TcxSchedulerViewHitTest.GetHitAtEvent: Boolean;
|
|
begin
|
|
Result := Event <> nil;
|
|
end;
|
|
|
|
function TcxSchedulerViewHitTest.GetNeedShowHint: Boolean;
|
|
var
|
|
AText: string;
|
|
begin
|
|
Result := FNeedShowHint or (HitAtEvent and Scheduler.NeedShowHint(Event, AText, False));
|
|
end;
|
|
|
|
{ TcxDragHelper }
|
|
|
|
constructor TcxDragHelper.Create(AScheduler: TcxCustomScheduler);
|
|
begin
|
|
FScheduler := AScheduler;
|
|
BeginDrag;
|
|
end;
|
|
|
|
procedure TcxDragHelper.BeginDrag;
|
|
begin
|
|
FSaveCursor := Scheduler.DragCursor;
|
|
GetOriginState;
|
|
FPrevAccepted := True;
|
|
end;
|
|
|
|
procedure TcxDragHelper.CalculateConflicts;
|
|
begin
|
|
FHasConflicts := Scheduler.HasConflict(False);
|
|
end;
|
|
|
|
procedure TcxDragHelper.CalculateDestination;
|
|
var
|
|
P: TPoint;
|
|
begin
|
|
FDestination := dodOther;
|
|
with Scheduler do
|
|
begin
|
|
P := ScreenToClient(GetMouseCursorPos);
|
|
if CurrentView.Visible and
|
|
cxRectPtIn(cxRectOffset(CurrentView.ViewInfo.Bounds, CurrentView.Bounds.TopLeft), P) then
|
|
FDestination := dodView
|
|
else
|
|
if DateNavigator.Visible and cxRectPtIn(DateNavigator.Bounds, P) then
|
|
begin
|
|
FDestination := dodDateNavigator;
|
|
DateNavigator.MousePositionChanged(P.X, P.Y);
|
|
end
|
|
else
|
|
if ControlBox.Visible and cxRectPtIn(ControlBox.Bounds, P) then
|
|
FDestination := dodControlBox;
|
|
end;
|
|
end;
|
|
|
|
function TcxDragHelper.CanUpdateEventState(
|
|
AEvent: TcxSchedulerControlEvent): Boolean;
|
|
begin
|
|
with AEvent.Source do
|
|
Result := State = cxOriginalEventStates[AllDayEvent];
|
|
end;
|
|
|
|
procedure TcxDragHelper.CheckAccepted(var Accepted: Boolean);
|
|
begin
|
|
Accepted := Accepted and (Destination <> dodOther) and IsValidTime;
|
|
end;
|
|
|
|
procedure TcxDragHelper.CheckEventState(AEvent: TcxSchedulerControlEvent);
|
|
var
|
|
ANewState: Integer;
|
|
begin
|
|
if CanUpdateEventState(AEvent) then
|
|
begin
|
|
ANewState := cxOriginalEventStates[AEvent.AllDayEvent];
|
|
if AEvent.State <> ANewState then
|
|
AEvent.State := ANewState;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxDragHelper.DragOver(const P: TPoint; State: TDragState;
|
|
var Accepted: Boolean);
|
|
begin
|
|
CalculateDestination;
|
|
FActualHitTime := GetActualHitTime;
|
|
CheckAccepted(Accepted);
|
|
FAcceptedChanged := Accepted <> FPrevAccepted;
|
|
end;
|
|
|
|
procedure TcxDragHelper.EndDrag(Accepted: Boolean);
|
|
begin
|
|
end;
|
|
|
|
function TcxDragHelper.GetOriginHitTestMask: Int64;
|
|
const
|
|
Mask = 1 shl htcControl;
|
|
begin
|
|
Result := Mask;
|
|
end;
|
|
|
|
procedure TcxDragHelper.GetOriginState;
|
|
begin
|
|
with Controller do
|
|
begin
|
|
FStartHitFlags := StartDragFlags and GetOriginHitTestMask;
|
|
FStartHitTime := StartDragHitTime;
|
|
FStartResource := StartDragResource;
|
|
end;
|
|
FPrevHitTime := FStartHitTime;
|
|
FPrevHitFlags := FStartHitFlags;
|
|
FPrevHitResource := FStartResource;
|
|
end;
|
|
|
|
function TcxDragHelper.HasChangedState: Boolean;
|
|
begin
|
|
with HitTest do
|
|
Result := FAcceptedChanged or
|
|
(FPrevHitFlags <> (Flags and GetOriginHitTestMask)) or
|
|
(IsValidTime and (FPrevHitTime <> GetActualHitTime)) or
|
|
(HitAtResource and (FPrevHitResource <> Resource));
|
|
end;
|
|
|
|
function TcxDragHelper.IsAtOrigin: Boolean;
|
|
begin
|
|
with HitTest do
|
|
begin
|
|
Result := (FStartHitFlags = (Flags and GetOriginHitTestMask)) and
|
|
(Controller.StartDragHitTime = Time);
|
|
if Result and IsShowResources then
|
|
Result := HitAtResource and (FStartResource = Resource);
|
|
end;
|
|
end;
|
|
|
|
function TcxDragHelper.IsShowResources: Boolean;
|
|
begin
|
|
Result := Scheduler.CurrentView.IsShowResources;
|
|
end;
|
|
|
|
function TcxDragHelper.IsValidTime: Boolean;
|
|
begin
|
|
Result := HitTest.HitAtTime;
|
|
end;
|
|
|
|
procedure TcxDragHelper.RefreshCurrentView;
|
|
begin
|
|
Scheduler.CurrentView.Refresh;
|
|
end;
|
|
|
|
procedure TcxDragHelper.SetSelection;
|
|
begin
|
|
Controller.SyncEventSelection(Controller.DragEvent);
|
|
end;
|
|
|
|
procedure TcxDragHelper.UpdateHelperState(Accepted: Boolean);
|
|
begin
|
|
with HitTest do
|
|
begin
|
|
FPrevHitFlags := Flags and GetOriginHitTestMask;
|
|
FPrevHitTime := GetActualHitTime;
|
|
FPrevHitResource := Resource;
|
|
end;
|
|
FPrevAccepted := Accepted;
|
|
end;
|
|
|
|
function TcxDragHelper.GetActualHitTime: TDateTime;
|
|
begin
|
|
if Destination = dodDateNavigator then
|
|
Result := DateNavigator.HitTest.Time
|
|
else
|
|
Result := HitTest.Time;
|
|
end;
|
|
|
|
function TcxDragHelper.GetController: TcxSchedulerViewController;
|
|
begin
|
|
Result := Scheduler.CurrentView.Controller;
|
|
end;
|
|
|
|
function TcxDragHelper.GetDateNavigator: TcxSchedulerCustomDateNavigator;
|
|
begin
|
|
Result := Scheduler.DateNavigator;
|
|
end;
|
|
|
|
function TcxDragHelper.GetEvents: TcxSchedulerCachedEventList;
|
|
begin
|
|
Result := Scheduler.EventList;
|
|
end;
|
|
|
|
function TcxDragHelper.GetHitTest: TcxSchedulerViewHitTest;
|
|
begin
|
|
Result := Scheduler.CurrentView.HitTest;
|
|
end;
|
|
|
|
{ TcxSchedulerDragObject}
|
|
|
|
constructor TcxSchedulerDragObject.Create(AControl: TControl);
|
|
begin
|
|
inherited Create(AControl);
|
|
FUseInternalCursors := (Control is TcxCustomScheduler) and
|
|
(Scheduler.DragCursor = crDrag);
|
|
end;
|
|
|
|
procedure TcxSchedulerDragObject.DropToDateNavigator(
|
|
ADateNavigator: TcxSchedulerCustomDateNavigator);
|
|
begin
|
|
if not ADateNavigator.HitTest.HitAtTime then Exit;
|
|
DragEventHelper.ProcessDateNavigator(ADateNavigator);
|
|
end;
|
|
|
|
procedure TcxSchedulerDragObject.CalculateConflictsForDateNavigator(
|
|
ADateNavigator: TcxSchedulerCustomDateNavigator);
|
|
begin
|
|
with DragEventHelper do
|
|
begin
|
|
UpdateDateNavigatorClones(ADateNavigator);
|
|
CalculateConflicts;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerDragObject.Finished(
|
|
Target: TObject; X, Y: Integer; Accepted: Boolean);
|
|
begin
|
|
if not Accepted and (Target is TcxCustomScheduler) and (Target <> Scheduler) then
|
|
TcxCustomScheduler(Target).DragCanceled;
|
|
inherited Finished(Target, X, Y, Accepted);
|
|
end;
|
|
|
|
function TcxSchedulerDragObject.GetDragCursor(Accepted: Boolean; X, Y: Integer): TCursor;
|
|
|
|
function CanAcceptEvent: Boolean;
|
|
begin
|
|
with DragEventHelper do
|
|
Result := not HasConflicts and FPrevAccepted;
|
|
end;
|
|
|
|
var
|
|
R: TRect;
|
|
begin
|
|
if Assigned(DragEventHelper) and Accepted and FUseInternalCursors then
|
|
begin
|
|
R := cxGetWindowRect(Scheduler);
|
|
if CanAcceptEvent or not cxRectPtIn(R, X, Y) then
|
|
if Scheduler.IsCopyDragDrop then
|
|
Result := crSchedulerCopyEvent
|
|
else
|
|
Result := crSchedulerMoveEvent
|
|
else
|
|
Result := crNoDrop
|
|
end
|
|
else
|
|
Result := inherited GetDragCursor(Accepted, X, Y);
|
|
end;
|
|
|
|
function TcxSchedulerDragObject.GetDragEventHelper: TcxDragEventHelper;
|
|
begin
|
|
Result := Scheduler.CurrentView.Controller.DragEventHelper;
|
|
end;
|
|
|
|
function TcxSchedulerDragObject.GetDragEvents: TcxSchedulerFilteredEventList;
|
|
begin
|
|
Result := Scheduler.EventList.Clones;
|
|
end;
|
|
|
|
function TcxSchedulerDragObject.GetHasConflicts: Boolean;
|
|
begin
|
|
Result := (DragEventHelper <> nil) and DragEventHelper.HasConflicts;
|
|
end;
|
|
|
|
function TcxSchedulerDragObject.GetScheduler: TcxCustomScheduler;
|
|
begin
|
|
Result := TcxCustomScheduler(Control);
|
|
end;
|
|
|
|
{ TcxDragEventHelper }
|
|
|
|
procedure TcxDragEventHelper.ApplyChanges;
|
|
begin
|
|
SetSelection;
|
|
Events.PostClones(FPrevIsDragCopy);
|
|
end;
|
|
|
|
procedure TcxDragEventHelper.BeginDrag;
|
|
begin
|
|
inherited BeginDrag;
|
|
PrepareClones;
|
|
CheckVisibility(True);
|
|
end;
|
|
|
|
procedure TcxDragEventHelper.CheckAccepted(var Accepted: Boolean);
|
|
|
|
function CanMoveBetweenResources: Boolean;
|
|
var
|
|
AResource: TcxSchedulerStorageResourceItem;
|
|
begin
|
|
AResource := HitTest.Resource;
|
|
Result := (FStartResource = AResource) or
|
|
(Scheduler.EventOperations.MovingBetweenResources and
|
|
((AResource = nil) or not AResource.ReadOnly));
|
|
end;
|
|
|
|
begin
|
|
inherited CheckAccepted(Accepted);
|
|
if not Accepted or (Destination = dodControlBox) then Exit;
|
|
if (Destination = dodView) and IsShowResources and HitTest.HitAtResource and
|
|
not CanMoveBetweenResources then Accepted := False;
|
|
if DateNavigator.Visible then
|
|
UpdateDateNavigator(Accepted);
|
|
end;
|
|
|
|
procedure TcxDragEventHelper.CheckVisibility(Accepted: Boolean);
|
|
begin
|
|
Inc(Scheduler.FLockRefresh);
|
|
try
|
|
Events.AlwaysShowSelectedEvent := not Accepted or (Destination <> dodView);
|
|
ViewInfo.SetEventsVisibility(GetSourcesVisible(Accepted),
|
|
GetClonesVisible(Accepted), True);
|
|
finally
|
|
Dec(Scheduler.FLockRefresh);
|
|
end;
|
|
end;
|
|
|
|
procedure TcxDragEventHelper.DragOver(const P: TPoint; State: TDragState;
|
|
var Accepted: Boolean);
|
|
var
|
|
ANeedUpdate: Boolean;
|
|
begin
|
|
inherited DragOver(P, State, Accepted);
|
|
ANeedUpdate := HasChangedState or (State in [dsDragLeave, dsDragEnter]);
|
|
if Accepted and ANeedUpdate then
|
|
begin
|
|
Accepted := DragObject.Dropped or (State <> dsDragLeave);
|
|
if Accepted then
|
|
UpdateClones;
|
|
end;
|
|
if ANeedUpdate then
|
|
begin
|
|
CalculateConflicts;
|
|
CheckVisibility(Accepted);
|
|
if State = dsDragLeave then
|
|
Scheduler.UpdateDateNavigatorDragging(False)
|
|
end;
|
|
Controller.CheckScrollOnDragOver(P, State);
|
|
end;
|
|
|
|
procedure TcxDragEventHelper.EndDrag(Accepted: Boolean);
|
|
begin
|
|
try
|
|
Events.AlwaysShowSelectedEvent := False;
|
|
CalculateDestination;
|
|
CheckAccepted(Accepted);
|
|
Controller.CancelScroll;
|
|
Scheduler.DragCursor := SaveCursor;
|
|
FPrevIsDragCopy := IsDragCopy;
|
|
if Accepted and IsValidTime and not (IsAtOrigin and not FPrevIsDragCopy) then
|
|
begin
|
|
UpdateClones;
|
|
CalculateConflicts;
|
|
if not HasConflicts then
|
|
begin
|
|
Scheduler.DoAfterDragEvent(FTarget, HitTest.HitX, HitTest.HitY, Accepted);
|
|
if Accepted then
|
|
ApplyChanges;
|
|
end;
|
|
end;
|
|
finally
|
|
Events.CancelClones;
|
|
DateNavigatorEndDrag;
|
|
Scheduler.FullRefresh;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxDragEventHelper.DateNavigatorEndDrag;
|
|
begin
|
|
if DateNavigator.Visible then
|
|
DateNavigator.Controller.DoCancelMode;
|
|
end;
|
|
|
|
function TcxDragEventHelper.GetClonesVisible(Accepted: Boolean): Boolean;
|
|
begin
|
|
Result := Accepted and ((Destination = dodView) and not (IsAtOrigin and not IsDragCopy));
|
|
end;
|
|
|
|
function TcxDragEventHelper.GetIsDragCopy: Boolean;
|
|
begin
|
|
Result := Scheduler.IsCopyDragDrop;
|
|
end;
|
|
|
|
procedure TcxDragEventHelper.GetOriginState;
|
|
begin
|
|
inherited GetOriginState;
|
|
FPrevIsDragCopy := IsDragCopy;
|
|
end;
|
|
|
|
function TcxDragEventHelper.GetSourcesVisible(Accepted: Boolean): Boolean;
|
|
begin
|
|
Result := not Accepted or
|
|
((Destination in [dodDateNavigator, dodControlBox]) or IsAtOrigin or IsDragCopy);
|
|
end;
|
|
|
|
function TcxDragEventHelper.HasChangedState: Boolean;
|
|
begin
|
|
Result := inherited HasChangedState or (FPrevIsDragCopy <> IsDragCopy);
|
|
end;
|
|
|
|
function TcxDragEventHelper.IsValidNavigatorDate: Boolean;
|
|
begin
|
|
Result := (Destination = dodDateNavigator) and DateNavigator.HitTest.HitAtTime;
|
|
end;
|
|
|
|
function TcxDragEventHelper.IsValidTime: Boolean;
|
|
begin
|
|
Result := HitTest.HitAtTime or IsValidNavigatorDate;
|
|
end;
|
|
|
|
procedure TcxDragEventHelper.PrepareClones;
|
|
var
|
|
I: Integer;
|
|
AEvent: TcxSchedulerControlEvent;
|
|
AResource, ADragEventResource: TcxSchedulerStorageResourceItem;
|
|
begin
|
|
ADragEventResource := Controller.DragEvent.GetResourceItem;
|
|
for I := Events.Selection.Count - 1 downto 0 do
|
|
begin
|
|
AEvent := Events.Selection.Items[I];
|
|
AResource := AEvent.GetResourceItem;
|
|
if IsShowResources and (AResource <> nil) and (AResource <> ADragEventResource) then
|
|
Events.Selection.Add(AEvent, [ssCtrl]);
|
|
end;
|
|
Events.CreateClones;
|
|
end;
|
|
|
|
procedure TcxDragEventHelper.ProcessDateNavigator(
|
|
ADateNavigator: TcxSchedulerCustomDateNavigator);
|
|
begin
|
|
try
|
|
UpdateDateNavigatorClones(ADateNavigator);
|
|
finally
|
|
Events.PostClones(IsDragCopy);
|
|
end;
|
|
end;
|
|
|
|
procedure TcxDragEventHelper.SetSelection;
|
|
var
|
|
I: Integer;
|
|
AEvent: TcxSchedulerControlEvent;
|
|
begin
|
|
for I := 0 to Clones.Count - 1 do
|
|
begin
|
|
AEvent := Clones[I];
|
|
if AEvent.Source = Controller.DragEvent then
|
|
Controller.SyncEventSelection(AEvent);
|
|
end;
|
|
end;
|
|
|
|
procedure TcxDragEventHelper.Update(Accepted: Boolean = True);
|
|
begin
|
|
DragOver(ViewInfo.Owner.ScreenToClient(GetMouseCursorPos), dsDragMove, Accepted);
|
|
end;
|
|
|
|
procedure TcxDragEventHelper.UpdateHelperState(Accepted: Boolean);
|
|
begin
|
|
inherited UpdateHelperState(Accepted);
|
|
FPrevIsDragCopy := IsDragCopy;
|
|
end;
|
|
|
|
procedure TcxDragEventHelper.UpdateClones;
|
|
begin
|
|
if Destination = dodView then
|
|
UpdateViewClones
|
|
else
|
|
if Destination = dodDateNavigator then
|
|
UpdateDateNavigatorClones(DateNavigator);
|
|
end;
|
|
|
|
procedure TcxDragEventHelper.UpdateDateNavigatorClones(
|
|
ADateNavigator: TcxSchedulerCustomDateNavigator);
|
|
var
|
|
ADelta: TDateTime;
|
|
I: Integer;
|
|
begin
|
|
ADelta := ADateNavigator.HitTest.Time - DateOf(Controller.DragEvent.{Source.}Start);
|
|
for I := 0 to Clones.Count - 1 do
|
|
with Clones[I] do
|
|
begin
|
|
State := Source.State;
|
|
AllDayEvent := Source.AllDayEvent;
|
|
Duration := Source.Duration;
|
|
MoveTo(Source.Start + ADelta);
|
|
ResourceID := Source.ResourceID;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxDragEventHelper.UpdateDateNavigator(var Accepted: Boolean);
|
|
var
|
|
P: TPoint;
|
|
begin
|
|
P := Scheduler.ScreenToClient(GetMouseCursorPos);
|
|
with DateNavigator do
|
|
begin
|
|
MousePositionChanged(P.X, P.Y);
|
|
if HitTest.HitAtControl then
|
|
Accepted := HitTest.HitAtTime;
|
|
UpdateDragging;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxDragEventHelper.UpdateViewClones;
|
|
begin
|
|
UpdateViewClonesResources;
|
|
UpdateViewClonesTime;
|
|
end;
|
|
|
|
procedure TcxDragEventHelper.UpdateViewClonesResources;
|
|
var
|
|
I: Integer;
|
|
AResource: TcxSchedulerStorageResourceItem;
|
|
begin
|
|
with HitTest do
|
|
begin
|
|
if HitAtResource then
|
|
AResource := Resource
|
|
else
|
|
AResource := FStartResource;
|
|
end;
|
|
if AResource <> nil then
|
|
begin
|
|
for I := 0 to Clones.Count - 1 do
|
|
with Clones[I] do
|
|
if not VarIsNull(Source.ResourceID) and
|
|
(not Source.Shared or Source.IsSharedWithResource(AResource)) then
|
|
ReplaceResourceID(AResource.ResourceID);
|
|
end;
|
|
end;
|
|
|
|
procedure TcxDragEventHelper.UpdateViewClonesTime;
|
|
begin
|
|
end;
|
|
|
|
function TcxDragEventHelper.GetClones: TcxSchedulerFilteredEventList;
|
|
begin
|
|
Result := Scheduler.EventList.Clones;
|
|
end;
|
|
|
|
function TcxDragEventHelper.GetViewInfo: TcxSchedulerCustomViewViewInfo;
|
|
begin
|
|
Result := TcxSchedulerCustomViewViewInfo(Scheduler.CurrentView.ViewInfo);
|
|
end;
|
|
|
|
{ TcxSchedulerEditController }
|
|
|
|
constructor TcxSchedulerEditController.Create(AOwner: TcxCustomScheduler);
|
|
begin
|
|
FOwner := AOwner;
|
|
FEditList := TcxInplaceEditList.Create(Scheduler);
|
|
end;
|
|
|
|
destructor TcxSchedulerEditController.Destroy;
|
|
begin
|
|
CloseEdit(False);
|
|
FEditList.Free;
|
|
inherited Destroy;
|
|
end;
|
|
|
|
procedure TcxSchedulerEditController.Activate(
|
|
AEvent: TcxSchedulerControlEvent);
|
|
begin
|
|
if InitEdit(AEvent) then
|
|
FEdit.Activate(FEditData);
|
|
end;
|
|
|
|
procedure TcxSchedulerEditController.Activate(
|
|
AEvent: TcxSchedulerControlEvent; const APos: TPoint; AShift: TShiftState);
|
|
begin
|
|
if InitEdit(AEvent) then
|
|
FEdit.ActivateByMouse(AShift, APos.X, APos.Y, FEditData);
|
|
end;
|
|
|
|
procedure TcxSchedulerEditController.Activate(
|
|
AEvent: TcxSchedulerControlEvent; Key: Char);
|
|
begin
|
|
if InitEdit(AEvent) then
|
|
FEdit.ActivateByKey(Key, FEditData);
|
|
end;
|
|
|
|
procedure TcxSchedulerEditController.CloseEdit(Accepted: Boolean);
|
|
|
|
function IsDataRefreshing: Boolean;
|
|
begin
|
|
Result := Scheduler.FLockRefresh > 0;
|
|
end;
|
|
|
|
begin
|
|
if not IsEditing then Exit;
|
|
FIsEditing := False;
|
|
FFocused := False;
|
|
try
|
|
if not (Scheduler.IsDestroying or IsDataRefreshing) then
|
|
begin
|
|
if Accepted and CanAccept then
|
|
begin
|
|
if not FEdit.Deactivate then raise EAbort.Create('');
|
|
UpdateValue;
|
|
if Event.Source = nil then
|
|
Event.MoveTo(Event.Start + Scheduler.GetTimeBias(Event.Start));
|
|
Scheduler.EventList.PostEvent(Event);
|
|
Scheduler.SetFocus;
|
|
end
|
|
else
|
|
begin
|
|
if FIsNewEvent then
|
|
begin
|
|
DeleteEvent(Event);
|
|
FEvent := nil;
|
|
end;
|
|
Scheduler.FullRefresh;
|
|
end;
|
|
end;
|
|
finally
|
|
FEdit.Parent := nil;
|
|
FEdit := nil;
|
|
FreeAndNil(FEditData);
|
|
FIsNewEvent := False;
|
|
if not Scheduler.IsDestroying then
|
|
begin
|
|
Scheduler.DoAfterEditing(Scheduler.EventList.LastEditedEvent);
|
|
if not IsDataRefreshing then
|
|
Scheduler.CurrentView.Refresh;
|
|
end;
|
|
FEvent := nil;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerEditController.Init(const AEditDate: TDateTime;
|
|
AResource: TcxSchedulerStorageResourceItem; AIsNewEvent: Boolean = False);
|
|
begin
|
|
FEditDate := DateOf(AEditDate);
|
|
FEditResource := AResource;
|
|
FIsNewEvent := AIsNewEvent;
|
|
end;
|
|
|
|
procedure TcxSchedulerEditController.DeleteEvent(AEvent: TcxSchedulerControlEvent);
|
|
begin
|
|
Scheduler.EventList.DeleteEvent(AEvent);
|
|
if Scheduler.CurrentView <> nil then
|
|
Scheduler.CurrentView.Refresh;
|
|
end;
|
|
|
|
procedure TcxSchedulerEditController.UpdateEdit;
|
|
var
|
|
R: TRect;
|
|
begin
|
|
if not IsEditing then Exit;
|
|
if GetEditRect(R, FEditDate, FEditResource) then
|
|
begin
|
|
FEdit.BoundsRect := R;
|
|
FEdit.Visible := True;
|
|
end
|
|
else
|
|
FEdit.Visible := False;
|
|
FEdit.EditValue := FEvent.Caption;
|
|
end;
|
|
|
|
procedure TcxSchedulerEditController.UpdateValue;
|
|
begin
|
|
if (FEdit <> nil) and FEdit.EditModified then
|
|
begin
|
|
FEdit.ValidateEdit(True);
|
|
FEvent.Caption := FEdit.EditValue;
|
|
end;
|
|
end;
|
|
|
|
function TcxSchedulerEditController.GetEditRect(var R: TRect;
|
|
const ADate: TDateTime; AResource: TcxSchedulerStorageResourceItem;
|
|
AMakeVisible: Boolean = False): Boolean;
|
|
begin
|
|
Scheduler.MakeEventVisible(Event, ADate, AResource);
|
|
with Scheduler.CurrentView do
|
|
R := cxRectOffset(GetEditRectForEvent(Event, ADate, AResource), Bounds.TopLeft);
|
|
Result := not cxRectIsEmpty(R);
|
|
end;
|
|
|
|
procedure TcxSchedulerEditController.EditAfterKeyDown(
|
|
Sender: TObject; var Key: Word; Shift: TShiftState);
|
|
begin
|
|
if IsKeyForControl(Key, Shift) then
|
|
begin
|
|
Scheduler.SetFocus;
|
|
CloseEdit(True);
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerEditController.EditExit(Sender: TObject);
|
|
begin
|
|
if IsEditing then CloseEdit(True);
|
|
end;
|
|
|
|
procedure TcxSchedulerEditController.EditKeyDown(
|
|
Sender: TObject; var Key: Word; Shift: TShiftState);
|
|
begin
|
|
if IsKeyForControl(Key, Shift) then
|
|
begin
|
|
CloseEdit(Key <> VK_ESCAPE);
|
|
Scheduler.SetFocus;
|
|
end;
|
|
if Assigned(Scheduler.OnKeyDown) then
|
|
Scheduler.OnKeyDown(Scheduler, Key, Shift);
|
|
end;
|
|
|
|
procedure TcxSchedulerEditController.EditKeyPress(
|
|
Sender: TObject; var Key: Char);
|
|
begin
|
|
if Assigned(Scheduler.OnKeyPress) then
|
|
Scheduler.OnKeyPress(Scheduler, Key);
|
|
end;
|
|
|
|
procedure TcxSchedulerEditController.EditKeyUp(
|
|
Sender: TObject; var Key: Word; Shift: TShiftState);
|
|
begin
|
|
if Assigned(Scheduler.OnKeyUp) then
|
|
Scheduler.OnKeyUp(Scheduler, Key, Shift);
|
|
end;
|
|
|
|
procedure TcxSchedulerEditController.EditPostEditValue(Sender: TObject);
|
|
begin
|
|
UpdateValue;
|
|
end;
|
|
|
|
function TcxSchedulerEditController.InitEdit(
|
|
AEvent: TcxSchedulerControlEvent): Boolean;
|
|
var
|
|
R: TRect;
|
|
begin
|
|
Result := False;
|
|
if AEvent = nil then Exit;
|
|
if IsEditing then
|
|
begin
|
|
if FEvent = AEvent then
|
|
begin
|
|
UpdateValue;
|
|
UpdateEdit;
|
|
end
|
|
else
|
|
CloseEdit(True);
|
|
Exit;
|
|
end;
|
|
FIsEditing := False;
|
|
FEvent := AEvent;
|
|
{ Controller.SelectSingleEvent(AEvent, NullDate, False); }
|
|
if not (Scheduler.DoBeforeEditing(AEvent, True) and
|
|
GetEditRect(R, FEditDate, FEditResource, True)) then Exit;
|
|
Scheduler.EventList.BeforeEditing(FEvent, True);
|
|
Scheduler.DoGetEventEditProperties(Event, FEditProperties);
|
|
FEdit := FEditList.GetEdit(EditProperties);
|
|
Result := FEdit <> nil;
|
|
if not Result then Exit;
|
|
FIsEditing := True;
|
|
PrepareEdit(FEdit);
|
|
if FIsEditing then
|
|
Scheduler.CurrentView.Refresh;
|
|
end;
|
|
|
|
function TcxSchedulerEditController.IsKeyForControl(
|
|
var AKey: Word; Shift: TShiftState): Boolean;
|
|
begin
|
|
Result := (AKey = VK_TAB) or (AKey = VK_ESCAPE) or (AKey = VK_RETURN);
|
|
end;
|
|
|
|
procedure TcxSchedulerEditController.PrepareEdit(AEdit: TcxCustomEdit);
|
|
const
|
|
VertAlignments: array[Boolean] of TcxEditVertAlignment = (taTopJustify, taVCenter);
|
|
var
|
|
R: TRect;
|
|
AVisible: Boolean;
|
|
begin
|
|
FFocused := True;
|
|
with FEdit do
|
|
begin
|
|
Visible := False;
|
|
AVisible := GetEditRect(R, FEditDate, FEditResource);
|
|
InternalProperties.Alignment.Vert := VertAlignments[View.GetEditWithSingleLineEditor(Event)];
|
|
BoundsRect := R;
|
|
Parent := Scheduler;
|
|
EditValue := FEvent.Caption;
|
|
OnAfterKeyDown := EditAfterKeyDown;
|
|
OnExit := EditExit;
|
|
OnKeyDown := EditKeyDown;
|
|
OnKeyPress := EditKeyPress;
|
|
OnKeyUp := EditKeyUp;
|
|
OnPostEditValue := EditPostEditValue;
|
|
Style.Init(Scheduler.Styles.GetEventContentParams(Event));
|
|
Visible := AVisible;
|
|
end;
|
|
Scheduler.DoInitEdit(FEdit);
|
|
end;
|
|
|
|
function TcxSchedulerEditController.CanAccept: Boolean;
|
|
begin
|
|
Result := FEdit.EditModified or FIsNewEvent;
|
|
end;
|
|
|
|
function TcxSchedulerEditController.GetController: TcxSchedulerViewController;
|
|
begin
|
|
Result := View.Controller;
|
|
end;
|
|
|
|
function TcxSchedulerEditController.GetEditVisible: Boolean;
|
|
begin
|
|
Result := IsEditing and FEdit.Visible;
|
|
end;
|
|
|
|
function TcxSchedulerEditController.GetView: TcxSchedulerCustomView;
|
|
begin
|
|
Result := Scheduler.CurrentView;
|
|
end;
|
|
|
|
procedure TcxSchedulerEditController.SetEditVisible(Value: Boolean);
|
|
begin
|
|
if not IsEditing then Exit;
|
|
if Value <> EditVisible then
|
|
begin
|
|
FEdit.Visible := Value;
|
|
UpdateEdit;
|
|
end;
|
|
end;
|
|
|
|
{ TcxSchedulerViewNavigation }
|
|
|
|
constructor TcxSchedulerViewNavigation.Create(
|
|
AView: TcxSchedulerCustomView);
|
|
begin
|
|
FView := AView;
|
|
end;
|
|
|
|
procedure TcxSchedulerViewNavigation.CheckSelection;
|
|
begin
|
|
with Scheduler do
|
|
Self.ValidateSelection(FSelStart, FSelFinish, FSelResource);
|
|
end;
|
|
|
|
procedure TcxSchedulerViewNavigation.ReplaceSelParams(
|
|
const ASelStart, ASelFinish: TDateTime);
|
|
begin
|
|
ReplaceSelParams(ASelStart, ASelFinish, GetResourceItem);
|
|
end;
|
|
|
|
procedure TcxSchedulerViewNavigation.ReplaceSelParams(
|
|
const ASelStart, ASelFinish: TDateTime; AResource: TcxSchedulerStorageResourceItem);
|
|
begin
|
|
Scheduler.ReplaceSelParams(ASelStart, ASelFinish, AResource);
|
|
end;
|
|
|
|
procedure TcxSchedulerViewNavigation.ReplaceSelParams(
|
|
AResource: TcxSchedulerStorageResourceItem);
|
|
begin
|
|
Scheduler.ReplaceSelParams(SelStart, SelFinish, AResource);
|
|
end;
|
|
|
|
function TcxSchedulerViewNavigation.ScrollResources(AGoForward: Boolean): Boolean;
|
|
const
|
|
ACode: array[Boolean] of TScrollCode = (scLineUp, scLineDown);
|
|
var
|
|
APos: Integer;
|
|
begin
|
|
with ResourceNavigator do
|
|
begin
|
|
if not AGoForward then
|
|
Result := FirstVisibleResourceIndex > 0
|
|
else
|
|
Result := (ResourcesPerPage <> 0) and ((ResourcesPerPage + FirstVisibleResourceIndex) < VisibleResourceCount);
|
|
if Result then
|
|
begin
|
|
APos := FirstVisibleResourceIndex;
|
|
Scroll(ACode[AGoForward], APos);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TcxSchedulerViewNavigation.ScrollResourcesEx(
|
|
AGoForward: Boolean; var AResource: TcxSchedulerStorageResourceItem): Boolean;
|
|
begin
|
|
Result := ScrollResources(AGoForward);
|
|
if Result then
|
|
begin
|
|
if not AGoForward then
|
|
AResource := VisibleResources[ResourceNavigator.FirstVisibleResourceIndex]
|
|
else
|
|
with ResourceNavigator do
|
|
AResource := VisibleResources[ResourcesPerPage + FirstVisibleResourceIndex - 1];
|
|
end;
|
|
end;
|
|
|
|
function TcxSchedulerViewNavigation.ScrollResourcesCycled(
|
|
AGoForward: Boolean; var AResource: TcxSchedulerStorageResourceItem): Boolean;
|
|
begin
|
|
Result := False;
|
|
if AGoForward and (ResourceNavigator.FirstVisibleResourceIndex > 0) then
|
|
begin
|
|
ResourceNavigator.FirstVisibleResourceIndex := 0;
|
|
AResource := VisibleResources[0];
|
|
Result := True;
|
|
end
|
|
else
|
|
if not AGoForward and (ResourceNavigator.FirstVisibleResourceIndex = 0) then
|
|
begin
|
|
AResource := VisibleResources[VisibleResourceCount - 1];
|
|
ResourceNavigator.FirstVisibleResourceIndex :=
|
|
VisibleResourceCount - ResourceNavigator.ResourcesPerPage;
|
|
Result := True;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerViewNavigation.SetSelAnchor(
|
|
const Anchor: TDateTime; AShift: TShiftState);
|
|
begin
|
|
SetSelAnchor(Anchor, AShift, SelResource);
|
|
end;
|
|
|
|
procedure TcxSchedulerViewNavigation.SetSelAnchor(
|
|
const Anchor: TDateTime; AShift: TShiftState;
|
|
AResource: TcxSchedulerStorageResourceItem);
|
|
var
|
|
APrevSelResource: TObject;
|
|
APrevSelStart, APrevSelFinish: TDateTime;
|
|
|
|
procedure StoreSelection;
|
|
begin
|
|
with Scheduler do
|
|
begin
|
|
APrevSelResource := SelResource;
|
|
APrevSelStart := SelStart;
|
|
APrevSelFinish := SelFinish;
|
|
end;
|
|
end;
|
|
|
|
function NeedUpdateOnMouseAction: Boolean;
|
|
begin
|
|
with Scheduler do
|
|
Result := (ssLeft in AShift) and ((SelResource <> APrevSelResource) or
|
|
(SelStart <> APrevSelStart) or (SelFinish <> APrevSelFinish));
|
|
end;
|
|
|
|
begin
|
|
StoreSelection;
|
|
if not (ssShift in AShift) or (AResource <> SelResource) then
|
|
Scheduler.ReplaceSelParams(Anchor, Anchor, AResource)
|
|
else
|
|
Scheduler.ReplaceSelParams(Scheduler.FSelStart, Anchor, AResource);
|
|
if NeedUpdateOnMouseAction then
|
|
View.LayoutChanged;
|
|
end;
|
|
|
|
procedure TcxSchedulerViewNavigation.ValidateSelection(var ASelStart,
|
|
ASelFinish: TDateTime; var AResource: TcxSchedulerStorageResourceItem);
|
|
begin
|
|
end;
|
|
|
|
procedure TcxSchedulerViewNavigation.DoKeyDown(
|
|
var AKey: Word; AShift: TShiftState);
|
|
begin
|
|
Scheduler.BeginUpdate;
|
|
try
|
|
FCurrentAnchor := SelAnchor;
|
|
FCurrentResource := SelResource;
|
|
FShift := AShift;
|
|
KeyDown(AKey, AShift);
|
|
Scheduler.LayoutChanged;
|
|
finally
|
|
Scheduler.EndUpdate;
|
|
end;
|
|
end;
|
|
|
|
function TcxSchedulerViewNavigation.IsKeyNavigation(
|
|
var AKey: Word; AShift: TShiftState): Boolean;
|
|
begin
|
|
Result := (AKey = VK_UP) or (AKey = VK_DOWN) or (AKey = VK_Next) or
|
|
(AKey = VK_Prior) or (AKey = VK_Left) or (AKey = VK_Right) or
|
|
(AKey = VK_Home) or (AKey = VK_End);
|
|
end;
|
|
|
|
function TcxSchedulerViewNavigation.IsSingleLine: Boolean;
|
|
begin
|
|
Result := TimeOf(Abs(Scheduler.FSelStart -
|
|
Scheduler.FSelFinish)) <= View.GetTimeIncrement;
|
|
end;
|
|
|
|
function TcxSchedulerViewNavigation.GetResourceItem: TcxSchedulerStorageResourceItem;
|
|
begin
|
|
Result := nil;
|
|
end;
|
|
|
|
procedure TcxSchedulerViewNavigation.KeyDown(var AKey: Word; AShift: TShiftState);
|
|
begin
|
|
end;
|
|
|
|
procedure TcxSchedulerViewNavigation.ReplaceDate(
|
|
ADate: TDateTime; AResource: TcxSchedulerStorageResourceItem);
|
|
begin
|
|
if ADate >= LastAvailableDate then Exit;
|
|
if AResource = nil then
|
|
AResource := SelResource;
|
|
with Scheduler do
|
|
begin
|
|
ADate := ADate - DateOf(FSelFinish);
|
|
ReplaceSelParams(FSelStart + ADate, FSelFinish + ADate, AResource);
|
|
end;
|
|
end;
|
|
|
|
function TcxSchedulerViewNavigation.GetResourceNavigator: TcxSchedulerResourceNavigator;
|
|
begin
|
|
Result := Scheduler.ResourceNavigator;
|
|
end;
|
|
|
|
function TcxSchedulerViewNavigation.GetScheduler: TcxCustomScheduler;
|
|
begin
|
|
Result := View.Scheduler;
|
|
end;
|
|
|
|
function TcxSchedulerViewNavigation.GetSelAnchor: TDateTime;
|
|
begin
|
|
Result := Scheduler.FSelFinish
|
|
end;
|
|
|
|
function TcxSchedulerViewNavigation.GetSelRealStart: TDateTime;
|
|
begin
|
|
Result := Scheduler.FSelStart;
|
|
end;
|
|
|
|
function TcxSchedulerViewNavigation.GetSelFinish: TDateTime;
|
|
begin
|
|
Result := Max(Scheduler.FSelFinish, Scheduler.FSelStart);
|
|
end;
|
|
|
|
function TcxSchedulerViewNavigation.GetSelResource: TcxSchedulerStorageResourceItem;
|
|
begin
|
|
Result := Scheduler.SelResource;
|
|
end;
|
|
|
|
function TcxSchedulerViewNavigation.GetSelStart: TDateTime;
|
|
begin
|
|
Result := Min(Scheduler.FSelFinish, Scheduler.FSelStart);
|
|
end;
|
|
|
|
function TcxSchedulerViewNavigation.GetTimeIncrement: TDateTime;
|
|
begin
|
|
Result := View.GetTimeIncrement;
|
|
end;
|
|
|
|
function TcxSchedulerViewNavigation.GetVisibleResource(
|
|
AIndex: Integer): TcxSchedulerStorageResourceItem;
|
|
begin
|
|
if Scheduler.StorageValid then
|
|
Result := Scheduler.Storage.Resources.ResourceItems.VisibleResources[AIndex]
|
|
else
|
|
Result := nil;
|
|
end;
|
|
|
|
function TcxSchedulerViewNavigation.GetVisibleResourceCount: Integer;
|
|
begin
|
|
if Scheduler.StorageValid then
|
|
Result := Scheduler.Storage.Resources.ResourceItems.VisibleResourceCount
|
|
else
|
|
Result := 0;
|
|
end;
|
|
|
|
{ TcxSchedulerViewController }
|
|
|
|
constructor TcxSchedulerViewController.Create(AOwner: TcxSchedulerSubControl);
|
|
begin
|
|
inherited Create(AOwner);
|
|
FNavigation := CreateNavigation;
|
|
end;
|
|
|
|
destructor TcxSchedulerViewController.Destroy;
|
|
begin
|
|
FNavigation.Free;
|
|
inherited Destroy;
|
|
end;
|
|
|
|
function TcxSchedulerViewController.CanCreateEventUsingDialog: Boolean;
|
|
begin
|
|
with Scheduler.EventOperations do
|
|
Result := Scheduler.StorageActive and CanShowEventDialog and Creating and
|
|
DialogEditing and not GetResourceReadOnly;
|
|
end;
|
|
|
|
function TcxSchedulerViewController.CanCreateEventUsingInplaceEdit: Boolean;
|
|
begin
|
|
with Scheduler.EventOperations do
|
|
Result := Scheduler.StorageActive and Creating and InplaceEditing and
|
|
not GetResourceReadOnly and IsCaptionAvailable and (Scheduler.SelectedEventCount = 0);
|
|
end;
|
|
|
|
function TcxSchedulerViewController.CanEditEvent(
|
|
AEvent: TcxSchedulerControlEvent; AInplace: Boolean): Boolean;
|
|
begin
|
|
with Scheduler.EventOperations do
|
|
begin
|
|
if AInplace then
|
|
Result := InplaceEditing and IsCaptionAvailable and View.IsInplaceEditingEnabled
|
|
else
|
|
Result := DialogEditing and DialogShowing;
|
|
end;
|
|
Result := Result and (AEvent <> nil);
|
|
if AInplace and Result then
|
|
Result := not AEvent.ReadOnly;
|
|
end;
|
|
|
|
function TcxSchedulerViewController.CanShowEventDialog: Boolean;
|
|
begin
|
|
Result := Scheduler.EventOperations.DialogShowing and
|
|
Assigned(cxEventEditorClass);
|
|
end;
|
|
|
|
procedure TcxSchedulerViewController.DeleteSelectedEvents;
|
|
begin
|
|
StopEditShowingTimer;
|
|
Scheduler.InternalDeleteSelectedEvents(False, True);
|
|
end;
|
|
|
|
function TcxSchedulerViewController.IsEventEditing(
|
|
AEvent: TcxSchedulerControlEvent; AResource: TcxSchedulerStorageResourceItem): Boolean;
|
|
begin
|
|
Result := IsEditing and (EditController.Event = AEvent) and
|
|
(EditController.FEditResource = AResource);
|
|
end;
|
|
|
|
procedure TcxSchedulerViewController.SelectSingleEvent(
|
|
AEvent: TcxSchedulerControlEvent; ADate: TDateTime; AMakeVisible: Boolean = True);
|
|
begin
|
|
if AMakeVisible then View.MakeEventVisible(AEvent, ADate, nil);
|
|
Scheduler.EventList.Selection.Add(AEvent, []);
|
|
end;
|
|
|
|
procedure TcxSchedulerViewController.BeforeMouseDown(Button: TMouseButton;
|
|
Shift: TShiftState; X, Y: Integer);
|
|
begin
|
|
inherited BeforeMouseDown(Button, Shift, X, Y);
|
|
StopEditShowingTimer;
|
|
Scheduler.HintController.Hide;
|
|
if not CanProcessMouseMove then Exit;
|
|
HitTest.HitPoint := Point(X, Y);
|
|
FDragKind := HitTest.GetDragKind;
|
|
if DragKind <> edkNone then
|
|
begin
|
|
CloseInplaceEdit;
|
|
FDragEvent := HitTest.Event;
|
|
if FDragEvent.IsClone and (FDragEvent.Source <> nil) then
|
|
FDragEvent := TcxSchedulerControlEvent(FDragEvent.Source);
|
|
FStartDragHitTime := HitTest.Time;
|
|
FStartDragFlags := HitTest.Flags;
|
|
FStartDragResource := HitTest.Resource;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerViewController.CancelScroll;
|
|
begin
|
|
end;
|
|
|
|
function TcxSchedulerViewController.CanDrag(X, Y: Integer): Boolean;
|
|
begin
|
|
Result := (DragKind in [edkEventDragRect, edkMoveEvent]) and HitTest.HitAtTime;
|
|
if Result then
|
|
begin
|
|
if Scheduler.EventList.Selection.IsSelected(DragEvent) and not Scheduler.HasConflict(True) then
|
|
Result := Scheduler.DoBeforeDragEvent(DragEvent, X, Y)
|
|
else
|
|
begin
|
|
Result := False;
|
|
SendMessage(Scheduler.Handle, WM_CANCELMODE, 0, 0);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerViewController.CheckOpenInplaceEditorOnMouseUp(
|
|
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
|
|
var
|
|
AEvent: TcxSchedulerControlEvent;
|
|
begin
|
|
if (HitTest.HitAtEvent and (HitTest.Event = FBeforeFocusedEvent)) and (Button = mbLeft) and
|
|
([ssShift, ssCtrl] * Shift = []) and not (DragKind in [edkResizeStart, edkResizeEnd]) then
|
|
begin
|
|
AEvent := HitTest.Event;
|
|
if cxRectPtIn(View.GetEditRectForEvent(AEvent, DateOf(HitTest.Time),
|
|
HitTest.Resource), X, Y) and CanEditEvent(AEvent, True) then
|
|
begin
|
|
EditController.Init(HitTest.Time, HitTest.Resource);
|
|
StartEditShowingTimer(AEvent);
|
|
end;
|
|
end;
|
|
FBeforeFocusedEvent := nil;
|
|
end;
|
|
|
|
procedure TcxSchedulerViewController.CheckScrolling(
|
|
const APos: TPoint);
|
|
begin
|
|
end;
|
|
|
|
procedure TcxSchedulerViewController.CheckScrollOnDragOver(
|
|
const P: TPoint; State: TDragState);
|
|
begin
|
|
if State <> dsDragLeave then
|
|
CheckScrolling(P)
|
|
else
|
|
CancelScroll;
|
|
end;
|
|
|
|
procedure TcxSchedulerViewController.CheckUpdateEventBounds;
|
|
var
|
|
ASizingHelper: TcxEventSizingHelper;
|
|
begin
|
|
if (Scheduler.DragAndDropState = ddsInProcess) and
|
|
(Scheduler.DragAndDropObject is TcxSchedulerDragAndDropObject) then
|
|
begin
|
|
ASizingHelper := TcxSchedulerDragAndDropObject(Scheduler.DragAndDropObject).SizingHelper;
|
|
if ASizingHelper <> nil then
|
|
ASizingHelper.UpdateEventBounds;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerViewController.CloseInplaceEdit;
|
|
begin
|
|
if EditController.IsEditing then
|
|
begin
|
|
EditController.CloseEdit(True);
|
|
HitTest.Recalculate;
|
|
end;
|
|
end;
|
|
|
|
function TcxSchedulerViewController.CreateResizeEventHelper: TcxEventSizingHelper;
|
|
begin
|
|
Result := TcxEventSizingHelper.Create(Scheduler);
|
|
end;
|
|
|
|
function TcxSchedulerViewController.ConsiderHiddenEvents: Boolean;
|
|
begin
|
|
Result := True;
|
|
end;
|
|
|
|
function TcxSchedulerViewController.CreateDragEventHelper: TcxDragEventHelper;
|
|
begin
|
|
Result := TcxDragEventHelper.Create(Scheduler);
|
|
end;
|
|
|
|
function TcxSchedulerViewController.CreateNavigation: TcxSchedulerViewNavigation;
|
|
begin
|
|
Result := TcxSchedulerViewNavigation.Create(View);
|
|
end;
|
|
|
|
procedure TcxSchedulerViewController.DoSchedulerDragOver(const P: TPoint;
|
|
AState: TDragState; var AAccept: Boolean);
|
|
begin
|
|
if Assigned(Scheduler.OnDragOver) then
|
|
Scheduler.OnDragOver(Scheduler, DragEvent, P.X, P.Y, AState, AAccept);
|
|
end;
|
|
|
|
procedure TcxSchedulerViewController.DragOver(Source: TObject; X, Y: Integer;
|
|
State: TDragState; var Accept: Boolean);
|
|
var
|
|
P: TPoint;
|
|
begin
|
|
Owner.MousePositionChanged(X, Y);
|
|
P := cxPoint(X, Y);
|
|
if Assigned(DragEventHelper) then
|
|
begin
|
|
if State = dsDragMove then
|
|
CheckNavigatorScrollArea(P);
|
|
if Accept then
|
|
DragEventHelper.DragOver(P, State, Accept);
|
|
DragEventHelper.UpdateHelperState(Accept);
|
|
end;
|
|
CheckScrollOnDragOver(P, State);
|
|
end;
|
|
|
|
procedure TcxSchedulerViewController.EndDrag(Target: TObject; X, Y: Integer);
|
|
var
|
|
APos: TPoint;
|
|
begin
|
|
DoneNavigatorScrollArea;
|
|
if Assigned(DragEventHelper) then
|
|
try
|
|
APos := Scheduler.ScreenToClient(GetMouseCursorPos);
|
|
Owner.MousePositionChanged(APos.X, APos.Y);
|
|
FDragEventHelper.FTarget := Target;
|
|
FDragEventHelper.EndDrag(not Scheduler.IsDragCanceled);
|
|
finally
|
|
FreeAndNil(FDragEventHelper);
|
|
end;
|
|
end;
|
|
|
|
function TcxSchedulerViewController.GetDragAndDropObjectClass: TcxDragAndDropObjectClass;
|
|
begin
|
|
Result := TcxSchedulerDragAndDropObject;
|
|
end;
|
|
|
|
function TcxSchedulerViewController.GetResourceReadOnly: Boolean;
|
|
begin
|
|
with Scheduler do
|
|
Result := not StorageValid or
|
|
((SelResource <> nil) and SelResource.ReadOnly) or
|
|
((Storage.ResourceCount > 0) and ((SelResource = nil) and not OptionsView.ShowEventsWithoutResource));
|
|
end;
|
|
|
|
function TcxSchedulerViewController.IsCaptionAvailable: Boolean;
|
|
begin
|
|
Result := Scheduler.StorageValid and Scheduler.Storage.IsCaptionAvailable;
|
|
end;
|
|
|
|
function TcxSchedulerViewController.IsCopyDragDrop: Boolean;
|
|
begin
|
|
Result := Scheduler.IsCopyDragDrop;
|
|
end;
|
|
|
|
function TcxSchedulerViewController.IsDragOperation: Boolean;
|
|
begin
|
|
Result := Scheduler.Dragging or (Scheduler.DragAndDropState <> ddsNone);
|
|
end;
|
|
|
|
procedure TcxSchedulerViewController.KeyDown(
|
|
var Key: Word; Shift: TShiftState);
|
|
begin
|
|
if View.Active and not EditController.IsEditing then
|
|
begin
|
|
if Navigation.IsKeyNavigation(Key, Shift) then
|
|
begin
|
|
Scheduler.BeginUpdate;
|
|
try
|
|
UnselectEvents;
|
|
Navigation.DoKeyDown(Key, Shift);
|
|
finally
|
|
Scheduler.EndUpdate;
|
|
Scheduler.Update;
|
|
end;
|
|
end;
|
|
case Key of
|
|
VK_ESCAPE:
|
|
if Scheduler.CaptureController = Self then
|
|
UnselectEvents;
|
|
VK_TAB:
|
|
SelectNextEvent(not (ssShift in Shift));
|
|
VK_DELETE, VK_INSERT:
|
|
if not Scheduler.ClipboardController.KeyDown(Key, Shift) and (Key = VK_DELETE) then
|
|
DeleteSelectedEvents;
|
|
VK_SHIFT:
|
|
FStartSelAnchor := Scheduler.FSelStart;
|
|
VK_PROCESSKEY:
|
|
if CanCreateEventUsingInplaceEdit then
|
|
Scheduler.CreateEventUsingInplaceEdit;
|
|
end;
|
|
end;
|
|
inherited KeyDown(Key, Shift);
|
|
end;
|
|
|
|
procedure TcxSchedulerViewController.KeyPress(var Key: Char);
|
|
var
|
|
AEvent: TcxSchedulerControlEvent;
|
|
begin
|
|
with Scheduler do
|
|
begin
|
|
if IsLocked or not StorageActive or GetResourceReadOnly or
|
|
Scheduler.ClipboardController.KeyPress(Key) then Exit;
|
|
if (Key = #13) or IsEditStartChar(Key) then
|
|
begin
|
|
if Key = #13 then
|
|
begin
|
|
if SelectedEventCount > 0 then
|
|
begin
|
|
AEvent := SelectedEvents[SelectedEventCount - 1];
|
|
if CanShowEventDialog then
|
|
EditEventUsingDialog(AEvent);
|
|
end
|
|
else
|
|
begin
|
|
if CanCreateEventUsingInplaceEdit then
|
|
CreateEventUsingInplaceEdit
|
|
else
|
|
if CanCreateEventUsingDialog then
|
|
CreateEventUsingDialog;
|
|
end;
|
|
end
|
|
else
|
|
if CanCreateEventUsingInplaceEdit then
|
|
DoCreateEventUsingInplaceEdit(Key);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerViewController.MouseDown(
|
|
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
|
|
var
|
|
AEvent: TcxSchedulerControlEvent;
|
|
begin
|
|
CloseInplaceEdit;
|
|
if HitTest.HitAtEvent then
|
|
begin
|
|
AEvent := HitTest.Event;
|
|
FBeforeFocusedEvent := AEvent;
|
|
UpdateEventSelection(AEvent, Button, Shift);
|
|
if Shift = [ssLeft, ssDouble] then
|
|
ShowEventEditor(AEvent)
|
|
else
|
|
View.Refresh;
|
|
end
|
|
else
|
|
if Button = mbLeft then
|
|
begin
|
|
UnselectEvents;
|
|
if HitTest.HitAtTime then
|
|
begin
|
|
FStartSelAnchor := HitTest.Time;
|
|
if HitTest.Resource = nil then
|
|
Navigation.SetSelAnchor(HitTest.Time, Shift)
|
|
else
|
|
Navigation.SetSelAnchor(HitTest.Time, Shift, HitTest.Resource);
|
|
if (Shift = [ssLeft, ssDouble]) and CanCreateEventUsingDialog then
|
|
Scheduler.CreateEventUsingDialog;
|
|
end;
|
|
end;
|
|
inherited MouseDown(Button, Shift, X, Y);
|
|
end;
|
|
|
|
procedure TcxSchedulerViewController.MouseMove(Shift: TShiftState; X, Y: Integer);
|
|
begin
|
|
inherited MouseMove(Shift, X, Y);
|
|
if CanProcessMouseMove and (ssLeft in Shift) and not EditController.IsEditing then
|
|
begin
|
|
if (DragKind = edkNone) and HitTest.HitAtTime then
|
|
begin
|
|
if Navigation.SelResource = HitTest.Resource then
|
|
begin
|
|
// fix: AB15749
|
|
// if FStartSelAnchor <> NullDate then
|
|
// Scheduler.FSelStart := FStartSelAnchor;
|
|
Navigation.SetSelAnchor(HitTest.Time, [ssShift] + Shift)
|
|
end
|
|
else
|
|
Navigation.SetSelAnchor(Scheduler.FSelStart, [ssShift] + Shift);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerViewController.MouseUp(Button: TMouseButton;
|
|
Shift: TShiftState; X, Y: Integer);
|
|
begin
|
|
inherited MouseUp(Button, Shift, X, Y);
|
|
CheckOpenInplaceEditorOnMouseUp(Button, Shift, X, Y);
|
|
FStartSelAnchor := NullDate;
|
|
FDragKind := edkNone;
|
|
end;
|
|
|
|
procedure TcxSchedulerViewController.RecreateNavigation;
|
|
begin
|
|
FNavigation.Free;
|
|
FNavigation := CreateNavigation;
|
|
FNavigation.CheckSelection;
|
|
end;
|
|
|
|
procedure TcxSchedulerViewController.SelectNextEvent(AForward: Boolean);
|
|
|
|
procedure GetNextSelectedIndex(var AIndex: Integer);
|
|
begin
|
|
if AForward then
|
|
Inc(AIndex)
|
|
else
|
|
Dec(AIndex);
|
|
end;
|
|
|
|
var
|
|
I, ASelectedIndex: Integer;
|
|
begin
|
|
if Scheduler.EventList.Count = 0 then
|
|
Exit;
|
|
with Scheduler do
|
|
begin
|
|
ASelectedIndex := -1;
|
|
for I := 0 to EventList.Count - 1 do
|
|
if EventList[I].Selected then
|
|
ASelectedIndex := I;
|
|
if (ASelectedIndex >= 0) and (TabOrdersList.Count > 0) then
|
|
ASelectedIndex := TabOrdersList.IndexOf(EventList[ASelectedIndex]);
|
|
GetNextSelectedIndex(ASelectedIndex);
|
|
if ASelectedIndex < -1 then
|
|
ASelectedIndex := TabOrdersList.Count - 1;
|
|
while (ASelectedIndex < TabOrdersList.Count) and (ASelectedIndex >= 0) and
|
|
not CurrentView.GetEventVisibility(TcxSchedulerControlEvent(TabOrdersList[ASelectedIndex])) do
|
|
GetNextSelectedIndex(ASelectedIndex);
|
|
if (ASelectedIndex < EventList.Count) and (ASelectedIndex >= 0) then
|
|
SelectSingleEvent(TcxSchedulerControlEvent(TabOrdersList[ASelectedIndex]), NullDate)
|
|
else
|
|
UnselectEvents;
|
|
CurrentView.Refresh;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerViewController.StartDrag(var DragObject: TDragObject);
|
|
begin
|
|
InitNavigatorScrollArea;
|
|
FDragEventHelper := CreateDragEventHelper;
|
|
if FDragEventHelper <> nil then
|
|
FDragEventHelper.FDragObject := DragObject;
|
|
end;
|
|
|
|
function TcxSchedulerViewController.StartDragAndDrop(const P: TPoint): Boolean;
|
|
begin
|
|
Result := (DragKind in [edkResizeStart, edkResizeEnd]) and
|
|
Scheduler.DoBeforeSizingEvent(DragEvent, P.X, P.Y);
|
|
end;
|
|
|
|
procedure TcxSchedulerViewController.SyncEventSelection(
|
|
AEvent: TcxSchedulerControlEvent);
|
|
begin
|
|
if View.GetTimeIncrement = 1 then
|
|
Scheduler.ReplaceSelParams(DateOf(AEvent.Start),
|
|
DateOf(AEvent.Finish) - Byte(AEvent.AllDayEvent or
|
|
(TimeOf(AEvent.Finish) = 0)) * View.GetTimeIncrement, AEvent.GetResourceItem)
|
|
else
|
|
begin
|
|
if AEvent.Start <> AEvent.Finish then
|
|
Scheduler.ReplaceSelParams(AEvent.Start,
|
|
AEvent.Finish - View.GetTimeIncrement, AEvent.GetResourceItem)
|
|
else
|
|
Scheduler.ReplaceSelParams(AEvent.Start,
|
|
AEvent.Finish, AEvent.GetResourceItem);
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerViewController.UnselectEvents;
|
|
begin
|
|
Scheduler.UnselectEvents
|
|
end;
|
|
|
|
procedure TcxSchedulerViewController.UpdateEventSelection(
|
|
AEvent: TcxSchedulerControlEvent; Button: TMouseButton; Shift: TShiftState);
|
|
begin
|
|
if AEvent = nil then Exit;
|
|
with Scheduler.EventList.Selection do
|
|
if (Button = mbRight) and (Shift * [ssCtrl, ssShift] <> [])then
|
|
begin
|
|
if not IsSelected(AEvent) then
|
|
Add(AEvent, [ssCtrl]);
|
|
end
|
|
else
|
|
Add(AEvent, Shift);
|
|
SyncEventSelection(AEvent);
|
|
end;
|
|
|
|
procedure TcxSchedulerViewController.CheckNavigatorScrollArea(const APoint: TPoint);
|
|
var
|
|
ACode: TScrollCode;
|
|
begin
|
|
if PtInArea(FUpScrollArea, APoint, False) then
|
|
ACode := scLineDown
|
|
else
|
|
if PtInArea(FDownScrollArea, APoint, True) then
|
|
ACode := scLineUp
|
|
else
|
|
ACode := scEndScroll;
|
|
NavigatorTimer.Tag := Byte(ACode);
|
|
if not NavigatorTimer.Enabled then
|
|
NavigatorTimer.Interval := cxNavigatorStartTimer;
|
|
NavigatorTimer.Enabled := ACode <> scEndScroll;
|
|
end;
|
|
|
|
procedure TcxSchedulerViewController.DoneNavigatorScrollArea;
|
|
begin
|
|
NavigatorTimer.OnTimer := nil;
|
|
FUpScrollArea := cxNullRect;
|
|
FDownScrollArea := cxNullRect;
|
|
end;
|
|
|
|
procedure TcxSchedulerViewController.InitNavigatorScrollArea;
|
|
begin
|
|
if Scheduler.ResourceNavigator.NeedScrollBar then
|
|
begin
|
|
FUpScrollArea := TcxSchedulerCustomView(Owner).GetViewContentRect;
|
|
FDownScrollArea := FUpScrollArea;
|
|
if Scheduler.ResourceNavigator.ScrollBarKind = sbHorizontal then
|
|
begin
|
|
FUpScrollArea.Left := FUpScrollArea.Right - cxScrollZoneSize;
|
|
FDownScrollArea.Right := FDownScrollArea.Left + cxScrollZoneSize;
|
|
end
|
|
else
|
|
begin
|
|
FDownScrollArea.Bottom := FDownScrollArea.Top + cxScrollZoneSize;
|
|
FUpScrollArea.Top := FUpScrollArea.Bottom - cxScrollZoneSize;
|
|
end;
|
|
NavigatorTimer.OnTimer := NavigatorTimerHandler;
|
|
end
|
|
end;
|
|
|
|
procedure TcxSchedulerViewController.NavigatorTimerHandler(Sender: TObject);
|
|
var
|
|
APos: Integer;
|
|
APoint: TPoint;
|
|
ACode: TScrollCode;
|
|
begin
|
|
APoint := cxPointOffset(Scheduler.ScreenToClient(GetMouseCursorPos),
|
|
-View.Left, -View.Top);
|
|
if not PtInRect(View.ClientRect, APoint) then Exit;
|
|
ACode := TScrollCode(NavigatorTimer.Tag);
|
|
APos := Scheduler.ResourceNavigator.FirstVisibleResourceIndex;
|
|
Scheduler.ResourceNavigator.Scroll(ACode, APos);
|
|
if DragEventHelper <> nil then
|
|
DragEventHelper.Update;
|
|
Scheduler.Update;
|
|
end;
|
|
|
|
function TcxSchedulerViewController.PtInArea(
|
|
const ARect: TRect; const P: TPoint; IsUpArea: Boolean): Boolean;
|
|
var
|
|
AHorz: Boolean;
|
|
begin
|
|
if not PtInRect(View.ClientRect, P) then
|
|
begin
|
|
Result := False;
|
|
Exit;
|
|
end;
|
|
Result := PtInRect(ARect, P);
|
|
if not Result then
|
|
begin
|
|
AHorz := Scheduler.ResourceNavigator.ScrollBarKind = sbHorizontal;
|
|
if IsUpArea then
|
|
Result := (AHorz and (P.X < ARect.Left)) or
|
|
(not AHorz and (P.Y < ARect.Top))
|
|
else
|
|
Result := (AHorz and (P.X > ARect.Right)) or
|
|
(not AHorz and (P.Y > ARect.Bottom))
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerViewController.EditShowingTimerHandler(Sender: TObject);
|
|
begin
|
|
StopEditShowingTimer;
|
|
EditController.Activate(FEditShowingTimerItem);
|
|
end;
|
|
|
|
function TcxSchedulerViewController.GetHitTest: TcxSchedulerViewHitTest;
|
|
begin
|
|
Result := View.HitTest;
|
|
end;
|
|
|
|
function TcxSchedulerViewController.GetEditController: TcxSchedulerEditController;
|
|
begin
|
|
Result := Scheduler.EditController;
|
|
end;
|
|
|
|
function TcxSchedulerViewController.GetIsEditing: Boolean;
|
|
begin
|
|
Result := EditController.IsEditing;
|
|
end;
|
|
|
|
function TcxSchedulerViewController.GetNavigatorTimer: TTimer;
|
|
begin
|
|
Result := Scheduler.ResourceNavigator.Timer;
|
|
end;
|
|
|
|
function TcxSchedulerViewController.GetScheduler: TcxCustomScheduler;
|
|
begin
|
|
Result := Owner.Scheduler;
|
|
end;
|
|
|
|
function TcxSchedulerViewController.GetView: TcxSchedulerCustomView;
|
|
begin
|
|
Result := TcxSchedulerCustomView(inherited Owner);
|
|
end;
|
|
|
|
procedure TcxSchedulerViewController.ShowEventEditor(
|
|
AEvent: TcxSchedulerControlEvent);
|
|
begin
|
|
StopEditShowingTimer;
|
|
if CanShowEventDialog then
|
|
Scheduler.EditEventUsingDialog(AEvent);
|
|
end;
|
|
|
|
procedure TcxSchedulerViewController.StartEditShowingTimer(
|
|
AEvent: TcxSchedulerControlEvent);
|
|
begin
|
|
StopEditShowingTimer;
|
|
FEditShowingTimerItem := AEvent;
|
|
FEditShowingTimer := TTimer.Create(nil);
|
|
FEditShowingTimer.Interval := GetDblClickInterval;
|
|
FEditShowingTimer.OnTimer := EditShowingTimerHandler;
|
|
end;
|
|
|
|
procedure TcxSchedulerViewController.StopEditShowingTimer;
|
|
begin
|
|
FreeAndNil(FEditShowingTimer);
|
|
end;
|
|
|
|
{ TcxEventSizingHelper }
|
|
|
|
procedure TcxEventSizingHelper.BeginDrag;
|
|
begin
|
|
inherited BeginDrag;
|
|
if IsValidTime then
|
|
begin
|
|
UpdateEventBounds;
|
|
CalculateConflicts;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxEventSizingHelper.DragOver(const P: TPoint;
|
|
State: TDragState; var Accepted: Boolean);
|
|
begin
|
|
Accepted := IsValidTime;
|
|
if HasChangedState and Accepted then
|
|
begin
|
|
UpdateEventBounds;
|
|
CalculateConflicts;
|
|
end;
|
|
Controller.CheckScrolling(P);
|
|
end;
|
|
|
|
procedure TcxEventSizingHelper.EndDrag(Accepted: Boolean);
|
|
begin
|
|
if Accepted and not HasConflicts then
|
|
begin
|
|
SetSelection;
|
|
Events.PostEvent(Event);
|
|
end
|
|
else
|
|
Scheduler.FullRefresh;
|
|
end;
|
|
|
|
function TcxEventSizingHelper.GetDragCursor(Accepted: Boolean): TCursor;
|
|
const
|
|
Cursors: array[Boolean] of TCursor = (crNoDrop, crSchedulerHorzResize);
|
|
begin
|
|
Result := Cursors[not HasConflicts];
|
|
end;
|
|
|
|
function TcxEventSizingHelper.IsValidTime: Boolean;
|
|
begin
|
|
with HitTest do
|
|
Result := HitAtTime and (not HitAtResource or (FStartResource = Resource));
|
|
end;
|
|
|
|
procedure TcxEventSizingHelper.CalcAllDayEvent;
|
|
begin
|
|
end;
|
|
|
|
function TcxEventSizingHelper.GetFinishTime: TDateTime;
|
|
begin
|
|
Result := HitTest.Time;
|
|
end;
|
|
|
|
function TcxEventSizingHelper.GetStartTime: TDateTime;
|
|
begin
|
|
Result := HitTest.Time;
|
|
end;
|
|
|
|
procedure TcxEventSizingHelper.UpdateEventBounds;
|
|
var
|
|
AValue: TDateTime;
|
|
begin
|
|
CalcAllDayEvent;
|
|
case Controller.DragKind of
|
|
edkResizeStart:
|
|
begin
|
|
AValue := GetStartTime;
|
|
if AValue > Event.Finish - Ord(Event.AllDayEvent) then
|
|
AValue := Event.Finish - Ord(Event.AllDayEvent);
|
|
Event.Start := AValue;
|
|
end;
|
|
edkResizeEnd:
|
|
begin
|
|
AValue := GetFinishTime;
|
|
if AValue < Event.Start then
|
|
AValue := Event.Start;
|
|
Event.Finish := AValue + Ord(Event.AllDayEvent);
|
|
end;
|
|
end;
|
|
RefreshCurrentView;
|
|
end;
|
|
|
|
function TcxEventSizingHelper.GetEvent: TcxSchedulerControlEvent;
|
|
begin
|
|
Result := TcxSchedulerViewController(Controller).DragEvent;
|
|
end;
|
|
|
|
function TcxEventSizingHelper.GetHitTest: TcxSchedulerViewHitTest;
|
|
begin
|
|
Result := TcxSchedulerViewHitTest(inherited HitTest);
|
|
end;
|
|
|
|
{ TcxSchedulerDragAndDropObject }
|
|
|
|
constructor TcxSchedulerDragAndDropObject.Create(AControl: TcxControl);
|
|
begin
|
|
inherited Create(AControl);
|
|
FScheduler := AControl as TcxCustomScheduler;
|
|
Controller.DragAndDropObject := Self;
|
|
end;
|
|
|
|
destructor TcxSchedulerDragAndDropObject.Destroy;
|
|
begin
|
|
Controller.DragAndDropObject := nil;
|
|
inherited Destroy;
|
|
end;
|
|
|
|
procedure TcxSchedulerDragAndDropObject.BeginDragAndDrop;
|
|
begin
|
|
inherited BeginDragAndDrop;
|
|
FSizingHelper := Controller.CreateResizeEventHelper;
|
|
end;
|
|
|
|
procedure TcxSchedulerDragAndDropObject.DragAndDrop(const P: TPoint;
|
|
var Accepted: Boolean);
|
|
var
|
|
AP: TPoint;
|
|
begin
|
|
if Assigned(FSizingHelper) then
|
|
begin
|
|
AP := P;
|
|
Controller.Owner.MousePositionChanged(AP.X, AP.Y);
|
|
HitTest.HitPoint := AP;
|
|
SizingHelper.DragOver(AP, dsDragMove, Accepted);
|
|
SizingHelper.UpdateHelperState(Accepted);
|
|
end;
|
|
inherited DragAndDrop(P, Accepted);
|
|
end;
|
|
|
|
procedure TcxSchedulerDragAndDropObject.EndDragAndDrop(Accepted: Boolean);
|
|
var
|
|
AP: TPoint;
|
|
begin
|
|
if Assigned(SizingHelper) then
|
|
try
|
|
AP := CurMousePos;
|
|
Controller.Owner.MousePositionChanged(AP.X, AP.Y);
|
|
HitTest.HitPoint := AP;
|
|
Scheduler.DoAfterSizingEvent(SizingHelper.Event, AP.X, AP.Y, Accepted);
|
|
SizingHelper.EndDrag(Accepted);
|
|
finally
|
|
FreeAndNil(FSizingHelper);
|
|
end;
|
|
inherited EndDragAndDrop(Accepted);
|
|
end;
|
|
|
|
function TcxSchedulerDragAndDropObject.GetController: TcxSchedulerViewController;
|
|
begin
|
|
Result := FScheduler.CurrentView.Controller;
|
|
end;
|
|
|
|
function TcxSchedulerDragAndDropObject.GetDragAndDropCursor(
|
|
Accepted: Boolean): TCursor;
|
|
begin
|
|
if Assigned(FSizingHelper) then
|
|
Result := SizingHelper.GetDragCursor(Accepted)
|
|
else
|
|
Result := inherited GetDragAndDropCursor(Accepted);
|
|
end;
|
|
|
|
function TcxSchedulerDragAndDropObject.GetHitTest: TcxSchedulerViewHitTest;
|
|
begin
|
|
Result := FScheduler.CurrentView.HitTest;
|
|
end;
|
|
|
|
{ TcxSchedulerHintController }
|
|
|
|
constructor TcxSchedulerHintController.Create(AOwner: TcxCustomScheduler);
|
|
begin
|
|
FOwner := AOwner;
|
|
FTimer := TTimer.Create(nil);
|
|
FTimer.Enabled := False;
|
|
FTimer.OnTimer := TimerHandler;
|
|
FHintWindow := HintWindowClass.Create(nil);
|
|
end;
|
|
|
|
destructor TcxSchedulerHintController.Destroy;
|
|
begin
|
|
Hide;
|
|
FreeAndNil(FTimer);
|
|
FreeAndNil(FHintWindow);
|
|
inherited Destroy;
|
|
end;
|
|
|
|
procedure TcxSchedulerHintController.Activate(const AHintRect: TRect;
|
|
const AHintText: string; AImmediateHint: Boolean = False; AAutoHide: Boolean = True);
|
|
begin
|
|
Hide;
|
|
FHintText := AHintText;
|
|
FHintRect := AHintRect;
|
|
FAutoHide := AAutoHide;
|
|
if AImmediateHint then
|
|
ShowHint
|
|
else
|
|
StartShowHintTimer;
|
|
end;
|
|
|
|
function TcxSchedulerHintController.CalcHintRect(AMaxWidth: Integer;
|
|
const AHintText: string; AFlags: Integer): TRect;
|
|
begin
|
|
CheckHintClass;
|
|
FHintFlags := AFlags;
|
|
Result := FHintWindow.CalcHintRect(AMaxWidth, AHintText, nil);
|
|
end;
|
|
|
|
procedure TcxSchedulerHintController.Hide;
|
|
begin
|
|
HideHint;
|
|
end;
|
|
|
|
procedure TcxSchedulerHintController.Reset;
|
|
begin
|
|
Hide;
|
|
end;
|
|
|
|
procedure TcxSchedulerHintController.MouseLeave;
|
|
begin
|
|
Scheduler.MouseLeave(Scheduler);
|
|
end;
|
|
|
|
function TcxSchedulerHintController.CanShowHint: Boolean;
|
|
begin
|
|
Result := not FLockHint and Application.Active and Scheduler.OptionsView.ShowHints;
|
|
end;
|
|
|
|
procedure TcxSchedulerHintController.CheckHintClass;
|
|
begin
|
|
if FHintWindow.ClassType <> HintWindowClass then
|
|
begin
|
|
FHintWindow.Free;
|
|
FHintWindow := HintWindowClass.Create(nil);
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerHintController.HideHint;
|
|
begin
|
|
StopTimer;
|
|
if not Showing then Exit;
|
|
EndMouseTracking(Self);
|
|
FHintWindow.Hide;
|
|
ShowWindow(FHintWindow.Handle, SW_HIDE); //MUST USE ShowWindow - WIN32 BUG
|
|
FShowing := False;
|
|
end;
|
|
|
|
procedure TcxSchedulerHintController.ShowHint;
|
|
var
|
|
AHintInfo: THintInfo;
|
|
begin
|
|
HideHint;
|
|
if not CanShowHint then Exit;
|
|
CheckHintClass;
|
|
FHintWindow.Color := clInfoBk;
|
|
with GetMouseCursorPos do
|
|
begin
|
|
if FAutoHide then
|
|
begin
|
|
FHintRect := cxRectOffset(FHintRect, X, Y);
|
|
if FHintFlags and cxAlignRight = cxAlignRight then
|
|
FHintRect := cxRectSetRight(FHintRect, X);
|
|
if FHintFlags and cxAlignBottom = cxAlignBottom then
|
|
FHintRect := cxRectSetTop(FHintRect, Y + cxGetCursorSize.cy);
|
|
end;
|
|
end;
|
|
if cxProcessControlHintInfo(AHintInfo, FHintWindow, Scheduler, FHintText, FHintRect) then
|
|
begin
|
|
FHintText := AHintInfo.HintStr;
|
|
cxActivateHint(FHintWindow, FHintRect, FHintText);
|
|
BeginMouseTracking(Scheduler, Scheduler.ClientBounds, Self);
|
|
FShowing := True;
|
|
if FAutoHide then StartHideHintTimer;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerHintController.StartHideHintTimer;
|
|
begin
|
|
FTimer.Tag := 0;
|
|
FTimer.Interval := Application.HintHidePause;
|
|
FTimer.Enabled := True;
|
|
end;
|
|
|
|
procedure TcxSchedulerHintController.StartShowHintTimer;
|
|
begin
|
|
FTimer.Tag := 1;
|
|
FTimer.Interval := Max(Application.HintShortPause, 1);
|
|
FTimer.Enabled := True;
|
|
end;
|
|
|
|
procedure TcxSchedulerHintController.StopTimer;
|
|
begin
|
|
FTimer.Enabled := False;
|
|
end;
|
|
|
|
procedure TcxSchedulerHintController.TimerHandler(Sender: TObject);
|
|
begin
|
|
if FTimer.Tag = 0 then
|
|
HideHint
|
|
else
|
|
ShowHint;
|
|
end;
|
|
|
|
{ TcxSchedulerEventHitTestController }
|
|
|
|
constructor TcxSchedulerEventHitTestController.Create(
|
|
AOwner: TcxCustomScheduler);
|
|
begin
|
|
FOwner := AOwner;
|
|
end;
|
|
|
|
procedure TcxSchedulerEventHitTestController.HideEventHint;
|
|
begin
|
|
if FPrevHintEvent <> nil then
|
|
begin
|
|
HintController.HideHint;
|
|
FPrevHintEvent := nil;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerEventHitTestController.MouseMove(
|
|
X, Y: Integer; AShift: TShiftState);
|
|
var
|
|
R: TRect;
|
|
AHintText: string;
|
|
begin
|
|
if Scheduler.IsDesigning then Exit;
|
|
HitTest.HitPoint := Point(X, Y);
|
|
if ((ssLeft in AShift) or not HitTest.HitAtEvent) {and HintController.ViewMode} then
|
|
begin
|
|
HideEventHint;
|
|
Exit;
|
|
end;
|
|
if HitTest.HitAtEvent and (FPrevHintEvent <> HitTest.Event) then
|
|
begin
|
|
HitTest.FNeedShowHint := Scheduler.NeedShowHint(HitTest.Event, AHintText, HitTest.NeedShowHint);
|
|
if HitTest.NeedShowHint then
|
|
begin
|
|
FPrevHintEvent := HitTest.Event;
|
|
R := HintController.CalcHintRect(Max(cxscMinHintWidth,
|
|
cxRectWidth(HitTest.FEventBounds)), AHintText, cxAlignBottom);
|
|
HintController.Activate(R, AHintText);
|
|
end
|
|
else
|
|
HideEventHint;
|
|
if Scheduler.OptionsView.HotTrack then
|
|
Scheduler.CurrentView.InvalidateRect(HitTest.FEventBounds);
|
|
end;
|
|
end;
|
|
|
|
function TcxSchedulerEventHitTestController.GetHintController: TcxSchedulerHintController;
|
|
begin
|
|
Result := Scheduler.HintController;
|
|
end;
|
|
|
|
function TcxSchedulerEventHitTestController.GetHitTest: TcxSchedulerViewHitTest;
|
|
begin
|
|
Result := Scheduler.CurrentView.HitTest;
|
|
end;
|
|
|
|
{ TcxSchedulerCustomView }
|
|
|
|
constructor TcxSchedulerCustomView.Create(AOwner: TcxCustomScheduler);
|
|
begin
|
|
inherited Create(AOwner);
|
|
FVisible := False;
|
|
FCanShow := True;
|
|
end;
|
|
|
|
procedure TcxSchedulerCustomView.Assign(Source: TPersistent);
|
|
begin
|
|
if Source is TcxSchedulerCustomView then
|
|
with TcxSchedulerCustomView(Source) do
|
|
begin
|
|
Self.CanShow := CanShow;
|
|
Self.Active := Active;
|
|
end;
|
|
inherited Assign(Source);
|
|
end;
|
|
|
|
function TcxSchedulerCustomView.CanDeactivateOnDateNavigatorSelectionChange: Boolean;
|
|
begin
|
|
Result := True;
|
|
end;
|
|
|
|
function TcxSchedulerCustomView.CanSelectPeriod: Boolean;
|
|
begin
|
|
Result := True;
|
|
end;
|
|
|
|
function TcxSchedulerCustomView.CheckEventsVisibility: Boolean;
|
|
begin
|
|
Result := True;
|
|
end;
|
|
|
|
function TcxSchedulerCustomView.CreateController: TcxSchedulerSubControlController;
|
|
begin
|
|
Result := TcxSchedulerViewController.Create(Self);
|
|
end;
|
|
|
|
function TcxSchedulerCustomView.CreateHitTest: TcxSchedulerSubControlHitTest;
|
|
begin
|
|
Result := TcxSchedulerViewHitTest.Create(Self);
|
|
end;
|
|
|
|
procedure TcxSchedulerCustomView.DateChanged;
|
|
begin
|
|
Refresh;
|
|
end;
|
|
|
|
procedure TcxSchedulerCustomView.DeactivateView;
|
|
begin
|
|
end;
|
|
|
|
procedure TcxSchedulerCustomView.DoLayoutChanged;
|
|
begin
|
|
TcxSchedulerCustomViewViewInfo(ViewInfo).FSelectedDays := Scheduler.SelectedDays;
|
|
TcxSchedulerCustomViewViewInfo(ViewInfo).FEvents := Scheduler.EventList;
|
|
inherited DoLayoutChanged;
|
|
Scheduler.UpdateScrollBars;
|
|
end;
|
|
|
|
function TcxSchedulerCustomView.DoShowPopupMenu(X, Y: Integer): Boolean;
|
|
begin
|
|
Result := False;
|
|
end;
|
|
|
|
function TcxSchedulerCustomView.EventContentSelected(
|
|
AEvent: TcxSchedulerControlEvent): Boolean;
|
|
begin
|
|
Result := True;
|
|
end;
|
|
|
|
function TcxSchedulerCustomView.GetClientRect: TRect;
|
|
begin
|
|
Result := inherited GetClientRect;
|
|
if Scheduler.HScrollBarVisible then
|
|
Dec(Result.Bottom, Scheduler.HScrollBar.Height);
|
|
if Scheduler.VScrollBarVisible then
|
|
Dec(Result.Right, Scheduler.VScrollBar.Width);
|
|
end;
|
|
|
|
function TcxSchedulerCustomView.GetControlCanvas: TcxCanvas;
|
|
begin
|
|
Result := Scheduler.GetInternalCanvas;
|
|
end;
|
|
|
|
function TcxSchedulerCustomView.GetDateOffset: Integer;
|
|
begin
|
|
Result := 1 - Ord(OptionsView.ActualStartOfWeek);
|
|
end;
|
|
|
|
function TcxSchedulerCustomView.GetDragObjectClass: TDragControlObjectClass;
|
|
begin
|
|
Result := TcxSchedulerDragObject;
|
|
end;
|
|
|
|
function TcxSchedulerCustomView.GetGroupingKind: TcxSchedulerGroupingKind;
|
|
begin
|
|
Result := gkNone;
|
|
end;
|
|
|
|
function TcxSchedulerCustomView.GetHScrollBarBounds: TRect;
|
|
begin
|
|
Result := ClientRect;
|
|
Result.Top := Result.Bottom;
|
|
Result.Bottom := Result.Top + Scheduler.HScrollBar.Height;
|
|
OffsetRect(Result, Bounds.Left, Bounds.Top);
|
|
with Scheduler.ResourceNavigator do
|
|
begin
|
|
if NeedScrollBar and (ScrollBarKind = sbHorizontal) then
|
|
Inc(Result.Left, MeasureWidth);
|
|
end;
|
|
end;
|
|
|
|
function TcxSchedulerCustomView.GetEditRectForEvent(
|
|
AEvent: TcxSchedulerControlEvent; const ADate: TDateTime;
|
|
AResource: TcxSchedulerStorageResourceItem): TRect;
|
|
begin
|
|
Result := cxNullRect;
|
|
end;
|
|
|
|
function TcxSchedulerCustomView.GetEditStyle(
|
|
AEvent: TcxSchedulerControlEvent): TcxCustomEditStyle;
|
|
begin
|
|
Result := Scheduler.EditStyle;
|
|
end;
|
|
|
|
function TcxSchedulerCustomView.GetEditProperties(
|
|
AEvent: TcxSchedulerControlEvent): TcxCustomEditProperties;
|
|
begin
|
|
Scheduler.DoGetEventEditProperties(AEvent, Result);
|
|
end;
|
|
|
|
function TcxSchedulerCustomView.GetEditWithSingleLineEditor(
|
|
AEvent: TcxSchedulerControlEvent): Boolean;
|
|
begin
|
|
Result := True;
|
|
end;
|
|
|
|
function TcxSchedulerCustomView.GetEventHintText(AEvent: TcxSchedulerControlEvent): string;
|
|
begin
|
|
Result := Scheduler.GetEventHintText(AEvent);
|
|
end;
|
|
|
|
function TcxSchedulerCustomView.GetEventVisibility(
|
|
AEvent: TcxSchedulerControlEvent): Boolean;
|
|
begin
|
|
Result := False;
|
|
end;
|
|
|
|
function TcxSchedulerCustomView.GetFirstVisibleDate: TDateTime;
|
|
begin
|
|
if SelectedDays.Count = 0 then
|
|
Result := Date
|
|
else
|
|
Result := Integer(SelectedDays.First)
|
|
end;
|
|
|
|
function TcxSchedulerCustomView.GetFirstVisibleTime: TDateTime;
|
|
begin
|
|
Result := 0;
|
|
end;
|
|
|
|
function TcxSchedulerCustomView.GetLastVisibleDate: TDateTime;
|
|
begin
|
|
if SelectedDays.Count = 0 then
|
|
Result := Date
|
|
else
|
|
Result := Integer(SelectedDays.Last)
|
|
end;
|
|
|
|
function TcxSchedulerCustomView.GetLastVisibleTime: TDateTime;
|
|
begin
|
|
Result := 1 - 1 / 24 / 60;
|
|
end;
|
|
|
|
function TcxSchedulerCustomView.GetSizeGripBounds: TRect;
|
|
begin
|
|
with Result do
|
|
begin
|
|
Left := Scheduler.VScrollBar.Left;
|
|
Right := Left + Scheduler.VScrollBar.Width;
|
|
Top := Scheduler.HScrollBar.Top;
|
|
Bottom := Top + Scheduler.HScrollBar.Height;
|
|
end;
|
|
end;
|
|
|
|
function TcxSchedulerCustomView.GetSchedulerLookAndFeel(
|
|
ADialogs: Boolean = False): TcxLookAndFeel;
|
|
begin
|
|
if ADialogs then
|
|
Result := Scheduler.DialogsLookAndFeel
|
|
else
|
|
Result := Scheduler.LookAndFeel;
|
|
end;
|
|
|
|
function TcxSchedulerCustomView.GetScrollTimeHint: string;
|
|
begin
|
|
Result := cxTimeToStr(GetFirstVisibleTime, ShortTimeFormat) + ' - ' +
|
|
cxTimeToStr(GetLastVisibleTime, ShortTimeFormat);
|
|
end;
|
|
|
|
function TcxSchedulerCustomView.GetTimeIncrement: TDateTime;
|
|
begin
|
|
Result := 1;
|
|
end;
|
|
|
|
function TcxSchedulerCustomView.GetVScrollBarBounds: TRect;
|
|
begin
|
|
Result := ClientRect;
|
|
Result.Left := Result.Right;
|
|
Result.Right := Result.Left + Scheduler.VScrollBar.Width;
|
|
OffsetRect(Result, Bounds.Left, Bounds.Top);
|
|
with Scheduler.ResourceNavigator do
|
|
begin
|
|
if NeedScrollBar and (ScrollBarKind = sbVertical) then
|
|
Dec(Result.Bottom, MeasureHeight);
|
|
end;
|
|
end;
|
|
|
|
function TcxSchedulerCustomView.GetViewContentRect: TRect;
|
|
begin
|
|
Result := ClientRect;
|
|
end;
|
|
|
|
function TcxSchedulerCustomView.GetVisibleDaysRange: Integer;
|
|
begin
|
|
Result := 31;
|
|
end;
|
|
|
|
procedure TcxSchedulerCustomView.InitEventBySelectedTime(
|
|
AEvent: TcxSchedulerEvent; AllDay: Boolean;
|
|
ARecurrence: Boolean; AInplaceEditing: Boolean);
|
|
var
|
|
AIsAllDaySelection: Boolean;
|
|
begin
|
|
AIsAllDaySelection := IsAllDaySelection;
|
|
AEvent.Start := Scheduler.SelStart;
|
|
AEvent.AllDayEvent := AllDay or AIsAllDaySelection;
|
|
if AllDay and not AIsAllDaySelection then
|
|
AEvent.Finish := DateOf(Scheduler.SelFinish) + 1
|
|
else
|
|
AEvent.Finish := Scheduler.SelFinish;
|
|
end;
|
|
|
|
function TcxSchedulerCustomView.IsAllDaySelection: Boolean;
|
|
var
|
|
AStart, AFinish, H, M, S, MS: Word;
|
|
begin
|
|
if DateOf(Scheduler.SelFinish - Scheduler.SelStart) >= 1 then
|
|
begin
|
|
DecodeTime(Scheduler.SelStart, H, M, S, MS);
|
|
AStart := H * 60 + M;
|
|
DecodeTime(Scheduler.SelFinish, H, M, S, MS);
|
|
AFinish := H * 60 + M;
|
|
Result := (AStart = 0) and (AFinish = 0);
|
|
end
|
|
else
|
|
Result := False;
|
|
end;
|
|
|
|
function TcxSchedulerCustomView.IsDayView: Boolean;
|
|
begin
|
|
Result := False;
|
|
end;
|
|
|
|
function TcxSchedulerCustomView.IsInplaceEditingEnabled: Boolean;
|
|
begin
|
|
Result := True;
|
|
end;
|
|
|
|
function TcxSchedulerCustomView.IsShowResources: Boolean;
|
|
begin
|
|
Result := Scheduler.HasResources;
|
|
end;
|
|
|
|
function TcxSchedulerCustomView.IsWorkTime(
|
|
AResourceItem: TcxSchedulerStorageResourceItem;
|
|
const ADateTime: TDateTime): Boolean;
|
|
begin
|
|
Result := Scheduler.DoIsWorkTime(AResourceItem, ADateTime);
|
|
end;
|
|
|
|
procedure TcxSchedulerCustomView.MakeEventVisible(
|
|
AEvent: TcxSchedulerControlEvent; const ADate: TDateTime;
|
|
AResource: TcxSchedulerStorageResourceItem);
|
|
begin
|
|
end;
|
|
|
|
procedure TcxSchedulerCustomView.PeriodChanged;
|
|
begin
|
|
Scheduler.ValidateSelection(SelectedDays);
|
|
end;
|
|
|
|
procedure TcxSchedulerCustomView.Scroll(AScrollBarKind: TScrollBarKind;
|
|
AScrollCode: TScrollCode; var AScrollPos: Integer);
|
|
begin
|
|
DoScaleScroll;
|
|
if AScrollBarKind = sbHorizontal then
|
|
Scheduler.HScrollBar.Position := AScrollPos
|
|
else
|
|
Scheduler.VScrollBar.Position := AScrollPos;
|
|
end;
|
|
|
|
procedure TcxSchedulerCustomView.ScrollSelectedDays(AScrollDelta: Integer);
|
|
begin
|
|
Scheduler.DateNavigator.ScrollSelection(AScrollDelta);
|
|
end;
|
|
|
|
procedure TcxSchedulerCustomView.ScrollSelectedDays(AForward: Boolean;
|
|
ANeedDate: TDateTime; AIsByPage: Boolean);
|
|
begin
|
|
Scheduler.DateNavigator.ScrollSelection(AForward, ANeedDate, AIsByPage);
|
|
end;
|
|
|
|
procedure TcxSchedulerCustomView.ScrollVisibleDays(
|
|
AScrollUp: Boolean);
|
|
begin
|
|
end;
|
|
|
|
procedure TcxSchedulerCustomView.SelectedDaysChanged;
|
|
begin
|
|
end;
|
|
|
|
function TcxSchedulerCustomView.ShowTaskComplete: Boolean;
|
|
begin
|
|
Result := False;
|
|
end;
|
|
|
|
procedure TcxSchedulerCustomView.TimeChanged;
|
|
begin
|
|
end;
|
|
|
|
procedure TcxSchedulerCustomView.UpdateDateNavigatorSelection;
|
|
begin
|
|
Scheduler.DateNavigator.MakeSelectionVisible;
|
|
end;
|
|
|
|
procedure TcxSchedulerCustomView.ValidateContentPopupMenuItems(
|
|
var AItems: TcxSchedulerContentPopupMenuItems);
|
|
begin
|
|
end;
|
|
|
|
procedure TcxSchedulerCustomView.ValidateSelectionFinishTime(
|
|
var ADateTime: TDateTime);
|
|
begin
|
|
end;
|
|
|
|
procedure TcxSchedulerCustomView.VisibleChanged;
|
|
begin
|
|
if Visible and not CanShow then
|
|
Visible := False
|
|
else
|
|
Scheduler.ViewVisibleChanged(Self)
|
|
end;
|
|
|
|
procedure TcxSchedulerCustomView.HideHintOnScroll(AScrollCode: TScrollCode);
|
|
begin
|
|
Scheduler.HintController.HideHint;
|
|
if AScrollCode = scEndScroll then
|
|
FCalculatedHintBounds := False;
|
|
end;
|
|
|
|
procedure TcxSchedulerCustomView.ShowHintOnScroll(const ADate: TDateTime);
|
|
begin
|
|
with Scheduler.ResourceNavigator do
|
|
begin
|
|
if NeedScrollBar and (ScrollBarKind = sbHorizontal) then
|
|
ShowHintOnScroll(DateTimeToStr(ADate), sbVertical)
|
|
else
|
|
ShowHintOnScroll(DateTimeToStr(ADate), sbHorizontal);
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerCustomView.ShowHintOnScroll(
|
|
const AHintText: string; AScrollBarKind: TScrollBarKind);
|
|
var
|
|
R: TRect;
|
|
begin
|
|
with Scheduler do
|
|
begin
|
|
R := HintController.CalcHintRect(cxscMinHintWidth, AHintText, cxAlignRight);
|
|
if not CalculatedHintBounds then
|
|
begin
|
|
if AScrollBarKind = sbVertical then
|
|
begin
|
|
R := cxRectSetRight(R, ClientToScreen(VScrollBar.BoundsRect.TopLeft).X - 5);
|
|
R := cxRectSetTop(R, GetMouseCursorPos.Y);
|
|
end
|
|
else
|
|
begin
|
|
R := cxRectSetBottom(R, ClientToScreen(HScrollBar.BoundsRect.TopLeft).Y - 5);
|
|
R := cxRectSetLeft(R, GetMouseCursorPos.X);
|
|
end;
|
|
end
|
|
else R := cxRectCenter(HintController.FHintRect, R.Right, R.Bottom);
|
|
HintController.Activate(R, AHintText, True, False);
|
|
end;
|
|
FCalculatedHintBounds := True;
|
|
end;
|
|
|
|
function TcxSchedulerCustomView.GetActive: Boolean;
|
|
begin
|
|
Result := Visible;
|
|
end;
|
|
|
|
function TcxSchedulerCustomView.GetCanShow: Boolean;
|
|
begin
|
|
Result := FCanShow;
|
|
Scheduler.DoCanShowView(Self, Result);
|
|
end;
|
|
|
|
function TcxSchedulerCustomView.GetController: TcxSchedulerViewController;
|
|
begin
|
|
Result := TcxSchedulerViewController(inherited Controller);
|
|
end;
|
|
|
|
function TcxSchedulerCustomView.GetDragCloneEventList: TcxSchedulerFilteredEventList;
|
|
begin
|
|
if Assigned(Controller.DragEventHelper) then
|
|
Result := Scheduler.EventList.Clones
|
|
else
|
|
Result := nil;
|
|
end;
|
|
|
|
function TcxSchedulerCustomView.GetEventList: TcxSchedulerCachedEventList;
|
|
begin
|
|
Result := Scheduler.EventList;
|
|
end;
|
|
|
|
function TcxSchedulerCustomView.GetHitTest: TcxSchedulerViewHitTest;
|
|
begin
|
|
Result := TcxSchedulerViewHitTest(inherited HitTest);
|
|
end;
|
|
|
|
function TcxSchedulerCustomView.GetSelectedDays: TcxSchedulerDateList;
|
|
begin
|
|
Result := Scheduler.SelectedDays
|
|
end;
|
|
|
|
function TcxSchedulerCustomView.GetOptionsView: TcxSchedulerOptionsView;
|
|
begin
|
|
Result := Scheduler.OptionsView;
|
|
end;
|
|
|
|
function TcxSchedulerCustomView.GetResources: TcxSchedulerStorageResourceItems;
|
|
begin
|
|
if Scheduler.StorageValid then
|
|
Result := Scheduler.Storage.Resources.ResourceItems
|
|
else
|
|
Result := nil;
|
|
end;
|
|
|
|
function TcxSchedulerCustomView.GetWorkDays: TDays;
|
|
begin
|
|
Result := OptionsView.WorkDays;
|
|
end;
|
|
|
|
function TcxSchedulerCustomView.GetWorkFinish: TDateTime;
|
|
begin
|
|
Result := OptionsView.WorkFinish;
|
|
end;
|
|
|
|
function TcxSchedulerCustomView.GetWorkStart: TDateTime;
|
|
begin
|
|
Result := OptionsView.WorkStart;
|
|
end;
|
|
|
|
procedure TcxSchedulerCustomView.SetActive(AValue: Boolean);
|
|
begin
|
|
Visible := FCanShow and AValue;
|
|
end;
|
|
|
|
procedure TcxSchedulerCustomView.SetCanShow(AValue: Boolean);
|
|
begin
|
|
if FCanShow <> AValue then
|
|
begin
|
|
FCanShow := AValue;
|
|
if not AValue then
|
|
Visible := False
|
|
else
|
|
begin
|
|
if not Scheduler.CurrentView.Visible then
|
|
Visible := True;
|
|
Changed;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
{ TcxSchedulerCustomViewViewInfo }
|
|
|
|
procedure TcxSchedulerCustomViewViewInfo.CheckResourceNavigator;
|
|
begin
|
|
ResourceNavigator.FScrollBarKind := GetResourceScrollBarKind;
|
|
ResourceNavigator.InitScrollBarsParameters;
|
|
end;
|
|
|
|
function TcxSchedulerCustomViewViewInfo.GetResourceScrollBarKind: TScrollBarKind;
|
|
begin
|
|
Result := sbHorizontal;
|
|
end;
|
|
|
|
function TcxSchedulerCustomViewViewInfo.DoGetEventDisplayText(
|
|
AEvent: TcxSchedulerControlEvent): string;
|
|
begin
|
|
Scheduler.DoGetEventDisplayText(AEvent, Result);
|
|
end;
|
|
|
|
function TcxSchedulerCustomViewViewInfo.DoSchedulerMoreEventsButtonClick: Boolean;
|
|
begin
|
|
Result := Scheduler.DoMoreEventsButtonClick;
|
|
end;
|
|
|
|
function TcxSchedulerCustomViewViewInfo.DoSchedulerNavigationButtonClick(
|
|
AnInterval: TDateTime; AResource: TcxSchedulerStorageResourceItem): Boolean;
|
|
begin
|
|
Result := Scheduler.DoNavigationButtonClick(AnInterval, AResource);
|
|
end;
|
|
|
|
function TcxSchedulerCustomViewViewInfo.GetEventHint(
|
|
AEvent: TcxSchedulerControlEvent): string;
|
|
begin
|
|
Result := Scheduler.GetEventHintText(AEvent);
|
|
end;
|
|
|
|
function TcxSchedulerCustomViewViewInfo.GetSchedulerEventsList: TcxSchedulerCachedEventList;
|
|
begin
|
|
Result := Scheduler.EventList;
|
|
end;
|
|
|
|
procedure TcxSchedulerCustomViewViewInfo.SetEventsVisibility(
|
|
AShowSources, AShowClones: Boolean; AForceRepaint: Boolean = False);
|
|
begin
|
|
end;
|
|
|
|
function TcxSchedulerCustomViewViewInfo.GetResourceNavigator: TcxSchedulerResourceNavigator;
|
|
begin
|
|
Result := Scheduler.ResourceNavigator;
|
|
end;
|
|
|
|
function TcxSchedulerCustomViewViewInfo.GetScheduler: TcxCustomScheduler;
|
|
begin
|
|
Result := Owner.Scheduler;
|
|
end;
|
|
|
|
{ TcxSchedulerCustomDataNavigator }
|
|
|
|
constructor TcxSchedulerCustomDateNavigator.Create(
|
|
AOwner: TcxCustomScheduler);
|
|
begin
|
|
inherited Create(AOwner);
|
|
FSaveSelectionList := TcxSchedulerDateList.Create;
|
|
end;
|
|
|
|
destructor TcxSchedulerCustomDateNavigator.Destroy;
|
|
begin
|
|
FSaveSelectionList.Free;
|
|
inherited Destroy;
|
|
end;
|
|
|
|
procedure TcxSchedulerCustomDateNavigator.BeginUpdate;
|
|
begin
|
|
if FLockCount = 0 then
|
|
SaveState;
|
|
Inc(FLockCount);
|
|
end;
|
|
|
|
procedure TcxSchedulerCustomDateNavigator.CancelUpdates;
|
|
begin
|
|
FLockCount := 0;
|
|
end;
|
|
|
|
procedure TcxSchedulerCustomDateNavigator.EndUpdate;
|
|
begin
|
|
Dec(FLockCount);
|
|
if FLockCount <= 0 then
|
|
begin
|
|
FLockCount := 0;
|
|
CheckChanges;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerCustomDateNavigator.BoundsChanging;
|
|
begin
|
|
BeginUpdate;
|
|
GetCalendarDimension(FPrevColCount, FPrevRowCount);
|
|
end;
|
|
|
|
procedure TcxSchedulerCustomDateNavigator.BoundsChanged;
|
|
var
|
|
AColCount, ARowCount: Integer;
|
|
begin
|
|
inherited BoundsChanged;
|
|
if not Scheduler.BoundsChanging and Scheduler.SubControlsCreated then
|
|
begin
|
|
GetCalendarDimension(AColCount, ARowCount);
|
|
if AColCount * ARowCount <> FPrevColCount * FPrevRowCount then
|
|
Scheduler.FullRefresh;
|
|
end;
|
|
EndUpdate;
|
|
end;
|
|
|
|
function TcxSchedulerCustomDateNavigator.CanMultiSelect: Boolean;
|
|
begin
|
|
Result := (Scheduler.CurrentView = nil) or
|
|
Scheduler.CurrentView.CanSelectPeriod;
|
|
if Result then
|
|
Result := Scheduler.CanSelectPeriod;
|
|
end;
|
|
|
|
procedure TcxSchedulerCustomDateNavigator.CheckChanges;
|
|
var
|
|
I: Integer;
|
|
ACallEvent: Boolean;
|
|
begin
|
|
if (FSaveRealFirstDate <> GetRealFirstDate) or (FSaveRealLastDate <> GetRealLastDate) then
|
|
DoPeriodChangedEvent;
|
|
Scheduler.UpdateHolidayDays(GetRealFirstDate, GetRealLastDate);
|
|
GetSelection.Changed := False;
|
|
ACallEvent := GetSelection.Count <> FSaveSelectionList.Count;
|
|
if not ACallEvent then
|
|
for I := 0 to FSaveSelectionList.Count - 1 do
|
|
if FSaveSelectionList[I] <> GetSelection[I] then
|
|
begin
|
|
ACallEvent := True;
|
|
break;
|
|
end;
|
|
if ACallEvent then
|
|
DoSelectionChangedEvent;
|
|
SaveState;
|
|
end;
|
|
|
|
procedure TcxSchedulerCustomDateNavigator.CheckCurrentDate;
|
|
begin
|
|
end;
|
|
|
|
function TcxSchedulerCustomDateNavigator.GetMonthSize: TSize;
|
|
begin
|
|
Result := cxNullSize;
|
|
end;
|
|
|
|
function TcxSchedulerCustomDateNavigator.GetSelection: TcxSchedulerDateList;
|
|
begin
|
|
Result := Scheduler.SelectedDays;
|
|
end;
|
|
|
|
function TcxSchedulerCustomDateNavigator.IsSchedulerLocked: Boolean;
|
|
begin
|
|
Result := Scheduler.AligningSubControls or Scheduler.IsLocked or
|
|
not Scheduler.HandleAllocated;
|
|
end;
|
|
|
|
procedure TcxSchedulerCustomDateNavigator.Loaded;
|
|
begin
|
|
FSavedSize := Scheduler.GetDateNavigatorLoadedSize;
|
|
end;
|
|
|
|
procedure TcxSchedulerCustomDateNavigator.PeriodChanged;
|
|
begin
|
|
Scheduler.DateNavigatorSelectionChanged;
|
|
end;
|
|
|
|
procedure TcxSchedulerCustomDateNavigator.SaveSize;
|
|
begin
|
|
FSavedSize := cxSize(Width, Height);
|
|
end;
|
|
|
|
procedure TcxSchedulerCustomDateNavigator.SaveState;
|
|
begin
|
|
FSaveSelectionList.Assign(GetSelection);
|
|
FSaveRealFirstDate := GetRealFirstDate;
|
|
FSaveRealLastDate := GetRealLastDate;
|
|
end;
|
|
|
|
procedure TcxSchedulerCustomDateNavigator.ScrollSelection(AForward: Boolean;
|
|
ANeedDate: TDateTime; AIsByPage: Boolean);
|
|
begin
|
|
BeginUpdate;
|
|
try
|
|
DoScrollSelection(AForward, ANeedDate, AIsByPage);
|
|
finally
|
|
EndUpdate;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerCustomDateNavigator.ScrollSelection(AScrollDelta: Integer);
|
|
begin
|
|
BeginUpdate;
|
|
try
|
|
DoScrollSelection(AScrollDelta);
|
|
finally
|
|
EndUpdate;
|
|
end;
|
|
end;
|
|
|
|
function TcxSchedulerCustomDateNavigator.GetEventDays: TcxSchedulerDateList;
|
|
begin
|
|
Result := Scheduler.EventDays;
|
|
end;
|
|
|
|
function TcxSchedulerCustomDateNavigator.GetHintController: TcxSchedulerHintController;
|
|
begin
|
|
Result := Scheduler.HintController;
|
|
end;
|
|
|
|
function TcxSchedulerCustomDateNavigator.GetHolidayDays: TcxSchedulerDateList;
|
|
begin
|
|
Result := Scheduler.HolidayDays;
|
|
end;
|
|
|
|
{ TcxSchedulerClipboardController }
|
|
|
|
constructor TcxSchedulerClipboardController.Create(AScheduler: TcxCustomScheduler);
|
|
begin
|
|
RegisterClipboardFormat;
|
|
FScheduler := AScheduler;
|
|
FStream := TMemoryStream.Create;
|
|
FStreamReader := TcxReader.Create(FStream);
|
|
FStreamWriter := TcxWriter.Create(FStream);
|
|
end;
|
|
|
|
destructor TcxSchedulerClipboardController.Destroy;
|
|
begin
|
|
FStream.Free;
|
|
FStreamReader.Free;
|
|
FStreamWriter.Free;
|
|
inherited Destroy;
|
|
end;
|
|
|
|
function TcxSchedulerClipboardController.CanCopy: Boolean;
|
|
begin
|
|
Result := Scheduler.SelectedEventCount > 0;
|
|
end;
|
|
|
|
function TcxSchedulerClipboardController.CanPaste: Boolean;
|
|
begin
|
|
Result := GetClipboardToStream;
|
|
if Result then
|
|
Result := ValidateStream;
|
|
end;
|
|
|
|
procedure TcxSchedulerClipboardController.Copy;
|
|
begin
|
|
Clipboard.Clear;
|
|
try
|
|
if GetSelectionAsStream then
|
|
SetStreamToClipboard;
|
|
finally
|
|
Stream.Clear;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerClipboardController.Cut;
|
|
begin
|
|
Copy;
|
|
if Scheduler.EventOperations.Deleting then
|
|
DeleteSelectedEvents;
|
|
end;
|
|
|
|
procedure TcxSchedulerClipboardController.Paste;
|
|
var
|
|
AEvents: TcxSchedulerFilteredEventList;
|
|
Anchor: TDateTime;
|
|
begin
|
|
if GetClipboardToStream then
|
|
begin
|
|
AEvents := TcxSchedulerFilteredEventList.Create;
|
|
try
|
|
if GetStreamAsEvents(AEvents, Anchor) then
|
|
InsertEvents(AEvents, Anchor);
|
|
finally
|
|
AEvents.Free;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerClipboardController.DeleteSelectedEvents;
|
|
begin
|
|
Scheduler.DeleteSelectedEvents;
|
|
end;
|
|
|
|
function TcxSchedulerClipboardController.GetClipboard: TClipboard;
|
|
begin
|
|
Result := Clipbrd.Clipboard;
|
|
end;
|
|
|
|
function TcxSchedulerClipboardController.GetClipboardToStream: Boolean;
|
|
var
|
|
AData: THandle;
|
|
ADataPtr: Pointer;
|
|
begin
|
|
Result := IsClipboardFormatAvailable(CF_SCHEDULERDATA);
|
|
if not Result then Exit;
|
|
Clipboard.Open;
|
|
try
|
|
AData := GetClipboardData(CF_SCHEDULERDATA);
|
|
if AData = 0 then Exit;
|
|
ADataPtr := GlobalLock(AData);
|
|
Result := ADataPtr <> nil;
|
|
if not Result then Exit;
|
|
try
|
|
Stream.Size := GlobalSize(AData);
|
|
Stream.Position := 0;
|
|
Stream.Write(ADataPtr^, Stream.Size);
|
|
finally
|
|
GlobalUnlock(AData);
|
|
end;
|
|
finally
|
|
Clipboard.Close;
|
|
end;
|
|
end;
|
|
|
|
function TcxSchedulerClipboardController.GetSelectionAsStream: Boolean;
|
|
var
|
|
I: Integer;
|
|
Anchor: TDateTime;
|
|
begin
|
|
Stream.Clear;
|
|
Result := Scheduler.SelectedEventCount > 0;
|
|
if not Result then Exit;
|
|
StreamWriter.WriteInteger(0);
|
|
StreamWriter.WriteInteger(Scheduler.SelectedEventCount);
|
|
Anchor := MaxInt;
|
|
for I := 0 to Scheduler.SelectedEventCount - 1 do
|
|
begin
|
|
if Anchor > Scheduler.SelectedEvents[I].Start then
|
|
Anchor := Scheduler.SelectedEvents[I].Start;
|
|
end;
|
|
StreamWriter.WriteDateTime(Anchor);
|
|
for I := 0 to Scheduler.SelectedEventCount - 1 do
|
|
SaveEvent(Scheduler.SelectedEvents[I]);
|
|
Stream.Position := 0;
|
|
StreamWriter.WriteInteger(Stream.Size);
|
|
end;
|
|
|
|
function TcxSchedulerClipboardController.GetStreamAsEvents(
|
|
AEvents: TcxSchedulerFilteredEventList; var Anchor: TDateTime): Boolean;
|
|
var
|
|
ACount: Integer;
|
|
AEvent: TcxSchedulerControlEvent;
|
|
begin
|
|
Result := ValidateStream;
|
|
if Result then
|
|
try
|
|
ACount := StreamReader.ReadInteger;
|
|
Anchor := StreamReader.ReadDateTime;
|
|
while Stream.Position <> Stream.Size do
|
|
begin
|
|
RestoreEvent(AEvent);
|
|
AEvents.Add(AEvent);
|
|
end;
|
|
Result := (AEvents.Count > 0) and (AEvents.Count = ACount);
|
|
finally
|
|
Stream.Clear;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerClipboardController.CalculateAnchorForResource(
|
|
AEvents: TcxSchedulerFilteredEventList;
|
|
const AResourceID: Variant; var Anchor: TDateTime);
|
|
var
|
|
I: Integer;
|
|
ANewAnchor: TDateTime;
|
|
begin
|
|
ANewAnchor := MaxInt;
|
|
for I := 0 to AEvents.Count - 1 do
|
|
if AEvents[I].IsSharedWithResource(AResourceID) and (ANewAnchor > AEvents[I].Start) then
|
|
ANewAnchor := AEvents[I].Start;
|
|
if ANewAnchor <> MaxInt then
|
|
Anchor := ANewAnchor;
|
|
end;
|
|
|
|
procedure TcxSchedulerClipboardController.InsertEvents(
|
|
AEvents: TcxSchedulerFilteredEventList; Anchor: TDateTime);
|
|
var
|
|
I: Integer;
|
|
AEvent: TcxSchedulerControlEvent;
|
|
AllDayDuration: Boolean;
|
|
IsDifferenceResources: Boolean;
|
|
begin
|
|
if not Scheduler.EventOperations.Creating then Exit;
|
|
IsDifferenceResources := False;
|
|
for I := 1 to AEvents.Count - 1 do
|
|
begin
|
|
IsDifferenceResources := not VarEquals(AEvents[I - 1].ResourceID, AEvents[I].ResourceID);
|
|
if IsDifferenceResources then Break;
|
|
end;
|
|
if IsDifferenceResources and (Scheduler.SelResource <> nil) then
|
|
CalculateAnchorForResource(AEvents, Scheduler.SelResource.ResourceID, Anchor);
|
|
Anchor := Scheduler.SelStart - Anchor;
|
|
AllDayDuration := Round(Frac(Anchor) / MinuteToTime) = 0;
|
|
Storage.BeginUpdate;
|
|
try
|
|
for I := 0 to AEvents.Count - 1 do
|
|
begin
|
|
AEvent := AEvents[I];
|
|
AEvent.MoveTo(AEvent.Start + Anchor);
|
|
AEvent.EventType := etNone;
|
|
if AEvent.AllDayEvent and not AllDayDuration then
|
|
begin
|
|
AEvent.AllDayEvent := False;
|
|
AEvent.Start := Scheduler.SelStart;
|
|
AEvent.Duration := 30 * MinuteToTime;
|
|
if AEvent.State = tlsFree then
|
|
AEvent.State := tlsBusy;
|
|
end;
|
|
if not IsDifferenceResources or (Scheduler.SelResource = nil) then
|
|
begin
|
|
if Scheduler.SelResource = nil then
|
|
AEvent.ResourceID := Null
|
|
else
|
|
AEvent.ResourceID := Scheduler.SelResource.ResourceID;
|
|
end;
|
|
if Scheduler.CanIntersect(AEvent) then
|
|
Storage.createEvent.Assign(AEvent)
|
|
end;
|
|
finally
|
|
Storage.EndUpdate;
|
|
end;
|
|
end;
|
|
|
|
function TcxSchedulerClipboardController.KeyDown(
|
|
var AKey: Word; AShift: TShiftState): Boolean;
|
|
begin
|
|
Result := False;
|
|
case AKey of
|
|
VK_INSERT:
|
|
if [ssShift, ssCtrl] * AShift <> [] then
|
|
begin
|
|
if ssShift in AShift then
|
|
Paste
|
|
else
|
|
if ssCtrl in AShift then
|
|
Copy;
|
|
Result := True;
|
|
end;
|
|
VK_DELETE:
|
|
if ssShift in AShift then
|
|
begin
|
|
Cut;
|
|
Result := True;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TcxSchedulerClipboardController.KeyPress(var AKey: Char): Boolean;
|
|
begin
|
|
Result := dxCharInSet(AKey, [^C, ^X, ^V]);
|
|
if Result then
|
|
begin
|
|
case AKey of
|
|
^C:
|
|
Copy;
|
|
^X:
|
|
Cut;
|
|
^V:
|
|
Paste;
|
|
end;
|
|
AKey := #0;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerClipboardController.RestoreEvent(
|
|
var AEvent: TcxSchedulerControlEvent);
|
|
var
|
|
I, ACount, ALastPos: Integer;
|
|
begin
|
|
ALastPos := StreamReader.ReadInteger;
|
|
if ALastPos <= Stream.Size then
|
|
begin
|
|
AEvent := TcxSchedulerControlEvent.Create(Storage);
|
|
ACount := StreamReader.ReadInteger;
|
|
if ACount > AEvent.ValueCount then
|
|
ACount := AEvent.ValueCount;
|
|
for I := 0 to ACount - 1 do
|
|
AEvent.Values[I] := StreamReader.ReadVariant;
|
|
AEvent.IsDataValid := False;
|
|
end;
|
|
Stream.Position := ALastPos;
|
|
end;
|
|
|
|
procedure TcxSchedulerClipboardController.SaveEvent(
|
|
AEvent: TcxSchedulerControlEvent);
|
|
var
|
|
I, APos: Integer;
|
|
begin
|
|
APos := Stream.Position;
|
|
StreamWriter.WriteInteger(APos);
|
|
StreamWriter.WriteInteger(AEvent.ValueCount);
|
|
for I := 0 to AEvent.ValueCount - 1 do
|
|
StreamWriter.WriteVariant(AEvent.Values[I]);
|
|
Stream.Position := APos;
|
|
StreamWriter.WriteInteger(Stream.Size);
|
|
Stream.Position := Stream.Size;
|
|
end;
|
|
|
|
procedure TcxSchedulerClipboardController.SetStreamToClipboard;
|
|
var
|
|
Data: THandle;
|
|
DataPtr: Pointer;
|
|
begin
|
|
if Stream.Size = 0 then Exit;
|
|
Clipboard.Open;
|
|
try
|
|
Data := GlobalAlloc(GMEM_MOVEABLE + GMEM_DDESHARE, Stream.Size);
|
|
try
|
|
DataPtr := GlobalLock(Data);
|
|
try
|
|
Stream.Position := 0;
|
|
Stream.ReadBuffer(DataPtr^, Stream.Size);
|
|
SetClipboardData(CF_SCHEDULERDATA, Data);
|
|
finally
|
|
GlobalUnlock(Data);
|
|
end;
|
|
except
|
|
GlobalFree(Data);
|
|
raise;
|
|
end;
|
|
finally
|
|
Clipboard.Close;
|
|
end;
|
|
end;
|
|
|
|
function TcxSchedulerClipboardController.ValidateStream: Boolean;
|
|
var
|
|
APos, ACount, ASavedCount: Integer;
|
|
begin
|
|
Stream.Position := 0;
|
|
Result := (Stream.Size > SizeOf(Integer) * 2 + SizeOf(TDateTime)) and
|
|
(StreamReader.ReadInteger = Stream.Size);
|
|
if not Result then Exit;
|
|
ASavedCount := StreamReader.ReadInteger;
|
|
ACount := 0;
|
|
StreamReader.ReadDateTime;
|
|
while Stream.Position < (Stream.Size - SizeOf(Integer)) do
|
|
begin
|
|
APos := StreamReader.ReadInteger;
|
|
if APos <= Stream.Size then
|
|
begin
|
|
Stream.Position := APos;
|
|
Inc(ACount);
|
|
end
|
|
else
|
|
Break;
|
|
end;
|
|
Result := ASavedCount = ACount;
|
|
if Result then
|
|
Stream.Position := SizeOf(Integer);
|
|
end;
|
|
|
|
function TcxSchedulerClipboardController.GetStorage: TcxCustomSchedulerStorage;
|
|
begin
|
|
Result := Scheduler.Storage;
|
|
end;
|
|
|
|
procedure TcxSchedulerClipboardController.RegisterClipboardFormat;
|
|
begin
|
|
CF_SCHEDULERDATA := Windows.RegisterClipboardFormat(SCF_SCHEDULERCLIPBOARDFORMAT);
|
|
end;
|
|
|
|
{ TcxSchedulerStyles }
|
|
|
|
constructor TcxSchedulerStyles.Create(AOwner: TPersistent);
|
|
begin
|
|
if AOwner is TcxCustomScheduler then
|
|
FScheduler := TcxCustomScheduler(AOwner);
|
|
inherited Create(AOwner);
|
|
BitmapInViewParams := True;
|
|
end;
|
|
|
|
procedure TcxSchedulerStyles.Assign(Source: TPersistent);
|
|
var
|
|
I: Integer;
|
|
begin
|
|
if Source is TcxSchedulerStyles then
|
|
begin
|
|
for I := 0 to cxcsMaxValue do
|
|
SetValue(I, TcxSchedulerStyles(Source).GetValue(I))
|
|
end;
|
|
inherited Assign(Source);
|
|
end;
|
|
|
|
function TcxSchedulerStyles.GetBackgroundParams: TcxViewParams;
|
|
begin
|
|
GetViewParams(cxcsBackground, nil, nil, Result);
|
|
end;
|
|
|
|
function TcxSchedulerStyles.GetContentParams(const ADateTime: TDateTime;
|
|
AResource: TcxSchedulerStorageResourceItem = nil): TcxViewParams;
|
|
begin
|
|
Result := GetContentParams(
|
|
ADateTime, Scheduler.DoIsWorkTime(AResource, ADateTime), AResource);
|
|
end;
|
|
|
|
function TcxSchedulerStyles.GetContentParams(const ADateTime: TDateTime;
|
|
ALightColor: Boolean; AResource: TcxSchedulerStorageResourceItem = nil): TcxViewParams;
|
|
var
|
|
AStyle: TcxStyle;
|
|
begin
|
|
AStyle := nil;
|
|
if Assigned(FOnGetContentStyle) then
|
|
FOnGetContentStyle(Scheduler, AResource, ADateTime, AStyle);
|
|
GetViewParams(cxcsContent, AResource, AStyle, Result);
|
|
Result.Color := PainterHelper.GetContentColor(Result.Color, ALightColor);
|
|
end;
|
|
|
|
function TcxSchedulerStyles.GetEventContentParams(
|
|
AEvent: TcxSchedulerEvent): TcxViewParams;
|
|
var
|
|
AStyle: TcxStyle;
|
|
begin
|
|
AStyle := nil;
|
|
if Assigned(OnGetEventStyle) then
|
|
OnGetEventStyle(Scheduler, AEvent, AStyle);
|
|
GetViewParams(cxcsEvent, AEvent, AStyle, Result);
|
|
end;
|
|
|
|
function TcxSchedulerStyles.IsEventStyleAssigned(
|
|
AEvent: TcxSchedulerEvent): Boolean;
|
|
var
|
|
AStyle: TcxStyle;
|
|
begin
|
|
Result := (AEvent.LabelColor <> clDefault) or (Event <> nil);
|
|
if not Result and Assigned(FOnGetEventStyle) then
|
|
begin
|
|
AStyle := nil;
|
|
FOnGetEventStyle(Scheduler, AEvent, AStyle);
|
|
Result := AStyle <> nil;
|
|
end;
|
|
end;
|
|
|
|
function TcxSchedulerStyles.GetDayHeaderParams(
|
|
const ADate: TDateTime): TcxViewParams;
|
|
var
|
|
AStyle: TcxStyle;
|
|
begin
|
|
AStyle := nil;
|
|
if Assigned(FOnGetDayHeaderStyle) then
|
|
FOnGetDayHeaderStyle(Scheduler, ADate, AStyle);
|
|
GetViewParams(cxcsDayHeader, Pointer(Trunc(ADate)), AStyle, Result);
|
|
end;
|
|
|
|
function TcxSchedulerStyles.GetGroupSeparatorParams: TcxViewParams;
|
|
begin
|
|
GetViewParams(cxcsGroupSeparator, nil, nil, Result);
|
|
end;
|
|
|
|
function TcxSchedulerStyles.GetResourceHeaderParams(
|
|
AResource: TcxSchedulerStorageResourceItem): TcxViewParams;
|
|
var
|
|
AStyle: TcxStyle;
|
|
begin
|
|
AStyle := nil;
|
|
if Assigned(FOnGetResourceHeaderStyle) then
|
|
FOnGetResourceHeaderStyle(Scheduler, AResource, AStyle);
|
|
GetViewParams(cxcsResourceHeader, nil, AStyle, Result);
|
|
end;
|
|
|
|
function TcxSchedulerStyles.GetSplitterParams(
|
|
AKind: TcxSchedulerSplitterKind): TcxViewParams;
|
|
begin
|
|
GetViewParams(cxcsHSplitter + Byte(AKind), nil, nil, Result);
|
|
end;
|
|
|
|
function TcxSchedulerStyles.GetSelectionParams: TcxViewParams;
|
|
begin
|
|
GetViewParams(cxcsSelection, nil, nil, Result);
|
|
end;
|
|
|
|
procedure TcxSchedulerStyles.Changed(AIndex: Integer);
|
|
begin
|
|
inherited Changed(AIndex);
|
|
if GetOwner is TcxCustomScheduler then
|
|
begin
|
|
Scheduler.DateNavigator.CheckSizes;
|
|
Scheduler.LookAndFeelChanged(Scheduler.LookAndFeel, []);
|
|
end;
|
|
end;
|
|
|
|
function TcxSchedulerStyles.EventContentSelected(
|
|
AEvent: TcxSchedulerControlEvent): Boolean;
|
|
begin
|
|
Result := AEvent.Selected and Scheduler.CurrentView.EventContentSelected(AEvent);
|
|
if Scheduler.EditController.IsEditing and (Scheduler.EditController.Event = AEvent) then
|
|
Result := False;
|
|
end;
|
|
|
|
procedure TcxSchedulerStyles.GetDefaultViewParams(
|
|
Index: Integer; AData: TObject; out AParams: TcxViewParams);
|
|
var
|
|
AEvent: TcxSchedulerControlEvent;
|
|
ASelected: Boolean;
|
|
begin
|
|
AParams.Bitmap := nil;
|
|
AParams.Font := Scheduler.Font;
|
|
AParams.TextColor := AParams.Font.Color;
|
|
AParams.Color := Scheduler.Color;
|
|
case Index of
|
|
cxcsDayHeader, cxcsResourceHeader:
|
|
begin
|
|
AParams.Color := Painter.DefaultHeaderColor;
|
|
AParams.TextColor := Painter.DefaultHeaderTextColor;
|
|
end;
|
|
cxcsBackground:
|
|
begin
|
|
AParams.Color := Painter.DefaultSchedulerBackgroundColor;
|
|
AParams.TextColor := Painter.DefaultSchedulerTextColor;
|
|
end;
|
|
cxcsContent:
|
|
begin
|
|
AParams.Color := Painter.DefaultSchedulerViewContentColor;
|
|
if AData <> nil then
|
|
begin
|
|
AParams.Color := Resources[TcxSchedulerStorageResourceItem(AData).Index].Color;
|
|
if AParams.Color = clDefault then
|
|
AParams.Color := PainterHelper.GetResourceContentColor(
|
|
TcxSchedulerStorageResourceItem(AData).Index);
|
|
end;
|
|
AParams.TextColor := Painter.DefaultSchedulerViewTextColor;
|
|
end;
|
|
cxcsSelection:
|
|
begin
|
|
AParams.Color := Painter.DefaultSelectionColor;
|
|
AParams.TextColor := Painter.DefaultSchedulerViewSelectedTextColor;
|
|
end;
|
|
cxcsHSplitter, cxcsVSplitter:
|
|
AParams.Color := Painter.DefaultSchedulerControlColor;
|
|
cxcsGroupSeparator:
|
|
AParams.Color := Painter.DefaultHeaderColor;
|
|
cxcsEvent:
|
|
begin
|
|
if AData <> nil then
|
|
begin
|
|
AEvent := TcxSchedulerControlEvent(AData);
|
|
ASelected := EventContentSelected(AEvent);
|
|
if (AEvent.LabelColor = clDefault) or ASelected then
|
|
begin
|
|
if ASelected then
|
|
begin
|
|
with GetSelectionParams do
|
|
begin
|
|
AParams.Color := Color;
|
|
AParams.TextColor := TextColor;
|
|
AParams.Font := Font;
|
|
end;
|
|
end
|
|
else
|
|
begin
|
|
AParams.Color := EventContentColors[AEvent.AllDayEvent or (AEvent.Duration >= 1)];
|
|
with GetContentParams(NullDate) do
|
|
begin
|
|
AParams.TextColor := TextColor;
|
|
AParams.Font := Font;
|
|
end;
|
|
end;
|
|
end
|
|
else
|
|
begin
|
|
AParams.Color := AEvent.LabelColor;
|
|
with GetContentParams(NullDate) do
|
|
begin
|
|
AParams.TextColor := TextColor;
|
|
AParams.Font := Font;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TcxSchedulerStyles.GetDayHeaderStyle: TcxStyle;
|
|
begin
|
|
Result := DayHeader;
|
|
end;
|
|
|
|
function TcxSchedulerStyles.GetEventParams(AEvent: TcxSchedulerEvent): TcxViewParams;
|
|
begin
|
|
Result := GetEventContentParams(AEvent);
|
|
end;
|
|
|
|
function TcxSchedulerStyles.GetResourceHeaderStyle: TcxStyle;
|
|
begin
|
|
Result := ResourceHeader;
|
|
end;
|
|
|
|
function TcxSchedulerStyles.GetPainter: TcxCustomLookAndFeelPainterClass;
|
|
begin
|
|
Result := Scheduler.LookAndFeelPainter;
|
|
end;
|
|
|
|
function TcxSchedulerStyles.GetPainterHelperClass: TcxSchedulerPainterHelperClass;
|
|
begin
|
|
Result := Scheduler.PainterHelper
|
|
end;
|
|
|
|
function TcxSchedulerStyles.GetResources: TcxSchedulerStorageResourceItems;
|
|
begin
|
|
Result := Scheduler.CurrentView.Resources;
|
|
end;
|
|
|
|
{ TcxSchedulerOptionsBehavior }
|
|
|
|
constructor TcxSchedulerOptionsBehavior.Create(AOwner: TcxCustomScheduler);
|
|
begin
|
|
FOwner := AOwner;
|
|
FHotTrack := True;
|
|
FSelectOnRightClick := False;
|
|
end;
|
|
|
|
procedure TcxSchedulerOptionsBehavior.Assign(Source: TPersistent);
|
|
begin
|
|
inherited Assign(Source);
|
|
if Source is TcxSchedulerOptionsBehavior then
|
|
with (Source as TcxSchedulerOptionsBehavior) do
|
|
begin
|
|
Self.SelectOnRightClick := SelectOnRightClick;
|
|
Self.HotTrack := HotTrack;
|
|
end;
|
|
end;
|
|
|
|
function TcxSchedulerOptionsBehavior.GetOwner: TPersistent;
|
|
begin
|
|
Result := FOwner;
|
|
end;
|
|
|
|
{ TcxCustomScheduler }
|
|
|
|
constructor TcxCustomScheduler.Create(AOwner: TComponent);
|
|
begin
|
|
inherited Create(AOwner);
|
|
FDialogsLookAndFeel := TcxLookAndFeel.Create(Self);
|
|
FDialogsLookAndFeel.MasterLookAndFeel := LookAndFeel;
|
|
FListeners := TInterfaceList.Create;
|
|
Color := clBtnFace;
|
|
ParentFont := False;
|
|
Font.Name := 'Tahoma';
|
|
Keys := [kAll, kArrows, kChars, kTab];
|
|
BeginUpdate;
|
|
SetBounds(0, 0, cxDefaultSchedulerWidth, cxDefaultSchedulerHeight);
|
|
FSubControls := TList.Create;
|
|
{$IFNDEF DEBUGPAINT}
|
|
FBitmap := TBitmap.Create;
|
|
FBitmap.PixelFormat := pf24Bit;
|
|
FBitmapCanvas := TcxCanvas.Create(FBitmap.Canvas);
|
|
{$ENDIF}
|
|
FCanvas := GetControlCanvas;
|
|
FStoredClientBounds := ClientBounds;
|
|
FResourceNavigator := CreateResourceNavigator;
|
|
CreateSubClasses;
|
|
FBackground := CreateBackground;
|
|
FSubControlsCreated := True;
|
|
BorderStyle := cxcbsDefault;
|
|
EndUpdate;
|
|
DragMode := dmAutomatic;
|
|
cxFormatController.AddListener(Self);
|
|
FOptionsBehavior := TcxSchedulerOptionsBehavior.Create(Self);
|
|
end;
|
|
|
|
destructor TcxCustomScheduler.Destroy;
|
|
begin
|
|
cxFormatController.RemoveListener(Self);
|
|
FSubControlsCreated := False;
|
|
Storage := nil;
|
|
DestroySubClasses;
|
|
while SubControlCount > 0 do
|
|
SubControls[0].Free;
|
|
FSubControls.Free;
|
|
{$IFNDEF DEBUGPAINT}
|
|
FBitmapCanvas.Free;
|
|
FBitmap.Free;
|
|
{$ENDIF}
|
|
NotififySchedulerRemoved;
|
|
FListeners.Free;
|
|
FreeAndNil(FDialogsLookAndFeel);
|
|
FreeAndNil(FOptionsBehavior);
|
|
inherited Destroy;
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.BeginUpdate;
|
|
begin
|
|
Inc(FLockCount);
|
|
Include(FControlFlags, cfLocked);
|
|
LockUpdateChanged(True);
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.CopyToClipboard;
|
|
begin
|
|
ClipboardController.Copy;
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.CreateEventUsingDialog(AllDay: Boolean = False;
|
|
ARecurrence: Boolean = False);
|
|
var
|
|
AModified: Boolean;
|
|
AEvent: TcxSchedulerControlEvent;
|
|
begin
|
|
if not StorageActive then Exit;
|
|
AEvent := TcxSchedulerControlEvent.Create(Storage);
|
|
EditController.FFocused := True;
|
|
try
|
|
InitEventBySelection(AEvent, AllDay, ARecurrence, False);
|
|
if DoBeforeEditing(AEvent, False) then
|
|
begin
|
|
EventList.BeforeEditing(AEvent, False);
|
|
cxShowEventEditorEx(GetEventEditInfo(AEvent, ARecurrence), AModified);
|
|
DoAfterEditing(EventList.LastEditedEvent);
|
|
end
|
|
finally
|
|
AEvent.Free;
|
|
EditController.FFocused := False;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.CreateEventUsingInplaceEdit;
|
|
begin
|
|
DoCreateEventUsingInplaceEdit;
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.CutToClipboard;
|
|
begin
|
|
ClipboardController.Cut;
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.DeleteEvent(AEvent: TcxSchedulerControlEvent);
|
|
begin
|
|
if not StorageActive or (AEvent = nil) or not EventOperations.Deleting or
|
|
AEvent.ReadOnly then Exit;
|
|
InternalDeleteEvent(AEvent, False);
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.DeleteSelectedEvents(
|
|
ACheckReadOnly: Boolean = True);
|
|
begin
|
|
if StorageActive then
|
|
InternalDeleteSelectedEvents(True, ACheckReadOnly);
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.EditEventUsingDialog(
|
|
AEvent: TcxSchedulerControlEvent; ACheckReadOnly: Boolean = True;
|
|
AForcePatternEditing: Boolean = False);
|
|
var
|
|
AReadOnly, AModified: Boolean;
|
|
begin
|
|
if (AEvent = nil) or not StorageActive or (cxEventEditorClass = nil) or
|
|
not DoBeforeEditing(AEvent, False) then Exit;
|
|
AReadOnly := ACheckReadOnly and
|
|
(not CurrentView.Controller.CanEditEvent(AEvent, False) or AEvent.ReadOnly);
|
|
EditController.FFocused := True;
|
|
try
|
|
EventList.BeforeEditing(AEvent, False);
|
|
GetEventEditInfo(AEvent, False, AReadOnly);
|
|
FEventEditInfo.AllowDelete := EventOperations.Deleting;
|
|
FEventEditInfo.ForcePatternEditing := AForcePatternEditing;
|
|
FEventEditInfo.OnDeleteFunc := DoBeforeDeleting;
|
|
cxShowEventEditorEx(FEventEditInfo, AModified);
|
|
DoAfterEditing(EventList.LastEditedEvent);
|
|
finally
|
|
EditController.FFocused := False;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.EditEventUsingInplaceEdit(
|
|
AEvent: TcxSchedulerControlEvent);
|
|
begin
|
|
if (AEvent = nil) or not StorageActive then Exit;
|
|
if CanFocusEx then
|
|
begin
|
|
SetFocus;
|
|
EditController.Activate(AEvent);
|
|
end;
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.DragDrop(
|
|
Source: TObject; X, Y: Integer);
|
|
begin
|
|
inherited DragDrop(Source, X, Y);
|
|
CaptureController.DragDrop(Source, X, Y);
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.EndUpdate;
|
|
begin
|
|
LockUpdateChanged(False);
|
|
Dec(FLockCount);
|
|
if FLockCount = 0 then
|
|
begin
|
|
Exclude(FControlFlags, cfLocked);
|
|
if cfInvalidLayout in FControlFlags then
|
|
begin
|
|
Exclude(FControlFlags, cfInvalidLayout);
|
|
LayoutChanged;
|
|
end
|
|
else
|
|
DateNavigator.RefreshDays;
|
|
end;
|
|
end;
|
|
|
|
function TcxCustomScheduler.GoToDate(ADate: TDateTime): Boolean;
|
|
begin
|
|
Result := False;
|
|
end;
|
|
|
|
function TcxCustomScheduler.GoToDate(ADate: TDateTime;
|
|
AViewMode: TcxSchedulerViewMode): Boolean;
|
|
begin
|
|
if ADate = NullDate then
|
|
Result := False
|
|
else
|
|
begin
|
|
FSelectedDays.Clear;
|
|
FSelectedDays.Add(ADate);
|
|
CurrentView.PeriodChanged;
|
|
Result := True;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.FullRefresh;
|
|
begin
|
|
if IsDestroying then Exit;
|
|
Inc(FLockRefresh);
|
|
try
|
|
ClearAllCachedData;
|
|
UpdateEventsCache(False);
|
|
LayoutChanged;
|
|
finally
|
|
Dec(FLockRefresh);
|
|
end;
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.LayoutChanged;
|
|
begin
|
|
if IsLocked or IsLoading or IsDestroying or not HandleAllocated then
|
|
Include(FControlFlags, cfInvalidLayout)
|
|
else
|
|
begin
|
|
if EditController <> nil then
|
|
EditController.CloseEdit(True);
|
|
Exclude(FControlFlags, cfImageValid);
|
|
if CurrentView.Visible and not CurrentView.CanShow then
|
|
CurrentView.Visible := False;
|
|
AlignSubControls;
|
|
if not (cfViewValid in FControlFlags) then
|
|
begin
|
|
SynchronizeVisibleDays;
|
|
UpdateEventsCache(False);
|
|
end;
|
|
DoLayoutChanged;
|
|
Exclude(FControlFlags, cfInvalidLayout);
|
|
UpdateScrollBars;
|
|
NotififySchedulerChanged;
|
|
end;
|
|
Invalidate;
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.MakeEventVisible(
|
|
AEvent: TcxSchedulerControlEvent; const ADate: TDateTime = NullDate;
|
|
AResource: TcxSchedulerStorageResourceItem = nil);
|
|
var
|
|
AEventDate: TDateTime;
|
|
begin
|
|
if AResource = nil then
|
|
AResource := AEvent.GetResourceItem;
|
|
MakeResourceVisible(AResource);
|
|
AEventDate := ADate;
|
|
if AEventDate = NullDate then
|
|
AEventDate := DateOf(AEvent.Start);
|
|
CurrentView.MakeEventVisible(AEvent, AEventDate, AResource);
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.MakeResourceVisible(
|
|
AResource: TcxSchedulerStorageResourceItem);
|
|
var
|
|
AVisibleIndex, I: Integer;
|
|
begin
|
|
if (AResource = nil) or not AResource.Visible or
|
|
(OptionsView.ResourcesPerPage = 0) then Exit;
|
|
AVisibleIndex := -1;
|
|
with Storage.Resources.ResourceItems do
|
|
begin
|
|
for I := 0 to VisibleResourceCount - 1 do
|
|
if AResource = VisibleResources[I] then
|
|
begin
|
|
AVisibleIndex := I;
|
|
Break;
|
|
end;
|
|
end;
|
|
if AVisibleIndex < FirstVisibleResourceIndex then
|
|
FirstVisibleResourceIndex := AVisibleIndex
|
|
else
|
|
if AVisibleIndex >= (FirstVisibleResourceIndex + OptionsView.ResourcesPerPage) then
|
|
FirstVisibleResourceIndex := Max(AVisibleIndex - (OptionsView.ResourcesPerPage - 1), 0);
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.PasteFromClipboard;
|
|
begin
|
|
ClipboardController.Paste;
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.SelectEvent(
|
|
AEvent: TcxSchedulerControlEvent; AShift: TShiftState = []);
|
|
begin
|
|
EventList.Selection.Add(AEvent, AShift);
|
|
if not IsLocked then
|
|
CurrentView.Refresh;
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.SelectTime(const ASelStart,
|
|
ASelFinish: TDateTime; AResource: TcxSchedulerStorageResourceItem);
|
|
begin
|
|
if DateTimeHelper.RoundTime(Abs(ASelStart - ASelFinish)) <= CurrentView.GetTimeIncrement then
|
|
ReplaceSelParams(ASelStart, ASelStart, AResource)
|
|
else
|
|
ReplaceSelParams(ASelStart, (ASelFinish - CurrentView.GetTimeIncrement), AResource);
|
|
LayoutChanged;
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.UnselectEvents;
|
|
begin
|
|
if EventList.Selection.Count = 0 then Exit;
|
|
EventList.Selection.Clear;
|
|
CurrentView.LayoutChanged;
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.RestoreFromIniFile(const AStorageName: string;
|
|
ARestoreResources: Boolean = True);
|
|
var
|
|
AStorage: TcxStorage;
|
|
begin
|
|
AStorage := TcxStorage.Create(AStorageName);
|
|
try
|
|
BeginUpdate;
|
|
try
|
|
AStorage.RestoreFromIni(Self);
|
|
if ARestoreResources and HasResources then
|
|
begin
|
|
Storage.InitRestore;
|
|
try
|
|
AStorage.RestoreFromIni(Storage.Resources);
|
|
finally
|
|
Storage.DoneRestore;
|
|
end;
|
|
end;
|
|
finally
|
|
EndUpdate;
|
|
end;
|
|
finally
|
|
AStorage.Free;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.RestoreFromRegistry(const AStorageName: string;
|
|
ARestoreResources: Boolean = True);
|
|
var
|
|
AStorage: TcxStorage;
|
|
begin
|
|
AStorage := TcxStorage.Create(AStorageName);
|
|
try
|
|
BeginUpdate;
|
|
try
|
|
AStorage.RestoreFromRegistry(Self);
|
|
if ARestoreResources and HasResources then
|
|
begin
|
|
Storage.InitRestore;
|
|
try
|
|
AStorage.RestoreFromRegistry(Storage.Resources);
|
|
finally
|
|
Storage.DoneRestore;
|
|
end;
|
|
end;
|
|
finally
|
|
EndUpdate;
|
|
end;
|
|
finally
|
|
AStorage.Free;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.RestoreFromStream(AStream: TStream;
|
|
ARestoreResources: Boolean = True);
|
|
var
|
|
AStorage: TcxStorage;
|
|
begin
|
|
AStorage := TcxStorage.Create(AStream);
|
|
try
|
|
BeginUpdate;
|
|
try
|
|
AStorage.RestoreFromStream(Self);
|
|
if ARestoreResources and HasResources then
|
|
begin
|
|
Storage.InitRestore;
|
|
try
|
|
AStorage.RestoreFromStream(Storage.Resources);
|
|
finally
|
|
Storage.DoneRestore;
|
|
end;
|
|
end;
|
|
finally
|
|
EndUpdate;
|
|
end;
|
|
finally
|
|
AStorage.Free;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.StoreToIniFile(const AStorageName: string;
|
|
AReCreate: Boolean = True; AStoreResources: Boolean = True);
|
|
var
|
|
AStorage: TcxStorage;
|
|
begin
|
|
AStorage := TcxStorage.Create(AStorageName);
|
|
try
|
|
BeginUpdate;
|
|
try
|
|
AStorage.ReCreate := ARecreate;
|
|
AStorage.StoreToIni(Self);
|
|
AStorage.ReCreate := False;
|
|
if AStoreResources and HasResources then
|
|
AStorage.StoreToIni(Storage.Resources);
|
|
finally
|
|
EndUpdate;
|
|
end;
|
|
finally
|
|
AStorage.Free;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.StoreToRegistry(const AStorageName: string;
|
|
AReCreate: Boolean = True; AStoreResources: Boolean = True);
|
|
var
|
|
AStorage: TcxStorage;
|
|
begin
|
|
AStorage := TcxStorage.Create(AStorageName);
|
|
try
|
|
BeginUpdate;
|
|
try
|
|
AStorage.ReCreate := ARecreate;
|
|
AStorage.StoreToRegistry(Self);
|
|
AStorage.ReCreate := False;
|
|
if AStoreResources and HasResources then
|
|
AStorage.StoreToRegistry(Storage.Resources);
|
|
finally
|
|
EndUpdate;
|
|
end;
|
|
finally
|
|
AStorage.Free;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.StoreToStream(AStream: TStream;
|
|
AStoreResources: Boolean = True);
|
|
var
|
|
AStorage: TcxStorage;
|
|
begin
|
|
AStorage := TcxStorage.Create(AStream);
|
|
try
|
|
BeginUpdate;
|
|
try
|
|
AStorage.StoreToStream(Self);
|
|
AStorage.ReCreate := False;
|
|
if AStoreResources and HasResources then
|
|
AStorage.StoreToStream(Storage.Resources);
|
|
finally
|
|
EndUpdate;
|
|
end;
|
|
finally
|
|
AStorage.Free;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.TranslationChanged;
|
|
begin
|
|
LayoutChanged;
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.AlignControls(AControl: TControl; var Rect: TRect);
|
|
begin
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.DefineProperties(Filer: TFiler);
|
|
begin
|
|
inherited DefineProperties(Filer);
|
|
Filer.DefineProperty('Selection', ReadSelectionData, WriteSelectionData,
|
|
(FSelectedDays.Count > 1) or (SelectedDays[0] <> Date));
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.GetChildren(
|
|
Proc: TGetChildProc; Root: TComponent);
|
|
begin
|
|
inherited GetChildren(Proc, Root);
|
|
if ControlBox.Control <> nil then
|
|
Proc(ControlBox.Control);
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.Notification(
|
|
AComponent: TComponent; Operation: TOperation);
|
|
var
|
|
I: Integer;
|
|
begin
|
|
inherited Notification(AComponent, Operation);
|
|
if not IsDestroying and FSubControlsCreated then
|
|
begin
|
|
if Operation = opRemove then
|
|
begin
|
|
if AComponent = ControlBox.Control then
|
|
begin
|
|
FCanModified := False;
|
|
ControlBox.Control := nil;
|
|
end;
|
|
if AComponent = EventImages then
|
|
EventImages := nil;
|
|
end;
|
|
ContentPopupMenu.Notification(AComponent, Operation);
|
|
EventPopupMenu.Notification(AComponent, Operation);
|
|
for I := 0 to SubControlCount - 1 do
|
|
SubControls[I].Notification(AComponent, Operation);
|
|
end;
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.AddListener(
|
|
AListener: IcxExternalDateNavigatorListener);
|
|
begin
|
|
if FListeners.IndexOf(AListener) = -1 then
|
|
FListeners.Add(AListener);
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.NotififySchedulerChanged;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
for I := 0 to FListeners.Count - 1 do
|
|
(FListeners[I] as IcxExternalDateNavigatorListener).SchedulerChanged;
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.NotififySchedulerRemoved;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
for I := 0 to FListeners.Count - 1 do
|
|
(FListeners[I] as IcxExternalDateNavigatorListener).SchedulerRemoved;
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.NotififyStorageChanged;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
for I := 0 to FListeners.Count - 1 do
|
|
(FListeners[I] as IcxExternalDateNavigatorListener).StorageChanged;
|
|
end;
|
|
|
|
|
|
procedure TcxCustomScheduler.RemoveListener(
|
|
AListener: IcxExternalDateNavigatorListener);
|
|
begin
|
|
FListeners.Remove(AListener);
|
|
end;
|
|
|
|
////////////////////////////// LAYOUT //////////////////////////////////////////
|
|
|
|
procedure TcxCustomScheduler.AlignSubControls(
|
|
Sender: TcxSchedulerSubControl = nil);
|
|
begin
|
|
if FAligningSubControls or IsLoading or not FSubControlsCreated then Exit;
|
|
FAligningSubControls := True;
|
|
try
|
|
CheckSplittersVisibilityChanging;
|
|
CalcLayout;
|
|
finally
|
|
FAligningSubControls := False;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.BoundsChanged;
|
|
begin
|
|
FBoundsChanging := True;
|
|
Include(FControlFlags, cfLocked);
|
|
try
|
|
{$IFNDEF DEBUGPAINT}
|
|
if ((FBitmap.Width < Width) or ((FBitmap.Width - Width) > cxSizeDelta)) or
|
|
((FBitmap.Height < Height) or ((FBitmap.Height - Height) > cxSizeDelta)) then
|
|
begin
|
|
FBitmap.Width := (Width div cxSizeDelta + 1) * cxSizeDelta;
|
|
FBitmap.Height := (Height div cxSizeDelta + 1) * cxSizeDelta;
|
|
end;
|
|
{$ENDIF}
|
|
if not (IsLoading or IsDestroying) and EditController.IsEditing then
|
|
CurrentView.Controller.CloseInplaceEdit;
|
|
inherited BoundsChanged;
|
|
AlignSubControls;
|
|
FPrevBounds := ClientBounds;
|
|
finally
|
|
Exclude(FControlFlags, cfLocked);
|
|
LayoutChanged;
|
|
FBoundsChanging := False;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.CalcVerticalSplitterBounds;
|
|
var
|
|
R: TRect;
|
|
begin
|
|
R := ClientBounds;
|
|
case OptionsView.ViewPosition of
|
|
vpRight:
|
|
FVertSplitter.Bounds := cxRectSetLeft(R, R.Left + DateNavigator.Width, OptionsView.VertSplitterWidth);
|
|
vpLeft:
|
|
FVertSplitter.Bounds := cxRectSetRight(R, R.Right - DateNavigator.Width, OptionsView.VertSplitterWidth);
|
|
vpTop:
|
|
begin
|
|
R.Top := R.Bottom - DateNavigator.Height;
|
|
FVertSplitter.Bounds := cxRectSetLeft(R, R.Left + DateNavigator.Width, OptionsView.VertSplitterWidth);
|
|
end;
|
|
vpBottom:
|
|
begin
|
|
R.Bottom := R.Top + DateNavigator.Height;
|
|
FVertSplitter.Bounds := cxRectSetLeft(R, R.Left + DateNavigator.Width, OptionsView.VertSplitterWidth);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.CalcLayout;
|
|
begin
|
|
CalcSplittersBounds;
|
|
case OptionsView.ViewPosition of
|
|
vpRight: CalcLayoutViewRight;
|
|
vpLeft: CalcLayoutViewLeft;
|
|
vpTop: CalcLayoutViewTop;
|
|
vpBottom: CalcLayoutViewBottom;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.CalcHorizontalSplitterBounds;
|
|
var
|
|
R: TRect;
|
|
begin
|
|
R := ClientBounds;
|
|
case OptionsView.ViewPosition of
|
|
vpRight:
|
|
begin
|
|
R.Right := R.Left + DateNavigator.Width;
|
|
FHorzSplitter.Bounds := cxRectSetTop(R, R.Top + DateNavigator.Height, OptionsView.HorzSplitterWidth);
|
|
end;
|
|
vpLeft:
|
|
begin
|
|
R.Left := R.Right - DateNavigator.Width;
|
|
FHorzSplitter.Bounds := cxRectSetTop(R, R.Top + DateNavigator.Height, OptionsView.HorzSplitterWidth);
|
|
end;
|
|
vpTop:
|
|
FHorzSplitter.Bounds := cxRectSetBottom(R, R.Bottom - DateNavigator.Height, OptionsView.HorzSplitterWidth);
|
|
vpBottom:
|
|
FHorzSplitter.Bounds := cxRectSetTop(R, R.Top + DateNavigator.Height, OptionsView.HorzSplitterWidth);
|
|
end;
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.CalcSplittersBounds;
|
|
begin
|
|
if IsVertSplitterVisible then
|
|
CalcVerticalSplitterBounds;
|
|
if IsHorzSplitterVisible then
|
|
CalcHorizontalSplitterBounds;
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.CalcLayoutViewRight;
|
|
var
|
|
R: TRect;
|
|
begin
|
|
R := ClientBounds;
|
|
if IsVertSplitterVisible then
|
|
begin
|
|
if DateNavigator.Visible then
|
|
begin
|
|
R.Right := R.Left + DateNavigator.Width;
|
|
if IsHorzSplitterVisible then
|
|
R.Bottom := R.Top + DateNavigator.Height;
|
|
DateNavigator.Bounds := R;
|
|
end;
|
|
if ControlBox.Visible then
|
|
begin
|
|
R.Bottom := ClientBounds.Bottom;
|
|
R.Right := R.Left + DateNavigator.Width;
|
|
if IsHorzSplitterVisible then
|
|
R.Top := DateNavigator.Bottom + OptionsView.HorzSplitterWidth;
|
|
ControlBox.Bounds := R;
|
|
end;
|
|
R.Top := ClientBounds.Top;
|
|
R.Left := R.Right + OptionsView.VertSplitterWidth;
|
|
R.BottomRight := ClientBounds.BottomRight;
|
|
end;
|
|
CurrentView.Bounds := R
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.CalcLayoutViewLeft;
|
|
var
|
|
R: TRect;
|
|
begin
|
|
R := ClientBounds;
|
|
if IsVertSplitterVisible then
|
|
begin
|
|
if DateNavigator.Visible then
|
|
begin
|
|
R.Left := R.Right - DateNavigator.Width;
|
|
if IsHorzSplitterVisible then
|
|
R.Bottom := R.Top + DateNavigator.Height;
|
|
DateNavigator.Bounds := R;
|
|
end;
|
|
if ControlBox.Visible then
|
|
begin
|
|
R.Bottom := ClientBounds.Bottom;
|
|
R.Left := R.Right - DateNavigator.Width;
|
|
if IsHorzSplitterVisible then
|
|
R.Top := DateNavigator.Bottom + OptionsView.HorzSplitterWidth;
|
|
ControlBox.Bounds := R;
|
|
end;
|
|
R.TopLeft := ClientBounds.TopLeft;
|
|
R.Right := ClientBounds.Right - (OptionsView.VertSplitterWidth + DateNavigator.Width);
|
|
R.Bottom := ClientBounds.Bottom;
|
|
end;
|
|
CurrentView.Bounds := R
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.CalcLayoutViewTop;
|
|
var
|
|
R: TRect;
|
|
begin
|
|
R := ClientBounds;
|
|
if IsHorzSplitterVisible then
|
|
begin
|
|
R.Top := R.Bottom - DateNavigator.Height;
|
|
if DateNavigator.Visible then
|
|
begin
|
|
if IsVertSplitterVisible then
|
|
R.Right := R.Left + DateNavigator.Width;
|
|
DateNavigator.Bounds := R;
|
|
end;
|
|
if ControlBox.Visible then
|
|
begin
|
|
R.Right := ClientBounds.Right;
|
|
if IsVertSplitterVisible then
|
|
R.Left := ClientBounds.Left + DateNavigator.Width + OptionsView.VertSplitterWidth
|
|
else
|
|
R.Left := ClientBounds.Left;
|
|
ControlBox.Bounds := R;
|
|
end;
|
|
R.TopLeft := ClientBounds.TopLeft;
|
|
R.Bottom := ClientBounds.Bottom - (DateNavigator.Height + OptionsView.HorzSplitterWidth);
|
|
R.Right := ClientBounds.Right;
|
|
end;
|
|
CurrentView.Bounds := R
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.CalcLayoutViewBottom;
|
|
var
|
|
R: TRect;
|
|
begin
|
|
R := ClientBounds;
|
|
if IsHorzSplitterVisible then
|
|
begin
|
|
R.Bottom := R.Top + DateNavigator.Height;
|
|
if DateNavigator.Visible then
|
|
begin
|
|
if IsVertSplitterVisible then
|
|
R.Right := R.Left + DateNavigator.Width;
|
|
DateNavigator.Bounds := R;
|
|
end;
|
|
if ControlBox.Visible then
|
|
begin
|
|
R.Right := ClientBounds.Right;
|
|
if IsVertSplitterVisible then
|
|
R.Left := ClientBounds.Left + DateNavigator.Width + OptionsView.VertSplitterWidth
|
|
else
|
|
R.Left := ClientBounds.Left;
|
|
ControlBox.Bounds := R;
|
|
end;
|
|
R.Left := ClientBounds.Left;
|
|
R.Top := R.Bottom + OptionsView.HorzSplitterWidth;
|
|
R.BottomRight := ClientBounds.BottomRight;
|
|
end;
|
|
CurrentView.Bounds := R
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.CheckHorzSplitterBounds;
|
|
var
|
|
R: TRect;
|
|
begin
|
|
//todo:
|
|
R := FHorzSplitter.Bounds;
|
|
if IsVertSplitterVisible then
|
|
begin
|
|
if IsViewAtLeft then
|
|
begin
|
|
R.Left := FVertSplitter.Right;
|
|
R.Right := ClientBounds.Right;
|
|
end
|
|
else
|
|
begin
|
|
R.Left := ClientBounds.Left;
|
|
R.Right := FVertSplitter.Left;
|
|
end
|
|
end
|
|
else
|
|
begin
|
|
R.Left := ClientBounds.Left;
|
|
R.Right := ClientBounds.Right;
|
|
end;
|
|
FHorzSplitter.Bounds := cxRectSetHeight(R, OptionsView.HorzSplitterWidth);
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.CheckSplittersVisibilityChanging; //1
|
|
begin
|
|
FVertSplitterShowing := not FVertSplitter.Visible and IsVertSplitterVisible;
|
|
if FVertSplitterShowing then
|
|
UpdateControlsBoundsOnVertSplitterShowing;
|
|
FVertSplitter.Visible := IsVertSplitterVisible;
|
|
|
|
FHorzSplitterShowing := not FHorzSplitter.Visible and IsHorzSplitterVisible;
|
|
if FHorzSplitterShowing then
|
|
UpdateControlsBoundsOnHorzSplitterShowing;
|
|
FHorzSplitter.Visible := IsHorzSplitterVisible;
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.ClearAllCachedData;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
for I := 0 to SubControlCount - 1 do
|
|
SubControls[I].ClearCachedData;
|
|
end;
|
|
|
|
function TcxCustomScheduler.IsHorzSplitterVisible: Boolean; //1
|
|
begin
|
|
if OptionsView.ViewPosition in [vpLeft, vpRight] then
|
|
Result := DateNavigator.Visible and ControlBox.Visible
|
|
else
|
|
Result := DateNavigator.Visible or ControlBox.Visible;
|
|
end;
|
|
|
|
function TcxCustomScheduler.IsVertSplitterVisible: Boolean; //1
|
|
begin
|
|
if OptionsView.ViewPosition in [vpLeft, vpRight] then
|
|
Result := CurrentView.Visible and (DateNavigator.Visible or ControlBox.Visible)
|
|
else
|
|
Result := DateNavigator.Visible and ControlBox.Visible;
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.UpdateControlsBoundsOnHorzSplitterShowing;
|
|
var
|
|
R: TRect;
|
|
begin
|
|
//todo:
|
|
CheckHorzSplitterBounds;
|
|
case OptionsView.ViewPosition of
|
|
vpRight, vpLeft:
|
|
begin
|
|
R := DateNavigator.Bounds;
|
|
R.Top := ClientBounds.Top;
|
|
R.Bottom := FHorzSplitter.Top;
|
|
DateNavigator.Bounds := R;
|
|
R.Top := FHorzSplitter.Bottom;
|
|
R.Bottom := ClientBounds.Bottom;
|
|
ControlBox.Bounds := R;
|
|
end;
|
|
vpTop: ;
|
|
vpBottom:
|
|
begin
|
|
R := ClientBounds;
|
|
R.Bottom := FHorzSplitter.Bottom;
|
|
R.Right := FVertSplitter.Left;
|
|
DateNavigator.Bounds := R;
|
|
R.Left := FVertSplitter.Right;
|
|
R.Right := ClientBounds.Right;
|
|
ControlBox.Bounds := R;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.UpdateControlsBoundsOnVertSplitterShowing;
|
|
var
|
|
R: TRect;
|
|
begin
|
|
//todo:
|
|
CheckHorzSplitterBounds;
|
|
FVertSplitter.Width := OptionsView.VertSplitterWidth;
|
|
R := ClientBounds;
|
|
if IsViewAtLeft then
|
|
begin
|
|
R.Right := FVertSplitter.Left;
|
|
CurrentView.Bounds := R;
|
|
R := DateNavigator.Bounds;
|
|
R.Left := FVertSplitter.Right;
|
|
R.Right := ClientBounds.Right;
|
|
end
|
|
else
|
|
begin
|
|
R.Left := FVertSplitter.Right;
|
|
CurrentView.Bounds := R;
|
|
R := DateNavigator.Bounds;
|
|
R.Left := ClientBounds.Left;
|
|
R.Right := FVertSplitter.Left;
|
|
end;
|
|
DateNavigator.Bounds := R;
|
|
R.Top := ControlBox.Bounds.Top;
|
|
R.Bottom := ClientBounds.Bottom;
|
|
ControlBox.Bounds := R;
|
|
end;
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
function TcxCustomScheduler.CanSelectPeriod: Boolean;
|
|
begin
|
|
Result := True;
|
|
end;
|
|
|
|
function TcxCustomScheduler.CanShowEventDialog: Boolean;
|
|
begin
|
|
Result := CurrentView.Controller.CanShowEventDialog;
|
|
end;
|
|
|
|
function TcxCustomScheduler.CanDeactivateOnSelectionChanged(AView: TcxSchedulerCustomView): Boolean;
|
|
begin
|
|
Result := (AView <> nil) and AView.CanDeactivateOnDateNavigatorSelectionChange;
|
|
end;
|
|
|
|
function TcxCustomScheduler.CanIntersect(AEvent: TcxSchedulerControlEvent): Boolean;
|
|
begin
|
|
Result := EventOperations.Intersection or
|
|
not AEvent.Conflicts(OptionsView.ShowEventsWithoutResource or not HasResources);
|
|
end;
|
|
|
|
function TcxCustomScheduler.CanModified: Boolean;
|
|
begin
|
|
Result := FCanModified;
|
|
end;
|
|
|
|
function TcxCustomScheduler.CreateBackground: TcxSchedulerSubControl;
|
|
begin
|
|
Result := TcxSchedulerBackground.Create(Self);
|
|
end;
|
|
|
|
function TcxCustomScheduler.CreateClipboardController: TcxSchedulerClipboardController;
|
|
begin
|
|
Result := TcxSchedulerClipboardController.Create(Self);
|
|
end;
|
|
|
|
function TcxCustomScheduler.CreateContentPopupMenu: TcxSchedulerContentPopupMenu;
|
|
begin
|
|
Result := TcxSchedulerContentPopupMenu.Create(Self);
|
|
end;
|
|
|
|
function TcxCustomScheduler.CreateControlBox: TcxSchedulerControlBox;
|
|
begin
|
|
Result := TcxSchedulerControlBox.Create(Self)
|
|
end;
|
|
|
|
function TcxCustomScheduler.CreateDateNavigator: TcxSchedulerCustomDateNavigator;
|
|
begin
|
|
Result := nil;
|
|
end;
|
|
|
|
function TcxCustomScheduler.CreateDefaultView: TcxSchedulerCustomView;
|
|
begin
|
|
Result := nil;
|
|
end;
|
|
|
|
function TcxCustomScheduler.CreateDefaultEditProperties: TcxCustomEditProperties;
|
|
begin
|
|
Result := TcxMemoProperties.Create(Self);
|
|
end;
|
|
|
|
function TcxCustomScheduler.CreateEditController: TcxSchedulerEditController;
|
|
begin
|
|
Result := TcxSchedulerEditController.Create(Self);
|
|
end;
|
|
|
|
function TcxCustomScheduler.CreateEventHitTestController: TcxSchedulerEventHitTestController;
|
|
begin
|
|
Result := TcxSchedulerEventHitTestController.Create(Self);
|
|
end;
|
|
|
|
function TcxCustomScheduler.CreateEventList: TcxSchedulerCachedEventList;
|
|
begin
|
|
Result := TcxSchedulerCachedEventList.Create;
|
|
Result.Selection.OnEventSelectionChanged := DoEventSelectionChanged;
|
|
end;
|
|
|
|
function TcxCustomScheduler.CreateEventOperations: TcxSchedulerEventOperations;
|
|
begin
|
|
Result := TcxSchedulerEventOperations.Create(Self);
|
|
end;
|
|
|
|
function TcxCustomScheduler.CreateEventPopupMenu: TcxSchedulerEventPopupMenu;
|
|
begin
|
|
Result := TcxSchedulerEventPopupMenu.Create(Self);
|
|
end;
|
|
|
|
function TcxCustomScheduler.CreateHintController: TcxSchedulerHintController;
|
|
begin
|
|
Result := TcxSchedulerHintController.Create(Self);
|
|
end;
|
|
|
|
function TcxCustomScheduler.CreateOptionsCustomize: TcxSchedulerOptionsCustomize;
|
|
begin
|
|
Result := TcxSchedulerOptionsCustomize.Create(Self);
|
|
end;
|
|
|
|
function TcxCustomScheduler.CreateOptionsView: TcxSchedulerOptionsView;
|
|
begin
|
|
Result := TcxSchedulerOptionsView.Create(Self);
|
|
end;
|
|
|
|
function TcxCustomScheduler.CreateResourceNavigator: TcxSchedulerResourceNavigator;
|
|
begin
|
|
Result := TcxSchedulerResourceNavigator.Create(Self);
|
|
end;
|
|
|
|
function TcxCustomScheduler.CreateSplitter(
|
|
AKind: TcxSchedulerSplitterKind): TcxSchedulerSplitter;
|
|
begin
|
|
Result := TcxSchedulerSplitter.Create(Self);
|
|
Result.SetKind(AKind);
|
|
end;
|
|
|
|
function TcxCustomScheduler.CreateStyles: TcxSchedulerStyles;
|
|
begin
|
|
Result := TcxSchedulerStyles.Create(Self);
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.CreateSubClasses;
|
|
begin
|
|
FTabOrdersList := TcxSchedulerEventList.Create;
|
|
FClipboardController := CreateClipboardController;
|
|
FEventEditInfo := TcxSchedulerEventEditInfo.Create;
|
|
FTextEditProperties := TcxTextEditProperties.Create(Self);
|
|
FEventHitTestController := CreateEventHitTestController;
|
|
FHintController := CreateHintController;
|
|
FEditController := CreateEditController;
|
|
FEditStyle := TcxCustomEditStyle.Create(Self, True);
|
|
FDefaultProperties := TcxMemoProperties.Create(Self);
|
|
FEventList := CreateEventList;
|
|
|
|
FEventDays := TcxSchedulerDateList.Create;
|
|
FHolidayDays := TcxSchedulerDateList.Create;
|
|
FSelectedDays := TcxSchedulerDateList.Create;
|
|
FSelectedDays.Add(Date);
|
|
FStyles := CreateStyles;
|
|
FEventOperations := CreateEventOperations;
|
|
FOptionsCustomize := CreateOptionsCustomize;
|
|
FOptionsView := CreateOptionsView;
|
|
// subcontrols
|
|
FControlBox := CreateControlBox;
|
|
FDateNavigator := CreateDateNavigator;
|
|
// this order
|
|
FVertSplitter := CreateSplitter(skVertical);
|
|
FHorzSplitter := CreateSplitter(skHorizontal);
|
|
// view
|
|
FCurrentView := CreateDefaultView;
|
|
FCurrentView.Visible := True;
|
|
// popups
|
|
FContentPopupMenu := CreateContentPopupMenu;
|
|
FEventPopupMenu := CreateEventPopupMenu;
|
|
CreateUpdateTimeTimer;
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.DateNavigatorSelectionChanged;
|
|
begin
|
|
if not (cfViewValid in FControlFlags) then Exit;
|
|
Exclude(FControlFlags, cfViewValid);
|
|
PeriodChanged;
|
|
Modified;
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.DblClick;
|
|
var
|
|
P: TPoint;
|
|
begin
|
|
P := ScreenToClient(GetMouseCursorPos);
|
|
if FActiveControl <> nil then
|
|
FActiveControl.MousePositionChanged(P.X, P.Y);
|
|
inherited DblClick;
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.DestroySubClasses;
|
|
begin
|
|
FTabOrdersList.Free;
|
|
FClipboardController.Free;
|
|
FEditController.Free;
|
|
FEventHitTestController.Free;
|
|
FUpdateTimeTimer.Free;
|
|
FContentPopupMenu.Free;
|
|
FEventPopupMenu.Free;
|
|
FEventOperations.Free;
|
|
FEventList.Free;
|
|
FEventDays.Free;
|
|
FHolidayDays.Free;
|
|
FOptionsCustomize.Free;
|
|
FOptionsView.Free;
|
|
FStyles.Free;
|
|
FSelectedDays.Free;
|
|
FEditStyle.Free;
|
|
FDefaultProperties.Free;
|
|
FTextEditProperties.Free;
|
|
FHintController.Free;
|
|
FEventEditInfo.Free;
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.DoAfterDragEvent(Target: TObject;
|
|
X, Y: Integer; var Accept: Boolean);
|
|
begin
|
|
if Assigned(FOnAfterDragEvent) then
|
|
FOnAfterDragEvent(Self, Target, X, Y, Accept);
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.DoAfterEditing(AEvent: TcxSchedulerControlEvent);
|
|
begin
|
|
if Assigned(FOnAfterEditing) then
|
|
FOnAfterEditing(Self, AEvent);
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.DoAfterSizingEvent(
|
|
AEvent: TcxSchedulerControlEvent; X, Y: Integer; var Accept: Boolean);
|
|
begin
|
|
if Assigned(FOnAfterSizingEvent) then
|
|
FOnAfterSizingEvent(Self, AEvent, X, Y, Accept);
|
|
end;
|
|
|
|
function TcxCustomScheduler.DoBeforeDeleting(
|
|
AEvent: TcxSchedulerControlEvent): Boolean;
|
|
begin
|
|
Result := True;
|
|
if Assigned(FOnBeforeDeleting) then
|
|
FOnBeforeDeleting(Self, AEvent, Result);
|
|
end;
|
|
|
|
function TcxCustomScheduler.DoBeforeDragEvent(
|
|
AEvent: TcxSchedulerControlEvent; X, Y: Integer): Boolean;
|
|
begin
|
|
Result := True;
|
|
if Assigned(FOnBeforeDragEvent) then
|
|
FOnBeforeDragEvent(Self, AEvent, X, Y, Result);
|
|
end;
|
|
|
|
function TcxCustomScheduler.DoBeforeEditing(
|
|
AEvent: TcxSchedulerControlEvent; AInplace: Boolean): Boolean;
|
|
begin
|
|
Result := (AEvent.Source <> nil) or (not AInplace or CanIntersect(AEvent));
|
|
if Result and Assigned(FOnBeforeEditing) then
|
|
FOnBeforeEditing(Self, AEvent, AInplace, Result);
|
|
end;
|
|
|
|
function TcxCustomScheduler.DoBeforeSizingEvent(
|
|
AEvent: TcxSchedulerControlEvent; X, Y: Integer): Boolean;
|
|
begin
|
|
Result := True;
|
|
if Assigned(FOnBeforeSizingEvent) then
|
|
FOnBeforeSizingEvent(Self, AEvent, X, Y, Result);
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.DoCalculateLayout(
|
|
AControl: TcxSchedulerSubControl);
|
|
begin
|
|
AControl.LayoutChanged;
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.DoCancelMode;
|
|
begin
|
|
if FCaptureControl <> nil then
|
|
FCaptureControl.Controller.DoCancelMode;
|
|
FCaptureControl := nil;
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.DoControllerReset(
|
|
AControl: TcxSchedulerSubControl);
|
|
begin
|
|
AControl.Controller.Reset;
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.DoCreateEventUsingInplaceEdit(
|
|
AKey: Char = #0);
|
|
var
|
|
AControlEvent: TcxSchedulerControlEvent;
|
|
begin
|
|
if not StorageActive then Exit;
|
|
AControlEvent := EventList.CreateEvent;
|
|
InitEventBySelection(AControlEvent, False, False, True);
|
|
if AControlEvent.Source <> nil then
|
|
AControlEvent.MoveTo(AControlEvent.Start + GetTimeBias(AControlEvent.Start));
|
|
EventList.Sort(@cxCompareSchedulerControlEvents);
|
|
CurrentView.Refresh;
|
|
EditController.Init(SelStart, SelResource, True);
|
|
if AKey = #0 then
|
|
EditController.Activate(AControlEvent)
|
|
else
|
|
EditController.Activate(AControlEvent, AKey);
|
|
if not EditController.IsEditing then
|
|
EditController.DeleteEvent(AControlEvent);
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.DoEventSelectionChanged(
|
|
AEvent: TcxSchedulerControlEvent);
|
|
begin
|
|
if Assigned(FOnEventSelectionChanged) then
|
|
FOnEventSelectionChanged(Self, AEvent);
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.DoFirstVisibleResourceChanged;
|
|
begin
|
|
if Assigned(FOnFirstVisibleResourceChanged) then
|
|
FOnFirstVisibleResourceChanged(Self);
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.DoGetEventDisplayText(
|
|
AEvent: TcxSchedulerControlEvent; var AText: string);
|
|
begin
|
|
AText := AEvent.Caption;
|
|
if Assigned(FOnGetEventDisplayText) then
|
|
FOnGetEventDisplayText(Self, AEvent, AText);
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.DoGetEventEditProperties(
|
|
AEvent: TcxSchedulerControlEvent; var AProperties: TcxCustomEditProperties);
|
|
begin
|
|
if CurrentView.GetEditWithSingleLineEditor(AEvent) then
|
|
AProperties := FTextEditProperties
|
|
else
|
|
AProperties := DefaultProperties;
|
|
if Assigned(OnGetEventEditProperties) then
|
|
begin
|
|
OnGetEventEditProperties(Self, AEvent, AProperties);
|
|
if AProperties = nil then
|
|
AProperties := DefaultProperties;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.DoHitTestRecalculate(
|
|
AControl: TcxSchedulerSubControl);
|
|
begin
|
|
AControl.Controller.HitTest.Recalculate;
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.DoInitEdit(AEdit: TcxCustomEdit);
|
|
begin
|
|
if Assigned(FOnInitEdit) then
|
|
FOnInitEdit(Self, AEdit);
|
|
end;
|
|
|
|
function TcxCustomScheduler.DoIsWorkTime(
|
|
AResourceItem: TcxSchedulerStorageResourceItem; const ADateTime: TDateTime): Boolean;
|
|
begin
|
|
Result := OptionsView.IsWorkTime(AResourceItem, ADateTime);
|
|
if Assigned(FOnIsWorkTime) then
|
|
FOnIsWorkTime(Self, AResourceItem, ADateTime, Result);
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.DoLayoutChanged;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
FCanvas := GetControlCanvas;
|
|
for I := 0 to FSubControls.Count - 1 do
|
|
SubControls[I].LayoutChanged;
|
|
UpdateScrollBars;
|
|
DoLayoutChangedEvent;
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.DoLayoutChangedEvent;
|
|
begin
|
|
if Assigned(FOnLayoutChanged) then
|
|
FOnLayoutChanged(Self);
|
|
end;
|
|
|
|
function TcxCustomScheduler.DoMoreEventsButtonClick: Boolean;
|
|
begin
|
|
Result := False;
|
|
if Assigned(FOnMoreEventsButtonClick) then
|
|
FOnMoreEventsButtonClick(Self, Result);
|
|
end;
|
|
|
|
function TcxCustomScheduler.DoNavigationButtonClick(AnInterval: TDateTime;
|
|
AResource: TcxSchedulerStorageResourceItem): Boolean;
|
|
begin
|
|
Result := False;
|
|
if Assigned(FOnNavigationButtonClick) then
|
|
FOnNavigationButtonClick(Self, AnInterval, AResource, Result);
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.DoCanShowView(
|
|
AView: TcxSchedulerCustomView; var Allow: Boolean);
|
|
begin
|
|
if Assigned(FOnCanShowView) then
|
|
FOnCanShowView(Self, AView, Allow);
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.DoSelectionChanged;
|
|
begin
|
|
if Assigned(FOnSelectionChanged) then
|
|
FOnSelectionChanged(Self);
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.DoScaleScroll;
|
|
begin
|
|
if Assigned(OnScaleScroll) then
|
|
with CurrentView do
|
|
OnScaleScroll(Self, GetFirstVisibleDate + GetFirstVisibleTime,
|
|
GetLastVisibleDate + GetLastVisibleTime);
|
|
end;
|
|
|
|
function TcxCustomScheduler.DoShowDateHint(const ADate: TDateTime; var AHintText: string): Boolean;
|
|
var
|
|
AOnShowDateHint: TcxSchedulerShowDateHintEvent;
|
|
begin
|
|
Result := False;
|
|
if not FOptionsView.ShowHints then
|
|
Exit;
|
|
Result := (Storage <> nil) and Storage.GetHolidayNamesByDate(ADate, AHintText);
|
|
AOnShowDateHint := OnShowDateHint;
|
|
if Assigned(AOnShowDateHint) then
|
|
AOnShowDateHint(Self, ADate, AHintText, Result);
|
|
Result := Result and (AHintText <> '');
|
|
end;
|
|
|
|
function TcxCustomScheduler.DoShowPopupMenu(AMenu: TComponent;
|
|
X, Y: Integer): Boolean;
|
|
begin
|
|
with CurrentView do
|
|
Result := Visible and cxRectPtIn(ViewInfo.Bounds, ScreenToClient(cxPoint(X, Y))) and
|
|
DoShowPopupMenu(X, Y);
|
|
if not Result then
|
|
Result := inherited DoShowPopupMenu(AMenu, X, Y);
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.DoViewTypeChanged(
|
|
ANewView: TcxSchedulerCustomView);
|
|
begin
|
|
if Assigned(FOnViewTypeChanged) then
|
|
FOnViewTypeChanged(Self, FCurrentView, ANewView);
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.DoUpdateTime;
|
|
begin
|
|
if not FSubControlsCreated or not HandleAllocated then Exit;
|
|
if CurrentView.Visible then
|
|
CurrentView.DateChanged;
|
|
if DateNavigator.Visible then
|
|
DateNavigator.CheckCurrentDate;
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.DragCanceled;
|
|
begin
|
|
FIsDragCanceled := True;
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.DrawSplitters;
|
|
begin
|
|
if OptionsView.ViewPosition in [vpLeft, vpRight] then
|
|
begin
|
|
FVertSplitter.Paint;
|
|
FHorzSplitter.Paint;
|
|
end
|
|
else
|
|
begin
|
|
FHorzSplitter.Paint;
|
|
FVertSplitter.Paint;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.FirstVisibleResourceChanged;
|
|
begin
|
|
ResourceNavigator.FirstVisibleResourceChanged;
|
|
DoFirstVisibleResourceChanged;
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.FontChanged;
|
|
begin
|
|
BeginUpdate;
|
|
if not IsLoading and FSubControlsCreated then
|
|
DateNavigator.SetIntegralSizes;
|
|
inherited FontChanged;
|
|
LayoutChanged;
|
|
EndUpdate;
|
|
end;
|
|
|
|
function TcxCustomScheduler.GetClientBounds: TRect;
|
|
begin
|
|
Result := GetBounds;
|
|
InflateRect(Result, -BorderSize, -BorderSize);
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.FocusChanged;
|
|
begin
|
|
if IsDestroying then Exit;
|
|
if OptionsView.HideSelection and not EditController.Focused then
|
|
begin
|
|
if (CurrentView <> nil) and CurrentView.Visible then
|
|
CurrentView.Refresh;
|
|
if DateNavigator.Visible then
|
|
DateNavigator.Refresh;
|
|
end;
|
|
inherited FocusChanged;
|
|
if not Focused then
|
|
HintController.HideHint;
|
|
end;
|
|
|
|
function TcxCustomScheduler.GetControlCanvas: TcxCanvas;
|
|
begin
|
|
{$IFDEF DEBUGPAINT}
|
|
Result := inherited Canvas
|
|
{$ELSE}
|
|
Result := FBitmapCanvas;
|
|
{$ENDIF}
|
|
end;
|
|
|
|
function TcxCustomScheduler.GetControlFromPoint(
|
|
const APoint: TPoint): TcxSchedulerSubControl;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
Result := Background;
|
|
for I := 0 to SubControlCount - 1 do
|
|
if SubControls[I].CanCapture(APoint) then
|
|
begin
|
|
Result := SubControls[I];
|
|
Break;
|
|
end;
|
|
end;
|
|
|
|
function TcxCustomScheduler.GetCursor(
|
|
X, Y: Integer): TCursor;
|
|
begin
|
|
Result := crDefault;
|
|
if not IsDesigning then
|
|
Result := GetControlFromPoint(cxPoint(X, Y)).Controller.GetCursor(X, Y);
|
|
if Result = crDefault then
|
|
Result := inherited GetCursor(X, Y);
|
|
end;
|
|
|
|
function TcxCustomScheduler.GetDateTimeHelper: TcxSchedulerDateTimeHelperClass;
|
|
begin
|
|
Result := cxSchedulerUtils.DateTimeHelper;
|
|
end;
|
|
|
|
function TcxCustomScheduler.GetDateNavigatorLoadedSize: TSize;
|
|
begin
|
|
if IsViewAtLeft then
|
|
Result.cx := FStoredClientBounds.Right - VertSplitter.Right
|
|
else
|
|
Result.cx := VertSplitter.Left - FStoredClientBounds.Left;
|
|
Result.cy := HorzSplitter.Top - FStoredClientBounds.Top;
|
|
end;
|
|
|
|
function TcxCustomScheduler.GetDesignHitTest(
|
|
X, Y: Integer; Shift: TShiftState): Boolean;
|
|
begin
|
|
Result := inherited GetDesignHitTest(X, Y, Shift);
|
|
if not Result then
|
|
begin
|
|
Result := Capture.AllowDesignHitTest(X, Y, Shift);
|
|
if not Result then
|
|
Result := GetControlFromPoint(cxPoint(X, Y)).AllowDesignHitTest(X, Y, Shift);
|
|
end;
|
|
end;
|
|
|
|
function TcxCustomScheduler.GetEventEditInfo(AEvent: TcxSchedulerControlEvent;
|
|
ARecurrence: Boolean = False; AReadOnly: Boolean = False): TcxSchedulerEventEditInfo;
|
|
begin
|
|
Result := FEventEditInfo;
|
|
Result.Event := AEvent;
|
|
Result.AllowHiddenEvents := OptionsView.ShowEventsWithoutResource or not HasResources;
|
|
Result.LookAndFeel := DialogsLookAndFeel;
|
|
Result.Intersection := EventOperations.Intersection;
|
|
Result.ReadOnly := AReadOnly;
|
|
Result.RecurrenceButton := EventOperations.Recurrence;
|
|
Result.Recurrence := ARecurrence;
|
|
Result.ForcePatternEditing := ARecurrence;
|
|
Result.BiasTime := GetTimeBias(AEvent.Start);
|
|
Result.ShowResources := EventOperations.SharingBetweenResources;
|
|
Result.ShowTaskComplete := CurrentView.ShowTaskComplete;
|
|
end;
|
|
|
|
function TcxCustomScheduler.GetEventHintText(
|
|
AEvent: TcxSchedulerControlEvent): string;
|
|
begin
|
|
Result := AEvent.Caption;
|
|
if not AEvent.AllDayEvent then
|
|
begin
|
|
with DateTimeHelper do
|
|
Result := TimeToStr(AEvent.Start) + '-' + TimeToStr(AEvent.Finish) + ' ' + Result;
|
|
end;
|
|
GetEventUserHintText(AEvent, Result);
|
|
end;
|
|
|
|
function TcxCustomScheduler.GetEventUserHintText(AEvent: TcxSchedulerControlEvent;
|
|
var AText: string): Boolean;
|
|
begin
|
|
Result := Assigned(FOnGetEventHintText);
|
|
if Result then
|
|
FOnGetEventHintText(Self, AEvent, AText);
|
|
end;
|
|
|
|
function TcxCustomScheduler.GetHScrollBarBounds: TRect;
|
|
begin
|
|
Result := CurrentView.GetHScrollBarBounds;
|
|
end;
|
|
|
|
function TcxCustomScheduler.GetInternalCanvas: TcxCanvas;
|
|
begin
|
|
Result := inherited Canvas;
|
|
end;
|
|
|
|
function TcxCustomScheduler.GetIsLocked: Boolean;
|
|
begin
|
|
Result := cfLocked in FControlFlags;
|
|
end;
|
|
|
|
function TcxCustomScheduler.GetNextView(
|
|
AView: TcxSchedulerCustomView): TcxSchedulerCustomView;
|
|
begin
|
|
Result := AView;
|
|
end;
|
|
|
|
function TcxCustomScheduler.GetOnShowDateHint: TcxSchedulerShowDateHintEvent;
|
|
begin
|
|
Result := FOnShowDateHint;
|
|
end;
|
|
|
|
function TcxCustomScheduler.GetPainterHelper: TcxSchedulerPainterHelperClass;
|
|
begin
|
|
Result := TcxSchedulerPainterHelper;
|
|
end;
|
|
|
|
function TcxCustomScheduler.GetSizeGripBounds: TRect;
|
|
begin
|
|
Result := CurrentView.GetSizeGripBounds;
|
|
end;
|
|
|
|
function TcxCustomScheduler.GetTimeBias(AStart: TDateTime): Double;
|
|
begin
|
|
Result := 0;
|
|
if StorageValid then
|
|
begin
|
|
with DateTimeHelper do
|
|
begin
|
|
Result := TimeZoneBias(OptionsView.CurrentTimeZone) - TimeZoneBias(CurrentTimeZone);
|
|
if OptionsView.CurrentTimeZoneDaylightSaving then
|
|
Result := Result + TimeZoneDaylightBias(AStart, CurrentTimeZone) * MinuteToTime;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TcxCustomScheduler.GetVScrollBarBounds: TRect;
|
|
begin
|
|
Result := CurrentView.GetVScrollBarBounds;
|
|
end;
|
|
|
|
function TcxCustomScheduler.HasConflict(AStartDrag: Boolean): Boolean;
|
|
begin
|
|
if EventOperations.Intersection then
|
|
Result := False
|
|
else
|
|
Result := EventList.HasConflict(IsCopyDragDrop, AStartDrag);
|
|
end;
|
|
|
|
function TcxCustomScheduler.HasResources: Boolean;
|
|
begin
|
|
Result := (Storage <> nil) and (Storage.ResourceCount > 0);
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.InitControl;
|
|
begin
|
|
inherited InitControl;
|
|
if not IsLoading and OptionsCustomize.IntegralSizing then
|
|
DateNavigator.SetIntegralSizes;
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.InitScrollBarsParameters;
|
|
begin
|
|
CurrentView.InitScrollBarsParameters;
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.InternalDeleteEvent(AEvent: TcxSchedulerControlEvent;
|
|
AIgnoreRecurring: Boolean);
|
|
var
|
|
ADeleteOccurrence: Boolean;
|
|
begin
|
|
if not DoBeforeDeleting(AEvent) then Exit;
|
|
if not AIgnoreRecurring and AEvent.IsRecurring then
|
|
begin
|
|
if cxShowRecurrenceSelectionDialog(AEvent, rsmDeleting,
|
|
DialogsLookAndFeel, ADeleteOccurrence) then
|
|
if ADeleteOccurrence then
|
|
AEvent.Delete
|
|
else
|
|
AEvent.Pattern.Delete;
|
|
end
|
|
else
|
|
AEvent.Delete;
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.InternalDeleteSelectedEvents(AForceDelete, ACheckReadOnly: Boolean);
|
|
var
|
|
I, AIndex, ACount: Integer;
|
|
AEvent: TcxSchedulerControlEvent;
|
|
ASelectedIDs: array of Variant;
|
|
|
|
procedure GetSelection;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
SetLength(ASelectedIDs, SelectedEventCount);
|
|
for I := 0 to SelectedEventCount - 1 do
|
|
ASelectedIDs[I] := SelectedEvents[I].ID;
|
|
end;
|
|
|
|
function GetIndexOfID(const AID: Variant): Integer;
|
|
begin
|
|
for Result := 0 to High(ASelectedIDs) do
|
|
if VarEquals(AID, ASelectedIDs[Result]) then Exit;
|
|
Result := -1;
|
|
end;
|
|
|
|
procedure DeleteIDByIndex(AIndex: Integer);
|
|
var
|
|
I: Integer;
|
|
begin
|
|
for I := AIndex + 1 to High(ASelectedIDs) do
|
|
ASelectedIDs[I - 1] := ASelectedIDs[I];
|
|
SetLength(ASelectedIDs, Length(ASelectedIDs) - 1);
|
|
end;
|
|
|
|
begin
|
|
GetSelection;
|
|
if AForceDelete then
|
|
BeginUpdate;
|
|
ACount := 0;
|
|
try
|
|
while ACount <> SelectedEventCount do
|
|
begin
|
|
ACount := SelectedEventCount;
|
|
for I := 0 to ACount - 1 do
|
|
begin
|
|
AEvent := SelectedEvents[I];
|
|
AIndex := GetIndexOfID(AEvent.ID);
|
|
if AIndex >= 0 then
|
|
begin
|
|
DeleteIDByIndex(AIndex);
|
|
if not AForceDelete then
|
|
DeleteEvent(AEvent)
|
|
else
|
|
if not (ACheckReadOnly and AEvent.ReadOnly) then
|
|
InternalDeleteEvent(AEvent, True);
|
|
if ACount <> SelectedEventCount then break;
|
|
end;
|
|
end;
|
|
end;
|
|
finally
|
|
SetLength(ASelectedIDs, 0);
|
|
if AForceDelete then
|
|
EndUpdate;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.InternalPaint(const AClipRect: TRect);
|
|
var
|
|
I: Integer;
|
|
ACanvas: TcxCanvas;
|
|
AControl: TcxSchedulerSubControl;
|
|
begin
|
|
ACanvas := GetControlCanvas;
|
|
SelectClipRgn(ACanvas.Handle, 0);
|
|
if BorderStyle = cxcbsDefault then
|
|
begin
|
|
LookAndFeelPainter.DrawSchedulerBorder(ACanvas, Bounds);
|
|
ACanvas.IntersectClipRect(ClientBounds);
|
|
end;
|
|
if ResourceNavigator.Visible and cxRectIsEqual(AClipRect, ResourceNavigator.Bounds) then
|
|
ResourceNavigator.Paint
|
|
else
|
|
begin
|
|
ACanvas.SaveClipRegion;
|
|
try
|
|
if not IsRectEmpty(AClipRect) then
|
|
ACanvas.IntersectClipRect(AClipRect);
|
|
for I := 0 to SubControlCount - 1 do
|
|
begin
|
|
AControl := SubControls[I];
|
|
if not AControl.IsSpecialPaint then
|
|
AControl.Paint;
|
|
end;
|
|
DrawSplitters;
|
|
finally
|
|
ACanvas.RestoreClipRegion;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TcxCustomScheduler.IsViewAtLeft: Boolean;
|
|
begin
|
|
Result := OptionsView.ViewPosition = vpLeft;
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.KeyDown(
|
|
var Key: Word; Shift: TShiftState);
|
|
begin
|
|
inherited KeyDown(Key, Shift);
|
|
if KeyboardListener <> nil then
|
|
KeyboardListener.Controller.KeyDown(Key, Shift)
|
|
else
|
|
CurrentView.Controller.KeyDown(Key, Shift);
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.KeyPress(var Key: Char);
|
|
begin
|
|
inherited KeyPress(Key);
|
|
if KeyboardListener <> nil then
|
|
KeyboardListener.Controller.KeyPress(Key)
|
|
else
|
|
if EditController.Edit <> nil then
|
|
PostMessage(EditController.Edit.Handle, WM_CHAR, Word(Key), 0)
|
|
else
|
|
CurrentView.Controller.KeyPress(Key);
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.KeyUp(
|
|
var Key: Word; Shift: TShiftState);
|
|
begin
|
|
inherited KeyUp(Key, Shift);
|
|
if KeyboardListener <> nil then
|
|
KeyboardListener.Controller.KeyUp(Key, Shift)
|
|
else
|
|
CurrentView.Controller.KeyUp(Key, Shift);
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.Loaded;
|
|
begin
|
|
inherited Loaded;
|
|
DateNavigator.Loaded;
|
|
ControlBox.Width := DateNavigator.Width;
|
|
if CurrentView <> nil then
|
|
CurrentView.VisibleChanged;
|
|
FullRefresh;
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.LockUpdateChanged(
|
|
ALocking: Boolean);
|
|
begin
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.LookAndFeelChanged(
|
|
Sender: TcxLookAndFeel; AChangedValues: TcxLookAndFeelValues);
|
|
var
|
|
I: Integer;
|
|
begin
|
|
for I := 0 to SubControlCount - 1 do
|
|
SubControls[I].LookAndFeelChanged(Sender, AChangedValues);
|
|
inherited LookAndFeelChanged(Sender, AChangedValues);
|
|
LayoutChanged;
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.Modified;
|
|
begin
|
|
if not FBoundsChanging and CanModified then
|
|
inherited Modified;
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.MouseDown(
|
|
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
|
|
begin
|
|
FPrevMousePos := cxInvalidPoint;
|
|
FActiveControl := GetControlFromPoint(cxPoint(X, Y));
|
|
Capture := FActiveControl;
|
|
Capture.DoBeforeMouseDown(Button, Shift, X, Y);
|
|
inherited MouseDown(Button, Shift, X, Y);
|
|
FCaptureControl := FActiveControl; //can be changed on BeginDrag
|
|
Capture.DoMouseDown(Button, Shift, X, Y);
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.MouseLeave(AControl: TControl);
|
|
begin
|
|
inherited MouseLeave(AControl);
|
|
if FActiveControl <> nil then
|
|
FActiveControl.Controller.MouseLeave;
|
|
FActiveControl := nil;
|
|
if CurrentView <> nil then
|
|
CurrentView.HitTest.SetHitPoint(cxInvalidPoint);
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.MouseMove(
|
|
Shift: TShiftState; X, Y: Integer);
|
|
var
|
|
FPrevControl: TcxSchedulerSubControl;
|
|
begin
|
|
if (FPrevMousePos.X = X) and (FPrevMousePos.Y = Y) then Exit;
|
|
FPrevMousePos := cxPoint(X, Y);
|
|
FPrevControl := FActiveControl;
|
|
FActiveControl := FCaptureControl;
|
|
if FActiveControl = nil then
|
|
FActiveControl := GetControlFromPoint(cxPoint(X, Y));
|
|
FActiveControl.DoMouseMove(Shift, X, Y);
|
|
inherited MouseMove(Shift, X, Y);
|
|
if OptionsView.HotTrack or OptionsView.ShowHints then
|
|
begin
|
|
CurrentView.MousePositionChanged(X, Y);
|
|
if (ssLeft in Shift) and not CurrentView.HitTest.HitAtControl and (FSelStart <> FSelFinish) then
|
|
begin
|
|
ReplaceSelParams(FSelStart, FSelStart, FSelResource);
|
|
CurrentView.Refresh;
|
|
end;
|
|
EventHitTestController.MouseMove(X, Y, Shift);
|
|
end;
|
|
if (FPrevControl <> FActiveControl) and (FPrevControl <> nil) then
|
|
FPrevControl.Controller.MouseLeave;
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.MouseUp(
|
|
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
|
|
begin
|
|
inherited MouseUp(Button, Shift, X, Y);
|
|
Capture.DoMouseUp(Button, Shift, X, Y);
|
|
Capture := nil;
|
|
CurrentView.MousePositionChanged(X, Y);
|
|
EventHitTestController.MouseMove(X, Y, Shift);
|
|
end;
|
|
|
|
function TcxCustomScheduler.NeedShowHint(AEvent: TcxSchedulerControlEvent;
|
|
var AHintText: string; AllowShow: Boolean): Boolean;
|
|
begin
|
|
if CurrentView <> nil then
|
|
AHintText := CurrentView.GetEventHintText(AEvent)
|
|
else
|
|
AHintText := GetEventHintText(AEvent);
|
|
Result := (Length(AHintText) > 0) and
|
|
(Assigned(FOnGetEventHintText) or AllowShow);
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.Paint;
|
|
var
|
|
R: TRect;
|
|
begin
|
|
if IsLoading then Exit;
|
|
{$IFNDEF DEBUGPAINT}
|
|
if not (cfImageValid in FControlFlags) then
|
|
{$ELSE}
|
|
GdiSetBatchLimit(1);
|
|
{$ENDIF}
|
|
begin
|
|
if (GetClipBox(inherited Canvas.Handle, R) = 0) or not
|
|
cxRectIsEqual(R, ResourceNavigator.Bounds) // todo: bug with redrawing
|
|
then
|
|
R := cxNullRect;
|
|
InternalPaint(R);
|
|
Include(FControlFlags, cfImageValid);
|
|
end;
|
|
{$IFNDEF DEBUGPAINT}
|
|
BitBlt(inherited Canvas.Handle, 0, 0, Width,
|
|
Height, BitmapCanvas.Handle, 0, 0, SRCCOPY);
|
|
{$ENDIF}
|
|
FCanModified := True;
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.PeriodChanged;
|
|
begin
|
|
FullRefresh;
|
|
DateNavigator.DoPeriodChangedEvent;
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.RemoveSubControl(
|
|
AControl: TcxSchedulerSubControl);
|
|
begin
|
|
if (FSubControls.Remove(AControl) <> -1) and not IsDestroying then
|
|
begin
|
|
LayoutChanged;
|
|
if Capture = AControl then
|
|
Capture := nil;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.ReplaceSelParams(ASelStart, ASelFinish: TDateTime;
|
|
AResource: TcxSchedulerStorageResourceItem);
|
|
begin
|
|
with DateTimeHelper do
|
|
begin
|
|
if (FSelResource <> AResource) or (FSelStart <> RoundTime(ASelStart)) or
|
|
(FSelFinish <> RoundTime(ASelFinish)) then
|
|
begin
|
|
FSelResource := AResource;
|
|
FSelStart := RoundTime(ASelStart);
|
|
FSelFinish := RoundTime(ASelFinish);
|
|
MakeResourceVisible(AResource);
|
|
DoSelectionChanged;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.Scroll(AScrollBarKind: TScrollBarKind;
|
|
AScrollCode: TScrollCode; var AScrollPos: Integer);
|
|
begin
|
|
if EditController.IsEditing then Exit;
|
|
if ResourceNavigator.NeedScrollBar and (AScrollBarKind = ResourceNavigator.ScrollBarKind) then
|
|
ResourceNavigator.Scroll(AScrollCode, AScrollPos)
|
|
else
|
|
begin
|
|
CurrentView.Scroll(AScrollBarKind, AScrollCode, AScrollPos);
|
|
DoScaleScroll;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.SelectedDaysChanged(AView: TcxSchedulerCustomView);
|
|
begin
|
|
if AView <> nil then
|
|
AView.SelectedDaysChanged;
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.SetCurrentView(
|
|
AView: TcxSchedulerCustomView);
|
|
begin
|
|
if (AView <> nil) and (AView.Scheduler = Self) then
|
|
begin
|
|
if Assigned(FCurrentView) then
|
|
FCurrentView.DeactivateView;
|
|
FCurrentView := AView;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.SubControlAdd(
|
|
AControl: TcxSchedulerSubControl);
|
|
begin
|
|
FSubControls.Add(AControl);
|
|
LayoutChanged;
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.SubControlRemove(
|
|
AControl: TcxSchedulerSubControl);
|
|
begin
|
|
FSubControls.Remove(AControl);
|
|
LayoutChanged;
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.SynchronizeVisibleDays;
|
|
begin
|
|
Include(FControlFlags, cfViewValid);
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.UpdateDateNavigatorDragging(Accept: Boolean);
|
|
begin
|
|
if not DateNavigator.Visible then Exit;
|
|
if Accept then
|
|
DateNavigator.UpdateDragging
|
|
else
|
|
DateNavigator.ClearDragging;
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.UpdateHolidayDays(ABegin, AEnd: TDate);
|
|
begin
|
|
FHolidayDays.Clear;
|
|
if (Storage <> nil) then
|
|
Storage.PopulateHolidayDates(FHolidayDays, ABegin, AEnd);
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.UpdateEventsCache(
|
|
ACheckDaysInterval: Boolean);
|
|
var
|
|
AStart, AFinish: TDateTime;
|
|
begin
|
|
CurrentView.Controller.CloseInplaceEdit;
|
|
if not StorageValid then
|
|
begin
|
|
FreeAndNil(FEventList);
|
|
FEventList := CreateEventList;
|
|
end;
|
|
FEventList.TimeZone := OptionsView.CurrentTimeZone;
|
|
FEventList.DaylightSaving := OptionsView.CurrentTimeZoneDaylightSaving;
|
|
FEventList.ShowEventsWithoutResource := OptionsView.ShowEventsWithoutResource or
|
|
(VisibleGroupingKind = gkNone);
|
|
AStart := Min(CurrentView.FirstVisibleDate, DateNavigator.GetRealFirstDate)
|
|
- CurrentView.GetVisibleDaysRange;
|
|
AFinish := Max(CurrentView.LastVisibleDate, DateNavigator.GetRealLastDate)
|
|
+ CurrentView.GetVisibleDaysRange;
|
|
if ACheckDaysInterval and (AStart >= EventList.Start) and
|
|
(AFinish <= EventList.Finish) then Exit;
|
|
FEventList.BeforeUpdate;
|
|
FEventList.SelStart := CurrentView.FirstVisibleDate - 7;
|
|
FEventList.SelFinish := CurrentView.LastVisibleDate + 7;
|
|
FEventList.UseTimeRange := CurrentView.CheckEventsVisibility;
|
|
if StorageValid then
|
|
Storage.GetEvents(FEventList, AStart, AFinish);
|
|
TabOrdersList.Assign(EventList);
|
|
TabOrdersList.Sort(@cxCompareTabOrders);
|
|
FEventDays.Clear;
|
|
if DateNavigator.GetShowDatesContainingEventsInBold then
|
|
FEventList.ExtractUsedDays(FEventDays);
|
|
if (FEventList.Selection.Count > 0) and (CurrentView <> nil) then
|
|
CurrentView.Controller.FDragEvent := FEventList.Selection[0]
|
|
else
|
|
CurrentView.Controller.FDragEvent := nil;
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.ValidateFirstVisibleResourceIndex;
|
|
begin
|
|
if (OptionsView.ResourcesPerPage = 0) and (FFirstVisibleResourceIndex <> 0) then
|
|
begin
|
|
FFirstVisibleResourceIndex := 0;
|
|
FirstVisibleResourceChanged;
|
|
end
|
|
else
|
|
if FFirstVisibleResourceIndex + OptionsView.ResourcesPerPage > ResourceNavigator.ResourceCount then
|
|
begin
|
|
FFirstVisibleResourceIndex := Max(0, ResourceNavigator.ResourceCount -
|
|
OptionsView.ResourcesPerPage);
|
|
end;
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.ValidateSelection(
|
|
ASelection: TcxSchedulerDateList);
|
|
begin
|
|
DateNavigator.UpdateSelection;
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.ValidateState;
|
|
var
|
|
AIsLocked: Boolean;
|
|
begin
|
|
AIsLocked := cfLocked in FControlFlags;
|
|
if cfInvalidLayout in FControlFlags then
|
|
try
|
|
LayoutChanged;
|
|
finally
|
|
FControlFlags := [];
|
|
if AIsLocked then
|
|
FControlFlags := [cfLocked];
|
|
end;
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.ViewVisibleChanged(
|
|
AView: TcxSchedulerCustomView);
|
|
begin
|
|
Exclude(FControlFlags, cfViewValid);
|
|
if FVisibleChangedCount = 0 then
|
|
DateNavigator.BeginUpdate;
|
|
Inc(FVisibleChangedCount);
|
|
try
|
|
if AView.Visible and (CurrentView <> AView) then
|
|
begin
|
|
CurrentView.Visible := False;
|
|
DoViewTypeChanged(AView);
|
|
CurrentView := AView;
|
|
end
|
|
else
|
|
if not FCurrentView.Visible and (FVisibleChangedCount = 1) then
|
|
GetNextView(FCurrentView).Visible := True;
|
|
finally
|
|
Dec(FVisibleChangedCount);
|
|
if FVisibleChangedCount = 0 then
|
|
begin
|
|
AlignSubControls;
|
|
LayoutChanged;
|
|
DateNavigator.EndUpdate;
|
|
end;
|
|
end;
|
|
Modified;
|
|
end;
|
|
|
|
function TcxCustomScheduler.VisibleGroupingKind: TcxSchedulerGroupingKind;
|
|
var
|
|
I, C: Integer;
|
|
begin
|
|
Result := CurrentView.GetGroupingKind;
|
|
C := 0;
|
|
if HasResources then
|
|
begin
|
|
for I := 0 to Storage.ResourceCount - 1 do
|
|
if Storage.Resources.ResourceItems[I].Visible then Inc(C);
|
|
end;
|
|
if C = 0 then
|
|
Result := gkNone
|
|
else
|
|
if Result = gkDefault then
|
|
Result := gkByResource;
|
|
end;
|
|
|
|
function TcxCustomScheduler.CanDrag(X, Y: Integer): Boolean;
|
|
begin
|
|
Result := inherited CanDrag(X, Y) and not IsDesigning and
|
|
CaptureController.CanDrag(X, Y);
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.DoEndDrag(
|
|
Target: TObject; X, Y: Integer);
|
|
begin
|
|
CaptureController.EndDrag(Target, X, Y);
|
|
inherited DoEndDrag(Target, X, Y);
|
|
Capture := nil;
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.DoStartDrag(
|
|
var DragObject: TDragObject);
|
|
begin
|
|
FIsDragCanceled := False;
|
|
inherited DoStartDrag(DragObject);
|
|
CaptureController.StartDrag(DragObject);
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.DragAndDrop(
|
|
const P: TPoint; var Accepted: Boolean);
|
|
begin
|
|
inherited DragAndDrop(P, Accepted);
|
|
CaptureController.DragAndDrop(P, Accepted);
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.DragOver(
|
|
Source: TObject; X, Y: Integer; State: TDragState; var Accept: Boolean);
|
|
var
|
|
AAccept, ACopyDragDrop: Boolean;
|
|
AControl: TcxSchedulerSubControl;
|
|
begin
|
|
ACopyDragDrop := IsCopyDragDrop;
|
|
if State <> dsDragMove then
|
|
FPrevMousePos := cxInvalidPoint
|
|
else
|
|
if (FPrevMousePos.X = X) and (FPrevMousePos.Y = Y) and (FPrevCopyDragDrop = ACopyDragDrop) then
|
|
Exit
|
|
else
|
|
FPrevMousePos := cxPoint(X, Y);
|
|
if not Dragging then
|
|
begin
|
|
AControl := GetControlFromPoint(Point(X, Y));
|
|
if AControl <> nil then
|
|
SetCaptureControl(AControl);
|
|
end;
|
|
AAccept := Accept and (DragMode = dmAutomatic);
|
|
inherited DragOver(Source, X, Y, State, Accept);
|
|
if not Assigned(OnDragOver) then Accept := AAccept;
|
|
CaptureController.DragOver(Source, X, Y, State, Accept);
|
|
FPrevCopyDragDrop := ACopyDragDrop;
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.EndDragAndDrop(
|
|
Accepted: Boolean);
|
|
begin
|
|
inherited EndDragAndDrop(Accepted);
|
|
CaptureController.EndDragAndDrop(Accepted);
|
|
end;
|
|
|
|
function TcxCustomScheduler.GetDragAndDropObjectClass: TcxDragAndDropObjectClass;
|
|
begin
|
|
Result := CaptureController.GetDragAndDropObjectClass;
|
|
end;
|
|
|
|
function TcxCustomScheduler.GetDragObjectClass: TDragControlObjectClass;
|
|
begin
|
|
Result := CurrentView.GetDragObjectClass;
|
|
end;
|
|
|
|
function TcxCustomScheduler.StartDragAndDrop(
|
|
const P: TPoint): Boolean;
|
|
begin
|
|
Result := CaptureController.StartDragAndDrop(P)
|
|
end;
|
|
|
|
// IcxSchedulerStorageListener
|
|
procedure TcxCustomScheduler.StorageChanged(Sender: TObject);
|
|
begin
|
|
FullRefresh;
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.StorageRemoved(Sender: TObject);
|
|
begin
|
|
CurrentView.Controller.CloseInplaceEdit;
|
|
FStorage.RemoveListener(Self);
|
|
FStorage := nil;
|
|
LayoutChanged;
|
|
end;
|
|
|
|
// IcxFormatControllerListener
|
|
procedure TcxCustomScheduler.DoStartOfWeekChanged(
|
|
AOldStartOfWeek, ANewStartOfWeek: TDay);
|
|
var
|
|
I, ADelta: Integer;
|
|
begin
|
|
ADelta := Ord(ANewStartOfWeek) - Ord(AOldStartOfWeek);
|
|
if (ADelta <> 0) and not CurrentView.IsDayView then
|
|
begin
|
|
for I := 0 to SelectedDays.Count - 1 do
|
|
SelectedDays[I] := SelectedDays[I] + ADelta;
|
|
end;
|
|
OptionsView.CalculateActualStartOfWeek;
|
|
FullRefresh;
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.FormatChanged;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
if DateTimeHelper <> nil then DateTimeHelper.Refresh;
|
|
if OptionsView.StartOfWeek = swSystem then
|
|
DoStartOfWeekChanged(OptionsView.ActualStartOfWeek,
|
|
TDay(DateTimeHelper.StartOfWeek))
|
|
else
|
|
begin
|
|
for I := 0 to SubControlCount - 1 do
|
|
SubControls[I].FormatChanged;
|
|
FullRefresh;
|
|
end;
|
|
end;
|
|
|
|
// IcxFormatControllerListener2
|
|
procedure TcxCustomScheduler.TimeChanged;
|
|
begin
|
|
DoUpdateTime;
|
|
end;
|
|
|
|
// IcxStoredObject
|
|
function TcxCustomScheduler.GetObjectName: string;
|
|
begin
|
|
if FStoringName <> '' then
|
|
Result := FStoringName
|
|
else
|
|
Result := Name;
|
|
end;
|
|
|
|
function TcxCustomScheduler.GetProperties(AProperties: TStrings): Boolean;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
AProperties.Add('SelectedDayCount');
|
|
AProperties.Add('ResourcesPerPage');
|
|
for I := 0 to SubControlCount - 1 do
|
|
SubControls[I].GetProperties(AProperties);
|
|
Result := True;
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.GetPropertyValue(const AName: string;
|
|
var AValue: Variant);
|
|
var
|
|
I: Integer;
|
|
begin
|
|
if AName = 'SelectedDayCount' then
|
|
AValue := SelectedDays.Count
|
|
else
|
|
if AName = 'ResourcesPerPage' then
|
|
AValue := OptionsView.ResourcesPerPage
|
|
else
|
|
for I := 0 to SubControlCount - 1 do
|
|
SubControls[I].GetPropertyValue(AName, AValue);
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.SetPropertyValue(const AName: string;
|
|
const AValue: Variant);
|
|
var
|
|
I: Integer;
|
|
ADate: TDateTime;
|
|
begin
|
|
if AName = 'SelectedDayCount' then
|
|
begin
|
|
SelectedDays.Clear;
|
|
ADate := Date;
|
|
for I := 0 to Min(Max(AValue - 1, 0), 41) do
|
|
SelectedDays.Add(ADate + I);
|
|
end
|
|
else
|
|
if AName = 'ResourcesPerPage' then
|
|
OptionsView.ResourcesPerPage := AValue
|
|
else
|
|
for I := 0 to SubControlCount - 1 do
|
|
SubControls[I].SetPropertyValue(AName, AValue);
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.CreateUpdateTimeTimer;
|
|
begin
|
|
FUpdateTimeTimer := TTimer.Create(nil);
|
|
FUpdateTimeTimer.Interval := 60 * 1000;
|
|
FUpdateTimeTimer.OnTimer := UpdateTimeHandler;
|
|
end;
|
|
|
|
function TcxCustomScheduler.GetActiveHitTest: TcxSchedulerSubControlHitTest;
|
|
var
|
|
AControl: TcxSchedulerSubControl;
|
|
APos: TPoint;
|
|
begin
|
|
if (FActiveControl <> nil) and (FCaptureControl = nil) then
|
|
Result := FActiveControl.HitTest
|
|
else
|
|
begin
|
|
APos := ScreenToClient(GetMouseCursorPos);
|
|
AControl := GetControlFromPoint(APos);
|
|
if AControl = Background then
|
|
Result := nil
|
|
else
|
|
begin
|
|
AControl.MousePositionChanged(APos.X, APos.Y);
|
|
Result := AControl.HitTest;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TcxCustomScheduler.GetCaptureControl: TcxSchedulerSubControl;
|
|
begin
|
|
Result := FCaptureControl;
|
|
if FCaptureControl = nil then
|
|
Result := Background;
|
|
end;
|
|
|
|
function TcxCustomScheduler.GetCaptureController: TcxSchedulerSubControlController;
|
|
begin
|
|
Result := Capture.Controller;
|
|
end;
|
|
|
|
function TcxCustomScheduler.GetSelectedEventCount: Integer;
|
|
begin
|
|
Result := EventList.Selection.Count;
|
|
end;
|
|
|
|
function TcxCustomScheduler.GetSelectedEvent(
|
|
AIndex: Integer): TcxSchedulerControlEvent;
|
|
begin
|
|
Result := EventList.Selection[AIndex]
|
|
end;
|
|
|
|
function TcxCustomScheduler.GetSelFinish: TDateTime;
|
|
begin
|
|
Result := Max(FSelStart, FSelFinish);
|
|
Result := DateTimeHelper.RoundTime(Result + CurrentView.GetTimeIncrement);
|
|
CurrentView.ValidateSelectionFinishTime(Result);
|
|
end;
|
|
|
|
function TcxCustomScheduler.GetSelStart: TDateTime;
|
|
begin
|
|
Result := Min(FSelStart, FSelFinish);
|
|
end;
|
|
|
|
function TcxCustomScheduler.GetIsDynamicUpdate: Boolean;
|
|
begin
|
|
Result := OptionsCustomize.DynamicSizing and not IsDesigning;
|
|
end;
|
|
|
|
function TcxCustomScheduler.GetStartOfWeek: TDay;
|
|
begin
|
|
Result := OptionsView.ActualStartOfWeek;
|
|
end;
|
|
|
|
function TcxCustomScheduler.GetStorageActive: Boolean;
|
|
begin
|
|
Result := (FStorage <> nil) and FStorage.IsActive;
|
|
end;
|
|
|
|
function TcxCustomScheduler.GetStorageValid: Boolean;
|
|
begin
|
|
Result := FStorage <> nil;
|
|
end;
|
|
|
|
function TcxCustomScheduler.GetSubControl(
|
|
AIndex: Integer): TcxSchedulerSubControl;
|
|
begin
|
|
Result := TcxSchedulerSubControl(FSubControls[AIndex])
|
|
end;
|
|
|
|
function TcxCustomScheduler.GetSubControlCount: Integer;
|
|
begin
|
|
Result := FSubControls.Count;
|
|
end;
|
|
|
|
function TcxCustomScheduler.GetVisibleEventCount: Integer;
|
|
begin
|
|
Result := EventList.Count;
|
|
end;
|
|
|
|
function TcxCustomScheduler.GetVisibleEvent(
|
|
AIndex: Integer): TcxSchedulerControlEvent;
|
|
begin
|
|
Result := EventList[AIndex];
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.InitEventBySelection(
|
|
AEvent: TcxSchedulerEvent; AllDay: Boolean;
|
|
ARecurrence: Boolean; AInplaceEditing: Boolean);
|
|
const
|
|
States: array[Boolean] of Byte = (tlsBusy, tlsFree);
|
|
begin
|
|
if SelResource <> nil then
|
|
AEvent.ResourceID := SelResource.ResourceID;
|
|
CurrentView.InitEventBySelectedTime(AEvent, AllDay, ARecurrence, AInplaceEditing);
|
|
AEvent.State := States[AEvent.AllDayEvent];
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.SetCaptureControl(
|
|
AValue: TcxSchedulerSubControl);
|
|
begin
|
|
if FCaptureControl <> AValue then
|
|
begin
|
|
CaptureController.DoCancelMode;
|
|
FCaptureControl := AValue;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.SetContentPopupMenu(
|
|
AValue: TcxSchedulerContentPopupMenu);
|
|
begin
|
|
FContentPopupMenu.Assign(AValue);
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.SetControlBox(
|
|
AValue: TcxSchedulerControlBox);
|
|
begin
|
|
FControlBox.Assign(AValue);
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.SetDialogsLookAndFeel(
|
|
AValue: TcxLookAndFeel);
|
|
begin
|
|
FDialogsLookAndFeel := AValue;
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.SetEventImages(AValue: TCustomImageList);
|
|
begin
|
|
if AValue <> FEventImages then
|
|
begin
|
|
if FEventImages <> nil then FEventImages.RemoveFreeNotification(Self);
|
|
FEventImages := AValue;
|
|
if FEventImages <> nil then FEventImages.FreeNotification(Self);
|
|
end;
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.SetEventOperations(
|
|
AValue: TcxSchedulerEventOperations);
|
|
begin
|
|
FEventOperations.Assign(AValue);
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.SetEventPopupMenu(
|
|
AValue: TcxSchedulerEventPopupMenu);
|
|
begin
|
|
FEventPopupMenu.Assign(AValue);
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.SetFirstVisibleResourceIndex(AValue: Integer);
|
|
var
|
|
APrevSelResource: TcxSchedulerStorageResourceItem;
|
|
begin
|
|
AValue := Max(0, AValue);
|
|
if AValue <> FFirstVisibleResourceIndex then
|
|
begin
|
|
FFirstVisibleResourceIndex := AValue;
|
|
if CurrentView <> nil then
|
|
begin
|
|
APrevSelResource := SelResource;
|
|
CurrentView.LayoutChanged;
|
|
if APrevSelResource <> SelResource then
|
|
DoSelectionChanged;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.SetOptionsBehavior(AValue: TcxSchedulerOptionsBehavior);
|
|
begin
|
|
if AValue <> FOptionsBehavior then
|
|
FOptionsBehavior.Assign(AValue);
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.SetOptionsCustomize(
|
|
AValue: TcxSchedulerOptionsCustomize);
|
|
begin
|
|
FOptionsCustomize.Assign(AValue);
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.SetOptionsView(
|
|
AValue: TcxSchedulerOptionsView);
|
|
begin
|
|
FOptionsView.Assign(AValue);
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.SetStorage(
|
|
AValue: TcxCustomSchedulerStorage);
|
|
begin
|
|
if FStorage <> AValue then
|
|
begin
|
|
if CurrentView <> nil then
|
|
CurrentView.Controller.CloseInplaceEdit;
|
|
FreeAndNil(FEventList);
|
|
FEventList := CreateEventList;
|
|
if FStorage <> nil then
|
|
FStorage.RemoveListener(Self);
|
|
FStorage := AValue;
|
|
if FStorage <> nil then
|
|
FStorage.AddListener(Self);
|
|
FullRefresh;
|
|
NotififyStorageChanged;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.SetResourceNavigator(
|
|
AValue: TcxSchedulerResourceNavigator);
|
|
begin
|
|
FResourceNavigator.Assign(AValue);
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.SetStyles(
|
|
AValue: TcxSchedulerStyles);
|
|
begin
|
|
FStyles.Assign(AValue);
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.UpdateTimeHandler(Sender: TObject);
|
|
begin
|
|
if CurrentView.Visible then
|
|
CurrentView.TimeChanged;
|
|
if DateNavigator.Visible then
|
|
DateNavigator.CheckCurrentDate;
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.WMCancelMode(var Message: TWMCancelMode);
|
|
begin
|
|
FIsDragCanceled := True;
|
|
try
|
|
inherited;
|
|
finally
|
|
FIsDragCanceled := False;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.WMSetCursor(var Message: TWMSetCursor);
|
|
var
|
|
P: TPoint;
|
|
ACursor: TCursor;
|
|
begin
|
|
ACursor := crDefault;
|
|
P := ScreenToClient(GetMouseCursorPos);
|
|
if IsDesigning and (DragAndDropState = ddsNone) and GetDesignHitTest(P.X, P.Y, [ssLeft]) then
|
|
ACursor := GetControlFromPoint(P).Controller.GetCursor(P.X, P.Y);
|
|
if ACursor <> crDefault then
|
|
SetCursor(Screen.Cursors[ACursor])
|
|
else
|
|
inherited;
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.WMTimeChange(var Message: TWMTimeChange);
|
|
begin
|
|
DoUpdateTime;
|
|
Message.Result := 0;
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.ReadSelectionData(AReader: TReader);
|
|
var
|
|
I: Integer;
|
|
begin
|
|
FSelectedDays.Count := AReader.ReadInteger and $FF;
|
|
for I := 0 to FSelectedDays.Count - 1 do
|
|
FSelectedDays[I] := Date + I;
|
|
end;
|
|
|
|
procedure TcxCustomScheduler.WriteSelectionData(AWriter: TWriter);
|
|
begin
|
|
AWriter.WriteInteger(FSelectedDays.Count);
|
|
end;
|
|
|
|
{ TcxSchedulerPopupMenu }
|
|
|
|
constructor TcxSchedulerPopupMenu.Create(
|
|
AScheduler: TcxCustomScheduler);
|
|
begin
|
|
FScheduler := AScheduler;
|
|
FUseBuiltInPopupMenu := True;
|
|
end;
|
|
|
|
destructor TcxSchedulerPopupMenu.Destroy;
|
|
begin
|
|
PopupMenu := nil;
|
|
FreeAndNil(FInternalMenu);
|
|
inherited Destroy;
|
|
end;
|
|
|
|
procedure TcxSchedulerPopupMenu.Assign(Source: TPersistent);
|
|
begin
|
|
if Source is TcxSchedulerPopupMenu then
|
|
begin
|
|
PopupMenu := TcxSchedulerPopupMenu(Source).PopupMenu;
|
|
UseBuiltInPopupMenu := TcxSchedulerPopupMenu(Source).UseBuiltInPopupMenu;
|
|
end;
|
|
end;
|
|
|
|
function TcxSchedulerPopupMenu.AddValidSeparator(AOwner: TMenuItem): TMenuItem;
|
|
begin
|
|
if AOwner.Count > 0 then
|
|
Result := CreateSeparator(AOwner)
|
|
else
|
|
Result := nil
|
|
end;
|
|
|
|
procedure TcxSchedulerPopupMenu.CreateInternalMenu;
|
|
begin
|
|
FreeAndNil(FInternalMenu);
|
|
FInternalMenu := TPopupMenu.Create(nil);
|
|
FInternalMenu.Images := MenuImages;
|
|
CreateItems;
|
|
end;
|
|
|
|
procedure TcxSchedulerPopupMenu.CreateItems;
|
|
begin
|
|
end;
|
|
|
|
function TcxSchedulerPopupMenu.CreateSeparator(AOwner: TMenuItem): TMenuItem;
|
|
begin
|
|
Result := CreateSubItem(AOwner, '-');
|
|
end;
|
|
|
|
function TcxSchedulerPopupMenu.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;
|
|
|
|
procedure TcxSchedulerPopupMenu.DoExecute(ACommand: Integer);
|
|
begin
|
|
end;
|
|
|
|
function TcxSchedulerPopupMenu.DoOnClick(ACommand: Integer): Boolean;
|
|
begin
|
|
Result := False;
|
|
end;
|
|
|
|
function TcxSchedulerPopupMenu.DoOnPopup: Boolean;
|
|
begin
|
|
Result := False;
|
|
end;
|
|
|
|
procedure TcxSchedulerPopupMenu.ExecuteCommand(ACommand: Integer);
|
|
begin
|
|
if IsValidCommand(ACommand) and not DoOnClick(ACommand) then
|
|
DoExecute(ACommand);
|
|
end;
|
|
|
|
function TcxSchedulerPopupMenu.FindItemByCommand(AOwnerItem: TMenuItem;
|
|
ACommand: Integer): TMenuItem;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
Result := nil;
|
|
if (InternalMenu = nil) or (AOwnerItem = nil) then Exit;
|
|
with AOwnerItem do
|
|
for I := 0 to Count - 1 do
|
|
if (Items[I].Tag = Ord(ACommand)) and (Items[I].Caption <> '-') then
|
|
begin
|
|
Result := Items[I];
|
|
system.Break;
|
|
end;
|
|
end;
|
|
|
|
function TcxSchedulerPopupMenu.IsValidCommand(ACommand: Integer): Boolean;
|
|
begin
|
|
Result := True;
|
|
end;
|
|
|
|
procedure TcxSchedulerPopupMenu.Notification(AComponent: TComponent;
|
|
Operation: TOperation);
|
|
begin
|
|
if (Operation = opRemove) and (AComponent = PopupMenu) then
|
|
PopupMenu := nil;
|
|
end;
|
|
|
|
function TcxSchedulerPopupMenu.Popup(X, Y: Integer): Boolean;
|
|
begin
|
|
with Scheduler.HintController do
|
|
begin
|
|
HideHint;
|
|
FLockHint := True;
|
|
end;
|
|
try
|
|
CreateInternalMenu;
|
|
Result := DoOnPopup;
|
|
if not Result then
|
|
begin
|
|
if UseBuiltInPopupMenu then
|
|
Result := ShowPopupMenu(Scheduler, FInternalMenu, X, Y)
|
|
else
|
|
Result := ShowPopupMenu(Scheduler, FPopupMenu, X, Y);
|
|
end;
|
|
finally
|
|
Scheduler.HintController.FLockHint := False;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerPopupMenu.OnItemClickHandler(Sender: TObject);
|
|
begin
|
|
if Sender is TComponent then
|
|
ExecuteCommand(TComponent(Sender).Tag);
|
|
end;
|
|
|
|
function TcxSchedulerPopupMenu.Storage: TcxCustomSchedulerStorage;
|
|
begin
|
|
Result := Scheduler.Storage;
|
|
end;
|
|
|
|
function TcxSchedulerPopupMenu.GetRoot: TMenuItem;
|
|
begin
|
|
Result := FInternalMenu.Items;
|
|
end;
|
|
|
|
procedure TcxSchedulerPopupMenu.SetPopupMenu(const Value: TComponent);
|
|
begin
|
|
if FPopupMenu <> Value then
|
|
begin
|
|
if (FPopupMenu <> nil) and not (csDestroying in FPopupMenu.ComponentState) then
|
|
FPopupMenu.RemoveFreeNotification(Scheduler);
|
|
FPopupMenu := Value;
|
|
if FPopupMenu <> nil then
|
|
FPopupMenu.FreeNotification(Scheduler);
|
|
end;
|
|
end;
|
|
|
|
{ TcxSchedulerCustomContentPopupMenu }
|
|
|
|
constructor TcxSchedulerCustomContentPopupMenu.Create(
|
|
AScheduler: TcxCustomScheduler);
|
|
begin
|
|
inherited Create(AScheduler);
|
|
FNewID := -1;
|
|
FAllDayID := -1;
|
|
FReccurenceID := -1;
|
|
end;
|
|
|
|
function TcxSchedulerCustomContentPopupMenu.CanCreateEvent: Boolean;
|
|
begin
|
|
Result := Scheduler.CurrentView.Controller.CanCreateEventUsingDialog;
|
|
end;
|
|
|
|
procedure TcxSchedulerCustomContentPopupMenu.CreateNewEventItems(ANew,
|
|
AllDay, AReccurence: Boolean; ANewID, AllDayID, AReccurenceID: Integer);
|
|
var
|
|
AEnabled: Boolean;
|
|
begin
|
|
AEnabled := CanCreateEvent;
|
|
if ANew then
|
|
begin
|
|
CreateSubItem(Root, cxGetResourceString(@scxpmNewEvent),
|
|
ANewID, 2, AEnabled);
|
|
FNewID := ANewID;
|
|
end;
|
|
if AllDay then
|
|
begin
|
|
CreateSubItem(Root, cxGetResourceString(@scxpmNewAllDayEvent),
|
|
AllDayID, -1, AEnabled);
|
|
FAllDayID := AllDayID;
|
|
end;
|
|
if Scheduler.StorageActive and Storage.IsRecurrenceAvailable and
|
|
AReccurence and Scheduler.EventOperations.Recurrence then
|
|
begin
|
|
CreateSubItem(Root, cxGetResourceString(@scxpmNewRecurringEvent),
|
|
AReccurenceID, 3, AEnabled);
|
|
FReccurenceID := AReccurenceID;
|
|
end;
|
|
AddValidSeparator(Root);
|
|
end;
|
|
|
|
procedure TcxSchedulerCustomContentPopupMenu.DoExecute(ACommand: Integer);
|
|
begin
|
|
if ACommand <> -1 then
|
|
begin
|
|
if ACommand = FNewID then
|
|
Scheduler.CreateEventUsingDialog
|
|
else if ACommand = FAllDayID then
|
|
Scheduler.CreateEventUsingDialog(True)
|
|
else if ACommand = FReccurenceID then
|
|
Scheduler.CreateEventUsingDialog(False, True);
|
|
end;
|
|
end;
|
|
|
|
{ TcxSchedulerContentPopupMenu }
|
|
|
|
constructor TcxSchedulerContentPopupMenu.Create(
|
|
AScheduler: TcxCustomScheduler);
|
|
begin
|
|
inherited Create(AScheduler);
|
|
FItems := [cpmiNewEvent, cpmiNewAllDayEvent, cpmiNewReccuringEvent,
|
|
cpmiToday, cpmiGoToDate, cpmiGoToThisDay, cpmiResourcesLayout];
|
|
end;
|
|
|
|
procedure TcxSchedulerContentPopupMenu.Assign(Source: TPersistent);
|
|
begin
|
|
inherited Assign(Source);
|
|
if Source is TcxSchedulerContentPopupMenu then
|
|
begin
|
|
Items := TcxSchedulerContentPopupMenu(Source).Items;
|
|
OnClick := TcxSchedulerContentPopupMenu(Source).OnClick;
|
|
OnPopup := TcxSchedulerContentPopupMenu(Source).OnPopup;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerContentPopupMenu.Execute(
|
|
AItem: TcxSchedulerContentPopupMenuItem);
|
|
begin
|
|
ExecuteCommand(Ord(AItem));
|
|
end;
|
|
|
|
function TcxSchedulerContentPopupMenu.GetMenuItem(
|
|
AItem: TcxSchedulerContentPopupMenuItem): TMenuItem;
|
|
begin
|
|
Result := FindItemByCommand(Root, Ord(AItem));
|
|
end;
|
|
|
|
procedure TcxSchedulerContentPopupMenu.CreateItems;
|
|
begin
|
|
FActualItems := FItems;
|
|
if Scheduler.CurrentView <> nil then
|
|
Scheduler.CurrentView.ValidateContentPopupMenuItems(FActualItems);
|
|
CreateNewEventItems(cpmiNewEvent in ActualItems, cpmiNewAllDayEvent in ActualItems,
|
|
cpmiNewReccuringEvent in ActualItems, Ord(cpmiNewEvent), Ord(cpmiNewAllDayEvent),
|
|
Ord(cpmiNewReccuringEvent));
|
|
CreateGoToThisDayItem;
|
|
if cpmiToday in ActualItems then
|
|
CreateSubItem(Root, cxGetResourceString(@scxpmToday), Ord(cpmiToday));
|
|
if cpmiGoToDate in ActualItems then
|
|
CreateSubItem(Root, cxGetResourceString(@scxpmGoToDate), Ord(cpmiGoToDate));
|
|
if (cpmiResourcesLayout in ActualItems) and Scheduler.CurrentView.IsShowResources then
|
|
begin
|
|
AddValidSeparator(Root);
|
|
CreateSubItem(Root, cxGetResourceString(@scxpmResourcesLayout), Ord(cpmiResourcesLayout));
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerContentPopupMenu.DoExecute(ACommand: Integer);
|
|
var
|
|
ADate: TDateTime;
|
|
AViewMode: TcxSchedulerViewMode;
|
|
begin
|
|
case ACommand of
|
|
Ord(cpmiNewEvent), Ord(cpmiNewAllDayEvent), Ord(cpmiNewReccuringEvent):
|
|
inherited DoExecute(ACommand);
|
|
Ord(cpmiResourcesLayout):
|
|
cxShowResourcesLayoutEditor(Scheduler.Storage, Scheduler.DialogsLookAndFeel);
|
|
Ord(cpmiGoToThisDay):
|
|
Scheduler.GoToDate(FSavedDate, vmDay);
|
|
Ord(cpmiToday):
|
|
Scheduler.GoToDate(Date);
|
|
Ord(cpmiGoToDate):
|
|
begin
|
|
ADate := DateOf(Scheduler.SelStart);
|
|
if cxShowGoToDateDialog(Scheduler, Scheduler.DialogsLookAndFeel, ADate, AViewMode) then
|
|
Scheduler.GoToDate(ADate, AViewMode);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TcxSchedulerContentPopupMenu.DoOnClick(ACommand: Integer): Boolean;
|
|
begin
|
|
Result := False;
|
|
if Assigned(FOnClick) then
|
|
FOnClick(Self, TcxSchedulerContentPopupMenuItem(ACommand), Result);
|
|
end;
|
|
|
|
function TcxSchedulerContentPopupMenu.DoOnPopup: Boolean;
|
|
begin
|
|
Result := False;
|
|
if Assigned(FOnPopup) then
|
|
FOnPopup(Self, InternalMenu, Result);
|
|
end;
|
|
|
|
function TcxSchedulerContentPopupMenu.IsValidCommand(
|
|
ACommand: Integer): Boolean;
|
|
begin
|
|
Result := (ACommand >= Ord(cpmiNewEvent)) and (ACommand <= Ord(cpmiResourcesLayout));
|
|
end;
|
|
|
|
procedure TcxSchedulerContentPopupMenu.CreateGoToThisDayItem;
|
|
var
|
|
AItem: TMenuItem;
|
|
begin
|
|
if (cpmiGoToThisDay in ActualItems) and not Scheduler.CurrentView.IsDayView then
|
|
begin
|
|
AItem := CreateSubItem(Root, cxGetResourceString(@scxpmGotoThisDay), Ord(cpmiGoToThisDay));
|
|
AItem.Enabled := Scheduler.ActiveHitTest.HitAtTime;
|
|
if AItem.Enabled then
|
|
FSavedDate := Scheduler.ActiveHitTest.Time;
|
|
end;
|
|
end;
|
|
|
|
{ TcxSchedulerEventPopupMenu }
|
|
|
|
constructor TcxSchedulerEventPopupMenu.Create(
|
|
AScheduler: TcxCustomScheduler);
|
|
begin
|
|
inherited Create(AScheduler);
|
|
FItems := [epmiOpen, epmiEditSeries, epmiShowTimeAs, epmiLabel, epmiDelete];
|
|
end;
|
|
|
|
procedure TcxSchedulerEventPopupMenu.Assign(Source: TPersistent);
|
|
begin
|
|
inherited Assign(Source);
|
|
if Source is TcxSchedulerEventPopupMenu then
|
|
begin
|
|
Items := TcxSchedulerEventPopupMenu(Source).Items;
|
|
OnClick := TcxSchedulerEventPopupMenu(Source).OnClick;
|
|
OnPopup := TcxSchedulerEventPopupMenu(Source).OnPopup;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerEventPopupMenu.CreateItems;
|
|
|
|
function GetEditEnabled: Boolean;
|
|
begin
|
|
Result := (Event <> nil) and Scheduler.CanShowEventDialog;
|
|
end;
|
|
|
|
begin
|
|
FEvent := GetEvent;
|
|
if epmiOpen in Items then
|
|
CreateSubItem(Root, cxGetResourceString(@scxpmOpen), Ord(epmiOpen)).Enabled :=
|
|
GetEditEnabled;
|
|
if (epmiEditSeries in Items) and (Event <> nil) and (Event.EventType <> etNone) then
|
|
CreateSubItem(Root, cxGetResourceString(@scxpmEditSeries), Ord(epmiEditSeries), 8).Enabled :=
|
|
GetEditEnabled;
|
|
if Items * [epmiLabel, epmiShowTimeAs] <> [] then
|
|
AddValidSeparator(Root);
|
|
CreateTimeItems;
|
|
CreateLabelItems;
|
|
CreateDeleteItem;
|
|
end;
|
|
|
|
procedure TcxSchedulerEventPopupMenu.DoExecute(ACommand: Integer);
|
|
begin
|
|
case ACommand of
|
|
Ord(epmiOpen):
|
|
Scheduler.EditEventUsingDialog(Event);
|
|
Ord(epmiEditSeries):
|
|
Scheduler.EditEventUsingDialog(Event, True, True);
|
|
Ord(epmiDelete):
|
|
Scheduler.InternalDeleteSelectedEvents(False, True);
|
|
10..13:
|
|
SetEventState(ACommand - 10);
|
|
else
|
|
if (ACommand >= 20) and (ACommand < 20 + EventLabels.Count) then
|
|
SetEventLabelColor(EventLabels[ACommand - 20].Color);
|
|
end;
|
|
end;
|
|
|
|
function TcxSchedulerEventPopupMenu.DoOnClick(ACommand: Integer): Boolean;
|
|
var
|
|
AItem: TcxSchedulerEventPopupMenuItem;
|
|
ASubItemIndex: Integer;
|
|
begin
|
|
Result := False;
|
|
UnpackCommand(ACommand, AItem, ASubItemIndex);
|
|
if Assigned(FOnClick) then
|
|
FOnClick(Self, AItem, ASubItemIndex, Result);
|
|
end;
|
|
|
|
function TcxSchedulerEventPopupMenu.DoOnPopup: Boolean;
|
|
begin
|
|
Result := False;
|
|
if Assigned(FOnPopup) then
|
|
FOnPopup(Self, InternalMenu, Result);
|
|
end;
|
|
|
|
function TcxSchedulerEventPopupMenu.GetMenuItem(
|
|
AItem: TcxSchedulerEventPopupMenuItem; ASubItemIndex: Integer = -1): TMenuItem;
|
|
begin
|
|
Result := FindItemByCommand(Root, Ord(AItem));
|
|
if Result <> nil then
|
|
begin
|
|
if (AItem = epmiLabel) and (ASubItemIndex in [0..10]) then
|
|
Result := FindItemByCommand(Result, ASubItemIndex + 20)
|
|
else
|
|
if (AItem = epmiShowTimeAs) and (ASubItemIndex in [0..3]) then
|
|
Result := FindItemByCommand(Result, ASubItemIndex + 10)
|
|
end;
|
|
end;
|
|
|
|
function TcxSchedulerEventPopupMenu.IsValidCommand(
|
|
ACommand: Integer): Boolean;
|
|
begin
|
|
Result := (ACommand >= Ord(epmiOpen)) and (ACommand <= Ord(epmiDelete)) or
|
|
(ACommand in [20..20 + EventLabels.Count - 1]) or //Label
|
|
(ACommand in [10..13]); //TimeLine
|
|
end;
|
|
|
|
procedure TcxSchedulerEventPopupMenu.SetEventLabelColor(AColor: Integer);
|
|
begin
|
|
if Event = nil then Exit;
|
|
if Event.EventType = etOccurrence then
|
|
Event.Pattern.LabelColor := AColor
|
|
else
|
|
Event.Source.LabelColor := AColor;
|
|
end;
|
|
|
|
procedure TcxSchedulerEventPopupMenu.SetEventState(AState: Integer);
|
|
begin
|
|
if Event = nil then Exit;
|
|
Event.State := AState;
|
|
Scheduler.EventList.PostEvent(Event);
|
|
end;
|
|
|
|
procedure TcxSchedulerEventPopupMenu.CreateDeleteItem;
|
|
|
|
function CanDelete: Boolean;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
with Scheduler do
|
|
begin
|
|
Result := EventOperations.Deleting;
|
|
if Result then
|
|
begin
|
|
for I := 0 to SelectedEventCount - 1 do
|
|
if not SelectedEvents[I].ReadOnly then
|
|
Exit;
|
|
Result := False;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
begin
|
|
if epmiDelete in Items then
|
|
begin
|
|
AddValidSeparator(Root);
|
|
CreateSubItem(Root, cxGetResourceString(@scxpmDelete), Ord(epmiDelete), 10).Enabled := CanDelete;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerEventPopupMenu.CreateLabelItems;
|
|
var
|
|
AOwner: TMenuItem;
|
|
I: Integer;
|
|
|
|
function GetColorChecked(AColor: TColor): Boolean;
|
|
begin
|
|
if Event = nil then
|
|
Result := False
|
|
else
|
|
Result := ColorToRgb(Event.LabelColor) = ColorToRgb(AColor);
|
|
end;
|
|
|
|
procedure CreateEventColorItem(ALabel: TcxSchedulerEventLabel);
|
|
var
|
|
AChecked: Boolean;
|
|
AItem: TMenuItem;
|
|
begin
|
|
AChecked := GetColorChecked(ALabel.Color);
|
|
AItem := CreateSubItem(AOwner, ALabel.Caption,
|
|
GetCommand(epmiLabel, ALabel.Index), -1, CanEdit, AChecked);
|
|
AItem.Default := AChecked;
|
|
EventLabels.Images.GetBitmap(ALabel.Index, AItem.Bitmap);
|
|
end;
|
|
|
|
begin
|
|
if not (epmiLabel in Items) or not Scheduler.StorageActive or
|
|
not Storage.IsLabelColorAvailable or (EventLabels.Count = 0) then Exit;
|
|
AOwner := CreateSubItem(Root, cxGetResourceString(@scxpmLabel), Ord(epmiLabel));
|
|
//label colors
|
|
CreateEventColorItem(EventLabels[0]);
|
|
if EventLabels.Count > 1 then
|
|
begin
|
|
CreateSeparator(AOwner);
|
|
for I := 1 to EventLabels.Count - 1 do
|
|
CreateEventColorItem(EventLabels[I]);
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerEventPopupMenu.CreateTimeItems;
|
|
var
|
|
AOwner: TMenuItem;
|
|
ACanSetNonFree: Boolean;
|
|
|
|
function GetTimeLineChecked(AIndex: Integer): Boolean;
|
|
begin
|
|
if Event = nil then
|
|
Result := False
|
|
else
|
|
Result := Integer(Event.State) = AIndex;
|
|
end;
|
|
|
|
function CanSetNonFree: Boolean;
|
|
var
|
|
APrevState: Integer;
|
|
begin
|
|
if Event = nil then
|
|
begin
|
|
Result := False;
|
|
Exit;
|
|
end;
|
|
APrevState := Event.State;
|
|
Event.State := tlsBusy;
|
|
try
|
|
Result := Scheduler.CanIntersect(Event);
|
|
finally
|
|
Event.State := APrevState;
|
|
end;
|
|
end;
|
|
|
|
procedure CreateTimeLineItem(const ACaption: string; AIndex: Integer);
|
|
var
|
|
AChecked: Boolean;
|
|
begin
|
|
AChecked := GetTimeLineChecked(AIndex);
|
|
CreateSubItem(AOwner, ACaption, GetCommand(epmiShowTimeAs, AIndex), AIndex,
|
|
CanEdit and ((AIndex = 0) or (ACanSetNonFree)), AChecked).Default := AChecked;
|
|
end;
|
|
|
|
begin
|
|
if not (epmiShowTimeAs in Items) or not Scheduler.StorageActive or
|
|
not Storage.IsStateAvailable then Exit;
|
|
AOwner := CreateSubItem(Root, cxGetResourceString(@scxpmShowTimeAs), Ord(epmiShowTimeAs));
|
|
AOwner.SubMenuImages := TimeLinePatterns;
|
|
// TimeLine styles
|
|
ACanSetNonFree := CanSetNonFree;
|
|
CreateTimeLineItem(cxGetResourceString(@scxpmFree), 0);
|
|
CreateTimeLineItem(cxGetResourceString(@scxpmTentative), 1);
|
|
CreateTimeLineItem(cxGetResourceString(@scxpmBusy), 2);
|
|
CreateTimeLineItem(cxGetResourceString(@scxpmOutOfOffice), 3);
|
|
end;
|
|
|
|
function TcxSchedulerEventPopupMenu.GetCommand(
|
|
AItem: TcxSchedulerEventPopupMenuItem; ASubItemIndex: Integer): Integer;
|
|
begin
|
|
Result := Ord(AItem);
|
|
case AItem of
|
|
epmiShowTimeAs:
|
|
if (ASubItemIndex >= 0) and (ASubItemIndex <= 3) then
|
|
Result := 10 + ASubItemIndex;
|
|
epmiLabel:
|
|
if (ASubItemIndex >= 0) and (ASubItemIndex < EventLabels.Count) then
|
|
Result := 20 + ASubItemIndex;
|
|
end;
|
|
end;
|
|
|
|
function TcxSchedulerEventPopupMenu.CanEdit: Boolean;
|
|
begin
|
|
Result := (Event <> nil) and not Event.ReadOnly and
|
|
not Scheduler.EventOperations.ReadOnly;
|
|
end;
|
|
|
|
function TcxSchedulerEventPopupMenu.GetEvent: TcxSchedulerControlEvent;
|
|
begin
|
|
with Scheduler.EventList.Selection do
|
|
begin
|
|
if Count = 1 then
|
|
Result := Items[0]
|
|
else
|
|
Result := nil;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerEventPopupMenu.UnpackCommand(ACommand: Integer;
|
|
out AItem: TcxSchedulerEventPopupMenuItem; out ASubItemIndex: Integer);
|
|
begin
|
|
AItem := epmiOpen;
|
|
ASubItemIndex := -1;
|
|
if not IsValidCommand(ACommand) then Exit;
|
|
if ACommand in [20..20 + EventLabels.Count - 1] then
|
|
begin
|
|
AItem := epmiLabel;
|
|
ASubItemIndex := ACommand - 20;
|
|
end
|
|
else
|
|
if ACommand in [10..13] then
|
|
begin
|
|
AItem := epmiShowTimeAs;
|
|
ASubItemIndex := ACommand - 10;
|
|
end
|
|
else
|
|
AItem := TcxSchedulerEventPopupMenuItem(ACommand);
|
|
end;
|
|
|
|
end.
|
|
|