lcl-cocoa: restoring the items checked status after the sort, if WS needs some extra assistance for that. bug #39121. potential resolution for #38137

git-svn-id: trunk@65351 -
This commit is contained in:
dmitry 2021-07-03 01:02:04 +00:00
parent 210f33e2b0
commit 0e0ef8c3ca
3 changed files with 47 additions and 0 deletions

View File

@ -1038,6 +1038,8 @@ procedure TCustomListView.SortWithParams(ACompareFunc: TListSortCompare);
var
FSavedSelection: TFPList;
FSavedFocused: TListItem;
FSavedChecked: TFPList;
FSavedCheckItem: TListItem;
i: Integer;
AItemIndex: Integer;
begin
@ -1048,6 +1050,7 @@ begin
begin
Include(FFlags, lffItemsSorting);
FSavedSelection := TFPList.Create;
FSavedChecked := nil;
try
if (ItemIndex >= 0) then
FSavedFocused := Items[ItemIndex]
@ -1061,6 +1064,15 @@ begin
if Items[i].Selected and (Items[i] <> Selected) then
FSavedSelection.Add(Items[i]);
end;
if (TWSCustomListViewClass(WidgetSetClass).RestoreItemCheckedAfterSort(Self))
and Items.WSUpdateAllowed
and not OwnerData then
begin
FSavedChecked := TFPList.Create;
for i := 0 to Items.Count - 1 do
if Items[i].Checked then
FSavedChecked.Add(Items[i]);
end;
Items.FCacheIndex := -1;
Items.FCacheItem := nil;
@ -1084,6 +1096,19 @@ begin
TWSCustomListViewClass(WidgetSetClass).ItemSetState(Self,
AItemIndex, Items[AItemIndex], lisSelected, True);
end;
if FSavedChecked <> nil then
begin
for i := 0 to FSavedChecked.Count - 1 do
begin
FSavedCheckItem := TListItem( FSavedChecked[i] );
// todo: this is inefficient, because FSavedCheckItem.Index must be called again
TWSCustomListViewClass(WidgetSetClass).ItemSetChecked(Self,
FSavedCheckItem.Index, FSavedCheckItem, True);
end;
FSavedChecked.Free;
end;
end;
finally
FreeThenNil(FSavedSelection);

View File

@ -202,6 +202,7 @@ type
class procedure SetScrollBars(const ALV: TCustomListView; const AValue: TScrollStyle); override;
class procedure SetSort(const ALV: TCustomListView; const {%H-}AType: TSortType; const {%H-}AColumn: Integer;
const {%H-}ASortDirection: TSortDirection); override;
class function RestoreItemCheckedAfterSort(const ALV: TCustomListView): Boolean; override;
(*class procedure SetViewOrigin(const ALV: TCustomListView; const AValue: TPoint); override;
class procedure SetViewStyle(const ALV: TCustomListView; const AValue: TViewStyle); override;*)
end;
@ -1675,9 +1676,14 @@ class procedure TCocoaWSCustomListView.SetSort(const ALV: TCustomListView;
const ASortDirection: TSortDirection);
var
lTableLV: TCocoaTableListView;
lCocoaLV: TCocoaListView;
lNSColumn: NSTableColumn;
Cb: TLCLListViewCallback;
begin
if not CheckColumnParams(lTableLV, lNSColumn, ALV, AColumn) then Exit;
if not CheckParamsCb(lCocoaLV, lTableLV, cb, ALV) then Exit;
cb.checkedIdx.removeAllIndexes;
lTableLV.reloadData();
{ //todo:
lNSColumn.setSortDescriptorPrototype(
@ -1689,6 +1695,12 @@ begin
);}
end;
class function TCocoaWSCustomListView.RestoreItemCheckedAfterSort(
const ALV: TCustomListView): Boolean;
begin
Result:=true;
end;
{ TCocoaWSProgressBar }
class function TCocoaWSProgressBar.CreateHandle(const AWinControl: TWinControl;

View File

@ -174,6 +174,10 @@ type
const ASortDirection: TSortDirection); virtual;
class procedure SetViewOrigin(const ALV: TCustomListView; const AValue: TPoint); virtual;
class procedure SetViewStyle(const ALV: TCustomListView; const Avalue: TViewStyle); virtual;
// if returns true, then LCL will call SetItemChecked after calling SetSort
// for every item previously checked. Only widgetsets that don't support native sort
// AND/OR that don't support native checkboxes should have this method return true
class function RestoreItemCheckedAfterSort(const ALV: TCustomListView): Boolean; virtual;
end;
TWSCustomListViewClass = class of TWSCustomListView;
@ -781,6 +785,12 @@ class procedure TWSCustomListView.SetViewStyle(const ALV: TCustomListView; const
begin
end;
class function TWSCustomListView.RestoreItemCheckedAfterSort(const ALV: TCustomListView
): Boolean;
begin
Result := false;
end;
class procedure TWSCustomListView.SetItemsCount(const ALV: TCustomListView; const Avalue: Integer);
begin
end;