aboutsummaryrefslogtreecommitdiffstats
path: root/eclipse/plugins/com.android.ide.eclipse.adt
diff options
context:
space:
mode:
authorTor Norbye <tnorbye@google.com>2011-07-28 14:07:18 -0700
committerTor Norbye <tnorbye@google.com>2011-07-29 13:10:36 -0700
commit401e50139efc9333a689c2306ca66a7b2c840c40 (patch)
tree216dd7bb1bb77b4c0b1cf7f3296922d3f3f5b14e /eclipse/plugins/com.android.ide.eclipse.adt
parent5c7d53f8dcb78d9e4ba353ec768866e82479698e (diff)
downloadsdk-401e50139efc9333a689c2306ca66a7b2c840c40.zip
sdk-401e50139efc9333a689c2306ca66a7b2c840c40.tar.gz
sdk-401e50139efc9333a689c2306ca66a7b2c840c40.tar.bz2
Add Java Quick Assistant for Extracting Strings
This changeset adds a Quick Assistant to Java files in Android projects, which proposes "Extract String" when the caret is within a String literal. It also moves a couple of utility methods from the Hyperlinks class to the AdtUtils class. Change-Id: Ica5ff40e32e3e145481d6c895178109289ed1d9b
Diffstat (limited to 'eclipse/plugins/com.android.ide.eclipse.adt')
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/plugin.xml8
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/AdtUtils.java44
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/JavaQuickAssistant.java71
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/VisualRefactoringAction.java22
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/xml/Hyperlinks.java34
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/BaseProjectHelper.java32
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/extractstring/ExtractStringInputPage.java7
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/extractstring/ExtractStringProposal.java178
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/extractstring/ExtractStringRefactoring.java2
9 files changed, 336 insertions, 62 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/plugin.xml b/eclipse/plugins/com.android.ide.eclipse.adt/plugin.xml
index 32442b6..1a432e1 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/plugin.xml
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/plugin.xml
@@ -607,6 +607,14 @@
class="com.android.ide.eclipse.adt.internal.editors.layout.refactoring.RefactoringAssistant"
target="org.eclipse.wst.xml.XML_DEFAULT" />
</extension>
+ <extension point="org.eclipse.jdt.ui.quickAssistProcessors">
+ <quickAssistProcessor
+ id="AndroidJavaAssistant"
+ name="Android Java Quick Assistant"
+ requiredSourceLevel="1.5"
+ class="com.android.ide.eclipse.adt.internal.editors.layout.refactoring.JavaQuickAssistant">
+ </quickAssistProcessor>
+ </extension>
<extension
point="org.eclipse.ui.propertyPages">
<page
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/AdtUtils.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/AdtUtils.java
index 4eb8e2e..657c186 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/AdtUtils.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/AdtUtils.java
@@ -16,6 +16,14 @@
package com.android.ide.eclipse.adt;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IFileEditorInput;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PlatformUI;
+
/** Utility methods for ADT */
public class AdtUtils {
@@ -104,4 +112,40 @@ public class AdtUtils {
return d[m][n];
}
+
+ /**
+ * Returns the current editor (the currently visible and active editor), or null if
+ * not found
+ *
+ * @return the current editor, or null
+ */
+ public static IEditorPart getActiveEditor() {
+ IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
+ if (window != null) {
+ IWorkbenchPage page = window.getActivePage();
+ if (page != null) {
+ return page.getActiveEditor();
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Returns the file for the current editor, if any.
+ *
+ * @return the file for the current editor, or null if none
+ */
+ public static IFile getActiveFile() {
+ IEditorPart editor = getActiveEditor();
+ if (editor != null) {
+ IEditorInput input = editor.getEditorInput();
+ if (input instanceof IFileEditorInput) {
+ IFileEditorInput fileInput = (IFileEditorInput) input;
+ return fileInput.getFile();
+ }
+ }
+
+ return null;
+ }
}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/JavaQuickAssistant.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/JavaQuickAssistant.java
new file mode 100644
index 0000000..ba6c614
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/JavaQuickAssistant.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * 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
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ide.eclipse.adt.internal.editors.layout.refactoring;
+
+import com.android.ide.eclipse.adt.internal.project.BaseProjectHelper;
+import com.android.ide.eclipse.adt.internal.refactorings.extractstring.ExtractStringProposal;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jdt.core.dom.ASTNode;
+import org.eclipse.jdt.ui.text.java.IInvocationContext;
+import org.eclipse.jdt.ui.text.java.IJavaCompletionProposal;
+import org.eclipse.jdt.ui.text.java.IProblemLocation;
+
+/**
+ * Quick Assistant for Java files in Android projects
+ */
+public class JavaQuickAssistant implements org.eclipse.jdt.ui.text.java.IQuickAssistProcessor {
+ public JavaQuickAssistant() {
+ }
+
+ public boolean hasAssists(IInvocationContext context) throws CoreException {
+ return true;
+ }
+
+ public IJavaCompletionProposal[] getAssists(IInvocationContext context,
+ IProblemLocation[] locations) throws CoreException {
+ // We should only offer Android quick assists within Android projects.
+ // This can be done by adding this logic to the extension registration:
+ //
+ // <enablement>
+ // <with variable="projectNatures">
+ // <iterate operator="or">
+ // <equals value="com.android.ide.eclipse.adt.AndroidNature"/>
+ // </iterate>
+ // </with>
+ // </enablement>
+ //
+ // However, this causes some errors to be dumped to the log, so instead we filter
+ // out non Android projects programmatically:
+
+ IProject project = context.getCompilationUnit().getJavaProject().getProject();
+ if (project == null || !BaseProjectHelper.isAndroidProject(project)) {
+ return null;
+ }
+
+ ASTNode coveringNode = context.getCoveringNode();
+ if (coveringNode != null && coveringNode.getNodeType() == ASTNode.STRING_LITERAL
+ && coveringNode.getLength() > 2) { // don't extract empty strings (includes quotes)
+ return new IJavaCompletionProposal[] {
+ new ExtractStringProposal(context)
+ };
+ }
+
+ return null;
+ }
+}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/VisualRefactoringAction.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/VisualRefactoringAction.java
index 4818132..151ff0a 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/VisualRefactoringAction.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/VisualRefactoringAction.java
@@ -17,6 +17,7 @@ package com.android.ide.eclipse.adt.internal.editors.layout.refactoring;
import com.android.ide.eclipse.adt.AdtConstants;
import com.android.ide.eclipse.adt.AdtPlugin;
+import com.android.ide.eclipse.adt.AdtUtils;
import com.android.ide.eclipse.adt.internal.editors.layout.LayoutEditor;
import com.android.ide.eclipse.adt.internal.editors.layout.gle2.CanvasViewInfo;
@@ -30,10 +31,8 @@ import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ITreeSelection;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
-import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.IWorkbenchWindowActionDelegate;
-import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.part.FileEditorInput;
abstract class VisualRefactoringAction implements IWorkbenchWindowActionDelegate {
@@ -76,13 +75,13 @@ abstract class VisualRefactoringAction implements IWorkbenchWindowActionDelegate
if (selection instanceof ITextSelection) {
mTextSelection = (ITextSelection) selection;
- editor = getActiveEditor();
+ editor = AdtUtils.getActiveEditor();
mFile = getSelectedFile(editor);
} else if (selection instanceof ITreeSelection) {
Object firstElement = ((ITreeSelection)selection).getFirstElement();
if (firstElement instanceof CanvasViewInfo) {
mTreeSelection = (ITreeSelection) selection;
- editor = getActiveEditor();
+ editor = AdtUtils.getActiveEditor();
mFile = getSelectedFile(editor);
}
}
@@ -102,21 +101,6 @@ abstract class VisualRefactoringAction implements IWorkbenchWindowActionDelegate
public abstract void run(IAction action);
/**
- * Returns the active editor (hopefully matching our selection) or null.
- */
- private IEditorPart getActiveEditor() {
- IWorkbenchWindow wwin = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
- if (wwin != null) {
- IWorkbenchPage page = wwin.getActivePage();
- if (page != null) {
- return page.getActiveEditor();
- }
- }
-
- return null;
- }
-
- /**
* Returns the active {@link IFile} (hopefully matching our selection) or null.
* The file is only returned if it's a file from a project with an Android nature.
* <p/>
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/xml/Hyperlinks.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/xml/Hyperlinks.java
index a9cf902..92485cd 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/xml/Hyperlinks.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/xml/Hyperlinks.java
@@ -45,6 +45,7 @@ import com.android.ide.common.resources.ResourceFolder;
import com.android.ide.common.resources.ResourceRepository;
import com.android.ide.common.resources.configuration.FolderConfiguration;
import com.android.ide.eclipse.adt.AdtPlugin;
+import com.android.ide.eclipse.adt.AdtUtils;
import com.android.ide.eclipse.adt.internal.editors.layout.LayoutEditor;
import com.android.ide.eclipse.adt.internal.editors.layout.gle2.GraphicalEditorPart;
import com.android.ide.eclipse.adt.internal.editors.manifest.ManifestEditor;
@@ -118,11 +119,8 @@ import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorReference;
import org.eclipse.ui.IEditorSite;
-import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.IWorkbenchPage;
-import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PartInitException;
-import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.ide.IDE;
import org.eclipse.ui.part.FileEditorInput;
import org.eclipse.ui.part.MultiPageEditorPart;
@@ -779,7 +777,7 @@ public class Hyperlinks {
private static Pair<IFile, IRegion> findIdDefinition(IProject project, String id) {
// FIRST look in the same file as the originating request, that's where you usually
// want to jump
- IFile self = getFile();
+ IFile self = AdtUtils.getActiveFile();
if (self != null && EXT_XML.equals(self.getFileExtension())) {
Pair<IFile, IRegion> target = findIdInXml(id, self);
if (target != null) {
@@ -1363,7 +1361,7 @@ public class Hyperlinks {
}
/** Returns the editor applicable to this hyperlink detection */
- public static IEditorPart getEditor() {
+ private static IEditorPart getEditor() {
// I would like to be able to find this via getAdapter(TextEditor.class) but
// couldn't find a way to initialize the editor context from
// AndroidSourceViewerConfig#getHyperlinkDetectorTargets (which only has
@@ -1372,34 +1370,12 @@ public class Hyperlinks {
// Therefore, for now, use a hack. This hack is reasonable because hyperlink
// resolvers are only run for the front-most visible window in the active
// workbench.
- IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
- if (window != null) {
- IWorkbenchPage page = window.getActivePage();
- if (page != null) {
- return page.getActiveEditor();
- }
- }
-
- return null;
- }
-
- /** Returns the file where the link request originated */
- private static IFile getFile() {
- IEditorPart editor = getEditor();
- if (editor != null) {
- IEditorInput input = editor.getEditorInput();
- if (input instanceof IFileEditorInput) {
- IFileEditorInput fileInput = (IFileEditorInput) input;
- return fileInput.getFile();
- }
- }
-
- return null;
+ return AdtUtils.getActiveEditor();
}
/** Returns the project applicable to this hyperlink detection */
private static IProject getProject() {
- IFile file = getFile();
+ IFile file = AdtUtils.getActiveFile();
if (file != null) {
return file.getProject();
}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/BaseProjectHelper.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/BaseProjectHelper.java
index 84f98a3..f2242e0 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/BaseProjectHelper.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/BaseProjectHelper.java
@@ -426,16 +426,10 @@ public final class BaseProjectHelper {
IProject project = javaProject.getProject();
// check if it's an android project based on its nature
- try {
- if (project.hasNature(AdtConstants.NATURE_DEFAULT)) {
- if (filter == null || filter.accept(project)) {
- androidProjectList.add(javaProject);
- }
+ if (isAndroidProject(project)) {
+ if (filter == null || filter.accept(project)) {
+ androidProjectList.add(javaProject);
}
- } catch (CoreException e) {
- // this exception, thrown by IProject.hasNature(), means the project either doesn't
- // exist or isn't opened. So, in any case we just skip it (the exception will
- // bypass the ArrayList.add()
}
}
@@ -444,6 +438,26 @@ public final class BaseProjectHelper {
}
/**
+ * Returns true if the given project is an Android project (e.g. is a Java project
+ * that also has the Android nature)
+ *
+ * @param project the project to test
+ * @return true if the given project is an Android project
+ */
+ public static boolean isAndroidProject(IProject project) {
+ // check if it's an android project based on its nature
+ try {
+ return project.hasNature(AdtConstants.NATURE_DEFAULT);
+ } catch (CoreException e) {
+ // this exception, thrown by IProject.hasNature(), means the project either doesn't
+ // exist or isn't opened. So, in any case we just skip it (the exception will
+ // bypass the ArrayList.add()
+ }
+
+ return false;
+ }
+
+ /**
* Returns the {@link IFolder} representing the output for the project for Android specific
* files.
* <p>
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/extractstring/ExtractStringInputPage.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/extractstring/ExtractStringInputPage.java
index dee8407..b45c137 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/extractstring/ExtractStringInputPage.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/extractstring/ExtractStringInputPage.java
@@ -29,7 +29,6 @@ import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
-import org.eclipse.jface.wizard.IWizardPage;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.ltk.ui.refactoring.UserInputWizardPage;
import org.eclipse.swt.SWT;
@@ -56,7 +55,7 @@ import java.util.regex.Pattern;
/**
* @see ExtractStringRefactoring
*/
-class ExtractStringInputPage extends UserInputWizardPage implements IWizardPage {
+class ExtractStringInputPage extends UserInputWizardPage {
/** Last res file path used, shared across the session instances but specific to the
* current project. The default for unknown projects is {@link #DEFAULT_RES_FILE_PATH}. */
@@ -286,7 +285,7 @@ class ExtractStringInputPage extends UserInputWizardPage implements IWizardPage
/**
* Utility method to guess a suitable new XML ID based on the selected string.
*/
- private String guessId(String text) {
+ public static String guessId(String text) {
if (text == null) {
return ""; //$NON-NLS-1$
}
@@ -315,7 +314,7 @@ class ExtractStringInputPage extends UserInputWizardPage implements IWizardPage
* Validates fields of the wizard input page. Displays errors as appropriate and
* enable the "Next" button (or not) by calling {@link #setPageComplete(boolean)}.
*
- * If validation succeeds, this udpates the text id & value in the refactoring object.
+ * If validation succeeds, this updates the text id & value in the refactoring object.
*
* @return True if the page has been positively validated. It may still have warnings.
*/
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/extractstring/ExtractStringProposal.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/extractstring/ExtractStringProposal.java
new file mode 100644
index 0000000..a14a3f0
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/extractstring/ExtractStringProposal.java
@@ -0,0 +1,178 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * 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
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.ide.eclipse.adt.internal.refactorings.extractstring;
+
+import com.android.ide.eclipse.adt.AdtPlugin;
+import com.android.ide.eclipse.adt.AdtUtils;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.jdt.core.IBuffer;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.dom.ASTNode;
+import org.eclipse.jdt.ui.text.java.IInvocationContext;
+import org.eclipse.jdt.ui.text.java.IJavaCompletionProposal;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.ITextSelection;
+import org.eclipse.jface.text.TextSelection;
+import org.eclipse.jface.text.contentassist.IContextInformation;
+import org.eclipse.ltk.ui.refactoring.RefactoringWizard;
+import org.eclipse.ltk.ui.refactoring.RefactoringWizardOpenOperation;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * Proposal for extracting strings in Java files
+ */
+public class ExtractStringProposal implements IJavaCompletionProposal {
+ private IInvocationContext mContext;
+
+ public ExtractStringProposal(IInvocationContext context) {
+ mContext = context;
+ }
+
+ public void apply(IDocument document) {
+ IEditorPart editor = AdtUtils.getActiveEditor();
+ IFile file = AdtUtils.getActiveFile();
+ if (editor == null || file == null) {
+ return;
+ }
+
+ ASTNode coveringNode = mContext.getCoveringNode();
+ int start = coveringNode.getStartPosition();
+ int length = coveringNode.getLength();
+ ITextSelection selection = new TextSelection(start, length);
+
+ ExtractStringRefactoring refactoring = new ExtractStringRefactoring(file, editor,
+ selection);
+
+ RefactoringWizard wizard = new ExtractStringWizard(refactoring, file.getProject());
+ RefactoringWizardOpenOperation op = new RefactoringWizardOpenOperation(wizard);
+ try {
+ IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
+ op.run(window.getShell(), wizard.getDefaultPageTitle());
+ } catch (InterruptedException e) {
+ }
+ }
+
+ public Point getSelection(IDocument document) {
+ return null;
+ }
+
+ public String getAdditionalProposalInfo() {
+ try {
+ ASTNode coveringNode = mContext.getCoveringNode();
+ int start = coveringNode.getStartPosition();
+ int length = coveringNode.getLength();
+ IBuffer buffer = mContext.getCompilationUnit().getBuffer();
+ StringBuilder sb = new StringBuilder();
+ String string = buffer.getText(start, length);
+ string = ExtractStringRefactoring.unquoteAttrValue(string);
+ String token = ExtractStringInputPage.guessId(string);
+
+ // Look up the beginning and the end of the line (outside of the extracted string)
+ // such that we can show a preview of the diff, e.g. if you have
+ // foo.setTitle("Hello"); we want to show foo.setTitle(R.string.hello);
+ // so we need to extract "foo.setTitle(" and ");".
+
+ // Look backwards to the beginning of the line (and strip whitespace)
+ int i = start - 1;
+ while (i > 0) {
+ char c = buffer.getChar(i);
+ if (c == '\r' || (c == '\n')) {
+ break;
+ }
+ i--;
+ }
+ String linePrefix = buffer.getText(i + 1, start - (i + 1)).trim();
+
+ // Look forwards to the end of the line (and strip whitespace)
+ i = start + length;
+ while (i < buffer.getLength()) {
+ char c = buffer.getChar(i);
+ if (c == '\r' || (c == '\n')) {
+ break;
+ }
+ i++;
+ }
+ String lineSuffix = buffer.getText(start + length, i - (start + length));
+
+ // Should we show the replacement as just R.string.foo or
+ // context.getString(R.string.foo) ?
+ boolean useContext = false;
+ ASTNode parent = coveringNode.getParent();
+ if (parent != null) {
+ int type = parent.getNodeType();
+ if (type == ASTNode.ASSIGNMENT
+ || type == ASTNode.VARIABLE_DECLARATION_STATEMENT
+ || type == ASTNode.VARIABLE_DECLARATION_FRAGMENT
+ || type == ASTNode.VARIABLE_DECLARATION_EXPRESSION) {
+ useContext = true;
+ }
+ }
+
+ // Display .java change:
+ sb.append("...<br>"); //$NON-NLS-1$
+ sb.append(linePrefix);
+ sb.append("<b>"); //$NON-NLS-1$
+ if (useContext) {
+ sb.append("context.getString("); //$NON-NLS-1$
+ }
+ sb.append("R.string."); //$NON-NLS-1$
+ sb.append(token);
+ if (useContext) {
+ sb.append(")"); //$NON-NLS-1$
+ }
+ sb.append("</b>"); //$NON-NLS-1$
+ sb.append(lineSuffix);
+ sb.append("<br>...<br>"); //$NON-NLS-1$
+
+ // Display strings.xml change:
+ sb.append("<br>"); //$NON-NLS-1$
+ sb.append("&lt;resources&gt;<br>"); //$NON-NLS-1$
+ sb.append(" <b>&lt;string name=\""); //$NON-NLS-1$
+ sb.append(token);
+ sb.append("\"&gt;"); //$NON-NLS-1$
+ sb.append(string);
+ sb.append("&lt;/string&gt;</b><br>"); //$NON-NLS-1$
+ sb.append("&lt;/resources&gt;"); //$NON-NLS-1$
+
+ return sb.toString();
+ } catch (JavaModelException e) {
+ AdtPlugin.log(e, null);
+ }
+
+ return "Initiates the Extract String refactoring operation";
+ }
+
+ public String getDisplayString() {
+ return "Extract String";
+ }
+
+ public Image getImage() {
+ return AdtPlugin.getAndroidLogo();
+ }
+
+ public IContextInformation getContextInformation() {
+ return null;
+ }
+
+ public int getRelevance() {
+ return 80;
+ }
+} \ No newline at end of file
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/extractstring/ExtractStringRefactoring.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/extractstring/ExtractStringRefactoring.java
index 8b2f729..79f012a 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/extractstring/ExtractStringRefactoring.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/extractstring/ExtractStringRefactoring.java
@@ -719,7 +719,7 @@ public class ExtractStringRefactoring extends Refactoring {
* @return The attribute value, without quotes. Whitespace is not trimmed, if any.
* String may be empty, but not null.
*/
- private String unquoteAttrValue(String attrValue) {
+ static String unquoteAttrValue(String attrValue) {
int len = attrValue.length();
int len1 = len - 1;
if (len >= 2 &&