1884 lines
63 KiB
ObjectPascal
1884 lines
63 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 cxSchedulerYearView;
|
|
|
|
{$I cxVer.inc}
|
|
|
|
interface
|
|
|
|
uses
|
|
{$IFDEF DELPHI6}
|
|
Types, DateUtils,
|
|
{$ENDIF}
|
|
Windows, Forms, Classes, SysUtils, Math, StdCtrls, Graphics,
|
|
Controls, Menus, cxClasses, cxControls, cxGraphics, cxStyles, cxGeometry,
|
|
cxLookAndFeelPainters, cxSchedulerCustomControls, cxSchedulerCustomResourceView,
|
|
cxSchedulerUtils, cxSchedulerStorage, cxSchedulerStrs, cxDateUtils;
|
|
|
|
const
|
|
cxMaxSelectedDaysCount = 20;
|
|
MaxYearViewWeekDays = 37;
|
|
cxYearViewScrollCurrentYearPos = 10;
|
|
cxYearViewScrollMaxPos = 21;
|
|
cxYearViewScrollMinPos = 0;
|
|
|
|
cxcsMonthHeader = 0;
|
|
cxcsUnusedContent = 1;
|
|
cxcsMaxYearViewStyle = cxcsUnusedContent;
|
|
|
|
// hittests
|
|
htcYear = $11;
|
|
htcMonth = $12;
|
|
|
|
type
|
|
TcxSchedulerMonthHeaderCellViewInfo = class;
|
|
TcxSchedulerMonthHeaderPopupMenu = class;
|
|
TcxSchedulerYearView = class;
|
|
TcxSchedulerYearViewViewInfo = class;
|
|
TcxSchedulerYearViewNavigation = class;
|
|
TcxSchedulerYearViewStyles = class;
|
|
TcxSchedulerYearViewContentCellViewInfo = class;
|
|
|
|
{ TcxSchedulerYearViewController }
|
|
|
|
TcxSchedulerYearViewController = class(TcxSchedulerCustomResourceViewController)
|
|
protected
|
|
function CreateDragEventHelper: TcxDragEventHelper; override;
|
|
function CreateNavigation: TcxSchedulerViewNavigation; override;
|
|
function CreateResizeEventHelper: TcxEventSizingHelper; override;
|
|
procedure KeyDown(var Key: Word; Shift: TShiftState); override;
|
|
end;
|
|
|
|
{ TcxSchedulerYearViewHitTest }
|
|
|
|
TcxSchedulerYearViewHitTest = class(TcxSchedulerCustomResourceViewHitTest)
|
|
public
|
|
property HitAtYear: Boolean index htcYear read GetBitState;
|
|
property HitAtMonth: Boolean index htcMonth read GetBitState;
|
|
end;
|
|
|
|
{ IcxSchedulerYearViewAdapter }
|
|
|
|
IcxSchedulerYearViewAdapter = interface
|
|
['{7B39CB3C-256E-4269-9B24-5A59BC3D868D}']
|
|
function GetMonthCount: Integer;
|
|
function GetFirstMonth: Integer;
|
|
function GetShowMonthHeaders: Boolean;
|
|
function GetShowWeekDayHeaders: Boolean;
|
|
function GetStartDayIndex: Integer;
|
|
function GetDayCountPerPage: Integer;
|
|
end;
|
|
|
|
{ TcxSchedulerYearViewPainter }
|
|
|
|
TcxSchedulerYearViewPainter = class(TcxSchedulerCustomViewPainter)
|
|
private
|
|
function GetViewInfo: TcxSchedulerYearViewViewInfo;
|
|
public
|
|
procedure Paint; override;
|
|
property ViewInfo: TcxSchedulerYearViewViewInfo read GetViewInfo;
|
|
end;
|
|
|
|
{ TcxSchedulerYearViewEventCellViewInfo }
|
|
|
|
TcxSchedulerYearViewEventCellViewInfo = class(TcxSchedulerEventCellViewInfo)
|
|
protected
|
|
procedure CalculateBorders; override;
|
|
procedure CalculateCaptions; override;
|
|
procedure CalculateEventTimeVisibility; override;
|
|
function CanAutoHideStandardImages: Boolean; override;
|
|
function GetForceShowClockInHeaderEvent: Boolean; override;
|
|
procedure InitHitTest(AHitTest: TcxSchedulerCustomResourceViewHitTest); override;
|
|
end;
|
|
|
|
{ TcxSchedulerYearViewViewInfo }
|
|
|
|
TcxSchedulerYearViewViewInfo = class(TcxSchedulerCustomResourceViewViewInfo)
|
|
private
|
|
FAdapterFirstMonth: Integer;
|
|
FAdapterMonthCount: Integer;
|
|
function GetAdapterFirstMonth: Integer;
|
|
function GetAdapterMonthCount: Integer;
|
|
function GetDaysCell(AIndex: Integer): TcxSchedulerYearViewContentCellViewInfo;
|
|
function GetDaysCellCount: Integer;
|
|
function GetMonthBounds(AIndex: Integer): TRect;
|
|
function GetYearView: TcxSchedulerYearView;
|
|
protected
|
|
FContentFont: TFont;
|
|
FContentSmallFont: TFont;
|
|
FDayCells: TList;
|
|
FDayTextHeight: Integer;
|
|
FMonthHeaderCells: TcxSchedulerViewInfoCellList;
|
|
FMonthHeaderWidth: Integer;
|
|
FShowMonthHeaders: Boolean;
|
|
FStartDayIndex: Integer;
|
|
FMaxYearViewWeekDays: Integer;
|
|
FMaxEventsCount: Integer;
|
|
FYear: Word;
|
|
FYearViewExtraAdapter: IcxSchedulerYearViewAdapter;
|
|
FRangeStart: Integer;
|
|
FRangeFinish: Integer;
|
|
procedure AddEventButtons(APlace: TcxSchedulerEventPlace);
|
|
procedure AddEventForCalculation(ABuilder: TcxSchedulerEventLayoutBuilder;
|
|
AEvent: TcxSchedulerControlEvent);
|
|
procedure AddEventToYearView(APlace: TcxSchedulerEventPlace);
|
|
function AddMonthHeader(AYear, AMonth: Integer; const ARect: TRect;
|
|
AFirstMonth: Integer = 0;
|
|
AMonthCount: Integer = 12): TcxSchedulerMonthHeaderCellViewInfo;
|
|
function AddWeekDayHeader(AWeekDay: Integer;
|
|
ARect: TRect): TcxSchedulerWeekDayHeaderCellViewInfo;
|
|
function AddYearViewContentCell(ARect: TRect; ADate: TDate; ASelected: Boolean;
|
|
AParams: TcxViewParams; AColIndex: Integer): TcxSchedulerYearViewContentCellViewInfo;
|
|
procedure CalculateContentCellMonthParams(AMonth: Integer;
|
|
out AMonthBounds: TRect; out AStartOfMonth: TDate;
|
|
out AStartMonthColumn, ADaysPerMonth: Integer);
|
|
procedure CalculateContentCells; virtual;
|
|
procedure CalculateContentNavigationButtons; override;
|
|
procedure CalculateDaysHeader; virtual;
|
|
procedure CalculateEventsViewInfo; virtual;
|
|
procedure CalculateMetrics; override;
|
|
procedure CalculateMonthHeaderWidth;
|
|
procedure CalculateMonthsHeader; virtual;
|
|
procedure CheckLayout(ADate: TDateTime);
|
|
procedure Clear; override;
|
|
function ContentCellClass: TcxSchedulerContentCellViewInfoClass; override;
|
|
function CreateEventCellViewInfo(AViewData: TcxSchedulerEventViewData): TcxSchedulerEventCellViewInfo; override;
|
|
function GetPartOfTheYear(ADate: TDateTime): Word;
|
|
procedure DoCalculate; override;
|
|
procedure DoContentNavigationButtonClick(Sender: TcxSchedulerContentNavigationButtonViewInfo); override;
|
|
function GetMonthColumnDate(AStartOfMonth: TDateTime;
|
|
ADaysPerMonth, AStartMonthColumn, AColumn: Integer): TDateTime;
|
|
function GetSmallFont(const AParams: TcxViewParams): TFont;
|
|
function IsEventVisible(AEvent: TcxSchedulerControlEvent): Boolean;
|
|
procedure PrepareSmallContentFont;
|
|
|
|
// page splitting
|
|
function GetFirstMonth: Integer; virtual;
|
|
function GetMonthCountPerPage: Integer; virtual;
|
|
|
|
property AdapterFirstMonth: Integer read GetAdapterFirstMonth write FAdapterFirstMonth;
|
|
property AdapterMonthCount: Integer read GetAdapterMonthCount write FAdapterMonthCount;
|
|
property FirstMonth: Integer read GetFirstMonth;
|
|
property MonthCountPerPage: Integer read GetMonthCountPerPage;
|
|
public
|
|
constructor Create(AOwner: TcxSchedulerSubControl); override;
|
|
destructor Destroy; override;
|
|
procedure CalculateHitTest(AHitTest: TcxSchedulerCustomResourceViewHitTest); override;
|
|
procedure UpdateSelection;
|
|
|
|
property DaysCellCount: Integer read GetDaysCellCount;
|
|
property DaysCells[AIndex: Integer]: TcxSchedulerYearViewContentCellViewInfo read GetDaysCell;
|
|
property MonthBounds[AIndex: Integer]: TRect read GetMonthBounds;
|
|
property MonthHeaderCells: TcxSchedulerViewInfoCellList read FMonthHeaderCells;
|
|
property View: TcxSchedulerYearView read GetYearView;
|
|
property Year: Word read FYear;
|
|
end;
|
|
|
|
{ TcxSchedulerYearViewNavigation }
|
|
|
|
TcxSchedulerYearViewNavigation = class(TcxSchedulerCustomResourceViewNavigation)
|
|
private
|
|
FCanChangeSelection: Boolean;
|
|
FSaveSelFinish: TDateTime;
|
|
FSaveSelStart: TDateTime;
|
|
function GetYearView: TcxSchedulerYearView;
|
|
function GetYearViewInfo: TcxSchedulerYearViewViewInfo;
|
|
protected
|
|
function ContentCell(AIndex: Integer): TcxSchedulerYearViewContentCellViewInfo;
|
|
procedure CorrectCurrentAnchor;
|
|
procedure DoKeyDown(var AKey: Word; AShift: TShiftState); override;
|
|
procedure GotoCornerCell(AGotoEnd: Boolean); virtual;
|
|
procedure GotoNextCellHorz(AGotoNext: Boolean); virtual;
|
|
procedure GotoNextCellVert(AGoForward: Boolean); virtual;
|
|
procedure GotoNextPage(AGotoForward: Boolean); virtual;
|
|
public
|
|
procedure KeyDown(var AKey: Word; AShift: TShiftState); override;
|
|
procedure ValidateSelection(var ASelStart, ASelFinish: TDateTime;
|
|
var AResource: TcxSchedulerStorageResourceItem); override;
|
|
|
|
property View: TcxSchedulerYearView read GetYearView;
|
|
property ViewInfo: TcxSchedulerYearViewViewInfo read GetYearViewInfo;
|
|
end;
|
|
|
|
{ TcxSchedulerMonthHeaderCellViewInfo }
|
|
|
|
TcxSchedulerMonthHeaderCellViewInfo = class(TcxSchedulerDayHeaderCellViewInfo)
|
|
private
|
|
FFirstMonth: Integer;
|
|
FMonth: Integer;
|
|
FMonthCount: Integer;
|
|
FYear: Integer;
|
|
procedure SetFirstMonth(AValue: Integer);
|
|
procedure SetMonth(AValue: Integer);
|
|
procedure SetMonthCount(AValue: Integer);
|
|
procedure SetYear(AValue: Integer);
|
|
protected
|
|
FColStart: Integer;
|
|
procedure CalculateDisplayText; virtual;
|
|
procedure InitHitTest(AHitTest: TcxSchedulerCustomResourceViewHitTest); override;
|
|
public
|
|
property FirstMonth: Integer read FFirstMonth write SetFirstMonth;
|
|
property Month: Integer read FMonth write SetMonth;
|
|
property MonthCount: Integer read FMonthCount write SetMonthCount;
|
|
property Year: Integer read FYear write SetYear;
|
|
end;
|
|
|
|
{ TcxSchedulerYearViewContentCellViewInfo }
|
|
|
|
TcxSchedulerYearViewContentCellViewInfo = class(TcxSchedulerMonthDayContentCellViewInfo)
|
|
protected
|
|
FColIndex: Integer;
|
|
procedure InitHitTest(AHitTest: TcxSchedulerCustomResourceViewHitTest); override;
|
|
end;
|
|
|
|
{ TcxYearViewDragEventHelper }
|
|
|
|
TcxYearViewDragEventHelper = class(TcxDragEventHelper)
|
|
protected
|
|
procedure UpdateViewClonesTime; override;
|
|
end;
|
|
|
|
{ TcxYearViewEventSizing }
|
|
|
|
TcxYearViewEventSizing = class(TcxEventSizingHelper)
|
|
protected
|
|
procedure UpdateEventBounds; override;
|
|
end;
|
|
|
|
{ TcxSchedulerYearViewStyles }
|
|
|
|
TcxSchedulerYearViewGetUnusedContentStyleEvent = procedure(Sender: TcxSchedulerYearView;
|
|
AYear, AMonth, ADayOfWeek: Integer; var AStyle: TcxStyle) of object;
|
|
TcxSchedulerYearViewGetMonthHeaderStyleEvent = procedure(Sender: TcxSchedulerYearView;
|
|
AYear, AMonth: Integer; var AStyle: TcxStyle) of object;
|
|
|
|
TcxSchedulerYearViewStyles = class(TcxStyles)
|
|
private
|
|
FScheduler: TcxCustomScheduler;
|
|
FYearView: TcxSchedulerYearView;
|
|
FOnGetMonthHeaderStyle: TcxSchedulerYearViewGetMonthHeaderStyleEvent;
|
|
FOnGetUnusedContentStyle: TcxSchedulerYearViewGetUnusedContentStyleEvent;
|
|
function GetPainter: TcxCustomLookAndFeelPainterClass;
|
|
protected
|
|
procedure Changed(AIndex: Integer); override;
|
|
procedure GetDefaultViewParams(Index: Integer; AData: TObject;
|
|
out AParams: TcxViewParams); override;
|
|
property Painter: TcxCustomLookAndFeelPainterClass read GetPainter;
|
|
public
|
|
constructor Create(AOwner: TPersistent); override;
|
|
procedure Assign(Source: TPersistent); override;
|
|
function GetMonthHeaderParams(AYear, AMonth: Integer): TcxViewParams;
|
|
function GetUnusedContentParams(
|
|
AYear, AMonth, ADayOfWeek: Integer): TcxViewParams;
|
|
|
|
property Scheduler: TcxCustomScheduler read FScheduler;
|
|
property YearView: TcxSchedulerYearView read FYearView;
|
|
published
|
|
property MonthHeader: TcxStyle index cxcsMonthHeader read GetValue write SetValue;
|
|
property UnusedContent: TcxStyle index cxcsUnusedContent read GetValue write SetValue;
|
|
property OnGetMonthHeaderStyle: TcxSchedulerYearViewGetMonthHeaderStyleEvent read FOnGetMonthHeaderStyle write FOnGetMonthHeaderStyle;
|
|
property OnGetUnusedContentStyle: TcxSchedulerYearViewGetUnusedContentStyleEvent read FOnGetUnusedContentStyle write FOnGetUnusedContentStyle;
|
|
end;
|
|
|
|
{ TcxSchedulerYearView }
|
|
|
|
TcxSchedulerYearView = class(TcxSchedulerCustomResourceView)
|
|
private
|
|
FAllDayEventsOnly: Boolean;
|
|
FMaxSelectedDaysCount: Integer;
|
|
FMonthHeaderPopupMenu: TcxSchedulerMonthHeaderPopupMenu;
|
|
FStyles: TcxSchedulerYearViewStyles;
|
|
FScale: Integer;
|
|
function GetHitTest: TcxSchedulerYearViewHitTest;
|
|
function GetNavigation: TcxSchedulerYearViewNavigation;
|
|
function GetViewInfo: TcxSchedulerYearViewViewInfo;
|
|
function GetYear: Word;
|
|
procedure SetAllDayEventsOnly(AValue: Boolean);
|
|
procedure SetMaxSelectedDaysCount(AValue: Integer);
|
|
procedure SetMonthHeaderPopupMenu(AValue: TcxSchedulerMonthHeaderPopupMenu);
|
|
procedure SetScale(AValue: Integer);
|
|
procedure SetStyles(AValue: TcxSchedulerYearViewStyles);
|
|
protected
|
|
procedure CreateSubClasses; override;
|
|
function CreateViewAdapter: TcxCustomResourceViewAdapter; override;
|
|
procedure DestroySubClasses; override;
|
|
function CanDeactivateOnDateNavigatorSelectionChange: Boolean; override;
|
|
function CanSelectPeriod: Boolean; override;
|
|
procedure ChangeLayout(ACurrentAnchor: TDateTime);
|
|
function CreateController: TcxSchedulerSubControlController; override;
|
|
function CreateHitTest: TcxSchedulerSubControlHitTest; override;
|
|
function CreateMonthHeaderPopupMenu: TcxSchedulerMonthHeaderPopupMenu; virtual;
|
|
function CreatePainter: TcxSchedulerSubControlPainter; override;
|
|
function CreateStyles: TcxSchedulerYearViewStyles; virtual;
|
|
function CreateViewInfo: TcxSchedulerSubControlViewInfo; override;
|
|
function DoShowPopupMenu(X, Y: Integer): Boolean; override;
|
|
function GetCompressWeekEnd: Boolean; override;
|
|
function GetGroupingKind: TcxSchedulerGroupingKind; override;
|
|
function GetFirstVisibleDate: TDateTime; override;
|
|
function GetLastVisibleDate: TDateTime; override;
|
|
function GetScrollPos: Integer; virtual;
|
|
function GetVisibleDaysRange: Integer; override;
|
|
procedure InitScrollBarsParameters; override;
|
|
procedure MakeEventVisible(AEvent: TcxSchedulerControlEvent;
|
|
const ADate: TDateTime; AResource: TcxSchedulerStorageResourceItem); override;
|
|
procedure Notification(AComponent: TComponent; Operation: TOperation); override;
|
|
procedure Scroll(AScrollBarKind: TScrollBarKind;
|
|
AScrollCode: TScrollCode; var AScrollPos: Integer); override;
|
|
procedure SelectedDaysChanged; override;
|
|
procedure SetGroupingKind(AValue: TcxSchedulerGroupingKind); override;
|
|
|
|
property Navigation: TcxSchedulerYearViewNavigation read GetNavigation;
|
|
property ViewInfo: TcxSchedulerYearViewViewInfo read GetViewInfo;
|
|
public
|
|
constructor Create(AOwner: TcxCustomScheduler); override;
|
|
procedure Assign(Source: TPersistent); override;
|
|
|
|
property HitTest: TcxSchedulerYearViewHitTest read GetHitTest;
|
|
property Year: Word read GetYear;
|
|
published
|
|
property Active;
|
|
property AllDayEventsOnly: Boolean read FAllDayEventsOnly write SetAllDayEventsOnly default False;
|
|
property MaxSelectedDaysCount: Integer read FMaxSelectedDaysCount write SetMaxSelectedDaysCount default 0;
|
|
property MonthHeaderPopupMenu: TcxSchedulerMonthHeaderPopupMenu read FMonthHeaderPopupMenu write SetMonthHeaderPopupMenu;
|
|
property Scale: Integer read FScale write SetScale default 12;
|
|
property Styles: TcxSchedulerYearViewStyles read FStyles write SetStyles;
|
|
end;
|
|
|
|
{ TcxSchedulerYearViewAdapter }
|
|
|
|
TcxSchedulerYearViewAdapter = class(TcxCustomResourceViewAdapter, IcxSchedulerYearViewAdapter)
|
|
private
|
|
FPredefinedCurrentAnchor: TDateTime;
|
|
protected
|
|
{ IUnknown }
|
|
function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall;
|
|
function _AddRef: Integer; stdcall;
|
|
function _Release: Integer; stdcall;
|
|
{ IcxSchedulerYearViewAdapter }
|
|
function GetDayCountPerPage: Integer; virtual;
|
|
function GetFirstMonth: Integer; virtual;
|
|
function GetMonthCount: Integer; virtual;
|
|
function GetShowMonthHeaders: Boolean; virtual;
|
|
function GetShowWeekDayHeaders: Boolean; virtual;
|
|
function GetStartDayIndex: Integer; virtual;
|
|
|
|
property PredefinedCurrentAnchor: TDateTime read FPredefinedCurrentAnchor write FPredefinedCurrentAnchor;
|
|
end;
|
|
|
|
{ TcxSchedulerMonthHeaderPopupMenu }
|
|
|
|
TcxSchedulerMonthHeaderPopupMenuItem = (mhpmiNewEvent, mhpmiNewAllDayEvent,
|
|
mhpmiNewReccuringEvent, mhpmiFullYear, mhpmiHalfYear, mhpmiQuarter);
|
|
TcxSchedulerMonthHeaderPopupMenuItems = set of TcxSchedulerMonthHeaderPopupMenuItem;
|
|
|
|
TcxSchedulerMonthHeaderPopupMenuPopupEvent = procedure (
|
|
Sender: TcxSchedulerMonthHeaderPopupMenu; ABuiltInMenu: TPopupMenu;
|
|
var AHandled: Boolean) of object;
|
|
TcxSchedulerMonthHeaderPopupMenuClickEvent = procedure (
|
|
Sender: TcxSchedulerMonthHeaderPopupMenu;
|
|
AItem: TcxSchedulerMonthHeaderPopupMenuItem; var AHandled: Boolean) of object;
|
|
|
|
TcxSchedulerMonthHeaderPopupMenu = class(TcxSchedulerCustomContentPopupMenu)
|
|
private
|
|
FItems: TcxSchedulerMonthHeaderPopupMenuItems;
|
|
FOnPopup: TcxSchedulerMonthHeaderPopupMenuPopupEvent;
|
|
FOnClick: TcxSchedulerMonthHeaderPopupMenuClickEvent;
|
|
function GetYearView: TcxSchedulerYearView;
|
|
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 YearView: TcxSchedulerYearView read GetYearView;
|
|
public
|
|
constructor Create(AScheduler: TcxCustomScheduler); override;
|
|
procedure Assign(Source: TPersistent); override;
|
|
procedure Execute(AItem: TcxSchedulerMonthHeaderPopupMenuItem);
|
|
function GetMenuItem(AItem: TcxSchedulerMonthHeaderPopupMenuItem): TMenuItem;
|
|
published
|
|
property Items: TcxSchedulerMonthHeaderPopupMenuItems
|
|
read FItems write FItems default [mhpmiNewEvent, mhpmiNewAllDayEvent,
|
|
mhpmiNewReccuringEvent, mhpmiFullYear, mhpmiHalfYear, mhpmiQuarter];
|
|
property PopupMenu;
|
|
property UseBuiltInPopupMenu;
|
|
|
|
property OnClick: TcxSchedulerMonthHeaderPopupMenuClickEvent read FOnClick write FOnClick;
|
|
property OnPopup: TcxSchedulerMonthHeaderPopupMenuPopupEvent read FOnPopup write FOnPopup;
|
|
end;
|
|
|
|
implementation
|
|
|
|
const
|
|
DayInc: array[Boolean] of Integer = (-1, 1);
|
|
YearScales: array[0..2] of Integer = (12, 6, 3);
|
|
|
|
type
|
|
TcxSchedulerCustomViewInfoItemAccess = class(TcxSchedulerCustomViewInfoItem);
|
|
TcxSchedulerCustomViewViewInfoAccess = class(TcxSchedulerCustomViewViewInfo);
|
|
|
|
{ TcxSchedulerYearViewController }
|
|
|
|
function TcxSchedulerYearViewController.CreateDragEventHelper: TcxDragEventHelper;
|
|
begin
|
|
Result := TcxYearViewDragEventHelper.Create(Scheduler);
|
|
end;
|
|
|
|
function TcxSchedulerYearViewController.CreateNavigation: TcxSchedulerViewNavigation;
|
|
begin
|
|
Result := TcxSchedulerYearViewNavigation.Create(View);
|
|
end;
|
|
|
|
function TcxSchedulerYearViewController.CreateResizeEventHelper: TcxEventSizingHelper;
|
|
begin
|
|
Result := TcxYearViewEventSizing.Create(Scheduler);
|
|
end;
|
|
|
|
procedure TcxSchedulerYearViewController.KeyDown(var Key: Word; Shift: TShiftState);
|
|
begin
|
|
if View.Active and not EditController.IsEditing and
|
|
TcxSchedulerYearViewNavigation(Navigation).IsKeyNavigation(Key, Shift) then
|
|
TcxSchedulerYearViewNavigation(Navigation).DoKeyDown(Key, Shift)
|
|
else
|
|
inherited KeyDown(Key, Shift);
|
|
end;
|
|
|
|
{ TcxSchedulerYearViewPainter }
|
|
|
|
procedure TcxSchedulerYearViewPainter.Paint;
|
|
begin
|
|
inherited Paint;
|
|
ViewInfo.MonthHeaderCells.Draw(Canvas, DrawHeaderCell);
|
|
ViewInfo.DayHeaderCells.Draw(Canvas, DrawHeaderCell);
|
|
ViewInfo.ContentCells.Draw(Canvas, DrawContentCell);
|
|
ViewInfo.EventCells.Draw(Canvas, DrawEventCell);
|
|
ViewInfo.Buttons.Draw(Canvas, DrawButtonCell);
|
|
ViewInfo.NavigationButtons.Draw(Canvas, DrawButtonCell);
|
|
end;
|
|
|
|
function TcxSchedulerYearViewPainter.GetViewInfo: TcxSchedulerYearViewViewInfo;
|
|
begin
|
|
Result := TcxSchedulerYearViewViewInfo(inherited ViewInfo);
|
|
end;
|
|
|
|
{ TcxSchedulerYearViewEventCellViewInfo }
|
|
|
|
procedure TcxSchedulerYearViewEventCellViewInfo.CalculateBorders;
|
|
begin
|
|
if ViewData.ContentFinish < EventFinish then
|
|
Exclude(FBorders, bRight);
|
|
if ViewData.ContentStart > EventStart then
|
|
Exclude(FBorders, bLeft);
|
|
end;
|
|
|
|
procedure TcxSchedulerYearViewEventCellViewInfo.CalculateCaptions;
|
|
begin
|
|
end;
|
|
|
|
procedure TcxSchedulerYearViewEventCellViewInfo.CalculateEventTimeVisibility;
|
|
var
|
|
B: Boolean;
|
|
begin
|
|
B := IsHeaderEvent and not Event.AllDayEvent;
|
|
ViewData.ShowStartTime := B and (TimeOf(Event.Start) <> 0) and
|
|
(EventStart > ViewData.ContentStart);
|
|
ViewData.ShowFinishTime := B and (TimeOf(Event.Finish) <> 0) and
|
|
(EventFinish < ViewData.ContentFinish);
|
|
end;
|
|
|
|
function TcxSchedulerYearViewEventCellViewInfo.CanAutoHideStandardImages: Boolean;
|
|
begin
|
|
Result := True;
|
|
end;
|
|
|
|
function TcxSchedulerYearViewEventCellViewInfo.GetForceShowClockInHeaderEvent: Boolean;
|
|
begin
|
|
Result := False;
|
|
end;
|
|
|
|
procedure TcxSchedulerYearViewEventCellViewInfo.InitHitTest(
|
|
AHitTest: TcxSchedulerCustomResourceViewHitTest);
|
|
begin
|
|
inherited InitHitTest(AHitTest);
|
|
InitHitTestForHorzEvent(AHitTest);
|
|
end;
|
|
|
|
{ TcxSchedulerYearViewViewInfo }
|
|
|
|
constructor TcxSchedulerYearViewViewInfo.Create(
|
|
AOwner: TcxSchedulerSubControl);
|
|
begin
|
|
inherited Create(AOwner);
|
|
FContentSmallFont := TFont.Create;
|
|
FDayCells := TList.Create;
|
|
FDayCells.Capacity := 444;
|
|
FMonthHeaderCells := TcxSchedulerViewInfoCellList.Create;
|
|
FCells.Add(FMonthHeaderCells);
|
|
end;
|
|
|
|
destructor TcxSchedulerYearViewViewInfo.Destroy;
|
|
begin
|
|
FContentSmallFont.Free;
|
|
FDayCells.Free;
|
|
inherited Destroy;
|
|
end;
|
|
|
|
procedure TcxSchedulerYearViewViewInfo.CalculateHitTest(
|
|
AHitTest: TcxSchedulerCustomResourceViewHitTest);
|
|
begin
|
|
if not MonthHeaderCells.CalculateHitTest(AHitTest) then
|
|
inherited CalculateHitTest(AHitTest);
|
|
end;
|
|
|
|
procedure TcxSchedulerYearViewViewInfo.UpdateSelection;
|
|
var
|
|
I: Integer;
|
|
ACell: TcxSchedulerMonthDayContentCellViewInfo;
|
|
begin
|
|
with View.Navigation do
|
|
begin
|
|
Self.FSelStart := DateTimeHelper.RoundTime(Min(SelStart, SelFinish));
|
|
Self.FSelFinish := DateTimeHelper.RoundTime(Max(SelStart, SelFinish));
|
|
end;
|
|
for I := 0 to ContentCells.Count - 1 do
|
|
begin
|
|
ACell := TcxSchedulerMonthDayContentCellViewInfo(ContentCells[I]);
|
|
if (ACell.TimeStart <> NullDate) and ACell.UpdateSelection(not HideSelection and
|
|
(ACell.TimeStart >= SelStart) and (ACell.TimeStart <= SelFinish)) then
|
|
View.InvalidateRect(ACell.Bounds);
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerYearViewViewInfo.AddEventButtons(
|
|
APlace: TcxSchedulerEventPlace);
|
|
var
|
|
I: Integer;
|
|
begin
|
|
for I := APlace.ColStart to APlace.ColFinish do
|
|
if DaysCells[I].LineCount = 0 then
|
|
begin
|
|
AddButton(DaysCells[I].Bounds, DaysCells[I].TimeStart, True, APlace.Event);
|
|
DaysCells[I].LineCount := 1;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerYearViewViewInfo.AddEventForCalculation(
|
|
ABuilder: TcxSchedulerEventLayoutBuilder; AEvent: TcxSchedulerControlEvent);
|
|
var
|
|
AStart, AFinish: TDateTime;
|
|
AOfs, I, AStartIndex, AFinishIndex: Integer;
|
|
AStartDay: TcxSchedulerYearViewContentCellViewInfo;
|
|
begin
|
|
if (FYearViewExtraAdapter = nil) then
|
|
begin
|
|
AStart := Max(FRangeStart, AEvent.Start);
|
|
AFinish := Min(FRangeFinish, AEvent.Finish);
|
|
AOfs := DayOfTheYear(EncodeDate(Year, FirstMonth, 1));
|
|
I := DayOfTheYear(AStart) - AOfs;
|
|
AFinishIndex := Max(DayOfTheYear(AFinish) - 1 - AOfs, I);
|
|
while (AFinishIndex < (DaysCellCount - 1)) and
|
|
AEvent.IsDayEvent(DaysCells[AFinishIndex + 1].TimeStart) do Inc(AFinishIndex);
|
|
end
|
|
else
|
|
begin
|
|
I := 0;
|
|
while (I < DaysCellCount) and not AEvent.IsDayEvent(DaysCells[I].TimeStart) do
|
|
Inc(I);
|
|
if I = DaysCellCount then Exit;
|
|
AFinishIndex := I;
|
|
while (AFinishIndex < DaysCellCount) and
|
|
AEvent.IsDayEvent(DaysCells[AFinishIndex].TimeStart) do Inc(AFinishIndex);
|
|
Dec(AFinishIndex);
|
|
end;
|
|
while I <= AFinishIndex do
|
|
begin
|
|
AStartIndex := I;
|
|
AStartDay := DaysCells[I];
|
|
while (I <= AFinishIndex) and (AStartDay.Bounds.Top = DaysCells[I].Bounds.Top) do
|
|
Inc(I);
|
|
ABuilder.AddEventPlace(AEvent, AStartIndex, I - 1, 1, TObject(MonthOf(AStartDay.DateTime)));
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerYearViewViewInfo.AddEventToYearView(
|
|
APlace: TcxSchedulerEventPlace);
|
|
var
|
|
ABounds: TRect;
|
|
AViewData: TcxSchedulerEventViewData;
|
|
AStart, AFinish: TDateTime;
|
|
begin
|
|
ABounds := MonthBounds[Integer(APlace.Resource)];
|
|
with DaysCells[APlace.ColStart] do
|
|
begin
|
|
AStart := TimeStart;
|
|
ABounds.Left := Bounds.Left + cxTextOffset;
|
|
end;
|
|
with DaysCells[APlace.ColFinish] do
|
|
begin
|
|
AFinish := TimeFinish;
|
|
ABounds.Right := Bounds.Right - cxTextOffset - 1;
|
|
end;
|
|
ABounds.Top := ABounds.Top + APlace.LineStart * (ContentLineHeight + cxTextOffset);
|
|
ABounds.Bottom := ABounds.Top + ContentLineHeight;
|
|
OffsetRect(ABounds, 0, FDayTextHeight);
|
|
AViewData := CreateEventViewData(TcxSchedulerControlEvent(APlace.Event),
|
|
ABounds, AStart, AFinish, nil);
|
|
AViewData.VisibleRect := MonthBounds[Integer(APlace.Resource)];
|
|
Dec(AViewData.VisibleRect.Bottom, cxTextOffset);
|
|
if AViewData.Bounds.Bottom > AViewData.VisibleRect.Bottom then
|
|
begin
|
|
//todo: lcm if not AViewData.Event.IsClone then
|
|
AddEventButtons(APlace);
|
|
AViewData.Free
|
|
end
|
|
else
|
|
AddEventCell(AViewData);
|
|
end;
|
|
|
|
function TcxSchedulerYearViewViewInfo.AddMonthHeader(AYear, AMonth: Integer;
|
|
const ARect: TRect; AFirstMonth, AMonthCount: Integer): TcxSchedulerMonthHeaderCellViewInfo;
|
|
var
|
|
AParams: TcxViewParams;
|
|
begin
|
|
AParams := View.Styles.GetMonthHeaderParams(AYear, AMonth);
|
|
CreateCellInstance(TcxSchedulerMonthHeaderCellViewInfo, ARect,
|
|
AParams, Result);
|
|
Result.Month := AMonth;
|
|
Result.Year := AYear;
|
|
Result.RotateHeader := True;
|
|
Result.FirstMonth := AFirstMonth;
|
|
Result.MonthCount := AMonthCount;
|
|
MonthHeaderCells.Add(Result);
|
|
end;
|
|
|
|
function TcxSchedulerYearViewViewInfo.AddWeekDayHeader(AWeekDay: Integer;
|
|
ARect: TRect): TcxSchedulerWeekDayHeaderCellViewInfo;
|
|
begin
|
|
Inc(AWeekDay, Integer(View.StartOfWeek));
|
|
if AWeekDay >= 7 then Dec(AWeekDay, 7);
|
|
CreateCellInstance(TcxSchedulerWeekDayHeaderCellViewInfo, ARect,
|
|
StylesAdapter.GetDayHeaderParams(AWeekDay),
|
|
Result);
|
|
Result.DateTime := AWeekDay;
|
|
DayHeaderCells.Add(Result);
|
|
end;
|
|
|
|
function TcxSchedulerYearViewViewInfo.AddYearViewContentCell(
|
|
ARect: TRect; ADate: TDate; ASelected: Boolean;
|
|
AParams: TcxViewParams; AColIndex: Integer): TcxSchedulerYearViewContentCellViewInfo;
|
|
var
|
|
AColor: TColor;
|
|
begin
|
|
CreateCellInstance(TcxSchedulerYearViewContentCellViewInfo,
|
|
ARect, AParams, Result);
|
|
Result.FSmallFont := True;
|
|
Result.SmallTextFont := GetSmallFont(AParams);
|
|
if ADate <> NullDate then
|
|
begin
|
|
Result.SetTime(ADate, ADate + 1);
|
|
Result.SetContentState(True, ASelected, FDayTextHeight - cxTextOffset, FSelectionParams);
|
|
AColor := StylesAdapter.GetContentParams(ADate, True, nil).Color;
|
|
Result.Color := PainterHelper.GetContentColor(AColor,
|
|
View.IsWorkTime(nil, ADate + View.WorkStart));
|
|
FDayCells.Add(Result);
|
|
end;
|
|
Result.LineCount := 0;
|
|
Result.FColIndex := AColIndex;
|
|
ContentCells.Add(Result);
|
|
end;
|
|
|
|
procedure TcxSchedulerYearViewViewInfo.CalculateContentCellMonthParams(
|
|
AMonth: Integer; out AMonthBounds: TRect; out AStartOfMonth: TDate;
|
|
out AStartMonthColumn, ADaysPerMonth: Integer);
|
|
begin
|
|
AMonthBounds := FMonthHeaderCells[AMonth + 1].Bounds;
|
|
AStartOfMonth := EncodeDate(Year, AMonth + FirstMonth, 1);
|
|
AStartMonthColumn := DayOfWeek(AStartOfMonth) - 1;
|
|
Dec(AStartMonthColumn, Integer(View.GetStartOfWeek));
|
|
if AStartMonthColumn < 0 then
|
|
Inc(AStartMonthColumn, 7);
|
|
ADaysPerMonth := DaysPerMonth(Year, AMonth + FirstMonth);
|
|
TcxSchedulerMonthHeaderCellViewInfo(FMonthHeaderCells[AMonth + 1]).FColStart := AStartMonthColumn;
|
|
end;
|
|
|
|
procedure TcxSchedulerYearViewViewInfo.CalculateContentCells;
|
|
var
|
|
I, J: Integer;
|
|
R, DayBounds, MonthBounds: TRect;
|
|
AStartOfMonth, ADate: TDate;
|
|
ACell: TcxSchedulerYearViewContentCellViewInfo;
|
|
AStartMonthColumn, ADaysPerMonth: Integer;
|
|
ASelected: Boolean;
|
|
AParams: TcxViewParams;
|
|
begin
|
|
FMaxEventsCount := 0;
|
|
for I := 0 to MonthCountPerPage - 1 do
|
|
begin
|
|
CalculateContentCellMonthParams(I, MonthBounds, AStartOfMonth,
|
|
AStartMonthColumn, ADaysPerMonth);
|
|
for J := 0 to FMaxYearViewWeekDays - 1 do
|
|
begin
|
|
DayBounds := DayHeaderCells[J].Bounds;
|
|
R := Rect(DayBounds.Left, MonthBounds.Top,
|
|
DayBounds.Right, MonthBounds.Bottom);
|
|
ADate := GetMonthColumnDate(AStartOfMonth, ADaysPerMonth,
|
|
AStartMonthColumn, J + FStartDayIndex);
|
|
ASelected := not HideSelection and
|
|
(ADate >= SelStart) and (ADate <= SelFinish);
|
|
if ADate = NullDate then
|
|
AParams := View.Styles.GetUnusedContentParams(FYear, (I + FirstMonth),
|
|
(Byte(View.OptionsView.ActualStartOfWeek) + J + FStartDayIndex) mod 7)
|
|
else
|
|
AParams := GetContentParams(ADate, nil);
|
|
ACell := AddYearViewContentCell(R, ADate, ASelected, AParams, J);
|
|
FMaxEventsCount := Max(FMaxEventsCount, (R.Bottom - R.Top) div FContentLineHeight + 1);
|
|
if I < MonthCountPerPage then
|
|
ACell.Borders := [bBottom, bRight]
|
|
else
|
|
ACell.Borders := [bRight];
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerYearViewViewInfo.CalculateContentNavigationButtons;
|
|
var
|
|
ABounds: TRect;
|
|
begin
|
|
if not CanCalculateNavigationButtons then Exit;
|
|
|
|
ABounds := Bounds;
|
|
ABounds.Left := ABounds.Left + FMonthHeaderWidth;
|
|
if IsValidNavigationButtonsPlace(ABounds) then
|
|
AddContentNavigationButton(ABounds, -1, cprSingle);
|
|
end;
|
|
|
|
procedure TcxSchedulerYearViewViewInfo.CalculateDaysHeader;
|
|
var
|
|
R: TRect;
|
|
I, W: Integer;
|
|
begin
|
|
W := Bounds.Right - Bounds.Left - FMonthHeaderWidth + 1;
|
|
R := cxRectSetHeight(Bounds, FDayHeaderHeight);
|
|
for I := 0 to FMaxYearViewWeekDays - 1 do
|
|
begin
|
|
R.Left := FMonthHeaderWidth + MulDiv(W, I, FMaxYearViewWeekDays);
|
|
R.Right := FMonthHeaderWidth + MulDiv(W, I + 1, FMaxYearViewWeekDays);
|
|
AddWeekDayHeader(((I + FStartDayIndex) mod 7), R);
|
|
end;
|
|
ProcessCheckBorders(DayHeaderCells, True, [nLeft]);
|
|
ProcessDateToDisplayText(True);
|
|
end;
|
|
|
|
procedure TcxSchedulerYearViewViewInfo.CalculateEventsViewInfo;
|
|
var
|
|
I: Integer;
|
|
AEvent: TcxSchedulerControlEvent;
|
|
ABuilder: TcxSchedulerEventLayoutBuilder;
|
|
begin
|
|
ABuilder := TcxSchedulerEventLayoutBuilder.Create;
|
|
try
|
|
for I := 0 to Events.AbsoluteCount - 1 do
|
|
begin
|
|
AEvent := Events.AbsoluteItems[I];
|
|
if IsEventVisible(AEvent) then
|
|
AddEventForCalculation(ABuilder, AEvent);
|
|
end;
|
|
ABuilder.Calculate;
|
|
for I := 0 to DaysCellCount - 1 do
|
|
DaysCells[I].LineCount := 0;
|
|
for I := ABuilder.EventPlaceCount - 1 downto 0 do
|
|
AddEventToYearView(ABuilder.EventPlaces[I]);
|
|
finally
|
|
ABuilder.Free;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerYearViewViewInfo.CalculateMetrics;
|
|
begin
|
|
inherited CalculateMetrics;
|
|
if FYearViewExtraAdapter = nil then
|
|
FYear := View.Year
|
|
else
|
|
FYear := YearOf(SelectedDays[0]);
|
|
FDayTextHeight := Round(FContentFontHeight * 2 / 3);
|
|
end;
|
|
|
|
procedure TcxSchedulerYearViewViewInfo.CalculateMonthHeaderWidth;
|
|
var
|
|
I: Integer;
|
|
AFont: TFont;
|
|
AStyle: TcxStyle;
|
|
begin
|
|
if not FShowMonthHeaders then
|
|
begin
|
|
FMonthHeaderWidth := 0;
|
|
Exit;
|
|
end;
|
|
AStyle := View.Styles.MonthHeader;
|
|
if (AStyle <> nil) and (cxStyles.svFont in AStyle.AssignedValues) then
|
|
AFont := AStyle.Font
|
|
else
|
|
AFont := DefaultFont;
|
|
FMonthHeaderWidth := cxTextWidth(AFont, 'WWWW') + 4 * cxTextOffset;
|
|
for I := 1 to 12 do
|
|
FMonthHeaderWidth := Max(FMonthHeaderWidth,
|
|
cxTextWidth(AFont, LongMonthNames[I]) + 4 * cxTextOffset);
|
|
end;
|
|
|
|
procedure TcxSchedulerYearViewViewInfo.CalculateMonthsHeader;
|
|
var
|
|
R: TRect;
|
|
I, H: Integer;
|
|
begin
|
|
CalculateMonthHeaderWidth;
|
|
H := Bounds.Bottom - Bounds.Top - FDayHeaderHeight;
|
|
R := cxRectSetHeight(cxRectSetWidth(Bounds, FMonthHeaderWidth),
|
|
FDayHeaderHeight);
|
|
AddMonthHeader(FYear, 0, R, AdapterFirstMonth, AdapterMonthCount).RotateHeader := False;
|
|
for I := 0 to MonthCountPerPage - 1 do
|
|
begin
|
|
R.Top := MulDiv(H, I, MonthCountPerPage) + FDayHeaderHeight;
|
|
R.Bottom := MulDiv(H, I + 1, MonthCountPerPage) + FDayHeaderHeight;
|
|
AddMonthHeader(FYear, I + FirstMonth, R);
|
|
end;
|
|
ProcessCheckBorders(MonthHeaderCells, True, [], []);
|
|
end;
|
|
|
|
procedure TcxSchedulerYearViewViewInfo.CheckLayout(ADate: TDateTime);
|
|
begin
|
|
if (ADate < Trunc(TcxSchedulerCustomViewInfoItemAccess(FDayCells[0]).FDateTime)) or
|
|
(ADate > Trunc(TcxSchedulerCustomViewInfoItemAccess(FDayCells[FDayCells.Count - 1]).FDateTime)) then
|
|
begin
|
|
View.Changed;
|
|
View.ChangeLayout(ADate);
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerYearViewViewInfo.Clear;
|
|
begin
|
|
FDayCells.Clear;
|
|
FMonthHeaderCells.Clear;
|
|
inherited Clear;
|
|
end;
|
|
|
|
function TcxSchedulerYearViewViewInfo.ContentCellClass: TcxSchedulerContentCellViewInfoClass;
|
|
begin
|
|
Result := TcxSchedulerYearViewContentCellViewInfo;
|
|
end;
|
|
|
|
function TcxSchedulerYearViewViewInfo.CreateEventCellViewInfo(
|
|
AViewData: TcxSchedulerEventViewData): TcxSchedulerEventCellViewInfo;
|
|
begin
|
|
Result := TcxSchedulerYearViewEventCellViewInfo.Create(AViewData);
|
|
end;
|
|
|
|
function TcxSchedulerYearViewViewInfo.GetPartOfTheYear(ADate: TDateTime): Word;
|
|
var
|
|
AYear, AMonth, ADay: Word;
|
|
begin
|
|
DecodeDate(ADate, AYear, AMonth, ADay);
|
|
Result := 0;
|
|
while AMonth >= (Result + 1) * AdapterMonthCount + 1 do
|
|
Inc(Result);
|
|
end;
|
|
|
|
procedure TcxSchedulerYearViewViewInfo.DoCalculate;
|
|
var
|
|
ADate: TDateTime;
|
|
begin
|
|
ADate := SelectedDays[0];
|
|
SelectedDays.Clear;
|
|
SelectedDays.Add(ADate);
|
|
PrepareSmallContentFont;
|
|
FStartDayIndex := 0;
|
|
FShowMonthHeaders := True;
|
|
FMaxYearViewWeekDays := MaxYearViewWeekDays;
|
|
Supports(TObject(Adapter), IcxSchedulerYearViewAdapter, FYearViewExtraAdapter);
|
|
try
|
|
inherited DoCalculate;
|
|
if FYearViewExtraAdapter <> nil then
|
|
begin
|
|
if not FYearViewExtraAdapter.GetShowWeekDayHeaders then
|
|
FDayHeaderHeight := 0;
|
|
FShowMonthHeaders := FYearViewExtraAdapter.GetShowMonthHeaders;
|
|
FStartDayIndex := FYearViewExtraAdapter.GetStartDayIndex;
|
|
FMaxYearViewWeekDays := FYearViewExtraAdapter.GetDayCountPerPage;
|
|
FAdapterFirstMonth := FYearViewExtraAdapter.GetFirstMonth;
|
|
FAdapterMonthCount := FYearViewExtraAdapter.GetMonthCount;
|
|
end;
|
|
FRangeStart := Trunc(EncodeDate(Year, FirstMonth, 1));
|
|
FRangeFinish := Trunc(EndOfTheMonth(EncodeDate(Year,
|
|
FirstMonth + GetMonthCountPerPage - 1, 1)));
|
|
|
|
CalculateMonthsHeader;
|
|
CalculateDaysHeader;
|
|
CalculateContentCells;
|
|
CalculateEventsViewInfo;
|
|
CalculateContentNavigationButtons;
|
|
finally
|
|
FYearViewExtraAdapter := nil;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerYearViewViewInfo.DoContentNavigationButtonClick(
|
|
Sender: TcxSchedulerContentNavigationButtonViewInfo);
|
|
var
|
|
ARequiredDay: TDateTime;
|
|
begin
|
|
ARequiredDay := SelectedDays[0] + Sender.Interval;
|
|
View.Navigation.FCurrentAnchor := ARequiredDay;
|
|
CheckLayout(ARequiredDay);
|
|
end;
|
|
|
|
function TcxSchedulerYearViewViewInfo.GetMonthColumnDate(
|
|
AStartOfMonth: TDateTime;
|
|
ADaysPerMonth, AStartMonthColumn, AColumn: Integer): TDateTime;
|
|
begin
|
|
Result := NullDate;
|
|
Dec(AColumn, AStartMonthColumn);
|
|
if (AColumn >= 0) and (AColumn < ADaysPerMonth) then
|
|
Result := AStartOfMonth + AColumn;
|
|
end;
|
|
|
|
function TcxSchedulerYearViewViewInfo.GetSmallFont(const AParams: TcxViewParams): TFont;
|
|
begin
|
|
if AParams.Font = FContentFont then
|
|
Result := FContentSmallFont
|
|
else
|
|
Result := nil;
|
|
end;
|
|
|
|
function TcxSchedulerYearViewViewInfo.GetFirstMonth: Integer;
|
|
begin
|
|
if FYearViewExtraAdapter = nil then
|
|
Result := 1
|
|
else
|
|
Result := FYearViewExtraAdapter.GetFirstMonth;
|
|
end;
|
|
|
|
function TcxSchedulerYearViewViewInfo.GetMonthCountPerPage: Integer;
|
|
begin
|
|
if FYearViewExtraAdapter = nil then
|
|
Result := 12
|
|
else
|
|
Result := FYearViewExtraAdapter.GetMonthCount;
|
|
end;
|
|
|
|
function TcxSchedulerYearViewViewInfo.IsEventVisible(
|
|
AEvent: TcxSchedulerControlEvent): Boolean;
|
|
begin
|
|
Result := not View.AllDayEventsOnly or (AEvent.AllDayEvent or (AEvent.Duration > 1));
|
|
if Result then
|
|
Result := (DateOf(AEvent.Start) <= FRangeFinish) and
|
|
(AEvent.Finish > FRangeStart);
|
|
end;
|
|
|
|
procedure TcxSchedulerYearViewViewInfo.PrepareSmallContentFont;
|
|
begin
|
|
FContentFont := StylesAdapter.GetContentParams(NullDate, Nil).Font;
|
|
FContentSmallFont.Assign(FContentFont);
|
|
FContentSmallFont.Size := Round(FContentFont.Size * 2 / 3);
|
|
end;
|
|
|
|
function TcxSchedulerYearViewViewInfo.GetAdapterFirstMonth: Integer;
|
|
begin
|
|
Result := Max(FAdapterFirstMonth, 1);
|
|
end;
|
|
|
|
function TcxSchedulerYearViewViewInfo.GetAdapterMonthCount: Integer;
|
|
begin
|
|
Result := FAdapterMonthCount;
|
|
if (Result < 1) or (Result > 12) then
|
|
Result := 12;
|
|
end;
|
|
|
|
function TcxSchedulerYearViewViewInfo.GetDaysCell(
|
|
AIndex: Integer): TcxSchedulerYearViewContentCellViewInfo;
|
|
begin
|
|
Result := TcxSchedulerYearViewContentCellViewInfo(FDayCells.List^[AIndex])
|
|
end;
|
|
|
|
function TcxSchedulerYearViewViewInfo.GetDaysCellCount: Integer;
|
|
begin
|
|
Result := FDayCells.Count;
|
|
end;
|
|
|
|
function TcxSchedulerYearViewViewInfo.GetMonthBounds(AIndex: Integer): TRect;
|
|
begin
|
|
Result := MonthHeaderCells[AIndex - FirstMonth + 1].Bounds;
|
|
Result.Left := Result.Right;
|
|
Result.Right := Bounds.Right;
|
|
end;
|
|
|
|
function TcxSchedulerYearViewViewInfo.GetYearView: TcxSchedulerYearView;
|
|
begin
|
|
Result := TcxSchedulerYearView(inherited View);
|
|
end;
|
|
|
|
{ TcxSchedulerYearViewNavigation }
|
|
|
|
procedure TcxSchedulerYearViewNavigation.KeyDown(var AKey: Word;
|
|
AShift: TShiftState);
|
|
begin
|
|
CorrectCurrentAnchor;
|
|
FCanChangeSelection := True;
|
|
case AKey of
|
|
VK_Left, VK_Right:
|
|
GotoNextCellHorz(AKey = VK_RIGHT);
|
|
VK_UP, VK_DOWN:
|
|
GotoNextCellVert(AKey = VK_DOWN);
|
|
VK_HOME, VK_END:
|
|
GotoCornerCell(AKey = VK_END);
|
|
VK_NEXT, VK_PRIOR:
|
|
GotoNextPage(AKey = VK_NEXT);
|
|
end;
|
|
if ViewInfo.FYearViewExtraAdapter <> nil then
|
|
TcxSchedulerYearViewAdapter(ViewInfo.FYearViewExtraAdapter).PredefinedCurrentAnchor :=
|
|
FCurrentAnchor;
|
|
ViewInfo.CheckLayout(FCurrentAnchor);
|
|
SetSelAnchor(FCurrentAnchor, AShift);
|
|
end;
|
|
|
|
procedure TcxSchedulerYearViewNavigation.ValidateSelection(
|
|
var ASelStart, ASelFinish: TDateTime;
|
|
var AResource: TcxSchedulerStorageResourceItem);
|
|
begin
|
|
AResource := nil;
|
|
FCanChangeSelection := FCanChangeSelection or View.HitTest.HitAtTime;
|
|
if not FCanChangeSelection then
|
|
begin
|
|
ASelStart := FSaveSelStart;
|
|
ASelFinish := FSaveSelFinish;
|
|
end;
|
|
ASelStart := Min(Max(ASelStart, View.FirstVisibleDate), View.LastVisibleDate);
|
|
ASelFinish := Min(Max(ASelFinish, View.FirstVisibleDate), View.LastVisibleDate);
|
|
if (View.MaxSelectedDaysCount > 0) then
|
|
ASelFinish := Max(Min(ASelFinish, ASelStart + View.MaxSelectedDaysCount - 1),
|
|
ASelStart - View.MaxSelectedDaysCount + 1);
|
|
FSaveSelFinish := ASelFinish;
|
|
FSaveSelStart := ASelStart;
|
|
FCanChangeSelection := False;
|
|
end;
|
|
|
|
function TcxSchedulerYearViewNavigation.ContentCell(
|
|
AIndex: Integer): TcxSchedulerYearViewContentCellViewInfo;
|
|
begin
|
|
Result := TcxSchedulerYearViewContentCellViewInfo(ViewInfo.ContentCells.List^[AIndex]);
|
|
end;
|
|
|
|
procedure TcxSchedulerYearViewNavigation.CorrectCurrentAnchor;
|
|
begin
|
|
FCurrentAnchor := Min(Max(FCurrentAnchor, View.FirstVisibleDate),
|
|
View.LastVisibleDate);
|
|
end;
|
|
|
|
procedure TcxSchedulerYearViewNavigation.DoKeyDown(
|
|
var AKey: Word; AShift: TShiftState);
|
|
var
|
|
APrevCurrentAnchor: TDateTime;
|
|
begin
|
|
if Scheduler.SelectedEventCount > 0 then
|
|
Scheduler.UnselectEvents;
|
|
FCurrentAnchor := SelAnchor;
|
|
FCurrentResource := SelResource;
|
|
APrevCurrentAnchor := FCurrentAnchor;
|
|
FShift := AShift;
|
|
KeyDown(AKey, AShift);
|
|
if YearOf(APrevCurrentAnchor) = YearOf(FCurrentAnchor) then
|
|
ViewInfo.UpdateSelection;
|
|
end;
|
|
|
|
procedure TcxSchedulerYearViewNavigation.GotoCornerCell(AGotoEnd: Boolean);
|
|
var
|
|
AMonth, AYear, ADay: Word;
|
|
begin
|
|
if ssCtrl in FShift then
|
|
begin
|
|
if AGotoEnd then
|
|
FCurrentAnchor := View.LastVisibleDate
|
|
else
|
|
FCurrentAnchor := View.FirstVisibleDate;
|
|
end
|
|
else
|
|
begin
|
|
DecodeDate(FCurrentAnchor, AYear, AMonth, ADay);
|
|
if AGotoEnd then
|
|
FCurrentAnchor := EncodeDate(AYear, AMonth, DaysPerMonth(AYear, AMonth))
|
|
else
|
|
FCurrentAnchor := EncodeDate(AYear, AMonth, 1);
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerYearViewNavigation.GotoNextCellHorz(AGotoNext: Boolean);
|
|
begin
|
|
FCurrentAnchor := FCurrentAnchor + DayInc[AGotoNext];
|
|
end;
|
|
|
|
procedure TcxSchedulerYearViewNavigation.GotoNextCellVert(AGoForward: Boolean);
|
|
|
|
function DayOfTheRange(ACurrentAnchor: TDateTime): Word;
|
|
var
|
|
AYear, AMonth, ADay: Word;
|
|
begin
|
|
DecodeDate(ACurrentAnchor, AYear, AMonth, ADay);
|
|
Result := Trunc(ACurrentAnchor) -
|
|
Trunc(EncodeDate(AYear, ViewInfo.AdapterFirstMonth, 1)) + 1;
|
|
end;
|
|
|
|
var
|
|
AYear, AMonth, ADay, APart: Word;
|
|
AIndex, AColIndex: Integer;
|
|
begin
|
|
APart := ViewInfo.GetPartOfTheYear(FCurrentAnchor);
|
|
DecodeDate(FCurrentAnchor, AYear, AMonth, ADay);
|
|
IncAMonth(AYear, AMonth, ADay, DayInc[AGoForward]);
|
|
if (AYear = ViewInfo.Year) and
|
|
(APart = ViewInfo.GetPartOfTheYear(EncodeDate(AYear, AMonth, ADay))) then
|
|
begin
|
|
AIndex := ViewInfo.FContentCells.IndexOf(ViewInfo.DaysCells[DayOfTheRange(FCurrentAnchor) - 1]);
|
|
AColIndex := ContentCell(AIndex).FColIndex;
|
|
AIndex := AIndex + DayInc[AGoForward];
|
|
while ContentCell(AIndex).FColIndex <> AColIndex do
|
|
Inc(AIndex, DayInc[AGoForward]);
|
|
while ContentCell(AIndex).TimeStart = NullDate do
|
|
Inc(AIndex, DayInc[AColIndex < 20]);
|
|
FCurrentAnchor := ContentCell(AIndex).TimeStart;
|
|
end
|
|
else
|
|
FCurrentAnchor := EncodeDate(AYear, AMonth, ADay);
|
|
end;
|
|
|
|
procedure TcxSchedulerYearViewNavigation.GotoNextPage(AGotoForward: Boolean);
|
|
var
|
|
AYear, AMonth, ADay: Word;
|
|
ANewMonth: Integer;
|
|
begin
|
|
DecodeDate(FCurrentAnchor, AYear, AMonth, ADay);
|
|
ANewMonth := AMonth;
|
|
Inc(ANewMonth, DayInc[AGotoForward] * ViewInfo.AdapterMonthCount);
|
|
if ANewMonth < 1 then
|
|
begin
|
|
Dec(AYear);
|
|
Inc(ANewMonth, 12);
|
|
end;
|
|
if ANewMonth > 12 then
|
|
begin
|
|
Inc(AYear);
|
|
Dec(ANewMonth, 12);
|
|
end;
|
|
AMonth := ANewMonth;
|
|
ADay := Min(ADay, DayOfTheMonth(EndOfAMonth(AYear, AMonth)));
|
|
FCurrentAnchor := EncodeDate(AYear, AMonth, ADay);
|
|
end;
|
|
|
|
function TcxSchedulerYearViewNavigation.GetYearView: TcxSchedulerYearView;
|
|
begin
|
|
Result := TcxSchedulerYearView(inherited View);
|
|
end;
|
|
|
|
function TcxSchedulerYearViewNavigation.GetYearViewInfo: TcxSchedulerYearViewViewInfo;
|
|
begin
|
|
Result := TcxSchedulerYearViewViewInfo(inherited ViewInfo);
|
|
end;
|
|
|
|
{ TcxSchedulerMonthHeaderCellViewInfo }
|
|
|
|
procedure TcxSchedulerMonthHeaderCellViewInfo.CalculateDisplayText;
|
|
|
|
function GetPartOfYear: string;
|
|
begin
|
|
if MonthCount = 0 then Exit;
|
|
Result := '';
|
|
if MonthCount = 6 then
|
|
Result := Result + scxHalfYearShort
|
|
else
|
|
if MonthCount = 3 then
|
|
Result := Result + scxQuarterShort;
|
|
if MonthCount <> 12 then
|
|
Result := Result + IntToStr(FirstMonth div MonthCount + 1) + ' ';
|
|
end;
|
|
|
|
begin
|
|
DateTime := NullDate;
|
|
if FMonth = 0 then
|
|
DisplayText := GetPartOfYear + IntToStr(FYear)
|
|
else
|
|
DisplayText := LongMonthNames[FMonth];
|
|
end;
|
|
|
|
procedure TcxSchedulerMonthHeaderCellViewInfo.InitHitTest(
|
|
AHitTest: TcxSchedulerCustomResourceViewHitTest);
|
|
begin
|
|
if FMonth = 0 then
|
|
TcxSchedulerYearViewHitTest(AHitTest).SetHitTime(htcYear, EncodeDate(Year, 1, 1))
|
|
else
|
|
TcxSchedulerYearViewHitTest(AHitTest).SetHitTime(htcMonth, EncodeDate(Year, FMonth, 1));
|
|
end;
|
|
|
|
procedure TcxSchedulerMonthHeaderCellViewInfo.SetFirstMonth(AValue: Integer);
|
|
begin
|
|
FFirstMonth := AValue;
|
|
CalculateDisplayText;
|
|
end;
|
|
|
|
procedure TcxSchedulerMonthHeaderCellViewInfo.SetMonth(AValue: Integer);
|
|
begin
|
|
FMonth := AValue;
|
|
CalculateDisplayText;
|
|
end;
|
|
|
|
procedure TcxSchedulerMonthHeaderCellViewInfo.SetMonthCount(AValue: Integer);
|
|
begin
|
|
FMonthCount := AValue;
|
|
CalculateDisplayText;
|
|
end;
|
|
|
|
procedure TcxSchedulerMonthHeaderCellViewInfo.SetYear(AValue: Integer);
|
|
begin
|
|
FYear := AValue;
|
|
CalculateDisplayText;
|
|
end;
|
|
|
|
{ TcxSchedulerYearViewContentCellViewInfo }
|
|
|
|
procedure TcxSchedulerYearViewContentCellViewInfo.InitHitTest(
|
|
AHitTest: TcxSchedulerCustomResourceViewHitTest);
|
|
begin
|
|
if Self.TimeStart <> NullDate then
|
|
inherited InitHitTest(AHitTest);
|
|
end;
|
|
|
|
{ TcxYearViewDragEventHelper }
|
|
|
|
procedure TcxYearViewDragEventHelper.UpdateViewClonesTime;
|
|
var
|
|
I: Integer;
|
|
ANewStart, ADelta: TDateTime;
|
|
AShift: TDateTime;
|
|
View: TcxSchedulerYearView;
|
|
begin
|
|
View := TcxSchedulerYearViewViewInfo(ViewInfo).GetYearView;
|
|
AShift := HitTest.Time - Controller.StartDragHitTime;
|
|
for I := 0 to Clones.Count - 1 do
|
|
begin
|
|
ANewStart := AShift + Clones[I].Source.Start;
|
|
ADelta := Max(0, View.GetFirstVisibleDate - DateOf(ANewStart));
|
|
if ADelta = 0 then
|
|
begin
|
|
ADelta := Min(0, View.GetLastVisibleDate - DateOf(ANewStart) -
|
|
DateOf(Clones[I].Duration) + Ord(Clones[I].AllDayEvent));
|
|
end;
|
|
Clones[I].MoveTo(ANewStart + ADelta);
|
|
end;
|
|
end;
|
|
|
|
{ TcxYearViewEventSizing }
|
|
|
|
procedure TcxYearViewEventSizing.UpdateEventBounds;
|
|
begin
|
|
if Event.AllDayEvent then
|
|
inherited UpdateEventBounds
|
|
else
|
|
begin
|
|
if Controller.DragKind = edkResizeStart then
|
|
begin
|
|
Event.AllDayEvent := TimeOf(Event.Finish) = 0;
|
|
Event.Start := HitTest.Time;
|
|
end
|
|
else
|
|
begin
|
|
Event.AllDayEvent := TimeOf(Event.Start) = 0;
|
|
if Event.AllDayEvent then
|
|
Event.Finish := HitTest.Time
|
|
else
|
|
Event.Finish := HitTest.Time + 1;
|
|
end;
|
|
CheckEventState(Event);
|
|
RefreshCurrentView;
|
|
end;
|
|
end;
|
|
|
|
{ TcxSchedulerYearViewStyles }
|
|
|
|
constructor TcxSchedulerYearViewStyles.Create(AOwner: TPersistent);
|
|
begin
|
|
inherited Create(AOwner);
|
|
FYearView := TcxSchedulerYearView(GetOwner);
|
|
FScheduler := FYearView.Scheduler;
|
|
BitmapInViewParams := True;
|
|
end;
|
|
|
|
procedure TcxSchedulerYearViewStyles.Assign(Source: TPersistent);
|
|
var
|
|
I: Integer;
|
|
begin
|
|
if Source is TcxSchedulerYearViewStyles then
|
|
for I := 0 to cxcsMaxYearViewStyle do
|
|
SetValue(I, TcxSchedulerYearViewStyles(Source).GetValue(I));
|
|
inherited Assign(Source);
|
|
end;
|
|
|
|
function TcxSchedulerYearViewStyles.GetMonthHeaderParams(
|
|
AYear, AMonth: Integer): TcxViewParams;
|
|
var
|
|
AStyle: TcxStyle;
|
|
begin
|
|
AStyle := nil;
|
|
if Assigned(FOnGetMonthHeaderStyle) then
|
|
FOnGetMonthHeaderStyle(YearView, AYear, AMonth, AStyle);
|
|
GetViewParams(cxcsMonthHeader, nil, AStyle, Result);
|
|
end;
|
|
|
|
function TcxSchedulerYearViewStyles.GetUnusedContentParams(
|
|
AYear, AMonth, ADayOfWeek: Integer): TcxViewParams;
|
|
var
|
|
AStyle: TcxStyle;
|
|
begin
|
|
AStyle := nil;
|
|
if Assigned(FOnGetUnusedContentStyle) then
|
|
FOnGetUnusedContentStyle(YearView, AYear, AMonth, ADayOfWeek, AStyle);
|
|
GetViewParams(cxcsUnusedContent, Pointer(ADayOfWeek), AStyle, Result);
|
|
{with YearView do
|
|
begin
|
|
if (AStyle = nil) or not (svColor in AStyle.AssignedValues) then
|
|
begin
|
|
Result.Color := PainterHelper.GetContentColor(Result.Color,
|
|
TDay(ADayOfWeek) in OptionsView.WorkDays);
|
|
end;
|
|
end;} //Do the same as GetDefaultViewParams
|
|
end;
|
|
|
|
procedure TcxSchedulerYearViewStyles.Changed(AIndex: Integer);
|
|
begin
|
|
inherited Changed(AIndex);
|
|
FYearView.Refresh;
|
|
end;
|
|
|
|
procedure TcxSchedulerYearViewStyles.GetDefaultViewParams(Index: Integer;
|
|
AData: TObject; out AParams: TcxViewParams);
|
|
begin
|
|
AParams.Bitmap := nil;
|
|
AParams.Font := Scheduler.Font;
|
|
AParams.TextColor := clBlack;
|
|
AParams.Color := Scheduler.Color;
|
|
case Index of
|
|
cxcsUnusedContent:
|
|
begin
|
|
with FYearView do
|
|
begin
|
|
AParams.Color := PainterHelper.GetContentColor(
|
|
clBtnFace, TDay(Integer(AData)) in OptionsView.WorkDays);
|
|
end;
|
|
end;
|
|
cxcsMonthHeader:
|
|
begin
|
|
AParams.Color := Painter.DefaultHeaderColor;
|
|
AParams.TextColor := Painter.DefaultHeaderTextColor;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TcxSchedulerYearViewStyles.GetPainter: TcxCustomLookAndFeelPainterClass;
|
|
begin
|
|
Result := FYearView.LookAndFeelPainter;
|
|
end;
|
|
|
|
{ TcxSchedulerYearView }
|
|
|
|
constructor TcxSchedulerYearView.Create(AOwner: TcxCustomScheduler);
|
|
begin
|
|
inherited Create(AOwner);
|
|
FScale := 12;
|
|
end;
|
|
|
|
procedure TcxSchedulerYearView.Assign(Source: TPersistent);
|
|
begin
|
|
if Source is TcxSchedulerYearView then
|
|
with TcxSchedulerYearView(Source) do
|
|
begin
|
|
Self.FMaxSelectedDaysCount := FMaxSelectedDaysCount;
|
|
Self.FAllDayEventsOnly := FAllDayEventsOnly;
|
|
Self.FMonthHeaderPopupMenu := FMonthHeaderPopupMenu;
|
|
Self.FStyles.Assign(FStyles);
|
|
Self.FScale := FScale;
|
|
end;
|
|
inherited Assign(Source);
|
|
end;
|
|
|
|
procedure TcxSchedulerYearView.CreateSubClasses;
|
|
begin
|
|
FStyles := CreateStyles;
|
|
inherited CreateSubClasses;
|
|
FMonthHeaderPopupMenu := CreateMonthHeaderPopupMenu;
|
|
end;
|
|
|
|
function TcxSchedulerYearView.CreateViewAdapter: TcxCustomResourceViewAdapter;
|
|
begin
|
|
Result := TcxSchedulerYearViewAdapter.Create(Self);
|
|
end;
|
|
|
|
procedure TcxSchedulerYearView.DestroySubClasses;
|
|
begin
|
|
FMonthHeaderPopupMenu.Free;
|
|
inherited DestroySubClasses;
|
|
FStyles.Free;
|
|
end;
|
|
|
|
function TcxSchedulerYearView.CanDeactivateOnDateNavigatorSelectionChange: Boolean;
|
|
begin
|
|
Result := False;
|
|
end;
|
|
|
|
function TcxSchedulerYearView.CanSelectPeriod: Boolean;
|
|
begin
|
|
Result := False;
|
|
end;
|
|
|
|
procedure TcxSchedulerYearView.ChangeLayout(ACurrentAnchor: TDateTime);
|
|
begin
|
|
Scheduler.DateNavigator.BeginUpdate;
|
|
try
|
|
SelectedDays.Clear;
|
|
SelectedDays.Add(EncodeDate(YearOf(ACurrentAnchor),
|
|
ViewInfo.GetPartOfTheYear(ACurrentAnchor) *
|
|
ViewInfo.AdapterMonthCount + 1, 1));
|
|
UpdateDateNavigatorSelection;
|
|
Changed;
|
|
Scheduler.FullRefresh;
|
|
finally
|
|
Scheduler.DateNavigator.EndUpdate;
|
|
end;
|
|
end;
|
|
|
|
function TcxSchedulerYearView.CreateController: TcxSchedulerSubControlController;
|
|
begin
|
|
Result := TcxSchedulerYearViewController.Create(Self);
|
|
end;
|
|
|
|
function TcxSchedulerYearView.CreateHitTest: TcxSchedulerSubControlHitTest;
|
|
begin
|
|
Result := TcxSchedulerYearViewHitTest.Create(Self);
|
|
end;
|
|
|
|
function TcxSchedulerYearView.CreateMonthHeaderPopupMenu: TcxSchedulerMonthHeaderPopupMenu;
|
|
begin
|
|
Result := TcxSchedulerMonthHeaderPopupMenu.Create(Scheduler);
|
|
end;
|
|
|
|
function TcxSchedulerYearView.CreatePainter: TcxSchedulerSubControlPainter;
|
|
begin
|
|
Result := TcxSchedulerYearViewPainter.Create(Self);
|
|
end;
|
|
|
|
function TcxSchedulerYearView.CreateStyles: TcxSchedulerYearViewStyles;
|
|
begin
|
|
Result := TcxSchedulerYearViewStyles.Create(Self);
|
|
end;
|
|
|
|
function TcxSchedulerYearView.CreateViewInfo: TcxSchedulerSubControlViewInfo;
|
|
begin
|
|
Result := TcxSchedulerYearViewViewInfo.Create(Self);
|
|
end;
|
|
|
|
function TcxSchedulerYearView.DoShowPopupMenu(X, Y: Integer): Boolean;
|
|
begin
|
|
if HitTest.HitAtMonth then
|
|
Result := MonthHeaderPopupMenu.Popup(X, Y)
|
|
else
|
|
Result := inherited DoShowPopupMenu(X, Y);
|
|
end;
|
|
|
|
function TcxSchedulerYearView.GetCompressWeekEnd: Boolean;
|
|
begin
|
|
Result := False;
|
|
end;
|
|
|
|
function TcxSchedulerYearView.GetGroupingKind: TcxSchedulerGroupingKind;
|
|
begin
|
|
Result := gkNone;
|
|
end;
|
|
|
|
function TcxSchedulerYearView.GetFirstVisibleDate: TDateTime;
|
|
begin
|
|
Result := EncodeDate(Year, ViewInfo.AdapterFirstMonth, 1);
|
|
end;
|
|
|
|
function TcxSchedulerYearView.GetLastVisibleDate: TDateTime;
|
|
var
|
|
AMonth: Integer;
|
|
begin
|
|
AMonth := ViewInfo.AdapterFirstMonth + ViewInfo.AdapterMonthCount - 1;
|
|
Result := EncodeDate(Year, AMonth, DayOfTheMonth(EndOfAMonth(Year, AMonth)));
|
|
end;
|
|
|
|
function TcxSchedulerYearView.GetScrollPos: Integer;
|
|
var
|
|
AMonthCount: Integer;
|
|
begin
|
|
AMonthCount := ViewInfo.AdapterMonthCount;
|
|
if AMonthCount <> 0 then
|
|
Result := Max(cxYearViewScrollMinPos,
|
|
Min(MulDiv(cxYearViewScrollMaxPos, 12, AMonthCount),
|
|
MulDiv((Year - YearOf(Now)), 12, AMonthCount) +
|
|
ViewInfo.AdapterFirstMonth div AMonthCount -
|
|
ViewInfo.GetPartOfTheYear(Now) +
|
|
MulDiv(cxYearViewScrollCurrentYearPos, 12, AMonthCount)))
|
|
else
|
|
Result := Max(cxYearViewScrollMinPos, Min(cxYearViewScrollMaxPos,
|
|
(Year - YearOf(Now) + cxYearViewScrollCurrentYearPos)));
|
|
end;
|
|
|
|
function TcxSchedulerYearView.GetVisibleDaysRange: Integer;
|
|
begin
|
|
Result := Trunc(GetLastVisibleDate - GetFirstVisibleDate);
|
|
end;
|
|
|
|
procedure TcxSchedulerYearView.InitScrollBarsParameters;
|
|
var
|
|
APos: Integer;
|
|
begin
|
|
inherited InitScrollBarsParameters;
|
|
APos := GetScrollPos;
|
|
SetScrollBarInfo(sbVertical, cxYearViewScrollMinPos,
|
|
MulDiv(cxYearViewScrollMaxPos, 12, ViewInfo.AdapterMonthCount),
|
|
1, 1, APos, True, True);
|
|
end;
|
|
|
|
procedure TcxSchedulerYearView.MakeEventVisible(AEvent: TcxSchedulerControlEvent;
|
|
const ADate: TDateTime; AResource: TcxSchedulerStorageResourceItem);
|
|
begin
|
|
if ADate <> NullDate then
|
|
begin
|
|
ViewInfo.CheckLayout(ADate);
|
|
LayoutChanged;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerYearView.Notification(AComponent: TComponent;
|
|
Operation: TOperation);
|
|
begin
|
|
inherited Notification(AComponent, Operation);
|
|
if (Operation = opRemove) then
|
|
begin
|
|
if AComponent = Styles.UnusedContent then
|
|
Styles.UnusedContent := nil;
|
|
if AComponent = Styles.MonthHeader then
|
|
Styles.MonthHeader := nil;
|
|
end;
|
|
MonthHeaderPopupMenu.Notification(AComponent, Operation);
|
|
end;
|
|
|
|
procedure TcxSchedulerYearView.Scroll(AScrollBarKind: TScrollBarKind;
|
|
AScrollCode: TScrollCode; var AScrollPos: Integer);
|
|
var
|
|
AYear, AMonth, AMonthCount: Integer;
|
|
ANavigation: TcxSchedulerYearViewNavigation;
|
|
begin
|
|
ANavigation := TcxSchedulerYearViewNavigation(Navigation);
|
|
HideHintOnScroll(AScrollCode);
|
|
AMonthCount := ViewInfo.AdapterMonthCount;
|
|
if AMonthCount = 0 then
|
|
AYear := YearOf(Now) - cxYearViewScrollCurrentYearPos + AScrollPos
|
|
else
|
|
AYear := MulDiv(YearOf(Now) - cxYearViewScrollCurrentYearPos, 12, AMonthCount) +
|
|
ViewInfo.GetPartOfTheYear(Now) + AScrollPos;
|
|
ANavigation.CorrectCurrentAnchor;
|
|
case AScrollCode of
|
|
scTrack:
|
|
begin
|
|
ShowHintOnScroll(IntToStr(AYear), sbHorizontal);
|
|
Exit;
|
|
end;
|
|
scPosition:
|
|
if AMonthCount = 0 then
|
|
ViewInfo.CheckLayout(EncodeDate(AYear, 1, 1))
|
|
else
|
|
begin
|
|
AMonth := AYear mod (12 div AMonthCount) * AMonthCount + 1;
|
|
AYear := AYear div (12 div AMonthCount);
|
|
ANavigation.FCurrentAnchor := EncodeDate(AYear, AMonth, 1);
|
|
end;
|
|
scLineUp, scPageUp:
|
|
ANavigation.GotoNextPage(False);
|
|
scLineDown, scPageDown:
|
|
ANavigation.GotoNextPage(True);
|
|
end;
|
|
ViewInfo.CheckLayout(ANavigation.FCurrentAnchor);
|
|
AScrollPos := GetScrollPos;
|
|
end;
|
|
|
|
procedure TcxSchedulerYearView.SelectedDaysChanged;
|
|
begin
|
|
if SelectedDays.Count > 0 then
|
|
ViewInfo.CheckLayout(SelectedDays[0]);
|
|
end;
|
|
|
|
procedure TcxSchedulerYearView.SetGroupingKind(AValue: TcxSchedulerGroupingKind);
|
|
begin
|
|
inherited SetGroupingKind(gkNone);
|
|
end;
|
|
|
|
function TcxSchedulerYearView.GetHitTest: TcxSchedulerYearViewHitTest;
|
|
begin
|
|
Result := TcxSchedulerYearViewHitTest(inherited HitTest);
|
|
end;
|
|
|
|
function TcxSchedulerYearView.GetNavigation: TcxSchedulerYearViewNavigation;
|
|
begin
|
|
Result := TcxSchedulerYearViewNavigation(Controller.Navigation);
|
|
end;
|
|
|
|
function TcxSchedulerYearView.GetViewInfo: TcxSchedulerYearViewViewInfo;
|
|
begin
|
|
Result := TcxSchedulerYearViewViewInfo(inherited ViewInfo);
|
|
end;
|
|
|
|
function TcxSchedulerYearView.GetYear: Word;
|
|
begin
|
|
Result := YearOf(inherited GetFirstVisibleDate);
|
|
end;
|
|
|
|
procedure TcxSchedulerYearView.SetAllDayEventsOnly(AValue: Boolean);
|
|
begin
|
|
if FAllDayEventsOnly <> AValue then
|
|
begin
|
|
FAllDayEventsOnly := AValue;
|
|
Changed;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerYearView.SetMaxSelectedDaysCount(
|
|
AValue: Integer);
|
|
begin
|
|
AValue := Max(0, AValue);
|
|
if AValue <> FMaxSelectedDaysCount then
|
|
begin
|
|
FMaxSelectedDaysCount := AValue;
|
|
Changed;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerYearView.SetMonthHeaderPopupMenu(
|
|
AValue: TcxSchedulerMonthHeaderPopupMenu);
|
|
begin
|
|
FMonthHeaderPopupMenu.Assign(AValue);
|
|
end;
|
|
|
|
procedure TcxSchedulerYearView.SetScale(AValue: Integer);
|
|
begin
|
|
if (AValue <> FScale) and (AValue in [3, 6, 12]) then
|
|
begin
|
|
FScale := AValue;
|
|
Changed;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerYearView.SetStyles(AValue: TcxSchedulerYearViewStyles);
|
|
begin
|
|
FStyles.Assign(AValue);
|
|
end;
|
|
|
|
{ TcxSchedulerYearViewAdapter }
|
|
|
|
function TcxSchedulerYearViewAdapter.QueryInterface(
|
|
const IID: TGUID; out Obj): HResult; stdcall;
|
|
begin
|
|
if GetInterface(IID, Obj) then
|
|
Result := 0
|
|
else
|
|
Result := E_NOINTERFACE;
|
|
end;
|
|
|
|
function TcxSchedulerYearViewAdapter._AddRef: Integer;
|
|
begin
|
|
Result := -1;
|
|
end;
|
|
|
|
function TcxSchedulerYearViewAdapter._Release: Integer;
|
|
begin
|
|
Result := -1;
|
|
end;
|
|
|
|
function TcxSchedulerYearViewAdapter.GetDayCountPerPage: Integer;
|
|
begin
|
|
Result := MaxYearViewWeekDays;
|
|
end;
|
|
|
|
function TcxSchedulerYearViewAdapter.GetFirstMonth: Integer;
|
|
var
|
|
AYear, AMonth, ADay: Word;
|
|
AMonthCount: Integer;
|
|
ACurrentAnchor: TDateTime;
|
|
begin
|
|
if PredefinedCurrentAnchor <> 0 then
|
|
ACurrentAnchor := PredefinedCurrentAnchor
|
|
else
|
|
ACurrentAnchor := TcxSchedulerCustomViewViewInfoAccess(TcxSchedulerYearView(View).ViewInfo).FSelectedDays[0];
|
|
PredefinedCurrentAnchor := 0;
|
|
DecodeDate(ACurrentAnchor, AYear, AMonth, ADay);
|
|
AMonthCount := GetMonthCount;
|
|
Result := 1;
|
|
while Result + AMonthCount <= AMonth do
|
|
Inc(Result, AMonthCount);
|
|
end;
|
|
|
|
function TcxSchedulerYearViewAdapter.GetMonthCount: Integer;
|
|
begin
|
|
Result := TcxSchedulerYearView(View).Scale;
|
|
end;
|
|
|
|
function TcxSchedulerYearViewAdapter.GetShowMonthHeaders: Boolean;
|
|
begin
|
|
Result := True;
|
|
end;
|
|
|
|
function TcxSchedulerYearViewAdapter.GetShowWeekDayHeaders: Boolean;
|
|
begin
|
|
Result := True;
|
|
end;
|
|
|
|
function TcxSchedulerYearViewAdapter.GetStartDayIndex: Integer;
|
|
begin
|
|
Result := 0;
|
|
end;
|
|
|
|
{ TcxSchedulerMonthHeaderPopupMenu }
|
|
|
|
constructor TcxSchedulerMonthHeaderPopupMenu.Create(AScheduler: TcxCustomScheduler);
|
|
begin
|
|
inherited Create(AScheduler);
|
|
FItems := [mhpmiNewEvent, mhpmiNewAllDayEvent, mhpmiNewReccuringEvent,
|
|
mhpmiFullYear, mhpmiHalfYear, mhpmiQuarter];
|
|
end;
|
|
|
|
procedure TcxSchedulerMonthHeaderPopupMenu.Assign(Source: TPersistent);
|
|
begin
|
|
inherited Assign(Source);
|
|
if Source is TcxSchedulerMonthHeaderPopupMenu then
|
|
begin
|
|
Items := TcxSchedulerMonthHeaderPopupMenu(Source).Items;
|
|
OnClick := TcxSchedulerMonthHeaderPopupMenu(Source).OnClick;
|
|
OnPopup := TcxSchedulerMonthHeaderPopupMenu(Source).OnPopup;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerMonthHeaderPopupMenu.Execute(AItem: TcxSchedulerMonthHeaderPopupMenuItem);
|
|
begin
|
|
ExecuteCommand(Ord(AItem));
|
|
end;
|
|
|
|
function TcxSchedulerMonthHeaderPopupMenu.GetMenuItem(AItem: TcxSchedulerMonthHeaderPopupMenuItem): TMenuItem;
|
|
begin
|
|
Result := FindItemByCommand(Root, Ord(AItem));
|
|
end;
|
|
|
|
procedure TcxSchedulerMonthHeaderPopupMenu.CreateItems;
|
|
|
|
function GetChecked(ACommand: Integer): Boolean;
|
|
var
|
|
AIndex: Integer;
|
|
begin
|
|
Result := False;
|
|
AIndex := ACommand - Ord(mhpmiFullYear);
|
|
if (AIndex >= 0) and (AIndex <= 2) then
|
|
Result := YearView.Scale = YearScales[AIndex];
|
|
end;
|
|
|
|
procedure CreateRulerItem(const ACaption: string;
|
|
AItem: TcxSchedulerMonthHeaderPopupMenuItem);
|
|
var
|
|
ACommand: Integer;
|
|
begin
|
|
if AItem in Items then
|
|
begin
|
|
ACommand := Ord(AItem);
|
|
CreateSubItem(Root, ACaption, ACommand, -1, True, GetChecked(ACommand));
|
|
end;
|
|
end;
|
|
|
|
begin
|
|
CreateNewEventItems(mhpmiNewEvent in FItems, mhpmiNewAllDayEvent in FItems,
|
|
mhpmiNewReccuringEvent in FItems, Ord(mhpmiNewEvent), Ord(mhpmiNewAllDayEvent),
|
|
Ord(mhpmiNewReccuringEvent));
|
|
if Items * [mhpmiFullYear, mhpmiHalfYear, mhpmiQuarter] <> [] then
|
|
begin
|
|
AddValidSeparator(Root);
|
|
CreateRulerItem(cxGetResourceString(@scxpmFullYear), mhpmiFullYear);
|
|
CreateRulerItem(cxGetResourceString(@scxpmHalfYear), mhpmiHalfYear);
|
|
CreateRulerItem(cxGetResourceString(@scxpmQuarter), mhpmiQuarter);
|
|
end;
|
|
end;
|
|
|
|
function TcxSchedulerMonthHeaderPopupMenu.GetYearView: TcxSchedulerYearView;
|
|
begin
|
|
Result := Scheduler.CurrentView as TcxSchedulerYearView;
|
|
end;
|
|
|
|
procedure TcxSchedulerMonthHeaderPopupMenu.DoExecute(ACommand: Integer);
|
|
var
|
|
AIndex: Integer;
|
|
begin
|
|
if ACommand in [Ord(mhpmiNewEvent), Ord(mhpmiNewAllDayEvent), Ord(mhpmiNewReccuringEvent)] then
|
|
inherited DoExecute(ACommand)
|
|
else
|
|
begin
|
|
AIndex := ACommand - Ord(mhpmiFullYear);
|
|
if AIndex in [0..2] then
|
|
YearView.Scale := YearScales[AIndex];
|
|
end;
|
|
end;
|
|
|
|
function TcxSchedulerMonthHeaderPopupMenu.DoOnClick(ACommand: Integer): Boolean;
|
|
begin
|
|
Result := False;
|
|
if Assigned(FOnClick) then
|
|
FOnClick(Self, TcxSchedulerMonthHeaderPopupMenuItem(ACommand), Result);
|
|
end;
|
|
|
|
function TcxSchedulerMonthHeaderPopupMenu.DoOnPopup: Boolean;
|
|
begin
|
|
Result := False;
|
|
if Assigned(FOnPopup) then
|
|
FOnPopup(Self, InternalMenu, Result);
|
|
end;
|
|
|
|
function TcxSchedulerMonthHeaderPopupMenu.IsValidCommand(ACommand: Integer): Boolean;
|
|
begin
|
|
Result := (ACommand >= Ord(mhpmiNewEvent)) and (ACommand <= Ord(mhpmiQuarter));
|
|
end;
|
|
|
|
end.
|