From 2062b0bb22176894e1887060758d15e349570271 Mon Sep 17 00:00:00 2001 From: wp_xxyyzz Date: Fri, 19 Aug 2022 21:32:56 +0000 Subject: [PATCH] tvplanit: Add "check/uncheck all" checkbox to header of the grid in the import preview form. git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@8399 8e941d3f-bd1b-0410-a28a-d453659cc2b4 --- .../tvplanit/source/vpimportpreview.lfm | 56 +------ .../tvplanit/source/vpimportpreview.lrj | 3 - .../tvplanit/source/vpimportpreview.pas | 157 +++++++++++++++++- .../source/vpimportpreview_icalevent.pas | 4 +- .../source/vpimportpreview_icaltask.pas | 5 +- .../tvplanit/source/vpimportpreview_vcard.pas | 3 + 6 files changed, 167 insertions(+), 61 deletions(-) diff --git a/components/tvplanit/source/vpimportpreview.lfm b/components/tvplanit/source/vpimportpreview.lfm index 911a56baf..33aa8c4a0 100644 --- a/components/tvplanit/source/vpimportpreview.lfm +++ b/components/tvplanit/source/vpimportpreview.lfm @@ -2,68 +2,26 @@ object VpImportPreviewForm: TVpImportPreviewForm Left = 327 Height = 295 Top = 127 - Width = 603 + Width = 634 Caption = 'VpImportPreviewForm' ClientHeight = 295 - ClientWidth = 603 - LCLVersion = '2.3.0.0' - object Grid: TDrawGrid - Left = 0 - Height = 258 - Top = 0 - Width = 603 - Align = alClient - AutoFillColumns = True - ColCount = 3 - Columns = < - item - Alignment = taCenter - ButtonStyle = cbsCheckboxColumn - SizePriority = 0 - Title.Caption = '' - Width = 33 - end - item - ReadOnly = True - Title.Caption = 'Title' - Width = 410 - end - item - ButtonStyle = cbsPickList - SizePriority = 0 - Title.Caption = 'Title' - Width = 160 - end> - ExtendedSelect = False - FixedCols = 0 - Options = [goFixedVertLine, goFixedHorzLine, goVertLine, goHorzLine, goRangeSelect, goColSizing, goEditing, goSmoothScroll] - TabOrder = 0 - OnDrawCell = GridDrawCell - OnGetCheckboxState = GridGetCheckboxState - OnPrepareCanvas = GridPrepareCanvas - OnSetCheckboxState = GridSetCheckboxState - ColWidths = ( - 33 - 410 - 160 - ) - end + ClientWidth = 634 object ButtonPanel: TPanel Left = 6 Height = 25 Top = 264 - Width = 591 + Width = 622 Align = alBottom AutoSize = True BorderSpacing.Around = 6 BevelOuter = bvNone ClientHeight = 25 - ClientWidth = 591 - TabOrder = 1 + ClientWidth = 622 + TabOrder = 0 object btnExecute: TButton AnchorSideTop.Control = ButtonPanel AnchorSideRight.Control = btnCancel - Left = 375 + Left = 406 Height = 25 Top = 0 Width = 141 @@ -77,7 +35,7 @@ object VpImportPreviewForm: TVpImportPreviewForm AnchorSideTop.Control = ButtonPanel AnchorSideRight.Control = ButtonPanel AnchorSideRight.Side = asrBottom - Left = 516 + Left = 547 Height = 25 Top = 0 Width = 75 diff --git a/components/tvplanit/source/vpimportpreview.lrj b/components/tvplanit/source/vpimportpreview.lrj index b3013e29c..2712d561a 100644 --- a/components/tvplanit/source/vpimportpreview.lrj +++ b/components/tvplanit/source/vpimportpreview.lrj @@ -1,8 +1,5 @@ {"version":1,"strings":[ {"hash":185343357,"name":"tvpimportpreviewform.caption","sourcebytes":[86,112,73,109,112,111,114,116,80,114,101,118,105,101,119,70,111,114,109],"value":"VpImportPreviewForm"}, -{"hash":4294967295,"name":"tvpimportpreviewform.grid.columns[0].title.caption","sourcebytes":[],"value":""}, -{"hash":5966629,"name":"tvpimportpreviewform.grid.columns[1].title.caption","sourcebytes":[84,105,116,108,101],"value":"Title"}, -{"hash":5966629,"name":"tvpimportpreviewform.grid.columns[2].title.caption","sourcebytes":[84,105,116,108,101],"value":"Title"}, {"hash":202226323,"name":"tvpimportpreviewform.btnexecute.caption","sourcebytes":[73,109,112,111,114,116,32,99,104,101,99,107,101,100,32,105,116,101,109,115],"value":"Import checked items"}, {"hash":77089212,"name":"tvpimportpreviewform.btncancel.caption","sourcebytes":[67,97,110,99,101,108],"value":"Cancel"} ]} diff --git a/components/tvplanit/source/vpimportpreview.pas b/components/tvplanit/source/vpimportpreview.pas index 2fb13c0c4..db63c0e50 100644 --- a/components/tvplanit/source/vpimportpreview.pas +++ b/components/tvplanit/source/vpimportpreview.pas @@ -9,12 +9,22 @@ uses Forms, Controls, Dialogs, Grids, ExtCtrls, StdCtrls, VpBaseDS; type + { TVpImportGrid } + + TVpImportGrid = class(TDrawGrid) + protected + procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X,Y: Integer); override; + public + procedure DrawCellCheckboxBitmaps(const ACol, ARow: Integer; const ARect: TRect); + + end; + + { TVpImportPreviewForm } TVpImportPreviewForm = class(TForm) btnExecute: TButton; btnCancel: TButton; - Grid: TDrawGrid; ButtonPanel: TPanel; procedure GridDrawCell(Sender: TObject; aCol, aRow: Integer; aRect: TRect; {%H-}aState: TGridDrawState); @@ -26,10 +36,13 @@ type const Value: TCheckboxState); private FDatastore: TVpCustomDatastore; + FGrid: TVpImportGrid; procedure SetDatastore(const AValue: TVpCustomDatastore); protected FItems: TFPList; + FCol0CheckState: TCheckboxState; + FLockCheckState: Integer; procedure CalcRowHeights; function GetCellText({%H-}ACol, {%H-}ARow: Integer): String; virtual; procedure PrepareItems; virtual; @@ -41,6 +54,7 @@ type function Execute: Boolean; function IsChecked({%H-}ARow: Integer): Boolean; virtual; property Datastore: TVpCustomDatastore read FDatastore write SetDatastore; + property Grid: TVpImportGrid read FGrid; end; @@ -52,14 +66,105 @@ implementation {$R *.lfm} uses - LCLIntf, LCLType; + LCLIntf, LCLType, Themes; + +{ TVpImportGrid } + +procedure TVpImportGrid.DrawCellCheckboxBitmaps(const ACol, ARow: Integer; + const ARect: TRect); +var + checkboxState: TCheckboxState; +begin + checkboxState := cbUnchecked; + GetCheckBoxState(ACol, ARow, checkboxState); + DrawGridCheckboxBitmaps(ACol, ARow, ARect, checkboxState); +end; + +procedure TVpImportGrid.MouseUp(Button: TMouseButton; Shift: TShiftState; + X,Y: Integer); +var + cell: TPoint; + R: TRect; + lSize: TSize; + Details: TThemedElementDetails; + checkboxState: TCheckboxState; +begin + inherited; + cell := MouseToCell(Point(x,y)); + if (cell.X = 0) and (cell.Y = 0) then + begin + R := CellRect(cell.X, cell.Y); + details := ThemeServices.GetElementDetails(tbCheckBoxCheckedNormal); + lSize := ThemeServices.GetDetailSize(Details); + lSize.cx := MulDiv(lSize.cx, Font.PixelsPerInch, Screen.PixelsPerInch); + lSize.cy := MulDiv(lSize.cy, Font.PixelsPerInch, Screen.PixelsPerInch); + OffsetRect(R, (R.Left+R.Right-lSize.CX) div 2, (R.Top+R.Bottom-lSize.CY) div 2); + R.Right := R.Left + lSize.CX; + R.Bottom := R.Top + lSize.CY; + if PtInRect(R, Point(x, y)) then + begin + checkboxState := cbGrayed; + GetCheckboxState(cell.x, cell.Y, checkboxState); + case checkboxState of + cbChecked: + SetCheckboxState(cell.X, cell.Y, cbUnchecked); + cbUnchecked, + cbGrayed: + SetCheckboxState(cell.X, cell.Y, cbChecked); + end; + end; + InvalidateCell(cell.X, cell.Y); + end; +end; + { TVpImportPreviewForm } constructor TVpImportPreviewForm.Create(AOwner: TComponent); begin inherited; - Grid.Options := Grid.Options + [goEditing, goRowSelect, goThumbTracking]; + + FCol0CheckState := cbChecked; + + FGrid := TVpImportGrid.Create(self); + with FGrid do + begin + Align := alClient; + AutoFillColumns := true; + Columns.Clear; + with Columns.Add do + begin + Alignment := taCenter; + ButtonStyle := cbsCheckboxColumn; + SizePriority := 0; + Title.Caption := ''; + Width := 10; //33; + end; + with Columns.Add do + begin + ReadOnly := true; + SizePriority := 2; + Title.Caption := ''; + end; + with Columns.Add do + begin + ButtonStyle := cbsPickList; + SizePriority := 0; + Title.Caption := ''; + Width := 160; + end; + ExtendedSelect := false; + FixedCols := 0; + Options := [goEditing, goRowSelect, goThumbTracking, + goFixedVertLine, goFixedHorzLine, goVertLine, goHorzLine, + goRangeSelect, goColSizing, goSmoothScroll]; + OnDrawCell := @GridDrawCell; + OnGetCheckboxState := @GridGetCheckboxState; + OnPrepareCanvas := @GridPrepareCanvas; + OnSetCheckboxState := @GridSetCheckboxState; + Parent := self; + end; + FItems := TFPList.Create; end; @@ -101,8 +206,24 @@ end; { Marks the item in the specified row to be accepted for import. To be overridden by ancestors. } procedure TVpImportPreviewForm.CheckItem(ARow: Integer; AChecked: Boolean); +var + r: Integer; + allcheckstate, cbs: TCheckboxState; begin - // + if ARow > 0 then + begin + Grid.GetCheckboxState(0, 1, allcheckstate{%H-}); + for r := 2 to Grid.RowCount-1 do + begin + Grid.GetCheckboxState(0, r, cbs{%H-}); + if cbs <> allcheckstate then + begin + FCol0Checkstate := cbGrayed; + exit; + end; + FCol0CheckState := allcheckstate; + end; + end; end; function TVpImportPreviewForm.Execute: Boolean; @@ -124,14 +245,22 @@ var R: TRect; begin R := ARect; - InflateRect(R, -varCellPadding, - varCellPadding); - s := GetCellText(ACol, ARow); - Grid.Canvas.TextRect(R, R.Left, R.Top, s); + if (ACol = 0) and (ARow = 0) then + Grid.DrawCellCheckboxBitmaps(aCol, aRow, R) + else + begin + InflateRect(R, -varCellPadding, - varCellPadding); + s := GetCellText(ACol, ARow); + Grid.Canvas.TextRect(R, R.Left, R.Top, s); + end; end; procedure TVpImportPreviewForm.GridGetCheckboxState(Sender: TObject; ACol, ARow: Integer; var Value: TCheckboxState); begin + if (ARow = 0) and (ACol = 0) then + Value := FCol0CheckState + else if ARow >= Grid.FixedRows then begin if IsChecked(ARow) then @@ -157,9 +286,23 @@ end; procedure TVpImportPreviewForm.GridSetCheckboxState(Sender: TObject; ACol, ARow: Integer; const Value: TCheckboxState); +var + r: Integer; begin + if (ARow = 0) and (ACol = 0) then + begin + FCol0CheckState := Value; + if Value <> cbGrayed then + for r := Grid.FixedRows to Grid.RowCount-1 do + CheckItem(r, Value = cbChecked); + Grid.Invalidate; + end + else if ARow >= Grid.FixedRows then + begin CheckItem(ARow, Value = cbChecked); + Grid.Invalidate; + end; end; { Returns that the item in the given row should be included in the import process. diff --git a/components/tvplanit/source/vpimportpreview_icalevent.pas b/components/tvplanit/source/vpimportpreview_icalevent.pas index 29df13715..f1750f7fb 100644 --- a/components/tvplanit/source/vpimportpreview_icalevent.pas +++ b/components/tvplanit/source/vpimportpreview_icalevent.pas @@ -65,8 +65,10 @@ begin if ARow < Grid.FixedRows then exit; item := TVpICalEntry(FItems[ARow - Grid.FixedRows]); - if item <> nil then + if item <> nil then begin item.Checked := AChecked; + inherited; + end; end; function TVpImportPreviewICalEventForm.GetCellText(ACol, ARow: Integer): String; diff --git a/components/tvplanit/source/vpimportpreview_icaltask.pas b/components/tvplanit/source/vpimportpreview_icaltask.pas index c8dab878e..d008bbd60 100644 --- a/components/tvplanit/source/vpimportpreview_icaltask.pas +++ b/components/tvplanit/source/vpimportpreview_icaltask.pas @@ -66,7 +66,10 @@ begin exit; item := TVpICalEntry(FItems[ARow - Grid.FixedRows]); if item <> nil then - item.Checked := AChecked; + begin + item.Checked := AChecked; + inherited; + end; end; function TVpImportPreviewICalTaskForm.GetCellText(ACol, ARow: Integer): String; diff --git a/components/tvplanit/source/vpimportpreview_vcard.pas b/components/tvplanit/source/vpimportpreview_vcard.pas index e3f9c3212..98a4c04a7 100644 --- a/components/tvplanit/source/vpimportpreview_vcard.pas +++ b/components/tvplanit/source/vpimportpreview_vcard.pas @@ -61,7 +61,10 @@ begin exit; card := TVpVCard(FItems[ARow - Grid.FixedRows]); if card <> nil then + begin card.Checked := AChecked; + inherited; + end; end; function TVpImportPreviewVCardForm.GetCellText(ACol, ARow: Integer): String;