| /* |
| * Copyright (C) 2009 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.AdtConstants; |
| |
| import org.eclipse.core.resources.IFile; |
| import org.eclipse.core.resources.IProject; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.jdt.core.ICompilationUnit; |
| import org.eclipse.jdt.core.JavaCore; |
| import org.eclipse.jface.action.IAction; |
| import org.eclipse.jface.text.ITextSelection; |
| import org.eclipse.jface.viewers.ISelection; |
| import org.eclipse.ltk.ui.refactoring.RefactoringWizard; |
| import org.eclipse.ltk.ui.refactoring.RefactoringWizardOpenOperation; |
| 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; |
| |
| /* |
| * Quick Reference Link: |
| * http://www.eclipse.org/articles/article.php?file=Article-Unleashing-the-Power-of-Refactoring/index.html |
| * and |
| * http://www.ibm.com/developerworks/opensource/library/os-ecjdt/ |
| */ |
| |
| /** |
| * Action executed when the "Extract String" menu item is invoked. |
| * <p/> |
| * The intent of the action is to start a refactoring that extracts a source string and |
| * replaces it by an Android string resource ID. |
| * <p/> |
| * Workflow: |
| * <ul> |
| * <li> The action is currently located in the Refactoring menu in the main menu. |
| * <li> TODO: extend the popup refactoring menu in a Java or Android XML file. |
| * <li> The action is only enabled if the selection is 1 character or more. That is at least part |
| * of the string must be selected, it's not enough to just move the insertion point. This is |
| * a limitation due to {@link #selectionChanged(IAction, ISelection)} not being called when |
| * the insertion point is merely moved. TODO: address this limitation. |
| * <ul> The action gets the current {@link ISelection}. It also knows the current |
| * {@link IWorkbenchWindow}. However for the refactoring we are also interested in having the |
| * actual resource file. By looking at the Active Window > Active Page > Active Editor we |
| * can get the {@link IEditorInput} and find the {@link ICompilationUnit} (aka Java file) |
| * that is being edited. |
| * <ul> TODO: change this to find the {@link IFile} being manipulated. The {@link ICompilationUnit} |
| * can be inferred using {@link JavaCore#createCompilationUnitFrom(IFile)}. This will allow |
| * us to be able to work with a selection from an Android XML file later. |
| * <li> The action creates a new {@link ExtractStringRefactoring} and make it run on in a new |
| * {@link ExtractStringWizard}. |
| * <ul> |
| */ |
| public class ExtractStringAction implements IWorkbenchWindowActionDelegate { |
| |
| /** Keep track of the current workbench window. */ |
| private IWorkbenchWindow mWindow; |
| private ITextSelection mSelection; |
| private IEditorPart mEditor; |
| private IFile mFile; |
| |
| /** |
| * Keep track of the current workbench window. |
| */ |
| @Override |
| public void init(IWorkbenchWindow window) { |
| mWindow = window; |
| } |
| |
| @Override |
| public void dispose() { |
| // Nothing to do |
| } |
| |
| /** |
| * Examine the selection to determine if the action should be enabled or not. |
| * <p/> |
| * Keep a link to the relevant selection structure (i.e. a part of the Java AST). |
| */ |
| @Override |
| public void selectionChanged(IAction action, ISelection selection) { |
| |
| // Note, two kinds of selections are returned here: |
| // ITextSelection on a Java source window |
| // IStructuredSelection in the outline or navigator |
| // This simply deals with the refactoring based on a non-empty selection. |
| // At that point, just enable the action and later decide if it's valid when it actually |
| // runs since we don't have access to the AST yet. |
| |
| mSelection = null; |
| mFile = null; |
| |
| if (selection instanceof ITextSelection) { |
| mSelection = (ITextSelection) selection; |
| if (mSelection.getLength() > 0) { |
| mEditor = getActiveEditor(); |
| mFile = getSelectedFile(mEditor); |
| } |
| } |
| |
| action.setEnabled(mSelection != null && mFile != null); |
| } |
| |
| /** |
| * Create a new instance of our refactoring and a wizard to configure it. |
| */ |
| @Override |
| public void run(IAction action) { |
| if (mSelection != null && mFile != null) { |
| ExtractStringRefactoring ref = new ExtractStringRefactoring(mFile, mEditor, mSelection); |
| RefactoringWizard wizard = new ExtractStringWizard(ref, mFile.getProject()); |
| RefactoringWizardOpenOperation op = new RefactoringWizardOpenOperation(wizard); |
| try { |
| op.run(mWindow.getShell(), wizard.getDefaultPageTitle()); |
| } catch (InterruptedException e) { |
| // Interrupted. Pass. |
| } |
| } |
| } |
| |
| /** |
| * 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/> |
| * At that point we do not try to analyze if the selection nor the file is suitable |
| * for the refactoring. This check is performed when the refactoring is invoked since |
| * it can then produce meaningful error messages as needed. |
| */ |
| private IFile getSelectedFile(IEditorPart editor) { |
| if (editor != null) { |
| IEditorInput input = editor.getEditorInput(); |
| |
| if (input instanceof FileEditorInput) { |
| FileEditorInput fi = (FileEditorInput) input; |
| IFile file = fi.getFile(); |
| if (file.exists()) { |
| IProject proj = file.getProject(); |
| try { |
| if (proj != null && proj.hasNature(AdtConstants.NATURE_DEFAULT)) { |
| return file; |
| } |
| } catch (CoreException e) { |
| // ignore |
| } |
| } |
| } |
| } |
| |
| return null; |
| } |
| } |