mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
SSR: reference predicate UI
This commit is contained in:
+60
-29
@@ -41,7 +41,9 @@ import com.intellij.structuralsearch.plugin.replace.ReplaceOptions;
|
||||
import com.intellij.structuralsearch.plugin.replace.ui.ReplaceConfiguration;
|
||||
import com.intellij.structuralsearch.plugin.util.StructuralSearchScriptScope;
|
||||
import com.intellij.ui.EditorTextField;
|
||||
import com.intellij.ui.TextAccessor;
|
||||
import com.intellij.ui.awt.RelativePoint;
|
||||
import com.intellij.ui.components.JBCheckBox;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -67,31 +69,31 @@ import java.util.regex.PatternSyntaxException;
|
||||
class EditVarConstraintsDialog extends DialogWrapper {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.structuralsearch.plugin.ui.EditVarConstraintsDialog");
|
||||
|
||||
JTextField maxoccurs;
|
||||
JCheckBox applyWithinTypeHierarchy;
|
||||
private JTextField maxoccurs;
|
||||
private JCheckBox applyWithinTypeHierarchy;
|
||||
private JCheckBox notRegexp;
|
||||
private EditorTextField regexp;
|
||||
JTextField minoccurs;
|
||||
private JTextField minoccurs;
|
||||
private JPanel mainForm;
|
||||
JList<Variable> parameterList;
|
||||
private JList<Variable> parameterList;
|
||||
private JCheckBox partOfSearchResults;
|
||||
private JCheckBox notExprType;
|
||||
private EditorTextField regexprForExprType;
|
||||
final Configuration myConfiguration;
|
||||
private final Configuration myConfiguration;
|
||||
private JCheckBox exprTypeWithinHierarchy;
|
||||
|
||||
final List<Variable> variables;
|
||||
Variable current;
|
||||
private final List<Variable> variables;
|
||||
private Variable current;
|
||||
private JCheckBox wholeWordsOnly;
|
||||
private JCheckBox formalArgTypeWithinHierarchy;
|
||||
private JCheckBox invertFormalArgType;
|
||||
private EditorTextField formalArgType;
|
||||
ComponentWithBrowseButton<EditorTextField> customScriptCode;
|
||||
JCheckBox maxoccursUnlimited;
|
||||
private ComponentWithBrowseButton<EditorTextField> customScriptCode;
|
||||
private JCheckBox maxoccursUnlimited;
|
||||
|
||||
TextFieldWithAutoCompletionWithBrowseButton withinTextField;
|
||||
private TextFieldWithAutoCompletionWithBrowseButton withinTextField;
|
||||
private JPanel containedInConstraints;
|
||||
private JCheckBox invertWithinIn;
|
||||
private JCheckBox invertWithin;
|
||||
private JPanel expressionConstraints;
|
||||
private JPanel occurencePanel;
|
||||
private JPanel textConstraintsPanel;
|
||||
@@ -101,6 +103,9 @@ class EditVarConstraintsDialog extends DialogWrapper {
|
||||
private JButton myZeroInfinityButton;
|
||||
private JButton myOneInfinityButton;
|
||||
private JButton myZeroOneButton;
|
||||
private TextFieldWithAutoCompletionWithBrowseButton refererenceTargetTextField;
|
||||
private JPanel referenceTargetConstraints;
|
||||
private JBCheckBox invertReferenceTarget;
|
||||
|
||||
private final Project myProject;
|
||||
|
||||
@@ -164,20 +169,9 @@ class EditVarConstraintsDialog extends DialogWrapper {
|
||||
|
||||
final List<String> names = ConfigurationManager.getInstance(project).getAllConfigurationNames();
|
||||
withinTextField.setAutoCompletionItems(names);
|
||||
withinTextField.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(@NotNull final ActionEvent e) {
|
||||
final SelectTemplateDialog dialog = new SelectTemplateDialog(project, false, false);
|
||||
dialog.selectConfiguration(withinTextField.getText().trim());
|
||||
dialog.show();
|
||||
if (dialog.getExitCode() == OK_EXIT_CODE) {
|
||||
final Configuration[] selectedConfigurations = dialog.getSelectedConfigurations();
|
||||
if (selectedConfigurations.length == 1) {
|
||||
withinTextField.setText(selectedConfigurations[0].getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
withinTextField.addActionListener(new SelectTemplateListener(project, withinTextField));
|
||||
refererenceTargetTextField.setAutoCompletionItems(names);
|
||||
refererenceTargetTextField.addActionListener(new SelectTemplateListener(project, refererenceTargetTextField));
|
||||
|
||||
boolean hasContextVar = false;
|
||||
for (Variable var : variables) {
|
||||
@@ -356,8 +350,16 @@ class EditVarConstraintsDialog extends DialogWrapper {
|
||||
|
||||
final String withinConstraint = withinTextField.getText().trim();
|
||||
final Configuration configuration = ConfigurationManager.getInstance(myProject).findConfigurationByName(withinConstraint);
|
||||
varInfo.setWithinConstraint(configuration == null && withinConstraint.length() > 0 ? '"' + withinConstraint + '"' : withinConstraint);
|
||||
varInfo.setInvertWithinConstraint(invertWithinIn.isSelected());
|
||||
varInfo.setWithinConstraint(configuration != null || withinConstraint.isEmpty() ? withinConstraint : '"' + withinConstraint + '"');
|
||||
varInfo.setInvertWithinConstraint(invertWithin.isSelected());
|
||||
|
||||
final String referenceTargetConstraint = refererenceTargetTextField.getText().trim();
|
||||
final Configuration configuration2 = ConfigurationManager.getInstance(myProject).findConfigurationByName(referenceTargetConstraint);
|
||||
varInfo.setReferenceConstraint((configuration2 != null || referenceTargetConstraint.isEmpty())
|
||||
? referenceTargetConstraint
|
||||
: '"' + referenceTargetConstraint + '"');
|
||||
varInfo.setInvertReference(invertReferenceTarget.isSelected());
|
||||
|
||||
}
|
||||
|
||||
private static ReplacementVariableDefinition getOrAddReplacementVariableDefinition(String varName, Configuration configuration) {
|
||||
@@ -415,7 +417,9 @@ class EditVarConstraintsDialog extends DialogWrapper {
|
||||
customScriptCode.getChildComponent().setText("");
|
||||
|
||||
withinTextField.setText("");
|
||||
invertWithinIn.setSelected(false);
|
||||
invertWithin.setSelected(false);
|
||||
refererenceTargetTextField.setText("");
|
||||
invertReferenceTarget.setSelected(false);
|
||||
} else {
|
||||
applyWithinTypeHierarchy.setSelected(varInfo.isWithinHierarchy());
|
||||
regexp.getDocument().setText(varInfo.getRegExp());
|
||||
@@ -445,7 +449,9 @@ class EditVarConstraintsDialog extends DialogWrapper {
|
||||
restoreScriptCode(varInfo);
|
||||
|
||||
withinTextField.setText(StringUtil.unquoteString(varInfo.getWithinConstraint()));
|
||||
invertWithinIn.setSelected(varInfo.isInvertWithinConstraint());
|
||||
invertWithin.setSelected(varInfo.isInvertWithinConstraint());
|
||||
refererenceTargetTextField.setText(StringUtil.unquoteString(varInfo.getReferenceConstraint()));
|
||||
invertReferenceTarget.setSelected(varInfo.isInvertReference());
|
||||
}
|
||||
|
||||
final boolean contextVar = Configuration.CONTEXT_VAR_NAME.equals(var.getName());
|
||||
@@ -453,6 +459,7 @@ class EditVarConstraintsDialog extends DialogWrapper {
|
||||
textConstraintsPanel.setVisible(!contextVar);
|
||||
partOfSearchResults.setEnabled(!contextVar);
|
||||
occurencePanel.setVisible(!contextVar);
|
||||
referenceTargetConstraints.setVisible(!contextVar);
|
||||
}
|
||||
|
||||
private void setSearchConstraintsVisible(boolean b) {
|
||||
@@ -559,6 +566,7 @@ class EditVarConstraintsDialog extends DialogWrapper {
|
||||
myRegExHelpLabel = RegExHelpPopup.createRegExLink(SSRBundle.message("regular.expression.help.label"), regexp, LOG);
|
||||
myRegExHelpLabel.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 5));
|
||||
withinTextField = new TextFieldWithAutoCompletionWithBrowseButton(myProject);
|
||||
refererenceTargetTextField = new TextFieldWithAutoCompletionWithBrowseButton(myProject);
|
||||
}
|
||||
|
||||
private EditorTextField createRegexComponent() {
|
||||
@@ -693,4 +701,27 @@ class EditVarConstraintsDialog extends DialogWrapper {
|
||||
super.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
private static class SelectTemplateListener implements ActionListener {
|
||||
private final Project myProject;
|
||||
private final TextAccessor myTextField;
|
||||
|
||||
public SelectTemplateListener(Project project, TextAccessor textField) {
|
||||
myProject = project;
|
||||
myTextField = textField;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(@NotNull final ActionEvent e) {
|
||||
final SelectTemplateDialog dialog = new SelectTemplateDialog(myProject, false, false);
|
||||
dialog.selectConfiguration(myTextField.getText().trim());
|
||||
dialog.show();
|
||||
if (dialog.getExitCode() == OK_EXIT_CODE) {
|
||||
final Configuration[] selectedConfigurations = dialog.getSelectedConfigurations();
|
||||
if (selectedConfigurations.length == 1) {
|
||||
myTextField.setText(selectedConfigurations[0].getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+7
-3
@@ -122,22 +122,26 @@ public class SubstitutionShortInfoHandler implements DocumentListener, EditorMou
|
||||
if (constraint.isPartOfSearchResults()) {
|
||||
append(buf, SSRBundle.message("target.tooltip.message"));
|
||||
}
|
||||
if (constraint.getRegExp() != null && constraint.getRegExp().length() > 0) {
|
||||
if (constraint.getRegExp() != null && !constraint.getRegExp().isEmpty()) {
|
||||
append(buf, SSRBundle.message("text.tooltip.message",
|
||||
constraint.isInvertRegExp() ? SSRBundle.message("not.tooltip.message") : "", constraint.getRegExp()));
|
||||
}
|
||||
if (constraint.isWithinHierarchy() || constraint.isStrictlyWithinHierarchy()) {
|
||||
append(buf, SSRBundle.message("within.hierarchy.tooltip.message"));
|
||||
}
|
||||
if (!StringUtil.isEmpty(constraint.getReferenceConstraint())) {
|
||||
final String text = StringUtil.unquoteString(constraint.getReferenceConstraint());
|
||||
append(buf, "reference target matches: " + text);
|
||||
}
|
||||
|
||||
if (constraint.getNameOfExprType() != null && constraint.getNameOfExprType().length() > 0) {
|
||||
if (constraint.getNameOfExprType() != null && !constraint.getNameOfExprType().isEmpty()) {
|
||||
append(buf, SSRBundle.message("exprtype.tooltip.message",
|
||||
constraint.isInvertExprType() ? SSRBundle.message("not.tooltip.message") : "",
|
||||
constraint.getNameOfExprType(),
|
||||
constraint.isExprTypeWithinHierarchy() ? SSRBundle.message("supertype.tooltip.message") : ""));
|
||||
}
|
||||
|
||||
if (constraint.getNameOfFormalArgType() != null && constraint.getNameOfFormalArgType().length() > 0) {
|
||||
if (constraint.getNameOfFormalArgType() != null && !constraint.getNameOfFormalArgType().isEmpty()) {
|
||||
append(buf, SSRBundle.message("expected.type.tooltip.message",
|
||||
constraint.isInvertFormalType() ? SSRBundle.message("not.tooltip.message") : "",
|
||||
constraint.getNameOfFormalArgType(),
|
||||
|
||||
+56
-11
@@ -1,9 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.structuralsearch.plugin.ui.EditVarConstraintsDialog">
|
||||
<grid id="53af4" binding="mainForm" layout-manager="GridLayoutManager" row-count="8" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<grid id="53af4" binding="mainForm" layout-manager="GridLayoutManager" row-count="9" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<xy x="24" y="82" width="889" height="681"/>
|
||||
<xy x="24" y="82" width="889" height="760"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
@@ -11,7 +11,7 @@
|
||||
<grid id="33d30" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<grid row="0" column="0" row-span="8" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false">
|
||||
<grid row="0" column="0" row-span="9" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false">
|
||||
<minimum-size width="150" height="-1"/>
|
||||
<preferred-size width="150" height="-1"/>
|
||||
<maximum-size width="150" height="-1"/>
|
||||
@@ -89,7 +89,7 @@
|
||||
<grid id="bb81f" binding="expressionConstraints" layout-manager="GridLayoutManager" row-count="4" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<grid row="4" column="1" row-span="1" col-span="2" vsize-policy="0" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
<grid row="5" column="1" row-span="1" col-span="2" vsize-policy="0" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<clientProperties>
|
||||
@@ -165,7 +165,7 @@
|
||||
</grid>
|
||||
<component id="9a3a8" class="javax.swing.JCheckBox" binding="partOfSearchResults">
|
||||
<constraints>
|
||||
<grid row="6" column="1" row-span="1" col-span="2" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
<grid row="7" column="1" row-span="1" col-span="2" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text resource-bundle="messages/SSRBundle" key="editvarcontraints.this.variable.is.target.of.the.search"/>
|
||||
@@ -173,7 +173,7 @@
|
||||
</component>
|
||||
<vspacer id="d06dd">
|
||||
<constraints>
|
||||
<grid row="7" column="1" row-span="1" col-span="2" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
|
||||
<grid row="8" column="1" row-span="1" col-span="2" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
</vspacer>
|
||||
<grid id="d8664" binding="occurencePanel" layout-manager="GridLayoutManager" row-count="2" column-count="4" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
@@ -291,7 +291,7 @@
|
||||
</grid>
|
||||
</children>
|
||||
</grid>
|
||||
<grid id="463bd" binding="containedInConstraints" layout-manager="GridLayoutManager" row-count="2" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<grid id="463bd" binding="containedInConstraints" layout-manager="GridLayoutManager" row-count="2" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<grid row="2" column="1" row-span="1" col-span="2" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
@@ -304,13 +304,21 @@
|
||||
<children>
|
||||
<component id="bfd62" class="com.intellij.structuralsearch.plugin.ui.TextFieldWithAutoCompletionWithBrowseButton" binding="withinTextField" custom-create="true">
|
||||
<constraints>
|
||||
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="2" anchor="8" fill="1" indent="0" use-parent-layout="false"/>
|
||||
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="2" anchor="8" fill="1" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
</component>
|
||||
<component id="896c2" class="javax.swing.JCheckBox" binding="invertWithinIn">
|
||||
<component id="3e748" class="com.intellij.ui.components.JBLabel">
|
||||
<constraints>
|
||||
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text resource-bundle="messages/SSRBundle" key="search.template"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="896c2" class="javax.swing.JCheckBox" binding="invertWithin">
|
||||
<constraints>
|
||||
<grid row="1" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text resource-bundle="messages/SSRBundle" key="editvarcontraints.invert.condition"/>
|
||||
@@ -327,7 +335,7 @@
|
||||
<grid id="964fd" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<grid row="5" column="1" row-span="1" col-span="1" vsize-policy="3" hsize-policy="7" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
<grid row="6" column="1" row-span="1" col-span="1" vsize-policy="3" hsize-policy="7" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<clientProperties>
|
||||
@@ -353,6 +361,43 @@
|
||||
</component>
|
||||
</children>
|
||||
</grid>
|
||||
<grid id="3b230" binding="referenceTargetConstraints" layout-manager="GridLayoutManager" row-count="2" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<grid row="4" column="1" row-span="1" col-span="2" vsize-policy="3" hsize-policy="7" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<clientProperties>
|
||||
<BorderFactoryClass class="java.lang.String" value="com.intellij.ui.IdeBorderFactory$PlainSmallWithIndent"/>
|
||||
</clientProperties>
|
||||
<border type="none" title-resource-bundle="messages/SSRBundle" title-key="var.constraints.reference.target.constraints.border"/>
|
||||
<children>
|
||||
<component id="2e0d7" class="com.intellij.ui.components.JBLabel">
|
||||
<constraints>
|
||||
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text resource-bundle="messages/SSRBundle" key="search.template"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="1ed13" class="com.intellij.structuralsearch.plugin.ui.TextFieldWithAutoCompletionWithBrowseButton" binding="refererenceTargetTextField" custom-create="true" default-binding="true">
|
||||
<constraints>
|
||||
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="0" fill="1" indent="2" use-parent-layout="false">
|
||||
<preferred-size width="150" height="-1"/>
|
||||
</grid>
|
||||
</constraints>
|
||||
<properties/>
|
||||
</component>
|
||||
<component id="308dd" class="com.intellij.ui.components.JBCheckBox" binding="invertReferenceTarget">
|
||||
<constraints>
|
||||
<grid row="1" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text resource-bundle="messages/SSRBundle" key="editvarcontraints.invert.condition"/>
|
||||
</properties>
|
||||
</component>
|
||||
</children>
|
||||
</grid>
|
||||
</children>
|
||||
</grid>
|
||||
</form>
|
||||
|
||||
@@ -107,6 +107,7 @@ predefined.configuration.fields_variables.with.given.name.pattern.updated=fields
|
||||
predefined.configuration.trys=try's
|
||||
predefined.configuration.block.dcls=block dcls
|
||||
predefined.configuration.methods.of.the.class=methods of the class
|
||||
predefined.configuration.deprecated.methods=deprecated methods
|
||||
predefined.configuration.instanceof=instanceof
|
||||
predefined.configuration.implementors.of.interface.within.hierarchy=implementors of interface (within hierarchy)
|
||||
predefined.configuration.generic.casts=generic casts
|
||||
@@ -149,6 +150,7 @@ predefined.configuration.new.expressions=new expressions
|
||||
predefined.configuration.lambdas=lambdas
|
||||
predefined.configuration.method.references=method references
|
||||
predefined.configuration.string.concatenations=string concatenations
|
||||
predefined.configuration.deprecated.method.calls=method calls to deprecated methods
|
||||
|
||||
# edit variable constraint dialog options
|
||||
invalid.regular.expression=Invalid regular expression\: {0}
|
||||
@@ -193,10 +195,11 @@ remove.template.action.name=Remove Template
|
||||
modify.editor.content.command.name=modify editor content
|
||||
var.constraints.variables.border=Variables
|
||||
var.constraints.occurrences.count.border=Occurrences count
|
||||
var.constraints.within.pattern.border=Contained in search template
|
||||
var.constraints.within.pattern.border=Contained in constraints
|
||||
var.constraints.script.constraints.border=Script constraints
|
||||
var.constraints.expression.constraints.border=Expression constraints
|
||||
var.constraints.text.constraints.border=Text constraints
|
||||
var.constraints.reference.target.constraints.border=Reference target constraints
|
||||
different.strategies.for.top.level.nodes.error.message=Different strategies for top level nodes
|
||||
option.is.not.recognized.error.message=Constraint ''{0}'' not recognized
|
||||
|
||||
|
||||
Reference in New Issue
Block a user