Cocoa/ListView: in vsReport, fix long-standing issues, Merge branch 'cocoa/listview'

This commit is contained in:
rich2014 2024-07-27 00:35:48 +08:00
commit 4146e268cc
2 changed files with 97 additions and 35 deletions

View File

@ -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;
@ -475,13 +476,23 @@ end;
function TCocoaTableListView.lclGetLabelRect(ARow, ACol: Integer;
const BoundsRect: TRect): TRect;
begin
Result := BoundsRect;
Result:= BoundsRect;
Result.Top:= Result.Top - 2;
Result.Height:= Result.Height + 4;
if self.isImagesInCell then begin
Result.Left:= Result.Left + BoundsRect.Height;
end;
end;
function TCocoaTableListView.lclGetIconRect(ARow, ACol: Integer;
const BoundsRect: TRect): TRect;
begin
Result := BoundsRect;
if self.isImagesInCell then begin
Result:= BoundsRect;
Result.Width:= Result.Height;
end else begin
Result:= TRect.Empty;
end;
end;
procedure TCocoaTableListView.lclInsDelRow(Arow: Integer; inserted: Boolean);
@ -515,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;
@ -575,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);
@ -652,16 +669,15 @@ begin
Result := 0;
end;
// TListView in LCL already supports editing, return False to avoid conflicts
function TCocoaTableListView.tableView_shouldEditTableColumn_row(tableView: NSTableView; tableColumn: NSTableColumn; row: NSInteger): Boolean;
begin
Result := not readOnly;
Result:= False;
end;
function TCocoaTableListView.selectionShouldChangeInTableView(
tableView: NSTableView): Boolean;
begin
if Assigned(beforeSel) then beforeSel.release;
beforeSel := (NSIndexSet.alloc).initWithIndexSet(selectedRowIndexes);
Result := true;
end;
@ -863,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;
@ -1005,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;

View File

@ -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;
@ -895,23 +906,38 @@ procedure TCocoaWSListView_TableViewHandler.SetDefaultItemHeight(
const AValue: Integer);
begin
if AValue > 0 then
_tableView.setRowHeight(AValue);
_tableView.CustomRowHeight:= AValue;
// setRowSizeStyle could be used here but is available only in 10.7+
end;
procedure TCocoaWSListView_TableViewHandler.SetImageList(
const AList: TListViewImageList; const AValue: TCustomImageListResolution);
var
lclcb: TLCLListViewCallback;
lvil: TListViewImageList;
spacing: NSSize;
begin
lclcb:= getCallback;
if NOT Assigned(lclcb) then
Exit;
if NOT lclcb.GetImageListType(lvil) then
Exit;
if AList <> lvil then
Exit;
_tableView.lclSetImagesInCell(Assigned(AValue));
if NOT Assigned(AValue) then
Exit;
if AValue.Height < _tableView.rowHeight-2 then
Exit;
spacing:= _tableView.intercellSpacing;
spacing.height:= _tableView.rowHeight / 3 + 2;
spacing.height:= AValue.Height / 3 + 2;
if spacing.height < 6 then
spacing.height:= 6
else if spacing.height > 12 then
spacing.height:= 12;
_tableView.setIntercellSpacing( spacing );
end;
@ -981,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(
@ -1079,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
@ -2718,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;