aboutsummaryrefslogtreecommitdiff
path: root/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/extractstring/ExtractStringAction.java
diff options
context:
space:
mode:
Diffstat (limited to 'eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/extractstring/ExtractStringAction.java')
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/extractstring/ExtractStringAction.java184
1 files changed, 184 insertions, 0 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/extractstring/ExtractStringAction.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/extractstring/ExtractStringAction.java
new file mode 100644
index 000000000..14556fd9f
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/extractstring/ExtractStringAction.java
@@ -0,0 +1,184 @@
+/*
+ * 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;
+ }
+}