From ac50c3aedfd4e18a3770315708ac4de47906eec4 Mon Sep 17 00:00:00 2001 From: Raphael Date: Sun, 12 Jul 2009 16:05:40 -0400 Subject: [PATCH] ADT XML extract string IDs: display existing IDs of the selected file. --- .../extractstring/ExtractStringInputPage.java | 44 +++++++++++++--- .../extractstring/XmlStringFileHelper.java | 60 +++++++++++++--------- 2 files changed, 71 insertions(+), 33 deletions(-) diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/extractstring/ExtractStringInputPage.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/extractstring/ExtractStringInputPage.java index 8b5e3573..286f252f 100644 --- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/extractstring/ExtractStringInputPage.java +++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/extractstring/ExtractStringInputPage.java @@ -33,6 +33,8 @@ import org.eclipse.ltk.ui.refactoring.UserInputWizardPage; import org.eclipse.swt.SWT; import org.eclipse.swt.events.ModifyEvent; import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Combo; @@ -42,6 +44,7 @@ import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Text; import java.util.HashMap; +import java.util.Set; import java.util.TreeSet; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -59,7 +62,7 @@ class ExtractStringInputPage extends UserInputWizardPage implements IWizardPage private final IProject mProject; /** Text field where the user enters the new ID to be generated or replaced with. */ - private Text mStringIdField; + private Combo mStringIdCombo; /** Text field where the user enters the new string value. */ private Text mStringValueField; /** The configuration selector, to select the resource path of the XML file. */ @@ -163,18 +166,24 @@ class ExtractStringInputPage extends UserInputWizardPage implements IWizardPage label.setText("ID &R.string."); } - mStringIdField = new Text(group, SWT.SINGLE | SWT.LEFT | SWT.BORDER); - mStringIdField.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - mStringIdField.setText(guessId(selectedString)); - mStringIdField.forceFocus(); + mStringIdCombo = new Combo(group, SWT.SINGLE | SWT.LEFT | SWT.BORDER | SWT.DROP_DOWN); + mStringIdCombo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + mStringIdCombo.setText(guessId(selectedString)); + mStringIdCombo.forceFocus(); - ref.setNewStringId(mStringIdField.getText().trim()); + ref.setNewStringId(mStringIdCombo.getText().trim()); - mStringIdField.addModifyListener(new ModifyListener() { + mStringIdCombo.addModifyListener(new ModifyListener() { public void modifyText(ModifyEvent e) { validatePage(); } }); + mStringIdCombo.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + validatePage(); + } + }); } /** @@ -270,7 +279,7 @@ class ExtractStringInputPage extends UserInputWizardPage implements IWizardPage // Analyze fatal errors. - String text = mStringIdField.getText().trim(); + String text = mStringIdCombo.getText().trim(); if (text == null || text.length() < 1) { setErrorMessage("Please provide a resource ID."); success = false; @@ -342,6 +351,23 @@ class ExtractStringInputPage extends UserInputWizardPage implements IWizardPage return success; } + private void updateStringValueCombo() { + String resFile = mResFileCombo.getText(); + Set ids = mXmlHelper.getResIdsForFile(mProject, resFile); + + // get the current text from the combo, to make sure we don't change it + String currText = mStringIdCombo.getText(); + + // erase the choices and fill with the given ids + mStringIdCombo.removeAll(); + mStringIdCombo.setItems(ids.toArray(new String[ids.size()])); + + // set the current text to preserve it in case it changed + if (!currText.equals(mStringIdCombo.getText())) { + mStringIdCombo.setText(currText); + } + } + public class OnConfigSelectorUpdated implements Runnable, ModifyListener { /** Regex pattern to parse a valid res path: it reads (/res/folder-name/)+(filename). */ @@ -458,6 +484,7 @@ class ExtractStringInputPage extends UserInputWizardPage implements IWizardPage } // finally validate the whole page + updateStringValueCombo(); validatePage(); } @@ -510,6 +537,7 @@ class ExtractStringInputPage extends UserInputWizardPage implements IWizardPage } } + updateStringValueCombo(); validatePage(); } } diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/extractstring/XmlStringFileHelper.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/extractstring/XmlStringFileHelper.java index 773dc1cf..6a1beebe 100644 --- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/extractstring/XmlStringFileHelper.java +++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/extractstring/XmlStringFileHelper.java @@ -4,7 +4,7 @@ * Licensed under the Eclipse Public License, Version 1.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.eclipse.org/org/documents/epl-v10.php * * Unless required by applicable law or agreed to in writing, software @@ -26,68 +26,78 @@ import org.w3c.dom.NodeList; import org.xml.sax.InputSource; import java.util.HashMap; -import java.util.HashSet; +import java.util.Set; +import java.util.TreeSet; import javax.xml.xpath.XPath; import javax.xml.xpath.XPathConstants; import javax.xml.xpath.XPathExpressionException; /** - * + * An helper utility to get IDs out of an Android XML resource file. */ class XmlStringFileHelper { /** A temporary cache of R.string IDs defined by a given xml file. The key is the * project path of the file, the data is a set of known string Ids for that file. */ - private HashMap> mResIdCache; + private HashMap> mResIdCache = new HashMap>(); /** An instance of XPath, created lazily on demand. */ private XPath mXPath; public XmlStringFileHelper() { } - + /** * Utility method used by the wizard to check whether the given string ID is already * defined in the XML file which path is given. - * - * @param project The project contain the XML file. + * + * @param project The project contain the XML file. * @param xmlFileWsPath The project path of the XML file, e.g. "/res/values/strings.xml". * The given file may or may not exist. * @param stringId The string ID to find. * @return True if such a string ID is already defined. */ public boolean isResIdDuplicate(IProject project, String xmlFileWsPath, String stringId) { - // This is going to be called many times on the same file. - // Build a cache of the existing IDs for a given file. - if (mResIdCache == null) { - mResIdCache = new HashMap>(); - } - HashSet cache = mResIdCache.get(xmlFileWsPath); + Set cache = getResIdsForFile(project, xmlFileWsPath); + return cache.contains(stringId); + } + + /** + * Utility method that retrieves all the *string* IDs defined in the given Android resource + * file. The instance maintains an internal cache so a given file is retrieved only once. + * Callers should consider the set to be read-only. + * + * @param project The project contain the XML file. + * @param xmlFileWsPath The project path of the XML file, e.g. "/res/values/strings.xml". + * The given file may or may not exist. + * @return The set of string IDs defined in the given file. Cached. Never null. + */ + public Set getResIdsForFile(IProject project, String xmlFileWsPath) { + Set cache = mResIdCache.get(xmlFileWsPath); if (cache == null) { - cache = getResIdsForFile(project, xmlFileWsPath); + cache = internalGetResIdsForFile(project, xmlFileWsPath); mResIdCache.put(xmlFileWsPath, cache); } - - return cache.contains(stringId); + return cache; } /** * Extract all the defined string IDs from a given file using XPath. - * @param project The project contain the XML file. + * @param project The project contain the XML file. * @param xmlFileWsPath The project path of the file to parse. It may not exist. * @return The set of all string IDs defined in the file. The returned set is always non * null. It is empty if the file does not exist. */ - private HashSet getResIdsForFile(IProject project, String xmlFileWsPath) { - HashSet ids = new HashSet(); - + private Set internalGetResIdsForFile(IProject project, String xmlFileWsPath) { + TreeSet ids = new TreeSet(); + if (mXPath == null) { mXPath = AndroidXPathFactory.newXPath(); } // Access the project that contains the resource that contains the compilation unit IResource resource = project.getFile(xmlFileWsPath); - + if (resource != null && resource.exists() && resource.getType() == IResource.FILE) { InputSource source; try { @@ -97,9 +107,9 @@ class XmlStringFileHelper { // // something // - + String xpathExpr = "/resources/string/@name"; //$NON-NLS-1$ - + Object result = mXPath.evaluate(xpathExpr, source, XPathConstants.NODESET); if (result instanceof NodeList) { NodeList list = (NodeList) result; @@ -108,14 +118,14 @@ class XmlStringFileHelper { ids.add(id); } } - + } catch (CoreException e1) { // IFile.getContents failed. Ignore. } catch (XPathExpressionException e) { // mXPath.evaluate failed. Ignore. } } - + return ids; } -- 2.11.0