no message
This commit is contained in:
8
.idea/workspace.xml
generated
8
.idea/workspace.xml
generated
@@ -7,14 +7,14 @@
|
|||||||
</component>
|
</component>
|
||||||
<component name="ChangeListManager">
|
<component name="ChangeListManager">
|
||||||
<list default="true" id="e42177c3-2328-4b27-8a01-35779b2beb99" name="Default Changelist" comment="">
|
<list default="true" id="e42177c3-2328-4b27-8a01-35779b2beb99" name="Default Changelist" comment="">
|
||||||
|
<change afterPath="$PROJECT_DIR$/src/Common/Visual/FilterFlag.java" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/src/Common/Visual/MenuButtonFilterFlag.java" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/src/Common/Visual/DBObjectFilterInterface.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/Common/Visual/DBbjectFilter_.java" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/src/Common/Visual/DBbjectFilter_.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/Common/Visual/DBObjectFilter_.java" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/src/Common/Visual/DataSetControlForm.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/Common/Visual/DataSetControlForm.java" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/src/Common/Visual/DataSetControlForm.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/Common/Visual/DataSetControlForm.java" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/src/Common/Visual/DataSetFiltersMenu.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/Common/Visual/DataSetFiltersMenu.java" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/src/Common/Visual/DataSetFiltersMenu.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/Common/Visual/DataSetFiltersMenu.java" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/src/Common/Visual/FilterFlagMenuItem.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/Common/Visual/FilterFlagMenuItem.java" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/src/Common/Visual/FilterFlagMenuItem.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/Common/Visual/FilterFlagMenuItem.java" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/src/Common/Visual/Tables/HeaderTextFilter.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/Common/Visual/Tables/HeaderTextFilter.java" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/src/Common/Visual/Tables/HeaderTextFilter.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/Common/Visual/Tables/HeaderTextFilter.java" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/src/_VisualDVM/ProjectData/Messages/MessagesControlForm.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/_VisualDVM/ProjectData/Messages/MessagesControlForm.java" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/src/_VisualDVM/ProjectData/Messages/Recommendations/UI/RecommendationsForm.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/_VisualDVM/ProjectData/Messages/Recommendations/UI/RecommendationsForm.java" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/src/_VisualDVM/TestingSystem/Common/Group/UI/GroupsForm.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/_VisualDVM/TestingSystem/Common/Group/UI/GroupsForm.java" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/src/_VisualDVM/TestingSystem/Common/Group/UI/GroupsForm.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/_VisualDVM/TestingSystem/Common/Group/UI/GroupsForm.java" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/src/_VisualDVM/TestingSystem/DVM/DVMTasks/UI/DVMRunTasksForm.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/_VisualDVM/TestingSystem/DVM/DVMTasks/UI/DVMRunTasksForm.java" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/src/_VisualDVM/TestingSystem/DVM/DVMTasks/UI/DVMRunTasksForm.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/_VisualDVM/TestingSystem/DVM/DVMTasks/UI/DVMRunTasksForm.java" afterDir="false" />
|
||||||
</list>
|
</list>
|
||||||
@@ -38,8 +38,8 @@
|
|||||||
<list>
|
<list>
|
||||||
<option value="FxmlFile" />
|
<option value="FxmlFile" />
|
||||||
<option value="Enum" />
|
<option value="Enum" />
|
||||||
<option value="Class" />
|
|
||||||
<option value="Interface" />
|
<option value="Interface" />
|
||||||
|
<option value="Class" />
|
||||||
</list>
|
</list>
|
||||||
</option>
|
</option>
|
||||||
</component>
|
</component>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package Common.Visual;
|
package Common.Visual;
|
||||||
import Common.Database.Objects.DBObject;
|
import Common.Database.Objects.DBObject;
|
||||||
public interface DBbjectFilter_<D extends DBObject> {
|
public interface DBObjectFilter_<D extends DBObject> {
|
||||||
boolean Validate(D dbObject);
|
boolean Validate(D dbObject);
|
||||||
default void DropMatchesCount(){}
|
default void DropMatchesCount(){}
|
||||||
default void ShowMatchesCount(){}
|
default void ShowMatchesCount(){}
|
||||||
@@ -32,10 +32,10 @@ public class DataSetControlForm<D extends DBObject> extends ControlForm<DataTabl
|
|||||||
protected String colNamesAndSizes = "";
|
protected String colNamesAndSizes = "";
|
||||||
protected Vector<ColumnInfo> columns = new Vector<>(); //информация о столбцах и их оформлении
|
protected Vector<ColumnInfo> columns = new Vector<>(); //информация о столбцах и их оформлении
|
||||||
//-
|
//-
|
||||||
protected Vector<DBbjectFilter_<D>> allFilters = new Vector<>();
|
protected Vector<DBObjectFilter_<D>> allFilters = new Vector<>();
|
||||||
<M> Vector<M> getFilters(Class<M> f){
|
<M> Vector<M> getFilters(Class<M> f){
|
||||||
Vector<M> res = new Vector<>();
|
Vector<M> res = new Vector<>();
|
||||||
for (DBbjectFilter_ filter_: allFilters){
|
for (DBObjectFilter_ filter_: allFilters){
|
||||||
//либо М, либо наследует от М
|
//либо М, либо наследует от М
|
||||||
if (filter_.getClass().equals(f)||filter_.getClass().getSuperclass().equals(f)){
|
if (filter_.getClass().equals(f)||filter_.getClass().getSuperclass().equals(f)){
|
||||||
res.add((M) filter_);
|
res.add((M) filter_);
|
||||||
@@ -43,7 +43,7 @@ public class DataSetControlForm<D extends DBObject> extends ControlForm<DataTabl
|
|||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
public void AddFilter(DBbjectFilter_ filter_in){
|
public void AddFilter(DBObjectFilter_ filter_in){
|
||||||
allFilters.add(filter_in);
|
allFilters.add(filter_in);
|
||||||
}
|
}
|
||||||
//---
|
//---
|
||||||
@@ -340,8 +340,8 @@ public class DataSetControlForm<D extends DBObject> extends ControlForm<DataTabl
|
|||||||
}
|
}
|
||||||
protected void createFilters() {
|
protected void createFilters() {
|
||||||
}
|
}
|
||||||
public boolean ApplyFilters(D object) {
|
protected boolean ApplyFilters(D object) {
|
||||||
for (DBbjectFilter_ filterInterface: allFilters){
|
for (DBObjectFilter_ filterInterface: allFilters){
|
||||||
if (!filterInterface.Validate(object))
|
if (!filterInterface.Validate(object))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -353,10 +353,10 @@ public class DataSetControlForm<D extends DBObject> extends ControlForm<DataTabl
|
|||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public void Show() {
|
public void Show() {
|
||||||
for (DBbjectFilter_ filter_ : allFilters) filter_.DropMatchesCount();
|
for (DBObjectFilter_ filter_ : allFilters) filter_.DropMatchesCount();
|
||||||
super.Show();
|
super.Show();
|
||||||
if (f_ui != null) f_ui.ShowMatchesCount(getRowCount());
|
if (f_ui != null) f_ui.ShowMatchesCount(getRowCount());
|
||||||
for (DBbjectFilter_ filter_ : allFilters) filter_.ShowMatchesCount();
|
for (DBObjectFilter_ filter_ : allFilters) filter_.ShowMatchesCount();
|
||||||
}
|
}
|
||||||
public void Show(Object pk) {
|
public void Show(Object pk) {
|
||||||
Show();
|
Show();
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import Common.Visual.Menus.VisualiserMenu;
|
|||||||
import java.awt.event.ActionEvent;
|
import java.awt.event.ActionEvent;
|
||||||
import java.awt.event.ActionListener;
|
import java.awt.event.ActionListener;
|
||||||
import java.util.Vector;
|
import java.util.Vector;
|
||||||
public abstract class DataSetFiltersMenu<D extends DBObject> extends VisualiserMenu implements DBbjectFilter_<D> {
|
public abstract class DataSetFiltersMenu<D extends DBObject> extends VisualiserMenu implements DBObjectFilter_<D> {
|
||||||
//--
|
//--
|
||||||
protected DataSet<?, D> dataSet;
|
protected DataSet<?, D> dataSet;
|
||||||
protected Vector<FilterFlagMenuItem<D>> field_filters;
|
protected Vector<FilterFlagMenuItem<D>> field_filters;
|
||||||
@@ -18,7 +18,7 @@ public abstract class DataSetFiltersMenu<D extends DBObject> extends VisualiserM
|
|||||||
fill();
|
fill();
|
||||||
//-
|
//-
|
||||||
for (FilterFlagMenuItem<D> filter : field_filters)
|
for (FilterFlagMenuItem<D> filter : field_filters)
|
||||||
add(filter.menuItem);
|
add(filter.getControl());
|
||||||
addSeparator();
|
addSeparator();
|
||||||
add(new StableMenuItem("Выбрать всё", "/Common/icons/SelectAll.png") {
|
add(new StableMenuItem("Выбрать всё", "/Common/icons/SelectAll.png") {
|
||||||
{
|
{
|
||||||
|
|||||||
59
src/Common/Visual/FilterFlag.java
Normal file
59
src/Common/Visual/FilterFlag.java
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
package Common.Visual;
|
||||||
|
import Common.Database.Objects.DBObject;
|
||||||
|
import Common.Database.Tables.DataSet;
|
||||||
|
import Common.Utils.Utils_;
|
||||||
|
|
||||||
|
import javax.swing.*;
|
||||||
|
//фильтр флаг. либо в меню, либо на баре. текста нет.
|
||||||
|
public abstract class FilterFlag<D extends DBObject> implements DBObjectFilter_<D> {
|
||||||
|
protected AbstractButton control = null;
|
||||||
|
String description; //описание фильтра
|
||||||
|
protected boolean active = true; //включен ли фильтр
|
||||||
|
int count = 0;
|
||||||
|
protected DataSet<?, D> dataSet = null; ///источник данных
|
||||||
|
protected String getNotActiveIconPath() {
|
||||||
|
return "/Common/icons/NotPick.png";
|
||||||
|
}
|
||||||
|
protected String getActiveIconPath() {
|
||||||
|
return "/Common/icons/Pick.png";
|
||||||
|
}
|
||||||
|
public FilterFlag(DataSet<?, D> dataSet_in, AbstractButton control_in, boolean active_in) {
|
||||||
|
dataSet = dataSet_in;
|
||||||
|
active = active_in;
|
||||||
|
control = control_in;
|
||||||
|
description = control.getText();
|
||||||
|
control.addActionListener(e -> {
|
||||||
|
active = !active;
|
||||||
|
Mark();
|
||||||
|
dataSet.ShowUI();
|
||||||
|
});
|
||||||
|
Mark();
|
||||||
|
}
|
||||||
|
public AbstractButton getControl(){return control;}
|
||||||
|
public void Mark() {
|
||||||
|
control.setIcon(Utils_.getIcon(active ? getActiveIconPath() : getNotActiveIconPath()));
|
||||||
|
}
|
||||||
|
public boolean isActive() {
|
||||||
|
return active;
|
||||||
|
}
|
||||||
|
public void setActive(boolean flag) {
|
||||||
|
active = flag;
|
||||||
|
Mark();
|
||||||
|
}
|
||||||
|
protected abstract boolean validate(D object);
|
||||||
|
@Override
|
||||||
|
public boolean Validate(D object) {
|
||||||
|
boolean valid = validate(object);
|
||||||
|
if (valid)
|
||||||
|
count++;
|
||||||
|
return valid & active;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void DropMatchesCount() {
|
||||||
|
count = 0;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void ShowMatchesCount() {
|
||||||
|
control.setText(description + " " + Utils_.RBrackets(count));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,59 +6,8 @@ import Common.Visual.Controls.StableMenuItem;
|
|||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
//одиночный фильтр, пункт фильтрационного меню.
|
//одиночный фильтр, пункт фильтрационного меню.
|
||||||
public abstract class FilterFlagMenuItem<D extends DBObject> implements DBbjectFilter_<D> {
|
public abstract class FilterFlagMenuItem<D extends DBObject> extends FilterFlag<D> {
|
||||||
public JMenuItem menuItem; //пункт меню фильтра. ( возможно потом сделать и кнопку)
|
public FilterFlagMenuItem(DataSet dataSet_in, String description_in, boolean active_in) {
|
||||||
//--
|
super(dataSet_in, new StableMenuItem(description_in), active_in);
|
||||||
String description;
|
|
||||||
boolean active = true; //включен ли фильтр
|
|
||||||
int count = 0;
|
|
||||||
public FilterFlagMenuItem(DataSet dataSet, String description_in, boolean active_in) {
|
|
||||||
menuItem = new StableMenuItem((description = description_in) + " (0)");
|
|
||||||
active = active_in;
|
|
||||||
menuItem.addActionListener(e -> {
|
|
||||||
active = !active;
|
|
||||||
Mark();
|
|
||||||
dataSet.ShowUI();
|
|
||||||
});
|
|
||||||
Mark();
|
|
||||||
}
|
}
|
||||||
public FilterFlagMenuItem(DataSet dataSet, String description_in) {
|
|
||||||
this(dataSet, description_in, true);
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public boolean Validate(D object) {
|
|
||||||
boolean valid = validate(object);
|
|
||||||
if (valid)
|
|
||||||
count++;
|
|
||||||
return valid & active;
|
|
||||||
}
|
|
||||||
//-----------------------
|
|
||||||
static String getNotActiveIconPath() {
|
|
||||||
return "/Common/icons/NotPick.png";
|
|
||||||
}
|
|
||||||
static String getActiveIconPath() {
|
|
||||||
return "/Common/icons/Pick.png";
|
|
||||||
}
|
|
||||||
void Mark() {
|
|
||||||
menuItem.setIcon(Utils_.getIcon(active ? getActiveIconPath() : getNotActiveIconPath()));
|
|
||||||
}
|
|
||||||
//-------
|
|
||||||
protected abstract boolean validate(D object);
|
|
||||||
//--
|
|
||||||
@Override
|
|
||||||
public void DropMatchesCount() {
|
|
||||||
count = 0;
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public void ShowMatchesCount() {
|
|
||||||
menuItem.setText(description + " " + Utils_.RBrackets(count));
|
|
||||||
}
|
|
||||||
public boolean isActive() {
|
|
||||||
return active;
|
|
||||||
}
|
|
||||||
public void setActive(boolean flag) {
|
|
||||||
active = flag;
|
|
||||||
Mark();
|
|
||||||
}
|
|
||||||
//--
|
|
||||||
}
|
}
|
||||||
|
|||||||
9
src/Common/Visual/MenuButtonFilterFlag.java
Normal file
9
src/Common/Visual/MenuButtonFilterFlag.java
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
package Common.Visual;
|
||||||
|
import Common.Database.Objects.DBObject;
|
||||||
|
public class MenuButtonFilterFlag<D extends DBObject> implements DBObjectFilter_<D> {
|
||||||
|
boolean active = true; //включен ли фильтр
|
||||||
|
@Override
|
||||||
|
public boolean Validate(D dbObject) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,7 +3,7 @@ import Common.CommonConstants;
|
|||||||
import Common.Database.Objects.DBObject;
|
import Common.Database.Objects.DBObject;
|
||||||
import Common.Database.Tables.DataSet;
|
import Common.Database.Tables.DataSet;
|
||||||
import Common.Utils.Utils_;
|
import Common.Utils.Utils_;
|
||||||
import Common.Visual.DBbjectFilter_;
|
import Common.Visual.DBObjectFilter_;
|
||||||
import Common.Visual.TextField.StyledTextField;
|
import Common.Visual.TextField.StyledTextField;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
@@ -13,7 +13,7 @@ import javax.swing.event.DocumentListener;
|
|||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import java.awt.event.MouseAdapter;
|
import java.awt.event.MouseAdapter;
|
||||||
import java.awt.event.MouseEvent;
|
import java.awt.event.MouseEvent;
|
||||||
public class HeaderTextFilter<D extends DBObject> implements DBbjectFilter_<D> {
|
public class HeaderTextFilter<D extends DBObject> implements DBObjectFilter_<D> {
|
||||||
DataSet dataSet = null; //таблица к интерфейсу которой относится фильтр.
|
DataSet dataSet = null; //таблица к интерфейсу которой относится фильтр.
|
||||||
int columnIndex = CommonConstants.Nan; //номер столбца к которому привязан фильтр.
|
int columnIndex = CommonConstants.Nan; //номер столбца к которому привязан фильтр.
|
||||||
JTextField textField = null;
|
JTextField textField = null;
|
||||||
|
|||||||
@@ -49,8 +49,7 @@ public class GroupsForm extends DataSetControlForm<Group> {
|
|||||||
@Override
|
@Override
|
||||||
public boolean isObjectVisible(Group object) {
|
public boolean isObjectVisible(Group object) {
|
||||||
return super.isObjectVisible(object) &&
|
return super.isObjectVisible(object) &&
|
||||||
(!filterMyOnly || Global.mainModule.getAccount().email.equals(object.sender_address)) &&
|
(!filterMyOnly || Global.mainModule.getAccount().email.equals(object.sender_address));
|
||||||
Global.testingServer.db.groups.getUI().ApplyFilters(object);
|
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public DataMenuBar createMenuBar() {
|
public DataMenuBar createMenuBar() {
|
||||||
@@ -85,7 +84,7 @@ public class GroupsForm extends DataSetControlForm<Group> {
|
|||||||
@Override
|
@Override
|
||||||
public void fill() {
|
public void fill() {
|
||||||
for (TestType type : TestType.values())
|
for (TestType type : TestType.values())
|
||||||
field_filters.add(new FilterFlagMenuItem<Group>(dataSet, type.getDescription()) {
|
field_filters.add(new FilterFlagMenuItem<Group>(dataSet, type.getDescription(), true) {
|
||||||
@Override
|
@Override
|
||||||
protected boolean validate(Group object) {
|
protected boolean validate(Group object) {
|
||||||
return object.type.equals(type);
|
return object.type.equals(type);
|
||||||
@@ -97,7 +96,7 @@ public class GroupsForm extends DataSetControlForm<Group> {
|
|||||||
@Override
|
@Override
|
||||||
public void fill() {
|
public void fill() {
|
||||||
for (LanguageName languageName : LanguageName.values()) {
|
for (LanguageName languageName : LanguageName.values()) {
|
||||||
field_filters.add(new FilterFlagMenuItem<Group>(dataSet, languageName.getDescription()) {
|
field_filters.add(new FilterFlagMenuItem<Group>(dataSet, languageName.getDescription(), true) {
|
||||||
@Override
|
@Override
|
||||||
protected boolean validate(Group object) {
|
protected boolean validate(Group object) {
|
||||||
return object.language.equals(languageName);
|
return object.language.equals(languageName);
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ public class DVMRunTasksForm extends DataSetControlForm<DVMRunTask> {
|
|||||||
public void fill() {
|
public void fill() {
|
||||||
for (TaskState state : TaskState.values()) {
|
for (TaskState state : TaskState.values()) {
|
||||||
if (state.isVisible()) {
|
if (state.isVisible()) {
|
||||||
field_filters.add(new FilterFlagMenuItem<DVMRunTask>(dataSet, state.getDescription()) {
|
field_filters.add(new FilterFlagMenuItem<DVMRunTask>(dataSet, state.getDescription(), true) {
|
||||||
@Override
|
@Override
|
||||||
protected boolean validate(DVMRunTask object) {
|
protected boolean validate(DVMRunTask object) {
|
||||||
return object.compilation_state.equals(state);
|
return object.compilation_state.equals(state);
|
||||||
@@ -101,7 +101,7 @@ public class DVMRunTasksForm extends DataSetControlForm<DVMRunTask> {
|
|||||||
public void fill() {
|
public void fill() {
|
||||||
for (TaskState state : TaskState.values()) {
|
for (TaskState state : TaskState.values()) {
|
||||||
if (state.isVisible()) {
|
if (state.isVisible()) {
|
||||||
field_filters.add(new FilterFlagMenuItem<DVMRunTask>(dataSet, state.getDescription()) {
|
field_filters.add(new FilterFlagMenuItem<DVMRunTask>(dataSet, state.getDescription(), true) {
|
||||||
@Override
|
@Override
|
||||||
protected boolean validate(DVMRunTask object) {
|
protected boolean validate(DVMRunTask object) {
|
||||||
return object.state.equals(state);
|
return object.state.equals(state);
|
||||||
@@ -121,8 +121,4 @@ public class DVMRunTasksForm extends DataSetControlForm<DVMRunTask> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@Override
|
|
||||||
public boolean isObjectVisible(DVMRunTask object) {
|
|
||||||
return super.isObjectVisible(object) && Global.testingServer.db.dvmRunTasks.getUI().ApplyFilters(object);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user