mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-06-07 17:56:01 +02:00
Add 'Expert settings' with Command line pattern to tool options page
Apply patch for Bugzilla 121994 - "Show All Project Types" checkbox resets "Project Type" dropdown
This commit is contained in:
parent
636fd2d51a
commit
1ebfda405f
6 changed files with 210 additions and 69 deletions
|
@ -1,5 +1,5 @@
|
|||
###############################################################################
|
||||
# Copyright (c) 2000, 2005 IBM Corporation and others.
|
||||
# Copyright (c) 2000, 2006 IBM Corporation and others.
|
||||
# All rights reserved. This program and the accompanying materials
|
||||
# are made available under the terms of the Eclipse Public License v1.0
|
||||
# which accompanies this distribution, and is available at
|
||||
|
@ -299,11 +299,13 @@ BuildPropertyCommon.label.browse=Browse...
|
|||
BuildPropertyCommon.label.configs=Defined configurations:
|
||||
|
||||
# ----------- Field Editors -----------
|
||||
FieldEditors.tool.command=Command:
|
||||
Multiline.error.message=Please give correct input
|
||||
|
||||
# ----------- Default flag names -----------
|
||||
# ----------- Build Tool Settings -----------
|
||||
BuildToolSettingsPage.alloptions=All options:
|
||||
BuildToolSettingsPage.tool.command=Command:
|
||||
BuildToolSettingsPage.tool.commandLinePattern=Command\nline pattern:
|
||||
BuildToolSettingsPage.tool.advancedSettings=Expert settings:
|
||||
|
||||
# ----------- File List Control -----------
|
||||
FileListControl.add=Add
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2002, 2005 IBM Corporation and others.
|
||||
* Copyright (c) 2002, 2006 IBM Corporation and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
|
@ -537,8 +537,10 @@ public class ToolsSettingsBlock extends AbstractCOptionPage {
|
|||
ManagedBuildManager.resetConfiguration(parent.getProject(), parent.getSelectedConfigurationClone());
|
||||
ITool tools[] = parent.getSelectedConfigurationClone().getFilteredTools();
|
||||
for( int i = 0; i < tools.length; i++ ){
|
||||
if(!tools[i].getCustomBuildStep())
|
||||
if(!tools[i].getCustomBuildStep()) {
|
||||
tools[i].setToolCommand(null);
|
||||
tools[i].setCommandLinePattern(null);
|
||||
}
|
||||
}
|
||||
|
||||
// Reset the category or tool selection and run selection event handler
|
||||
|
@ -557,8 +559,10 @@ public class ToolsSettingsBlock extends AbstractCOptionPage {
|
|||
ManagedBuildManager.resetResourceConfiguration(resParent.getProject(), resParent.getCurrentResourceConfigClone());
|
||||
ITool tools[] = resParent.getCurrentResourceConfigClone().getTools();
|
||||
for( int i = 0; i < tools.length; i++ ){
|
||||
if(!tools[i].getCustomBuildStep())
|
||||
if(!tools[i].getCustomBuildStep()) {
|
||||
tools[i].setToolCommand(null);
|
||||
tools[i].setCommandLinePattern(null);
|
||||
}
|
||||
}
|
||||
|
||||
// Reset the category or tool selection and run selection event handler
|
||||
|
@ -621,32 +625,57 @@ public class ToolsSettingsBlock extends AbstractCOptionPage {
|
|||
IHoldsOptions realHo = page.getRealHoldsOptions(holder);
|
||||
|
||||
if(realHo != null){
|
||||
if(holder instanceof ITool)
|
||||
((ITool)realHo).setToolCommand(((ITool)holder).getToolCommand());
|
||||
|
||||
IOption options[] = holder.getOptions();
|
||||
for(int i = 0; i < options.length; i++){
|
||||
saveOption(options[i], holder);
|
||||
}
|
||||
}
|
||||
}
|
||||
private void saveOption(IOption clonedOption, IHoldsOptions cloneHolder){
|
||||
IHoldsOptions realHolder;
|
||||
IConfiguration realCfg = null;
|
||||
IResourceConfiguration realRcCfg = null;
|
||||
// IBuildObject handler = null;
|
||||
if(resParent != null){
|
||||
realHolder = resParent.getRealHoldsOptions(holder);
|
||||
realRcCfg = (IResourceConfiguration)((ITool)realHolder).getParent();
|
||||
realCfg = realRcCfg.getParent();
|
||||
} else {
|
||||
realHolder = parent.getRealHoldsOptions(holder);
|
||||
realCfg = parent.getConfigurationFromHoldsOptions(realHolder);
|
||||
}
|
||||
if(holder instanceof ITool) {
|
||||
String currentValue = ((ITool)realHo).getToolCommand();
|
||||
if (!(currentValue.equals(((ITool)holder).getToolCommand()))) {
|
||||
((ITool)realHo).setToolCommand(((ITool)holder).getToolCommand());
|
||||
//if(resParent != null){
|
||||
// TODO: This causes the entire project to be rebuilt. Is there a way to only have this
|
||||
// file rebuilt? "Clean" its output? Change its modification date?
|
||||
//realCfg.setRebuildState(true);
|
||||
//} else {
|
||||
realCfg.setRebuildState(true);
|
||||
//}
|
||||
}
|
||||
currentValue = ((ITool)realHo).getCommandLinePattern();
|
||||
if (!(currentValue.equals(((ITool)holder).getCommandLinePattern()))) {
|
||||
((ITool)realHo).setCommandLinePattern(((ITool)holder).getCommandLinePattern());
|
||||
//if(resParent != null){
|
||||
// TODO: This causes the entire project to be rebuilt. Is there a way to only have this
|
||||
// file rebuilt? "Clean" its output? Change its modification date?
|
||||
//realCfg.setRebuildState(true);
|
||||
//} else {
|
||||
realCfg.setRebuildState(true);
|
||||
//}
|
||||
}
|
||||
}
|
||||
IOption options[] = holder.getOptions();
|
||||
for(int i = 0; i < options.length; i++){
|
||||
saveOption(options[i], holder, realHolder, realCfg, realRcCfg);
|
||||
}
|
||||
}
|
||||
}
|
||||
private void saveOption(IOption clonedOption, IHoldsOptions cloneHolder,
|
||||
IHoldsOptions realHolder, IConfiguration realCfg, IResourceConfiguration realRcCfg){
|
||||
IOption realOption;
|
||||
IHoldsOptions realHolder;
|
||||
// IBuildObject handler = null;
|
||||
|
||||
if(resParent != null){
|
||||
realOption = resParent.getRealOption(clonedOption,cloneHolder);
|
||||
realHolder = resParent.getRealHoldsOptions(cloneHolder);
|
||||
realRcCfg = (IResourceConfiguration)((ITool)realHolder).getParent();
|
||||
realCfg = realRcCfg.getParent();
|
||||
// handler = realRcCfg;
|
||||
} else {
|
||||
realOption = parent.getRealOption(clonedOption,cloneHolder);
|
||||
realHolder = parent.getRealHoldsOptions(cloneHolder);
|
||||
realCfg = parent.getConfigurationFromHoldsOptions(realHolder);
|
||||
// handler = realCfg;
|
||||
}
|
||||
|
||||
|
@ -770,6 +799,13 @@ public class ToolsSettingsBlock extends AbstractCOptionPage {
|
|||
for(int i = 0; i < tools.length; i++){
|
||||
ITool tool = tools[i];
|
||||
if(!tool.getCustomBuildStep()){
|
||||
ITool cfgTool = cfg.getToolChain().getTool(tool.getSuperClass().getId());
|
||||
// Check for a non-default command or command-line-pattern
|
||||
if(cfgTool != null){
|
||||
if (!(tool.getToolCommand().equals(cfgTool.getToolCommand()))) return false;
|
||||
if (!(tool.getCommandLinePattern().equals(cfgTool.getCommandLinePattern()))) return false;
|
||||
}
|
||||
// Check for a non-default option
|
||||
IOption options[] = tool.getOptions();
|
||||
for( int j = 0; j < options.length; j++){
|
||||
IOption option = options[j];
|
||||
|
@ -781,7 +817,6 @@ public class ToolsSettingsBlock extends AbstractCOptionPage {
|
|||
} while((ext = ext.getSuperClass()) != null);
|
||||
|
||||
if(ext != null){
|
||||
ITool cfgTool = cfg.getToolChain().getTool(tool.getSuperClass().getId());
|
||||
if(cfgTool != null){
|
||||
IOption defaultOpt = cfgTool.getOptionBySuperClassId(ext.getId());
|
||||
try {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2004, 2005 IBM Corporation and others.
|
||||
* Copyright (c) 2004, 2006 IBM Corporation and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
|
@ -18,44 +18,91 @@ import java.util.List;
|
|||
import java.util.Set;
|
||||
import java.util.Vector;
|
||||
|
||||
import org.eclipse.cdt.internal.ui.util.PixelConverter;
|
||||
import org.eclipse.cdt.managedbuilder.core.BuildException;
|
||||
import org.eclipse.cdt.managedbuilder.core.IBuildObject;
|
||||
import org.eclipse.cdt.managedbuilder.core.IConfiguration;
|
||||
import org.eclipse.cdt.managedbuilder.core.IManagedOptionValueHandler;
|
||||
import org.eclipse.cdt.managedbuilder.core.IOption;
|
||||
import org.eclipse.cdt.managedbuilder.core.IOptionCategory;
|
||||
import org.eclipse.cdt.managedbuilder.core.IResourceConfiguration;
|
||||
import org.eclipse.cdt.managedbuilder.core.ITool;
|
||||
import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager;
|
||||
import org.eclipse.cdt.managedbuilder.internal.core.Tool;
|
||||
import org.eclipse.cdt.managedbuilder.internal.macros.BuildMacroProvider;
|
||||
import org.eclipse.cdt.managedbuilder.internal.macros.DefaultMacroSubstitutor;
|
||||
import org.eclipse.cdt.managedbuilder.internal.macros.IMacroContextInfo;
|
||||
import org.eclipse.cdt.managedbuilder.internal.macros.IMacroSubstitutor;
|
||||
import org.eclipse.cdt.managedbuilder.internal.macros.MacroResolver;
|
||||
import org.eclipse.cdt.managedbuilder.internal.macros.MbsMacroSupplier;
|
||||
import org.eclipse.cdt.managedbuilder.internal.ui.ManagedBuilderUIMessages;
|
||||
import org.eclipse.cdt.managedbuilder.macros.BuildMacroException;
|
||||
import org.eclipse.cdt.managedbuilder.macros.IBuildMacro;
|
||||
import org.eclipse.jface.preference.FieldEditor;
|
||||
import org.eclipse.jface.preference.StringFieldEditor;
|
||||
import org.eclipse.jface.util.PropertyChangeEvent;
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.graphics.Point;
|
||||
import org.eclipse.swt.layout.GridData;
|
||||
import org.eclipse.swt.widgets.Composite;
|
||||
import org.eclipse.swt.widgets.Label;
|
||||
|
||||
public class BuildToolSettingsPage extends BuildSettingsPage {
|
||||
|
||||
// Label class for a preference page.
|
||||
class LabelFieldEditor extends FieldEditor {
|
||||
|
||||
private String fTitle;
|
||||
|
||||
private Label fTitleLabel;
|
||||
|
||||
public LabelFieldEditor( Composite parent, String title ) {
|
||||
fTitle = title;
|
||||
this.createControl( parent );
|
||||
}
|
||||
|
||||
protected void adjustForNumColumns( int numColumns ) {
|
||||
((GridData)fTitleLabel.getLayoutData()).horizontalSpan = 2;
|
||||
}
|
||||
|
||||
protected void doFillIntoGrid( Composite parent, int numColumns ) {
|
||||
fTitleLabel = new Label( parent, SWT.WRAP );
|
||||
fTitleLabel.setText( fTitle );
|
||||
GridData gd = new GridData();
|
||||
gd.verticalAlignment = SWT.TOP;
|
||||
gd.grabExcessHorizontalSpace = false;
|
||||
gd.horizontalSpan = 2;
|
||||
fTitleLabel.setLayoutData( gd );
|
||||
}
|
||||
|
||||
public int getNumberOfControls() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* The label field editor is only used to present a text label on a preference page.
|
||||
*/
|
||||
protected void doLoad() {
|
||||
}
|
||||
|
||||
protected void doLoadDefault() {
|
||||
}
|
||||
|
||||
protected void doStore() {
|
||||
}
|
||||
}
|
||||
|
||||
// Data members
|
||||
|
||||
// all build options field editor label
|
||||
private static final String ALL_OPTIONS = ManagedBuilderUIMessages.getResourceString("BuildToolSettingsPage.alloptions"); //$NON-NLS-1$
|
||||
// Field editor label
|
||||
private static final String COMMAND = "FieldEditors.tool.command"; //$NON-NLS-1$
|
||||
// Field editor label for tool command
|
||||
private static final String COMMAND = "BuildToolSettingsPage.tool.command"; //$NON-NLS-1$
|
||||
// Advanced settings label
|
||||
private static final String ADVANCED_GROUP = "BuildToolSettingsPage.tool.advancedSettings"; //$NON-NLS-1$
|
||||
// Field editor label for tool command line pattern
|
||||
private static final String COMMAND_LINE_PATTERN = "BuildToolSettingsPage.tool.commandLinePattern"; //$NON-NLS-1$
|
||||
|
||||
private static final String DEFAULT_SEPERATOR = ";"; //$NON-NLS-1$
|
||||
// Whitespace character
|
||||
private static final String WHITESPACE = " "; //$NON-NLS-1$
|
||||
// Empty String
|
||||
private static final String EMPTY_STRING = ""; //$NON-NLS-1$
|
||||
//private static final String EMPTY_STRING = ""; //$NON-NLS-1$
|
||||
// field editor that displays all the build options for a particular tool
|
||||
private MultiLineTextFieldEditor allOptionFieldEditor;
|
||||
//tool command command
|
||||
//tool command field
|
||||
private StringFieldEditor commandStringField;
|
||||
//tool command-line-pattern field
|
||||
private StringFieldEditor commandLinePatternField;
|
||||
// A list of safe options to put unrecognized values in
|
||||
private Vector defaultOptionNames;
|
||||
// Map that holds all string options and its values
|
||||
|
@ -106,16 +153,51 @@ public class BuildToolSettingsPage extends BuildSettingsPage {
|
|||
// Load up the preference store
|
||||
super.createFieldEditors();
|
||||
// Add a string editor to edit the tool command
|
||||
Composite parent = getFieldEditorParent();
|
||||
PixelConverter converter = new PixelConverter(parent);
|
||||
commandStringField = new StringFieldEditor(clonedTool.getId(),
|
||||
ManagedBuilderUIMessages.getResourceString(COMMAND),
|
||||
getFieldEditorParent());
|
||||
parent);
|
||||
commandStringField.setEmptyStringAllowed(false);
|
||||
GridData gd = ((GridData)commandStringField.getTextControl(parent).getLayoutData());
|
||||
gd.grabExcessHorizontalSpace = true;
|
||||
gd.minimumWidth = converter.convertWidthInCharsToPixels(3);
|
||||
addField(commandStringField);
|
||||
// Add a field editor that displays overall build options
|
||||
allOptionFieldEditor = new MultiLineTextFieldEditor(BuildToolSettingsPreferenceStore.ALL_OPTIONS_ID,
|
||||
ALL_OPTIONS, getFieldEditorParent());
|
||||
allOptionFieldEditor.getTextControl().setEditable(false);
|
||||
gd = ((GridData)allOptionFieldEditor.getTextControl().getLayoutData());
|
||||
gd.grabExcessHorizontalSpace = true;
|
||||
gd.minimumWidth = converter.convertWidthInCharsToPixels(20);
|
||||
addField(allOptionFieldEditor);
|
||||
|
||||
// Create the Advanced Settings group
|
||||
createAdvancedSettingsGroup(converter);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* Creates the group that contains the build artifact name controls.
|
||||
*/
|
||||
private void createAdvancedSettingsGroup(PixelConverter converter) {
|
||||
addField( createLabelEditor( getFieldEditorParent(), WHITESPACE ) ); //$NON-NLS-1$
|
||||
addField( createLabelEditor( getFieldEditorParent(), ManagedBuilderUIMessages.getResourceString(ADVANCED_GROUP) ) );
|
||||
|
||||
// Add a string editor to edit the tool command line pattern
|
||||
Composite parent = getFieldEditorParent();
|
||||
commandLinePatternField = new StringFieldEditor(BuildToolSettingsPreferenceStore.COMMAND_LINE_PATTERN_ID,
|
||||
ManagedBuilderUIMessages.getResourceString(COMMAND_LINE_PATTERN),
|
||||
parent);
|
||||
GridData gd = ((GridData)commandLinePatternField.getTextControl(parent).getLayoutData());
|
||||
gd.grabExcessHorizontalSpace = true;
|
||||
gd.widthHint = converter.convertWidthInCharsToPixels(30);
|
||||
gd.minimumWidth = converter.convertWidthInCharsToPixels(20);
|
||||
addField(commandLinePatternField);
|
||||
|
||||
}
|
||||
|
||||
protected FieldEditor createLabelEditor( Composite parent, String title ) {
|
||||
return new LabelFieldEditor( parent, title );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -232,7 +314,7 @@ public class BuildToolSettingsPage extends BuildSettingsPage {
|
|||
IOption[] options = clonedTool.getOptions();
|
||||
for (int k = 0; k < options.length; ++k) {
|
||||
IOption opt = options[k];
|
||||
String name = opt.getId();
|
||||
//String name = opt.getId();
|
||||
// check whether the option value is "STRING" type
|
||||
Iterator stringOptsIter = stringOptionsMap.values().iterator();
|
||||
while (stringOptsIter.hasNext()) {
|
||||
|
@ -346,9 +428,9 @@ public class BuildToolSettingsPage extends BuildSettingsPage {
|
|||
IOption[] options = clonedTool.getOptions();
|
||||
for (int k = 0; k < options.length; ++k) {
|
||||
IOption opt = options[k];
|
||||
String name = opt.getId();
|
||||
String listStr = ""; //$NON-NLS-1$
|
||||
String[] listVal = null;
|
||||
//String name = opt.getId();
|
||||
//String listStr = ""; //$NON-NLS-1$
|
||||
//String[] listVal = null;
|
||||
try {
|
||||
switch (opt.getValueType()) {
|
||||
case IOption.BOOLEAN :
|
||||
|
@ -565,6 +647,14 @@ public class BuildToolSettingsPage extends BuildSettingsPage {
|
|||
}
|
||||
}
|
||||
|
||||
// Save the tool command line pattern if it has changed
|
||||
// Get the actual value out of the field editor
|
||||
String commandLinePattern = clonedTool.getCommandLinePattern();
|
||||
if (commandLinePattern.length() > 0 &&
|
||||
(!commandLinePattern.equals(tool.getCommandLinePattern()))) {
|
||||
tool.setCommandLinePattern(commandLinePattern);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -584,6 +674,7 @@ public class BuildToolSettingsPage extends BuildSettingsPage {
|
|||
|
||||
public void setValues(){
|
||||
commandStringField.load();
|
||||
commandLinePatternField.load();
|
||||
updateAllOptionField();
|
||||
}
|
||||
|
||||
|
@ -595,5 +686,8 @@ public class BuildToolSettingsPage extends BuildSettingsPage {
|
|||
clonedTool.setToolCommand(commandStringField.getStringValue());
|
||||
updateAllOptionField();
|
||||
}
|
||||
else if(event.getSource() == commandLinePatternField){
|
||||
clonedTool.setCommandLinePattern(commandLinePatternField.getStringValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2005 Intel Corporation and others.
|
||||
* Copyright (c) 2005, 2006 Intel Corporation and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
|
@ -39,6 +39,7 @@ public class BuildToolSettingsPreferenceStore implements IPreferenceStore {
|
|||
private final static String WHITESPACE = " "; //$NON-NLS-1$
|
||||
|
||||
public final static String ALL_OPTIONS_ID = EMPTY_STRING;
|
||||
public final static String COMMAND_LINE_PATTERN_ID = "org.eclipse.commandLinePatternId";
|
||||
private IConfiguration config;
|
||||
private IResourceConfiguration rcConfig;
|
||||
private IOptionCategory optCategory;
|
||||
|
@ -137,6 +138,8 @@ public class BuildToolSettingsPreferenceStore implements IPreferenceStore {
|
|||
if(optCategory instanceof Tool){
|
||||
if(optCategory.getId().equals(name))
|
||||
return true;
|
||||
else if(COMMAND_LINE_PATTERN_ID.equals(name))
|
||||
return true;
|
||||
else if(ALL_OPTIONS_ID.equals(name))
|
||||
return true;
|
||||
} else if(getOptionValue(name) != null){
|
||||
|
@ -210,6 +213,8 @@ public class BuildToolSettingsPreferenceStore implements IPreferenceStore {
|
|||
if(optCategory instanceof Tool){
|
||||
if(optCategory.getId().equals(name))
|
||||
return ((Tool)optCategory).getToolCommand();
|
||||
else if(COMMAND_LINE_PATTERN_ID.equals(name))
|
||||
return ((Tool)optCategory).getCommandLinePattern();
|
||||
else if(ALL_OPTIONS_ID.equals(name)){
|
||||
try {
|
||||
return listToString(((Tool)optCategory).getToolCommandFlags(
|
||||
|
@ -338,6 +343,8 @@ public class BuildToolSettingsPreferenceStore implements IPreferenceStore {
|
|||
if(optCategory instanceof Tool){
|
||||
if(optCategory.getId().equals(name))
|
||||
((Tool)optCategory).setToolCommand(value);
|
||||
else if (COMMAND_LINE_PATTERN_ID.equals(name))
|
||||
((Tool)optCategory).setCommandLinePattern(value);
|
||||
} else
|
||||
setOptionValue(name,value);
|
||||
}
|
||||
|
|
|
@ -504,6 +504,7 @@ public class ResourceBuildPropertyPage extends AbstractBuildPropertyPage impleme
|
|||
}
|
||||
|
||||
public boolean containsDefaults(){
|
||||
// Check for a non-default "excluded" value
|
||||
if(getCurrentResourceConfigClone().isExcluded() != DEFAULT_EXCLUDE_VALUE)
|
||||
return false;
|
||||
return fOptionBlock.containsDefaults();
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2002, 2005 IBM Corporation and others.
|
||||
* Copyright (c) 2002, 2006 IBM Corporation and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
|
@ -189,8 +189,10 @@ public class CProjectPlatformPage extends WizardPage {
|
|||
showAllProjTypes.addListener(SWT.Selection, new Listener() {
|
||||
public void handleEvent(Event e) {
|
||||
populateTypes();
|
||||
platformSelection.select(0);
|
||||
handleTypeSelection();
|
||||
IProjectType type = projectTypes.contains(selectedProjectType)
|
||||
? selectedProjectType
|
||||
: (IProjectType) projectTypes.get(0);
|
||||
setSelectedProjectType(type);
|
||||
}
|
||||
});
|
||||
showAllProjTypes.addDisposeListener(new DisposeListener() {
|
||||
|
|
Loading…
Add table
Reference in a new issue