From ad8dd1dba2a943320f59d51924d89c941a2331f7 Mon Sep 17 00:00:00 2001 From: rich2014 Date: Sat, 27 Jul 2024 00:34:54 +0800 Subject: [PATCH] Cocoa/ListView: in vsReport, fix the issues related to Multi Selection --- lcl/interfaces/cocoa/cocoatables.pas | 45 +++++++++++++++++------ lcl/interfaces/cocoa/cocoawscomctrls.pas | 47 ++++++++++++++++-------- 2 files changed, 64 insertions(+), 28 deletions(-) diff --git a/lcl/interfaces/cocoa/cocoatables.pas b/lcl/interfaces/cocoa/cocoatables.pas index 21db8b653f..98db343a95 100644 --- a/lcl/interfaces/cocoa/cocoatables.pas +++ b/lcl/interfaces/cocoa/cocoatables.pas @@ -73,10 +73,9 @@ type public callback: IListViewCallback; + selectingByProgram: Boolean; readOnly: Boolean; - beforeSel : NSIndexSet; - isImagesInCell: Boolean; isFirstColumnCheckboxes: Boolean; isOwnerDraw : Boolean; @@ -93,6 +92,8 @@ type // Own methods, mostly convenience methods function getIndexOfColumn(ACol: NSTableColumn): Integer; message 'getIndexOfColumn:'; procedure reloadDataForRow_column(ARow, ACol: NSInteger); message 'reloadDataForRow:column:'; + procedure selectRowIndexesByProgram( indexes: NSIndexSet ); + message 'selectRowIndexesByProgram:'; function initWithFrame(frameRect: NSRect): id; override; procedure dealloc; override; @@ -525,7 +526,6 @@ end; procedure TCocoaTableListView.dealloc; begin //if Assigned(Items) then FreeAndNil(Items); - if Assigned(beforeSel) then beforeSel.release; if Assigned(smallimages) then smallimages.release; // all contents is released automatically inherited dealloc; end; @@ -585,6 +585,13 @@ begin reloadDataForRowIndexes_columnIndexes(lRowSet, lColSet); end; +procedure TCocoaTableListView.selectRowIndexesByProgram( indexes: NSIndexSet ); +begin + self.selectingByProgram:= True; + self.selectRowIndexes_byExtendingSelection( indexes, False ); + self.selectingByProgram:= False; +end; + function TCocoaTableListView.initWithFrame(frameRect: NSRect): id; begin Result:=inherited initWithFrame(frameRect); @@ -671,8 +678,6 @@ end; function TCocoaTableListView.selectionShouldChangeInTableView( tableView: NSTableView): Boolean; begin - if Assigned(beforeSel) then beforeSel.release; - beforeSel := (NSIndexSet.alloc).initWithIndexSet(selectedRowIndexes); Result := true; end; @@ -874,16 +879,26 @@ var Unsel : NSIndexSet; rm : NSIndexSet; ad : NSIndexSet; + selectionIndexSet: NSMutableIndexSet; + lclcb: TLCLListViewCallback; begin - if Assigned(callback) then - begin - CompareIndexSets(beforeSel, selectedRowIndexes, rm, ad); + if NOT Assigned(callback) then + Exit; - NewSel := Self.selectedRow(); - callback.selectionChanged(NewSel, ad, rm); + lclcb:= TLCLListViewCallback( callback.GetCallbackObject ); - beforeSel.release; - beforeSel := nil; + if TCocoaListView(lclcb.Owner).initializing then + Exit; + + selectionIndexSet:= lclcb.selectionIndexSet; + CompareIndexSets(selectionIndexSet, selectedRowIndexes, rm, ad); + + NewSel := Self.selectedRow(); + callback.selectionChanged(NewSel, ad, rm); + + if NOT self.selectingByProgram then begin + selectionIndexSet.removeAllIndexes; + selectionIndexSet.addIndexes( self.selectedRowIndexes ); end; end; @@ -1016,8 +1031,14 @@ begin end; procedure TCellCocoaTableListView.backend_reloadData; +var + lclcb: TLCLListViewCallback; begin self.reloadData; + if Assigned(self.callback) then begin + lclcb:= TLCLListViewCallback( self.callback.GetCallbackObject ); + self.selectRowIndexesByProgram( lclcb.selectionIndexSet ); + end; end; procedure TCellCocoaTableListView.backend_onInit; diff --git a/lcl/interfaces/cocoa/cocoawscomctrls.pas b/lcl/interfaces/cocoa/cocoawscomctrls.pas index 610ad38600..7d80bc4657 100644 --- a/lcl/interfaces/cocoa/cocoawscomctrls.pas +++ b/lcl/interfaces/cocoa/cocoawscomctrls.pas @@ -163,7 +163,6 @@ type TLCLListViewCallback = class(TLCLCommonCallback, IListViewCallback) public listView: TCustomListView; - tempItemsCountDelta : Integer; isSetTextFromWS: Integer; // allows to suppress the notifation about text change // when initiated by Cocoa itself. @@ -382,10 +381,12 @@ type private _listView: TCocoaListView; _tableView: TCocoaTableListView; + private + function getCallback: TLCLListViewCallback; + procedure doReloadDataAfterDelete( AIndex: PtrInt ); public constructor Create( listView: TCocoaListView ); function getColumnFromIndex( const AIndex: Integer ): NSTableColumn; - function getCallback: TLCLListViewCallback; public // Column procedure ColumnDelete( const AIndex: Integer ); override; @@ -439,7 +440,7 @@ type _collectionView: TCocoaCollectionView; private function getCallback: TLCLListViewCallback; - procedure doReloadDataAfterDelete( AIndex: PtrInt); + procedure doReloadDataAfterDelete( AIndex: PtrInt ); public constructor Create( listView: TCocoaListView ); public @@ -523,6 +524,20 @@ begin Result:= TLCLListViewCallback( _tableView.lclGetCallback.GetCallbackObject ); end; +procedure TCocoaWSListView_TableViewHandler.doReloadDataAfterDelete( AIndex: PtrInt); +var + lclcb : TLCLListViewCallback; +begin + lclcb:= getCallback; + if NOT Assigned(lclcb) then + Exit; + + lclcb.checkedIdx.shiftIndexesStartingAtIndex_by( AIndex+1, -1); + lclcb.selectionIndexSet.shiftIndexesStartingAtIndex_by( AIndex+1, -1 ); + _tableView.selectRowIndexesByProgram( lclcb.selectionIndexSet ); + _tableView.lclInsDelRow(AIndex, false); +end; + procedure TCocoaWSListView_TableViewHandler.ColumnDelete( const AIndex: Integer); var @@ -715,17 +730,8 @@ end; procedure TCocoaWSListView_TableViewHandler.ItemDelete(const AIndex: Integer ); -var - lclcb : TLCLListViewCallback; begin - lclcb:= getCallback; - if NOT Assigned(lclcb) then - Exit; - - lclcb.tempItemsCountDelta:= -1; - lclcb.checkedIdx.shiftIndexesStartingAtIndex_by(AIndex, -1); - _tableView.lclInsDelRow(AIndex, false); - lclcb.tempItemsCountDelta := 0; + Application.QueueAsyncCall( doReloadDataAfterDelete, AIndex ); end; function TCocoaWSListView_TableViewHandler.ItemDisplayRect(const AIndex, @@ -783,8 +789,13 @@ begin if NOT Assigned(lclcb) then Exit; + if TCocoaListView(lclcb.Owner).initializing then + Exit; + lclcb.checkedIdx.shiftIndexesStartingAtIndex_by(AIndex, 1); + lclcb.selectionIndexSet.shiftIndexesStartingAtIndex_by( AIndex, 1 ); _tableView.lclInsDelRow(AIndex, true); + _tableView.selectRowIndexesByProgram( lclcb.selectionIndexSet ); _tableView.sizeToFit(); end; @@ -828,7 +839,7 @@ begin begin isSel := _tableView.selectedRowIndexes.containsIndex(row); if AIsSet and not isSel then - _tableView.selectRowIndexes_byExtendingSelection(NSIndexSet.indexSetWithIndex(row),false) + _tableView.selectRowIndexesByProgram( NSIndexSet.indexSetWithIndex(row) ) else if not AIsSet and isSel then _tableView.deselectRow(row); end; @@ -996,8 +1007,12 @@ begin if NOT Assigned(lclcb) then Exit; + if TCocoaListView(lclcb.Owner).initializing then + Exit; + if Assigned(lclcb.checkedIdx) then lclcb.checkedIdx.removeAllIndexes; + lclcb.selectionIndexSet.removeAllIndexes; _tableView.reloadData(); { //todo: lNSColumn.setSortDescriptorPrototype( @@ -1094,7 +1109,7 @@ begin Application.QueueAsyncCall( doReloadDataAfterDelete, AIndex ); end; -procedure TCocoaWSListView_CollectionViewHandler.doReloadDataAfterDelete( AIndex: PtrInt); +procedure TCocoaWSListView_CollectionViewHandler.doReloadDataAfterDelete( AIndex: PtrInt ); var lclcb : TLCLListViewCallback; begin @@ -2733,7 +2748,7 @@ end; function TLCLListViewCallback.ItemsCount: Integer; begin - Result:=listView.Items.Count + tempItemsCountDelta; + Result:= listView.Items.Count; end; function TLCLListViewCallback.GetItemTextAt(ARow, ACol: Integer;