mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2026-01-04 14:51:31 +01:00
MG: added uni dependencies
git-svn-id: trunk@2774 -
This commit is contained in:
parent
a01c08ffab
commit
99e98a1b11
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -223,6 +223,7 @@ ide/sysvaruseroverridedlg.pas svneol=native#text/pascal
|
||||
ide/tcolumndlg1.lfm svneol=native#text/plain
|
||||
ide/transfermacros.pp svneol=native#text/pascal
|
||||
ide/unitdependencies.lrs svneol=native#text/pascal
|
||||
ide/unitdependencies.pas svneol=native#text/pascal
|
||||
ide/uniteditor.pp svneol=native#text/pascal
|
||||
ide/unitinfodlg.pp svneol=native#text/pascal
|
||||
ide/viewforms1.lrs svneol=native#text/pascal
|
||||
|
||||
@ -52,6 +52,10 @@ type
|
||||
FReplaceHistory: TStringList;
|
||||
FMaxFindHistory: Integer;
|
||||
|
||||
// Unit dependencies
|
||||
FUnitDependenciesHistory: TStringList;
|
||||
FMaxUnitDependeciesHistory: integer;
|
||||
|
||||
// FPC unitlinks
|
||||
FLastFPCUnitLinks: string;
|
||||
FLastFPCPath: string;
|
||||
@ -74,6 +78,9 @@ type
|
||||
procedure AddToFindHistory(const AFindStr: string);
|
||||
procedure AddToReplaceHistory(const AReplaceStr: String);
|
||||
|
||||
// Unit dependencies
|
||||
procedure AddToUnitDependenciesHistory(const ARootFilename: String);
|
||||
|
||||
function LastFPCUnitLinksValid: boolean;
|
||||
function LastFPCUnitLinksNeedsUpdate(const SearchPath: string): boolean;
|
||||
procedure SetLastFPCUnitLinks(const FPCPath, SearchPath, UnitLinks: string);
|
||||
@ -87,7 +94,12 @@ type
|
||||
property ReplaceHistory: TStringList read FReplaceHistory write FReplaceHistory;
|
||||
property MaxFindHistory: Integer read FMaxFindHistory write FMaxFindHistory;
|
||||
property Filename: string read FFilename write SetFilename;
|
||||
|
||||
|
||||
// Unit dependencies
|
||||
property UnitDependenciesHistory: TStringList read FUnitDependenciesHistory;
|
||||
property MaxUnitDependeciesHistory: integer
|
||||
read FMaxUnitDependeciesHistory write FMaxUnitDependeciesHistory;
|
||||
|
||||
// FPC unitlinks
|
||||
property LastFPCUnitLinks: string read FLastFPCUnitLinks;
|
||||
property LastFPCPath: string read FLastFPCPath write SetLastFPCPath;
|
||||
@ -99,7 +111,8 @@ type
|
||||
read FFileDialogSettings write FFileDialogSettings;
|
||||
end;
|
||||
|
||||
var InputHistories: TInputHistories;
|
||||
const
|
||||
InputHistories: TInputHistories = nil;
|
||||
|
||||
|
||||
implementation
|
||||
@ -132,6 +145,9 @@ begin
|
||||
FReplaceHistory:=TStringList.Create;
|
||||
FMaxFindHistory:=20;
|
||||
|
||||
FUnitDependenciesHistory:=TStringList.Create;
|
||||
FMaxUnitDependeciesHistory:=20;
|
||||
|
||||
FFileDialogSettings.HistoryList:=TStringList.Create;
|
||||
FFileDialogSettings.MaxHistory:=20;
|
||||
|
||||
@ -142,6 +158,7 @@ end;
|
||||
destructor TInputHistories.Destroy;
|
||||
begin
|
||||
FFileDialogSettings.HistoryList.Free;
|
||||
FUnitDependenciesHistory.Free;
|
||||
FFindHistory.Free;
|
||||
FReplaceHistory.Free;
|
||||
inherited Destroy;
|
||||
@ -167,6 +184,7 @@ begin
|
||||
fMaxFindHistory:=XMLConfig.GetValue(Path+'Find/History/Max',FMaxFindHistory);
|
||||
LoadRecentList(XMLConfig,FFindHistory,Path+'Find/History/Find/');
|
||||
LoadRecentList(XMLConfig,FReplaceHistory,Path+'Find/History/Replace/');
|
||||
LoadRecentList(XMLConfig,FUnitDependenciesHistory,Path+'UnitDependencies/History/');
|
||||
FLastFPCAge:=XMLConfig.GetValue(Path+'FPCUnitLinks/FPCAge',-1);
|
||||
FLastFPCPath:=XMLConfig.GetValue(Path+'FPCUnitLinks/FPCPath','');
|
||||
FLastFPCSearchPath:=XMLConfig.GetValue(Path+'FPCUnitLinks/FPCSearchPath','');
|
||||
@ -187,6 +205,7 @@ begin
|
||||
XMLConfig.SetValue(Path+'Find/History/Max',FMaxFindHistory);
|
||||
SaveRecentList(XMLConfig,FFindHistory,Path+'Find/History/Find/');
|
||||
SaveRecentList(XMLConfig,FReplaceHistory,Path+'Find/History/Replace/');
|
||||
SaveRecentList(XMLConfig,FUnitDependenciesHistory,Path+'UnitDependencies/History/');
|
||||
XMLConfig.SetValue(Path+'FPCUnitLinks/FPCAge',FLastFPCAge);
|
||||
XMLConfig.SetValue(Path+'FPCUnitLinks/FPCPath',FLastFPCPath);
|
||||
XMLConfig.SetValue(Path+'FPCUnitLinks/FPCSearchPath',FLastFPCSearchPath);
|
||||
@ -253,6 +272,13 @@ begin
|
||||
AddToRecentList(AReplaceStr,FReplaceHistory,FMaxFindHistory);
|
||||
end;
|
||||
|
||||
procedure TInputHistories.AddToUnitDependenciesHistory(
|
||||
const ARootFilename: String);
|
||||
begin
|
||||
AddToRecentList(ARootFilename,FUnitDependenciesHistory,
|
||||
FMaxUnitDependeciesHistory);
|
||||
end;
|
||||
|
||||
function TInputHistories.LastFPCUnitLinksValid: boolean;
|
||||
begin
|
||||
Result:=(LastFPCPath<>'') and (FLastFPCAge>=0);
|
||||
|
||||
47
ide/main.pp
47
ide/main.pp
@ -54,7 +54,7 @@ uses
|
||||
LMessages, ProjectDefs, Watchesdlg, BreakPointsdlg, ColumnDlg, OutputFilter,
|
||||
BuildLazDialog, MiscOptions, EditDefineTree, CodeToolsOptions, TypInfo,
|
||||
IDEOptionDefs, CodeToolsDefines, LocalsDlg, DebuggerDlg, InputHistory,
|
||||
DiskDiffsDialog,
|
||||
DiskDiffsDialog, UnitDependencies,
|
||||
// main ide
|
||||
BaseDebugManager, DebugManager, MainBar;
|
||||
|
||||
@ -131,6 +131,7 @@ type
|
||||
procedure mnuViewInspectorClicked(Sender : TObject);
|
||||
procedure mnuViewUnitsClicked(Sender : TObject);
|
||||
procedure mnuViewFormsClicked(Sender : TObject);
|
||||
procedure mnuViewUnitDependenciesClicked(Sender : TObject);
|
||||
procedure mnuViewCodeExplorerClick(Sender : TObject);
|
||||
procedure mnuViewMessagesClick(Sender : TObject);
|
||||
procedure MessageViewDblClick(Sender : TObject);
|
||||
@ -377,7 +378,8 @@ type
|
||||
function DoOpenMainUnit(ProjectLoading: boolean): TModalResult;
|
||||
function DoRevertMainUnit: TModalResult;
|
||||
function DoViewUnitsAndForms(OnlyForms: boolean): TModalResult;
|
||||
|
||||
procedure DoViewUnitDependencies;
|
||||
|
||||
// project(s)
|
||||
function DoNewProject(NewProjectType:TProjectType):TModalResult;
|
||||
function DoSaveProject(Flags: TSaveFlags):TModalResult;
|
||||
@ -645,7 +647,7 @@ begin
|
||||
with EnvironmentOptions do begin
|
||||
SetLazarusDefaultFilename;
|
||||
Load(false);
|
||||
TranslateResourceStrings(ExtractFilePath(ExpandFilename(ParamStr(0))),
|
||||
TranslateResourceStrings(EnvironmentOptions.LazarusDirectory,
|
||||
LazarusLanguageIDs[EnvironmentOptions.Language]);
|
||||
|
||||
if EnvironmentOptions.CompilerFilename='' then
|
||||
@ -1338,6 +1340,7 @@ begin
|
||||
itmViewCodeExplorer.OnClick := @mnuViewCodeExplorerClick;
|
||||
itmViewUnits.OnClick := @mnuViewUnitsClicked;
|
||||
itmViewForms.OnClick := @mnuViewFormsClicked;
|
||||
itmViewUnitDependencies.OnClick := @mnuViewUnitDependenciesClicked;
|
||||
itmViewToggleFormUnit.OnClick := @mnuToggleFormUnitClicked;
|
||||
itmViewMessage.OnClick := @mnuViewMessagesClick;
|
||||
end;
|
||||
@ -1903,6 +1906,11 @@ Begin
|
||||
DoViewUnitsAndForms(true);
|
||||
end;
|
||||
|
||||
Procedure TMainIDE.mnuViewUnitDependenciesClicked(Sender : TObject);
|
||||
begin
|
||||
DoViewUnitDependencies;
|
||||
end;
|
||||
|
||||
Procedure TMainIDE.mnuViewCodeExplorerClick(Sender : TObject);
|
||||
begin
|
||||
SourceNotebook.Show;
|
||||
@ -3963,6 +3971,33 @@ Begin
|
||||
Result:=mrOk;
|
||||
end;
|
||||
|
||||
procedure TMainIDE.DoViewUnitDependencies;
|
||||
var
|
||||
WasVisible: boolean;
|
||||
ALayout: TIDEWindowLayout;
|
||||
begin
|
||||
if UnitDependenciesView=nil then begin
|
||||
UnitDependenciesView:=TUnitDependenciesView.Create(Self);
|
||||
WasVisible:=false;
|
||||
end else
|
||||
WasVisible:=UnitDependenciesView.Visible;
|
||||
|
||||
if not UnitDependenciesView.RootValid then begin
|
||||
if Project1.MainUnit>=0 then begin
|
||||
UnitDependenciesView.RootFilename:=Project1.MainUnitInfo.Filename;
|
||||
UnitDependenciesView.RootShortFilename:=
|
||||
ExtractFilename(Project1.MainUnitInfo.Filename);
|
||||
end;
|
||||
end;
|
||||
|
||||
UnitDependenciesView.Show;
|
||||
ALayout:=EnvironmentOptions.IDEWindowLayoutList.
|
||||
ItemByFormID(DefaultUnitDependenciesName);
|
||||
ALayout.Apply;
|
||||
if not WasVisible then
|
||||
BringWindowToTop(UnitDependenciesView.Handle);
|
||||
end;
|
||||
|
||||
function TMainIDE.DoOpenFileAtCursor(Sender: TObject):TModalResult;
|
||||
var ActiveSrcEdit: TSourceEditor;
|
||||
ActiveUnitInfo: TUnitInfo;
|
||||
@ -7016,6 +7051,9 @@ begin
|
||||
ALayout.Form.SetBounds(250,Top+Height+30,Screen.Width-300,
|
||||
Screen.Height-200-Top-Height);
|
||||
end else
|
||||
if ALayout.FormID=DefaultUnitDependenciesName then begin
|
||||
ALayout.Form.SetBounds(200,200,400,300);
|
||||
end else
|
||||
if ALayout.FormID=DefaultMessagesViewName then begin
|
||||
ALayout.Form.SetBounds(260,SourceNotebook.Top+SourceNotebook.Height+30,
|
||||
Screen.Width-300,80);
|
||||
@ -7060,6 +7098,9 @@ end.
|
||||
|
||||
{ =============================================================================
|
||||
$Log$
|
||||
Revision 1.379 2002/09/14 07:05:12 lazarus
|
||||
MG: added uni dependencies
|
||||
|
||||
Revision 1.378 2002/09/13 16:58:23 lazarus
|
||||
MG: removed the 1x1 bitmap from TBitBtn
|
||||
|
||||
|
||||
@ -63,8 +63,8 @@ type
|
||||
property OnSelectionChanged : TNotifyEvent read FOnSelectionChanged write FOnSelectionChanged;
|
||||
end;
|
||||
|
||||
var
|
||||
MessagesView : TMessagesView;
|
||||
const
|
||||
MessagesView : TMessagesView = nil;
|
||||
|
||||
|
||||
implementation
|
||||
|
||||
304
ide/unitdependencies.pas
Normal file
304
ide/unitdependencies.pas
Normal file
@ -0,0 +1,304 @@
|
||||
{
|
||||
/***************************************************************************
|
||||
unitdependencies.pas
|
||||
--------------------
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
***************************************************************************
|
||||
* *
|
||||
* This source is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This code is distributed in the hope that it will be useful, but *
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
|
||||
* General Public License for more details. *
|
||||
* *
|
||||
* A copy of the GNU General Public License is available on the World *
|
||||
* Wide Web at <http://www.gnu.org/copyleft/gpl.html>. You can also *
|
||||
* obtain it by writing to the Free Software Foundation, *
|
||||
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
* *
|
||||
***************************************************************************
|
||||
|
||||
|
||||
Author: Mattias Gaertner
|
||||
|
||||
Abstract:
|
||||
Defines the TUnitDependenciesView form.
|
||||
|
||||
}
|
||||
unit UnitDependencies;
|
||||
|
||||
{$mode objfpc}{$H+}
|
||||
|
||||
interface
|
||||
|
||||
{$I ide.inc}
|
||||
|
||||
uses
|
||||
{$IFDEF IDE_MEM_CHECK}
|
||||
MemCheck,
|
||||
{$ENDIF}
|
||||
Classes, SysUtils, Forms, Dialogs, Buttons, ComCtrls, StdCtrls,
|
||||
CodeToolManager, EnvironmentOpts, LResources, IDEOptionDefs,
|
||||
LazarusIDEStrConsts, InputHistory;
|
||||
|
||||
type
|
||||
|
||||
{ TUnitNode }
|
||||
|
||||
TUnitNode = class
|
||||
private
|
||||
FFilename: string;
|
||||
FFirstChild: TUnitNode;
|
||||
FLastChild: TUnitNode;
|
||||
FNextSibling: TUnitNode;
|
||||
FParent: TUnitNode;
|
||||
FPrevSibling: TUnitNode;
|
||||
FShortFilename: string;
|
||||
FTreeNode: TTreeNode;
|
||||
procedure SetFilename(const AValue: string);
|
||||
procedure SetShortFilename(const AValue: string);
|
||||
procedure SetTreeNode(const AValue: TTreeNode);
|
||||
procedure CreateShortFilename;
|
||||
public
|
||||
constructor Create;
|
||||
destructor Destroy; override;
|
||||
procedure CreateChilds;
|
||||
property Filename: string read FFilename write SetFilename;
|
||||
property FirstChild: TUnitNode read FFirstChild;
|
||||
property LastChild: TUnitNode read FLastChild;
|
||||
property NextSibling: TUnitNode read FNextSibling;
|
||||
property PrevSibling: TUnitNode read FPrevSibling;
|
||||
property Parent: TUnitNode read FParent;
|
||||
property ShortFilename: string read FShortFilename write SetShortFilename;
|
||||
property TreeNode: TTreeNode read FTreeNode write SetTreeNode;
|
||||
end;
|
||||
|
||||
|
||||
{ TUnitDependenciesView }
|
||||
|
||||
TUnitDependenciesView = class(TForm)
|
||||
UnitHistoryList: TComboBox;
|
||||
SelectUnitButton: TBitBtn;
|
||||
UnitTreeView: TTreeView;
|
||||
RefreshButton: TBitBtn;
|
||||
procedure UnitDependenciesViewResize(Sender: TObject);
|
||||
private
|
||||
FRootFilename: string;
|
||||
FRootShortFilename: string;
|
||||
FRootValid: boolean;
|
||||
FRootNode: TUnitNode;
|
||||
procedure DoResize;
|
||||
procedure ClearTree;
|
||||
procedure RebuildTree;
|
||||
procedure SetRootFilename(const AValue: string);
|
||||
procedure SetRootShortFilename(const AValue: string);
|
||||
public
|
||||
constructor Create(TheOwner: TComponent); override;
|
||||
destructor Destroy; override;
|
||||
function RootValid: boolean;
|
||||
procedure UpdateUnitTree;
|
||||
property RootFilename: string read FRootFilename write SetRootFilename;
|
||||
property RootShortFilename: string read FRootShortFilename write SetRootShortFilename;
|
||||
end;
|
||||
|
||||
const
|
||||
UnitDependenciesView: TUnitDependenciesView = nil;
|
||||
|
||||
implementation
|
||||
|
||||
{ TUnitDependenciesView }
|
||||
|
||||
procedure TUnitDependenciesView.UnitDependenciesViewResize(Sender: TObject);
|
||||
begin
|
||||
DoResize;
|
||||
end;
|
||||
|
||||
procedure TUnitDependenciesView.DoResize;
|
||||
begin
|
||||
with UnitHistoryList do begin
|
||||
SetBounds(0,0,Parent.ClientWidth-Left,Height);
|
||||
end;
|
||||
|
||||
with SelectUnitButton do begin
|
||||
SetBounds(0,UnitHistoryList.Top+UnitHistoryList.Height+2,25,Height);
|
||||
end;
|
||||
|
||||
with RefreshButton do begin
|
||||
SetBounds(SelectUnitButton.Left+SelectUnitButton.Width+5,
|
||||
SelectUnitButton.Top,100,SelectUnitButton.Height);
|
||||
end;
|
||||
|
||||
with UnitTreeView do begin
|
||||
SetBounds(0,SelectUnitButton.Top+SelectUnitButton.Height+2,
|
||||
Parent.ClientWidth,Parent.ClientHeight-Top);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TUnitDependenciesView.ClearTree;
|
||||
begin
|
||||
FRootNode.Free;
|
||||
FRootNode:=nil;
|
||||
end;
|
||||
|
||||
procedure TUnitDependenciesView.RebuildTree;
|
||||
begin
|
||||
ClearTree;
|
||||
if RootFilename='' then exit;
|
||||
FRootNode:=TUnitNode.Create;
|
||||
FRootNode.Filename:=RootFilename;
|
||||
FRootNode.ShortFilename:=FRootShortFilename;
|
||||
UnitTreeView.Items.Clear;
|
||||
FRootNode.TreeNode:=UnitTreeView.Items.Add(nil,'');
|
||||
FRootNode.CreateChilds;
|
||||
end;
|
||||
|
||||
procedure TUnitDependenciesView.SetRootFilename(const AValue: string);
|
||||
begin
|
||||
if FRootFilename=AValue then exit;
|
||||
FRootFilename:=AValue;
|
||||
FRootShortFilename:=FRootFilename;
|
||||
RebuildTree;
|
||||
UpdateUnitTree;
|
||||
end;
|
||||
|
||||
procedure TUnitDependenciesView.SetRootShortFilename(const AValue: string);
|
||||
begin
|
||||
if FRootShortFilename=AValue then exit;
|
||||
FRootShortFilename:=AValue;
|
||||
if FRootNode<>nil then
|
||||
FRootNode.ShortFilename:=AValue;
|
||||
end;
|
||||
|
||||
function TUnitDependenciesView.RootValid: boolean;
|
||||
begin
|
||||
Result:=FRootValid;
|
||||
end;
|
||||
|
||||
procedure TUnitDependenciesView.UpdateUnitTree;
|
||||
begin
|
||||
|
||||
end;
|
||||
|
||||
constructor TUnitDependenciesView.Create(TheOwner: TComponent);
|
||||
var
|
||||
ALayout: TIDEWindowLayout;
|
||||
begin
|
||||
inherited Create(TheOwner);
|
||||
if LazarusResources.Find(ClassName)=nil then begin
|
||||
Name:=DefaultUnitDependenciesName;
|
||||
Caption := 'Unit Dependencies';
|
||||
ALayout:=EnvironmentOptions.IDEWindowLayoutList.ItemByFormID(Name);
|
||||
ALayout.Form:=TForm(Self);
|
||||
ALayout.Apply;
|
||||
|
||||
UnitHistoryList:=TComboBox.Create(Self);
|
||||
with UnitHistoryList do begin
|
||||
Name:='UnitHistoryList';
|
||||
Parent:=Self;
|
||||
Left:=0;
|
||||
Top:=0;
|
||||
Width:=Parent.ClientWidth-Left;
|
||||
Visible:=true;
|
||||
end;
|
||||
|
||||
SelectUnitButton:=TBitBtn.Create(Self);
|
||||
with SelectUnitButton do begin
|
||||
Name:='SelectUnitButton';
|
||||
Parent:=Self;
|
||||
Left:=0;
|
||||
Top:=UnitHistoryList.Top+UnitHistoryList.Height+2;
|
||||
Width:=25;
|
||||
Caption:='...';
|
||||
Visible:=true;
|
||||
end;
|
||||
|
||||
RefreshButton:=TBitBtn.Create(Self);
|
||||
with RefreshButton do begin
|
||||
Name:='RefreshButton';
|
||||
Parent:=Self;
|
||||
Left:=SelectUnitButton.Left+SelectUnitButton.Width+5;
|
||||
Top:=SelectUnitButton.Top;
|
||||
Width:=100;
|
||||
Height:=SelectUnitButton.Height;
|
||||
Caption:='Refresh';
|
||||
Visible:=true;
|
||||
end;
|
||||
|
||||
UnitTreeView:=TTreeView.Create(Self);
|
||||
with UnitTreeView do begin
|
||||
Name:='UnitTreeView';
|
||||
Parent:=Self;
|
||||
Left:=0;
|
||||
Top:=SelectUnitButton.Top+SelectUnitButton.Height+2;
|
||||
Width:=Parent.ClientWidth;
|
||||
Height:=Parent.ClientHeight-Top;
|
||||
Visible:=true;
|
||||
end;
|
||||
|
||||
OnResize:=@UnitDependenciesViewResize;
|
||||
end;
|
||||
end;
|
||||
|
||||
destructor TUnitDependenciesView.Destroy;
|
||||
begin
|
||||
ClearTree;
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
{ TUnitNode }
|
||||
|
||||
procedure TUnitNode.SetFilename(const AValue: string);
|
||||
begin
|
||||
if FFilename=AValue then exit;
|
||||
FFilename:=AValue;
|
||||
CreateShortFilename;
|
||||
end;
|
||||
|
||||
procedure TUnitNode.SetShortFilename(const AValue: string);
|
||||
begin
|
||||
if ShortFilename=AValue then exit;
|
||||
FShortFilename:=AValue;
|
||||
if TreeNode<>nil then
|
||||
TreeNode.Text:=FShortFilename;
|
||||
end;
|
||||
|
||||
procedure TUnitNode.SetTreeNode(const AValue: TTreeNode);
|
||||
begin
|
||||
if FTreeNode=AValue then exit;
|
||||
FTreeNode:=AValue;
|
||||
if FTreeNode<>nil then begin
|
||||
FTreeNode.Text:=ShortFilename;
|
||||
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TUnitNode.CreateShortFilename;
|
||||
begin
|
||||
ShortFilename:=Filename;
|
||||
end;
|
||||
|
||||
constructor TUnitNode.Create;
|
||||
begin
|
||||
|
||||
end;
|
||||
|
||||
destructor TUnitNode.Destroy;
|
||||
begin
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
procedure TUnitNode.CreateChilds;
|
||||
//var
|
||||
// UsedInterfaceFilenames, UsedImplementation: TStrings;
|
||||
begin
|
||||
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
Loading…
Reference in New Issue
Block a user