ADT: Extract String IDs from Layout XML strings.

This commit is contained in:
Raphael
2009-07-10 19:49:31 -04:00
parent fe1b8d8f82
commit 32ad938b85
8 changed files with 689 additions and 191 deletions

View File

@@ -666,6 +666,12 @@
id="com.android.ide.eclipse.adt.refactoring.extract.string" id="com.android.ide.eclipse.adt.refactoring.extract.string"
name="Extract Android String"> name="Extract Android String">
</command> </command>
<keyBinding
commandId="com.android.ide.eclipse.adt.refactoring.extract.string"
contextId="org.eclipse.ui.globalScope"
keyConfigurationId="org.eclipse.ui.defaultAcceleratorConfiguration"
keySequence="M3+M2+A S">
</keyBinding>
</extension> </extension>
<extension <extension
point="org.eclipse.ltk.core.refactoring.refactoringContributions"> point="org.eclipse.ltk.core.refactoring.refactoringContributions">

View File

@@ -310,12 +310,12 @@ public abstract class AndroidContentAssist implements IContentAssistProcessor {
Object[] choices = null; Object[] choices = null;
if (attrInfo.isInValue) { if (attrInfo.isInValue) {
// Editing an attribute's value... Get the attribute name and then the // Editing an attribute's value... Get the attribute name and then the
// possible choice for the tuple(parent,attribute) // possible choices for the tuple(parent,attribute)
String value = attrInfo.value; String value = attrInfo.value;
if (value.startsWith("'") || value.startsWith("\"")) { //$NON-NLS-1$ //$NON-NLS-2$ if (value.startsWith("'") || value.startsWith("\"")) { //$NON-NLS-1$ //$NON-NLS-2$
value = value.substring(1); value = value.substring(1);
// The prefix that was found at the beginning only scan for characters // The prefix that was found at the beginning only scan for characters
// valid of tag name. We now know the real prefix for this attribute's // valid for tag name. We now know the real prefix for this attribute's
// value, which is needed to generate the completion choices below. // value, which is needed to generate the completion choices below.
attrInfo.correctedPrefix = value; attrInfo.correctedPrefix = value;
} else { } else {
@@ -772,7 +772,7 @@ public abstract class AndroidContentAssist implements IContentAssistProcessor {
IDescriptorProvider descriptorProvider = data.getDescriptorProvider(mDescriptorId); IDescriptorProvider descriptorProvider = data.getDescriptorProvider(mDescriptorId);
if (descriptorProvider != null) { if (descriptorProvider != null) {
mRootDescriptor = new ElementDescriptor("", mRootDescriptor = new ElementDescriptor("", //$NON-NLS-1$
descriptorProvider.getRootElementDescriptors()); descriptorProvider.getRootElementDescriptors());
} }
} }

View File

@@ -79,7 +79,7 @@ import java.net.URL;
* source editor. This can be a no-op if desired. * source editor. This can be a no-op if desired.
*/ */
public abstract class AndroidEditor extends FormEditor implements IResourceChangeListener { public abstract class AndroidEditor extends FormEditor implements IResourceChangeListener {
/** Preference name for the current page of this file */ /** Preference name for the current page of this file */
private static final String PREF_CURRENT_PAGE = "_current_page"; private static final String PREF_CURRENT_PAGE = "_current_page";
@@ -91,7 +91,7 @@ public abstract class AndroidEditor extends FormEditor implements IResourceChang
/** Width hint for text fields. Helps the grid layout resize properly on smaller screens */ /** Width hint for text fields. Helps the grid layout resize properly on smaller screens */
public static final int TEXT_WIDTH_HINT = 50; public static final int TEXT_WIDTH_HINT = 50;
/** Page index of the text editor (always the last page) */ /** Page index of the text editor (always the last page) */
private int mTextPageIndex; private int mTextPageIndex;
/** The text editor */ /** The text editor */
@@ -108,7 +108,7 @@ public abstract class AndroidEditor extends FormEditor implements IResourceChang
public AndroidEditor() { public AndroidEditor() {
super(); super();
ResourcesPlugin.getWorkspace().addResourceChangeListener(this); ResourcesPlugin.getWorkspace().addResourceChangeListener(this);
mTargetListener = new ITargetChangeListener() { mTargetListener = new ITargetChangeListener() {
public void onProjectTargetChange(IProject changedProject) { public void onProjectTargetChange(IProject changedProject) {
if (changedProject == getProject()) { if (changedProject == getProject()) {
@@ -118,7 +118,7 @@ public abstract class AndroidEditor extends FormEditor implements IResourceChang
public void onTargetsLoaded() { public void onTargetsLoaded() {
commitPages(false /* onSave */); commitPages(false /* onSave */);
// recreate the ui root node always // recreate the ui root node always
initUiRootNode(true /*force*/); initUiRootNode(true /*force*/);
} }
@@ -133,14 +133,14 @@ public abstract class AndroidEditor extends FormEditor implements IResourceChang
* UI node editor. * UI node editor.
*/ */
abstract public UiElementNode getUiRootNode(); abstract public UiElementNode getUiRootNode();
/** /**
* Creates the various form pages. * Creates the various form pages.
* <p/> * <p/>
* Derived classes must implement this to add their own specific tabs. * Derived classes must implement this to add their own specific tabs.
*/ */
abstract protected void createFormPages(); abstract protected void createFormPages();
/** /**
* Creates the initial UI Root Node, including the known mandatory elements. * Creates the initial UI Root Node, including the known mandatory elements.
* @param force if true, a new UiManifestNode is recreated even if it already exists. * @param force if true, a new UiManifestNode is recreated even if it already exists.
@@ -150,9 +150,9 @@ public abstract class AndroidEditor extends FormEditor implements IResourceChang
/** /**
* Subclasses should override this method to process the new XML Model, which XML * Subclasses should override this method to process the new XML Model, which XML
* root node is given. * root node is given.
* *
* The base implementation is empty. * The base implementation is empty.
* *
* @param xml_doc The XML document, if available, or null if none exists. * @param xml_doc The XML document, if available, or null if none exists.
*/ */
protected void xmlModelChanged(Document xml_doc) { protected void xmlModelChanged(Document xml_doc) {
@@ -169,7 +169,7 @@ public abstract class AndroidEditor extends FormEditor implements IResourceChang
createAndroidPages(); createAndroidPages();
selectDefaultPage(null /* defaultPageId */); selectDefaultPage(null /* defaultPageId */);
} }
/** /**
* Creates the page for the Android Editors * Creates the page for the Android Editors
*/ */
@@ -193,7 +193,7 @@ public abstract class AndroidEditor extends FormEditor implements IResourceChang
action = mTextEditor.getAction(ActionFactory.REDO.getId()); action = mTextEditor.getAction(ActionFactory.REDO.getId());
bars.setGlobalActionHandler(ActionFactory.REDO.getId(), action); bars.setGlobalActionHandler(ActionFactory.REDO.getId(), action);
bars.updateActionBars(); bars.updateActionBars();
} }
} }
@@ -207,7 +207,7 @@ public abstract class AndroidEditor extends FormEditor implements IResourceChang
if (defaultPageId == null) { if (defaultPageId == null) {
if (getEditorInput() instanceof IFileEditorInput) { if (getEditorInput() instanceof IFileEditorInput) {
IFile file = ((IFileEditorInput) getEditorInput()).getFile(); IFile file = ((IFileEditorInput) getEditorInput()).getFile();
QualifiedName qname = new QualifiedName(AdtPlugin.PLUGIN_ID, QualifiedName qname = new QualifiedName(AdtPlugin.PLUGIN_ID,
getClass().getSimpleName() + PREF_CURRENT_PAGE); getClass().getSimpleName() + PREF_CURRENT_PAGE);
String pageId; String pageId;
@@ -234,7 +234,7 @@ public abstract class AndroidEditor extends FormEditor implements IResourceChang
} }
} }
} }
/** /**
* Removes all the pages from the editor. * Removes all the pages from the editor.
*/ */
@@ -247,10 +247,10 @@ public abstract class AndroidEditor extends FormEditor implements IResourceChang
/** /**
* Overrides the parent's setActivePage to be able to switch to the xml editor. * Overrides the parent's setActivePage to be able to switch to the xml editor.
* *
* If the special pageId TEXT_EDITOR_ID is given, switches to the mTextPageIndex page. * If the special pageId TEXT_EDITOR_ID is given, switches to the mTextPageIndex page.
* This is needed because the editor doesn't actually derive from IFormPage and thus * This is needed because the editor doesn't actually derive from IFormPage and thus
* doesn't have the get-by-page-id method. In this case, the method returns null since * doesn't have the get-by-page-id method. In this case, the method returns null since
* IEditorPart does not implement IFormPage. * IEditorPart does not implement IFormPage.
*/ */
@Override @Override
@@ -262,18 +262,18 @@ public abstract class AndroidEditor extends FormEditor implements IResourceChang
return super.setActivePage(pageId); return super.setActivePage(pageId);
} }
} }
/** /**
* Notifies this multi-page editor that the page with the given id has been * Notifies this multi-page editor that the page with the given id has been
* activated. This method is called when the user selects a different tab. * activated. This method is called when the user selects a different tab.
* *
* @see MultiPageEditorPart#pageChange(int) * @see MultiPageEditorPart#pageChange(int)
*/ */
@Override @Override
protected void pageChange(int newPageIndex) { protected void pageChange(int newPageIndex) {
super.pageChange(newPageIndex); super.pageChange(newPageIndex);
if (getEditorInput() instanceof IFileEditorInput) { if (getEditorInput() instanceof IFileEditorInput) {
IFile file = ((IFileEditorInput) getEditorInput()).getFile(); IFile file = ((IFileEditorInput) getEditorInput()).getFile();
@@ -288,9 +288,9 @@ public abstract class AndroidEditor extends FormEditor implements IResourceChang
} }
/** /**
* Notifies this listener that some resource changes * Notifies this listener that some resource changes
* are happening, or have already happened. * are happening, or have already happened.
* *
* Closes all project files on project close. * Closes all project files on project close.
* @see IResourceChangeListener * @see IResourceChangeListener
*/ */
@@ -318,7 +318,7 @@ public abstract class AndroidEditor extends FormEditor implements IResourceChang
* Initializes the editor part with a site and input. * Initializes the editor part with a site and input.
* <p/> * <p/>
* Checks that the input is an instance of {@link IFileEditorInput}. * Checks that the input is an instance of {@link IFileEditorInput}.
* *
* @see FormEditor * @see FormEditor
*/ */
@Override @Override
@@ -330,7 +330,7 @@ public abstract class AndroidEditor extends FormEditor implements IResourceChang
/** /**
* Removes attached listeners. * Removes attached listeners.
* *
* @see WorkbenchPart * @see WorkbenchPart
*/ */
@Override @Override
@@ -341,7 +341,7 @@ public abstract class AndroidEditor extends FormEditor implements IResourceChang
if (mXmlModelStateListener != null) { if (mXmlModelStateListener != null) {
xml_model.removeModelStateListener(mXmlModelStateListener); xml_model.removeModelStateListener(mXmlModelStateListener);
} }
} finally { } finally {
xml_model.releaseFromRead(); xml_model.releaseFromRead();
} }
@@ -355,7 +355,7 @@ public abstract class AndroidEditor extends FormEditor implements IResourceChang
super.dispose(); super.dispose();
} }
/** /**
* Commit all dirty pages then saves the contents of the text editor. * Commit all dirty pages then saves the contents of the text editor.
* <p/> * <p/>
@@ -403,7 +403,7 @@ public abstract class AndroidEditor extends FormEditor implements IResourceChang
* The incorrect casting makes the original implementation crash due * The incorrect casting makes the original implementation crash due
* to our {@link StructuredTextEditor} not being an {@link IFormPage} * to our {@link StructuredTextEditor} not being an {@link IFormPage}
* so we have to override and duplicate to fix it. * so we have to override and duplicate to fix it.
* *
* @param onSave <code>true</code> if commit is performed as part * @param onSave <code>true</code> if commit is performed as part
* of the 'save' operation, <code>false</code> otherwise. * of the 'save' operation, <code>false</code> otherwise.
* @since 3.3 * @since 3.3
@@ -421,7 +421,7 @@ public abstract class AndroidEditor extends FormEditor implements IResourceChang
} }
} }
} }
} }
} }
/* (non-Javadoc) /* (non-Javadoc)
@@ -451,8 +451,8 @@ public abstract class AndroidEditor extends FormEditor implements IResourceChang
* <li> Links starting with "file:/" are simply sent to a local browser. * <li> Links starting with "file:/" are simply sent to a local browser.
* <li> Links starting with "page:" are expected to be an editor page id to switch to. * <li> Links starting with "page:" are expected to be an editor page id to switch to.
* <li> Other links are ignored. * <li> Other links are ignored.
* </ul> * </ul>
* *
* @return A new hyper-link listener for FormText to use. * @return A new hyper-link listener for FormText to use.
*/ */
public final IHyperlinkListener createHyperlinkListener() { public final IHyperlinkListener createHyperlinkListener() {
@@ -478,7 +478,7 @@ public abstract class AndroidEditor extends FormEditor implements IResourceChang
/** /**
* Open the http link into a browser * Open the http link into a browser
* *
* @param link The URL to open in a browser * @param link The URL to open in a browser
*/ */
private void openLinkInBrowser(String link) { private void openLinkInBrowser(String link) {
@@ -516,7 +516,7 @@ public abstract class AndroidEditor extends FormEditor implements IResourceChang
"Error opening the Android XML editor. Is the document an XML file?"); "Error opening the Android XML editor. Is the document an XML file?");
throw new RuntimeException("Android XML Editor Error", new CoreException(status)); throw new RuntimeException("Android XML Editor Error", new CoreException(status));
} }
IStructuredModel xml_model = getModelForRead(); IStructuredModel xml_model = getModelForRead();
if (xml_model != null) { if (xml_model != null) {
try { try {
@@ -534,9 +534,9 @@ public abstract class AndroidEditor extends FormEditor implements IResourceChang
"Android XML Editor Error", null, e.getStatus()); "Android XML Editor Error", null, e.getStatus());
} }
} }
/** /**
* Returns the ISourceViewer associated with the Structured Text editor. * Returns the ISourceViewer associated with the Structured Text editor.
*/ */
public final ISourceViewer getStructuredSourceViewer() { public final ISourceViewer getStructuredSourceViewer() {
if (mTextEditor != null) { if (mTextEditor != null) {
@@ -558,13 +558,18 @@ public abstract class AndroidEditor extends FormEditor implements IResourceChang
} }
return null; return null;
} }
/** /**
* Returns a version of the model that has been shared for read. * Returns a version of the model that has been shared for read.
* <p/> * <p/>
* Callers <em>must</em> call model.releaseFromRead() when done, typically * Callers <em>must</em> call model.releaseFromRead() when done, typically
* in a try..finally clause. * in a try..finally clause.
* *
* Portability note: this uses getModelManager which is part of wst.sse.core; however
* the interface returned is part of wst.sse.core.internal.provisional so we can
* expect it to change in a distant future if they start cleaning their codebase,
* however unlikely that is.
*
* @return The model for the XML document or null if cannot be obtained from the editor * @return The model for the XML document or null if cannot be obtained from the editor
*/ */
public final IStructuredModel getModelForRead() { public final IStructuredModel getModelForRead() {
@@ -576,14 +581,14 @@ public abstract class AndroidEditor extends FormEditor implements IResourceChang
} }
} }
return null; return null;
} }
/** /**
* Returns a version of the model that has been shared for edit. * Returns a version of the model that has been shared for edit.
* <p/> * <p/>
* Callers <em>must</em> call model.releaseFromEdit() when done, typically * Callers <em>must</em> call model.releaseFromEdit() when done, typically
* in a try..finally clause. * in a try..finally clause.
* *
* @return The model for the XML document or null if cannot be obtained from the editor * @return The model for the XML document or null if cannot be obtained from the editor
*/ */
public final IStructuredModel getModelForEdit() { public final IStructuredModel getModelForEdit() {
@@ -595,7 +600,7 @@ public abstract class AndroidEditor extends FormEditor implements IResourceChang
} }
} }
return null; return null;
} }
/** /**
* Helper class to perform edits on the XML model whilst making sure the * Helper class to perform edits on the XML model whilst making sure the
@@ -609,7 +614,7 @@ public abstract class AndroidEditor extends FormEditor implements IResourceChang
* <p/> * <p/>
* The method is synchronous. As soon as the {@link IStructuredModel#changedModel()} method * The method is synchronous. As soon as the {@link IStructuredModel#changedModel()} method
* is called, XML model listeners will be triggered. * is called, XML model listeners will be triggered.
* *
* @param edit_action Something that will change the XML. * @param edit_action Something that will change the XML.
*/ */
public final void editXmlModel(Runnable edit_action) { public final void editXmlModel(Runnable edit_action) {
@@ -623,7 +628,7 @@ public abstract class AndroidEditor extends FormEditor implements IResourceChang
model.releaseFromEdit(); model.releaseFromEdit();
} }
} }
/** /**
* Starts an "undo recording" session. This is managed by the underlying undo manager * Starts an "undo recording" session. This is managed by the underlying undo manager
* associated to the structured XML model. * associated to the structured XML model.
@@ -632,7 +637,7 @@ public abstract class AndroidEditor extends FormEditor implements IResourceChang
* <p/> * <p/>
* beginUndoRecording/endUndoRecording calls can be nested (inner calls are ignored, only one * beginUndoRecording/endUndoRecording calls can be nested (inner calls are ignored, only one
* undo operation is recorded.) * undo operation is recorded.)
* *
* @param label The label for the undo operation. Can be null but we should really try to put * @param label The label for the undo operation. Can be null but we should really try to put
* something meaningful if possible. * something meaningful if possible.
* @return True if the undo recording actually started, false if any kind of error occured. * @return True if the undo recording actually started, false if any kind of error occured.
@@ -652,7 +657,7 @@ public abstract class AndroidEditor extends FormEditor implements IResourceChang
} }
return false; return false;
} }
/** /**
* Ends an "undo recording" session. * Ends an "undo recording" session.
* <p/> * <p/>
@@ -671,14 +676,14 @@ public abstract class AndroidEditor extends FormEditor implements IResourceChang
} }
} }
} }
/** /**
* Creates an "undo recording" session by calling the undoableAction runnable * Creates an "undo recording" session by calling the undoableAction runnable
* using {@link #beginUndoRecording(String)} and {@link #endUndoRecording()}. * using {@link #beginUndoRecording(String)} and {@link #endUndoRecording()}.
* <p> * <p>
* You can nest several calls to {@link #wrapUndoRecording(String, Runnable)}, only one * You can nest several calls to {@link #wrapUndoRecording(String, Runnable)}, only one
* recording session will be created. * recording session will be created.
* *
* @param label The label for the undo operation. Can be null. Ideally we should really try * @param label The label for the undo operation. Can be null. Ideally we should really try
* to put something meaningful if possible. * to put something meaningful if possible.
*/ */
@@ -693,7 +698,7 @@ public abstract class AndroidEditor extends FormEditor implements IResourceChang
} }
} }
} }
/** /**
* Returns the XML {@link Document} or null if we can't get it * Returns the XML {@link Document} or null if we can't get it
*/ */
@@ -709,7 +714,7 @@ public abstract class AndroidEditor extends FormEditor implements IResourceChang
} }
return null; return null;
} }
/** /**
* Returns the {@link IProject} for the edited file. * Returns the {@link IProject} for the edited file.
*/ */
@@ -719,16 +724,16 @@ public abstract class AndroidEditor extends FormEditor implements IResourceChang
if (input instanceof FileEditorInput) { if (input instanceof FileEditorInput) {
FileEditorInput fileInput = (FileEditorInput)input; FileEditorInput fileInput = (FileEditorInput)input;
IFile inputFile = fileInput.getFile(); IFile inputFile = fileInput.getFile();
if (inputFile != null) { if (inputFile != null) {
return inputFile.getProject(); return inputFile.getProject();
} }
} }
} }
return null; return null;
} }
/** /**
* Returns the {@link AndroidTargetData} for the edited file. * Returns the {@link AndroidTargetData} for the edited file.
*/ */
@@ -738,22 +743,22 @@ public abstract class AndroidEditor extends FormEditor implements IResourceChang
Sdk currentSdk = Sdk.getCurrent(); Sdk currentSdk = Sdk.getCurrent();
if (currentSdk != null) { if (currentSdk != null) {
IAndroidTarget target = currentSdk.getTarget(project); IAndroidTarget target = currentSdk.getTarget(project);
if (target != null) { if (target != null) {
return currentSdk.getTargetData(target); return currentSdk.getTargetData(target);
} }
} }
} }
return null; return null;
} }
/** /**
* Listen to changes in the underlying XML model in the structured editor. * Listen to changes in the underlying XML model in the structured editor.
*/ */
private class XmlModelStateListener implements IModelStateListener { private class XmlModelStateListener implements IModelStateListener {
/** /**
* A model is about to be changed. This typically is initiated by one * A model is about to be changed. This typically is initiated by one
* client of the model, to signal a large change and/or a change to the * client of the model, to signal a large change and/or a change to the
@@ -765,7 +770,7 @@ public abstract class AndroidEditor extends FormEditor implements IResourceChang
public void modelAboutToBeChanged(IStructuredModel model) { public void modelAboutToBeChanged(IStructuredModel model) {
// pass // pass
} }
/** /**
* Signals that the changes foretold by modelAboutToBeChanged have been * Signals that the changes foretold by modelAboutToBeChanged have been
* made. A typical use might be to refresh, or to resume processing that * made. A typical use might be to refresh, or to resume processing that
@@ -776,7 +781,7 @@ public abstract class AndroidEditor extends FormEditor implements IResourceChang
public void modelChanged(IStructuredModel model) { public void modelChanged(IStructuredModel model) {
xmlModelChanged(getXmlDocument(model)); xmlModelChanged(getXmlDocument(model));
} }
/** /**
* Notifies that a model's dirty state has changed, and passes that state * Notifies that a model's dirty state has changed, and passes that state
* in isDirty. A model becomes dirty when any change is made, and becomes * in isDirty. A model becomes dirty when any change is made, and becomes
@@ -787,7 +792,7 @@ public abstract class AndroidEditor extends FormEditor implements IResourceChang
public void modelDirtyStateChanged(IStructuredModel model, boolean isDirty) { public void modelDirtyStateChanged(IStructuredModel model, boolean isDirty) {
// pass // pass
} }
/** /**
* A modelDeleted means the underlying resource has been deleted. The * A modelDeleted means the underlying resource has been deleted. The
* model itself is not removed from model management until all have * model itself is not removed from model management until all have
@@ -799,7 +804,7 @@ public abstract class AndroidEditor extends FormEditor implements IResourceChang
public void modelResourceDeleted(IStructuredModel model) { public void modelResourceDeleted(IStructuredModel model) {
// pass // pass
} }
/** /**
* A model has been renamed or copied (as in saveAs..). In the renamed * A model has been renamed or copied (as in saveAs..). In the renamed
* case, the two paramenters are the same instance, and only contain the * case, the two paramenters are the same instance, and only contain the
@@ -810,14 +815,14 @@ public abstract class AndroidEditor extends FormEditor implements IResourceChang
public void modelResourceMoved(IStructuredModel oldModel, IStructuredModel newModel) { public void modelResourceMoved(IStructuredModel oldModel, IStructuredModel newModel) {
// pass // pass
} }
/** /**
* This AndroidEditor implementation of IModelChangedListener is empty. * This AndroidEditor implementation of IModelChangedListener is empty.
*/ */
public void modelAboutToBeReinitialized(IStructuredModel structuredModel) { public void modelAboutToBeReinitialized(IStructuredModel structuredModel) {
// pass // pass
} }
/** /**
* This AndroidEditor implementation of IModelChangedListener is empty. * This AndroidEditor implementation of IModelChangedListener is empty.
*/ */

View File

@@ -32,8 +32,10 @@ import org.eclipse.swt.widgets.Composite;
*/ */
public final class ReferenceAttributeDescriptor extends TextAttributeDescriptor { public final class ReferenceAttributeDescriptor extends TextAttributeDescriptor {
/** The {@link ResourceType} that this reference attribute can accept. It can be null,
* in which case any reference type can be used. */
private ResourceType mResourceType; private ResourceType mResourceType;
/** /**
* Creates a reference attributes that can contain any type of resources. * Creates a reference attributes that can contain any type of resources.
* @param xmlLocalName The XML name of the attribute (case sensitive) * @param xmlLocalName The XML name of the attribute (case sensitive)
@@ -46,7 +48,7 @@ public final class ReferenceAttributeDescriptor extends TextAttributeDescriptor
String tooltip) { String tooltip) {
super(xmlLocalName, uiName, nsUri, tooltip); super(xmlLocalName, uiName, nsUri, tooltip);
} }
/** /**
* Creates a reference attributes that can contain a reference to a specific * Creates a reference attributes that can contain a reference to a specific
* {@link ResourceType}. * {@link ResourceType}.
@@ -58,14 +60,20 @@ public final class ReferenceAttributeDescriptor extends TextAttributeDescriptor
* See {@link SdkConstants#NS_RESOURCES} for a common value. * See {@link SdkConstants#NS_RESOURCES} for a common value.
* @param tooltip A non-empty tooltip string or null * @param tooltip A non-empty tooltip string or null
*/ */
public ReferenceAttributeDescriptor(ResourceType resourceType, public ReferenceAttributeDescriptor(ResourceType resourceType,
String xmlLocalName, String uiName, String nsUri, String xmlLocalName, String uiName, String nsUri,
String tooltip) { String tooltip) {
super(xmlLocalName, uiName, nsUri, tooltip); super(xmlLocalName, uiName, nsUri, tooltip);
mResourceType = resourceType; mResourceType = resourceType;
} }
/** Returns the {@link ResourceType} that this reference attribute can accept.
* It can be null, in which case any reference type can be used. */
public ResourceType getResourceType() {
return mResourceType;
}
/** /**
* @return A new {@link UiResourceAttributeNode} linked to this reference descriptor. * @return A new {@link UiResourceAttributeNode} linked to this reference descriptor.
*/ */
@@ -73,7 +81,7 @@ public final class ReferenceAttributeDescriptor extends TextAttributeDescriptor
public UiAttributeNode createUiNode(UiElementNode uiParent) { public UiAttributeNode createUiNode(UiElementNode uiParent) {
return new UiResourceAttributeNode(mResourceType, this, uiParent); return new UiResourceAttributeNode(mResourceType, this, uiParent);
} }
// ------- IPropertyDescriptor Methods // ------- IPropertyDescriptor Methods
@Override @Override

View File

@@ -4,7 +4,7 @@
* Licensed under the Eclipse Public License, Version 1.0 (the "License"); * 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 not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.eclipse.org/org/documents/epl-v10.php * http://www.eclipse.org/org/documents/epl-v10.php
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
@@ -47,7 +47,7 @@ import org.eclipse.ui.part.FileEditorInput;
* Action executed when the "Extract String" menu item is invoked. * Action executed when the "Extract String" menu item is invoked.
* <p/> * <p/>
* The intent of the action is to start a refactoring that extracts a source string and * The intent of the action is to start a refactoring that extracts a source string and
* replaces it by an Android string resource ID. * replaces it by an Android string resource ID.
* <p/> * <p/>
* Workflow: * Workflow:
* <ul> * <ul>
@@ -74,6 +74,7 @@ public class ExtractStringAction implements IWorkbenchWindowActionDelegate {
/** Keep track of the current workbench window. */ /** Keep track of the current workbench window. */
private IWorkbenchWindow mWindow; private IWorkbenchWindow mWindow;
private ITextSelection mSelection; private ITextSelection mSelection;
private IEditorPart mEditor;
private IFile mFile; private IFile mFile;
/** /**
@@ -103,11 +104,12 @@ public class ExtractStringAction implements IWorkbenchWindowActionDelegate {
mSelection = null; mSelection = null;
mFile = null; mFile = null;
if (selection instanceof ITextSelection) { if (selection instanceof ITextSelection) {
mSelection = (ITextSelection) selection; mSelection = (ITextSelection) selection;
if (mSelection.getLength() > 0) { if (mSelection.getLength() > 0) {
mFile = getSelectedFile(); mEditor = getActiveEditor();
mFile = getSelectedFile(mEditor);
} }
} }
@@ -119,7 +121,7 @@ public class ExtractStringAction implements IWorkbenchWindowActionDelegate {
*/ */
public void run(IAction action) { public void run(IAction action) {
if (mSelection != null && mFile != null) { if (mSelection != null && mFile != null) {
ExtractStringRefactoring ref = new ExtractStringRefactoring(mFile, mSelection); ExtractStringRefactoring ref = new ExtractStringRefactoring(mFile, mEditor, mSelection);
RefactoringWizard wizard = new ExtractStringWizard(ref, mFile.getProject()); RefactoringWizard wizard = new ExtractStringWizard(ref, mFile.getProject());
RefactoringWizardOpenOperation op = new RefactoringWizardOpenOperation(wizard); RefactoringWizardOpenOperation op = new RefactoringWizardOpenOperation(wizard);
try { try {
@@ -130,6 +132,21 @@ public class ExtractStringAction implements IWorkbenchWindowActionDelegate {
} }
} }
/**
* 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. * 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. * The file is only returned if it's a file from a project with an Android nature.
@@ -138,33 +155,26 @@ public class ExtractStringAction implements IWorkbenchWindowActionDelegate {
* for the refactoring. This check is performed when the refactoring is invoked since * for the refactoring. This check is performed when the refactoring is invoked since
* it can then produce meaningful error messages as needed. * it can then produce meaningful error messages as needed.
*/ */
private IFile getSelectedFile() { private IFile getSelectedFile(IEditorPart editor) {
IWorkbenchWindow wwin = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); if (editor != null) {
if (wwin != null) { IEditorInput input = editor.getEditorInput();
IWorkbenchPage page = wwin.getActivePage();
if (page != null) { if (input instanceof FileEditorInput) {
IEditorPart editor = page.getActiveEditor(); FileEditorInput fi = (FileEditorInput) input;
if (editor != null) { IFile file = fi.getFile();
IEditorInput input = editor.getEditorInput(); if (file.exists()) {
IProject proj = file.getProject();
if (input instanceof FileEditorInput) { try {
FileEditorInput fi = (FileEditorInput) input; if (proj != null && proj.hasNature(AndroidConstants.NATURE)) {
IFile file = fi.getFile(); return file;
if (file.exists()) {
IProject proj = file.getProject();
try {
if (proj != null && proj.hasNature(AndroidConstants.NATURE)) {
return file;
}
} catch (CoreException e) {
// ignore
}
} }
} catch (CoreException e) {
// ignore
} }
} }
} }
} }
return null; return null;
} }
} }

View File

@@ -366,7 +366,7 @@ public final class FolderConfiguration implements Comparable<FolderConfiguration
} }
} }
return result.toString(); return result == null ? null : result.toString();
} }
public int compareTo(FolderConfiguration folderConfig) { public int compareTo(FolderConfiguration folderConfig) {

View File

@@ -1,5 +1,14 @@
#!/bin/bash #!/bin/bash
HOST=`uname`
if [ "${HOST:0:6}" == "CYGWIN" ]; then
if [ "x$1" == "x" ] || [ `basename "$1"` != "layoutlib.jar" ]; then
echo "Usage: $0 sdk/platforms/xxx/data/layoutlib.jar"
echo "Argument 1 should be the path to the layoutlib.jar that should be updated by create_bridge_symlinks.sh."
exit 1
fi
fi
echo "### $0 executing" echo "### $0 executing"
function die() { function die() {