Lab8 сдана
This commit is contained in:
parent
e7f367dc4d
commit
783ff07009
42
AirBomber/AirBomber/FormPlaneCollection.Designer.cs
generated
42
AirBomber/AirBomber/FormPlaneCollection.Designer.cs
generated
@ -34,6 +34,8 @@
|
|||||||
buttonRefreshCollection = new Button();
|
buttonRefreshCollection = new Button();
|
||||||
maskedTextBoxNumber = new MaskedTextBox();
|
maskedTextBoxNumber = new MaskedTextBox();
|
||||||
groupBoxTools = new GroupBox();
|
groupBoxTools = new GroupBox();
|
||||||
|
buttonSortByColor = new Button();
|
||||||
|
buttonSortByType = new Button();
|
||||||
groupBoxStorages = new GroupBox();
|
groupBoxStorages = new GroupBox();
|
||||||
textBoxStorageName = new TextBox();
|
textBoxStorageName = new TextBox();
|
||||||
buttonDelObject = new Button();
|
buttonDelObject = new Button();
|
||||||
@ -63,9 +65,9 @@
|
|||||||
//
|
//
|
||||||
// buttonAddPlane
|
// buttonAddPlane
|
||||||
//
|
//
|
||||||
buttonAddPlane.Location = new Point(76, 417);
|
buttonAddPlane.Location = new Point(49, 525);
|
||||||
buttonAddPlane.Name = "buttonAddPlane";
|
buttonAddPlane.Name = "buttonAddPlane";
|
||||||
buttonAddPlane.Size = new Size(160, 64);
|
buttonAddPlane.Size = new Size(209, 44);
|
||||||
buttonAddPlane.TabIndex = 0;
|
buttonAddPlane.TabIndex = 0;
|
||||||
buttonAddPlane.Text = "Добавить самолет";
|
buttonAddPlane.Text = "Добавить самолет";
|
||||||
buttonAddPlane.UseVisualStyleBackColor = true;
|
buttonAddPlane.UseVisualStyleBackColor = true;
|
||||||
@ -73,7 +75,7 @@
|
|||||||
//
|
//
|
||||||
// buttonRemovePlane
|
// buttonRemovePlane
|
||||||
//
|
//
|
||||||
buttonRemovePlane.Location = new Point(76, 549);
|
buttonRemovePlane.Location = new Point(76, 612);
|
||||||
buttonRemovePlane.Name = "buttonRemovePlane";
|
buttonRemovePlane.Name = "buttonRemovePlane";
|
||||||
buttonRemovePlane.Size = new Size(160, 60);
|
buttonRemovePlane.Size = new Size(160, 60);
|
||||||
buttonRemovePlane.TabIndex = 1;
|
buttonRemovePlane.TabIndex = 1;
|
||||||
@ -83,9 +85,9 @@
|
|||||||
//
|
//
|
||||||
// buttonRefreshCollection
|
// buttonRefreshCollection
|
||||||
//
|
//
|
||||||
buttonRefreshCollection.Location = new Point(76, 648);
|
buttonRefreshCollection.Location = new Point(49, 678);
|
||||||
buttonRefreshCollection.Name = "buttonRefreshCollection";
|
buttonRefreshCollection.Name = "buttonRefreshCollection";
|
||||||
buttonRefreshCollection.Size = new Size(160, 86);
|
buttonRefreshCollection.Size = new Size(209, 56);
|
||||||
buttonRefreshCollection.TabIndex = 2;
|
buttonRefreshCollection.TabIndex = 2;
|
||||||
buttonRefreshCollection.Text = "Обновить коллекцию";
|
buttonRefreshCollection.Text = "Обновить коллекцию";
|
||||||
buttonRefreshCollection.UseVisualStyleBackColor = true;
|
buttonRefreshCollection.UseVisualStyleBackColor = true;
|
||||||
@ -93,7 +95,7 @@
|
|||||||
//
|
//
|
||||||
// maskedTextBoxNumber
|
// maskedTextBoxNumber
|
||||||
//
|
//
|
||||||
maskedTextBoxNumber.Location = new Point(76, 501);
|
maskedTextBoxNumber.Location = new Point(76, 575);
|
||||||
maskedTextBoxNumber.Mask = "00";
|
maskedTextBoxNumber.Mask = "00";
|
||||||
maskedTextBoxNumber.Name = "maskedTextBoxNumber";
|
maskedTextBoxNumber.Name = "maskedTextBoxNumber";
|
||||||
maskedTextBoxNumber.Size = new Size(160, 31);
|
maskedTextBoxNumber.Size = new Size(160, 31);
|
||||||
@ -102,6 +104,8 @@
|
|||||||
//
|
//
|
||||||
// groupBoxTools
|
// groupBoxTools
|
||||||
//
|
//
|
||||||
|
groupBoxTools.Controls.Add(buttonSortByColor);
|
||||||
|
groupBoxTools.Controls.Add(buttonSortByType);
|
||||||
groupBoxTools.Controls.Add(groupBoxStorages);
|
groupBoxTools.Controls.Add(groupBoxStorages);
|
||||||
groupBoxTools.Controls.Add(buttonAddPlane);
|
groupBoxTools.Controls.Add(buttonAddPlane);
|
||||||
groupBoxTools.Controls.Add(buttonRefreshCollection);
|
groupBoxTools.Controls.Add(buttonRefreshCollection);
|
||||||
@ -114,6 +118,26 @@
|
|||||||
groupBoxTools.TabStop = false;
|
groupBoxTools.TabStop = false;
|
||||||
groupBoxTools.Text = "Инструменты";
|
groupBoxTools.Text = "Инструменты";
|
||||||
//
|
//
|
||||||
|
// buttonSortByColor
|
||||||
|
//
|
||||||
|
buttonSortByColor.Location = new Point(49, 469);
|
||||||
|
buttonSortByColor.Name = "buttonSortByColor";
|
||||||
|
buttonSortByColor.Size = new Size(209, 48);
|
||||||
|
buttonSortByColor.TabIndex = 6;
|
||||||
|
buttonSortByColor.Text = "Сортировка по цвету";
|
||||||
|
buttonSortByColor.UseVisualStyleBackColor = true;
|
||||||
|
buttonSortByColor.Click += buttonSortByColor_Click;
|
||||||
|
//
|
||||||
|
// buttonSortByType
|
||||||
|
//
|
||||||
|
buttonSortByType.Location = new Point(49, 415);
|
||||||
|
buttonSortByType.Name = "buttonSortByType";
|
||||||
|
buttonSortByType.Size = new Size(209, 48);
|
||||||
|
buttonSortByType.TabIndex = 5;
|
||||||
|
buttonSortByType.Text = "Сортировка по типу";
|
||||||
|
buttonSortByType.UseVisualStyleBackColor = true;
|
||||||
|
buttonSortByType.Click += buttonSortByType_Click;
|
||||||
|
//
|
||||||
// groupBoxStorages
|
// groupBoxStorages
|
||||||
//
|
//
|
||||||
groupBoxStorages.Controls.Add(textBoxStorageName);
|
groupBoxStorages.Controls.Add(textBoxStorageName);
|
||||||
@ -184,14 +208,14 @@
|
|||||||
// SaveToolStripMenuItem
|
// SaveToolStripMenuItem
|
||||||
//
|
//
|
||||||
SaveToolStripMenuItem.Name = "SaveToolStripMenuItem";
|
SaveToolStripMenuItem.Name = "SaveToolStripMenuItem";
|
||||||
SaveToolStripMenuItem.Size = new Size(270, 34);
|
SaveToolStripMenuItem.Size = new Size(212, 34);
|
||||||
SaveToolStripMenuItem.Text = "Сохранение";
|
SaveToolStripMenuItem.Text = "Сохранение";
|
||||||
SaveToolStripMenuItem.Click += SaveToolStripMenuItem_Click;
|
SaveToolStripMenuItem.Click += SaveToolStripMenuItem_Click;
|
||||||
//
|
//
|
||||||
// LoadToolStripMenuItem
|
// LoadToolStripMenuItem
|
||||||
//
|
//
|
||||||
LoadToolStripMenuItem.Name = "LoadToolStripMenuItem";
|
LoadToolStripMenuItem.Name = "LoadToolStripMenuItem";
|
||||||
LoadToolStripMenuItem.Size = new Size(270, 34);
|
LoadToolStripMenuItem.Size = new Size(212, 34);
|
||||||
LoadToolStripMenuItem.Text = "Загрузка";
|
LoadToolStripMenuItem.Text = "Загрузка";
|
||||||
LoadToolStripMenuItem.Click += LoadToolStripMenuItem_Click;
|
LoadToolStripMenuItem.Click += LoadToolStripMenuItem_Click;
|
||||||
//
|
//
|
||||||
@ -245,5 +269,7 @@
|
|||||||
private ToolStripMenuItem LoadToolStripMenuItem;
|
private ToolStripMenuItem LoadToolStripMenuItem;
|
||||||
private OpenFileDialog openFileDialog;
|
private OpenFileDialog openFileDialog;
|
||||||
private SaveFileDialog saveFileDialog;
|
private SaveFileDialog saveFileDialog;
|
||||||
|
private Button buttonSortByColor;
|
||||||
|
private Button buttonSortByType;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -94,6 +94,7 @@ namespace AirBomber
|
|||||||
MessageBox.Show(ex.Message);
|
MessageBox.Show(ex.Message);
|
||||||
_logger.LogWarning($"Объект не добавлен в набор {listBoxStorages.SelectedItem.ToString()}");
|
_logger.LogWarning($"Объект не добавлен в набор {listBoxStorages.SelectedItem.ToString()}");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Удаление объекта из набора
|
/// Удаление объекта из набора
|
||||||
@ -235,5 +236,35 @@ namespace AirBomber
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// Сортировка по типу
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sender"></param>
|
||||||
|
/// <param name="e"></param>
|
||||||
|
private void buttonSortByType_Click(object sender, EventArgs e) => ComparePlanes(new PlaneCompareByType());
|
||||||
|
/// <summary>
|
||||||
|
/// Сортировка по цвету
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sender"></param>
|
||||||
|
/// <param name="e"></param>
|
||||||
|
private void buttonSortByColor_Click(object sender, EventArgs e) => ComparePlanes(new PlaneCompareByColor());
|
||||||
|
/// <summary>
|
||||||
|
/// Сортировка по сравнителю
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="comparer"></param>
|
||||||
|
private void ComparePlanes(IComparer<DrawningAirPlane?> comparer)
|
||||||
|
{
|
||||||
|
if (listBoxStorages.SelectedIndex == -1)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var obj = _storage[listBoxStorages.SelectedItem.ToString() ?? string.Empty];
|
||||||
|
if (obj == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
obj.Sort(comparer);
|
||||||
|
pictureBoxCollection.Image = obj.ShowPlanes();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
33
AirBomber/AirBomber/PlaneCollectionInfo.cs
Normal file
33
AirBomber/AirBomber/PlaneCollectionInfo.cs
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace AirBomber
|
||||||
|
{
|
||||||
|
internal class PlaneCollectionInfo: IEquatable<PlaneCollectionInfo>
|
||||||
|
{
|
||||||
|
public string Name { get; private set; }
|
||||||
|
public string Description { get; private set; }
|
||||||
|
public PlaneCollectionInfo(string name, string description)
|
||||||
|
{
|
||||||
|
Name = name;
|
||||||
|
Description = description;
|
||||||
|
}
|
||||||
|
public bool Equals(PlaneCollectionInfo other)
|
||||||
|
{
|
||||||
|
if (Name != other?.Name)
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
public override int GetHashCode()
|
||||||
|
{
|
||||||
|
return Name.GetHashCode();
|
||||||
|
}
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return Name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using AirBomber;
|
||||||
|
|
||||||
namespace AirBomber
|
namespace AirBomber
|
||||||
{
|
{
|
||||||
@ -31,6 +32,11 @@ namespace AirBomber
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly SetGeneric<T> _collection;
|
private readonly SetGeneric<T> _collection;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
/// Сортировка
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="comparer"></param>
|
||||||
|
public void Sort(IComparer<T?> comparer) => _collection.SortSet(comparer);
|
||||||
|
/// <summary>
|
||||||
/// Конструктор
|
/// Конструктор
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="picWidth"></param>
|
/// <param name="picWidth"></param>
|
||||||
@ -49,13 +55,13 @@ namespace AirBomber
|
|||||||
/// <param name="collect"></param>
|
/// <param name="collect"></param>
|
||||||
/// <param name="obj"></param>
|
/// <param name="obj"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static bool operator +(PlanesGenericCollection<T, U> collect, T obj)
|
public static int operator +(PlanesGenericCollection<T, U> collect, T obj)
|
||||||
{
|
{
|
||||||
if (obj == null)
|
if (obj == null)
|
||||||
{
|
{
|
||||||
return false;
|
return -1;
|
||||||
}
|
}
|
||||||
return collect._collection.Insert(obj);
|
return collect._collection.Insert(obj, new DrawningPlanesEquatables());
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Перегрузка оператора вычитания
|
/// Перегрузка оператора вычитания
|
||||||
|
@ -4,6 +4,7 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using System.Xml.Linq;
|
||||||
|
|
||||||
namespace AirBomber
|
namespace AirBomber
|
||||||
{
|
{
|
||||||
@ -12,11 +13,11 @@ namespace AirBomber
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Словарь (хранилище)
|
/// Словарь (хранилище)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
readonly Dictionary<string, PlanesGenericCollection<DrawningAirPlane, DrawningObjectAirPlane>> _planeStorages;
|
readonly Dictionary<PlaneCollectionInfo, PlanesGenericCollection<DrawningAirPlane, DrawningObjectAirPlane>> _planeStorages;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Возвращение списка названий наборов
|
/// Возвращение списка названий наборов
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public List<string> Keys => _planeStorages.Keys.ToList();
|
public List<PlaneCollectionInfo> Keys => _planeStorages.Keys.ToList();
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Ширина окна отрисовки
|
/// Ширина окна отрисовки
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -44,7 +45,7 @@ namespace AirBomber
|
|||||||
/// <param name="pictureHeight"></param>
|
/// <param name="pictureHeight"></param>
|
||||||
public PlanesGenericStorage(int pictureWidth, int pictureHeight)
|
public PlanesGenericStorage(int pictureWidth, int pictureHeight)
|
||||||
{
|
{
|
||||||
_planeStorages = new Dictionary<string, PlanesGenericCollection<DrawningAirPlane, DrawningObjectAirPlane>>();
|
_planeStorages = new Dictionary<PlaneCollectionInfo, PlanesGenericCollection<DrawningAirPlane, DrawningObjectAirPlane>>();
|
||||||
_pictureWidth = pictureWidth;
|
_pictureWidth = pictureWidth;
|
||||||
_pictureHeight = pictureHeight;
|
_pictureHeight = pictureHeight;
|
||||||
}
|
}
|
||||||
@ -55,9 +56,10 @@ namespace AirBomber
|
|||||||
public void AddSet(string name)
|
public void AddSet(string name)
|
||||||
{
|
{
|
||||||
// TODO Прописать логику для добавления DONE
|
// TODO Прописать логику для добавления DONE
|
||||||
if (!_planeStorages.ContainsKey(name))
|
if(!_planeStorages.ContainsKey(new PlaneCollectionInfo(name, string.Empty)))
|
||||||
{
|
{
|
||||||
_planeStorages.Add(name, new PlanesGenericCollection<DrawningAirPlane, DrawningObjectAirPlane>(_pictureWidth, _pictureHeight));
|
_planeStorages.Add(new PlaneCollectionInfo(name, string.Empty),
|
||||||
|
new PlanesGenericCollection<DrawningAirPlane, DrawningObjectAirPlane>(_pictureWidth, _pictureHeight));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -67,10 +69,11 @@ namespace AirBomber
|
|||||||
public void DelSet(string name)
|
public void DelSet(string name)
|
||||||
{
|
{
|
||||||
// TODO Прописать логику для удаления DONE
|
// TODO Прописать логику для удаления DONE
|
||||||
if (_planeStorages.ContainsKey(name))
|
if (!_planeStorages.ContainsKey(new PlaneCollectionInfo(name, string.Empty)))
|
||||||
{
|
{
|
||||||
_planeStorages.Remove(name);
|
return;
|
||||||
}
|
}
|
||||||
|
_planeStorages.Remove(new PlaneCollectionInfo(name, string.Empty));
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Доступ к набору
|
/// Доступ к набору
|
||||||
@ -83,9 +86,9 @@ namespace AirBomber
|
|||||||
get
|
get
|
||||||
{
|
{
|
||||||
// TODO Продумать логику получения набора DONE
|
// TODO Продумать логику получения набора DONE
|
||||||
if (_planeStorages.ContainsKey(ind))
|
if (_planeStorages.ContainsKey(new PlaneCollectionInfo(ind, string.Empty)))
|
||||||
{
|
{
|
||||||
return _planeStorages[ind];
|
return _planeStorages[new PlaneCollectionInfo(ind, string.Empty)];
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -102,7 +105,7 @@ namespace AirBomber
|
|||||||
File.Delete(filename);
|
File.Delete(filename);
|
||||||
}
|
}
|
||||||
StringBuilder data = new();
|
StringBuilder data = new();
|
||||||
foreach (KeyValuePair<string, PlanesGenericCollection<DrawningAirPlane, DrawningObjectAirPlane>>record in _planeStorages)
|
foreach (KeyValuePair<PlaneCollectionInfo, PlanesGenericCollection<DrawningAirPlane, DrawningObjectAirPlane>>record in _planeStorages)
|
||||||
{
|
{
|
||||||
StringBuilder records = new();
|
StringBuilder records = new();
|
||||||
foreach (DrawningAirPlane? elem in record.Value.GetPlanes)
|
foreach (DrawningAirPlane? elem in record.Value.GetPlanes)
|
||||||
@ -169,7 +172,7 @@ namespace AirBomber
|
|||||||
DrawningAirPlane? plane = elem?.CreateDrawningAirPlane(_separatorForObject, _pictureWidth, _pictureHeight);
|
DrawningAirPlane? plane = elem?.CreateDrawningAirPlane(_separatorForObject, _pictureWidth, _pictureHeight);
|
||||||
if (plane != null)
|
if (plane != null)
|
||||||
{
|
{
|
||||||
if (!(collection + plane))
|
if ((collection + plane) == -1)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -186,7 +189,7 @@ namespace AirBomber
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_planeStorages.Add(record[0], collection);
|
_planeStorages.Add(new PlaneCollectionInfo(record[0], string.Empty), collection);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -37,9 +37,19 @@ namespace AirBomber
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="plane">Добавляемый самолет</param>
|
/// <param name="plane">Добавляемый самолет</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public bool Insert(T plane, IEqualityComparer<T?>? equal = null)
|
public int Insert(T plane, IEqualityComparer<T?>? equal = null)
|
||||||
{
|
{
|
||||||
return Insert(plane, 0, equal);
|
if (equal != null)
|
||||||
|
{
|
||||||
|
foreach (var secondLoco in _places)
|
||||||
|
{
|
||||||
|
if (equal.Equals(plane, secondLoco))
|
||||||
|
{
|
||||||
|
throw new Exception("Такой объект уже есть в коллекции");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Insert(plane, 0);
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Добавление объекта в набор на конкретную позицию
|
/// Добавление объекта в набор на конкретную позицию
|
||||||
@ -47,19 +57,23 @@ namespace AirBomber
|
|||||||
/// <param name="plane">Добавляемый самолет</param>
|
/// <param name="plane">Добавляемый самолет</param>
|
||||||
/// <param name="position">Позиция</param>
|
/// <param name="position">Позиция</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public bool Insert(T plane, int position, IEqualityComparer<T?>? equal = null)
|
public int Insert(T plane, int position, IEqualityComparer<T?>? equal = null)
|
||||||
{
|
{
|
||||||
if (position < 0 || position >= _maxCount)
|
if (_places.Count >= _maxCount)
|
||||||
throw new StorageOverflowException("Невозможно добавить");
|
|
||||||
|
|
||||||
if (Count >= _maxCount)
|
|
||||||
throw new StorageOverflowException(_maxCount);
|
throw new StorageOverflowException(_maxCount);
|
||||||
|
|
||||||
if (equal != null && _places.Contains(plane, equal))
|
if (position < 0 || position >= _maxCount)
|
||||||
throw new ArgumentException("Такой объект уже есть в коллекции");
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
_places.Insert(0, plane);
|
if (equal != null)
|
||||||
return true;
|
{
|
||||||
|
if (_places.Contains(plane, equal))
|
||||||
|
throw new ArgumentException(("Такой объект уже есть в коллекции"));
|
||||||
|
}
|
||||||
|
_places.Insert(position, plane);
|
||||||
|
return position;
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Удаление объекта из набора с конкретной позиции
|
/// Удаление объекта из набора с конкретной позиции
|
||||||
|
Loading…
Reference in New Issue
Block a user