mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-21 21:59:18 +02:00
Cocoa/ListView: fix and improve the selection in various situations with vsIcon Style
This commit is contained in:
parent
ed64d28b68
commit
381bd18471
@ -33,7 +33,8 @@ type
|
|||||||
TCocoaCollectionView = objcclass(
|
TCocoaCollectionView = objcclass(
|
||||||
NSCollectionView,
|
NSCollectionView,
|
||||||
NSCollectionViewDataSourceProtocol,
|
NSCollectionViewDataSourceProtocol,
|
||||||
NSCollectionViewDelegateProtocol_1011 )
|
NSCollectionViewDelegateProtocol_1011,
|
||||||
|
TCocoaListViewBackendControlProtocol )
|
||||||
public
|
public
|
||||||
iconSize: NSSize;
|
iconSize: NSSize;
|
||||||
itemSize: NSSize;
|
itemSize: NSSize;
|
||||||
@ -41,6 +42,11 @@ type
|
|||||||
callback: TLCLListViewCallback;
|
callback: TLCLListViewCallback;
|
||||||
function lclGetCallback: ICommonCallback; override;
|
function lclGetCallback: ICommonCallback; override;
|
||||||
procedure lclClearCallback; override;
|
procedure lclClearCallback; override;
|
||||||
|
|
||||||
|
procedure backend_setCallback( cb: TLCLListViewCallback );
|
||||||
|
procedure backend_reloadData;
|
||||||
|
procedure backend_onInit( lclListView: TCustomListView );
|
||||||
|
public
|
||||||
procedure updateItemValue( indexPath:NSIndexPath; cocoaItem:TCocoaCollectionItem );
|
procedure updateItemValue( indexPath:NSIndexPath; cocoaItem:TCocoaCollectionItem );
|
||||||
message 'updateItemValue:cocoaItem:';
|
message 'updateItemValue:cocoaItem:';
|
||||||
procedure updateItemSize( baseSize: NSSize );
|
procedure updateItemSize( baseSize: NSSize );
|
||||||
@ -197,6 +203,20 @@ begin
|
|||||||
callback:= nil;
|
callback:= nil;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TCocoaCollectionView.backend_setCallback(cb: TLCLListViewCallback);
|
||||||
|
begin
|
||||||
|
self.callback:= cb;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TCocoaCollectionView.backend_reloadData;
|
||||||
|
begin
|
||||||
|
self.reloadData;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TCocoaCollectionView.backend_onInit( lclListView: TCustomListView );
|
||||||
|
begin
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TCocoaCollectionView.updateItemValue(
|
procedure TCocoaCollectionView.updateItemValue(
|
||||||
indexPath:NSIndexPath; cocoaItem: TCocoaCollectionItem );
|
indexPath:NSIndexPath; cocoaItem: TCocoaCollectionItem );
|
||||||
var
|
var
|
||||||
@ -274,8 +294,13 @@ end;
|
|||||||
|
|
||||||
procedure TCocoaCollectionView.reloadData;
|
procedure TCocoaCollectionView.reloadData;
|
||||||
begin
|
begin
|
||||||
inherited reloadData;
|
if NOT TCocoaListView(self.callback.Owner).initializing then begin
|
||||||
restoreFromStableSelection;
|
inherited reloadData;
|
||||||
|
self.cancelPreviousPerformRequestsWithTarget_selector_object(
|
||||||
|
self, ObjcSelector('restoreFromStableSelection'), nil );
|
||||||
|
self.performSelector_withObject_afterDelay(
|
||||||
|
ObjcSelector('restoreFromStableSelection'), nil, 0 );
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TCocoaCollectionView.selectOneItemByIndex(
|
procedure TCocoaCollectionView.selectOneItemByIndex(
|
||||||
@ -370,9 +395,11 @@ var
|
|||||||
begin
|
begin
|
||||||
for indexPath in indexPaths do begin
|
for indexPath in indexPaths do begin
|
||||||
item:= TCocoaCollectionItem( self.itemAtIndexPath(indexPath) );
|
item:= TCocoaCollectionItem( self.itemAtIndexPath(indexPath) );
|
||||||
item.setSelected( True );
|
if Assigned(item) then begin
|
||||||
item.textField.setToolTip( item.textField.stringValue );
|
item.setSelected( True );
|
||||||
item.view.setNeedsDisplay_(True);
|
item.textField.setToolTip( item.textField.stringValue );
|
||||||
|
item.view.setNeedsDisplay_(True);
|
||||||
|
end;
|
||||||
callback.selectOne( indexPath.item, True );
|
callback.selectOne( indexPath.item, True );
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
@ -391,9 +418,11 @@ var
|
|||||||
begin
|
begin
|
||||||
for indexPath in indexPaths do begin
|
for indexPath in indexPaths do begin
|
||||||
item:= TCocoaCollectionItem( self.itemAtIndexPath(indexPath) );
|
item:= TCocoaCollectionItem( self.itemAtIndexPath(indexPath) );
|
||||||
item.setSelected( False );
|
if Assigned(item) then begin
|
||||||
item.textField.setToolTip( nil );
|
item.setSelected( False );
|
||||||
item.view.setNeedsDisplay_(True);
|
item.textField.setToolTip( nil );
|
||||||
|
item.view.setNeedsDisplay_(True);
|
||||||
|
end;
|
||||||
callback.selectOne( indexPath.item, False );
|
callback.selectOne( indexPath.item, False );
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
@ -196,22 +196,6 @@ type
|
|||||||
procedure setButtonType(aType: NSButtonType); override;
|
procedure setButtonType(aType: NSButtonType); override;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ TCellCocoaTableListView }
|
|
||||||
|
|
||||||
TCellCocoaTableListView = objcclass(TCocoaTableListView, NSTableViewDelegateProtocol, NSTableViewDataSourceProtocol)
|
|
||||||
public
|
|
||||||
function tableView_objectValueForTableColumn_row(tableView: NSTableView; tableColumn: NSTableColumn; row: NSInteger): id; message 'tableView:objectValueForTableColumn:row:';
|
|
||||||
procedure tableView_setObjectValue_forTableColumn_row(tableView: NSTableView; object_: id; tableColumn: NSTableColumn; row: NSInteger); message 'tableView:setObjectValue:forTableColumn:row:';
|
|
||||||
function tableView_dataCellForTableColumn_row(tableView: NSTableView; tableColumn: NSTableColumn; row: NSInteger): NSCell; message 'tableView:dataCellForTableColumn:row:';
|
|
||||||
procedure lclInsDelRow(Arow: Integer; inserted: Boolean); override;
|
|
||||||
procedure lclSetColumnAlign(acolumn: NSTableColumn; aalignment: NSTextAlignment); override;
|
|
||||||
end;
|
|
||||||
|
|
||||||
TCellCocoaTableListView1013 = objcclass(TCellCocoaTableListView, NSTableViewDelegateProtocol, NSTableViewDataSourceProtocol)
|
|
||||||
// overriding the highlight color for dark theme
|
|
||||||
procedure highlightSelectionInClipRect(clipRect: NSRect); override;
|
|
||||||
end;
|
|
||||||
|
|
||||||
// View based NSTableView
|
// View based NSTableView
|
||||||
|
|
||||||
TCocoaTableListItem = objcclass(NSView)
|
TCocoaTableListItem = objcclass(NSView)
|
||||||
@ -241,6 +225,45 @@ type
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function AllocCocoaTableListView: TCocoaTableListView;
|
||||||
|
|
||||||
|
function LCLCoordToRow(tbl: NSTableView; X,Y: Integer): Integer;
|
||||||
|
function LCLGetItemRect(tbl: NSTableView; row, col: Integer; var r: TRect): Boolean;
|
||||||
|
function LCLGetTopRow(tbl: NSTableView): Integer;
|
||||||
|
|
||||||
|
const
|
||||||
|
DefaultRowHeight = 16; // per "rowHeight" property docs
|
||||||
|
|
||||||
|
implementation
|
||||||
|
|
||||||
|
uses
|
||||||
|
ComCtrls, CocoaWSComCtrls, CocoaWSCommon;
|
||||||
|
|
||||||
|
type
|
||||||
|
{ TCellCocoaTableListView }
|
||||||
|
|
||||||
|
TCellCocoaTableListView = objcclass(
|
||||||
|
TCocoaTableListView,
|
||||||
|
NSTableViewDelegateProtocol,
|
||||||
|
NSTableViewDataSourceProtocol,
|
||||||
|
TCocoaListViewBackendControlProtocol )
|
||||||
|
public
|
||||||
|
procedure backend_setCallback( cb: TLCLListViewCallback );
|
||||||
|
procedure backend_reloadData;
|
||||||
|
procedure backend_onInit( lclListView: TCustomListView );
|
||||||
|
public
|
||||||
|
function tableView_objectValueForTableColumn_row(tableView: NSTableView; tableColumn: NSTableColumn; row: NSInteger): id; message 'tableView:objectValueForTableColumn:row:';
|
||||||
|
procedure tableView_setObjectValue_forTableColumn_row(tableView: NSTableView; object_: id; tableColumn: NSTableColumn; row: NSInteger); message 'tableView:setObjectValue:forTableColumn:row:';
|
||||||
|
function tableView_dataCellForTableColumn_row(tableView: NSTableView; tableColumn: NSTableColumn; row: NSInteger): NSCell; message 'tableView:dataCellForTableColumn:row:';
|
||||||
|
procedure lclInsDelRow(Arow: Integer; inserted: Boolean); override;
|
||||||
|
procedure lclSetColumnAlign(acolumn: NSTableColumn; aalignment: NSTextAlignment); override;
|
||||||
|
end;
|
||||||
|
|
||||||
|
TCellCocoaTableListView1013 = objcclass(TCellCocoaTableListView, NSTableViewDelegateProtocol, NSTableViewDataSourceProtocol)
|
||||||
|
// overriding the highlight color for dark theme
|
||||||
|
procedure highlightSelectionInClipRect(clipRect: NSRect); override;
|
||||||
|
end;
|
||||||
|
|
||||||
{ TViewCocoaTableListView }
|
{ TViewCocoaTableListView }
|
||||||
|
|
||||||
TViewCocoaTableListView = objcclass(TCocoaTableListView, NSTableViewDelegateProtocol, NSTableViewDataSourceProtocol)
|
TViewCocoaTableListView = objcclass(TCocoaTableListView, NSTableViewDelegateProtocol, NSTableViewDataSourceProtocol)
|
||||||
@ -256,17 +279,6 @@ type
|
|||||||
procedure lclInsDelRow(Arow: Integer; inserted: Boolean); override;
|
procedure lclInsDelRow(Arow: Integer; inserted: Boolean); override;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function AllocCocoaTableListView: TCocoaTableListView;
|
|
||||||
|
|
||||||
function LCLCoordToRow(tbl: NSTableView; X,Y: Integer): Integer;
|
|
||||||
function LCLGetItemRect(tbl: NSTableView; row, col: Integer; var r: TRect): Boolean;
|
|
||||||
function LCLGetTopRow(tbl: NSTableView): Integer;
|
|
||||||
|
|
||||||
const
|
|
||||||
DefaultRowHeight = 16; // per "rowHeight" property docs
|
|
||||||
|
|
||||||
implementation
|
|
||||||
|
|
||||||
function LCLCoordToRow(tbl: NSTableView; X,Y: Integer): Integer;
|
function LCLCoordToRow(tbl: NSTableView; X,Y: Integer): Integer;
|
||||||
var
|
var
|
||||||
pt : NSPoint;
|
pt : NSPoint;
|
||||||
@ -986,6 +998,33 @@ begin
|
|||||||
NSCell(acolumn.dataCell).setAlignment( aalignment );
|
NSCell(acolumn.dataCell).setAlignment( aalignment );
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TCellCocoaTableListView.backend_setCallback(cb: TLCLListViewCallback);
|
||||||
|
begin
|
||||||
|
self.callback:= cb;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TCellCocoaTableListView.backend_reloadData;
|
||||||
|
begin
|
||||||
|
self.reloadData;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TCellCocoaTableListView.backend_onInit(lclListView: TCustomListView );
|
||||||
|
var
|
||||||
|
sz: NSSize;
|
||||||
|
begin
|
||||||
|
self.setDataSource(self);
|
||||||
|
self.setDelegate(self);
|
||||||
|
self.setAllowsColumnReordering(False);
|
||||||
|
self.setAllowsColumnSelection(False);
|
||||||
|
|
||||||
|
UpdateFocusRing( self, lclListView.BorderStyle );
|
||||||
|
|
||||||
|
sz := self.intercellSpacing;
|
||||||
|
// Windows compatibility. on Windows there's no extra space between columns
|
||||||
|
sz.width := 0;
|
||||||
|
self.setIntercellSpacing(sz);
|
||||||
|
end;
|
||||||
|
|
||||||
function TCellCocoaTableListView.tableView_objectValueForTableColumn_row(
|
function TCellCocoaTableListView.tableView_objectValueForTableColumn_row(
|
||||||
tableView: NSTableView; tableColumn: NSTableColumn; row: NSInteger): id;
|
tableView: NSTableView; tableColumn: NSTableColumn; row: NSInteger): id;
|
||||||
var
|
var
|
||||||
|
@ -1001,6 +1001,7 @@ var
|
|||||||
newResponder : NSResponder;
|
newResponder : NSResponder;
|
||||||
lastCb : ICommonCallback;
|
lastCb : ICommonCallback;
|
||||||
newCb : ICommonCallback;
|
newCb : ICommonCallback;
|
||||||
|
newRespsonderClassName: String;
|
||||||
begin
|
begin
|
||||||
inc( makeFirstResponderCount );
|
inc( makeFirstResponderCount );
|
||||||
try
|
try
|
||||||
@ -1040,6 +1041,7 @@ begin
|
|||||||
if Assigned(newCb) then
|
if Assigned(newCb) then
|
||||||
newCb.BecomeFirstResponder;
|
newCb.BecomeFirstResponder;
|
||||||
|
|
||||||
|
newRespsonderClassName:= newResponder.lclClassName;
|
||||||
finally
|
finally
|
||||||
dec( makeFirstResponderCount );
|
dec( makeFirstResponderCount );
|
||||||
end;
|
end;
|
||||||
|
@ -192,6 +192,14 @@ type
|
|||||||
end;
|
end;
|
||||||
TLCLListViewCallBackClass = class of TLCLListViewCallback;
|
TLCLListViewCallBackClass = class of TLCLListViewCallback;
|
||||||
|
|
||||||
|
{ TCocoaListViewBackendControl }
|
||||||
|
TCocoaListViewBackendControlProtocol = objcprotocol
|
||||||
|
procedure backend_setCallback( cb: TLCLListViewCallback ); message 'backend_setCallback:';
|
||||||
|
procedure backend_reloadData; message 'backend_reloadData';
|
||||||
|
procedure backend_onInit( lclListView: TCustomListView );
|
||||||
|
message 'backend_onInit:';
|
||||||
|
end;
|
||||||
|
|
||||||
{ TCocoaListView }
|
{ TCocoaListView }
|
||||||
|
|
||||||
TCocoaListView = objcclass(NSView)
|
TCocoaListView = objcclass(NSView)
|
||||||
@ -202,9 +210,11 @@ type
|
|||||||
_WSHandler: TCocoaWSListViewHandler;
|
_WSHandler: TCocoaWSListViewHandler;
|
||||||
_lclListView: TCustomListView;
|
_lclListView: TCustomListView;
|
||||||
_needsCallLclInit: Boolean;
|
_needsCallLclInit: Boolean;
|
||||||
|
_initializing: Boolean;
|
||||||
private
|
private
|
||||||
procedure createControls; message 'createControls';
|
procedure createControls; message 'createControls';
|
||||||
procedure releaseControls; message 'releaseControls';
|
procedure releaseControls; message 'releaseControls';
|
||||||
|
procedure initData; message 'initData';
|
||||||
public
|
public
|
||||||
callback: TLCLListViewCallback;
|
callback: TLCLListViewCallback;
|
||||||
function lclGetCallback: ICommonCallback; override;
|
function lclGetCallback: ICommonCallback; override;
|
||||||
@ -217,6 +227,7 @@ type
|
|||||||
function WSHandler: TCocoaWSListViewHandler; message 'WSHandler';
|
function WSHandler: TCocoaWSListViewHandler; message 'WSHandler';
|
||||||
procedure addSubview(aView: NSView); override;
|
procedure addSubview(aView: NSView); override;
|
||||||
procedure setScrollView(aView: TCocoaScrollView); message 'setScrollView:';
|
procedure setScrollView(aView: TCocoaScrollView); message 'setScrollView:';
|
||||||
|
function initializing: Boolean; message 'isinitializing';
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ TCocoaWSCustomListView }
|
{ TCocoaWSCustomListView }
|
||||||
@ -1140,6 +1151,9 @@ var
|
|||||||
lclcb: TLCLListViewCallback;
|
lclcb: TLCLListViewCallback;
|
||||||
begin
|
begin
|
||||||
lclcb:= self.getCallback;
|
lclcb:= self.getCallback;
|
||||||
|
if TCocoaListView(lclcb.Owner).initializing then
|
||||||
|
Exit;
|
||||||
|
|
||||||
lclcb.selectionIndexSet.shiftIndexesStartingAtIndex_by( AIndex, 1 );
|
lclcb.selectionIndexSet.shiftIndexesStartingAtIndex_by( AIndex, 1 );
|
||||||
_collectionView.reloadData;
|
_collectionView.reloadData;
|
||||||
end;
|
end;
|
||||||
@ -1311,7 +1325,11 @@ end;
|
|||||||
procedure TCocoaWSListView_CollectionViewHandler.SetSort(
|
procedure TCocoaWSListView_CollectionViewHandler.SetSort(
|
||||||
const AType: TSortType; const AColumn: Integer;
|
const AType: TSortType; const AColumn: Integer;
|
||||||
const ASortDirection: TSortDirection);
|
const ASortDirection: TSortDirection);
|
||||||
|
var
|
||||||
|
lclcb : TLCLListViewCallback;
|
||||||
begin
|
begin
|
||||||
|
lclcb:= getCallback;
|
||||||
|
lclcb.selectionIndexSet.removeAllIndexes;
|
||||||
_collectionView.reloadData();
|
_collectionView.reloadData();
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -1984,24 +2002,6 @@ end;
|
|||||||
|
|
||||||
{ TCocoaListView }
|
{ TCocoaListView }
|
||||||
|
|
||||||
procedure TCocoaListView.setViewStyle(viewStyle: TViewStyle);
|
|
||||||
var
|
|
||||||
needsInit: Boolean = False;
|
|
||||||
begin
|
|
||||||
if Assigned(_backendControl) and (_viewStyle=viewStyle) then
|
|
||||||
Exit;
|
|
||||||
|
|
||||||
_viewStyle:= viewStyle;
|
|
||||||
releaseControls;
|
|
||||||
createControls;
|
|
||||||
|
|
||||||
needsInit:= _needsCallLclInit;
|
|
||||||
_needsCallLclInit:= False;
|
|
||||||
if needsInit then
|
|
||||||
TCustomListViewAccess(_lclListView).InitializeWnd;
|
|
||||||
_needsCallLclInit:= True;
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TCocoaListView.documentView: NSView;
|
function TCocoaListView.documentView: NSView;
|
||||||
begin
|
begin
|
||||||
Result:= _backendControl;
|
Result:= _backendControl;
|
||||||
@ -2028,27 +2028,26 @@ begin
|
|||||||
Inherited addSubview(aView);
|
Inherited addSubview(aView);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure initCocoaTableListView(
|
function TCocoaListView.initializing: Boolean;
|
||||||
lclListView: TCustomListView; cocoaListView:TCocoaTableListView );
|
|
||||||
var
|
|
||||||
sz: NSSize;
|
|
||||||
begin
|
begin
|
||||||
cocoaListView.setDataSource(cocoaListView);
|
Result:= _initializing;
|
||||||
cocoaListView.setDelegate(cocoaListView);
|
end;
|
||||||
cocoaListView.setAllowsColumnReordering(False);
|
|
||||||
cocoaListView.setAllowsColumnSelection(False);
|
|
||||||
|
|
||||||
UpdateFocusRing( cocoaListView, lclListView.BorderStyle );
|
procedure TCocoaListView.setViewStyle(viewStyle: TViewStyle);
|
||||||
|
begin
|
||||||
|
if Assigned(_backendControl) and (_viewStyle=viewStyle) then
|
||||||
|
Exit;
|
||||||
|
|
||||||
sz := cocoaListView.intercellSpacing;
|
_viewStyle:= viewStyle;
|
||||||
// Windows compatibility. on Windows there's no extra space between columns
|
releaseControls;
|
||||||
sz.width := 0;
|
createControls;
|
||||||
cocoaListView.setIntercellSpacing(sz);
|
initData;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TCocoaListView.createControls;
|
procedure TCocoaListView.createControls;
|
||||||
var
|
var
|
||||||
controlFrame: NSRect;
|
controlFrame: NSRect;
|
||||||
|
backendControlAccess: TCocoaListViewBackendControlProtocol;
|
||||||
begin
|
begin
|
||||||
if _viewStyle = vsReport then begin
|
if _viewStyle = vsReport then begin
|
||||||
_backendControl:= AllocCocoaTableListView;
|
_backendControl:= AllocCocoaTableListView;
|
||||||
@ -2067,12 +2066,9 @@ begin
|
|||||||
self.setScrollView( _scrollView );
|
self.setScrollView( _scrollView );
|
||||||
ScrollViewSetBorderStyle( _scrollView, _lclListView.BorderStyle);
|
ScrollViewSetBorderStyle( _scrollView, _lclListView.BorderStyle);
|
||||||
|
|
||||||
if _viewStyle = vsReport then begin
|
backendControlAccess:= TCocoaListViewBackendControlProtocol(_backendControl);
|
||||||
initCocoaTableListView( _lclListView, TCocoaTableListView(_backendControl) );
|
backendControlAccess.backend_onInit( _lclListView );
|
||||||
TCocoaTableListView(_backendControl).callback:= self.callback;
|
backendControlAccess.backend_setCallback( self.callback );
|
||||||
end else begin
|
|
||||||
TCocoaCollectionView(_backendControl).callback:= self.callback;
|
|
||||||
end;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TCocoaListView.releaseControls;
|
procedure TCocoaListView.releaseControls;
|
||||||
@ -2087,6 +2083,21 @@ begin
|
|||||||
_backendControl:= nil;
|
_backendControl:= nil;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TCocoaListView.initData;
|
||||||
|
var
|
||||||
|
needsInit: Boolean = False;
|
||||||
|
begin
|
||||||
|
needsInit:= _needsCallLclInit;
|
||||||
|
_needsCallLclInit:= False;
|
||||||
|
if needsInit then begin
|
||||||
|
_initializing:= True;
|
||||||
|
TCustomListViewAccess(_lclListView).InitializeWnd;
|
||||||
|
_initializing:= False;
|
||||||
|
TCocoaListViewBackendControlProtocol(_backendControl).backend_reloadData;
|
||||||
|
end;
|
||||||
|
_needsCallLclInit:= True;
|
||||||
|
end;
|
||||||
|
|
||||||
function TCocoaListView.lclGetCallback: ICommonCallback;
|
function TCocoaListView.lclGetCallback: ICommonCallback;
|
||||||
begin
|
begin
|
||||||
Result:= callback;
|
Result:= callback;
|
||||||
|
Loading…
Reference in New Issue
Block a user