清理多余引用
This commit is contained in:
@@ -3,10 +3,6 @@ using ACadSharp.Entities;
|
||||
|
||||
using Autodesk.Revit.DB;
|
||||
|
||||
using ShrlAlgoToolkit.RevitAddins.Common.Assists;
|
||||
using ShrlAlgoToolkit;
|
||||
using ShrlAlgoToolkit.RevitAddins;
|
||||
|
||||
namespace ShrlAlgoToolkit.RevitAddins.Common.Assists;
|
||||
|
||||
public static class DWGAssist
|
||||
|
||||
@@ -86,7 +86,7 @@ public static class ImageAssist
|
||||
/// <returns></returns>
|
||||
public static BitmapSource LoadFileImage(string filename, int width, int height)
|
||||
{
|
||||
var bm = Assists.WindowsThumbnailProvider.GetThumbnail(filename, width, height, Assists.ThumbnailOptions.None);
|
||||
var bm = WindowsThumbnailProvider.GetThumbnail(filename, width, height, ThumbnailOptions.None);
|
||||
return Imaging.CreateBitmapSourceFromHBitmap(
|
||||
bm.GetHbitmap(),
|
||||
IntPtr.Zero,
|
||||
|
||||
@@ -2,10 +2,6 @@
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
using ShrlAlgoToolkit.RevitAddins.Common.Assists;
|
||||
using ShrlAlgoToolkit;
|
||||
using ShrlAlgoToolkit.RevitAddins;
|
||||
|
||||
namespace ShrlAlgoToolkit.RevitAddins.Common.Assists;
|
||||
|
||||
public static class LogAssist
|
||||
@@ -20,7 +16,7 @@ public static class LogAssist
|
||||
{
|
||||
if (logFolder == default)
|
||||
{
|
||||
var assemblyPath = typeof(Assists.LogAssist).Assembly.Location;
|
||||
var assemblyPath = typeof(LogAssist).Assembly.Location;
|
||||
var directory = Path.GetDirectoryName(assemblyPath);
|
||||
logFolder = Path.Combine(directory, "Logs");
|
||||
}
|
||||
@@ -46,7 +42,7 @@ public static class LogAssist
|
||||
{
|
||||
if (logFolder == default)
|
||||
{
|
||||
var assemblyPath = typeof(Assists.LogAssist).Assembly.Location;
|
||||
var assemblyPath = typeof(LogAssist).Assembly.Location;
|
||||
var directory = Path.GetDirectoryName(assemblyPath);
|
||||
logFolder = $"{directory}\\Logs";
|
||||
}
|
||||
@@ -81,7 +77,7 @@ public static class LogAssist
|
||||
{
|
||||
var filePath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + $"\\{fileName}.txt";
|
||||
File.WriteAllText(filePath, sb.ToString());
|
||||
System.Diagnostics.Process.Start(filePath);
|
||||
Process.Start(filePath);
|
||||
}
|
||||
|
||||
public static void WriteTextFile(this string lineContent, string filePath)
|
||||
@@ -132,10 +128,10 @@ public static class LogAssist
|
||||
}
|
||||
|
||||
var t = ex.GetType();
|
||||
var currentUICulture = System.Threading.Thread.CurrentThread.CurrentUICulture;
|
||||
System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("zh-CN");
|
||||
var currentUICulture = Thread.CurrentThread.CurrentUICulture;
|
||||
Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("zh-CN");
|
||||
var o = Activator.CreateInstance(t);
|
||||
System.Threading.Thread.CurrentThread.CurrentUICulture = currentUICulture;
|
||||
Thread.CurrentThread.CurrentUICulture = currentUICulture;
|
||||
|
||||
return ((Exception)o).Message;
|
||||
}
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
using System.Windows;
|
||||
|
||||
using ShrlAlgoToolkit.RevitAddins.Common.Assists;
|
||||
using ShrlAlgoToolkit;
|
||||
using ShrlAlgoToolkit.RevitAddins;
|
||||
|
||||
namespace ShrlAlgoToolkit.RevitAddins.Common.Assists;
|
||||
|
||||
public sealed record SingletonViewAssist<T>
|
||||
|
||||
@@ -1,20 +1,16 @@
|
||||
using System.Windows;
|
||||
|
||||
using ShrlAlgoToolkit.RevitAddins.Common.Assists;
|
||||
using ShrlAlgoToolkit;
|
||||
using ShrlAlgoToolkit.RevitAddins;
|
||||
|
||||
namespace ShrlAlgoToolkit.RevitAddins.Common.Assists
|
||||
{
|
||||
public class TextSearchAssist
|
||||
{
|
||||
// Using a DependencyProperty as the backing store for IsTextMatch. This enables animation, styling, binding, etc...
|
||||
public static readonly DependencyProperty IsTextMatchProperty =
|
||||
DependencyProperty.RegisterAttached("IsTextMatch", typeof(bool), typeof(Assists.TextSearchAssist), new UIPropertyMetadata(false));
|
||||
DependencyProperty.RegisterAttached("IsTextMatch", typeof(bool), typeof(TextSearchAssist), new UIPropertyMetadata(false));
|
||||
|
||||
// Using a DependencyProperty as the backing store for SearchValue. This enables animation, styling, binding, etc...
|
||||
public static readonly DependencyProperty SearchValueProperty =
|
||||
DependencyProperty.RegisterAttached("SearchValue", typeof(string), typeof(Assists.TextSearchAssist),
|
||||
DependencyProperty.RegisterAttached("SearchValue", typeof(string), typeof(TextSearchAssist),
|
||||
new FrameworkPropertyMetadata(string.Empty, FrameworkPropertyMetadataOptions.Inherits));
|
||||
|
||||
public static bool GetIsTextMatch(DependencyObject obj)
|
||||
|
||||
@@ -1,8 +1,4 @@
|
||||
using ShrlAlgoToolkit.RevitAddins.Common.Assists;
|
||||
using ShrlAlgoToolkit;
|
||||
using ShrlAlgoToolkit.RevitAddins;
|
||||
|
||||
namespace ShrlAlgoToolkit.RevitAddins.Common.Assists;
|
||||
namespace ShrlAlgoToolkit.RevitAddins.Common.Assists;
|
||||
|
||||
public enum ThumbnailOptions
|
||||
{
|
||||
|
||||
@@ -2,10 +2,6 @@
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
using ShrlAlgoToolkit.RevitAddins.Common.Assists;
|
||||
using ShrlAlgoToolkit;
|
||||
using ShrlAlgoToolkit.RevitAddins;
|
||||
|
||||
namespace ShrlAlgoToolkit.RevitAddins.Common.Assists;
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Windows;
|
||||
using System.Windows.Interop;
|
||||
|
||||
@@ -43,32 +42,6 @@ public static class WinDialogAssist
|
||||
return dialog;
|
||||
//return $"{filterName}({str})|{str}";
|
||||
}
|
||||
/// <summary>
|
||||
/// 释放命令行管理程序分配的ITEMIDLIST结构
|
||||
/// Frees an ITEMIDLIST structure allocated by the Shell.
|
||||
/// </summary>
|
||||
/// <param name="pidlList"></param>
|
||||
[DllImport("shell32.dll", ExactSpelling = true)]
|
||||
private static extern void ILFree(IntPtr pidlList);
|
||||
/// <summary>
|
||||
/// 返回与指定文件路径关联的ITEMIDLIST结构。
|
||||
/// Returns the ITEMIDLIST structure associated with a specified file path.
|
||||
/// </summary>
|
||||
/// <param name="pszPath"></param>
|
||||
/// <returns></returns>
|
||||
[DllImport("shell32.dll", CharSet = CharSet.Unicode, ExactSpelling = true)]
|
||||
private static extern IntPtr ILCreateFromPathW(string pszPath);
|
||||
/// <summary>
|
||||
/// 打开一个Windows资源管理器窗口,其中选择了特定文件夹中的指定项目。
|
||||
/// Opens a Windows Explorer window with specified items in a particular folder selected.
|
||||
/// </summary>
|
||||
/// <param name="pidlList"></param>
|
||||
/// <param name="cild"></param>
|
||||
/// <param name="children"></param>
|
||||
/// <param name="dwFlags"></param>
|
||||
/// <returns></returns>
|
||||
[DllImport("shell32.dll", ExactSpelling = true)]
|
||||
private static extern int SHOpenFolderAndSelectItems(IntPtr pidlList, uint cild, IntPtr children, uint dwFlags);
|
||||
|
||||
/// <summary>
|
||||
/// 打开或在现有目录并选中相应文件
|
||||
@@ -82,7 +55,7 @@ public static class WinDialogAssist
|
||||
{
|
||||
throw new FileNotFoundException("指定的文件不存在", fileFullName);
|
||||
}
|
||||
var proc = new System.Diagnostics.Process();
|
||||
var proc = new Process();
|
||||
proc.StartInfo.FileName = "explorer";
|
||||
//打开资源管理器
|
||||
proc.StartInfo.Arguments = "/select," + fileFullName;
|
||||
@@ -102,7 +75,7 @@ public static class WinDialogAssist
|
||||
////选中"notepad.exe"这个程序,即记事本
|
||||
//proc.Start();
|
||||
|
||||
System.Diagnostics.Process.Start("explorer.exe", $"/select,\"{fileOrFolderPath}\"");
|
||||
Process.Start("explorer.exe", $"/select,\"{fileOrFolderPath}\"");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -123,12 +96,12 @@ public static class WinDialogAssist
|
||||
dialog.SetFilter(title, extensions);
|
||||
return dialog.ShowDialog() == true ? dialog.FileName : null;
|
||||
}
|
||||
public static void UpdateViewDisplay(Autodesk.Revit.UI.PreviewControl _currentPreviewControl, System.Windows.Controls.Grid PreviewContainer, Document _backgroundDoc, View view, ViewDetailLevel detailLevel, DisplayStyle displayStyle)
|
||||
public static void UpdateViewDisplay(PreviewControl currentPreviewControl, System.Windows.Controls.Grid previewContainer, Document backgroundDoc, View view, ViewDetailLevel detailLevel, DisplayStyle displayStyle)
|
||||
{
|
||||
if (_backgroundDoc == null || view == null) return;
|
||||
if (backgroundDoc == null || view == null) return;
|
||||
|
||||
_backgroundDoc.Invoke(
|
||||
ts =>
|
||||
backgroundDoc.Invoke(
|
||||
_ =>
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -142,48 +115,25 @@ public static class WinDialogAssist
|
||||
});
|
||||
|
||||
// 2. 销毁旧控件
|
||||
if (_currentPreviewControl != null)
|
||||
if (currentPreviewControl != null)
|
||||
{
|
||||
PreviewContainer.Children.Clear();
|
||||
_currentPreviewControl.Dispose();
|
||||
_currentPreviewControl = null;
|
||||
previewContainer.Children.Clear();
|
||||
currentPreviewControl.Dispose();
|
||||
currentPreviewControl = null;
|
||||
}
|
||||
|
||||
// 3. 创建新控件并加入 UI
|
||||
_currentPreviewControl = new Autodesk.Revit.UI.PreviewControl(_backgroundDoc, view.Id);
|
||||
PreviewContainer.Children.Add(_currentPreviewControl);
|
||||
currentPreviewControl = new PreviewControl(backgroundDoc, view.Id);
|
||||
previewContainer.Children.Add(currentPreviewControl);
|
||||
}
|
||||
///// <summary>
|
||||
///// 单选文件夹路径
|
||||
///// </summary>
|
||||
///// <returns></returns>
|
||||
//public static string GetSelectedFolderPath()
|
||||
//{
|
||||
// var dialog = new Ookii.Dialogs.Wpf.VistaFolderBrowserDialog { Multiselect = false };
|
||||
|
||||
// var folderPath = dialog.ShowDialog() == true ? dialog.SelectedPath : null;
|
||||
|
||||
// return folderPath;
|
||||
//}
|
||||
|
||||
///// <summary>
|
||||
///// 多选文件夹路径
|
||||
///// </summary>
|
||||
///// <returns></returns>
|
||||
//public static string[] GetSelectedFolderPaths()
|
||||
//{
|
||||
// var dialog = new Ookii.Dialogs.Wpf.VistaFolderBrowserDialog { Multiselect = true };
|
||||
|
||||
// return dialog.ShowDialog() == true ? dialog.SelectedPaths : null;
|
||||
//}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 打开窗口,非模态窗口置顶显示,默认非模态
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private static void ShowAhead(this Window window)
|
||||
{
|
||||
_ = new WindowInteropHelper(window) { Owner = System.Diagnostics.Process.GetCurrentProcess().MainWindowHandle };
|
||||
_ = new WindowInteropHelper(window) { Owner = Process.GetCurrentProcess().MainWindowHandle };
|
||||
window.Show();
|
||||
}
|
||||
|
||||
@@ -191,7 +141,7 @@ public static class WinDialogAssist
|
||||
where T : Window, new()
|
||||
{
|
||||
AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
|
||||
var view = Assists.SingletonViewAssist<T>.GetInstance(out var isNewCreate);
|
||||
var view = SingletonViewAssist<T>.GetInstance(out var isNewCreate);
|
||||
if (isNewCreate)
|
||||
{
|
||||
view.DataContext = viewModel;
|
||||
@@ -201,36 +151,29 @@ public static class WinDialogAssist
|
||||
AppDomain.CurrentDomain.AssemblyResolve -= CurrentDomain_AssemblyResolve;
|
||||
}
|
||||
|
||||
private static readonly Dictionary<Type, Window> _windows = [];
|
||||
private static readonly Dictionary<Type, Window> Windows = [];
|
||||
public static void ShowOrActivate<TView, TViewModel>(params object[] viewModelParams)
|
||||
where TView : Window,new()
|
||||
where TViewModel : class
|
||||
{
|
||||
var windowType = typeof(TView);
|
||||
if (!_windows.ContainsKey(windowType) || _windows[windowType] == null)
|
||||
if (!Windows.ContainsKey(windowType) || Windows[windowType] == null)
|
||||
{
|
||||
//CloseAllWindowsExcept(windowType);
|
||||
AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
|
||||
_windows[windowType] = new TView();
|
||||
_windows[windowType].Closed += WindowClosed;
|
||||
_windows[windowType].Closed += (_, _) => _windows[windowType] = null;
|
||||
if (_windows[windowType].DataContext == null || !(_windows[windowType].DataContext is TViewModel))
|
||||
Windows[windowType] = new TView();
|
||||
Windows[windowType].Closed += WindowClosed;
|
||||
Windows[windowType].Closed += (_, _) => Windows[windowType] = null;
|
||||
if (Windows[windowType].DataContext == null || !(Windows[windowType].DataContext is TViewModel))
|
||||
{
|
||||
if (viewModelParams.Length == 0)
|
||||
{
|
||||
_windows[windowType].DataContext = Activator.CreateInstance(typeof(TViewModel));
|
||||
}
|
||||
else
|
||||
{
|
||||
_windows[windowType].DataContext = Activator.CreateInstance(typeof(TViewModel), viewModelParams);
|
||||
}
|
||||
Windows[windowType].DataContext = viewModelParams.Length == 0 ? Activator.CreateInstance(typeof(TViewModel)) : Activator.CreateInstance(typeof(TViewModel), viewModelParams);
|
||||
}
|
||||
_ = new WindowInteropHelper(_windows[windowType]) { Owner = Process.GetCurrentProcess().MainWindowHandle };
|
||||
_windows[windowType].Show();
|
||||
_ = new WindowInteropHelper(Windows[windowType]) { Owner = Process.GetCurrentProcess().MainWindowHandle };
|
||||
Windows[windowType].Show();
|
||||
}
|
||||
else
|
||||
{
|
||||
_windows[windowType].Activate();
|
||||
Windows[windowType].Activate();
|
||||
}
|
||||
}
|
||||
private static void WindowClosed(object sender, EventArgs e)
|
||||
@@ -242,16 +185,11 @@ public static class WinDialogAssist
|
||||
where TWindow : Window, new()
|
||||
where TViewModel : class
|
||||
{
|
||||
var window = new TWindow();
|
||||
if (viewModelParams.Length == 0)
|
||||
var window = new TWindow
|
||||
{
|
||||
window.DataContext = Activator.CreateInstance(typeof(TViewModel));
|
||||
}
|
||||
else
|
||||
{
|
||||
window.DataContext = Activator.CreateInstance(typeof(TViewModel), viewModelParams);
|
||||
}
|
||||
_ = new WindowInteropHelper(window) { Owner = System.Diagnostics.Process.GetCurrentProcess().MainWindowHandle };
|
||||
DataContext = viewModelParams.Length == 0 ? Activator.CreateInstance(typeof(TViewModel)) : Activator.CreateInstance(typeof(TViewModel), viewModelParams)
|
||||
};
|
||||
_ = new WindowInteropHelper(window) { Owner = Process.GetCurrentProcess().MainWindowHandle };
|
||||
window.ShowDialog();
|
||||
}
|
||||
private static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
|
||||
@@ -264,9 +202,9 @@ public static class WinDialogAssist
|
||||
|
||||
string name = new AssemblyName(args.Name).Name;
|
||||
List<string> list = new List<string>();
|
||||
for (int i = 0; i < frames.Length; i++)
|
||||
foreach (var t in frames)
|
||||
{
|
||||
MethodBase method = frames[i].GetMethod();
|
||||
MethodBase method = t.GetMethod();
|
||||
if ((object)method.DeclaringType == null)
|
||||
{
|
||||
continue;
|
||||
|
||||
@@ -3,10 +3,6 @@ using System.Drawing.Imaging;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
using ShrlAlgoToolkit.RevitAddins.Common.Assists;
|
||||
using ShrlAlgoToolkit;
|
||||
using ShrlAlgoToolkit.RevitAddins;
|
||||
|
||||
namespace ShrlAlgoToolkit.RevitAddins.Common.Assists;
|
||||
|
||||
/// <summary>
|
||||
@@ -20,7 +16,7 @@ public class WindowsThumbnailProvider
|
||||
{
|
||||
var result = new Bitmap(srcBitmap.Width, srcBitmap.Height, targetPixelFormat);
|
||||
|
||||
var bmpBounds = new System.Drawing.Rectangle(0, 0, srcBitmap.Width, srcBitmap.Height);
|
||||
var bmpBounds = new Rectangle(0, 0, srcBitmap.Width, srcBitmap.Height);
|
||||
|
||||
var srcData = srcBitmap.LockBits(bmpBounds, ImageLockMode.ReadOnly, srcBitmap.PixelFormat);
|
||||
|
||||
@@ -32,7 +28,7 @@ public class WindowsThumbnailProvider
|
||||
{
|
||||
for (var x = 0; x <= srcData.Width - 1; x++)
|
||||
{
|
||||
var pixelColor = System.Drawing.Color.FromArgb(Marshal.ReadInt32(srcData.Scan0, (srcData.Stride * y) + (4 * x)));
|
||||
var pixelColor = Color.FromArgb(Marshal.ReadInt32(srcData.Scan0, (srcData.Stride * y) + (4 * x)));
|
||||
|
||||
if ((pixelColor.A > 0) & (pixelColor.A < 255))
|
||||
{
|
||||
@@ -58,7 +54,7 @@ public class WindowsThumbnailProvider
|
||||
return Image.GetPixelFormatSize(bmp.PixelFormat) < 32 ? bmp : CreateAlphaBitmap(bmp, PixelFormat.Format32bppArgb);
|
||||
}
|
||||
|
||||
public static Bitmap GetThumbnail(string fileName, int width, int height, Assists.ThumbnailOptions options)
|
||||
public static Bitmap GetThumbnail(string fileName, int width, int height, ThumbnailOptions options)
|
||||
{
|
||||
var hBitmap = GetHBitmap(Path.GetFullPath(fileName), width, height, options);
|
||||
|
||||
@@ -84,10 +80,10 @@ public class WindowsThumbnailProvider
|
||||
// The following parameter is not used - binding context.
|
||||
IntPtr pbc,
|
||||
ref Guid riid,
|
||||
[MarshalAs(UnmanagedType.Interface)] out Assists.WindowsThumbnailProvider.IShellItem shellItem
|
||||
[MarshalAs(UnmanagedType.Interface)] out IShellItem shellItem
|
||||
);
|
||||
|
||||
private static IntPtr GetHBitmap(string fileName, int width, int height, Assists.ThumbnailOptions options)
|
||||
private static IntPtr GetHBitmap(string fileName, int width, int height, ThumbnailOptions options)
|
||||
{
|
||||
var shellItem2Guid = new Guid(ShellItem2Guid);
|
||||
var retCode = SHCreateItemFromParsingName(fileName, IntPtr.Zero, ref shellItem2Guid, out var nativeShellItem);
|
||||
@@ -97,13 +93,13 @@ public class WindowsThumbnailProvider
|
||||
throw Marshal.GetExceptionForHR(retCode);
|
||||
}
|
||||
|
||||
var nativeSize = new Assists.WindowsThumbnailProvider.NativeSize { Width = width, Height = height };
|
||||
var nativeSize = new NativeSize { Width = width, Height = height };
|
||||
|
||||
var hr = ((Assists.WindowsThumbnailProvider.IShellItemImageFactory)nativeShellItem).GetImage(nativeSize, options, out var hBitmap);
|
||||
var hr = ((IShellItemImageFactory)nativeShellItem).GetImage(nativeSize, options, out var hBitmap);
|
||||
|
||||
Marshal.ReleaseComObject(nativeShellItem);
|
||||
|
||||
return hr == Assists.WindowsThumbnailProvider.HResult.Ok ? hBitmap : throw Marshal.GetExceptionForHR((int)hr);
|
||||
return hr == HResult.Ok ? hBitmap : throw Marshal.GetExceptionForHR((int)hr);
|
||||
}
|
||||
|
||||
internal enum HResult
|
||||
@@ -130,13 +126,13 @@ public class WindowsThumbnailProvider
|
||||
{
|
||||
void BindToHandler(IntPtr pbc, [MarshalAs(UnmanagedType.LPStruct)] Guid bhid, [MarshalAs(UnmanagedType.LPStruct)] Guid riid, out IntPtr ppv);
|
||||
|
||||
void Compare(Assists.WindowsThumbnailProvider.IShellItem psi, uint hint, out int piOrder);
|
||||
void Compare(IShellItem psi, uint hint, out int piOrder);
|
||||
|
||||
void GetAttributes(uint sfgaoMask, out uint psfgaoAttribs);
|
||||
|
||||
void GetDisplayName(Assists.WindowsThumbnailProvider.SIGDN sigdnName, out IntPtr ppszName);
|
||||
void GetDisplayName(SIGDN sigdnName, out IntPtr ppszName);
|
||||
|
||||
void GetParent(out Assists.WindowsThumbnailProvider.IShellItem ppsi);
|
||||
void GetParent(out IShellItem ppsi);
|
||||
}
|
||||
|
||||
[ComImport]
|
||||
@@ -145,7 +141,7 @@ public class WindowsThumbnailProvider
|
||||
internal interface IShellItemImageFactory
|
||||
{
|
||||
[PreserveSig]
|
||||
Assists.WindowsThumbnailProvider.HResult GetImage([In] [MarshalAs(UnmanagedType.Struct)] Assists.WindowsThumbnailProvider.NativeSize size, [In] Assists.ThumbnailOptions flags, [Out] out IntPtr phbm);
|
||||
HResult GetImage([In] [MarshalAs(UnmanagedType.Struct)] NativeSize size, [In] ThumbnailOptions flags, [Out] out IntPtr phbm);
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
|
||||
Reference in New Issue
Block a user