From 1307b246ebc894d6574ef7f8eed844ed303f8f50 Mon Sep 17 00:00:00 2001 From: Alena Laskavaia Date: Thu, 29 Jan 2009 22:11:00 +0000 Subject: [PATCH] [261280] - customization for discovery and proper filtration in ui --- .../cdt/make/core/MakeScannerProvider.java | 1 - .../scannerconfig2/DefaultRunSIProvider.java | 23 +++--- .../scannerconfig2/PerFileSICollector.java | 6 +- .../scannerconfig2/SCDMakefileGenerator.java | 79 +++++++++++++++---- .../ui/dialogs/GCCPerFileSCDProfilePage.java | 13 ++- .../dialogs/GCCPerProjectSCDProfilePage.java | 27 +++++-- .../internal/core/InputType.java | 7 ++ .../ui/properties/DiscoveryTab.java | 78 ++++++++++++++++-- 8 files changed, 191 insertions(+), 43 deletions(-) diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/MakeScannerProvider.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/MakeScannerProvider.java index 5755b4f73bc..798f71f4455 100644 --- a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/MakeScannerProvider.java +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/MakeScannerProvider.java @@ -37,7 +37,6 @@ import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.QualifiedName; import org.w3c.dom.Element; -import org.w3c.dom.Node; /** * @deprecated @author DInglis diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig2/DefaultRunSIProvider.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig2/DefaultRunSIProvider.java index b34295c7b38..fbb27d9e62e 100644 --- a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig2/DefaultRunSIProvider.java +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig2/DefaultRunSIProvider.java @@ -105,15 +105,11 @@ public class DefaultRunSIProvider implements IExternalScannerInfoProvider { // Print the command for visual interaction. launcher.showCommand(true); - // add additional arguments - // subclass can change default behavior - String[] compileArguments = prepareArguments( - buildInfo.isUseDefaultProviderCommand(providerId)); - - String ca = coligate(compileArguments); + String[] comandLineOptions = getCommandLineOptions(); + String ca = coligate(comandLineOptions); monitor.subTask(MakeMessages.getString("ExternalScannerInfoProvider.Invoking_Command") //$NON-NLS-1$ - + fCompileCommand.toString() + ca); + + getCommandToLaunch() + ca); cos = new StreamMonitor(new SubProgressMonitor(monitor, 70), cos, 100); ConsoleOutputSniffer sniffer = ScannerInfoConsoleParserFactory.getESIProviderOutputSniffer( @@ -121,7 +117,7 @@ public class DefaultRunSIProvider implements IExternalScannerInfoProvider { OutputStream consoleOut = (sniffer == null ? cos : sniffer.getOutputStream()); OutputStream consoleErr = (sniffer == null ? cos : sniffer.getErrorStream()); TraceUtil.outputTrace("Default provider is executing command:", fCompileCommand.toString() + ca, ""); //$NON-NLS-1$ //$NON-NLS-2$ - Process p = launcher.execute(fCompileCommand, compileArguments, setEnvironment(launcher, env), fWorkingDirectory); + Process p = launcher.execute(getCommandToLaunch(), comandLineOptions, setEnvironment(launcher, env), fWorkingDirectory); if (p != null) { try { // Close the input of the Process explicitely. @@ -158,7 +154,16 @@ public class DefaultRunSIProvider implements IExternalScannerInfoProvider { return true; } - + protected IPath getCommandToLaunch() { + return fCompileCommand; + } + + protected String[] getCommandLineOptions() { + // add additional arguments + // subclass can change default behavior + return prepareArguments( + buildInfo.isUseDefaultProviderCommand(providerId)); + } /** * Initialization of protected fields. diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig2/PerFileSICollector.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig2/PerFileSICollector.java index bef26141494..acc4b13ab6a 100644 --- a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig2/PerFileSICollector.java +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig2/PerFileSICollector.java @@ -60,7 +60,7 @@ import org.w3c.dom.NodeList; * * @author vhirsl */ -public final class PerFileSICollector implements IScannerInfoCollector3, IScannerInfoCollectorCleaner { +public class PerFileSICollector implements IScannerInfoCollector3, IScannerInfoCollectorCleaner { private static final int INCLUDE_PATH = 1; private static final int QUOTE_INCLUDE_PATH = 2; private static final int INCLUDE_FILE = 3; @@ -225,6 +225,10 @@ public final class PerFileSICollector implements IScannerInfoCollector3, IScanne } } + protected InfoContext getInfoContext() { + return context; + } + /* (non-Javadoc) * @see org.eclipse.cdt.make.core.scannerconfig.IScannerInfoCollector#contributeToScannerConfig(java.lang.Object, java.util.Map) */ diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig2/SCDMakefileGenerator.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig2/SCDMakefileGenerator.java index 76e38c4ccf2..aee6dfd21b2 100644 --- a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig2/SCDMakefileGenerator.java +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig2/SCDMakefileGenerator.java @@ -21,7 +21,11 @@ import java.util.List; import org.eclipse.cdt.make.core.MakeCorePlugin; import org.eclipse.cdt.make.core.scannerconfig.IScannerInfoCollector2; import org.eclipse.cdt.make.core.scannerconfig.ScannerInfoTypes; +import org.eclipse.cdt.make.internal.core.scannerconfig.ScannerConfigUtil; +import org.eclipse.cdt.make.internal.core.scannerconfig.gnu.GCCScannerConfigUtil; import org.eclipse.cdt.make.internal.core.scannerconfig.util.CCommandDSC; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; /** @@ -32,24 +36,29 @@ import org.eclipse.cdt.make.internal.core.scannerconfig.util.CCommandDSC; public class SCDMakefileGenerator extends DefaultRunSIProvider { private static final String ENDL = System.getProperty("line.separator"); //$NON-NLS-1$ private static final String DENDL = ENDL+ENDL; - + private String fMakeCommand = "-f ${project_name}_scd.mk "; + /* (non-Javadoc) * @see org.eclipse.cdt.make.internal.core.scannerconfig2.DefaultRunSIProvider#initialize() */ protected boolean initialize() { - boolean rc = super.initialize(); + String args = buildInfo.getProviderRunArguments(providerId); + if (null == args) + args = " -E -P -v -dD "; + else { + int nPos = args.indexOf('|'); + if(nPos > 0) { + fMakeCommand = args.substring(0, nPos); + args = args.substring(nPos + 1); + } + } + fCompileCommand = new Path(buildInfo.getProviderRunCommand(providerId)); + args = substituteDynamicVariables(args); + fCompileArguments = ScannerConfigUtil.tokenizeStringWithQuotes(args, "\"");//$NON-NLS-1$ + fWorkingDirectory = MakeCorePlugin.getWorkingDirectory(); + fMakeCommand = substituteDynamicVariables(fMakeCommand); - if (rc) { - fWorkingDirectory = MakeCorePlugin.getWorkingDirectory(); - // replace string variables in compile arguments - // TODO Vmir - use string variable replacement - for (int i = 0; i < fCompileArguments.length; ++i) { - fCompileArguments[i] = fCompileArguments[i].replaceAll("\\$\\{project_name\\}", //$NON-NLS-1$ - resource.getProject().getName()); - } - rc = generateMakefile(resource.getProject().getName()); - } - return rc; + return generateMakefile(resource.getProject().getName()); } /** @@ -86,14 +95,18 @@ public class SCDMakefileGenerator extends DefaultRunSIProvider { buffer.append(ENDL); buffer.append("\t@echo begin generating scanner info for $@"+ENDL+"\t"); //$NON-NLS-1$ //$NON-NLS-2$ buffer.append(cmd.getSCDRunnableCommand(true, true)); // quote includes and defines - buffer.append(" -E -P -v -dD "); //$NON-NLS-1$ + for (String arg : prepareArguments(buildInfo.isUseDefaultProviderCommand(providerId))) { + buffer.append(' '); + buffer.append(arg); + } + buffer.append(' '); buffer.append(cmd.appliesToCPPFileType() ? "specs.cpp" : "specs.c"); //$NON-NLS-1$ //$NON-NLS-2$ buffer.append(ENDL); buffer.append("\t@echo end generating scanner info for $@"); //$NON-NLS-1$ buffer.append(DENDL); } - File makefile = new File(fWorkingDirectory.toFile(), projectName+"_scd.mk"); //$NON-NLS-1$ + File makefile = new File(fWorkingDirectory.toFile(), getMakeFileName(projectName)); //$NON-NLS-1$ try { PrintStream ps = new PrintStream(new FileOutputStream(makefile)); ps.println(buffer.toString()); @@ -108,4 +121,40 @@ public class SCDMakefileGenerator extends DefaultRunSIProvider { return rc; } + + private String getMakeFileName(String projectName) { + String[] makeArgs = ScannerConfigUtil.tokenizeStringWithQuotes(fMakeCommand, "\"");//$NON-NLS-1$ + boolean found = false; + for(String arg : makeArgs) { + if(found) + return arg; + if(arg.equals("-f")) + found = true; + } + return projectName+"_scd.mk"; + } + + + protected String substituteDynamicVariables(String in) { + String string = in; +// TODO: replace it with Eclipse Dynamic Variable Resolver +// string = VariablesPlugin.getDefault().getStringVariableManager().performStringSubstitution(string, false); + string = string.replaceAll("\\$\\{project_name\\}", //$NON-NLS-1$ + resource.getProject().getName()); + string = string.replaceAll("\\$\\{plugin_state_location\\}", //$NON-NLS-1$ + MakeCorePlugin.getWorkingDirectory().toString()); + string = string.replaceAll("\\$\\{specs_file\\}", + GCCScannerConfigUtil.C_SPECS_FILE ); //$NON-NLS-1$ + return string; + } + + @Override + protected String[] getCommandLineOptions() { + return ScannerConfigUtil.tokenizeStringWithQuotes(fMakeCommand, "\""); + } + + @Override + protected IPath getCommandToLaunch() { + return new Path("make"); + } } diff --git a/build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/ui/dialogs/GCCPerFileSCDProfilePage.java b/build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/ui/dialogs/GCCPerFileSCDProfilePage.java index dc3df52c213..8cd0660705d 100644 --- a/build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/ui/dialogs/GCCPerFileSCDProfilePage.java +++ b/build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/ui/dialogs/GCCPerFileSCDProfilePage.java @@ -11,6 +11,7 @@ package org.eclipse.cdt.make.ui.dialogs; import java.io.File; +import java.util.List; import org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo2; import org.eclipse.cdt.make.internal.core.scannerconfig.jobs.BuildOutputReaderJob; @@ -43,7 +44,6 @@ import org.eclipse.swt.widgets.Text; * @author vhirsl */ public class GCCPerFileSCDProfilePage extends AbstractDiscoveryPage { - private static final String providerId = "makefileGenerator"; //$NON-NLS-1$ private Button bopEnabledButton; private Text bopOpenFileText; @@ -260,7 +260,7 @@ public class GCCPerFileSCDProfilePage extends AbstractDiscoveryPage { buildInfo.setBuildOutputFileActionEnabled(true); buildInfo.setBuildOutputFilePath(getBopOpenFileText()); buildInfo.setBuildOutputParserEnabled(bopEnabledButton.getSelection()); - buildInfo.setProviderOutputParserEnabled(providerId, bopEnabledButton.getSelection()); + buildInfo.setProviderOutputParserEnabled(getProviderIDForSelectedProfile(), bopEnabledButton.getSelection()); } } @@ -273,5 +273,14 @@ public class GCCPerFileSCDProfilePage extends AbstractDiscoveryPage { bopEnabledButton.setSelection(buildInfo.isBuildOutputParserEnabled()); } } + + private String getProviderIDForSelectedProfile() { + IScannerConfigBuilderInfo2 builderInfo = getContainer().getBuildInfo(); + // Provider IDs for selected profile + List providerIDs = builderInfo.getProviderIdList(); + if(providerIDs.size() == 0) + return ""; + return (String)providerIDs.iterator().next(); + } } diff --git a/build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/ui/dialogs/GCCPerProjectSCDProfilePage.java b/build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/ui/dialogs/GCCPerProjectSCDProfilePage.java index 464bfd563e3..5aa64de1c3b 100644 --- a/build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/ui/dialogs/GCCPerProjectSCDProfilePage.java +++ b/build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/ui/dialogs/GCCPerProjectSCDProfilePage.java @@ -11,6 +11,7 @@ package org.eclipse.cdt.make.ui.dialogs; import java.io.File; +import java.util.List; import org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo2; import org.eclipse.cdt.make.internal.core.scannerconfig.jobs.BuildOutputReaderJob; @@ -43,7 +44,6 @@ import org.eclipse.swt.widgets.Text; * @author vhirsl */ public class GCCPerProjectSCDProfilePage extends AbstractDiscoveryPage { - private static final String providerId = "specsFile"; //$NON-NLS-1$ private static Object lock = GCCPerProjectSCDProfilePage.class; private Shell shell; @@ -251,10 +251,22 @@ public class GCCPerProjectSCDProfilePage extends AbstractDiscoveryPage { } private void initializeValues() { - bopEnabledButton.setSelection(getContainer().getBuildInfo().isBuildOutputParserEnabled()); - setBopOpenFileText(getContainer().getBuildInfo().getBuildOutputFilePath()); - sipEnabledButton.setSelection(getContainer().getBuildInfo().isProviderOutputParserEnabled(providerId)); - sipRunCommandText.setText(getContainer().getBuildInfo().getProviderRunCommand(providerId)); + IScannerConfigBuilderInfo2 builderInfo = getContainer().getBuildInfo(); + String providerId = getProviderIDForSelectedProfile(); + + bopEnabledButton.setSelection(builderInfo.isBuildOutputParserEnabled()); + setBopOpenFileText(builderInfo.getBuildOutputFilePath()); + sipEnabledButton.setSelection(builderInfo.isProviderOutputParserEnabled(providerId)); + sipRunCommandText.setText(builderInfo.getProviderRunCommand(providerId)); + } + + private String getProviderIDForSelectedProfile() { + IScannerConfigBuilderInfo2 builderInfo = getContainer().getBuildInfo(); + // Provider IDs for selected profile + List providerIDs = builderInfo.getProviderIdList(); + if(providerIDs.size() == 0) + return ""; + return (String)providerIDs.iterator().next(); } private void handleBOPLoadFileButtonSelected() { @@ -318,7 +330,7 @@ public class GCCPerProjectSCDProfilePage extends AbstractDiscoveryPage { buildInfo.setBuildOutputFileActionEnabled(true); buildInfo.setBuildOutputFilePath(getBopOpenFileText()); buildInfo.setBuildOutputParserEnabled(bopEnabledButton.getSelection()); - + String providerId = getProviderIDForSelectedProfile(); buildInfo.setProviderOutputParserEnabled(providerId, sipEnabledButton.getSelection()); buildInfo.setProviderRunCommand(providerId, sipRunCommandText.getText().trim()); } @@ -331,7 +343,8 @@ public class GCCPerProjectSCDProfilePage extends AbstractDiscoveryPage { if (buildInfo != null) { setBopOpenFileText(buildInfo.getBuildOutputFilePath()); bopEnabledButton.setSelection(buildInfo.isBuildOutputParserEnabled()); - + + String providerId = getProviderIDForSelectedProfile(); sipEnabledButton.setSelection(buildInfo.isProviderOutputParserEnabled(providerId)); sipRunCommandText.setText(buildInfo.getProviderRunCommand(providerId)); } diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/InputType.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/InputType.java index 5afe4d38501..26b3a450e4d 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/InputType.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/InputType.java @@ -1818,6 +1818,13 @@ public class InputType extends BuildObject implements IInputType { if(id == null){ id = ((Tool)tool).getDiscoveryProfileId(); } + // if there is more than one ('|'-separated), return the first one + // TODO: expand interface with String[] getDiscoveryProfileIds(ITool tool) + if(null != id) { + int nPos = id.indexOf('|'); + if (nPos > 0) + id = id.substring(0, nPos); + } return id; } diff --git a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/properties/DiscoveryTab.java b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/properties/DiscoveryTab.java index 1d8db0c0c67..1dc76782fb7 100644 --- a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/properties/DiscoveryTab.java +++ b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/properties/DiscoveryTab.java @@ -33,6 +33,8 @@ import org.eclipse.cdt.managedbuilder.core.IConfiguration; import org.eclipse.cdt.managedbuilder.core.IInputType; import org.eclipse.cdt.managedbuilder.core.IResourceInfo; import org.eclipse.cdt.managedbuilder.core.ITool; +import org.eclipse.cdt.managedbuilder.internal.core.InputType; +import org.eclipse.cdt.managedbuilder.internal.core.Tool; import org.eclipse.cdt.ui.CUIPlugin; import org.eclipse.cdt.ui.newui.CDTPrefUtil; import org.eclipse.cdt.ui.newui.UIMessages; @@ -54,6 +56,7 @@ import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Combo; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Group; +import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableItem; @@ -71,6 +74,7 @@ public class DiscoveryTab extends AbstractCBuildPropertyTab implements IBuildInf private static final String PROFILE_NAME = "name"; //$NON-NLS-1$ private static final int DEFAULT_HEIGHT = 110; private static final int[] DEFAULT_SASH_WEIGHTS = new int[] { 10, 20 }; + private Label fTableDefinition; private Table resTable; private Button scEnabledButton; private Button scProblemReportingEnabledButton; @@ -118,9 +122,16 @@ public class DiscoveryTab extends AbstractCBuildPropertyTab implements IBuildInf sashForm = new SashForm(usercomp, SWT.NONE); sashForm.setOrientation(SWT.HORIZONTAL); sashForm.setLayoutData(new GridData(GridData.FILL_BOTH)); - - resTable = new Table(sashForm, SWT.SINGLE|SWT.H_SCROLL|SWT.V_SCROLL|SWT.BORDER); - GridData gd = new GridData(GridData.FILL_VERTICAL); + + Composite comp = new Composite(sashForm, SWT.NONE); + comp.setLayout(new GridLayout(1, true)); + comp.setLayoutData(new GridData(GridData.FILL_BOTH)); + + fTableDefinition = new Label(comp, SWT.LEFT); + fTableDefinition.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + resTable = new Table(comp, SWT.SINGLE|SWT.H_SCROLL|SWT.V_SCROLL|SWT.BORDER); + GridData gd = new GridData(GridData.FILL_BOTH); gd.widthHint = 150; resTable.setLayoutData(gd); resTable.addSelectionListener(new SelectionAdapter() { @@ -205,8 +216,16 @@ public class DiscoveryTab extends AbstractCBuildPropertyTab implements IBuildInf } private void updateData() { - if (scopeComboBox != null) - scopeComboBox.select(cbi.isPerRcTypeDiscovery() ? 0 : 1); + int selScope = 0; + String lblText = "Tools:"; + if(!cbi.isPerRcTypeDiscovery()) { + selScope = 1; + lblText = "Configuration:"; + } + if (scopeComboBox != null) + scopeComboBox.select(selScope); + fTableDefinition.setText(lblText); + Map m = cbi.getInfoMap(); int pos = resTable.getSelectionIndex(); @@ -291,9 +310,41 @@ public class DiscoveryTab extends AbstractCBuildPropertyTab implements IBuildInf int counter = 0; int pos = 0; String savedId = buildInfo.getSelectedProfileId(); + ITool[] tools = null; + Tool tool = (Tool)iContext.getTool(); + if(null == tool) { + IConfiguration conf = iContext.getConfiguration(); + if(null != conf) { + tools = conf.getToolChain().getTools(); + } + if(null == tools) + return; + } + else + tools = new ITool[] { tool }; + for (String profileId : profilesList) { - if (!cbi.isProfileSupported(iContext, profileId)) - continue; + boolean ok = false; + for(int i = 0; i < tools.length; ++i) { + IInputType[] inputTypes = ((Tool)tools[i]).getAllInputTypes(); + if(null != inputTypes) { + for(IInputType it : inputTypes) { + String[] requiedProfiles = getDiscoveryProfileIds(tools[i], it); + if(null != requiedProfiles) { + for(String requiredProfile : requiedProfiles) { + if(profileId.equals(requiredProfile)) { + ok = true; + break; + } + } + } + } + } + if(ok) + break; + } + if(!ok) + continue; visibleProfilesList.add(profileId); labels[counter] = profiles[counter] = getProfileName(profileId); if (profileId.equals(savedId)) @@ -325,7 +376,18 @@ public class DiscoveryTab extends AbstractCBuildPropertyTab implements IBuildInf handleDiscoveryProfileChanged(); } - private String[] normalize(String[] labels, String[] ids, int counter) { + private String[] getDiscoveryProfileIds(ITool iTool, IInputType it) { + String attribute = ((InputType)it).getDiscoveryProfileIdAttribute(); + if(null == attribute) + return new String[0]; + // FIXME: temporary; we should add new method to IInputType instead of that + String[] profileIds = attribute.split("\\|"); + for(int i = 0; i < profileIds.length; ++i) + profileIds[i] = profileIds[i].trim(); + return profileIds; + } + + private String[] normalize(String[] labels, String[] ids, int counter) { int mode = CDTPrefUtil.getInt(CDTPrefUtil.KEY_DISC_NAMES); String[] tmp = new String[counter]; // Always show either Name + ID, or ID only