diff --git a/core/org.eclipse.cdt.ui/.classpath b/core/org.eclipse.cdt.ui/.classpath index 539af0d2b37..61b33a8512d 100644 --- a/core/org.eclipse.cdt.ui/.classpath +++ b/core/org.eclipse.cdt.ui/.classpath @@ -5,5 +5,6 @@ + diff --git a/core/org.eclipse.cdt.ui/ChangeLog b/core/org.eclipse.cdt.ui/ChangeLog index a3e291556c6..0e60d89ca6a 100644 --- a/core/org.eclipse.cdt.ui/ChangeLog +++ b/core/org.eclipse.cdt.ui/ChangeLog @@ -1,3 +1,11 @@ +2004-03-09 Hoda Amer + A new UI tool for renaming model elements. + Mainly under the ui/refactor folder. + This tool relies on search in finding all occurrences + of a specific model element. + and changes the found occurrences in the code to a new name. + It could be invoked by a menu item in the C/C++ Packages view. + 2004-03-09 Hoda Amer Fix for bug#52188: Content Assist: Disabling the '.' (dot) and '->' triggers has no effect. diff --git a/core/org.eclipse.cdt.ui/icons/full/obj16/change.gif b/core/org.eclipse.cdt.ui/icons/full/obj16/change.gif new file mode 100644 index 00000000000..5bef5e71561 Binary files /dev/null and b/core/org.eclipse.cdt.ui/icons/full/obj16/change.gif differ diff --git a/core/org.eclipse.cdt.ui/icons/full/obj16/composite_change.gif b/core/org.eclipse.cdt.ui/icons/full/obj16/composite_change.gif new file mode 100644 index 00000000000..661a2cf2243 Binary files /dev/null and b/core/org.eclipse.cdt.ui/icons/full/obj16/composite_change.gif differ diff --git a/core/org.eclipse.cdt.ui/icons/full/obj16/cu_change.gif b/core/org.eclipse.cdt.ui/icons/full/obj16/cu_change.gif new file mode 100644 index 00000000000..02fad7f59af Binary files /dev/null and b/core/org.eclipse.cdt.ui/icons/full/obj16/cu_change.gif differ diff --git a/core/org.eclipse.cdt.ui/icons/full/obj16/error_obj.gif b/core/org.eclipse.cdt.ui/icons/full/obj16/error_obj.gif new file mode 100644 index 00000000000..b04020bc723 Binary files /dev/null and b/core/org.eclipse.cdt.ui/icons/full/obj16/error_obj.gif differ diff --git a/core/org.eclipse.cdt.ui/icons/full/obj16/fatalerror_obj.gif b/core/org.eclipse.cdt.ui/icons/full/obj16/fatalerror_obj.gif new file mode 100644 index 00000000000..d85b98be77a Binary files /dev/null and b/core/org.eclipse.cdt.ui/icons/full/obj16/fatalerror_obj.gif differ diff --git a/core/org.eclipse.cdt.ui/icons/full/obj16/file_change.gif b/core/org.eclipse.cdt.ui/icons/full/obj16/file_change.gif new file mode 100644 index 00000000000..df822a92fc8 Binary files /dev/null and b/core/org.eclipse.cdt.ui/icons/full/obj16/file_change.gif differ diff --git a/core/org.eclipse.cdt.ui/icons/full/obj16/info_obj.gif b/core/org.eclipse.cdt.ui/icons/full/obj16/info_obj.gif new file mode 100644 index 00000000000..26c7477336c Binary files /dev/null and b/core/org.eclipse.cdt.ui/icons/full/obj16/info_obj.gif differ diff --git a/core/org.eclipse.cdt.ui/icons/full/obj16/text_edit.gif b/core/org.eclipse.cdt.ui/icons/full/obj16/text_edit.gif new file mode 100644 index 00000000000..c639f65e1f4 Binary files /dev/null and b/core/org.eclipse.cdt.ui/icons/full/obj16/text_edit.gif differ diff --git a/core/org.eclipse.cdt.ui/icons/full/obj16/warning_obj.gif b/core/org.eclipse.cdt.ui/icons/full/obj16/warning_obj.gif new file mode 100644 index 00000000000..cf8d571833d Binary files /dev/null and b/core/org.eclipse.cdt.ui/icons/full/obj16/warning_obj.gif differ diff --git a/core/org.eclipse.cdt.ui/icons/full/wizban/fieldrefact_wiz.gif b/core/org.eclipse.cdt.ui/icons/full/wizban/fieldrefact_wiz.gif new file mode 100644 index 00000000000..2e0d346881a Binary files /dev/null and b/core/org.eclipse.cdt.ui/icons/full/wizban/fieldrefact_wiz.gif differ diff --git a/core/org.eclipse.cdt.ui/icons/full/wizban/methrefact_wiz.gif b/core/org.eclipse.cdt.ui/icons/full/wizban/methrefact_wiz.gif new file mode 100644 index 00000000000..3ea2af722aa Binary files /dev/null and b/core/org.eclipse.cdt.ui/icons/full/wizban/methrefact_wiz.gif differ diff --git a/core/org.eclipse.cdt.ui/icons/full/wizban/typerefact_wiz.gif b/core/org.eclipse.cdt.ui/icons/full/wizban/typerefact_wiz.gif new file mode 100644 index 00000000000..90e2d452778 Binary files /dev/null and b/core/org.eclipse.cdt.ui/icons/full/wizban/typerefact_wiz.gif differ diff --git a/core/org.eclipse.cdt.ui/plugin.properties b/core/org.eclipse.cdt.ui/plugin.properties index e55906c1cc7..14731ce2c92 100644 --- a/core/org.eclipse.cdt.ui/plugin.properties +++ b/core/org.eclipse.cdt.ui/plugin.properties @@ -93,9 +93,15 @@ PathNameSorter.tooltip= Sort the view by Resource Path # Action sets CSearchActionSet.label= C/C++ Search CSearchActionSet.description= Action set containing search related C/C++ actions +RefactoringActionSet.label= Refactoring +RefactoringActionSet.description= Action set containing refactoring related actions # Menus searchMenu.label= Se&arch +refactoringMenu.label= Re&factor + +# Refactoring +Refactoring.renameAction.label= Re&name # Open Type OpenTypeAction.label= Open &Type... diff --git a/core/org.eclipse.cdt.ui/plugin.xml b/core/org.eclipse.cdt.ui/plugin.xml index 43db1bb2e98..50a8fc94d98 100644 --- a/core/org.eclipse.cdt.ui/plugin.xml +++ b/core/org.eclipse.cdt.ui/plugin.xml @@ -27,6 +27,7 @@ + @@ -166,35 +167,35 @@ id="org.eclipse.cdt.ui.ceditor" point="org.eclipse.ui.editors"> @@ -263,16 +264,16 @@ @@ -283,20 +284,37 @@ + + + + + + + + @@ -322,24 +340,24 @@ @@ -380,8 +398,8 @@ - @@ -454,24 +471,24 @@ pageId="org.eclipse.cdt.ui.CSearchPage" label="%ElementNameSorter.label" icon="icons/full/clcl16/search_sortmatch.gif" - tooltip="%ElementNameSorter.tooltip" class="org.eclipse.cdt.internal.ui.search.ElementNameSorter" + tooltip="%ElementNameSorter.tooltip" id="org.eclipse.cdt.search.internal.ui.ElementNameSorter"> @@ -524,20 +541,19 @@ - \n"); //$NON-NLS-2$ //$NON-NLS-1$ + } + return buff.toString(); + } + + /* non java-doc + * @see IChange#getName() + */ + public String getName() { + return fName; + } + + /* non java-doc + * @see IChange#getModifiedLanguageElement() + */ + public Object getModifiedLanguageElement() { + return null; + } + + /* non java-doc + * @see IChange#setActive + * This method activates/disactivates all subchanges of this change. The + * change itself is always active to ensure that sub changes are always + * considered if they are active. + */ + public void setActive(boolean active) { + for (Iterator iter= fChanges.iterator(); iter.hasNext(); ) { + ((IChange)iter.next()).setActive(active); + } + } + + /*non java-doc + * @see IChange#isUndoable() + * Composite can be undone iff all its sub-changes can be undone. + */ + public boolean isUndoable() { + for (Iterator iter= fChanges.iterator(); iter.hasNext(); ) { + IChange each= (IChange)iter.next(); + if (! each.isUndoable()) + return false; + } + return true; + } +} diff --git a/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/IProcessorBasedRefactoring.java b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/IProcessorBasedRefactoring.java new file mode 100644 index 00000000000..35b61e86886 --- /dev/null +++ b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/IProcessorBasedRefactoring.java @@ -0,0 +1,28 @@ +/********************************************************************** + * Copyright (c) 2004 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.internal.corext.refactoring; + +import org.eclipse.core.runtime.IAdaptable; + +/** + * A tagging interface for refactorings that are implemented using + * the processor/participant architecture + */ +public interface IProcessorBasedRefactoring extends IAdaptable { + + /** + * Returns the refactoring's processor + * + * @return the refactoring's processor + */ + public IRefactoringProcessor getProcessor(); + +} diff --git a/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/IQualifiedNameUpdatingRefactoring.java b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/IQualifiedNameUpdatingRefactoring.java new file mode 100644 index 00000000000..ec6b497491e --- /dev/null +++ b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/IQualifiedNameUpdatingRefactoring.java @@ -0,0 +1,43 @@ +/********************************************************************** + * Copyright (c) 2004 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.internal.corext.refactoring; + +public interface IQualifiedNameUpdatingRefactoring { + + /** + * Performs a dynamic check whether this refactoring object is capable of + * updating qualified names in non C files. The return value of this + * method may change according to the state of the refactoring. + */ + public boolean canEnableQualifiedNameUpdating(); + + /** + * If canEnableQualifiedNameUpdating returns true, + * then this method is used to ask the refactoring object whether references + * in non C files should be updated. This call can be ignored if + * canEnableQualifiedNameUpdating returns false. + */ + public boolean getUpdateQualifiedNames(); + + /** + * If canEnableQualifiedNameUpdating returns true, + * then this method is used to inform the refactoring object whether + * references in non C files should be updated. This call can be ignored + * if canEnableQualifiedNameUpdating returns false. + */ + public void setUpdateQualifiedNames(boolean update); + + public String getFilePatterns(); + + public void setFilePatterns(String patterns); +} + + diff --git a/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/IRefactoringProcessor.java b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/IRefactoringProcessor.java new file mode 100644 index 00000000000..34e85834ffb --- /dev/null +++ b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/IRefactoringProcessor.java @@ -0,0 +1,43 @@ +/********************************************************************** + * Copyright (c) 2004 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.internal.corext.refactoring; + +import org.eclipse.cdt.internal.corext.refactoring.base.IChange; +import org.eclipse.cdt.internal.corext.refactoring.base.RefactoringStatus; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.core.runtime.IProgressMonitor; + + +public interface IRefactoringProcessor extends IAdaptable { + + public void initialize(Object[] elements) throws CoreException; + + public boolean isAvailable() throws CoreException; + + public String getProcessorName(); + + public int getStyle(); + +// public IProject[] getAffectedProjects() throws CoreException; + + public Object[] getElements(); + + public Object[] getDerivedElements() throws CoreException; + +// public IResourceModifications getResourceModifications() throws CoreException; + + public RefactoringStatus checkActivation() throws CoreException; + + public RefactoringStatus checkInput(IProgressMonitor pm) throws CoreException; + + public IChange createChange(IProgressMonitor pm) throws CoreException; +} diff --git a/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/IReferenceUpdating.java b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/IReferenceUpdating.java new file mode 100644 index 00000000000..d9aa0e65a6a --- /dev/null +++ b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/IReferenceUpdating.java @@ -0,0 +1,35 @@ +/********************************************************************** + * Copyright (c) 2004 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.internal.corext.refactoring; + +public interface IReferenceUpdating { + + /** + * Checks if this refactoring object is capable of updating references to the renamed element. + */ + public boolean canEnableUpdateReferences(); + + /** + * If canUpdateReferences returns true, then this method is used to + * inform the refactoring object whether references should be updated. + * This call can be ignored if canUpdateReferences returns false. + */ + public void setUpdateReferences(boolean update); + + /** + * If canUpdateReferences returns true, then this method is used to + * ask the refactoring object whether references should be updated. + * This call can be ignored if canUpdateReferences returns false. + */ + public boolean getUpdateReferences(); + +} + diff --git a/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/IRenameProcessor.java b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/IRenameProcessor.java new file mode 100644 index 00000000000..fc037241dc0 --- /dev/null +++ b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/IRenameProcessor.java @@ -0,0 +1,28 @@ +/********************************************************************** + * Copyright (c) 2004 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.internal.corext.refactoring; + +import org.eclipse.core.runtime.CoreException; + +import org.eclipse.cdt.internal.corext.refactoring.base.*; + + +public interface IRenameProcessor extends IRefactoringProcessor { + + public String getCurrentElementName(); + + public RefactoringStatus checkNewElementName(String newName) throws CoreException; + + public void setNewElementName(String newName); + + public String getNewElementName(); + +} diff --git a/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/IRenameRefactoring.java b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/IRenameRefactoring.java new file mode 100644 index 00000000000..6e462e9b92f --- /dev/null +++ b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/IRenameRefactoring.java @@ -0,0 +1,40 @@ +/********************************************************************** + * Copyright (c) 2004 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.internal.corext.refactoring; + +import org.eclipse.cdt.core.model.CModelException; +import org.eclipse.cdt.internal.corext.refactoring.base.*; + +/** + * Represents a refactoring that renames an ICElement. + */ +public interface IRenameRefactoring extends IRefactoring { + + /** + * Sets new name for the entity that this refactoring is working on. + */ + public void setNewName(String newName); + + /** + * Get the name for the entity that this refactoring is working on. + */ + public String getNewName(); + + /** + * Gets the current name of the entity that this refactoring is working on. + */ + public String getCurrentName(); + + /** + * Checks if the new name is valid for the entity that this refactoring renames. + */ + public RefactoringStatus checkNewName(String newName) throws CModelException; +} diff --git a/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/IResourceModifications.java b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/IResourceModifications.java new file mode 100644 index 00000000000..2b94370421f --- /dev/null +++ b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/IResourceModifications.java @@ -0,0 +1,93 @@ +/********************************************************************** + * Copyright (c) 2004 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.internal.corext.refactoring; + + +import java.util.List; + +import org.eclipse.core.resources.IContainer; +import org.eclipse.core.resources.IResource; + +/** + * A data structure describing the resource modification resulting from + * applying a certain refactoring. + * + * @since 3.0 + */ +public interface IResourceModifications { + + /** + * Returns the list of resources to be created. + * + * @return the list of resources to be created + */ + public List getCreate(); + + /** + * Returns the list of resources to be deleted. + * + * @return the list of resources to be deleted + */ + public List getDelete(); + + /** + * Returns the list of resources to be copied. + * + * @return the list of resources to be copied + */ + public List getCopy(); + + /** + * Returns the copy target. + * + * @return the copy target + */ + public IContainer getCopyTarget(); + + /** + * Returns the list of resources to be moved. + * + * @return the list of resources to be moved + */ + public List getMove(); + + /** + * Returns the move target + * + * @return the move target + */ + public IContainer getMoveTarget(); + + /** + * Returns the resource to be renamed + * + * @return the resourcr to be renamed + */ + public IResource getRename(); + + /** + * Returns the new name of the resource to be renamed + * + * @return the new resource name + */ + public String getNewName(); + + /** + * Returns an array of participants that want to participate + * in the resource modifications described by this data + * structure. + * + * @param processor the main processor of the overall refactoring + * @return an array of participants + */ +// public IRefactoringParticipant[] getParticipants(IRefactoringProcessor processor, SharableParticipants shared) throws CoreException; + +} diff --git a/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/ITextUpdating.java b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/ITextUpdating.java new file mode 100644 index 00000000000..2d07a8555f8 --- /dev/null +++ b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/ITextUpdating.java @@ -0,0 +1,80 @@ +/********************************************************************** + * Copyright (c) 2004 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.internal.corext.refactoring; + + + +public interface ITextUpdating { + + /** + * Performs a dynamic check whether this refactoring object is capable of updating references to the renamed element. + */ + public boolean canEnableTextUpdating(); + + /** + * If canEnableTextUpdating returns true, then this method is used to + * ask the refactoring object whether references in JavaDoc comments should be updated. + * This call can be ignored if canEnableTextUpdating returns false. + */ + public boolean getUpdateJavaDoc(); + + /** + * If canEnableTextUpdating returns true, then this method is used to + * ask the refactoring object whether references in regular (non JavaDoc) comments should be updated. + * This call can be ignored if canEnableTextUpdating returns false. + */ + public boolean getUpdateComments(); + + /** + * If canEnableTextUpdating returns true, then this method is used to + * ask the refactoring object whether references in string literals should be updated. + * This call can be ignored if canEnableTextUpdating returns false. + */ + public boolean getUpdateStrings(); + + /** + * If canEnableTextUpdating returns true, then this method is used to + * inform the refactoring object whether references in JavaDoc comments should be updated. + * This call can be ignored if canEnableTextUpdating returns false. + */ + public void setUpdateJavaDoc(boolean update); + + /** + * If canEnableTextUpdating returns true, then this method is used to + * inform the refactoring object whether references in regular (non JavaDoc) comments should be updated. + * This call can be ignored if canEnableTextUpdating returns false. + */ + public void setUpdateComments(boolean update); + + /** + * If canEnableTextUpdating returns true, then this method is used to + * inform the refactoring object whether references in string literals should be updated. + * This call can be ignored if canEnableTextUpdating returns false. + */ + public void setUpdateStrings(boolean update); + + /** + * Returns the current name of the element to be renamed. + * + * @return the current name of the element to be renamed + */ + public String getCurrentElementName(); + + /** + * Returns the new name of the element + * + * @return the new element name + */ + public String getNewElementName(); +} + + + diff --git a/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/NullChange.java b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/NullChange.java new file mode 100644 index 00000000000..273096cfd50 --- /dev/null +++ b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/NullChange.java @@ -0,0 +1,43 @@ +/********************************************************************** + * Copyright (c) 2004 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.internal.corext.refactoring; + +import org.eclipse.cdt.internal.corext.refactoring.base.*; +import org.eclipse.core.runtime.IProgressMonitor; + + +public class NullChange extends Change { + + private String fName; + + public NullChange(String name){ + fName= name; + } + + public NullChange(){ + this(null); + } + + public void perform(ChangeContext context, IProgressMonitor pm) { + } + + public IChange getUndoChange() { + return new NullChange(fName); + } + + public String getName(){ + return "NullChange (" + fName + ")"; //$NON-NLS-1$ //$NON-NLS-2$ + } + + public Object getModifiedLanguageElement(){ + return null; + } +} diff --git a/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/RefactoringCoreMessages.java b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/RefactoringCoreMessages.java new file mode 100644 index 00000000000..010f9c8b80c --- /dev/null +++ b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/RefactoringCoreMessages.java @@ -0,0 +1,66 @@ +/********************************************************************** + * Copyright (c) 2004 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.internal.corext.refactoring; + +import java.text.MessageFormat; +import java.util.MissingResourceException; +import java.util.ResourceBundle; + +public class RefactoringCoreMessages { + + private static final String RESOURCE_BUNDLE= "org.eclipse.cdt.internal.corext.refactoring.refactoring";//$NON-NLS-1$ + + private static ResourceBundle fgResourceBundle= ResourceBundle.getBundle(RESOURCE_BUNDLE); + + private RefactoringCoreMessages() { + } + + public static String getString(String key) { + try { + return fgResourceBundle.getString(key); + } catch (MissingResourceException e) { + return "!" + key + "!";//$NON-NLS-2$ //$NON-NLS-1$ + } + } + + public static String getFormattedString(String key, String arg) { + try{ + return MessageFormat.format(fgResourceBundle.getString(key), new String[] { arg }); + } catch (MissingResourceException e) { + return "!" + key + "!";//$NON-NLS-2$ //$NON-NLS-1$ + } + } + + public static String getFormattedString(String key, Object arg) { + try{ + return MessageFormat.format(fgResourceBundle.getString(key), new Object[] { arg }); + } catch (MissingResourceException e) { + return "!" + key + "!";//$NON-NLS-2$ //$NON-NLS-1$ + } + } + + public static String getFormattedString(String key, String[] args) { + try{ + return MessageFormat.format(fgResourceBundle.getString(key), args); + } catch (MissingResourceException e) { + return "!" + key + "!";//$NON-NLS-2$ //$NON-NLS-1$ + } + } + + public static String getFormattedString(String key, Object[] args) { + try{ + return MessageFormat.format(fgResourceBundle.getString(key), args); + } catch (MissingResourceException e) { + return "!" + key + "!";//$NON-NLS-2$ //$NON-NLS-1$ + } + } + +} diff --git a/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/RefactoringSearchEngine.java b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/RefactoringSearchEngine.java new file mode 100644 index 00000000000..9ac2447de7c --- /dev/null +++ b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/RefactoringSearchEngine.java @@ -0,0 +1,160 @@ +/********************************************************************** + * Copyright (c) 2004 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.internal.corext.refactoring; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.eclipse.cdt.core.model.CModelException; +import org.eclipse.cdt.core.model.CoreModel; +import org.eclipse.cdt.core.model.ICElement; +import org.eclipse.cdt.core.model.ITranslationUnit; +import org.eclipse.cdt.core.search.BasicSearchMatch; +import org.eclipse.cdt.core.search.BasicSearchResultCollector; +import org.eclipse.cdt.core.search.ICSearchPattern; +import org.eclipse.cdt.core.search.ICSearchResultCollector; +import org.eclipse.cdt.core.search.ICSearchScope; +import org.eclipse.cdt.core.search.SearchEngine; +import org.eclipse.cdt.internal.corext.Assert; +import org.eclipse.cdt.internal.corext.util.CModelUtil; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.IProgressMonitor; + + +/** + * Convenience wrapper for SearchEngine - performs searching and sorts the results. + */ +public class RefactoringSearchEngine { + + //no instances + private RefactoringSearchEngine(){ + } + + public static ITranslationUnit[] findAffectedTranslationUnits(final IProgressMonitor pm, ICSearchScope scope, ICSearchPattern pattern) throws CModelException { + final Set matches= new HashSet(5); + ICSearchResultCollector collector = new BasicSearchResultCollector(); + try { + new SearchEngine().search(ResourcesPlugin.getWorkspace(), pattern, scope, collector, false); + } catch (InterruptedException e){ + + } + + List result= new ArrayList(matches.size()); + for (Iterator iter= matches.iterator(); iter.hasNext(); ) { + IResource resource= (IResource)iter.next(); + ICElement element= CoreModel.getDefault().create(resource); + if (element instanceof ITranslationUnit) { + ITranslationUnit original= (ITranslationUnit)element; + result.add(CModelUtil.toWorkingCopy(original)); // take working copy is there is one + } + } + return (ITranslationUnit[])result.toArray(new ITranslationUnit[result.size()]); + } + + /** + * Performs searching for a given SearchPattern. + * Returns SearchResultGroup[] + * In each of SearchResultGroups all SearchResults are + * sorted backwards by SearchResult#getStart() + * @see SearchResult + */ + public static SearchResultGroup[] search(IProgressMonitor pm, ICSearchScope scope, ICSearchPattern pattern) throws CModelException { + return search(scope, pattern, new BasicSearchResultCollector(pm)); + } + + public static SearchResultGroup[] search(ICSearchScope scope, ICSearchPattern pattern, BasicSearchResultCollector collector) throws CModelException { + return search(scope, pattern, collector, null); + } + + public static SearchResultGroup[] search(IProgressMonitor pm, ICSearchScope scope, ICSearchPattern pattern, ITranslationUnit[] workingCopies) throws CModelException { + return search(scope, pattern, new BasicSearchResultCollector(pm), workingCopies); + } + + public static SearchResultGroup[] search(ICSearchScope scope, ICSearchPattern pattern, BasicSearchResultCollector collector, ITranslationUnit[] workingCopies) throws CModelException { + internalSearch(scope, pattern, collector, workingCopies); + Set results = collector.getSearchResults(); + List resultList = new ArrayList(results); + return groupByResource(createSearchResultArray(resultList)); + } + + public static SearchResultGroup[] groupByResource(BasicSearchMatch[] results){ + Map grouped= groupByResource(Arrays.asList(results)); + + SearchResultGroup[] result= new SearchResultGroup[grouped.keySet().size()]; + int i= 0; + for (Iterator iter= grouped.keySet().iterator(); iter.hasNext();) { + IResource resource= (IResource)iter.next(); + List searchResults= (List)grouped.get(resource); + result[i]= new SearchResultGroup(resource, createSearchResultArray(searchResults)); + i++; + } + return result; + } + + private static BasicSearchMatch[] createSearchResultArray(List searchResults){ + return (BasicSearchMatch[])searchResults.toArray(new BasicSearchMatch[searchResults.size()]); + } + + private static Map groupByResource(List searchResults){ + Map grouped= new HashMap(); //IResource -> List of SearchResults + for (Iterator iter= searchResults.iterator(); iter.hasNext();) { + BasicSearchMatch searchResult= (BasicSearchMatch) iter.next(); + if (! grouped.containsKey(searchResult.getResource())) + grouped.put(searchResult.getResource(), new ArrayList(1)); + ((List)grouped.get(searchResult.getResource())).add(searchResult); + } + return grouped; + } + + private static void internalSearch(ICSearchScope scope, ICSearchPattern pattern, ICSearchResultCollector collector, ITranslationUnit[] workingCopies) throws CModelException { + if (pattern == null) + return; + Assert.isNotNull(scope, "scope"); //$NON-NLS-1$ + try { + createSearchEngine(workingCopies).search(ResourcesPlugin.getWorkspace(), pattern, scope, collector, false); + }catch (InterruptedException e){ + + } + } + + private static SearchEngine createSearchEngine(ITranslationUnit[] workingCopies){ +// if (workingCopies == null) + return new SearchEngine(); +// else +// return new SearchEngine(workingCopies); + } + +// public static ICSearchPattern createSearchPattern(ICElement[] elements, int limitTo) { +// if (elements == null || elements.length == 0) +// return null; +// Set set= new HashSet(Arrays.asList(elements)); +// Iterator iter= set.iterator(); +// ICElement first= (ICElement)iter.next(); +// ICSearchPattern pattern= createSearchPattern(first, limitTo); +// while(iter.hasNext()){ +// ICElement each= (ICElement)iter.next(); +// pattern= SearchEngine.createOrSearchPattern(pattern, createSearchPattern(each, limitTo)); +// } +// return pattern; +// } + +// private static ICSearchPattern createSearchPattern(ICElement element, int limitTo) { +// return SearchEngine.createSearchPattern(element, limitTo, true); +// } + +} diff --git a/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/RefactoringStyles.java b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/RefactoringStyles.java new file mode 100644 index 00000000000..1b9e1f6668c --- /dev/null +++ b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/RefactoringStyles.java @@ -0,0 +1,24 @@ +/********************************************************************** + * Copyright (c) 2004 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.internal.corext.refactoring; + + +public final class RefactoringStyles { + + public static final int NONE= 0; + public static final int NEEDS_PREVIEW= 1 << 0; + public static final int FORCE_PREVIEW= 1 << 1; + public static final int NEEDS_PROGRESS= 1 << 2; + + private RefactoringStyles() { + // no instance + } +} diff --git a/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/RenameProcessor.java b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/RenameProcessor.java new file mode 100644 index 00000000000..906775d69ed --- /dev/null +++ b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/RenameProcessor.java @@ -0,0 +1,68 @@ +/********************************************************************** + * Copyright (c) 2004 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.internal.corext.refactoring; + +import org.eclipse.cdt.internal.corext.Assert; +import org.eclipse.core.runtime.CoreException; + +public abstract class RenameProcessor implements IRenameProcessor { + + private int fStyle; + protected String fNewElementName; + + public int getStyle() { + return fStyle; + } + + protected RenameProcessor() { + fStyle= RefactoringStyles.NEEDS_PREVIEW; + } + + protected RenameProcessor(int style) { + fStyle= style; + } + + /* (non-Javadoc) + * @see org.eclipse.jdt.internal.corext.refactoring.participants.IRenameProcessor#setNewElementName(java.lang.String) + */ + public void setNewElementName(String newName) { + Assert.isNotNull(newName); + fNewElementName= newName; + } + + /* (non-Javadoc) + * @see org.eclipse.jdt.internal.corext.refactoring.participants.IRenameProcessor#getNewElementName() + */ + public String getNewElementName() { + return fNewElementName; + } + + /* (non-Javadoc) + * @see org.eclipse.jdt.internal.corext.refactoring.participants.IRefactoringProcessor#getDerivedElements() + */ + public Object[] getDerivedElements() throws CoreException { + return new Object[0]; + } + +// public void propagateDataTo(IRenameParticipant participant) throws CoreException { +// participant.setNewElementName(fNewElementName); +// if (this instanceof IReferenceUpdating) { +// participant.setUpdateReferences(((IReferenceUpdating)this).getUpdateReferences()); +// } +// } + + /* (non-Javadoc) + * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class) + */ + public Object getAdapter(Class clazz) { + return null; + } +} diff --git a/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/RenameRefactoring.java b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/RenameRefactoring.java new file mode 100644 index 00000000000..e1a79ea7f84 --- /dev/null +++ b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/RenameRefactoring.java @@ -0,0 +1,156 @@ +/********************************************************************** + * Copyright (c) 2004 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.internal.corext.refactoring; + + +import org.eclipse.cdt.core.model.CModelException; +import org.eclipse.cdt.internal.corext.Assert; +import org.eclipse.cdt.internal.corext.refactoring.base.IChange; +import org.eclipse.cdt.internal.corext.refactoring.base.Refactoring; +import org.eclipse.cdt.internal.corext.refactoring.base.RefactoringStatus; +import org.eclipse.cdt.internal.corext.refactoring.rename.RenameElementProcessor; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.SubProgressMonitor; + +public class RenameRefactoring extends Refactoring implements IProcessorBasedRefactoring, IRenameRefactoring { + + private Object fElement; + private IRenameProcessor fProcessor; + + public RenameRefactoring(Object element) throws CoreException { + Assert.isNotNull(element); + + fElement= element; + fProcessor = new RenameElementProcessor(); + fProcessor.initialize(new Object[] {fElement}); + } + + public boolean isAvailable() { + return fProcessor != null; + } + + public Object getAdapter(Class clazz) { + if (clazz.isInstance(fProcessor)) + return fProcessor; + return super.getAdapter(clazz); + } + + public IRefactoringProcessor getProcessor() { + return fProcessor; + } + + public int getStyle() { + return fProcessor.getStyle(); + } + + /* (non-Javadoc) + * @see org.eclipse.jdt.internal.corext.refactoring.tagging.IRenameRefactoring#getNewName() + */ + public String getNewName() { + return fProcessor.getNewElementName(); + } + + /* (non-Javadoc) + * @see org.eclipse.jdt.internal.corext.refactoring.tagging.IRenameRefactoring#setNewName(java.lang.String) + */ + public void setNewName(String newName) { + fProcessor.setNewElementName(newName); + } + + + /* (non-Javadoc) + * @see org.eclipse.jdt.internal.corext.refactoring.tagging.IRenameRefactoring#getCurrentName() + */ + public String getCurrentName() { + return fProcessor.getCurrentElementName(); + } + + /* (non-Javadoc) + * @see org.eclipse.jdt.internal.corext.refactoring.tagging.IRenameRefactoring#checkNewName(java.lang.String) + */ + public RefactoringStatus checkNewName(String newName) throws CModelException { + RefactoringStatus result= new RefactoringStatus(); + try { + result.merge(fProcessor.checkNewElementName(newName)); + } catch (CoreException e) { + throw new CModelException(e); + } + return result; + } + + /* (non-Javadoc) + * @see org.eclipse.jdt.internal.corext.refactoring.base.IRefactoring#getName() + */ + public String getName() { + return fProcessor.getProcessorName(); + } + + /* (non-Javadoc) + * @see org.eclipse.jdt.internal.corext.refactoring.base.Refactoring#checkActivation(org.eclipse.core.runtime.IProgressMonitor) + */ + public RefactoringStatus checkActivation(IProgressMonitor pm) throws CModelException { + RefactoringStatus result= new RefactoringStatus(); + try { + result.merge(fProcessor.checkActivation()); + } catch (CoreException e) { + throw new CModelException(e); + } + return result; + } + + /* (non-Javadoc) + * @see org.eclipse.jdt.internal.corext.refactoring.base.Refactoring#checkInput(org.eclipse.core.runtime.IProgressMonitor) + */ + public RefactoringStatus checkInput(IProgressMonitor pm) throws CModelException { + RefactoringStatus result= new RefactoringStatus(); + try { + //initParticipants(); + pm.beginTask("", 2); //$NON-NLS-1$ + + result.merge(fProcessor.checkInput(new SubProgressMonitor(pm, 1))); + if (result.hasFatalError()) + return result; + + } catch (CModelException e) { + throw e; + } catch (CoreException e) { + throw new CModelException(e); + } + return result; + } + + /* (non-Javadoc) + * @see org.eclipse.jdt.internal.corext.refactoring.base.IRefactoring#createChange(org.eclipse.core.runtime.IProgressMonitor) + */ + public IChange createChange(IProgressMonitor pm) throws CModelException { + pm.beginTask("", 1); //$NON-NLS-1$ + CompositeChange result= new CompositeChange(); + try { + result.add(fProcessor.createChange(new SubProgressMonitor(pm, 1))); + } catch (CModelException e) { + throw e; + } catch (CoreException e) { + throw new CModelException(e); + } + return result; + } + + /* non java-doc + * for debugging only + */ + public String toString() { + if (isAvailable()) + return getName(); + else + return "No refactoring available to process: " + fElement; + } +} diff --git a/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/ResourceUtil.java b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/ResourceUtil.java new file mode 100644 index 00000000000..16ec0e997d5 --- /dev/null +++ b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/ResourceUtil.java @@ -0,0 +1,83 @@ +/********************************************************************** + * Copyright (c) 2004 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.internal.corext.refactoring; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.cdt.core.model.ICElement; +import org.eclipse.cdt.core.model.IMember; +import org.eclipse.cdt.core.model.IOpenable; +import org.eclipse.cdt.core.model.ITranslationUnit; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IResource; + +public class ResourceUtil { + + private ResourceUtil(){ + } + + public static IFile[] getFiles(ITranslationUnit[] cus) { + List files= new ArrayList(cus.length); + for (int i= 0; i < cus.length; i++) { + IResource resource= ResourceUtil.getResource(cus[i]); + if (resource.getType() == IResource.FILE) + files.add(resource); + } + return (IFile[]) files.toArray(new IFile[files.size()]); + } + + public static IFile getFile(ITranslationUnit cu) { + IResource resource= ResourceUtil.getResource(cu); + if (resource.getType() == IResource.FILE) + return (IFile)resource; + else + return null; + } + + //----- other ------------------------------ + + /** + * Finds an IResource for a given ITranslationUnit. + * If the parameter is a working copy then the IResource for + * the original element is returned. + */ + public static IResource getResource(ITranslationUnit cu) { + return cu.getResource(); + } + + + /** + * Returns the IResource that the given IMember is defined in. + * @see #getResource + */ + public static IResource getResource(IMember member) { + //Assert.isTrue(!member.isBinary()); + return getResource(member.getTranslationUnit()); + } + + public static IResource getResource(Object o){ + if (o instanceof IResource) + return (IResource)o; + if (o instanceof ICElement) + return getResource((ICElement)o); + return null; + } + + private static IResource getResource(ICElement element){ + if (element.getElementType() == ICElement.C_UNIT) + return getResource((ITranslationUnit) element); + else if (element instanceof IOpenable) + return element.getResource(); + else + return null; + } +} diff --git a/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/SearchResultGroup.java b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/SearchResultGroup.java new file mode 100644 index 00000000000..4aabc0c2b4d --- /dev/null +++ b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/SearchResultGroup.java @@ -0,0 +1,60 @@ +/********************************************************************** + * Copyright (c) 2004 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.internal.corext.refactoring; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.eclipse.cdt.core.search.BasicSearchMatch; +import org.eclipse.cdt.internal.corext.Assert; +import org.eclipse.core.resources.IResource; + +public class SearchResultGroup { + + private final IResource fResouce; + private final List fSearchResults; + + public SearchResultGroup(IResource res, BasicSearchMatch[] results){ + Assert.isNotNull(results); + fResouce= res; + fSearchResults= new ArrayList(Arrays.asList(results));//have to is this way to allow adding + } + + public void add(BasicSearchMatch result) { + Assert.isNotNull(result); + fSearchResults.add(result); + } + + public IResource getResource() { + return fResouce; + } + + public BasicSearchMatch[] getSearchResults() { + return (BasicSearchMatch[]) fSearchResults.toArray(new BasicSearchMatch[fSearchResults.size()]); + } + + public static IResource[] getResources(SearchResultGroup[] searchResultGroups){ + Set resourceSet= new HashSet(searchResultGroups.length); + for (int i= 0; i < searchResultGroups.length; i++) { + resourceSet.add(searchResultGroups[i].getResource()); + } + return (IResource[]) resourceSet.toArray(new IResource[resourceSet.size()]); + } + + public IResource getResultGroupResource(){ + if (getSearchResults() == null || getSearchResults().length == 0) + return null; + return getSearchResults()[0].getResource(); + } +} diff --git a/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/TextChangeManager.java b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/TextChangeManager.java new file mode 100644 index 00000000000..51d8166d44e --- /dev/null +++ b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/TextChangeManager.java @@ -0,0 +1,117 @@ +/********************************************************************** + * Copyright (c) 2004 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.internal.corext.refactoring; + +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.core.runtime.CoreException; + +import org.eclipse.cdt.core.model.ITranslationUnit; + +import org.eclipse.cdt.internal.corext.refactoring.changes.TranslationUnitChange; +import org.eclipse.cdt.internal.corext.refactoring.changes.TextChange; + +/** + * A TextChangeManager manages associations between ITranslationUnit + * or IFile and TextChange objects. + */ +public class TextChangeManager { + + private Map fMap= new HashMap(10); // ITranslationUnit -> TextChange + + private final boolean fKeepExecutedTextEdits; + + public TextChangeManager() { + this(false); + } + + /** + * @see TextChange.setKeepExecutedTextEdits + */ + public TextChangeManager(boolean keepExecutedTextEdits) { + fKeepExecutedTextEdits= keepExecutedTextEdits; + } + + /** + * Adds an association between the given Translation unit and the passed + * change to this manager. + * + * @param cu the Translation unit (key) + * @param change the change associated with the Translation unit + */ + public void manage(ITranslationUnit cu, TextChange change) { + fMap.put(cu, change); + } + + /** + * Returns the TextChange associated with the given Translation unit. + * If the manager does not already manage an association it creates a one. + * + * @param cu the Translation unit for which the text buffer change is requested + * @return the text change associated with the given Translation unit. + */ + public TextChange get(ITranslationUnit cu) throws CoreException { + TextChange result= (TextChange)fMap.get(cu); + if (result == null) { + result= new TranslationUnitChange(cu.getElementName(), cu); + result.setKeepExecutedTextEdits(fKeepExecutedTextEdits); + fMap.put(cu, result); + } + return result; + } + + /** + * Removes the TextChange managed under the given key + * unit. + * + * @param unit the key determining the TextChange to be removed. + * @return the removed TextChange. + */ + public TextChange remove(ITranslationUnit unit) { + return (TextChange)fMap.remove(unit); + } + + /** + * Returns all text changes managed by this instance. + * + * @return all text changes managed by this instance + */ + public TextChange[] getAllChanges(){ + return (TextChange[])fMap.values().toArray(new TextChange[fMap.values().size()]); + } + + /** + * Returns all Translation units managed by this instance. + * + * @return all Translation units managed by this instance + */ + public ITranslationUnit[] getAllTranslationUnits(){ + return (ITranslationUnit[]) fMap.keySet().toArray(new ITranslationUnit[fMap.keySet().size()]); + } + + /** + * Clears all associations between resources and text changes. + */ + public void clear() { + fMap.clear(); + } + + /** + * Returns if any text changes are managed for the specified Translation unit. + * + * @return true if any text changes are managed for the specified Translation unit and false otherwise. + */ + public boolean containsChangesIn(ITranslationUnit cu){ + return fMap.containsKey(cu); + } +} + diff --git a/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/base/Change.java b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/base/Change.java new file mode 100644 index 00000000000..9a9d90cf49b --- /dev/null +++ b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/base/Change.java @@ -0,0 +1,136 @@ +/********************************************************************** + * Copyright (c) 2004 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.internal.corext.refactoring.base; + +import org.eclipse.cdt.core.model.ICElement; +import org.eclipse.cdt.core.model.ITranslationUnit; +import org.eclipse.cdt.internal.corext.refactoring.RefactoringCoreMessages; +import org.eclipse.cdt.internal.corext.util.CModelUtil; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.OperationCanceledException; + +/** + * An abstract default implementation for a change object - suitable for subclassing. This class manages + * the change's active status. + *

+ * NOTE: This class/interface is part of an interim API that is still under development + * and expected to change significantly before reaching stability. It is being made available at + * this early stage to solicit feedback from pioneering adopters on the understanding that any + * code that uses this API will almost certainly be broken (repeatedly) as the API evolves.

+ */ +public abstract class Change implements IChange { + + private boolean fIsActive= true; + + /* (Non-Javadoc) + * Method declared in IChange. + */ + public RefactoringStatus aboutToPerform(ChangeContext context, IProgressMonitor pm) { + pm.beginTask("", 1); //$NON-NLS-1$ + // PR: 1GEWDUH: ITPJCORE:WINNT - Refactoring - Unable to undo refactor change + RefactoringStatus result= new RefactoringStatus(); + IResource resource= getResource(getModifiedLanguageElement()); + if (resource != null) { + pm.subTask(RefactoringCoreMessages.getFormattedString("Change.checking_for", resource.getName())); //$NON-NLS-1$ + checkIfModifiable(resource, result, context); + } + pm.worked(1); + return result; + } + + /* (Non-Javadoc) + * Method declared in IChange. + */ + public void performed() { + // do nothing. + } + + /* (Non-Javadoc) + * Method declared in IChange. + */ + public void setActive(boolean active) { + fIsActive= active; + } + + /* (Non-Javadoc) + * Method declared in IChange. + */ + public boolean isActive() { + return fIsActive; + } + + /* (Non-Javadoc) + * Method declared in IChange. + */ + public boolean isUndoable() { + return true; + } + + /* (Non-Javadoc) + * debugging only + */ + public String toString(){ + return getName(); + } + + /** + * Handles the given exception using the IChangeExceptionHandler provided by + * the given change context. If the execution of the change is to be aborted than + * this method throws a corresponding CModelException. The exception + * is either the given exception if it is an instance of CModelException or + * a new one created by calling new CModelException(exception, code). + * + * @param context the change context used to retrieve the exception handler + * @param exception the exception caugth during change execution + * @exception ChangeAbortException if the execution is to be aborted + */ + protected void handleException(ChangeContext context, Exception exception) throws ChangeAbortException { + if (exception instanceof ChangeAbortException) + throw (ChangeAbortException)exception; + if (exception instanceof OperationCanceledException) + throw (OperationCanceledException)exception; + context.getExceptionHandler().handle(context, this, exception); + } + + protected static void checkIfModifiable(Object element, RefactoringStatus status, ChangeContext context) { + IResource resource= getResource(element); + if (resource != null) + checkIfModifiable(resource, status, context); + } + + protected static void checkIfModifiable(IResource resource, RefactoringStatus status, ChangeContext context) { + if (resource.isReadOnly()) { + status.addFatalError(RefactoringCoreMessages.getFormattedString("Change.is_read_only", resource.getFullPath().toString())); //$NON-NLS-1$ + } + if (resource instanceof IFile) + context.checkUnsavedFile(status, (IFile)resource); + } + + + private static IResource getResource(Object element) { + if (element instanceof IResource) { + return (IResource)element; + } + if (element instanceof ITranslationUnit) { + return CModelUtil.toOriginal((ITranslationUnit)element).getResource(); + } + if (element instanceof ICElement) { + return ((ICElement)element).getUnderlyingResource(); + } + if (element instanceof IAdaptable) { + return (IResource) ((IAdaptable)element).getAdapter(IResource.class); + } + return null; + } +} diff --git a/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/base/ChangeAbortException.java b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/base/ChangeAbortException.java new file mode 100644 index 00000000000..d2d20cf41a1 --- /dev/null +++ b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/base/ChangeAbortException.java @@ -0,0 +1,82 @@ +/********************************************************************** + * Copyright (c) 2004 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.internal.corext.refactoring.base; + + +import java.io.PrintStream; +import java.io.PrintWriter; + +import org.eclipse.cdt.internal.corext.Assert; +import org.eclipse.cdt.internal.corext.refactoring.RefactoringCoreMessages; + + +/** + * This exception is thrown if an unexpected errors occurs during execution + * of a change object. + */ +public class ChangeAbortException extends RuntimeException { + + private Throwable fThrowable; + + + /** + * Creates a new ChangeAbortException for the given throwable. + * + * @param t the unexpected throwable caught while performing the change + * @param context the change context used to process the change + */ + public ChangeAbortException(Throwable t) { + fThrowable= t; + Assert.isNotNull(fThrowable); + } + + /** + * Returns the Throwable that has caused the change to fail. + * + * @return the throwable that has caused the change to fail + */ + public Throwable getThrowable() { + return fThrowable; + } + + /** + * Prints a stack trace out for the exception, and + * any nested exception that it may have embedded in + * its Status object. + */ + public void printStackTrace(PrintStream output) { + synchronized (output) { + output.print("ChangeAbortException: "); //$NON-NLS-1$ + super.printStackTrace(output); + + if (fThrowable != null) { + output.print(RefactoringCoreMessages.getFormattedString("ChangeAbortException.wrapped", "ChangeAbortException: ")); //$NON-NLS-2$ //$NON-NLS-1$ + fThrowable.printStackTrace(output); + } + } + } + /** + * Prints a stack trace out for the exception, and + * any nested exception that it may have embedded in + * its Status object. + */ + public void printStackTrace(PrintWriter output) { + synchronized (output) { + output.print("ChangeAbortException: "); //$NON-NLS-1$ + super.printStackTrace(output); + + if (fThrowable != null) { + output.print(RefactoringCoreMessages.getFormattedString("ChangeAbortException.wrapped", "ChangeAbortException: ")); //$NON-NLS-2$ //$NON-NLS-1$ + fThrowable.printStackTrace(output); + } + } + } +} diff --git a/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/base/ChangeContext.java b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/base/ChangeContext.java new file mode 100644 index 00000000000..9553da5be34 --- /dev/null +++ b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/base/ChangeContext.java @@ -0,0 +1,168 @@ +/********************************************************************** + * Copyright (c) 2004 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.internal.corext.refactoring.base; + + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.core.resources.IFile; + +import org.eclipse.cdt.internal.corext.Assert; +import org.eclipse.cdt.internal.corext.refactoring.RefactoringCoreMessages; + +/** + * A change context is used to give an IChange object access to several workspace + * resource independend from whether the change is executed head less or not. + *

+ * NOTE: This class/interface is part of an interim API that is still under development + * and expected to change significantly before reaching stability. It is being made available at + * this early stage to solicit feedback from pioneering adopters on the understanding that any + * code that uses this API will almost certainly be broken (repeatedly) as the API evolves.

+ */ +public class ChangeContext { + + private IFile[] fUnsavedFiles; + private List fHandledUnsavedFiles; + private IChangeExceptionHandler fExceptionHandler; + private IChange fFailedChange; + private boolean fTryToUndo; + private List fPerformedChanges= new ArrayList(); + + + /** + * Creates a new change context with the given exception handler. + * + * @param handler object to handle exceptions caught during performing + * a change. Must not be null + */ + public ChangeContext(IChangeExceptionHandler handler) { + // PR: 1GEWDUH: ITPJCORE:WINNT - Refactoring - Unable to undo refactor change + this(handler, new IFile[] {}); + } + + /** + * Creates a new change context with the given exception handler. + * + * @param handler object to handle exceptions caught during performing + * a change. Must not be null + */ + public ChangeContext(IChangeExceptionHandler handler, IFile[] unsavedFiles) { + // PR: 1GEWDUH: ITPJCORE:WINNT - Refactoring - Unable to undo refactor change + fExceptionHandler= handler; + Assert.isNotNull(fExceptionHandler); + fUnsavedFiles= unsavedFiles; + Assert.isNotNull(fUnsavedFiles); + fHandledUnsavedFiles= new ArrayList(fUnsavedFiles.length); + } + + /** + * Returns the list of unsaved resources. + * + * @return the list of unsaved resources + */ + public IFile[] getUnsavedFiles() { + // PR: 1GEWDUH: ITPJCORE:WINNT - Refactoring - Unable to undo refactor change + return fUnsavedFiles; + } + + public void checkUnsavedFile(RefactoringStatus status, IFile file) { + if (fHandledUnsavedFiles.contains(file)) + return; + + // PR: 1GEWDUH: ITPJCORE:WINNT - Refactoring - Unable to undo refactor change + for (int i= 0; i < fUnsavedFiles.length; i++) { + if (fUnsavedFiles[i].equals(file)) { + status.addFatalError(RefactoringCoreMessages.getFormattedString("Change.is_unsaved", file.getFullPath().toString())); //$NON-NLS-1$ + fHandledUnsavedFiles.add(file); + return; + } + } + } + + /** + * Returns the exception handler used to report exception back to the client. + * + * @return the exception handler to report exceptions + */ + public IChangeExceptionHandler getExceptionHandler() { + return fExceptionHandler; + } + + /** + * Sets the change that caused an exception to the given value. + * + * @param change the change that caused an exception + */ + public void setFailedChange(IChange change) { + fFailedChange= change; + } + + /** + * Returns the change that caused an exception. + * + * @return the change that caused an exception + */ + public IChange getFailedChange() { + return fFailedChange; + } + + /** + * An unexpected error has occurred during execution of a change. Communicate + * to the outer operation that the successfully performed changes collected by + * this change context are supposed to be undone. + * + * @see ChangeContext#addPerformedChange(IChange) + */ + public void setTryToUndo() { + fTryToUndo= true; + } + + /** + * Returns true if an exception has been caught during execution of + * the change and the outer operation should try to undo all successfully performed + * changes. Otherwise false is returned. + * + * @return if the outer operation should try to undo all successfully performed + * changes + */ + public boolean getTryToUndo() { + return fTryToUndo; + } + + /** + * Adds the given change to the list of successfully performed changes. + * + * @param the change executed successfully. + */ + public void addPerformedChange(IChange change) { +// if (change instanceof ICompositeChange) +// return; + + fPerformedChanges.add(change); + } + + /** + * Returns all changes that have been performed successfully + * + * @return the successfully performed changes. + */ + public IChange[] getPerformedChanges() { + return (IChange[])fPerformedChanges.toArray(new IChange[fPerformedChanges.size()]); + } + + /** + * Removes all performed changes from this context. + */ + public void clearPerformedChanges() { + fPerformedChanges= new ArrayList(1); + } +} diff --git a/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/base/Context.java b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/base/Context.java new file mode 100644 index 00000000000..194000af135 --- /dev/null +++ b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/base/Context.java @@ -0,0 +1,24 @@ +/********************************************************************** + * Copyright (c) 2004 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.internal.corext.refactoring.base; + + +import org.eclipse.core.runtime.IAdaptable; + +/** + * A Context can be used to annotate a RefactoringStatusEntrywith + * additional information presentable in the UI. + */ +public class Context { + public IAdaptable getCorrespondingElement() { + return null; + } +} diff --git a/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/base/IChange.java b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/base/IChange.java new file mode 100644 index 00000000000..a706e40e5e6 --- /dev/null +++ b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/base/IChange.java @@ -0,0 +1,124 @@ +/********************************************************************** + * Copyright (c) 2004 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.internal.corext.refactoring.base; + + +import org.eclipse.core.runtime.IProgressMonitor; + +import org.eclipse.cdt.core.model.CModelException; + + +/** + * Represents a generic change to the workbench. An IChange object is typically + * created by calling IRefactoring::createChange. + *

+ * Calling perform performs the actual change to the workbench. Clients then call + * getUndoChange. It is the implementors responsbility to make sure that the + * IChange object returned by getUndoChange really represents a reverse change. + * + * Clients can implement this interface. + *

+ * NOTE: This class/interface is part of an interim API that is still under development + * and expected to change significantly before reaching stability. It is being made available at + * this early stage to solicit feedback from pioneering adopters on the understanding that any + * code that uses this API will almost certainly be broken (repeatedly) as the API evolves.

+ */ +public interface IChange { + + public static final int REFACTORING_CHANGE_ABORTED= 900; + + /** + * The client is about to calling perform on this change. The client of this + * change must ensure that the method is called outside a runnable that modifies the + * workbench. Typically aboutToPerform, perform and + * performed are used as follows: + *
+	 *	try {
+	 *		change.aboutToPerform(context);
+	 *		workbench.run(new IWorkspaceRunnable() {
+	 *			public void run(IProgressMonitor pm) throws CoreException {
+	 *				change.perform(context, pm);
+	 *			}
+	 *		}, progressMonitor);
+	 *	} finally {
+	 *		change.performed();
+	 *	}
+	 * 
+ * @see #performed() + */ + public RefactoringStatus aboutToPerform(ChangeContext context, IProgressMonitor pm); + + /** + * Performs this change. It is critical that you call perform + * before you call getUndoChange. In general, IChange + * objects do not know what the reverse will be before they are performed. + */ + public void perform(ChangeContext context, IProgressMonitor pm) throws CModelException, ChangeAbortException; + + /** + * The change has been performed. Clients must ensure that this method is called after all + * resource deltas emitted by calling perform are processed. This method must + * be called even if the perform has thrown a runtime exception. + * @see #aboutToPerform(ChangeContext, IProgressMonitor) + */ + public void performed(); + + /** + * Returns the change that, when performed, will undo the receiver. IChange + * objects can assume that perform has been called on them before. It is the + * caller's responsiblity to make sure that this is true. As mentioned in the class comment, + * it is the responsiblity of the implementors to make sure that this method does create a + * reverse change. + * + * @return the reverse change of this change + */ + public IChange getUndoChange(); + + /** + * Sets the activation status for this IChange. When a change is not active, + * then executing it is expected to do nothing. + * + * @param active the activation status for this change. + */ + public void setActive(boolean active); + + /** + * Returns the activation status of this IChange. This method doesn't + * consider the activation status of possible children. + * + * @return the change's activation status. + * @see #setActive(boolean) + */ + public boolean isActive(); + + /** + * Returns the name of this change. The main purpose of the change's name is to + * render it in the UI. + * + * @return the change's name. + */ + public String getName(); + + /** + * Returns the language element modified by this IChange. The method + * may return null if the change isn't related to a language element. + * + * @return the language element modified by this change + */ + public Object getModifiedLanguageElement(); + + /** + * Returns whether the change can be undone. + * If false is returned, then the result + * of getUndoChange will be ignored. + */ + public boolean isUndoable(); +} diff --git a/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/base/IChangeExceptionHandler.java b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/base/IChangeExceptionHandler.java new file mode 100644 index 00000000000..3d2aab8e15b --- /dev/null +++ b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/base/IChangeExceptionHandler.java @@ -0,0 +1,37 @@ +/********************************************************************** + * Copyright (c) 2004 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.internal.corext.refactoring.base; + + + +/** + * An ChangeExceptionHandler is informed about any exception that occurrs during + * performing a change. Implementors of this interface can control if the change is supposed to + * be continued or if it is to be aborted. + *

+ * NOTE: This class/interface is part of an interim API that is still under development + * and expected to change significantly before reaching stability. It is being made available at + * this early stage to solicit feedback from pioneering adopters on the understanding that any + * code that uses this API will almost certainly be broken (repeatedly) as the API evolves.

+ */ +public interface IChangeExceptionHandler { + + + /** + * Handles the given exception. + * + * @param context the change context passed to IChange.perform + * @param change the change that caused the exception + * @param exception the exception cought during executing the change + * @exception ChangeAbortException if the change is to be aborted + */ + public void handle(ChangeContext context, IChange change, Exception exception) throws ChangeAbortException; +} diff --git a/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/base/ICompositeChange.java b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/base/ICompositeChange.java new file mode 100644 index 00000000000..beab2ccb5bf --- /dev/null +++ b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/base/ICompositeChange.java @@ -0,0 +1,34 @@ +/********************************************************************** + * Copyright (c) 2004 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.internal.corext.refactoring.base; + + + +/** + * A composite change consisting of a list of changes. Performing a composite + * change peforms all managed changes. Managed changes can be either primitive + * or composite changes. + * Clients can implement this interface if they want their IChange to be treated as composites. + *

+ * NOTE: This class/interface is part of an interim API that is still under development + * and expected to change significantly before reaching stability. It is being made available at + * this early stage to solicit feedback from pioneering adopters on the understanding that any + * code that uses this API will almost certainly be broken (repeatedly) as the API evolves.

+ */ +public interface ICompositeChange extends IChange { + + /** + * Returns the set of changes this composite change consists of. If the composite + * change doesn't have any children, null is returned. + * @return an array of changes this composite change consists of + */ + public IChange[] getChildren(); +} diff --git a/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/base/IRefactoring.java b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/base/IRefactoring.java new file mode 100644 index 00000000000..726e1037d2d --- /dev/null +++ b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/base/IRefactoring.java @@ -0,0 +1,55 @@ +/********************************************************************** + * Copyright (c) 2004 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.internal.corext.refactoring.base; + +import org.eclipse.cdt.core.model.CModelException; +import org.eclipse.core.runtime.IProgressMonitor; + + +/** + * Represents a refactoring. + *

+ * NOTE: This class/interface is part of an interim API that is still under development + * and expected to change significantly before reaching stability. It is being made available at + * this early stage to solicit feedback from pioneering adopters on the understanding that any + * code that uses this API will almost certainly be broken (repeatedly) as the API evolves.

+ */ +public interface IRefactoring { + + /** + * Checks the proconditions of the receiving refactoring object. + * If the resulting IStatus has severity IStatus.ERROR, + * than createChange will not be called on the receiver. + * Must not return null. + * Implementors can assume the progress monitor to be not initialized. + * @see RefactoringStatus + * @see RefactoringStatus#OK + * @see RefactoringStatus#ERROR + */ + public RefactoringStatus checkPreconditions(IProgressMonitor pm) throws CModelException; + + /** + * Creates an IChange object that performs the actual refactoring. + * This is guaranteed not to be called before checkPreconditions or + * if checkPreconditions returns an RefactoringStatus + * object with severity RefactoringStatus.ERROR. + * Implementors can assume the progress monitor to be not initialized. + */ + public IChange createChange(IProgressMonitor pm) throws CModelException; + + + /** + * Returns the name of this refactoring. + * + * @return the refactoring's name. Mainly used in the UI. + */ + public String getName(); +} diff --git a/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/base/Refactoring.java b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/base/Refactoring.java new file mode 100644 index 00000000000..c0324845434 --- /dev/null +++ b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/base/Refactoring.java @@ -0,0 +1,85 @@ +/********************************************************************** + * Copyright (c) 2004 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.internal.corext.refactoring.base; + + +import org.eclipse.cdt.core.model.CModelException; +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.SubProgressMonitor; + +/** + * Superclass for all refactorings. + *

+ * NOTE: This class/interface is part of an interim API that is still under development + * and expected to change significantly before reaching stability. It is being made available at + * this early stage to solicit feedback from pioneering adopters on the understanding that any + * code that uses this API will almost certainly be broken (repeatedly) as the API evolves.

+ */ +public abstract class Refactoring implements IRefactoring, IAdaptable { + + + /* non java-doc + * for debugging only + */ + public String toString(){ + return getName(); + } + + //---- Conditions --------------------------- + + /** + * Checks if this refactoring can be activated. + * Typically, this is used in the ui to check if a corresponding menu entry should be shown. + * Must not return null. + */ + public abstract RefactoringStatus checkActivation(IProgressMonitor pm) throws CModelException; + + /** + * After checkActivation has been performed and the user has provided all input + * necessary to perform the refactoring this method is called to check the remaining preconditions. + * Typically, this is used in the ui after the user has pressed 'next' on the last user input page. + * This method is always called after checkActivation and only if the status returned by + * checkActivation isOK. + * Must not return null. + * @see #checkActivation + * @see RefactoringStatus#isOK + */ + public abstract RefactoringStatus checkInput(IProgressMonitor pm) throws CModelException; + + /** + * @see IRefactoring#checkPreconditions + * This implementation performs checkActivation + * and checkInput and merges the results. + * + * @see #checkActivation + * @see #checkInput + * @see RefactoringStatus#merge + */ + public RefactoringStatus checkPreconditions(IProgressMonitor pm) throws CModelException{ + pm.beginTask("", 11); //$NON-NLS-1$ + RefactoringStatus result= new RefactoringStatus(); + result.merge(checkActivation(new SubProgressMonitor(pm, 1, SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK))); + if (!result.hasFatalError()) + result.merge(checkInput(new SubProgressMonitor(pm, 10, SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK))); + pm.done(); + return result; + } + + /* (non-Javadoc) + * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class) + */ + public Object getAdapter(Class adapter) { + if (adapter.isInstance(this)) + return this; + return null; + } +} diff --git a/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/base/RefactoringStatus.java b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/base/RefactoringStatus.java new file mode 100644 index 00000000000..1fb2ce92421 --- /dev/null +++ b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/base/RefactoringStatus.java @@ -0,0 +1,453 @@ +/********************************************************************** + * Copyright (c) 2004 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.internal.corext.refactoring.base; + + + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.eclipse.cdt.internal.corext.Assert; +import org.eclipse.core.runtime.IStatus; + + +/** + * A RefactoringStatus object represents the outcome of a precondition checking + * operation. + * It keeps a list of RefactoringStatusEntries. + * Clients can instantiate. + * This class is not intented to be subclassed. + *

+ * NOTE: This class/interface is part of an interim API that is still under development + * and expected to change significantly before reaching stability. It is being made available at + * this early stage to solicit feedback from pioneering adopters on the understanding that any + * code that uses this API will almost certainly be broken (repeatedly) as the API evolves.

+ */ +public class RefactoringStatus { + + public static final int OK= 0; + public static final int INFO= 1; + public static final int WARNING= 2; + public static final int ERROR= 3; + public static final int FATAL= 4; + + private List fEntries; + private int fSeverity= OK; + + public RefactoringStatus(){ + fEntries= new ArrayList(0); + } + + /** + * Creates a RefactorngStatus with one INFO entry. + * This is a convenience method. + */ + public static RefactoringStatus createInfoStatus(String msg){ + return createStatus(INFO, msg); + } + + /** + * Creates a RefactorngStatus with one INFO entry. + * This is a convenience method. + */ + public static RefactoringStatus createInfoStatus(String msg, Context context){ + return createStatus(INFO, msg, context); + } + + /** + * Creates a RefactorngStatus with one WARNING entry. + * This is a convenience method. + */ + public static RefactoringStatus createWarningStatus(String msg){ + return createStatus(WARNING, msg); + } + + /** + * Creates a RefactorngStatus with one WARNING entry. + * This is a convenience method. + */ + public static RefactoringStatus createWarningStatus(String msg, Context context){ + return createStatus(WARNING, msg, context); + } + + /** + * Creates a RefactorngStatus with one ERROR entry. + * This is a convenience method. + */ + public static RefactoringStatus createErrorStatus(String msg){ + return createStatus(ERROR, msg); + } + + /** + * Creates a RefactorngStatus with one ERROR entry. + * This is a convenience method. + */ + public static RefactoringStatus createErrorStatus(String msg, Context context){ + return createStatus(ERROR, msg, context); + } + + /** + * Creates a RefactorngStatus with one FATAL entry. + * This is a convenience method. + */ + public static RefactoringStatus createFatalErrorStatus(String msg){ + return createStatus(FATAL, msg); + } + + /** + * Creates a RefactorngStatus with one FATAL entry. + * This is a convenience method. + */ + public static RefactoringStatus createFatalErrorStatus(String msg, Context context){ + return createStatus(FATAL, msg, context); + } + + /** + * Creates a RefactorngStatus from the given IStatus + */ + public static RefactoringStatus create(IStatus status){ + if (status.isOK()) + return new RefactoringStatus(); + + if (! status.isMultiStatus()){ + switch (status.getSeverity()){ + case IStatus.INFO: + return RefactoringStatus.createWarningStatus(status.getMessage()); + case IStatus.WARNING: + return RefactoringStatus.createErrorStatus(status.getMessage()); + case IStatus.ERROR: + return RefactoringStatus.createFatalErrorStatus(status.getMessage()); + default: + return new RefactoringStatus(); + } + } else { + IStatus[] children= status.getChildren(); + RefactoringStatus result= new RefactoringStatus(); + for (int i= 0; i < children.length; i++) { + result.merge(RefactoringStatus.create(children[i])); + } + return result; + } + } + + /* + * @see RefactoringStatusCodes + */ + public static RefactoringStatus createStatus(int severity, String msg, Context context, Object data, int code) { + RefactoringStatus result= new RefactoringStatus(); + result.fEntries.add(new RefactoringStatusEntry(msg, severity, context, data, code)); + result.fSeverity= severity; + return result; + } + + public static RefactoringStatus createStatus(int severity, String msg, Context context) { + return createStatus(severity, msg, context, null, RefactoringStatusCodes.NONE); + } + + public static RefactoringStatus createStatus(int severity, String msg){ + return createStatus(severity, msg, null); + } + + /** + * Adds an info to this status. + * If the current severity was OK it will be changed to INFO. + * It will remain unchanged otherwise. + * @see #OK + * @see #INFO + */ + public void addInfo(String msg){ + addInfo(msg, null); + } + + /** + * Adds an info to this status. + * If the current severity was OK it will be changed to INFO. + * It will remain unchanged otherwise. + * @see #OK + * @see #INFO + */ + public void addInfo(String msg, Context context){ + fEntries.add(RefactoringStatusEntry.createInfo(msg, context)); + fSeverity= Math.max(fSeverity, INFO); + } + + /** + * Adds a warning to this status. + * If the current severity was OK or INFO it will be changed to WARNING. + * It will remain unchanged otherwise. + * @see #OK + * @see #INFO + * @see #WARNING + */ + public void addWarning(String msg){ + addWarning(msg, null); + } + + /** + * Adds a warning to this status. + * If the current severity was OK or INFO it will be changed to WARNING. + * It will remain unchanged otherwise. + * @see #OK + * @see #INFO + * @see #WARNING + */ + public void addWarning(String msg, Context context){ + fEntries.add(RefactoringStatusEntry.createWarning(msg, context)); + fSeverity= Math.max(fSeverity, WARNING); + } + + + /** + * Adds an error to this status. + * If the current severity was OK, INFO or WARNING + * it will be changed to ERROR. + * It will remain unchanged otherwise. + * @see #OK + * @see #INFO + * @see #WARNING + * @see #ERROR + */ + public void addError(String msg){ + addError(msg, null); + } + + /** + * Adds an error to this status. + * If the current severity was OK, INFO or WARNING + * it will be changed to ERROR. + * It will remain unchanged otherwise. + * @see #OK + * @see #INFO + * @see #WARNING + * @see #ERROR + */ + public void addError(String msg, Context context){ + fEntries.add(RefactoringStatusEntry.createError(msg, context)); + fSeverity= Math.max(fSeverity, ERROR); + } + + + /** + * Adds a fatal error to this status. + * If the current severity was OK, INFO, WARNING + * or ERROR it will be changed to FATAL. + * It will remain unchanged otherwise. + * @see #OK + * @see #INFO + * @see #WARNING + * @see #ERROR + * @see #FATAL + */ + public void addFatalError(String msg){ + addFatalError(msg, null); + } + + /** + * Adds a fatal error to this status. + * If the current severity was OK, INFO, WARNING + * or ERROR it will be changed to FATAL. + * It will remain unchanged otherwise. + * @see #OK + * @see #INFO + * @see #WARNING + * @see #ERROR + * @see #FATAL + */ + public void addFatalError(String msg, Context context){ + fEntries.add(RefactoringStatusEntry.createFatal(msg, context)); + fSeverity= Math.max(fSeverity, FATAL); + } + + /** + * Adds an RefactoringStatusEntry. + * + * @param entry the RefactoringStatusEntry to be added + */ + public void addEntry(RefactoringStatusEntry entry) { + Assert.isNotNull(entry); + fEntries.add(entry); + fSeverity= Math.max(fSeverity, entry.getSeverity()); + } + + /** + * Returns true iff there were no errors, warings or infos added. + * @see #OK + * @see #INFO + * @see #WARNING + * @see #ERROR + */ + public boolean isOK(){ + return fSeverity == OK; + } + + /** + * Returns true if the current severity is FATAL. + * @see #FATAL + */ + public boolean hasFatalError() { + return fSeverity == FATAL; + } + + /** + * Returns true if the current severity is FATAL or + * ERROR. + * @see #FATAL + * @see #ERROR + */ + public boolean hasError() { + return fSeverity == FATAL || fSeverity == ERROR; + } + + /** + * Returns true if the current severity is FATAL, + * ERROR or WARNING. + * @see #FATAL + * @see #ERROR + * @see #WARNING + */ + public boolean hasWarning() { + return fSeverity == FATAL || fSeverity == ERROR || fSeverity == WARNING; + } + + /** + * Returns true if the status has an entry with the given code. + * Otherwise false is returned. + * + * @param code the code of the RefactoringStatusEntry. + * @return true if the status has an entry with the given code. + * Otherwise false is returned. + */ + public boolean hasEntryWithCode(int code) { + for (Iterator iter= fEntries.iterator(); iter.hasNext();) { + RefactoringStatusEntry entry= (RefactoringStatusEntry) iter.next(); + if (entry.getCode() == code) + return true; + } + return false; + } + + /** + * Merges the receiver and the parameter statuses. + * The resulting list of entries in the receiver will contain entries from both. + * The resuling severity in the reciver will be the more severe of its current severity + * and the parameter's severity. + * Merging with null is allowed - it has no effect. + * @see #getSeverity + */ + public void merge(RefactoringStatus that){ + if (that == null) + return; + fEntries.addAll(that.getEntries()); + fSeverity= Math.max(fSeverity, that.getSeverity()); + } + + + /** + * Returns the current severity. + * Severities are ordered as follows: OK < INFO < WARNING < ERROR + */ + public int getSeverity(){ + return fSeverity; + } + + /** + * Returns all entries. + * Returns a List of RefactoringStatusEntries. + * This list is empty if there are no entries. + */ + public List getEntries(){ + return fEntries; + } + + /** + * Returns the RefactoringStatusEntry at the specified index. + * + * @param index of entry to return + * @return the enrty at the specified index + * + * @throws IndexOutOfBoundsException if the index is out of range + */ + public RefactoringStatusEntry getEntry(int index) { + return (RefactoringStatusEntry)fEntries.get(index); + } + + /** + * Returns the first entry which severity is equal or greater than the given + * severity. Returns null if no element exists with + * the given severity. + * @param severity must be one of FATAL, ERROR, + * WARNING or INFO. + */ + public RefactoringStatusEntry getFirstEntry(int severity) { + Assert.isTrue(severity >= OK && severity <= FATAL); + if (severity > fSeverity) + return null; + Iterator iter= fEntries.iterator(); + while(iter.hasNext()) { + RefactoringStatusEntry entry= (RefactoringStatusEntry)iter.next(); + if (entry.getSeverity() >= severity) + return entry; + } + return null; + } + + + /** + * Returns the first message which severity is equal or greater than the given + * severity. Returns null if no element exists with + * the given severity. + * @param severity must me one of FATAL, ERROR, + * WARNING or INFO. + */ + public String getFirstMessage(int severity) { + RefactoringStatusEntry entry= getFirstEntry(severity); + if (entry == null) + return null; + return entry.getMessage(); + } + + + /* non java-doc + * for debugging only + * not for nls + */ + /*package*/ static String getSeverityString(int severity){ + Assert.isTrue(severity >= OK && severity <= FATAL); + if (severity == RefactoringStatus.OK) return "OK"; //$NON-NLS-1$ + if (severity == RefactoringStatus.INFO) return "INFO"; //$NON-NLS-1$ + if (severity == RefactoringStatus.WARNING) return "WARNING"; //$NON-NLS-1$ + if (severity == RefactoringStatus.ERROR) return "ERROR"; //$NON-NLS-1$ + if (severity == RefactoringStatus.FATAL) return "FATALERROR"; //$NON-NLS-1$ + return null; + } + + /* non java-doc + * for debugging only + */ + public String toString(){ + StringBuffer buff= new StringBuffer(); + buff.append("<") //$NON-NLS-1$ + .append(getSeverityString(fSeverity)) + .append("\n"); //$NON-NLS-1$ + if (!isOK()){ + for (Iterator iter= fEntries.iterator(); iter.hasNext();){ + buff.append("\t") //$NON-NLS-1$ + .append(iter.next()) + .append("\n"); //$NON-NLS-1$ + } + } + buff.append(">"); //$NON-NLS-1$ + return buff.toString(); + } +} + + diff --git a/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/base/RefactoringStatusCodes.java b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/base/RefactoringStatusCodes.java new file mode 100644 index 00000000000..e27c6f75c2a --- /dev/null +++ b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/base/RefactoringStatusCodes.java @@ -0,0 +1,57 @@ +/********************************************************************** + * Copyright (c) 2004 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.internal.corext.refactoring.base; + + +public class RefactoringStatusCodes { + + private RefactoringStatusCodes() { + } + + public static final int NONE= 0; + + public static final int OVERRIDES_ANOTHER_METHOD= 1; + public static final int METHOD_DECLARED_IN_INTERFACE= 2; + + public static final int EXPRESSION_NOT_RVALUE= 64; + public static final int EXPRESSION_NOT_RVALUE_VOID= 65; + public static final int EXTRANEOUS_TEXT= 66; + + public static final int NOT_STATIC_FINAL_SELECTED= 128; + public static final int SYNTAX_ERRORS= 129; + public static final int DECLARED_IN_CLASSFILE= 130; + public static final int CANNOT_INLINE_BLANK_FINAL= 131; + public static final int LOCAL_AND_ANONYMOUS_NOT_SUPPORTED= 132; + public static final int REFERENCE_IN_CLASSFILE= 133; + public static final int WILL_NOT_REMOVE_DECLARATION= 134; + + public static int CANNOT_MOVE_STATIC= 192; + public static int SELECT_METHOD_IMPLEMENTATION= 193; + public static int CANNOT_MOVE_NATIVE= 194; + public static int CANNOT_MOVE_SYNCHRONIZED= 195; + public static int CANNOT_MOVE_CONSTRUCTOR= 196; + public static int SUPER_REFERENCES_NOT_ALLOWED= 197; + public static int ENCLOSING_INSTANCE_REFERENCES_NOT_ALLOWED= 198; + public static int CANNOT_MOVE_RECURSIVE= 199; + public static int CANNOT_MOVE_TO_SAME_CU= 200; + public static int CANNOT_MOVE_TO_LOCAL= 201; + public static int METHOD_NOT_SELECTED= 202; + public static int NO_NEW_RECEIVERS= 203; + public static int PARAM_NAME_ALREADY_USED= 204; + + // inline method error codes + public static final int INLINE_METHOD_FIELD_INITIALIZER= 256; + public static final int INLINE_METHOD_LOCAL_INITIALIZER= 257; + public static final int INLINE_METHOD_NULL_BINDING= 258; + public static final int INLINE_METHOD_ONLY_SIMPLE_FUNCTIONS= 259; + public static final int INLINE_METHOD_EXECUTION_FLOW= 260; + public static final int INLINE_METHOD_INITIALIZER_IN_FRAGEMENT= 261; +} diff --git a/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/base/RefactoringStatusEntry.java b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/base/RefactoringStatusEntry.java new file mode 100644 index 00000000000..d4de83163ca --- /dev/null +++ b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/base/RefactoringStatusEntry.java @@ -0,0 +1,243 @@ +/********************************************************************** + * Copyright (c) 2004 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.internal.corext.refactoring.base; + +import org.eclipse.cdt.internal.corext.Assert; +import org.eclipse.cdt.ui.CUIPlugin; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; + +/** + * An immutable tuple (message, severity) representing an entry in the list in + * RefactoringStatus. + *

+ * NOTE: This class/interface is part of an interim API that is still under development + * and expected to change significantly before reaching stability. It is being made available at + * this early stage to solicit feedback from pioneering adopters on the understanding that any + * code that uses this API will almost certainly be broken (repeatedly) as the API evolves.

+ */ +public class RefactoringStatusEntry{ + + private final String fMessage; + private final int fSeverity; + private final Context fContext; + private final Object fData; + private final int fCode; + + public RefactoringStatusEntry(String msg, int severity, Context context, Object data, int code){ + Assert.isTrue(severity == RefactoringStatus.INFO + || severity == RefactoringStatus.WARNING + || severity == RefactoringStatus.ERROR + || severity == RefactoringStatus.FATAL); + Assert.isNotNull(msg); + fMessage= msg; + fSeverity= severity; + fContext= context; + fData= data; + fCode= code; + } + + /** + * Creates an entry with the given severity. + * @param msg message + * @param severity severity + * @param context a context which can be used to show more detailed information + * about this error in the UI + */ + public RefactoringStatusEntry(String msg, int severity, Context context){ + this(msg, severity, context, null, RefactoringStatusCodes.NONE); + } + + /** + * Creates an entry with the given severity. The corresponding resource and source range are set to null. + * @param severity severity + * @param msg message + */ + public RefactoringStatusEntry(String msg, int severity) { + this(msg, severity, null); + } + + /** + * Creates an entry with RefactoringStatus.INFO status. + * @param msg message + */ + public static RefactoringStatusEntry createInfo(String msg) { + return new RefactoringStatusEntry(msg, RefactoringStatus.INFO); + } + + /** + * Creates an entry with RefactoringStatus.INFO status. + * @param msg message + */ + public static RefactoringStatusEntry createInfo(String msg, Context context) { + return new RefactoringStatusEntry(msg, RefactoringStatus.INFO, context); + } + + /** + * Creates an entry with RefactoringStatus.WARNING status. + * @param msg message + */ + public static RefactoringStatusEntry createWarning(String msg) { + return new RefactoringStatusEntry(msg, RefactoringStatus.WARNING); + } + + /** + * Creates an entry with RefactoringStatus.WARNING status. + * @param msg message + */ + public static RefactoringStatusEntry createWarning(String msg, Context context) { + return new RefactoringStatusEntry(msg, RefactoringStatus.WARNING, context); + } + + /** + * Creates an entry with RefactoringStatus.ERROR status. + * @param msg message + */ + public static RefactoringStatusEntry createError(String msg) { + return new RefactoringStatusEntry(msg, RefactoringStatus.ERROR); + } + + /** + * Creates an entry with RefactoringStatus.ERROR status. + * @param msg message + */ + public static RefactoringStatusEntry createError(String msg, Context context) { + return new RefactoringStatusEntry(msg, RefactoringStatus.ERROR, context); + } + + /** + * Creates an entry with RefactoringStatus.FATAL status. + * @param msg message + */ + public static RefactoringStatusEntry createFatal(String msg) { + return new RefactoringStatusEntry(msg, RefactoringStatus.FATAL); + } + + /** + * Creates an entry with RefactoringStatus.FATAL status. + * @param msg message + */ + public static RefactoringStatusEntry createFatal(String msg, Context context) { + return new RefactoringStatusEntry(msg, RefactoringStatus.FATAL, context); + } + + /** + * @return true iff (severity == RefactoringStatus.FATAL). + */ + public boolean isFatalError() { + return fSeverity == RefactoringStatus.FATAL; + } + + /** + * @return true iff (severity == RefactoringStatus.ERROR). + */ + public boolean isError() { + return fSeverity == RefactoringStatus.ERROR; + } + + /** + * @return true iff (severity == RefactoringStatus.WARNING). + */ + public boolean isWarning() { + return fSeverity == RefactoringStatus.WARNING; + } + + /** + * @return true iff (severity == RefactoringStatus.INFO). + */ + public boolean isInfo() { + return fSeverity == RefactoringStatus.INFO; + } + + /** + * @return message. + */ + public String getMessage() { + return fMessage; + } + + /** + * @return severity level. + * @see RefactoringStatus#INFO + * @see RefactoringStatus#WARNING + * @see RefactoringStatus#ERROR + * @see RefactoringStatus#FATAL + */ + public int getSeverity() { + return fSeverity; + } + + /** + * Returns the context which can be used to show more detailed information + * regarding this status entry in the UI. The method may return null + * indicating that no context is available. + * + * @return the status entry's context + */ + public Context getContext() { + return fContext; + } + + public Object getData() { + return fData; + } + + public int getCode() { + return fCode; + } + + /** + * Converts this RefactoringStatusEntry into an IStatus. + * The mapping is done as follows: + *
    + *
  • Fatal entries are mapped to IStatus.ERROR. + *
  • + *
  • Error and warning entries are mapped to IStatus.WARNING. + *
  • + *
  • Information entries are mapped to IStatus.INFO.
  • + *
+ * @return IStatus + */ + public IStatus asStatus () { + int statusSeverity= IStatus.ERROR; + switch (fSeverity) { + case RefactoringStatus.OK: + statusSeverity= IStatus.OK; + break; + case RefactoringStatus.INFO: + statusSeverity= IStatus.INFO; + break; + case RefactoringStatus.WARNING: + case RefactoringStatus.ERROR: + statusSeverity= IStatus.WARNING; + break; + } + return new Status(statusSeverity, CUIPlugin.getPluginId(), fCode, fMessage, null); + } + + /* non java-doc + * for debugging only + */ + public String toString() { + String contextString= fContext == null ? "": fContext.toString(); //$NON-NLS-1$ + return "\n" //$NON-NLS-1$ + + RefactoringStatus.getSeverityString(fSeverity) + + ": " //$NON-NLS-1$ + + fMessage + + "\nContext: " //$NON-NLS-1$ + + contextString + + "\nData: " //$NON-NLS-1$ + + getData() + +"\ncode: " //$NON-NLS-1$ + + fCode + + "\n"; //$NON-NLS-1$ + } +} diff --git a/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/changes/AbstractTextChange.java b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/changes/AbstractTextChange.java new file mode 100644 index 00000000000..4e51a8ddb7f --- /dev/null +++ b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/changes/AbstractTextChange.java @@ -0,0 +1,209 @@ +/********************************************************************** + * Copyright (c) 2004 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.internal.corext.refactoring.changes; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; + +import org.eclipse.cdt.core.model.CModelException; + +import org.eclipse.text.edits.TextEdit; +import org.eclipse.text.edits.UndoEdit; +import org.eclipse.cdt.internal.corext.Assert; +import org.eclipse.cdt.internal.corext.refactoring.NullChange; +import org.eclipse.cdt.internal.corext.refactoring.base.Change; +import org.eclipse.cdt.internal.corext.refactoring.base.ChangeAbortException; +import org.eclipse.cdt.internal.corext.refactoring.base.ChangeContext; +import org.eclipse.cdt.internal.corext.refactoring.base.IChange; +import org.eclipse.cdt.internal.corext.textmanipulation.TextBuffer; +import org.eclipse.cdt.internal.corext.refactoring.changes.TextBufferEditor; + +public abstract class AbstractTextChange extends Change { + + private String fName; + private int fChangeKind; + private IChange fUndoChange; + + protected final static int ORIGINAL_CHANGE= 0; + protected final static int UNDO_CHANGE= 1; + protected final static int REDO_CHANGE= 2; + + protected static class LocalTextEditProcessor extends TextBufferEditor { + public static final int EXCLUDE= 1; + public static final int INCLUDE= 2; + + private TextEdit[] fExcludes; + private TextEdit[] fIncludes; + + public LocalTextEditProcessor(TextBuffer buffer) { + super(buffer); + } + public void setIncludes(TextEdit[] includes) { + Assert.isNotNull(includes); + Assert.isTrue(fExcludes == null); + fIncludes= flatten(includes); + } + public void setExcludes(TextEdit[] excludes) { + Assert.isNotNull(excludes); + Assert.isTrue(fIncludes == null); + fExcludes= excludes; + } + protected boolean considerEdit(TextEdit edit) { + if (fExcludes != null) { + for (int i= 0; i < fExcludes.length; i++) { + if (edit.equals(fExcludes[i])) + return false; + } + return true; + } + if (fIncludes != null) { + for (int i= 0; i < fIncludes.length; i++) { + if (edit.equals(fIncludes[i])) + return true; + } + return false; + } + return true; + } + private TextEdit[] flatten(TextEdit[] edits) { + List result= new ArrayList(5); + for (int i= 0; i < edits.length; i++) { + flatten(result, edits[i]); + } + return (TextEdit[])result.toArray(new TextEdit[result.size()]); + } + private void flatten(List result, TextEdit edit) { + result.add(edit); + TextEdit[] children= edit.getChildren(); + for (int i= 0; i < children.length; i++) { + flatten(result, children[i]); + } + } + } + + /** + * Creates a new TextChange with the given name. + * + * @param name the change's name mainly used to render the change in the UI. + * @param changeKind a flag indicating if the change is a ORIGINAL_CHANGE, + * a UNDO_CHANGE or a REDO_CHANGE + */ + protected AbstractTextChange(String name, int changeKind) { + fName= name; + Assert.isNotNull(fName); + fChangeKind= changeKind; + Assert.isTrue(0 <= fChangeKind && fChangeKind <= 2); + } + + /** + * Acquires a new text buffer to perform the changes managed by this + * text buffer change. Two subsequent calls to this method must + * return the identical ITextBuffer object. + * + * @return the acquired text buffer + */ + protected abstract TextBuffer acquireTextBuffer() throws CoreException; + + /** + * Releases the given text buffer. The given text buffer is not usable + * anymore after calling this method. + * + * @param textBuffer the text buffer to be released + */ + protected abstract void releaseTextBuffer(TextBuffer textBuffer); + + /** + * Create a new TextBuffer. Any call to this method + * must create a new TextBufferinstance. + * + * @return the created text buffer + */ + protected abstract TextBuffer createTextBuffer() throws CoreException; + + /** + * Adds the TextEdits managed by this change to the given + * text buffer editor. + * + * @param editor the text buffer edit + * @param copy if true the edits are copied before adding. + * Otherwise the original edits are added. + */ + protected abstract void addTextEdits(LocalTextEditProcessor editor) throws CoreException; + + /** + * Creates a IChange that can undo this change. + * + * @param edits the text edits that can undo the edits performed by this change + * @param changeKind the change kind of the reverse change. Either + * UNDO_CHANGE or
REDO_CHANGE
+ * @return a change that can undo this change + */ + protected abstract IChange createReverseChange(UndoEdit edits , int changeKind); + + /** + * Returns true if this change is a reverse change. This is the case for an undo + * or a redo change. Returns false if the change is an original + * change. + * + * @return whether or not this change is a reverse change + */ + public boolean isReverseChange() { + return fChangeKind != ORIGINAL_CHANGE; + } + + protected int getReverseKind() { + if (fChangeKind == ORIGINAL_CHANGE || fChangeKind == REDO_CHANGE) + return UNDO_CHANGE; + else + return REDO_CHANGE; + } + + /* (Non-Javadoc) + * Method declared in IChange. + */ + public String getName(){ + return fName; + } + + /* Non-Javadoc + * Method declared in IChange + */ + public IChange getUndoChange() { + return fUndoChange; + } + + /* Non-Javadoc + * Method declared in IChange + */ + public void perform(ChangeContext context, IProgressMonitor pm) throws CModelException, ChangeAbortException { + if (!isActive()) { + fUndoChange= new NullChange(); + return; + } + LocalTextEditProcessor editor= null; + try { + fUndoChange= null; + editor= new LocalTextEditProcessor(acquireTextBuffer()); + addTextEdits(editor); + fUndoChange= createReverseChange(editor.performEdits(pm), getReverseKind()); + } catch (Exception e) { + handleException(context, e); + } finally { + if (editor != null) { + releaseTextBuffer(editor.getTextBuffer()); + } + } + } +} + diff --git a/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/changes/TextBufferEditor.java b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/changes/TextBufferEditor.java new file mode 100644 index 00000000000..a3a7ab4b9e4 --- /dev/null +++ b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/changes/TextBufferEditor.java @@ -0,0 +1,120 @@ +/********************************************************************** + * Copyright (c) 2004 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.internal.corext.refactoring.changes; + +import org.eclipse.cdt.internal.corext.Assert; +import org.eclipse.cdt.internal.corext.textmanipulation.TextBuffer; +import org.eclipse.cdt.ui.CUIPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.text.edits.MalformedTreeException; +import org.eclipse.text.edits.MultiTextEdit; +import org.eclipse.text.edits.TextEdit; +import org.eclipse.text.edits.TextEditProcessor; +import org.eclipse.text.edits.UndoEdit; + +public class TextBufferEditor extends TextEditProcessor { + + private TextBuffer fBuffer; + private TextEditProcessor fUndoProcessor; + + /** + * Creates a new TextBufferEditor for the given + * TextBuffer. + * + * @param the text buffer this editor is working on. + */ + public TextBufferEditor(TextBuffer buffer) { + super(buffer.getDocument(), new MultiTextEdit(0, buffer.getDocument().getLength()), + TextEdit.CREATE_UNDO | TextEdit.UPDATE_REGIONS); + fBuffer= buffer; + } + + /** + * Returns the text buffer this editor is working on. + * + * @return the text buffer this editor is working on + */ + public TextBuffer getTextBuffer() { + return fBuffer; + } + + /** + * Adds an Edit to this edit processor. Adding an edit + * to an edit processor transfers ownership of the edit to the + * processor. So after an edit has been added to a processor the + * creator of the edit must not continue modifying the edit. + * + * @param edit the edit to add + * @exception MalformedTreeException if the text edit can not be + * added to this edit processor. + * + * @see TextEdit#addChild(TextEdit) + */ + public void add(TextEdit edit) throws MalformedTreeException { + getRoot().addChild(edit); + } + + /** + * Adds an undo memento to this edit processor. Adding an undo memento + * transfers ownership of the memento to the processor. So after a memento + * has been added the creator of that memento must not continue + * modifying it. + * + * @param undo the undo memento to add + * @exception EditException if the undo memento can not be added + * to this processor + */ + public void add(UndoEdit undo) { + Assert.isTrue(!getRoot().hasChildren()); + fUndoProcessor= new TextEditProcessor(getDocument(), undo, TextEdit.CREATE_UNDO | TextEdit.UPDATE_REGIONS); + } + + /* (non-Javadoc) + * @see org.eclipse.text.edits.TextEditProcessor#canPerformEdits() + */ + public boolean canPerformEdits() { + if (fUndoProcessor != null) + return fUndoProcessor.canPerformEdits(); + return super.canPerformEdits(); + } + + /** + * Executes the text edits added to this text buffer editor and clears all added + * text edits. + * + * @param pm a progress monitor to report progress or null if + * no progress is desired. + * @return an object representing the undo of the executed TextEdits + * @exception CoreException if the edits cannot be executed + */ + public UndoEdit performEdits(IProgressMonitor pm) throws CoreException { + try { + if (fUndoProcessor != null) { + return fUndoProcessor.performEdits(); + } else { + return super.performEdits(); + } + } catch (BadLocationException e) { + String message= (e != null ? e.getMessage() : ""); //$NON-NLS-1$ + throw new CoreException(new Status(IStatus.ERROR, CUIPlugin.getPluginId(), + IStatus.ERROR, message, e)); + } catch (MalformedTreeException e) { + String message= (e != null ? e.getMessage() : ""); //$NON-NLS-1$ + throw new CoreException(new Status(IStatus.ERROR, CUIPlugin.getPluginId(), + IStatus.ERROR, message, e)); + } + } +} + diff --git a/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/changes/TextChange.java b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/changes/TextChange.java new file mode 100644 index 00000000000..164524ab1a5 --- /dev/null +++ b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/changes/TextChange.java @@ -0,0 +1,572 @@ +/********************************************************************** + * Copyright (c) 2004 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.internal.corext.refactoring.changes; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; + +import org.eclipse.cdt.core.model.CModelException; +import org.eclipse.cdt.internal.corext.Assert; +import org.eclipse.cdt.internal.corext.textmanipulation.GroupDescription; +import org.eclipse.cdt.internal.corext.textmanipulation.TextBuffer; +import org.eclipse.cdt.internal.corext.textmanipulation.TextRegion; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.jface.text.IRegion; +import org.eclipse.text.edits.MultiTextEdit; +import org.eclipse.text.edits.TextEdit; +import org.eclipse.text.edits.TextEditCopier; + +public abstract class TextChange extends AbstractTextChange { + + public static class EditChange { + private boolean fIsActive; + private TextChange fTextChange; + private GroupDescription fDescription; + + /* package */ EditChange(GroupDescription description, TextChange change) { + fTextChange= change; + fIsActive= true; + fDescription= description; + } + public String getName() { + return fDescription.getName(); + } + public void setActive(boolean active) { + fIsActive= active; + } + public boolean isActive() { + return fIsActive; + } + public TextChange getTextChange() { + return fTextChange; + } + public IRegion getTextRange() { + return fDescription.getTextRange(); + } + public boolean isEmpty() { + return fDescription.hasTextEdits(); + } + /* package */ GroupDescription getGroupDescription() { + return fDescription; + } + public boolean coveredBy(IRegion sourceRegion) { + int sLength= sourceRegion.getLength(); + if (sLength == 0) + return false; + int sOffset= sourceRegion.getOffset(); + int sEnd= sOffset + sLength - 1; + TextEdit[] edits= fDescription.getTextEdits(); + for (int i= 0; i < edits.length; i++) { + TextEdit edit= edits[i]; + if (edit.isDeleted()) + return false; + int rOffset= edit.getOffset(); + int rLength= edit.getLength(); + int rEnd= rOffset + rLength - 1; + if (rLength == 0) { + if (!(sOffset < rOffset && rOffset <= sEnd)) + return false; + } else { + if (!(sOffset <= rOffset && rEnd <= sEnd)) + return false; + } + } + return true; + } + } + + private List fTextEditChanges; + private TextEditCopier fCopier; + private TextEdit fEdit; + private boolean fKeepExecutedTextEdits; + private boolean fAutoMode; + private String fTextType; + + /** + * Creates a new TextChange with the given name. + * + * @param name the change's name mainly used to render the change in the UI. + */ + protected TextChange(String name) { + super(name, ORIGINAL_CHANGE); + fTextEditChanges= new ArrayList(5); + fTextType= "txt"; //$NON-NLS-1$ + } + + /** + * Sets the text type. Text types are defined by the extension + * point >>TODO<<. + * + * @param type the text type. If null is passed the + * text type is resetted to the default text type "text". + */ + protected void setTextType(String type) { + if (type == null) + fTextType= "txt"; //$NON-NLS-1$ + fTextType= type; + } + + /** + * Returns the text change's text type. + * + * @return the text change's text type + */ + public String getTextType() { + return fTextType; + } + + /** + * Adds a text edit object to this text buffer change. + * + * @param name the name of the given text edit. The name is used to render this + * change in the UI. + * @param edit the text edit to add + */ + public void addTextEdit(String name, TextEdit edit) { + addTextEdit(name, new TextEdit[] {edit}); + } + + /** + * Adds an array of text edit objects to this text buffer change. + * + * @param name the name of the given text edit. The name is used to render this + * change in the UI. + * @param edite the array of text edits to add + */ + public void addTextEdit(String name, TextEdit[] edits) { + Assert.isNotNull(name); + Assert.isNotNull(edits); + GroupDescription description= new GroupDescription(name, edits); + fTextEditChanges.add(new EditChange(description, this)); + if (fEdit == null) { + fEdit= new MultiTextEdit(); + fAutoMode= true; + } else { + Assert.isTrue(fAutoMode, "Can only add edits when in auto organizing mode"); //$NON-NLS-1$ + } + for (int i= 0; i < edits.length; i++) { + insert(fEdit, edits[i]); + } + } + + /** + * Sets the root text edit. + * + * @param edit the root text edit + */ + public void setEdit(TextEdit edit) { + Assert.isTrue(fEdit == null, "Root edit can only be set once"); //$NON-NLS-1$ + Assert.isTrue(edit != null); + fEdit= edit; + fTextEditChanges= new ArrayList(5); + fAutoMode= false; + } + + /** + * Gets the root text edit. + * + * @return Returns the root text edit + */ + public TextEdit getEdit() { + return fEdit; + } + + /** + * Adds a group description. + * + * @param description the group description to be added + */ + public void addGroupDescription(GroupDescription description) { + Assert.isTrue(fEdit != null, "Can only add a description if a root edit exists"); //$NON-NLS-1$ + Assert.isTrue(!fAutoMode, "Group descriptions are only supported if root edit has been set by setEdit"); //$NON-NLS-1$ + Assert.isTrue(description != null); + fTextEditChanges.add(new EditChange(description, this)); + } + + /** + * Adds a set of group descriptions. + * + * @param descriptios the group descriptions to be added + */ + public void addGroupDescriptions(GroupDescription[] descriptions) { + for (int i= 0; i < descriptions.length; i++) { + addGroupDescription(descriptions[i]); + } + } + + /** + * Returns the group descriptions that have been added to this change + * @return GroupDescription[] + */ + public GroupDescription[] getGroupDescriptions() { + GroupDescription[] res= new GroupDescription[fTextEditChanges.size()]; + for (int i= 0; i < res.length; i++) { + EditChange elem= (EditChange) fTextEditChanges.get(i); + res[i]= elem.getGroupDescription(); + } + return res; + } + + /** + * Returns the group description with the given name or null if no such + * GroupDescription exists. + */ + public GroupDescription getGroupDescription(String name) { + for (int i= 0; i < fTextEditChanges.size(); i++) { + EditChange elem= (EditChange) fTextEditChanges.get(i); + GroupDescription description= elem.getGroupDescription(); + if (name.equals(description.getName())) { + return description; + } + } + return null; + } + + + /** + * Returns the text edit changes managed by this text change. + * + * @return the text edit changes + */ + public EditChange[] getTextEditChanges() { + return (EditChange[])fTextEditChanges.toArray(new EditChange[fTextEditChanges.size()]); + } + + /** + * Returns the text this change is working on. + * + * @return the original text. + * @exception CModelException if text cannot be accessed + */ + public String getCurrentContent() throws CModelException { + TextBuffer buffer= null; + try { + buffer= acquireTextBuffer(); + return buffer.getContent(); + } catch (CModelException e){ + throw e; + } catch (CoreException e) { + throw new CModelException(e); + } finally { + if (buffer != null) + releaseTextBuffer(buffer); + } + } + + /** + * Returns a preview of the change without actually modifying the underlying text. + * + * @return the change's preview + * @exception CModelException if the preview could not be created + */ + public String getPreviewContent() throws CModelException { + return getPreviewTextBuffer().getContent(); + } + + /** + * Note: API is under construction + */ + public TextBuffer getPreviewTextBuffer() throws CModelException { + try { + LocalTextEditProcessor editor= new LocalTextEditProcessor(createTextBuffer()); + addTextEdits(editor); + editor.performEdits(new NullProgressMonitor()); + return editor.getTextBuffer(); + } catch (CModelException e){ + throw e; + } catch (CoreException e) { + throw new CModelException(e); + } + } + + /** + * Returns the current content to be modified by the given text edit change. The + * text edit change must have been added to this TextChange + * by calling addTextEdit() + * + * @param change the text edit change for which the content is requested + * @param surroundingLines the number of surrounding lines added at top and bottom + * of the content + * @return the current content to be modified by the given text edit change + */ + public String getCurrentContent(EditChange change, int surroundingLines) throws CoreException { + return getContent(change, surroundingLines, false); + } + + /** + * Returns the preview of the given text edit change. The text edit change must + * have been added to this TextChange by calling addTextEdit() + * + * + * @param change the text edit change for which the preview is requested + * @param surroundingLines the number of surrounding lines added at top and bottom + * of the preview + * @return the preview of the given text edit change + */ + public String getPreviewContent(EditChange change, int surroundingLines) throws CoreException { + return getContent(change, surroundingLines, true); + } + + /** + * Returns the current content denoted by the given range. + * + * @param range the range describing the content to be returned + * @return the current content denoted by the given range + */ + public String getCurrentContent(IRegion range) throws CoreException { + TextBuffer buffer= null; + try { + buffer= acquireTextBuffer(); + int offset= buffer.getLineInformationOfOffset(range.getOffset()).getOffset(); + int length= range.getLength() + range.getOffset() - offset; + return buffer.getContent(offset, length); + } finally { + if (buffer != null) + releaseTextBuffer(buffer); + } + } + + /** + * Returns a preview denoted by the given range. First the changes + * passed in argument changes are applied and then a string denoted + * by range is extracted from the result. + * + * @param changes the changes to apply + * @param range the range denoting the resulting string. + * @return the computed preview + */ + public String getPreviewContent(EditChange[] changes, IRegion range) throws CoreException { + TextBuffer buffer= createTextBuffer(); + LocalTextEditProcessor editor= new LocalTextEditProcessor(buffer); + addTextEdits(editor, changes); + int oldLength= buffer.getLength(); + editor.performEdits(new NullProgressMonitor()); + int delta= buffer.getLength() - oldLength; + int offset= buffer.getLineInformationOfOffset(range.getOffset()).getOffset(); + int length= range.getLength() + range.getOffset() - offset + delta; + if (length > 0) { + return buffer.getContent(offset, length); + } else { + // range got removed + return ""; //$NON-NLS-1$ + } + } + + /** + * Controls whether the text change should keep executed edits. If set to true + * a call to getExecutedTextEdit(TextEdit original) will return the executed edit + * associated with the original edit. + * + * @param keep if true executed edits are kept + */ + public void setKeepExecutedTextEdits(boolean keep) { + fKeepExecutedTextEdits= keep; + if (!fKeepExecutedTextEdits) + fCopier= null; + } + + /** + * Returns the edit that got copied and executed instead of the orignial. + * + * @return the executed edit + */ + private TextEdit getExecutedTextEdit(TextEdit original) { + if (!fKeepExecutedTextEdits || fCopier == null) + return null; + return fCopier.getCopy(original); + } + + /** + * Returns the text range of the given text edit. If the change doesn't + * manage the given text edit or if setTrackPositionChanges + * is set to false null is returned. + * + *

+ * Note: API is under construction + *

+ */ + public IRegion getNewTextRange(TextEdit edit) { + Assert.isNotNull(edit); + TextEdit result= getExecutedTextEdit(edit); + if (result == null) + return null; + return result.getRegion(); + } + + /** + * Returns the new text range for given text edits. If setTrackPositionChanges + * is set to false null is returned. + * + *

+ * Note: API is under construction + *

+ */ + public IRegion getNewTextRange(TextEdit[] edits) { + Assert.isTrue(edits != null && edits.length > 0); + if (!fKeepExecutedTextEdits || fCopier == null) + return null; + + TextEdit[] copies= new TextEdit[edits.length]; + for (int i= 0; i < edits.length; i++) { + TextEdit copy= fCopier.getCopy(edits[i]); + if (copy == null) + return null; + copies[i]= copy; + } + return TextEdit.getCoverage(copies); + } + + /** + * Note: API is under construction + */ + public IRegion getNewTextRange(EditChange editChange) { + return getNewTextRange(editChange.getGroupDescription().getTextEdits()); + } + + /* (Non-Javadoc) + * Method declared in IChange. + */ + public void setActive(boolean active) { + super.setActive(active); + for (Iterator iter= fTextEditChanges.iterator(); iter.hasNext();) { + EditChange element= (EditChange) iter.next(); + element.setActive(active); + } + } + + /* non Java-doc + * @see AbstractTextChange#addTextEdits + */ + protected void addTextEdits(LocalTextEditProcessor editor) throws CoreException { + if (fEdit == null) + return; + List excludes= new ArrayList(0); + for (Iterator iter= fTextEditChanges.iterator(); iter.hasNext(); ) { + EditChange edit= (EditChange)iter.next(); + if (!edit.isActive()) { + excludes.addAll(Arrays.asList(edit.getGroupDescription().getTextEdits())); + } + } + fCopier= new TextEditCopier(fEdit); + TextEdit copiedEdit= fCopier.perform(); + if (copiedEdit != null) { + editor.add(copiedEdit); + editor.setExcludes(mapEdits( + (TextEdit[])excludes.toArray(new TextEdit[excludes.size()]), + fCopier)); + } + if (!fKeepExecutedTextEdits) + fCopier= null; + } + + protected void addTextEdits(LocalTextEditProcessor editor, EditChange[] changes) throws CoreException { + if (fEdit == null) + return; + List includes= new ArrayList(0); + for (int c= 0; c < changes.length; c++) { + EditChange change= changes[c]; + Assert.isTrue(change.getTextChange() == this); + if (change.isActive()) { + includes.addAll(Arrays.asList(change.getGroupDescription().getTextEdits())); + } + } + fCopier= new TextEditCopier(fEdit); + TextEdit copiedEdit= fCopier.perform(); + if (copiedEdit != null) { + editor.add(copiedEdit); + editor.setIncludes(mapEdits( + (TextEdit[])includes.toArray(new TextEdit[includes.size()]), + fCopier)); + } + if (!fKeepExecutedTextEdits) + fCopier= null; + } + + private TextEdit[] mapEdits(TextEdit[] edits, TextEditCopier copier) { + if (edits == null) + return null; + for (int i= 0; i < edits.length; i++) { + edits[i]= copier.getCopy(edits[i]); + } + return edits; + } + + private String getContent(EditChange change, int surroundingLines, boolean preview) throws CoreException { + Assert.isTrue(change.getTextChange() == this); + TextBuffer buffer= createTextBuffer(); + IRegion range= null; + if (preview) { + LocalTextEditProcessor editor= new LocalTextEditProcessor(buffer); + boolean keepEdits= fKeepExecutedTextEdits; + setKeepExecutedTextEdits(true); + addTextEdits(editor, new EditChange[] { change }); + editor.performEdits(new NullProgressMonitor()); + range= getNewTextRange(change); + setKeepExecutedTextEdits(keepEdits); + } else { + range= change.getTextRange(); + } + int startLine= Math.max(buffer.getLineOfOffset(range.getOffset()) - surroundingLines, 0); + int endLine= Math.min( + buffer.getLineOfOffset(range.getOffset() + range.getLength() - 1) + surroundingLines, + buffer.getNumberOfLines() - 1); + int offset= buffer.getLineInformation(startLine).getOffset(); + TextRegion region= buffer.getLineInformation(endLine); + int length = region.getOffset() + region.getLength() - offset; + return buffer.getContent(offset, length); + } + + private static void insert(TextEdit parent, TextEdit edit) { + if (!parent.hasChildren()) { + parent.addChild(edit); + return; + } + TextEdit[] children= parent.getChildren(); + // First dive down to find the right parent. + for (int i= 0; i < children.length; i++) { + TextEdit child= children[i]; + if (covers(child, edit)) { + insert(child, edit); + return; + } + } + // We have the right parent. Now check if some of the children have to + // be moved under the new edit since it is covering it. + for (int i= children.length - 1; i >= 0; i--) { + TextEdit child= children[i]; + if (covers(edit, child)) { + parent.removeChild(i); + edit.addChild(child); + } + } + parent.addChild(edit); + } + + private static boolean covers(TextEdit thisEdit, TextEdit otherEdit) { + if (thisEdit.getLength() == 0) // an insertion point can't cover anything + return false; + + int thisOffset= thisEdit.getOffset(); + int thisEnd= thisEdit.getExclusiveEnd(); + if (otherEdit.getLength() == 0) { + int otherOffset= otherEdit.getOffset(); + return thisOffset < otherOffset && otherOffset < thisEnd; + } else { + int otherOffset= otherEdit.getOffset(); + int otherEnd= otherEdit.getExclusiveEnd(); + return thisOffset <= otherOffset && otherEnd <= thisEnd; + } + } +} + diff --git a/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/changes/TextFileChange.java b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/changes/TextFileChange.java new file mode 100644 index 00000000000..6ffa9e795a0 --- /dev/null +++ b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/changes/TextFileChange.java @@ -0,0 +1,239 @@ +/********************************************************************** + * Copyright (c) 2004 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.internal.corext.refactoring.changes; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.core.runtime.SubProgressMonitor; + +import org.eclipse.core.resources.IFile; + +import org.eclipse.cdt.core.model.CModelException; + +import org.eclipse.text.edits.UndoEdit; +import org.eclipse.cdt.internal.corext.Assert; +import org.eclipse.cdt.internal.corext.refactoring.Checks; +import org.eclipse.cdt.internal.corext.refactoring.base.ChangeAbortException; +import org.eclipse.cdt.internal.corext.refactoring.base.ChangeContext; +import org.eclipse.cdt.internal.corext.refactoring.base.IChange; +import org.eclipse.cdt.internal.corext.refactoring.base.RefactoringStatus; +import org.eclipse.cdt.internal.corext.textmanipulation.TextBuffer; + +public class TextFileChange extends TextChange { + + protected static class UndoTextFileChange extends UndoTextChange { + private IFile fFile; + private TextBuffer fAcquiredTextBuffer; + private int fAcquireCounter; + public UndoTextFileChange(String name, IFile file, int changeKind, UndoEdit undo) { + super(name, changeKind, undo); + fFile= file; + } + public Object getModifiedLanguageElement(){ + return fFile; + } + protected TextBuffer acquireTextBuffer() throws CoreException { + TextBuffer result= TextBuffer.acquire(fFile); + if (fAcquiredTextBuffer == null || result == fAcquiredTextBuffer) { + fAcquiredTextBuffer= result; + fAcquireCounter++; + } + return result; + } + protected void releaseTextBuffer(TextBuffer textBuffer) { + TextBuffer.release(textBuffer); + if (textBuffer == fAcquiredTextBuffer) { + if (--fAcquireCounter == 0) + fAcquiredTextBuffer= null; + } + } + protected TextBuffer createTextBuffer() throws CoreException { + return TextBuffer.create(fFile); + } + protected IChange createReverseChange(UndoEdit undo, int changeKind) { + return new UndoTextFileChange(getName(), fFile, changeKind, undo); + } + public RefactoringStatus aboutToPerform(ChangeContext context, IProgressMonitor pm) { + RefactoringStatus result= Checks.validateModifiesFiles(new IFile[] {fFile}); + if (result.hasFatalError()) + return result; + context.checkUnsavedFile(result, fFile); + return result; + } + public void perform(ChangeContext context, IProgressMonitor pm) throws CModelException, ChangeAbortException { + if (!isActive()) { + super.perform(context, pm); + return; + } + try{ + acquireTextBuffer(); + pm.beginTask("", 10); //$NON-NLS-1$ + super.perform(context, new SubProgressMonitor(pm, 8)); + TextBuffer.aboutToChange(fAcquiredTextBuffer); + TextBuffer.save(fAcquiredTextBuffer, new SubProgressMonitor(pm, 2)); + } catch (Exception e) { + handleException(context, e); + } finally { + pm.done(); + } + } + public void performed() { + // During acquiring of text buffer an exception has occured. In this case + // the pointer is null + if (fAcquiredTextBuffer != null) { + try { + TextBuffer.changed(fAcquiredTextBuffer); + } catch (CoreException e) { + Assert.isTrue(false, "Should not happen since the buffer is acquired through a text buffer manager"); //$NON-NLS-1$ + } finally { + releaseTextBuffer(fAcquiredTextBuffer); + } + } + super.performed(); + } + } + + private IFile fFile; + private TextBuffer fAcquiredTextBuffer; + private int fAcquireCounter; + private boolean fSave= true; + + /** + * Creates a new TextFileChange for the given file. + * + * @param name the change's name mainly used to render the change in the UI + * @param file the file this text change operates on + */ + public TextFileChange(String name, IFile file) { + super(name); + fFile= file; + Assert.isNotNull(fFile); + } + + /** + * Sets the save state. If set to true the change will save the + * content of the file back to disk. + * + * @param save whether or not the changes should be saved to disk + */ + public void setSave(boolean save) { + fSave= save; + } + + /** + * Returns the IFile this change is working on. + * + * @return the file this change is working on + */ + public IFile getFile() { + return fFile; + } + + /* non java-doc + * Method declared in TextChange + */ + protected TextBuffer acquireTextBuffer() throws CoreException { + TextBuffer result= TextBuffer.acquire(fFile); + if (fAcquiredTextBuffer == null || result == fAcquiredTextBuffer) { + fAcquiredTextBuffer= result; + fAcquireCounter++; + } + return result; + } + + /* non java-doc + * Method declared in TextChange + */ + protected void releaseTextBuffer(TextBuffer textBuffer) { + TextBuffer.release(textBuffer); + if (textBuffer == fAcquiredTextBuffer) { + if (--fAcquireCounter == 0) + fAcquiredTextBuffer= null; + } + } + + /* non java-doc + * Method declared in TextChange + */ + protected TextBuffer createTextBuffer() throws CoreException { + return TextBuffer.create(fFile); + } + + /* non java-doc + * Method declared in TextChange + */ + protected IChange createReverseChange(UndoEdit undo, int changeKind) { + return new UndoTextFileChange(getName(), fFile, changeKind, undo); + } + + /* non java-doc + * Method declared in IChange. + */ + public Object getModifiedLanguageElement(){ + return fFile; + } + + /* non java-doc + * Method declared in TextChange + */ + public RefactoringStatus aboutToPerform(ChangeContext context, IProgressMonitor pm) { + if (fSave) { + return Checks.validateModifiesFiles(new IFile[] {fFile}); + } + return new RefactoringStatus(); + } + + /* non java-doc + * Method declared in TextChange + */ + public void perform(ChangeContext context, IProgressMonitor pm) throws CModelException, ChangeAbortException { + if (pm == null) + pm= new NullProgressMonitor(); + if (!isActive()) { + super.perform(context, pm); + return; + } + try{ + acquireTextBuffer(); + pm.beginTask("", 10); //$NON-NLS-1$ + super.perform(context, new SubProgressMonitor(pm, 8)); + if (fSave) { + TextBuffer.aboutToChange(fAcquiredTextBuffer); + TextBuffer.save(fAcquiredTextBuffer, new SubProgressMonitor(pm, 2)); + } + } catch (Exception e) { + handleException(context, e); + } finally { + pm.done(); + } + } + + /* non java-doc + * Method declared in TextChange + */ + public void performed() { + // During acquiring of text buffer an exception has occured. In this case + // the pointer is null + if (fAcquiredTextBuffer != null) { + try { + if (fSave) + TextBuffer.changed(fAcquiredTextBuffer); + } catch (CoreException e) { + Assert.isTrue(false, "Should not happen since the buffer is acquired through a text buffer manager"); //$NON-NLS-1$ + } finally { + releaseTextBuffer(fAcquiredTextBuffer); + } + } + super.performed(); + } +} + diff --git a/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/changes/TranslationUnitChange.java b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/changes/TranslationUnitChange.java new file mode 100644 index 00000000000..16458437ab8 --- /dev/null +++ b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/changes/TranslationUnitChange.java @@ -0,0 +1,57 @@ +/********************************************************************** + * Copyright (c) 2004 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.internal.corext.refactoring.changes; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.runtime.CoreException; + +import org.eclipse.cdt.core.model.ITranslationUnit; + +import org.eclipse.cdt.internal.corext.Assert; + +public class TranslationUnitChange extends TextFileChange { + + private ITranslationUnit fCUnit; + + /** + * Creates a new TranslationUnitChange. + * + * @param name the change's name mainly used to render the change in the UI + * @param cunit the Translation unit this text change works on + */ + public TranslationUnitChange(String name, ITranslationUnit cunit) throws CoreException { + super(name, getFile(cunit)); + Assert.isNotNull(cunit); + fCUnit= cunit; + setTextType("java"); //$NON-NLS-1$ + } + + private static IFile getFile(ITranslationUnit cunit) throws CoreException { + return (IFile) cunit.getResource(); + } + + /* non java-doc + * Method declared in IChange. + */ + public Object getModifiedLanguageElement(){ + return fCUnit; + } + + /** + * Returns the Translation unit this change works on. + * + * @return the Translation unit this change works on + */ + public ITranslationUnit getTranslationUnit() { + return fCUnit; + } +} + diff --git a/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/changes/UndoTextChange.java b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/changes/UndoTextChange.java new file mode 100644 index 00000000000..04a3311a63b --- /dev/null +++ b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/changes/UndoTextChange.java @@ -0,0 +1,30 @@ +/********************************************************************** + * Copyright (c) 2004 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.internal.corext.refactoring.changes; + +import org.eclipse.core.runtime.CoreException; + +import org.eclipse.text.edits.UndoEdit; + +abstract class UndoTextChange extends AbstractTextChange { + + private UndoEdit fUndos; + + public UndoTextChange(String name, int changeKind, UndoEdit undos) { + super(name, changeKind); + fUndos= undos; + } + + protected void addTextEdits(LocalTextEditProcessor editor) throws CoreException { + editor.add(fUndos); + } +} + diff --git a/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/refactoring.properties b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/refactoring.properties new file mode 100644 index 00000000000..1633d93d2dc --- /dev/null +++ b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/refactoring.properties @@ -0,0 +1,786 @@ +############################################################################### +# Copyright (c) 2004 Rational Software Corporation and others. +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Common Public License v0.5 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/cpl-v05.html +# +# Contributors: +# IBM Rational Software - Initial API and implementation +############################################################################### +# NLS properties for the Refactoring Core + +####################################### +# org.eclipse.jdt.internal.core.refactoring + +Assert.assertion_failed=assertion failed; +Assert.null_argument=null argument; + +Checks.Choose_name=Choose a name +Checks.all_excluded=All resources have been excluded from refactoring. Cannot proceed +Checks.cannot_be_parsed=''{0}'' has syntax errors. Content of that file will not be updated. +Checks.cu_not_created=Translation unit could not be created for this element. +Checks.cu_not_parsed=This refactoring cannot be performed correctly due to syntax errors in the translation unit. To perform this operation you will need to fix the errors. +Checks.cu_has_compile_errors=Code modification may not be accurate as affected resource ''{0}'' has compile errors. +Checks.no_dot=Type name cannot contain a dot (.) +Checks.cu_name_used=translation unit ''{0}.java'' already exists +Checks.method_native=Method {0}::{1} is native. Running the modified program will cause {2}. +Checks.methodName.constructor=New method name has constructor name +Checks.methodName.exists=Method ''{0}'' already exists in type ''{1}'' +Checks.methodName.overrides=New method ''{0}'' overrides existing method in type ''{1}'' +Checks.methodName.returnTypeClash=New method ''{0}'' overrides a method declared in type ''{1}'' that uses a different return type. +Checks.has_main=Type {0} contains a main method - some applications (such as scripts) may not work after refactoring +Checks.constructor_name= If you proceed, the method {0} in ''{1}'' will have a constructor name. +Checks.method_names_lowercase=This name is discouraged. According to convention, names of methods should start with lowercase letters + +####################################### +# org.eclipse.jdt.internal.core.refactoring.base +####################################### + +Change.checking_for=Checking change for: {0} +Change.internal_Error=Internal Error +Change.is_unsaved={0} is unsaved +Change.is_read_only={0} is read only +Change.unexpected_exception=Unexpected exception while executing a change. See log for details. +Change.javaChanges= C changes + + +ChangeAbortException.wrapped=Exception wrapped by {0} + +Refactoring.binary={0} is binary +Refactoring.not_in_model={0} does not exist in the model +Refactoring.read_only={0} is read only +Refactoring.unknown_structure={0} - unknown structure + +####################################### +# org.eclipse.jdt.internal.core.refactoring.changes +####################################### +AbstractRenameChange.Renaming=Renaming... + +RenameResourceChange.rename_resource=rename resource +RenameResourceChange.name=Rename ''{0}'' to: ''{1}'' + +CompositeChange.CompositeChange=CompositeChange> + +DeleteFromClassPathChange.remove=Remove entry from classpath of C project: + +MovePackageChange.move=Move package ''{0}'' to ''{1}'' +MoveResourceChange.move=Move resource ''{0}'' to ''{1}'' + +RenameCProjectChange.rename=Rename C Project ''{0}'' to ''{1}'' +RenameCProjectChange.update=Updating classpaths + +RenameSourceFolderChange.rename=Rename Source Folder ''{0}'' to ''{1}'' + +AbstractCElementRenameChange.checking_change=Checking change for: + +AbstractDeleteChange.deleting=deleting + +CreatePackageChange.Creating_package=Creating package +CreatePackageChange.Create_package=Create package + +AddToClasspathChange.add=Add entry to classpath of C project: + +CopyCompilationUnitChange.copy=Copy ''{0}'' to ''{1}'' + +CopyPackageChange.copy=Copy package ''{0}'' to ''{1}'' + +RenamePackageChange.checking_change=Checking change for: {0} +RenamePackageChange.name=Rename package ''{0}'' to ''{1}'' + +MoveCompilationUnitChange.default_package=(default package) +MoveCompilationUnitChange.name=Move Translation Unit ''{0}'' to ''{1}'' + +RenameCompilationUnitChange.name=Rename translation unit ''{0}'' to ''{1}'' + +####################################### +# org.eclipse.jdt.internal.core.refactoring.code +####################################### + +#-- Extract Method ------------------------------------------- +LocalTypeAnalyzer.local_type_from_outside=Selected block references a local type declared outside the selection. +LocalTypeAnalyzer.local_type_referenced_outside=A local type declared in the selected block is referenced outside the selection. + +FlowAnalyzer.execution_flow=Selected statements contain a return statement but not all possible execution flows end in a return. + +ExtractMethodAnalyzer.assignments_to_local=Ambiguous return value: selected block contains more than one assignment to local variable. +ExtractMethodAnalyzer.only_method_body=Cannot extract new method from selection. Only statements from a method body can be extracted. +ExtractMethodAnalyzer.after_do_keyword=Selection may not start immediately after the \'do\' keyword. +ExtractMethodAnalyzer.super_or_this=Cannot extract super or this call from constructor. +ExtractMethodAnalyzer.cannot_determine_return_type=Cannot determine expression's return type. Using void instead. +ExtractMethodAnalyzer.branch_mismatch=Selection contains branch statement but corresponding branch target is not selected. +ExtractMethodAnalyzer.parent_mismatch=Not all selected statements are enclosed by the same parent statement. +ExtractMethodAnalyzer.cannot_extract_anonymous_type=Cannot extract the body of a anonymous type declaration. Select whole declaration. +ExtractMethodAnalyzer.cannot_extract_variable_declaration_fragment=Cannot extract a variable declaration fragment. Select whole declaration statement. +ExtractMethodAnalyzer.cannot_extract_for_initializer=Cannot extract initialization part of a for statement. +ExtractMethodAnalyzer.cannot_extract_for_updater=Cannot extract increment part of a for statement. +ExtractMethodAnalyzer.cannot_extract_variable_declaration=Cannot extract parts of a variable declaration. Select whole declaration. +ExtractMethodAnalyzer.cannot_extract_type_reference=Cannot extract a single type reference. +ExtractMethodAnalyzer.cannot_extract_name_in_declaration=Cannot extract the name part of a declaration. +ExtractMethodAnalyzer.ambiguous_return_value=Ambiguous return value: expression, access to local or return statement extracted. +ExtractMethodAnalyzer.compile_errors=The method''s body cannot be analyzed because of compilation errors in method ''{0}''. To perform the operation you will need to fix the errors. +ExtractMethodAnalyzer.leftHandSideOfAssignment=Cannot extract the left hand side of an assignment. +ExtractMethodAnalyzer.single_expression_or_set=Can only extract a single expression or a set of statements. +ExtractMethodAnalyzer.cannot_extract_null_type=Cannot extract null expression. + +ExtractMethodRefactoring.name=Extract Method {0} in {1} +ExtractMethodRefactoring.add_method=add new method {0} +ExtractMethodRefactoring.checking_new_name=Checking new method name +ExtractMethodRefactoring.checking_selection=Checking text selection +ExtractMethodRefactoring.no_set_of_statements=Selection does not mark a set of statements. Only statements from a method body can be extracted. +ExtractMethodRefactoring.substitute_with_call=substitute statement(s) with call to {0} +ExtractMethodRefactoring.change_name=extract method {0} from method {1} +ExtractMethodRefactoring.organize_imports=Organize Imports +ExtractMethodRefactoring.duplicates.single=replace duplicate code fragment with call to {0} +ExtractMethodRefactoring.duplicates.multi=replace duplicate code fragments with call to {0} +ExtractMethodRefactoring.error.nameInUse=''{0}'' is already used as a name in the selected code +ExtractMethodRefactoring.error.sameParameter=A parameter ''{0}'' already exists + +#-- Inline Method ------------------------------------------------------ +InlineMethodRefactoring.name= Inline Method Refactoring +InlineMethodRefactoring.searching= Searching for references... +InlineMethodRefactoring.processing= Processing {0} +InlineMethodRefactoring.edit.inline= Inline invocation +InlineMethodRefactoring.edit.delete= Delete method declaration +InlineMethodRefactoring.edit.inlineCall= Inline Call +InlineMethodRefactoring.edit.import= Update import statements +InlineMethodRefactoring.error.classFile= Can\'t inline method since it is declared in a class file +InlineMethodRefactoring.error.noMethodDeclaration= Unable to resolve corresponding method declaration. +InlineMethodRefactoring.checking.overridden= Checking for overridden methods... +# The there keys below are referenced indirectly by passing a string to a helper +# method. So don't remove them even if they are marked as unused. +InlineMethodRefactoring.checking.overridden.error= Type {0} overrides method to be inlined. +InlineMethodRefactoring.checking.overrides.error= Method to be inlined overrides method from class {0}. +InlineMethodRefactoring.checking.implements.error= Method to be inlined implements method from interface {0}. + +InlineMethodRefactoring.SourceAnalyzer.recursive_call=Method declaration contains recursive call. +InlineMethodRefactoring.SourceAnalyzer.declaration_has_errors=The method declaration contains compile errors. To perform the operation you will need to fix the errors. + +InlineMethodRefactoring.SourceAnalyzer.qualified_this_expressions=Cannot inline a method that uses qualified this expressions. +InlineMethodRefactoring.SourceAnalyzer.syntax_errors=The translation unit containing this method declaration has syntax errors. To perform the operation you will need to fix the errors. +InlineMethodRefactoring.SourceAnalyzer.abstract_methods=Cannot inline abstract methods. + +CallInliner.receiver_type=Can\'t determine receiver\'s type. +CallInliner.execution_flow=Can\'t inline method. Return statement in method declaration interrupts execution flow. +CallInliner.multiDeclaration=Can\'t inline method used as an initializer in a multi fragment variable declaration. +CallInliner.simple_functions=Inlining is only possible on simple functions (consisting of a single return statement), or functions used in an assignment. +CallInliner.field_initializer_simple=In field initializers inlining is only supported for simple functions (e.g. functions consisting of a single return statement). +CallInliner.field_initialize_new_local=Can\'t inline field initializer because new local variable is required. +CallInliner.field_initialize_write_parameter=Can\'t inline field initializer because one of the method parameters is used as an assignment target and will require new local variable. +CallInliner.field_initialize_self_reference=Can\'t inline method. Method references the field to be initialized. +CallInliner.constructors=Can\'t inline a constructor invocation that is used as a class instance creation. + +#-- SEF ------------------------------------------------------ +SelfEncapsulateField.AccessAnalyzer.encapsulate_read_access=Encapsulate read access +SelfEncapsulateField.AccessAnalyzer.encapsulate_write_access=Encapsulate write access +SelfEncapsulateField.AccessAnalyzer.encapsulate_prefix_access=Encapsulate prefix access +SelfEncapsulateField.AccessAnalyzer.encapsulate_postfix_access=Encapsulate postfix access +SelfEncapsulateField.AccessAnalyzer.cannot_convert_postfix_expression=Cannot convert postfix expression. It is used inside another expression. + +SelfEncapsulateField.name=Self Encapsulate Field +SelfEncapsulateField.method_exists=A method ''{0}'' already exists in type ''{1}''. +SelfEncapsulateField.compiler_errors_field=Cannot analyze field ''{0}'' due to the following compiler error: {1} +SelfEncapsulateField.compiler_errors_update={0} contains compiler errors. This may affect field access update. +SelfEncapsulateField.type_not_resolveable=The type of the selected field cannot be resolved. An import statement may be missing. +SelfEncapsulateField.cannot_analyze_selected_field=Cannot analyze selected field ''{0}'' +SelfEncapsulateField.checking_preconditions=Checking preconditions.. +SelfEncapsulateField.searching_for_cunits=Searching for affected translation units... +SelfEncapsulateField.analyzing=Analyzing... +SelfEncapsulateField.create_changes=Create changes +SelfEncapsulateField.change_visibility=Change visibility to private +SelfEncapsulateField.add_setter=Add Setter method +SelfEncapsulateField.add_getter=Add Getter method + +#-- inline temp ------------------------------------------------------ +InlineTempRefactoring.name=Inline local variable +InlineTempRefactoring.syntax_errors=This translation unit contains syntax errors. To perform the operation you will need to fix the errors. +InlineTempRefactoring.select_temp=A local variable declaration or reference must be selected to activate this refactoring. +InlineTempRefactoring.method_parameter=Cannot inline method parameters. +InlineTempRefactoring.exceptions_declared=Cannot inline exceptions declared in \'catch\' clauses. +InlineTempRefactoring.not_initialized=Local variable ''{0}'' is not initialized at declaration. +InlineTempRefactoring.assigned_more_once=Local variable ''{0}'' is assigned more than once. +InlineTempRefactoring.preview=Creating preview +InlineTempRefactoring.inline=Inline local variable +InlineTempRefactoring.inline_edit_name=Inline local variable: +InlineTempRefactoring.remove_edit_name=Remove local variable: +InlineTempRefactoring.Array_vars_initialized=Array variables initialized with constants cannot be inlined. +InlineTempRefactoring.for_initializers=Cannot inline variables declared in the initializer list of a \'for\' statement. + +#-- extract temp ------------------------------------------------------ +ExtractTempRefactoring.name=Extract Local Variable +ExtractTempRefactoring.select_expression=An expression must be selected to activate this refactoring. +ExtractTempRefactoring.syntax_error=This file contains syntax errors. To perform this operation you will need to fix the errors. +ExtractTempRefactoring.explicit_constructor=Code from explicit constructor calls cannot be extracted to a variable. +ExtractTempRefactoring.expression_in_method=An expression used in a method must be selected to activate this refactoring. +ExtractTempRefactoring.no_void=Cannot extract an expression of type \'void\'. +ExtractTempRefactoring.null_literals=Cannot extract single null literals. +ExtractTempRefactoring.array_initializer=Operation not applicable to an array initializer. +ExtractTempRefactoring.assignment=Cannot extract assignment that is part of another expression. +ExtractTempRefactoring.single_conditional_expression=Currently no support to extract a single conditional expression. +ExtractTempRefactoring.convention=This name is discouraged. According to convention, names of local variables should start with lowercase letters. +ExtractTempRefactoring.checking_preconditions=Checking preconditions... +ExtractTempRefactoring.preview=Preparing preview +ExtractTempRefactoring.extract_temp=Extract Temp +ExtractTempRefactoring.update_imports=Update imports +ExtractTempRefactoring.declare_local_variable=Declare local variable +ExtractTempRefactoring.replace=Replace expression with a local variable reference +ExtractTempRefactoring.name_in_new=Cannot extract this name - try selecting the whole instance creation expression. +ExtractTempRefactoring.names_in_declarations=An expression has to be selected to activate this refactoring. Names used in declarations are not expressions. +ExtractTempRefactoring.assigned_to=The selected expression is assigned. Extracting may change the program\'s semantics. +ExtractTempRefactoring.refers_to_for_variable=Cannot extract expression, since it refers to a variable declared in the initializer of the enclosing \'for\' statement. +ExtractTempRefactoring.for_initializer_updater=Cannot extract \'for\' initializer or updater. + +#-- extract constant -------------------------------------------------- +ExtractConstantRefactoring.name=Extract Constant +ExtractConstantRefactoring.select_expression=An expression must be selected to activate this refactoring. +ExtractConstantRefactoring.syntax_error=This file contains syntax errors. To perform this operation you will need to fix the errors. +ExtractConstantRefactoring.declare_constant=Declare constant +ExtractConstantRefactoring.update_imports=Update imports +ExtractConstantRefactoring.replace=Replace expression with a constant reference +ExtractConstantRefactoring.preview=Preparing preview +ExtractConstantRefactoring.field_exists=Field ''{0}'' already exists. +ExtractConstantRefactoring.no_void=Cannot extract an expression of type \'void\'. +ExtractConstantRefactoring.null_literals=Cannot extract single null literals. +ExtractConstantRefactoring.not_load_time_constant=Cannot extract this expression - it is not a valid static constant. +ExtractConstantRefactoring.extract_constant=Extract Constant +ExtractConstantRefactoring.convention=This name is discouraged. According to convention, names of class constants do not contain lowercase letters. +ExtractConstantRefactoring.checking_preconditions=Checking preconditions... +ExtractConstantRefactoring.rename=Rename Constant + +#-- introduce parameter -------------------------------------------------- +IntroduceParameterRefactoring.name=Introduce Parameter +IntroduceParameterRefactoring.introduce_parameter=Introduce Parameter +IntroduceParameterRefactoring.syntax_error=This translation unit contains syntax errors. To perform the operation you will need to fix the errors. +IntroduceParameterRefactoring.select=An expression must be selected to activate this refactoring. +IntroduceParameterRefactoring.expression_in_method=An expression used in a method must be selected to activate this refactoring. +IntroduceParameterRefactoring.no_void=Cannot introduce a parameter from an expression of type \'void\'. +IntroduceParameterRefactoring.duplicate_name=A parameter or local variable with this name already exists. +IntroduceParameterRefactoring.preview=Preparing preview + +IntroduceParameterRefactoring.add_parameter=Add parameter +IntroduceParameterRefactoring.replace=Replace expression with a parameter reference +IntroduceParameterRefactoring.add_argument=Add actual argument expression + + +####################################### +# org.eclipse.jdt.internal.core.refactoring.rename +####################################### +RenameCompilationUnitRefactoring.name=Rename ''{0}'' to ''{1}'' +RenameCompilationUnitRefactoring.not_parsed={0} has syntax errors. No references will be updated if you proceed +RenameCompilationUnitRefactoring.not_parsed_1={0} has syntax errors. +RenameCompilationUnitRefactoring.same_name=The same name chosen + +RenameFieldRefactoring.name=Rename field ''{0}'' to ''{1}'' +RenameFieldRefactoring.hiding=After renaming, the field ''{0}'' will be hidden in the scope of the field ''{1}'' declared in type ''{2}'' +RenameFieldRefactoring.hiding2=After renaming, the field named ''{0}'' declared in type ''{1}'' will be hidden in the scope of the field ''{2}'' +RenameFieldRefactoring.another_name=Choose another name. +RenameFieldRefactoring.checking=Checking preconditions... +RenameFieldRefactoring.field_already_defined=Field with this name is already defined. +RenameFieldRefactoring.searching=Searching for references... +RenameFieldRefactoring.deleted=The selected field has been deleted from ''{0}'' +RenameFieldRefactoring.already_exists=Method ''{0}'' already exists in ''{1}'' +RenameFieldRefactoring.overridden=Method ''{0}'' is overridden or overrides another method +RenameFieldRefactoring.overridden_or_overrides=Method ''{0}'' is overridden or overrides another method +RenameFieldRefactoring.Update_getter_occurrence=Update getter occurrence +RenameFieldRefactoring.Update_setter_occurrence=Update setter occurrence +RenameFieldRefactoring.searching_for_text_matches=searching for text matches +RenameFieldRefactoring.Update_field_declaration=Update field declaration +RenameFieldRefactoring.Update_field_reference=Update field reference +RenameFieldRefactoring.should_start_lowercase=This name is discouraged. According to convention, C instance field names should start with lowercase letters +RenameFieldRefactoring.declared_in_supertype=Cannot be renamed because it is declared in a supertype + +RenamePackageRefactoring.another_name=Choose another name. +RenamePackageRefactoring.checking=Checking preconditions... +RenamePackageRefactoring.creating_change=Preparing preview... +RenamePackageRefactoring.package_exists=Package already exists +RenamePackageRefactoring.searching=Searching for references... +RenamePackageRefactoring.update_reference=update package reference +RenamePackageRefactoring.name=Rename package ''{0}'' to ''{1}'' +RenamePackageRefactoring.aleady_exists=Package ''{0}'' already exists in this project in folder ''{1}'' + +RenameMethodInInterfaceRefactoring.already_defined=A related type declares a method with the new name (and same number of parameters) +RenameMethodInInterfaceRefactoring.special_case=Cannot rename this method because it is a special case (see the language specification section 9.2 for details) + +RenameMethodRefactoring.name=Rename method ''{0}'' to ''{1}'' +RenameMethodRefactoring.no_binary=Related method ''{0}'' (declared in ''{1}'') is binary. Refactoring cannot be performed. +RenameMethodRefactoring.no_native=Renaming native methods will cause an unsatisfied link error on runtime. +RenameMethodRefactoring.no_native_1=Related method ''{0}'' (declared in ''{1}'') is native. Renaming will cause an UnsatisfiedLinkError on runtime. +RenameMethodRefactoring.no_read_only=Related method ''{0}'' (declared in ''{1}'') is read-only. Refactoring cannot be performed. +RenameMethodRefactoring.not_in_model=Related method ''{0}'' (declared in ''{1}'') does not exist in the model. +RenameMethodRefactoring.same_name=This name already exists. + +RenamePrivateMethodRefactoring.hierarchy_defines=''{0}'' or a type in its hierarchy defines a method ''{1}'' with the same number of parameters and same parameter type names. +RenamePrivateMethodRefactoring.hierarchy_defines2=''{0}'' or a type in its hierarchy defines a method ''{1}'' with the same number of parameters, but different parameter type names. +RenamePrivateMethodRefactoring.update=Update method reference + +RenameVirtualMethodRefactoring.requieres_renaming_native=Renaming ''{0}'' requires renaming a native method. Renaming will cause {1} on runtime. +RenameVirtualMethodRefactoring.hierarchy_declares1=Hierarchy declares a method ''{0}'' with the same number of parameters, but different parameter type names. +RenameVirtualMethodRefactoring.hierarchy_declares2=Hierarchy declares a method ''{0}'' with the same number of parameters and same parameter type names. + +RenameMethodRefactoring.update_occurrence=Update method occurrence +RenameMethodRefactoring.update_declaration=Update method declaration +RenameMethodRefactoring.deleted=The selected method has been deleted from ''{0}'' + +RenameTypeRefactoring.checking=Checking preconditions... +RenameTypeRefactoring.choose_another_name=Please choose another name. +RenameTypeRefactoring.creating_change=Preparing preview... +RenameTypeRefactoring.rename_constructor=rename constructor +RenameTypeRefactoring.searching=Searching for references... +RenameTypeRefactoring.update_reference=update type reference +RenameTypeRefactoring.name=Rename type ''{0}'' to ''{1}'' +RenameTypeRefactoring.enclosed=Type ''{0}'' is enclosed in a type named ''{1}'' +RenameTypeRefactoring.encloses=Type ''{0}'' encloses a type named ''{1}'' +RenameTypeRefactoring.exists=Type named ''{0}'' already exists in package ''{1}'' +RenameTypeRefactoring.imported=Type named ''{0}'' is imported (single-type-import) in ''{1}'' (a translation unit must not import and declare a type with the same name) +RenameTypeRefactoring.member_type_exists=Another member type named ''{0}'' already exists in ''{1}'' +RenameTypeRefactoring.enclosed_type_native=A type enclosed in type ''{0}'' declares a native method. Renaming will cause an unsatisfied link error on runtime. +RenameTypeRefactoring.name_conflict1=Name conflict with type ''{0}'' in ''{1}'' +RenameTypeRefactoring.searching_text=searching for text matches +RenameTypeRefactoring.update=Type declaration update +RenameTypeRefactoring.does_not_exist=Type ''{0}'' does not exist in the saved version of ''{1}'' +RenameTypeRefactoring.will_not_rename=Compilation unit will not be renamed +RenameTypeRefactoring.local_type=Local Type declared inside ''{0}'' is named {1} +RenameTypeRefactoring.member_type=Member Type declared inside ''{0}'' is named {1} +RenameTypeRefactoring.another_type=Another type named ''{0} is referenced in ''{1}'' +RenameTypeRefactoring.wrong_element=Rename refactoring does not handle this type of element. + +TextMatchFinder.comment=text reference update in a comment +TextMatchFinder.string=text reference update in a string literal +TextMatchFinder.searching=searching for text matches in: + +RippleMethodFinder.analizing_hierarchy=analyzing hierarchy + +RefactoringAnalyzeUtil.name_collision=Name collision with name ''{0}'' + +RenameTempRefactoring.must_select_local=A local variable declaration or reference must be selected to activate this refactoring +RenameTempRefactoring.only_in_methods_and_initializers=Only local variables declared in methods and initializers can be renamed +RenameTempRefactoring.lowercase=This name is discouraged. According to convention, local variable names should start with lowercase letters. +RenameTempRefactoring.rename=Rename Local Variable +RenameTempRefactoring.changeName=Rename local variable:''{0}'' to: ''{1}'' + +MethodChecks.overrides=The selected method overrides method ''{0}'' declared in type ''{1}''. +MethodChecks.implements=The selected method is an implementation of method ''{0}'' declared in type ''{1}'' + +RenameCProjectRefactoring.rename=Rename C project ''{0}'' to:''{1}'' +RenameCProjectRefactoring.already_exists=A project with that name already exists +RenameCProjectRefactoring.read_only=Project ''{0}'' is marked as read-only + +RenamePackageRefactoring.searching_text=searching for text matches +RenamePackageRefactoring.Packagered_only=Package ''{0}'' is read-only. +RenamePackageRefactoring.resource_read_only=Resource corresponding to package ''{0}'' is read only. Click ''Continue'' if still you want to rename it. +RenamePackageRefactoring.contains_type=Package ''{0}'' already contains a type named ''{1}'' + +RenameResourceRefactoring.Internal_Error=Internal Error +RenameResourceRefactoring.alread_exists=A file or folder with this name already exists +RenameResourceRefactoring.invalidName=This is an invalid name for a file or folder + +RenameSourceFolderRefactoring.blank=Name must not start or end with a blank +RenameSourceFolderRefactoring.invalid_name=This is an invalid name for a file or folder +RenameSourceFolderRefactoring.already_exists=An element with this name already exists +RenameSourceFolderRefactoring.alread_exists=An element with this name already exists +RenameSourceFolderRefactoring.rename=Rename Source Folder ''{0}'' to ''{1}'' + +################ Rename Processors ######################################### + +RenameResourceProcessor.name=Rename resource ''{0}'' to ''{1}'' + +####################################### +# org.eclipse.jdt.internal.core.refactoring.reorg +####################################### +MoveRefactoring.reorganize_elements=Reorganize elements + +DeleteRefactoring.delete_package_fragment_root= Deleting a package fragment root + +MoveCuUpdateCreator.update_imports=update imports +MoveCuUpdateCreator.searching=Searching for references to types in ''{0}'' +MoveCuUpdateCreator.update_references=update references + +CopyRefactoring.cu.copyOf1=CopyOf{0} +CopyRefactoring.cu.copyOfMore=Copy_{0}_of_{1} +CopyRefactoring.resource.copyOf1=Copy of {0} +CopyRefactoring.resource.copyOfMore=Copy ({0}) of {1} +CopyRefactoring.package.copyOf1={0}.copy +CopyRefactoring.package.copyOfMore={1}.copy{0} + +####################################### +# org.eclipse.jdt.internal.core.refactoring.structure +####################################### +PullUpRefactoring.Pull_Up=Pull Up +PullUpRefactoring.no_interface_members=Pull up is not allowed on interface members +PullUpRefactoring.no_java.lang.Object=Pull up is not allowed on elements declared in java.lang.Object +PullUpRefactoring.no_binary_types=Pull up is not allowed on elements declared in binary types +PullUpRefactoring.no_read_only_types=Pull up is not allowed on elements declared in read-only types +PullUpRefactoring.not_this_type=Pull up is not allowed on elements declared in this type +PullUpRefactoring.final_fields=Pulling up final fields will result in compilation errors if they are not initialized on creation or in constructors +PullUpRefactoring.checking_referenced_elements=Checking referenced elements +PullUpRefactoring.does_not_exist=Element {0} does not exist in the saved version of the file +PullUpRefactoring.type_not_accessible=Type ''{0}'' referenced in one of the pulled elements is not accessible from type ''{1}'' +PullUpRefactoring.field_not_accessible=Field ''{0}'' referenced in one of the pulled elements is not accessible from type ''{1}'' +PullUpRefactoring.method_not_accessible=Method ''{0}'' referenced in one of the pulled elements is not accessible from type ''{1}'' +PullUpRefactoring.different_method_return_type=Method ''{0}'' declared in type''{1}'' has a different return type than its pulled up counterpart, which will result in compile errors if you proceed +PullUpRefactoring.different_field_type=Field ''{0}'' declared in type ''{1}'' has a different type than its pulled up counterpart +PullUpRefactoring.static_method=Method ''{0}'' declared in type ''{1}'' is \'static\', which will result in compile errors if you proceed +PullUpRefactoring.lower_visibility=Method ''{0}'' declared in type ''{1}'' has visibility lower than \'protected\', which will result in compile errors if you proceed +PullUpRefactoring.preview=Preparing preview +PullUpRefactoring.calculating_required=Calculating required members +PullUpRefactoring.gets_instantiated=Class ''{0}'' cannot be made abstract because it gets instantiated +PullUpRefactoring.Field_declared_in_class=Field ''{0}'' is declared in class ''{1}''. Pulling it up may result in changed program semantics. +PullUpRefactoring.methodis_declared_in_class=Method ''{0}'' is declared in class ''{1}''. Pulling it up may result in changed program semantics. +PullUpRefactoring.field_cannot_be_accessed=Field ''{0}'' cannot be accessed from ''{1}'' +PullUpRefactoring.method_cannot_be_accessed=Method ''{0}'' cannot be accessed from ''{1}'' +PullUpRefactoring.Type_declared_in_class=Type ''{0}'' is declared in class ''{1}''. Pulling it up may result in changed program semantics. + +MemberCheckUtil.signature_exists=Method ''{0}'' (with the same signature) already exists in type ''{1}'', which will result in compile errors if you proceed +MemberCheckUtil.same_param_count=Method ''{0}'' (with the same number of parameters) already exists in type ''{1}'' +MemberCheckUtil.field_exists=Field ''{0}'' already exists in type ''{1}'', which will result in compile errors if you proceed +MemberCheckUtil.type_name_conflict0=Nested type ''{0}'' already exists in type ''{1}'', which will result in compile errors if you proceed +MemberCheckUtil.type_name_conflict1=Destination type has the same simple name as ''{0}'', which will result in compile errors if you proceed +MemberCheckUtil.type_name_conflict2=Destination type is enclosed in a type that has same simple name as ''{0}'', which will result in compile errors if you proceed +MemberCheckUtil.type_name_conflict3=Destination type has the same simple name as ''{0}'' (enclosed in ''{1}''), which will result in compile errors if you proceed +MemberCheckUtil.type_name_conflict4=Destination type is enclosed in a type that has same simple name as ''{0}'' (enclosed in ''{1}''), which will result in compile errors if you proceed + +ChangeSignatureRefactoring.modify_Parameters=Change Method Signature +ChangeSignatureRefactoring.restructure_parameters=Restructure parameters +ChangeSignatureRefactoring.checking_preconditions=Checking preconditions... +ChangeSignatureRefactoring.method_deleted=The selected method has been deleted from ''{0}'' +ChangeSignatureRefactoring.native=Method ''{0}'' declared in type ''{1}'' is native. Reordering parameters will cause UnsatisfiedLinkError on runtime if you do not update your native libraries +ChangeSignatureRefactoring.duplicate_name=Duplicate parameter name: {0} + +MoveMembersRefactoring.Move_Members=Move Members +MoveMembersRefactoring.compile_errors=Operation can't be performed due to compile errors in ''{0}''. Please fix errors first. +MoveMembersRefactoring.deleteMembers= delete members +MoveMembersRefactoring.addMembers= add members +MoveMembersRefactoring.referenceUpdate= update reference to moved member +MoveMembersRefactoring.Checking_preconditions=Checking preconditions... +MoveMembersRefactoring.static_declaration=Static members can be declared only in top level or static types. +MoveMembersRefactoring.multi_var_fields=Currently, only field declarations with single variable declaration fragments can be moved. +MoveMembersRefactoring.only_public_static_final=Only ''public static final'' fields with variable initializers can be moved to an interface. +MoveMembersRefactoring.Object=Move is not allowed on members declared in 'java.lang.Object'. +MoveMembersRefactoring.binary=Pull up is not allowed on members of binary types. +MoveMembersRefactoring.read_only=Pull up is not allowed on members of read-only types. +MoveMembersRefactoring.move_members=Move members +MoveMembersRefactoring.not_found=Destination type ''{0}'' not be found +MoveMembersRefactoring.same=Destination and source types are the same (''{0}'') +MoveMembersRefactoring.inside=Destination type ''{1}'' is inside moved member''{0}''. +MoveMembersRefactoring.not_exist=Destination type ''{0}'' does not exist +MoveMembersRefactoring.dest_binary=Destination type ''{0}'' is binary +MoveMembersRefactoring.native=Moved method ''{0}'' is native. You will need to update native libraries. +MoveMembersRefactoring.moved_field=In ''{2}'', moved field ''{0}'' will not be visible from ''{1}'' +MoveMembersRefactoring.accessed_field=Accessed field ''{0}'' will not be visible from ''{1}'' +MoveMembersRefactoring.moved_method=In ''{2}'', moved method ''{0}'' will not be visible from ''{2}'' +MoveMembersRefactoring.accessed_method=Accessed method ''{0}'' will not be visible from ''{1}'' +MoveMembersRefactoring.moved_type=In ''{2}'', moved type ''{0}'' will not be visible from ''{2}'' +MoveMembersRefactoring.accessed_type=Accessed type ''{0}'' will not be visible from ''{1}'' + +MoveRefactoring.scanning_qualified_names=Scanning for qualified names in non C files... + +QualifiedNameFinder.update_name=Update fully qualified name + +####################################### +# org.eclipse.jdt.internal.core.refactoring.surround +####################################### + +SurroundWithTryCatchRefactoring.name=Surround with try/catch Block +SurroundWithTryCatchAnalyzer.doesNotCover=Selection does not cover a set of statements. Extend selection to a valid range using the "Expand Selection With" actions from the Edit menu. +SurroundWithTryCatchAnalyzer.doesNotContain=Selection does not contain statements from a method body or static initializer. +SurroundWithTryCatchAnalyzer.noUncaughtExceptions=No uncaught exceptions are thrown by the selected code. +SurroundWithTryCatchAnalyzer.onlyStatements=Only statements can be surrounded with try/catch blocks. +SurroundWithTryCatchAnalyzer.cannotHandleSuper=Cannot surround a super constructor call. +SurroundWithTryCatchAnalyzer.cannotHandleThis=Cannot surround a constructor invocation. +SurroundWithTryCatchAnalyzer.compile_errors=The selected code cannot be analyzed because of compilation errors. To perform this operation you will need to fix the errors. + +####################################### +# org.eclipse.jdt.internal.core.refactoring.util +####################################### + +CommentAnalyzer.internal_error=Internal error during precondition checking. +CommentAnalyzer.ends_inside_comment=Selection ends inside a comment. +CommentAnalyzer.starts_inside_comment=Selection starts inside a comment. + +StatementAnalyzer.doesNotCover= The selection does not cover a set of statements or an expression. Extend selection to a valid range using the "Expand Selection With" actions from the Edit menu. +StatementAnalyzer.beginning_of_selection=The beginning of the selection contains characters that do not belong to a statement. +StatementAnalyzer.end_of_selection=The end of the selection contains characters that do not belong to a statement. +StatementAnalyzer.do_body_expression=Operation not applicable to a do statement's body and expression. +StatementAnalyzer.for_initializer_expression=Operation not applicable to a for statement's initializer and expression part. +StatementAnalyzer.for_expression_updater=Operation not applicable to a for statement's expression and updater part. +StatementAnalyzer.for_updater_body=Operation not applicable to a for statement's updater and body part. +StatementAnalyzer.catch_argument=Operation is not applicable to a catch block's argument declaration. +StatementAnalyzer.while_expression_body=Operation not applicable to a while statement's expression and body. +StatementAnalyzer.try_statement=Selection must either cover whole try statement or parts of try, catch, or finally block. +StatementAnalyzer.switch_statement=Selection must either cover whole switch statement or parts of a single case block. +StatementAnalyzer.synchronized_statement=Selection must either cover whole synchronized statement or parts of the synchronized block. + +CodeAnalyzer.array_initializer=Operation not applicable to an array initializer. +CElementUtil.initializer=initializer + +####################################### +# other +####################################### +CopyResourceString.copy=Copy resource ''{0}'' to ''{1}'' + +RenameAnalyzeUtil.shadows=Problem in ''{0}''. Another name shadows access to the renamed element +CopyRefactoring.update_ref=Update Type Reference +CopyRefactoring.searching=Searching +CompositeChange.performingChangesTask.name=Performing changes... +CodeRefactoringUtil.error.message=The body of the method ''{0}'' cannot be analyzed because of compilation errors in that method. To perform the operation you will need to fix the errors. +InlineTemRefactoring.error.message.nulLiteralsCannotBeInlined=Null literals cannot be inlined +InlineTemRefactoring.error.message.fieldsCannotBeInlined=Cannot inline fields +RenameMethodRefactoring.taskName.checkingPreconditions=Checking preconditions... +RenameMethodRefactoring.taskName.searchingForReferences=Searching for references... + +PushDownRefactoring.name=Push Down +PushDownRefactoring.no_subclasses=Class ''{0}'' does not have any modifiable non-anonymous subclasses to which members could be pushed down +PushDownRefactoring.not_in_saved=One of the selected members does not exist in the saved version of the file +PushDownRefactoring.interface_members=Pushing down interface members is not supported +PushDownRefactoring.members_of_binary=Pushing down members declared in binary types is not supported +PushDownRefactoring.members_of_read-only=Pushing down members declared in read-only types is not supported +PushDownRefactoring.calculating=Calculating required members +PushDownRefactoring.referenced=Pushed down member ''{0}'' is referenced by ''{1}'' +PushDownRefactoring.checking=Checking referenced elements +PushDownRefactoring.type_not_accessible=Type ''{0}'' referenced in one of the pushed elements is not accessible from type ''{1}'' +PushDownRefactoring.field_not_accessible=Field ''{0}'' referenced in one of the pulled elements is not accessible from type ''{1}'' +PushDownRefactoring.method_not_accessible=Method ''{0}'' referenced in one of the pulled elements is not accessible from type ''{1}'' +PushDownRefactoring.gets_instantiated=Class ''{0}'' cannot be made abstract because it gets instantiated +PushDownRefactoring.preview=Creating preview... +PushDownRefactoring.initializer=initializer +PushDownRefactoring.creating_preview=Creating preview... + +ChangeSignatureRefactoring.invalid_return_type=''{0}'' is not a valid return type name +ChangeSignatureRefactoring.default_value=Enter the default value for parameter ''{0}'' +ChangeSignatureRefactoring.invalid_expression=''{0}'' is not a valid expression +ChangeSignatureRefactoring.parameter_type=Enter the type for parameter ''{0}'' +ChangeSignatureRefactoring.invalid_type_name=''{0}'' is not a valid parameter type name +ChangeSignatureRefactoring.unchanged=Method signature and return type are unchanged. +ChangeSignatureRefactoring.parameter_used=Parameter ''{0}'' is used in method ''{1}'' declared in type ''{2}'' +ChangeSignatureRefactoring.anonymous_subclass=anonymous subclass of ''{0}'' +ChangeSignatureRefactoring.non-virtual=Changing visibility to \'private\' will make this method non-virtual, which may affect the program\'s behavior +ChangeSignatureRefactoring.already_has=Method ''{0}'' already has a parameter named ''{1}'' +ChangeSignatureRefactoring.preview=Preparing preview +ChangeSignatureRefactoring.modify_parameters=Modify parameters +ChangeSignatureRefactoring.not_unique=Parameter type name ''{0}'' cannot be uniquely resolved or is not a valid type name. +ChangeSignatureRefactoring.ambiguous=Parameter type name ''{0}'' is ambiguous. There are {1} types with that name. + +MoveInnerToTopRefactoring.names_start_lowercase=This name is discouraged. According to convention, names of instance fields and local variables start with lowercase letters. +MoveInnerToTopRefactoring.already_declared=A field named ''{0}'' is already declared in type ''{1}'' +MoveInnerToTopRefactoring.deleted=The selected type has been deleted from ''{0}'' +MoveInnerToTopRefactoring.compilation_Unit_exists=Compilation Unit named ''{0}'' already exists in package ''{1}'' +MoveInnerToTopRefactoring.name_used=Name ''{0}'' is used as a parameter name in one of the constructors of type ''{1}'' +MoveInnerToTopRefactoring.name=Move Member Type to New File +MoveInnerToTopRefactoring.creating_preview=Creating change +MoveInnerToTopRefactoring.move_to_Top=Move Member Type to New File +MoveInnerToTopRefactoring.type_exists=Type named ''{0}'' already exists in package ''{1}'' + +InstanceMethodMover.move_method=Move instance method +InstanceMethodMover.replace_with_delegation=Replace method body with delegation. +InstanceMethodMover.create_in_receiver=Create method in new receiver\'s class. +InstanceMethodMover.add_imports=Add needed imports for created method +InstanceMethodMover.to_local_localunsupported=Moving to within local classes is currently unsupported. +InstanceMethodMover.parameter_name_used=Parameter name ''{0}'' is already used +InstanceMethodMover.no_static_methods=This refactoring cannot be used to move static methods. +InstanceMethodMover.single_implementation=Select a single method implementation to move. +InstanceMethodMover.no_native_methods=This refactoring cannot be used to move native methods. +InstanceMethodMover.no_synchronized_methods=This refactoring cannot be used to move synchronized methods. +InstanceMethodMover.no_constructors=This refactoring cannot be used to move a constructor. +InstanceMethodMover.uses_super=The method cannot be moved, since it uses the \"super\" keyword. +InstanceMethodMover.refers_enclosing_instances=The method cannot be moved, since it refers to enclosing instances (i.e. .this). +InstanceMethodMover.potentially_recursive=This refactoring cannot be used to move potentially recursive methods. +InstanceMethodMover.cannot_be_moved=This method cannot be moved, since no possible new receivers were found. An instance method can be moved to source classes that are used as types of its parameters or types of fields declared in the same class as the method. + +ExtractInterfaceUtil.update_reference=Update type reference +ExtractInterfaceUtil.update_imports=Update imports + +ExtractInterfaceRefactoring.deleted=The selected type has been deleted from ''{0}'' +ExtractInterfaceRefactoring.no_Throwable=Extract Interface refactoring is not available on \"java.lang.Throwable\" and its subclasses. +ExtractInterfaceRefactoring.type_exists=Type named ''{0}'' already exists in package ''{1}'' +ExtractInterfaceRefactoring.compilation_Unit_exists=Compilation Unit named ''{0}'' already exists in package ''{1}'' +ExtractInterfaceRefactoring.internal_Error=Internal Error. Please see log for details. +ExtractInterfaceRefactoring.name=Extract Interface +ExtractInterfaceRefactoring.analyzing...=Analyzing... +ExtractInterfaceRefactoring.update_reference=Update type reference +ExtractInterfaceRefactoring.update_type_declaration=Update type declaration + +UseSupertypeWherePossibleRefactoring.deleted=The selected type has been deleted from ''{0}'' +UseSupertypeWherePossibleRefactoring.unavailable_on_Throwable=Use Supertype Where Possible refactoring is not available on \"java.lang.Throwable\" and its subclasses. +UseSupertypeWherePossibleRefactoring.name=Use Supertype Where Possible +UseSupertypeWherePossibleRefactoring.analyzing...=Analyzing... + +MoveInstanceMethodRefactoring.method_declaration=A method declaration must be selected in order to activate this refactoring. +MoveInstanceMethodRefactoring.name=Move Instance Method + +CopyPackageFragmentRootChange.copy=Copy Package Fragment Root ''{0}'' to project ''{1}'' + +DeletePackageFragmentRootChange.delete=Delete package fragment root ''{0}'' + +MovePackageFragmentRootChange.move=Move Package Fragment Root ''{0}'' to project ''{1}'' + +PromoteTempToFieldRefactoring.name=Promote Local Variable to Field +PromoteTempToFieldRefactoring.select_declaration=Select a declaration or a reference to a local variable. +PromoteTempToFieldRefactoring.only_declared_in_methods=Currently, only local variables declared in methods can be converted to fields. +PromoteTempToFieldRefactoring.method_parameters=Cannot convert method parameters to fields. +PromoteTempToFieldRefactoring.exceptions=Cannot convert exceptions declared in catch clauses to fields. +PromoteTempToFieldRefactoring.uses_types_declared_locally=Cannot promote this local variable to a field because it uses types or variables declared locally in the method. +PromoteTempToFieldRefactoring.cannot_promote=Cannot promote this local variable to a field. +PromoteTempToFieldRefactoring.uses_type_declared_locally=Cannot promote this local variable to a field because it uses a type declared locally in the method. +PromoteTempToFieldRefactoring.Name_conflict=Name conflict with name ''{0}'' used in ''{1}'' +PromoteTempToFieldRefactoring.Name_conflict_with_field=Name conflict with existing field +PromoteTempToFieldRefactoring.editName=Promote local variable to field + +ConvertAnonymousToNestedRefactoring.name=Convert Anonymous to Inner +ConvertAnonymousToNestedRefactoring.place_caret=Place the caret inside an anonymous inner class. +ConvertAnonymousToNestedRefactoring.type_exists=Nested type with that name already exists. +ConvertAnonymousToNestedRefactoring.another_name=Choose another name. +ConvertAnonymousToNestedRefactoring.name_hides=Class name hides an enclosing type name. +ConvertAnonymousToNestedRefactoring.edit_name=Convert anonymous inner class to a nested class + +InlineConstantRefactoring.members_declared_in_anonymous=Cannot inline since the initializer to be inlined refers to members declared in an anonymous class scope (currently unsupported). +InlineConstantRefactoring.Inline=Inline Constant +InlineConstantRefactoring.syntax_errors=This file contains syntax errors. To perform this operation you will need to fix the errors. +InlineConstantRefactoring.local_anonymous_unsupported=Inlining of constants defined in local or anonymous classes is currently not supported. +InlineConstantRefactoring.static_final_field=A static final field must be selected. +InlineConstantRefactoring.blank_finals=Inline Constant cannot inline blank finals. +InlineConstantRefactoring.binary_file=Cannot inline this constant, since it is declared in a binary file. +InlineConstantRefactoring.preview=Generating preview ... +InlineConstantRefactoring.inline=Inline Constant +InlineConstantRefactoring.remove_declaration=Remove constant declaration +InlineConstantRefactoring.name=Inline Constant +InlineConstantRefactoring.source_code_unavailable=References in ''{0}'' cannot be inlined since source code is not available + +DeleteFileChange.1=Delete file ''{0}'' + +DeleteFolderChange.0=Delete folder ''{0}'' + +DeleteSourceManipulationChange.0=Delete ''{0}'' +DeleteSourceManipulationChange.1=(default package) + +CopyRefactoring.0=Copy + +MoveRefactoring.0=Move + +OverwriteHelper.0=Confirm overwritting +OverwriteHelper.1=''{0}'' exists in the selected destination. Do you want to overwrite? + +ReadOnlyResourceFinder.0=Confirm Delete of Read Only Elements +ReadOnlyResourceFinder.1=The selected elements contain read-only resources. Do you still want to delete them? +ReadOnlyResourceFinder.2=Confirm Move of Read Only Elements +ReadOnlyResourceFinder.3=The selected elements contain read-only resources. Do you still want to move them? + +ChangeSignatureRefactoring.new_parameter=Enter the type for the new parameter + +MoveInnerToTopRefactoring.29=Creating preview +MoveInnerToTopRefactoring.30=convert nested type to top level +MoveInstanceMethodRefactoring.2=The selected method cannot be moved + +PullUpRefactoring.42=Pull up + +PushDownRefactoring.25=Push down + +ReorgPolicyFactory.doesnotexist0=The selected element cannot be the destination of this operation +ReorgPolicyFactory.readonly=The selected destination is read-only +ReorgPolicyFactory.structure=The structure of the selected destination is not known +ReorgPolicyFactory.inconsistent=The selected destination is not consistent with its underlying resource or buffer +ReorgPolicyFactory.archive=The selected destination is an archive +ReorgPolicyFactory.external=The selected destination is external to the workbench +ReorgPolicyFactory.subCu=Elements inside translation units cannot be used as destinations for copying files, folders or translation units +ReorgPolicyFactory.phantom=The selected destination does not exist or is a phantom resource +ReorgPolicyFactory.inaccessible=The selected destination is not accessible +ReorgPolicyFactory.not_this_resource=The selected resource cannot be used as a destination +ReorgPolicyFactory.linked=Linked resources can only be copied to projects +ReorgPolicyFactory.no_resource=A resource cannot be the destination for the selected elements. +ReorgPolicyFactory.copy=Copy +ReorgPolicyFactory.doesnotexist1=The selected element cannot be the destination for this operation +ReorgPolicyFactory.cannot_modify=The selected destination element cannot be modified +ReorgPolicyFactory.cannot=The selected element cannot be the destination for this operation +ReorgPolicyFactory.package_decl=Package declarations are not available as destinations +ReorgPolicyFactory.src2proj=Source folders can only be copied to C projects +ReorgPolicyFactory.jmodel=The C Model cannot be the destination of this operation +ReorgPolicyFactory.src2writable=Source folders cannot be copied to read-only elements +ReorgPolicyFactory.src2nosrc=Source folders cannot be copied or moved to projects that contain no source folders +ReorgPolicyFactory.packages=Packages can only be moved or copied to source folders or C projects that do not have source folders +ReorgPolicyFactory.cannot1=The selected element cannot be the destination of this operation +ReorgPolicyFactory.noCopying=Copying is not available +ReorgPolicyFactory.element2parent=Elements cannot be moved to their own parents. +ReorgPolicyFactory.package2parent=A package cannot be moved to its own parent. +ReorgPolicyFactory.parent=A file or folder cannot be moved to its own parent. +ReorgPolicyFactory.noMoving=Moving is not available + +ReorgUtils.0=file ''{0}'' +ReorgUtils.1=folder ''{0}'' +ReorgUtils.2=project ''{0}'' +ReorgUtils.3=class file ''{0}'' +ReorgUtils.4=file ''{0}'' +ReorgUtils.5=field ''{0}'' +ReorgUtils.6=the import container +ReorgUtils.7=import declaration ''{0}'' +ReorgUtils.8=the initializer +ReorgUtils.9=C project ''{0}'' +ReorgUtils.10=constructor ''{0}'' +ReorgUtils.11=method ''{0}'' +ReorgUtils.12=package declaration ''{0}'' +ReorgUtils.13=the default package +ReorgUtils.14=package ''{0}'' +ReorgUtils.15=source folder ''{0}'' +ReorgUtils.16=class folder ''{0}'' +ReorgUtils.17=package fragment root ''{0}'' +ReorgUtils.18=type ''{0}'' +ReorgUtils.19=new {0}() '{...'} +ReorgUtils.20=anonymous type ''{0}'' +DeleteChangeCreator.1=Delete elements +DeleteRefactoring.1=Analyzing... +DeleteRefactoring.2=Confirm Referenced Archive Delete +DeleteRefactoring.3=Archive file ''{0}'' is referenced by the following project(s). Do you still want to delete it? +DeleteRefactoring.4=Confirm Folder Delete +DeleteRefactoring.5=Folder ''{0}'' contains a C source folder. Deleting it will delete the source folder as well. Do you still wish to delete it? +DeleteRefactoring.7=Delete +DeleteRefactoring.8=Confirm Delete of Getters/Setters +DeleteRefactoring.9=Do you also want to delete getter/setter methods for field ''{0}''? +MoveStaticMemberAnalyzer.nonStatic=Replacing non-static access to static member with static access + +# +# Introduce Factory +IntroduceFactory.name=Introduce Factory +IntroduceFactory.checkingActivation=Checking activation of IntroduceFactory +IntroduceFactory.syntax_error=Introduce Factory cannot be performed due to syntax errors. +IntroduceFactory.checking_preconditions=Checking preconditions for Introduce Factory... +IntroduceFactory.examiningSelection=Examining selection... +IntroduceFactory.notAConstructorInvocation=Selected entity is not a constructor invocation or definition\! +# +IntroduceFactory.noASTNodeForConstructorSearchHit=Can\'t find AST node for constructor search hit @ [''{0}'', ''{1}'']: <''{2}''> in translation unit ''{3}'' +IntroduceFactory.unexpectedInitializerNodeType=Unexpected AST node type for initializer when searching for constructor call: \'''{0}''\' in translation unit ''{1}'' +IntroduceFactory.noConstructorCallNodeInsideFoundVarbleDecl=Couldn\'t find AST node for constructor call inside ''{0}'' +IntroduceFactory.unexpectedASTNodeTypeForConstructorSearchHit=Unexpected AST node type for constructor search hit: ''{0}'' in translation unit ''{1}'' +IntroduceFactory.noBindingForSelectedConstructor=Couldn\'t resolve binding of selected constructor; perhaps a reference to an unknown type. +# +IntroduceFactory.addFactoryMethod=Add factory method +IntroduceFactory.replaceCalls=Replace constructor calls with calls to factory method +IntroduceFactory.protectConstructor=Protect constructor +# +IntroduceFactory.unsupportedNestedTypes=Introduce Factory does not support constructors on nested types. +IntroduceFactory.duplicateMethodName=Duplicate method name: +IntroduceFactory.createChanges=Creating changes for IntroduceFactory +IntroduceFactory.topLevelChangeLabel=Changes to introduce factory for +IntroduceFactory.constructorInBinaryClass=Introduce Factory is not supported when the constructor is in a binary class. +IntroduceFactory.unableToResolveConstructorBinding=Unable to resolve call target; perhaps there are compilation errors? +IntroduceFactory.callSitesInBinaryClass=Constructor call sites in binary classes can not be replaced by factory method calls. +# +# Generalize Type +ChangeTypeRefactoring.Generalize_Type=Generalize Type +ChangeTypeRefactoring.checking_preconditions=Checking preconditions... +ChangeTypeRefactoring.changes=Computing changes +ChangeTypeRefactoring.name=Generalize Type +ChangeTypeRefactoring.cantDoIt=Type of selected declaration cannot be changed +ChangeTypeRefactoring.notSupportedOnNodeType=Generalize Type is only supported on declarations of variables, parameters, and fields, and on method return types. +ChangeTypeRefactoring.notSupportedOnBinary=Generalize Type is not allowed on return types and parameters of methods that override binary methods. +ChangeTypeRefactoring.invalidSelection=Invalid selection for Generalize Type. +ChangeTypeRefactoring.multiDeclarationsNotSupported=Multi-declarations currently not handled. +ChangeTypeRefactoring.noMatchingConstraintVariable=No constraint variable matches the selected ASTNode. +ChangeTypeRefactoring.unhandledSearchException=exception occurred during search: +ChangeTypeRefactoring.failedToSelectType=failed to select type: +ChangeTypeMessages.CreateChangesForChangeType=Creating changes for Generalize Type... +ChangeTypeRefactoring.javaLangObject=java.lang.Object +ChangeTypeRefactoring.arraysNotSupported=Generalize Type is currently not supported on array types. +ChangeTypeRefactoring.localTypesNotSupported=Generalize Type is currently not supported on local types. +ChangeTypeRefactoring.primitivesNotSupported=Generalize Type is not supported on primitive types. +ChangeTypeRefactoring.typeChange=change declared type from +ChangeTypeRefactoring.allChanges=All changes needed for Generalize Type +ChangeTypeRefactoring.to=\ to +ChangeTypeRefactoring.analyzingMessage=Analyzing... diff --git a/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/rename/RenameElementProcessor.java b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/rename/RenameElementProcessor.java new file mode 100644 index 00000000000..85a08f8838d --- /dev/null +++ b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/corext/refactoring/rename/RenameElementProcessor.java @@ -0,0 +1,409 @@ +/********************************************************************** + * Copyright (c) 2004 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.internal.corext.refactoring.rename; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.eclipse.cdt.core.model.CoreModel; +import org.eclipse.cdt.core.model.ICElement; +import org.eclipse.cdt.core.model.IEnumeration; +import org.eclipse.cdt.core.model.IField; +import org.eclipse.cdt.core.model.IFunction; +import org.eclipse.cdt.core.model.IFunctionDeclaration; +import org.eclipse.cdt.core.model.IMethod; +import org.eclipse.cdt.core.model.IMethodDeclaration; +import org.eclipse.cdt.core.model.INamespace; +import org.eclipse.cdt.core.model.ISourceReference; +import org.eclipse.cdt.core.model.IStructure; +import org.eclipse.cdt.core.model.ITranslationUnit; +import org.eclipse.cdt.core.model.IVariable; +import org.eclipse.cdt.core.search.BasicSearchMatch; +import org.eclipse.cdt.core.search.ICSearchConstants; +import org.eclipse.cdt.core.search.ICSearchScope; +import org.eclipse.cdt.core.search.OrPattern; +import org.eclipse.cdt.core.search.SearchEngine; +import org.eclipse.cdt.internal.core.model.CElement; +import org.eclipse.cdt.internal.corext.Assert; +import org.eclipse.cdt.internal.corext.refactoring.Checks; +import org.eclipse.cdt.internal.corext.refactoring.CompositeChange; +import org.eclipse.cdt.internal.corext.refactoring.IReferenceUpdating; +import org.eclipse.cdt.internal.corext.refactoring.RefactoringCoreMessages; +import org.eclipse.cdt.internal.corext.refactoring.RefactoringSearchEngine; +import org.eclipse.cdt.internal.corext.refactoring.RenameProcessor; +import org.eclipse.cdt.internal.corext.refactoring.ResourceUtil; +import org.eclipse.cdt.internal.corext.refactoring.SearchResultGroup; +import org.eclipse.cdt.internal.corext.refactoring.TextChangeManager; +import org.eclipse.cdt.internal.corext.refactoring.base.IChange; +import org.eclipse.cdt.internal.corext.refactoring.base.RefactoringStatus; +import org.eclipse.cdt.internal.corext.util.CModelUtil; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.OperationCanceledException; +import org.eclipse.core.runtime.SubProgressMonitor; +import org.eclipse.text.edits.ReplaceEdit; + +public class RenameElementProcessor extends RenameProcessor implements IReferenceUpdating{ + private ICElement fCElement = null; + private SearchResultGroup[] fReferences; + private TextChangeManager fChangeManager; + private final String QUALIFIER = "::"; + + private boolean fUpdateReferences; + + public ICElement getCElement() { + return fCElement; + } + + //---- IRefactoringProcessor --------------------------------------------------- + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.corext.refactoring.IRefactoringProcessor#initialize(java.lang.Object[]) + */ + public void initialize(Object[] elements) throws CoreException { + Assert.isTrue(elements != null && elements.length == 1); + Object element= elements[0]; + if(element == null) + return; + if (!(element instanceof ISourceReference)) + return; + fCElement= (ICElement)element; + setNewElementName(fCElement.getElementName()); + fUpdateReferences= true; //default is yes + + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.corext.refactoring.IRefactoringProcessor#isAvailable() + */ + public boolean isAvailable() throws CoreException { + if (fCElement == null) + return false; + if (!(fCElement instanceof ISourceReference)) + return false; + if (! Checks.isAvailable(fCElement)) + return false; + return true; + } + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.corext.refactoring.IRefactoringProcessor#getProcessorName() + */ + public String getProcessorName() { + return RefactoringCoreMessages.getFormattedString( + "RenameTypeRefactoring.name", //$NON-NLS-1$ + new String[]{fCElement.getElementName(), fNewElementName}); + } + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.corext.refactoring.IRefactoringProcessor#getElements() + */ + public Object[] getElements() { + return new Object[] {fCElement}; + } + + //---- IRenameProcessor ---------------------------------------------- + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.corext.refactoring.IRenameProcessor#getCurrentElementName() + */ + public String getCurrentElementName() { + if(fCElement == null) + return ""; + String name = fCElement.getElementName(); + if (name.indexOf(QUALIFIER) != -1){ + return (name.substring(name.lastIndexOf(QUALIFIER) + 2, name.length())); + } + return name; + } + + public int getCurrentElementNameLength() { + if(fCElement == null) + return 0; + String name = fCElement.getElementName(); + if (name.indexOf(QUALIFIER) != -1){ + String unQualifiedName =name.substring(name.lastIndexOf(QUALIFIER) + 2, name.length()); + return (unQualifiedName.length()); + } + return name.length(); + } + + public int getCurrentElementNameStartPos() { + if(fCElement == null) + return 0; + String name = fCElement.getElementName(); + if (name.indexOf(QUALIFIER) != -1){ + return (((CElement)fCElement).getIdStartPos() + name.lastIndexOf(QUALIFIER) + 2); + } + return ((CElement)fCElement).getIdStartPos(); + } + + public RefactoringStatus checkNewElementName(String newName){ + if ((fCElement == null) || (!(fCElement instanceof ISourceReference)) || (fCElement instanceof ITranslationUnit)) { + return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.getString("RenameTypeRefactoring.wrong_element")); + } + + Assert.isNotNull(newName, "new name"); //$NON-NLS-1$ + RefactoringStatus result= null; + if (fCElement instanceof IStructure){ + result= Checks.checkClassName(newName); + } + else if (fCElement instanceof IMethodDeclaration) { + result= Checks.checkMethodName(newName); + } + else if (fCElement instanceof IField){ + result= Checks.checkFieldName(newName); + } + else { + result = Checks.checkIdentifier(newName); + } + + if (Checks.isAlreadyNamed(fCElement, newName)) + result.addFatalError(RefactoringCoreMessages.getString("RenameTypeRefactoring.choose_another_name")); //$NON-NLS-1$ + return result; + } + //---- IReferenceUpdating -------------------------------------- + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.corext.refactoring.IReferenceUpdating#canEnableUpdateReferences() + */ + public boolean canEnableUpdateReferences() { + return true; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.corext.refactoring.IReferenceUpdating#getUpdateReferences() + */ + public boolean getUpdateReferences() { + return fUpdateReferences; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.corext.refactoring.IReferenceUpdating#setUpdateReferences(boolean) + */ + public void setUpdateReferences(boolean update){ + fUpdateReferences= update; + } + //------------------------------------------ + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.corext.refactoring.ITextUpdating#canEnableTextUpdating() + */ + public boolean canEnableTextUpdating() { + return false; + } + + + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.corext.refactoring.IRefactoringProcessor#checkActivation() + */ + public RefactoringStatus checkActivation() throws CoreException { + RefactoringStatus result= null; + if ((fCElement == null) || (!(fCElement instanceof ISourceReference)) || (fCElement instanceof ITranslationUnit)) { + return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.getString("RenameTypeRefactoring.wrong_element")); + } + return Checks.checkIfTuBroken(fCElement); + + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.corext.refactoring.IRefactoringProcessor#checkInput(org.eclipse.core.runtime.IProgressMonitor) + */ + public RefactoringStatus checkInput(IProgressMonitor pm) + throws CoreException { + Assert.isNotNull(fCElement, "type"); //$NON-NLS-1$ + Assert.isNotNull(fNewElementName, "newName"); //$NON-NLS-1$ + RefactoringStatus result= new RefactoringStatus(); + try{ + pm.beginTask("", 20); //$NON-NLS-1$ + pm.setTaskName(RefactoringCoreMessages.getString("RenameTypeRefactoring.checking"));//$NON-NLS-1$ + result.merge(checkNewElementName(fNewElementName)); + + if (result.hasFatalError()) + return result; + pm.worked(5); + + fReferences= null; + if (fUpdateReferences){ + pm.setTaskName(RefactoringCoreMessages.getString("RenameTypeRefactoring.searching")); //$NON-NLS-1$ + fReferences= getReferences(fCElement.getElementName(), new SubProgressMonitor(pm, 35)); + } + pm.worked(10); + + pm.setTaskName(RefactoringCoreMessages.getString("RenameTypeRefactoring.checking")); //$NON-NLS-1$ + if (pm.isCanceled()) + throw new OperationCanceledException(); + + if (result.hasFatalError()) + return result; + // more checks go here + fChangeManager= createChangeManager(new SubProgressMonitor(pm, 35)); + pm.worked(5); + + return result; + } finally { + pm.done(); + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.corext.refactoring.IRefactoringProcessor#createChange(org.eclipse.core.runtime.IProgressMonitor) + */ + public IChange createChange(IProgressMonitor pm) throws CoreException { + pm.beginTask(RefactoringCoreMessages.getString("RenameTypeRefactoring.creating_change"), 4); //$NON-NLS-1$ + CompositeChange builder= new CompositeChange( + RefactoringCoreMessages.getString("Change.javaChanges")); //$NON-NLS-1$ + builder.addAll(fChangeManager.getAllChanges()); + pm.worked(1); + return builder; + } + + private IFile[] getAllFilesToModify() throws CoreException { + List result= new ArrayList(); + result.addAll(Arrays.asList(ResourceUtil.getFiles(fChangeManager.getAllTranslationUnits()))); + return (IFile[]) result.toArray(new IFile[result.size()]); + } + + private TextChangeManager createChangeManager(IProgressMonitor pm) throws CoreException { + try{ + pm.beginTask("", 7); //$NON-NLS-1$ + TextChangeManager manager= new TextChangeManager(); + + if (fUpdateReferences) + addReferenceUpdates(manager, new SubProgressMonitor(pm, 3)); + + pm.worked(1); + + addTypeDeclarationUpdate(manager); + pm.worked(1); + + return manager; + } finally{ + pm.done(); + } + } + + private void addReferenceUpdates(TextChangeManager manager, IProgressMonitor pm) throws CoreException { + pm.beginTask("", fReferences.length); //$NON-NLS-1$ + for (int i= 0; i < fReferences.length; i++){ + IResource res= fReferences[i].getResultGroupResource(); + if (res == null) + continue; + ITranslationUnit cu= (ITranslationUnit) CoreModel.getDefault().create(res); + if (cu == null) + continue; + + ITranslationUnit tu = CModelUtil.toWorkingCopy(cu); + + if((tu == null) || (!( tu instanceof ITranslationUnit))) + return; + ITranslationUnit wc = (ITranslationUnit)tu; + String name= RefactoringCoreMessages.getString("RenameTypeRefactoring.update_reference"); //$NON-NLS-1$ + BasicSearchMatch[] results= fReferences[i].getSearchResults(); + + for (int j= 0; j < results.length; j++){ + BasicSearchMatch searchResult= results[j]; + int oldNameLength = getCurrentElementNameLength(); + int offset= searchResult.getEndOffset() - oldNameLength; + manager.get(wc).addTextEdit(name, + new ReplaceEdit(offset, oldNameLength, fNewElementName)); + } + pm.worked(1); + } + } + + private void addTypeDeclarationUpdate(TextChangeManager manager) throws CoreException { + String name= RefactoringCoreMessages.getString("RenameTypeRefactoring.update"); //$NON-NLS-1$ + if(fCElement instanceof ISourceReference){ + ITranslationUnit cu= ((ISourceReference)fCElement).getTranslationUnit(); // WorkingCopyUtil.getWorkingCopyIfExists(fCElement.getTranslationUnit()); + manager.get(cu).addTextEdit(name, new ReplaceEdit(getCurrentElementNameStartPos(), getCurrentElementNameLength(), fNewElementName)); + } + } + + private SearchResultGroup[] getReferences(String searchPrefix, IProgressMonitor pm) throws CoreException { + return RefactoringSearchEngine.search(pm, createRefactoringScope(), createSearchPattern(searchPrefix)); + } + + private ICSearchScope createRefactoringScope() throws CoreException { + return SearchEngine.createWorkspaceScope(); + } + + private OrPattern createSearchPattern(String searchPrefix) throws CoreException { + OrPattern orPattern = new OrPattern(); + if(fCElement instanceof IStructure){ + orPattern.addPattern(SearchEngine.createSearchPattern( searchPrefix, + ICSearchConstants.TYPE, ICSearchConstants.REFERENCES, false )); + IStructure structure = (IStructure) fCElement; + if(structure.getElementType() == ICElement.C_CLASS){ + orPattern.addPattern(SearchEngine.createSearchPattern( searchPrefix, + ICSearchConstants.METHOD, ICSearchConstants.ALL_OCCURRENCES, false )); + orPattern.addPattern(SearchEngine.createSearchPattern( "~"+ searchPrefix, + ICSearchConstants.METHOD, ICSearchConstants.ALL_OCCURRENCES, false )); + } + } + else if(fCElement instanceof IMethod){ + // The inline declaration is the same as the definition + // we don't need to search for the declaration if it is inline + ICElement parent = fCElement.getParent(); + if( (!(((IMethod)fCElement).isInline())) && (!(parent instanceof IStructure )) ) { + orPattern.addPattern(SearchEngine.createSearchPattern( searchPrefix, + ICSearchConstants.METHOD, ICSearchConstants.DECLARATIONS, false )); + } + orPattern.addPattern(SearchEngine.createSearchPattern( searchPrefix, + ICSearchConstants.METHOD, ICSearchConstants.REFERENCES, false )); + } + else if(fCElement instanceof IMethodDeclaration){ + orPattern.addPattern(SearchEngine.createSearchPattern( searchPrefix, + ICSearchConstants.METHOD, ICSearchConstants.DEFINITIONS, false )); + orPattern.addPattern(SearchEngine.createSearchPattern( searchPrefix, + ICSearchConstants.METHOD, ICSearchConstants.REFERENCES, false )); + } + else if(fCElement instanceof IFunction){ + orPattern.addPattern(SearchEngine.createSearchPattern( searchPrefix, + ICSearchConstants.FUNCTION, ICSearchConstants.DECLARATIONS, false )); + orPattern.addPattern(SearchEngine.createSearchPattern( searchPrefix, + ICSearchConstants.FUNCTION, ICSearchConstants.REFERENCES, false )); + orPattern.addPattern(SearchEngine.createSearchPattern( searchPrefix, + ICSearchConstants.METHOD, ICSearchConstants.DECLARATIONS, false )); + orPattern.addPattern(SearchEngine.createSearchPattern( searchPrefix, + ICSearchConstants.METHOD, ICSearchConstants.REFERENCES, false )); + } + else if(fCElement instanceof IFunctionDeclaration){ + orPattern.addPattern(SearchEngine.createSearchPattern( searchPrefix, + ICSearchConstants.FUNCTION, ICSearchConstants.DEFINITIONS, false )); + orPattern.addPattern(SearchEngine.createSearchPattern( searchPrefix, + ICSearchConstants.FUNCTION, ICSearchConstants.REFERENCES, false )); + } + else if(fCElement instanceof IField){ + orPattern.addPattern(SearchEngine.createSearchPattern( searchPrefix, + ICSearchConstants.FIELD, ICSearchConstants.REFERENCES, false )); + } + else if(fCElement instanceof IVariable){ + orPattern.addPattern(SearchEngine.createSearchPattern( searchPrefix, + ICSearchConstants.VAR, ICSearchConstants.REFERENCES, false )); + } + else if(fCElement instanceof INamespace){ + orPattern.addPattern(SearchEngine.createSearchPattern( searchPrefix, + ICSearchConstants.NAMESPACE, ICSearchConstants.REFERENCES, false )); + } + else if(fCElement instanceof IEnumeration){ + orPattern.addPattern(SearchEngine.createSearchPattern( searchPrefix, + ICSearchConstants.ENUM, ICSearchConstants.REFERENCES, false )); + } + else { + orPattern.addPattern(SearchEngine.createSearchPattern( searchPrefix, + ICSearchConstants.UNKNOWN_SEARCH_FOR, ICSearchConstants.REFERENCES, false )); + } + return orPattern; + } + +} diff --git a/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/AbortChangeExceptionHandler.java b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/AbortChangeExceptionHandler.java new file mode 100644 index 00000000000..c2d30763949 --- /dev/null +++ b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/AbortChangeExceptionHandler.java @@ -0,0 +1,30 @@ +/********************************************************************** + * Copyright (c) 2004 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation +***********************************************************************/ + +package org.eclipse.cdt.internal.ui.refactoring; + +import org.eclipse.cdt.internal.corext.refactoring.base.ChangeAbortException; +import org.eclipse.cdt.internal.corext.refactoring.base.ChangeContext; +import org.eclipse.cdt.internal.corext.refactoring.base.IChange; +import org.eclipse.cdt.internal.corext.refactoring.base.IChangeExceptionHandler; +import org.eclipse.cdt.ui.CUIPlugin; + +/** + * A default implementation of IChangeExceptionHandler which + * always aborts an change if an exception is caught. + */ +public class AbortChangeExceptionHandler implements IChangeExceptionHandler { + + public void handle(ChangeContext context, IChange change, Exception e) { + CUIPlugin.getDefault().log(e); + throw new ChangeAbortException(e); + } +} diff --git a/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/ChangeElement.java b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/ChangeElement.java new file mode 100644 index 00000000000..1f766688869 --- /dev/null +++ b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/ChangeElement.java @@ -0,0 +1,94 @@ +/********************************************************************** + * Copyright (c) 2004 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.internal.ui.refactoring; + +import org.eclipse.core.runtime.CoreException; + +/** + * Instances of ChangeElement are used to present + * IChange object as nodes in a tree. + */ +abstract class ChangeElement { + + /** Flag indicating that the change element isn't active */ + public final static int INACTIVE= 0; + /** Flag indicating that the change element is partly active (some children are inactive) */ + public final static int PARTLY_ACTIVE= 1; + /** Flage indicating that the change element is active */ + public final static int ACTIVE= 2; + + protected final static int[][] ACTIVATION_TABLE= new int[][] { + /*INACTIVE*/ /*PARTLY_ACTIVE */ /*ACTIVE */ + /* INACTIVE */ { INACTIVE, PARTLY_ACTIVE, PARTLY_ACTIVE }, + /* PARTLY_ACTIVE*/{ PARTLY_ACTIVE, PARTLY_ACTIVE, PARTLY_ACTIVE }, + /* ACTIVE */ { PARTLY_ACTIVE, PARTLY_ACTIVE, ACTIVE} + }; + + protected static final ChangeElement[] EMPTY_CHILDREN= new ChangeElement[0]; + + private ChangeElement fParent; + + /** + * Creates a new ChangeElement with the + * given parent + * + * @param parent the change element's parent or null + * if the change element doesn't have a parent + */ + public ChangeElement(ChangeElement parent) { + fParent= parent; + } + + /** + * Returns the change element's parent. + * + * @return the change element's parent + */ + public ChangeElement getParent() { + return fParent; + } + + /** + * Returns the viewer used to present a preview of this change element + * + * @return the viewer suitable to present a preview of this change or + * null if no previewer is configured. + */ +// public abstract ChangePreviewViewerDescriptor getChangePreviewViewer() throws CoreException; + + public abstract void feedInput(IChangePreviewViewer viewer) throws CoreException; + + /** + * Sets the activation status for this ChangeElement. When a + * change element is not active, then executing it is expected to do nothing. + * + * @param active the activation status for this change element + */ + public abstract void setActive(boolean active); + + /** + * Returns the activation status of this ChangeElement. + * Returns one of the following values: IChange.ACTIVE + * if the node and all its children are active, IChange.INACTIVE + * if all children and the node itself is inactive, and IChange.PARTLy_ACTIVE + * otherwise. + * + * @return the change element's activation status. + */ + public abstract int getActive(); + + /** + * Returns the change element's children. + * + * @return the change element's children. + */ + public abstract ChangeElement[] getChildren(); +} diff --git a/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/ChangeElementContentProvider.java b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/ChangeElementContentProvider.java new file mode 100644 index 00000000000..541a1f132f5 --- /dev/null +++ b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/ChangeElementContentProvider.java @@ -0,0 +1,231 @@ +/********************************************************************** + * Copyright (c) 2004 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.internal.ui.refactoring; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; +import java.util.Map; + +import org.eclipse.cdt.core.model.CModelException; +import org.eclipse.cdt.core.model.ICElement; +import org.eclipse.cdt.core.model.IParent; +import org.eclipse.cdt.core.model.ISourceRange; +import org.eclipse.cdt.core.model.ISourceReference; +import org.eclipse.cdt.core.model.ITranslationUnit; +import org.eclipse.cdt.internal.corext.refactoring.base.IChange; +import org.eclipse.cdt.internal.corext.refactoring.base.ICompositeChange; +import org.eclipse.cdt.internal.corext.refactoring.changes.TextChange; +import org.eclipse.cdt.internal.corext.refactoring.changes.TextChange.EditChange; +import org.eclipse.jface.text.IRegion; +import org.eclipse.jface.text.Region; +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.Viewer; + +/** + * A default content provider to present a hierarchy of IChange + * objects in a tree viewer. + */ +class ChangeElementContentProvider implements ITreeContentProvider { + + private static final ChangeElement[] EMPTY_CHILDREN= new ChangeElement[0]; + + private static class OffsetComparator implements Comparator { + public int compare(Object o1, Object o2) { + EditChange c1= (EditChange)o1; + EditChange c2= (EditChange)o2; + int p1= getOffset(c1); + int p2= getOffset(c2); + if (p1 < p2) + return -1; + if (p1 > p2) + return 1; + // same offset + return 0; + } + private int getOffset(EditChange edit) { + return edit.getTextRange().getOffset(); + } + } + + /* non Java-doc + * @see ITreeContentProvider#inputChanged + */ + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + // do nothing + } + + /* non Java-doc + * @see ITreeContentProvider#getChildren + */ + public Object[] getChildren(Object o) { + ChangeElement element= (ChangeElement)o; + ChangeElement[] children= element.getChildren(); + if (children == null) { + children= createChildren(element); + } + return children; + } + + /* non Java-doc + * @see ITreeContentProvider#getParent + */ + public Object getParent(Object element){ + return ((ChangeElement)element).getParent(); + } + + /* non Java-doc + * @see ITreeContentProvider#hasChildren + */ + public boolean hasChildren(Object element){ + Object[] children= getChildren(element); + return children != null && children.length > 0; + } + + /* non Java-doc + * @see ITreeContentProvider#dispose + */ + public void dispose(){ + } + + /* non Java-doc + * @see ITreeContentProvider#getElements + */ + public Object[] getElements(Object element){ + return getChildren(element); + } + + private ChangeElement[] createChildren(ChangeElement object) { + ChangeElement[] result= EMPTY_CHILDREN; + if (!(object instanceof DefaultChangeElement)) + return result; + + DefaultChangeElement changeElement= (DefaultChangeElement)object; + IChange change= changeElement.getChange(); + if (change instanceof ICompositeChange) { + IChange[] children= ((ICompositeChange)change).getChildren(); + result= new ChangeElement[children.length]; + for (int i= 0; i < children.length; i++) { + result[i]= new DefaultChangeElement(changeElement, children[i]); + } + } +//////////////// +// else if (change instanceof TranslationUnitChange) { +// List children= new ArrayList(5); +// TranslationUnitChange cunitChange= (TranslationUnitChange)change; +// ITranslationUnit cunit= cunitChange.getTranslationUnit(); +// Map map= new HashMap(20); +// EditChange[] changes=getSortedTextEditChanges(cunitChange); +// for (int i= 0; i < changes.length; i++) { +// EditChange tec= changes[i]; +// try { +// ICElement element= getModifiedCElement(tec, cunit); +// if (element.equals(cunit)) { +// children.add(new TextEditChangeElement(changeElement, tec)); +// } else { +// PseudoCChangeElement pjce= getChangeElement(map, element, children, changeElement); +// pjce.addChild(new TextEditChangeElement(pjce, tec)); +// } +// } catch (CModelException e) { +// children.add(new TextEditChangeElement(changeElement, tec)); +// } +// } +// result= (ChangeElement[]) children.toArray(new ChangeElement[children.size()]); +// } +// else if (change instanceof TextChange) { +// EditChange[] changes= getSortedTextEditChanges((TextChange)change); +// result= new ChangeElement[changes.length]; +// for (int i= 0; i < changes.length; i++) { +// result[i]= new TextEditChangeElement(changeElement, changes[i]); +// } +// } +/////////// + changeElement.setChildren(result); + return result; + } + + private EditChange[] getSortedTextEditChanges(TextChange change) { + EditChange[] edits= change.getTextEditChanges(); + List result= new ArrayList(edits.length); + for (int i= 0; i < edits.length; i++) { + if (!edits[i].isEmpty()) + result.add(edits[i]); + } + Comparator comparator= new OffsetComparator(); + Collections.sort(result, comparator); + return (EditChange[])result.toArray(new EditChange[result.size()]); + } + + private PseudoCChangeElement getChangeElement(Map map, ICElement element, List children, ChangeElement cunitChange) { + PseudoCChangeElement result= (PseudoCChangeElement)map.get(element); + if (result != null) + return result; + ICElement parent= element.getParent(); + if (parent instanceof ITranslationUnit) { + result= new PseudoCChangeElement(cunitChange, element); + children.add(result); + map.put(element, result); + } else { + PseudoCChangeElement parentChange= getChangeElement(map, parent, children, cunitChange); + result= new PseudoCChangeElement(parentChange, element); + parentChange.addChild(result); + map.put(element, result); + } + return result; + } + + private ICElement getModifiedCElement(EditChange edit, ITranslationUnit cunit) throws CModelException { + IRegion range= edit.getTextRange(); + if (range.getOffset() == 0 && range.getLength() == 0) + return cunit; + ICElement result= getElementAt(cunit, range.getOffset()); + if (result == null) + return cunit; + + try { + while(true) { + ISourceReference ref= (ISourceReference)result; + IRegion sRange= new Region(ref.getSourceRange().getStartPos(), ref.getSourceRange().getLength()); + if (result.getElementType() == ICElement.C_UNIT || result.getParent() == null || edit.coveredBy(sRange)) + break; + result= result.getParent(); + } + } catch(CModelException e) { + // Do nothing, use old value. + } catch(ClassCastException e) { + // Do nothing, use old value. + } + return result; + } + + protected ICElement getElementAt(IParent unit, int position) throws CModelException { + if (unit instanceof ISourceReference) { + ICElement[] children = unit.getChildren(); + for (int i = 0; i < children.length; i++) { + ICElement aChild = children[i]; + if (aChild instanceof ISourceReference) { + ISourceReference child = (ISourceReference) children[i]; + ISourceRange range = child.getSourceRange(); + if (position < range.getStartPos() + range.getLength() && position >= range.getStartPos()) { + if (child instanceof IParent) { + return getElementAt((IParent)child, position); + } else { + return ((ICElement)child); + } + } + } + } + } + return null; + } +} + diff --git a/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/ChangeElementLabelProvider.java b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/ChangeElementLabelProvider.java new file mode 100644 index 00000000000..660e0f1ad95 --- /dev/null +++ b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/ChangeElementLabelProvider.java @@ -0,0 +1,152 @@ +/********************************************************************** + * Copyright (c) 2004 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.internal.ui.refactoring; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import org.eclipse.cdt.internal.corext.refactoring.base.IChange; +import org.eclipse.cdt.internal.corext.refactoring.base.ICompositeChange; +import org.eclipse.cdt.internal.corext.refactoring.changes.TextFileChange; +import org.eclipse.cdt.internal.corext.refactoring.changes.TranslationUnitChange; +import org.eclipse.cdt.internal.ui.CPluginImages; +import org.eclipse.cdt.ui.CElementLabelProvider; +import org.eclipse.core.resources.IFile; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.jface.viewers.LabelProviderChangedEvent; +import org.eclipse.swt.graphics.Image; + +class ChangeElementLabelProvider extends LabelProvider { + + private int fCElementFlags; + private CElementLabelProvider fCElementLabelProvider; + private Map fDescriptorImageMap= new HashMap(); + private boolean fShowQualification= true; + + public ChangeElementLabelProvider(int CElementFlags) { + fCElementFlags= CElementFlags; + fCElementLabelProvider= new CElementLabelProvider(CElementFlags); + } + + public void setShowQualification(boolean showQualification) { + fShowQualification= showQualification; + LabelProviderChangedEvent event= new LabelProviderChangedEvent(this, null); + fireLabelProviderChanged(event); + } + + public Image getImage(Object object) { + if (object instanceof DefaultChangeElement) { + Object element= ((DefaultChangeElement)object).getChange(); + return doGetImage(element); + } + else if (object instanceof TextEditChangeElement) { + Object element= ((TextEditChangeElement)object).getTextEditChange(); + return doGetImage(element); + } + else if (object instanceof PseudoCChangeElement) { + PseudoCChangeElement element= (PseudoCChangeElement)object; + return fCElementLabelProvider.getImage(element.getCElement()); + } + return super.getImage(object); + } + + public String getText(Object object) { + if (object instanceof DefaultChangeElement) { + IChange change= ((DefaultChangeElement)object).getChange(); + if (!fShowQualification) + return change.getName(); + + if (change instanceof TextFileChange) { + IFile file= ((TextFileChange)change).getFile(); + return RefactoringMessages.getFormattedString( + "PreviewWizardPage.changeElementLabelProvider.textFormat", //$NON-NLS-1$ + new String[] {file.getName(), getPath(file)}); + } else { + return change.getName(); + } + } + else if (object instanceof TextEditChangeElement) { + TextEditChangeElement element= (TextEditChangeElement)object; + String result= element.getTextEditChange().getName(); + if ((fCElementFlags & CElementLabelProvider.SHOW_POST_QUALIFIED) != 0) { + ChangeElement parent= getParent(element); + if (parent != null) + result= RefactoringMessages.getFormattedString( + "PreviewWizardPage.changeElementLabelProvider.textFormatEdit", //$NON-NLS-1$ + new String[] {getText(parent), result}); + } + return result; + } + else if (object instanceof PseudoCChangeElement) { + PseudoCChangeElement element= (PseudoCChangeElement)object; + return fCElementLabelProvider.getText(element.getCElement()); + } + return super.getText(object); + } + + public void dispose() { + for (Iterator iter= fDescriptorImageMap.values().iterator(); iter.hasNext(); ) { + Image image= (Image)iter.next(); + image.dispose(); + } + super.dispose(); + } + + private Image doGetImage(Object element) { + ImageDescriptor descriptor= null; + if (descriptor == null) { + if (element instanceof ICompositeChange) { + descriptor= CPluginImages.DESC_OBJS_COMPOSITE_CHANGE; + } + else if (element instanceof TextEditChangeElement) { + descriptor= CPluginImages.DESC_OBJS_TEXT_EDIT; + } + else if (element instanceof TranslationUnitChange) { + descriptor= CPluginImages.DESC_OBJS_CU_CHANGE; + } + else if (element instanceof TextFileChange) { + descriptor= CPluginImages.DESC_OBJS_FILE_CHANGE; + } + else { + descriptor= CPluginImages.DESC_OBJS_DEFAULT_CHANGE; + } + } + Image image= (Image)fDescriptorImageMap.get(descriptor); + if (image == null) { + image= descriptor.createImage(); + fDescriptorImageMap.put(descriptor, image); + } + return image; + } + + private String getPath(IFile file) { + StringBuffer result= new StringBuffer(file.getProject().getName()); + String projectRelativePath= file.getParent().getProjectRelativePath().toString(); + if (projectRelativePath.length() > 0) { + result.append('/'); + result.append(projectRelativePath); + } + return result.toString(); + } + + private ChangeElement getParent(TextEditChangeElement element) { + ChangeElement parent= element.getParent(); + while (parent != null + && !(parent instanceof PseudoCChangeElement) + && !(parent instanceof DefaultChangeElement)) { + parent= parent.getParent(); + } + return parent; + } +} + diff --git a/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/ChangeElementTreeViewer.java b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/ChangeElementTreeViewer.java new file mode 100644 index 00000000000..a4bdce9bd0e --- /dev/null +++ b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/ChangeElementTreeViewer.java @@ -0,0 +1,175 @@ +/********************************************************************** + * Copyright (c) 2004 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.internal.ui.refactoring; + +import org.eclipse.jface.viewers.CheckStateChangedEvent; +import org.eclipse.jface.viewers.CheckboxTreeViewer; +import org.eclipse.jface.viewers.ICheckStateListener; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Item; +import org.eclipse.swt.widgets.TreeItem; +import org.eclipse.swt.widgets.Widget; + +class ChangeElementTreeViewer extends CheckboxTreeViewer { + + public ChangeElementTreeViewer(Composite parentComposite) { + super(parentComposite, SWT.NONE); + addCheckStateListener(new ICheckStateListener() { + public void checkStateChanged(CheckStateChangedEvent event){ + ChangeElement element= (ChangeElement)event.getElement(); + boolean checked= event.getChecked(); + + element.setActive(checked); + setSubtreeChecked(element, checked); + setSubtreeGrayed(element, false); + ChangeElement parent= element.getParent(); + while(parent != null) { + int active= parent.getActive(); + boolean grayed= (active == ChangeElement.PARTLY_ACTIVE); + setChecked(parent, checked ? true : grayed); + setGrayed(parent, grayed); + parent= parent.getParent(); + } + } + }); + } + + protected void inputChanged(Object input, Object oldInput) { + super.inputChanged(input, oldInput); + // XXX workaround for http://bugs.eclipse.org/bugs/show_bug.cgi?id=9390 + initializeChildren((ChangeElement)input); + } + + protected void doUpdateItem(Item item, Object element) { + super.doUpdateItem(item, element); + TreeItem treeItem= (TreeItem)item; + ChangeElement ce= (ChangeElement)element; + int state= ce.getActive(); + boolean checked= state == ChangeElement.INACTIVE ? false : true; + treeItem.setChecked(checked); + boolean grayed= state == ChangeElement.PARTLY_ACTIVE ? true : false; + treeItem.setGrayed(grayed); + } + + protected void revealNext() { + revealElement(true); + } + + protected void revealPrevious() { + revealElement(false); + } + + private void initializeChildren(ChangeElement element) { + if (element == null) + return; + ChangeElement[] children= element.getChildren(); + if (children == null) + return; + for (int i= 0; i < children.length; i++) { + ChangeElement child= children[i]; + int state= child.getActive(); + boolean checked= state == ChangeElement.INACTIVE ? false : true; + if (checked) + setChecked(child, checked); + boolean grayed= state == ChangeElement.PARTLY_ACTIVE ? true : false; + if (grayed) + setGrayed(child, grayed); + } + } + + private void setSubtreeGrayed(Object element, boolean grayed) { + Widget widget= findItem(element); + if (widget instanceof TreeItem) { + TreeItem item= (TreeItem)widget; + if (item.getGrayed() != grayed) { + item.setGrayed(grayed); + grayChildren(getChildren(item), grayed); + } + } + } + + private void grayChildren(Item[] items, boolean grayed) { + for (int i= 0; i < items.length; i++) { + Item element= items[i]; + if (element instanceof TreeItem) { + TreeItem item= (TreeItem)element; + if (item.getGrayed() != grayed) { + item.setGrayed(grayed); + grayChildren(getChildren(item), grayed); + } + } + } + } + + private void revealElement(boolean next) { + ChangeElement current= (ChangeElement)getInput(); + IStructuredSelection selection= (IStructuredSelection)getSelection(); + if (!selection.isEmpty()) + current= (ChangeElement)selection.iterator().next(); + + ChangeElement candidate= getLeaf(current, next); + if (candidate == null) { + candidate= getElement(current, next); + if (candidate != null) { + ChangeElement leaf= getLeaf(candidate, next); + if (leaf != null) + candidate= leaf; + } + } + if (candidate != null) + setSelection(new StructuredSelection(candidate), true); + else + getControl().getDisplay().beep(); + } + + private ChangeElement getLeaf(ChangeElement element, boolean first) { + ChangeElement result= null; + ChangeElement[] children= element.getChildren(); + while(children != null && children.length > 0) { + result= children[first ? 0 : children.length - 1]; + children= result.getChildren(); + } + return result; + } + + private ChangeElement getElement(ChangeElement element, boolean next) { + while(true) { + ChangeElement parent= element.getParent(); + if (parent == null) + return null; + ChangeElement candidate= getSibling(parent.getChildren(), element, next); + if (candidate != null) + return candidate; + element= parent; + } + } + + private ChangeElement getSibling(ChangeElement[] children, ChangeElement element, boolean next) { + for (int i= 0; i < children.length; i++) { + if (children[i] == element) { + if (next) + if (i < children.length - 1) + return children[i + 1]; + else + return null; + else + if (i > 0) + return children[i - 1]; + else + return null; + } + } + return null; + } +} diff --git a/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/ChangeExceptionHandler.java b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/ChangeExceptionHandler.java new file mode 100644 index 00000000000..15ba2e190c5 --- /dev/null +++ b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/ChangeExceptionHandler.java @@ -0,0 +1,107 @@ +/********************************************************************** + * Copyright (c) 2004 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation +***********************************************************************/ + +package org.eclipse.cdt.internal.ui.refactoring; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; + +import org.eclipse.jface.dialogs.ErrorDialog; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.util.Assert; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; + +import org.eclipse.cdt.internal.corext.refactoring.base.ChangeAbortException; +import org.eclipse.cdt.internal.corext.refactoring.base.ChangeContext; +import org.eclipse.cdt.internal.corext.refactoring.base.IChange; +import org.eclipse.cdt.internal.corext.refactoring.base.IChangeExceptionHandler; + +import org.eclipse.cdt.ui.CUIPlugin; +import org.eclipse.cdt.internal.ui.refactoring.RefactoringMessages; + +/** + * An implementation of IChangeExceptionHandler which pops up a dialog + * box asking the user if the refactoring is to be aborted without further actions or + * if the refactoring engine should try to undo all successfully executed changes. + */ +public class ChangeExceptionHandler implements IChangeExceptionHandler { + + private Shell fParent; + + private static class RefactorErrorDialog extends ErrorDialog { + public RefactorErrorDialog(Shell parentShell, String dialogTitle, String message, IStatus status, int displayMask) { + super(parentShell, dialogTitle, message, status, displayMask); + } + protected void createButtonsForButtonBar(Composite parent) { + super.createButtonsForButtonBar(parent); + Button ok= getButton(IDialogConstants.OK_ID); + ok.setText( RefactoringMessages.getString("ChangeExceptionHandler.undo")); //$NON-NLS-1$ + Button abort= createButton(parent, IDialogConstants.CANCEL_ID, RefactoringMessages.getString("ChangeExceptionHandler.abort"), true); //$NON-NLS-1$ + abort.moveBelow(ok); + abort.setFocus(); + } + protected Control createMessageArea (Composite parent) { + Control result= super.createMessageArea(parent); + new Label(parent, SWT.NONE); // filler + Label label= new Label(parent, SWT.NONE); + label.setText(RefactoringMessages.getString("ChangeExceptionHandler.button_explanation")); //$NON-NLS-1$ + label.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + applyDialogFont(result); + return result; + } + } + + public ChangeExceptionHandler(Shell parent) { + Assert.isNotNull(parent); + fParent= parent; + } + + public void handle(ChangeContext context, IChange change, Exception e) { + CUIPlugin.getDefault().log(e); + IStatus status= null; + if (e instanceof CoreException) { + status= ((CoreException)e).getStatus(); + } else { + if (e.getMessage() == null) + status= new Status(IStatus.ERROR, CUIPlugin.getPluginId(), IStatus.ERROR, + RefactoringMessages.getString("ChangeExceptionHandler.no_details"), e); //$NON-NLS-1$ + else + status= new Status(IStatus.ERROR, CUIPlugin.getPluginId(), IStatus.ERROR, e.getMessage(), e); + } + final ErrorDialog dialog= new RefactorErrorDialog(fParent, + RefactoringMessages.getString("ChangeExceptionHandler.refactoring"), //$NON-NLS-1$ + RefactoringMessages.getFormattedString("ChangeExceptionHandler.unexpected_exception", new String[] {change.getName()}), //$NON-NLS-1$ + status, IStatus.OK | IStatus.INFO | IStatus.WARNING | IStatus.ERROR); + + final int[] result= new int[1]; + Runnable runnable= new Runnable() { + public void run() { + result[0]= dialog.open(); + } + }; + fParent.getDisplay().syncExec(runnable); + switch(result[0]) { + case IDialogConstants.OK_ID: + context.setTryToUndo(); + // Fall through + case IDialogConstants.CANCEL_ID: + throw new ChangeAbortException(e); + } + } +} diff --git a/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/CheckConditionsOperation.java b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/CheckConditionsOperation.java new file mode 100644 index 00000000000..0174ef8eb6f --- /dev/null +++ b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/CheckConditionsOperation.java @@ -0,0 +1,89 @@ +/********************************************************************** + * Copyright (c) 2004 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.internal.ui.refactoring; + +import java.lang.reflect.InvocationTargetException; + +import org.eclipse.core.runtime.IProgressMonitor; + +import org.eclipse.jface.operation.IRunnableWithProgress; +import org.eclipse.jface.util.Assert; + +import org.eclipse.cdt.core.model.CModelException; + +import org.eclipse.cdt.internal.corext.refactoring.base.Refactoring; +import org.eclipse.cdt.internal.corext.refactoring.base.RefactoringStatus; + +/** + * Operation that, when run, check proceconditions of an Refactoring passed + * on creation. + */ +public class CheckConditionsOperation implements IRunnableWithProgress { + private Refactoring fRefactoring; + private int fStyle; + private RefactoringStatus fStatus; + + public final static int NONE= 0; + public final static int ACTIVATION= 1 << 1; + public final static int INPUT= 1 << 2; + public final static int PRECONDITIONS= ACTIVATION | INPUT; + final static int LAST= 1 << 3; + + /** + * Creates a new CheckConditionsOperation. + * + * @param refactoring the refactoring. Parameter must not be null. + * @param style style to define which conditions to check. + */ + public CheckConditionsOperation(Refactoring refactoring, int style) { + Assert.isNotNull(refactoring); + fRefactoring= refactoring; + fStyle= style; + Assert.isTrue(checkStyle(fStyle)); + } + + /* + * (Non-Javadoc) + * Method defined int IRunnableWithProgress + */ + public void run(IProgressMonitor pm) throws InvocationTargetException { + try { + fStatus= null; + if ((fStyle & PRECONDITIONS) == PRECONDITIONS) + fStatus= fRefactoring.checkPreconditions(pm); + else if ((fStyle & ACTIVATION) == ACTIVATION) + fStatus= fRefactoring.checkActivation(pm); + else if ((fStyle & INPUT) == INPUT) + fStatus= fRefactoring.checkInput(pm); + } catch (CModelException e) { + throw new InvocationTargetException(e); + } finally { + pm.done(); + } + } + + /** + * Returns the outcome of the operation or null if an exception + * has occured when performing the operation. + * + * @return the RefactoringStatus returned from + * IRefactoring.checkPreconditions. + * @see org.eclipse.jdt.internal.corext.refactoring.base.IRefactoring#checkPreconditions(IProgressMonitor) + */ + public RefactoringStatus getStatus() { + return fStatus; + } + + private boolean checkStyle(int style) { + return style < LAST; + } + +} diff --git a/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/CreateChangeOperation.java b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/CreateChangeOperation.java new file mode 100644 index 00000000000..d6c4be927ce --- /dev/null +++ b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/CreateChangeOperation.java @@ -0,0 +1,156 @@ +/********************************************************************** + * Copyright (c) 2004 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation +***********************************************************************/ + +package org.eclipse.cdt.internal.ui.refactoring; + +import java.lang.reflect.InvocationTargetException; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.SubProgressMonitor; + +import org.eclipse.jface.operation.IRunnableWithProgress; +import org.eclipse.jface.util.Assert; + +import org.eclipse.cdt.core.model.CModelException; + +import org.eclipse.cdt.internal.corext.refactoring.base.IChange; +import org.eclipse.cdt.internal.corext.refactoring.base.Refactoring; +import org.eclipse.cdt.internal.corext.refactoring.base.RefactoringStatus; + +/** + * Operation that, when performed, creates an IChange object for the refactoring + * passed as a constructor parameter. + */ +public class CreateChangeOperation implements IRunnableWithProgress { + + private Refactoring fRefactoring; + private int fStyle; + private int fCheckPassedSeverity; + private IChange fChange; + private RefactoringStatus fStatus; + + public static final int CHECK_NONE= CheckConditionsOperation.NONE; + public static final int CHECK_ACTIVATION= CheckConditionsOperation.ACTIVATION; + public static final int CHECK_INPUT= CheckConditionsOperation.INPUT; + public static final int CHECK_PRECONDITION= CheckConditionsOperation.PRECONDITIONS; + private static final int LAST= CheckConditionsOperation.LAST; + + /** + * Creates a new instance with the given refactoring. + * + * @param refactoring the refactoring. Parameter must not be null + * @param style style to define which conditions to check + */ + public CreateChangeOperation(Refactoring refactoring, int style) { + Assert.isNotNull(refactoring); + fRefactoring= refactoring; + fStyle= style; + Assert.isTrue(checkStyle(fStyle)); + fCheckPassedSeverity= RefactoringStatus.ERROR; + } + + /** + * Creates a new instance with the given refactoring. + * + * @param refactoring the refactoring. Parameter must not be null + * @param style style to define which conditions to check + * @param checkPassedSeverity the severity below which the check is considered + * to be passed + * @see #setCheckPassedSeverity(int) + */ + public CreateChangeOperation(Refactoring refactoring, int style, int checkPassedSeverity) { + Assert.isNotNull(refactoring); + fRefactoring= refactoring; + fStyle= style; + Assert.isTrue(checkStyle(fStyle)); + setCheckPassedSeverity(checkPassedSeverity); + } + + /** + * Sets the check passed severity value. This value is used to deceide whether the + * condition check is interpreted as passed or not. The condition check is considered + * to be passed if the refactoring status's severity is less or equal the given severity. + * The given value must be smaller than RefactoringStatus.FATAL. + */ + public void setCheckPassedSeverity(int severity) { + fCheckPassedSeverity= severity; + Assert.isTrue (fCheckPassedSeverity < RefactoringStatus.FATAL); + } + + /* (Non=Javadoc) + * Method declared in IRunnableWithProgress + */ + public void run(IProgressMonitor pm) throws InvocationTargetException { + fChange= null; + fStatus= null; + try { + fChange= null; + if (fStyle != CHECK_NONE) { + pm.beginTask("", 5); //$NON-NLS-1$ + pm.subTask(""); //$NON-NLS-1$ + CheckConditionsOperation op= new CheckConditionsOperation(fRefactoring, fStyle); + op.run(new SubProgressMonitor(pm, 4, SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK)); + fStatus= op.getStatus(); + if (fStatus != null && fStatus.getSeverity() <= fCheckPassedSeverity) { + fChange= fRefactoring.createChange( + new SubProgressMonitor(pm, 1, SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK)); + } else { + pm.worked(1); + } + } else { + fChange= fRefactoring.createChange(pm); + } + } catch (CModelException e) { + throw new InvocationTargetException(e); + } finally { + pm.done(); + } + } + + /** + * Returns the outcome of the operation or null if an exception + * occured when performing the operation. + * + * @return the outcome of the operation + */ + public IChange getChange() { + return fChange; + } + + /** + * Returns the status of the condition cheking. Returns null if an + * exception occured when performing the operation. + * + * @return the condition checking's status + */ + public RefactoringStatus getStatus() { + return fStatus; + } + + /** + * Returns the checking style. + * + * @return the style used for precondition checking. Is one of NONE, + * ACTIVATION, INPUT, or PRECONDITION. + */ + public int getConditionCheckingStyle() { + return fStyle; + } + + public void setConditionCheckingStyle(int style) { + Assert.isTrue(checkStyle(style)); + fStyle= style; + } + + private boolean checkStyle(int style) { + return style < LAST; + } +} diff --git a/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/DefaultChangeElement.java b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/DefaultChangeElement.java new file mode 100644 index 00000000000..01c8e7cd807 --- /dev/null +++ b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/DefaultChangeElement.java @@ -0,0 +1,123 @@ +/********************************************************************** + * Copyright (c) 2004 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.internal.ui.refactoring; + +import org.eclipse.cdt.internal.corext.refactoring.base.IChange; +import org.eclipse.cdt.internal.corext.refactoring.base.ICompositeChange; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.jface.util.Assert; +//import org.eclipse.jdt.internal.corext.refactoring.changes.CompilationUnitChange; +//import org.eclipse.jdt.internal.corext.refactoring.changes.TextChange; + +class DefaultChangeElement extends ChangeElement { + + private IChange fChange; + private ChangeElement[] fChildren; + + /** + * Creates a new ChangeElement for the given + * change. + * + * @param parent the change element's parent or null + * if the change element doesn't have a parent + * @param change the actual change. Argument must not be + * null + */ + public DefaultChangeElement(ChangeElement parent, IChange change) { + super(parent); + fChange= change; + Assert.isNotNull(fChange); + } + + /** + * Returns the underlying IChange object. + * + * @return the underlying change + */ + public IChange getChange() { + return fChange; + } + + /* (non-Javadoc) + * @see org.eclipse.jdt.internal.ui.refactoring.ChangeElement#getChangePreviewViewer() + */ +// public ChangePreviewViewerDescriptor getChangePreviewViewer() throws CoreException { +// return ChangePreviewViewerDescriptor.get(fChange); +// } + + /* (non-Javadoc) + * @see org.eclipse.jdt.internal.ui.refactoring.ChangeElement#feedInput(org.eclipse.jdt.internal.ui.refactoring.IChangePreviewViewer) + */ + public void feedInput(IChangePreviewViewer viewer) throws CoreException { + viewer.setInput(fChange); + } + + /* non Java-doc + * @see ChangeElement#setActive + */ + public void setActive(boolean active) { + fChange.setActive(active); + } + + /* non Java-doc + * @see ChangeElement.getActive + */ + public int getActive() { + if (fChange instanceof ICompositeChange /*|| fChange instanceof CompilationUnitChange || fChange instanceof TextChange*/) + return getCompositeChangeActive(); + else + return getDefaultChangeActive(); + } + + /* non Java-doc + * @see ChangeElement.getChildren + */ + public ChangeElement[] getChildren() { + return fChildren; + } + + /** + * Sets the children. + * + * @param the children of this node. Must not be null + */ + public void setChildren(ChangeElement[] children) { + Assert.isNotNull(children); + fChildren= children; + } + + private int getDefaultChangeActive() { + int result= fChange.isActive() ? ACTIVE : INACTIVE; + if (fChildren != null) { + for (int i= 0; i < fChildren.length; i++) { + result= ACTIVATION_TABLE[fChildren[i].getActive()][result]; + if (result == PARTLY_ACTIVE) + break; + } + } + return result; + } + + private int getCompositeChangeActive() { + if (fChildren != null && fChildren.length > 0) { + int result= fChildren[0].getActive(); + for (int i= 1; i < fChildren.length; i++) { + result= ACTIVATION_TABLE[fChildren[i].getActive()][result]; + if (result == PARTLY_ACTIVE) + break; + } + return result; + } else { + return ACTIVE; + } + } +} + diff --git a/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/ErrorWizardPage.java b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/ErrorWizardPage.java new file mode 100644 index 00000000000..4012e3c7e9e --- /dev/null +++ b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/ErrorWizardPage.java @@ -0,0 +1,141 @@ +/********************************************************************** + * Copyright (c) 2004 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation +***********************************************************************/ + +package org.eclipse.cdt.internal.ui.refactoring; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; + +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.wizard.IWizardPage; + +import org.eclipse.ui.help.WorkbenchHelp; + +import org.eclipse.cdt.internal.ui.ICHelpContextIds; + +import org.eclipse.cdt.internal.corext.refactoring.base.IChange; +import org.eclipse.cdt.internal.corext.refactoring.base.RefactoringStatus; + +/** + * Presents the list of failed preconditions to the user + */ +class ErrorWizardPage extends RefactoringWizardPage { + + public static final String PAGE_NAME= "ErrorPage"; //$NON-NLS-1$ + + private RefactoringStatus fStatus; + private RefactoringStatusViewer fViewer; + + public ErrorWizardPage() { + super(PAGE_NAME); + } + + /** + * Sets the page's refactoring status to the given value. + * @param status the refactoring status. + */ + public void setStatus(RefactoringStatus status) { + fStatus= status; + if (fStatus != null) { + setPageComplete(isRefactoringPossible()); + int severity= fStatus.getSeverity(); + if (severity >= RefactoringStatus.FATAL) { + setDescription(RefactoringMessages.getString("ErrorWizardPage.cannot_proceed")); //$NON-NLS-1$ + } else if (severity >= RefactoringStatus.INFO) { + setDescription(RefactoringMessages.getString("ErrorWizardPage.confirm")); //$NON-NLS-1$ + } else { + setDescription(""); //$NON-NLS-1$ + } + } else { + setPageComplete(true); + setDescription(""); //$NON-NLS-1$ + } + } + + public RefactoringStatus getStatus() { + return fStatus; + } + + //---- UI creation ---------------------------------------------------------------------- + + /* (non-Javadoc) + * Method declared in IWizardPage. + */ + public void createControl(Composite parent) { + initializeDialogUnits(parent); + setControl(fViewer= new RefactoringStatusViewer(parent, SWT.NONE)); + Dialog.applyDialogFont(fViewer); + WorkbenchHelp.setHelp(getControl(), ICHelpContextIds.REFACTORING_ERROR_WIZARD_PAGE); + } + + //---- Reimplementation of WizardPage methods ------------------------------------------ + + /* (non-Javadoc) + * Method declared on IDialog. + */ + public void setVisible(boolean visible) { + if (visible) { + fViewer.setStatus(fStatus); + } + super.setVisible(visible); + } + + /* (non-Javadoc) + * Method declared in IWizardPage. + */ + public boolean canFlipToNextPage() { + // We have to call super.getNextPage since computing the next + // page is expensive. So we avoid it as long as possible. + return fStatus != null && isRefactoringPossible() && + isPageComplete() && super.getNextPage() != null; + } + + /* (non-Javadoc) + * Method declared in IWizardPage. + */ + public IWizardPage getNextPage() { + RefactoringWizard wizard= getRefactoringWizard(); + IChange change= wizard.getChange(); + if (change == null) { + change= wizard.createChange(CreateChangeOperation.CHECK_NONE, RefactoringStatus.ERROR, false); + wizard.setChange(change); + } + if (change == null) + return this; + + return super.getNextPage(); + } + + /* (non-JavaDoc) + * Method defined in RefactoringWizardPage + */ + protected boolean performFinish() { + RefactoringWizard wizard= getRefactoringWizard(); + IChange change= wizard.getChange(); + PerformChangeOperation op= null; + if (change != null) { + op= new PerformChangeOperation(change); + } else { + CreateChangeOperation ccop= new CreateChangeOperation(getRefactoring(), CreateChangeOperation.CHECK_NONE); + ccop.setCheckPassedSeverity(RefactoringStatus.ERROR); + + op= new PerformChangeOperation(ccop); + op.setCheckPassedSeverity(RefactoringStatus.ERROR); + } + return wizard.performFinish(op); + } + + //---- Helpers ---------------------------------------------------------------------------------------- + + private boolean isRefactoringPossible() { + return fStatus.getSeverity() < RefactoringStatus.FATAL; + } +} diff --git a/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/IChangePreviewViewer.java b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/IChangePreviewViewer.java new file mode 100644 index 00000000000..59f7f97a7ed --- /dev/null +++ b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/IChangePreviewViewer.java @@ -0,0 +1,53 @@ +/********************************************************************** + * Copyright (c) 2004 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.internal.ui.refactoring; + +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; + +import org.eclipse.core.runtime.CoreException; + +/** + * Presents a preview of a ChangeElement + */ +public interface IChangePreviewViewer { + + /** + * Creates the preview viewer's widget hierarchy. This method + * should only be called once. Method getControl() + * should be use retrieve the widget hierarchy. + * + * @param parent the parent for the widget hierarchy + * + * @see #getControl() + */ + public void createControl(Composite parent); + + /** + * Returns the preview viewer's SWT control. + * + * @return the preview viewer's SWT control + */ + public Control getControl(); + + /** + * Sets the preview viewer's input element. + * + * @param input the input element + */ + public void setInput(Object input) throws CoreException; + + /** + * Refreshes the preview viewer. + */ + public void refresh(); +} + diff --git a/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/IPreviewWizardPage.java b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/IPreviewWizardPage.java new file mode 100644 index 00000000000..5921abd8356 --- /dev/null +++ b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/IPreviewWizardPage.java @@ -0,0 +1,29 @@ +/********************************************************************** + * Copyright (c) 2004 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.internal.ui.refactoring; + +import org.eclipse.jface.wizard.IWizardPage; + +import org.eclipse.cdt.internal.corext.refactoring.base.IChange; + +public interface IPreviewWizardPage extends IWizardPage { + + /** The page's name */ + public static final String PAGE_NAME= "PreviewPage"; //$NON-NLS-1$ + + /** + * Sets that change for which the page is supposed to display a preview. + * + * @param change the new change. + */ + public void setChange(IChange change); +} + diff --git a/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/IStatusContextViewer.java b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/IStatusContextViewer.java new file mode 100644 index 00000000000..65fa4ace362 --- /dev/null +++ b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/IStatusContextViewer.java @@ -0,0 +1,48 @@ +/********************************************************************** + * Copyright (c) 2004 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.internal.ui.refactoring; + +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; + +import org.eclipse.cdt.internal.corext.refactoring.base.Context; + +/** + * A special viewer to present a context for a RefactoringStatusEntry. + */ +public interface IStatusContextViewer { + + /** + * Creates the status viewer's widget hierarchy. This method + * should only be called once. Method getControl() + * should be used to retrieve the widget hierarchy. + * + * @param parent the parent for the widget hierarchy + * + * @see #getControl() + */ + public void createControl(Composite parent); + + /** + * Returns the status context viewer's SWT control. + * + * @return the status context viewer's SWT control + */ + public Control getControl(); + + /** + * Sets the status context viewer's input element. + * + * @param input the input element + */ + public void setInput(Context input); +} + diff --git a/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/ListContentProvider.java b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/ListContentProvider.java new file mode 100644 index 00000000000..ae5e1a6aa84 --- /dev/null +++ b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/ListContentProvider.java @@ -0,0 +1,47 @@ +/********************************************************************** + * Copyright (c) 2004 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.internal.ui.refactoring; + +import java.util.List; + +import org.eclipse.jface.viewers.IStructuredContentProvider; +import org.eclipse.jface.viewers.Viewer; + +/** + * A specialized content provider to show a list of editor parts. + */ +public class ListContentProvider implements IStructuredContentProvider { + List fContents; + + public ListContentProvider() { + } + + public Object[] getElements(Object input) { + if (fContents != null && fContents == input) + return fContents.toArray(); + return new Object[0]; + } + + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + if (newInput instanceof List) + fContents= (List)newInput; + else + fContents= null; + // we use a fixed set. + } + + public void dispose() { + } + + public boolean isDeleted(Object o) { + return fContents != null && !fContents.contains(o); + } +} diff --git a/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/ListDialog.java b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/ListDialog.java new file mode 100644 index 00000000000..ff830dd7d1e --- /dev/null +++ b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/ListDialog.java @@ -0,0 +1,95 @@ +/********************************************************************** + * Copyright (c) 2004 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.internal.ui.refactoring; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Table; + +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.viewers.ILabelProvider; +import org.eclipse.jface.viewers.IStructuredContentProvider; +import org.eclipse.jface.viewers.TableViewer; + +import org.eclipse.ui.dialogs.SelectionDialog; + +public class ListDialog extends SelectionDialog { + + private IStructuredContentProvider fContentProvider; + private ILabelProvider fLabelProvider; + private Object fInput; + private TableViewer fTableViewer; + private boolean fAddCancelButton; + + public ListDialog(Shell parent) { + super(parent); + fAddCancelButton= false; + } + + public void setInput(Object input) { + fInput= input; + } + + public void setContentProvider(IStructuredContentProvider sp){ + fContentProvider= sp; + } + + public void setLabelProvider(ILabelProvider lp){ + fLabelProvider= lp; + } + + public void setAddCancelButton(boolean addCancelButton) { + fAddCancelButton= addCancelButton; + } + + public TableViewer getTableViewer(){ + return fTableViewer; + } + + public boolean hasFilters(){ + return fTableViewer.getFilters() != null && fTableViewer.getFilters().length != 0; + } + + public void create() { + setShellStyle(SWT.DIALOG_TRIM | SWT.RESIZE); + super.create(); + } + + protected void createButtonsForButtonBar(Composite parent) { + if (! fAddCancelButton) + createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, true); + else + super.createButtonsForButtonBar(parent); + } + + protected Control createDialogArea(Composite container) { + Composite parent= (Composite) super.createDialogArea(container); + createMessageArea(parent); + fTableViewer= new TableViewer(parent, getTableStyle()); + fTableViewer.setContentProvider(fContentProvider); + Table table= fTableViewer.getTable(); + fTableViewer.setLabelProvider(fLabelProvider); + fTableViewer.setInput(fInput); + GridData gd= new GridData(GridData.FILL_BOTH); + gd.heightHint= convertHeightInCharsToPixels(15); + gd.widthHint= convertWidthInCharsToPixels(55); + table.setLayoutData(gd); + applyDialogFont(parent); + return parent; + } + + protected int getTableStyle() { + return SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER; + } +} diff --git a/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/PerformChangeOperation.java b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/PerformChangeOperation.java new file mode 100644 index 00000000000..a91be4956d5 --- /dev/null +++ b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/PerformChangeOperation.java @@ -0,0 +1,219 @@ +/********************************************************************** + * Copyright (c) 2004 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.internal.ui.refactoring; + +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.jface.operation.IRunnableWithProgress; +import org.eclipse.jface.text.IRewriteTarget; +import org.eclipse.jface.util.Assert; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.SubProgressMonitor; + +import org.eclipse.core.resources.IWorkspaceRunnable; + +import org.eclipse.ui.IEditorPart; + +import org.eclipse.cdt.core.model.CoreModel; + +import org.eclipse.cdt.internal.corext.refactoring.base.ChangeAbortException; +import org.eclipse.cdt.internal.corext.refactoring.base.ChangeContext; +import org.eclipse.cdt.internal.corext.refactoring.base.IChange; +import org.eclipse.cdt.internal.corext.refactoring.base.RefactoringStatus; + +import org.eclipse.cdt.internal.ui.ICStatusConstants; +import org.eclipse.cdt.ui.CUIPlugin; + +/** + * Operation that, when performed, performes a change to the workbench. + */ +public class PerformChangeOperation implements IRunnableWithProgress { + + private IChange fChange; + private ChangeContext fChangeContext; + private CreateChangeOperation fCreateChangeOperation; + private int fCheckPassedSeverity; + private boolean fChangeExecuted; + + /** + * Creates a new perform change operation instance for the given change. + * + * @param change the change to be applied to the workbench + */ + public PerformChangeOperation(IChange change) { + fChange= change; + Assert.isNotNull(fChange); + } + + /** + * Creates a new perform change operation for the given create change operation. + * When executed, a new change is created using the passed instance. + * + * @param op the CreateChangeOperation used to create a new + * change object + */ + public PerformChangeOperation(CreateChangeOperation op) { + fCreateChangeOperation= op; + Assert.isNotNull(fCreateChangeOperation); + fCheckPassedSeverity= RefactoringStatus.INFO; + } + + /** + * Returns true if the change has been executed. Otherwise false + * is returned. + * + * @return true if the change has been executed, otherwise + * false + */ + public boolean changeExecuted() { + return fChangeExecuted; + } + + /** + * Returns the change used by this operation. This is either the change passed to + * the constructor or the one create by the CreateChangeOperation. + * Method returns null if the create operation did not create + * the change. + * + * @return the change used by this operation or null if no change + * has been created + */ + public IChange getChange() { + return fChange; + } + + public RefactoringStatus getStatus() { + return fCreateChangeOperation != null ? fCreateChangeOperation.getStatus() : null; + } + + /** + * Sets the check passed severity value. This value is used to deceide whether the + * condition check, executed if a change is to be created, is interpreted as passed + * or not. The condition check is considered to be passed if the refactoring status's + * severity is less or equal the given severity. The given value must be smaller + * than RefactoringStatus.FATAL. + * + * @param severity the severity value considered to be "ok". + */ + public void setCheckPassedSeverity(int severity) { + fCheckPassedSeverity= severity; + Assert.isTrue (fCheckPassedSeverity < RefactoringStatus.FATAL); + } + + /** + * Sets the change context used to execute the change. The given context is passed + * to the method IChange.perform. + * + * @param context the change context to use + * @see IChange#perform(ChangeContext, IProgressMonitor) + */ + public void setChangeContext(ChangeContext context) { + fChangeContext= context; + Assert.isNotNull(fChangeContext); + } + + /* (non-Javadoc) + * Method declard in IRunnableWithProgress + */ + public void run(IProgressMonitor pm) throws InvocationTargetException, InterruptedException { + try{ + fChangeExecuted= false; + if (createChange()) { + pm.beginTask("", 2); //$NON-NLS-1$ + fCreateChangeOperation.run(new SubProgressMonitor(pm, 1, SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK)); + fChange= fCreateChangeOperation.getChange(); + RefactoringStatus status= fCreateChangeOperation.getStatus(); + int conditionCheckingStyle= fCreateChangeOperation.getConditionCheckingStyle(); + if (fChange != null && + (conditionCheckingStyle == CreateChangeOperation.CHECK_NONE || + status != null && status.getSeverity() <= fCheckPassedSeverity)) { + executeChange(new SubProgressMonitor(pm, 1, SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK)); + fChangeExecuted= true; + } else { + pm.worked(1); + } + } else { + executeChange(pm); + fChangeExecuted= true; + } + } catch (CoreException e) { + throw new InvocationTargetException(e); + } finally{ + pm.done(); + } + } + + private void executeChange(IProgressMonitor pm) throws CoreException { + Assert.isNotNull(fChangeContext); + IRewriteTarget[] targets= null; + try { + targets= getRewriteTargets(); + beginCompoundChange(targets); + // Since we have done precondition checking this check should be fast. No PM. + // PR: 1GEWDUH: ITPJCORE:WINNT - Refactoring - Unable to undo refactor change + fChange.aboutToPerform(fChangeContext, new NullProgressMonitor()); + IWorkspaceRunnable runnable= new IWorkspaceRunnable() { + public void run(IProgressMonitor monitor) throws CoreException { + try { + fChange.perform(fChangeContext, monitor); + } catch (ChangeAbortException e) { + throw new CoreException( + new Status( + IStatus.ERROR, + CUIPlugin.getPluginId(), ICStatusConstants.CHANGE_ABORTED, + RefactoringMessages.getString("PerformChangeOperation.unrecoverable_error"), e)); //$NON-NLS-1$ + } + } + }; + CoreModel.run(runnable, pm); + } finally { + fChange.performed(); + if (targets != null) + endCompoundChange(targets); + } + } + + private boolean createChange() { + return fCreateChangeOperation != null; + } + + private static void beginCompoundChange(IRewriteTarget[] targets) { + for (int i= 0; i < targets.length; i++) { + targets[i].beginCompoundChange(); + } + } + + private static void endCompoundChange(IRewriteTarget[] targets) { + for (int i= 0; i < targets.length; i++) { + targets[i].endCompoundChange(); + } + } + + private static IRewriteTarget[] getRewriteTargets() { + IEditorPart[] editors= CUIPlugin.getInstanciatedEditors(); + List result= new ArrayList(editors.length); + for (int i= 0; i < editors.length; i++) { + IRewriteTarget target= (IRewriteTarget)editors[i].getAdapter(IRewriteTarget.class); + if (target != null) { + result.add(target); + } + } + return (IRewriteTarget[]) result.toArray(new IRewriteTarget[result.size()]); + } +} + diff --git a/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/PerformRefactoringUtil.java b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/PerformRefactoringUtil.java new file mode 100644 index 00000000000..cfaec9a0d50 --- /dev/null +++ b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/PerformRefactoringUtil.java @@ -0,0 +1,127 @@ +/********************************************************************** + * Copyright (c) 2004 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.internal.ui.refactoring; + +import java.lang.reflect.InvocationTargetException; + +import org.eclipse.swt.widgets.Shell; + +import org.eclipse.jface.operation.IRunnableContext; +import org.eclipse.jface.operation.IRunnableWithProgress; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.NullProgressMonitor; + +import org.eclipse.core.resources.IWorkspaceRunnable; + +import org.eclipse.cdt.core.model.CoreModel; + +import org.eclipse.cdt.internal.corext.refactoring.base.ChangeAbortException; +import org.eclipse.cdt.internal.corext.refactoring.base.ChangeContext; +import org.eclipse.cdt.internal.corext.refactoring.base.IChange; +import org.eclipse.cdt.internal.corext.refactoring.base.Refactoring; + +import org.eclipse.cdt.internal.ui.ICStatusConstants; +import org.eclipse.cdt.internal.ui.util.ExceptionHandler; + +public class PerformRefactoringUtil { + + //no instances + private PerformRefactoringUtil(){ + } + + public static boolean performRefactoring(PerformChangeOperation op, Refactoring refactoring, IRunnableContext execContext, Shell parent) { + ChangeContext context= new ChangeContext(new ChangeExceptionHandler(parent)); + boolean success= false; +// IUndoManager undoManager= Refactoring.getUndoManager(); + try{ + op.setChangeContext(context); +// undoManager.aboutToPerformRefactoring(); + execContext.run(false, false, op); + if (op.changeExecuted()) { + if (! op.getChange().isUndoable()){ + success= false; + } else { +// undoManager.addUndo(refactoring.getName(), op.getChange().getUndoChange()); + success= true; + } + } + } catch (InvocationTargetException e) { + Throwable t= e.getTargetException(); + if (t instanceof CoreException) { + IStatus status= ((CoreException)t).getStatus(); + if (status != null && status.getCode() == ICStatusConstants.CHANGE_ABORTED && status.getPlugin().equals(status.getPlugin())) { + success= handleChangeAbortException(execContext, context); + return true; + } + } + handleUnexpectedException(e); + return false; + } catch (InterruptedException e) { + return false; + } finally { + context.clearPerformedChanges(); +// undoManager.refactoringPerformed(success); + } + + return true; + } + + private static boolean handleChangeAbortException(IRunnableContext execContext, final ChangeContext context) { + if (!context.getTryToUndo()) + return false; // Return false since we handle an unexpected exception and we don't have any + // idea in which state the workbench is. + + IRunnableWithProgress op= new IRunnableWithProgress() { + public void run(IProgressMonitor monitor) throws InterruptedException, InvocationTargetException { + try { + CoreModel.run(new IWorkspaceRunnable() { + public void run(IProgressMonitor pm) throws CoreException { + ChangeContext undoContext= new ChangeContext(new AbortChangeExceptionHandler()); + IChange[] changes= context.getPerformedChanges(); + pm.beginTask(RefactoringMessages.getString("RefactoringWizard.undoing"), changes.length); //$NON-NLS-1$ + IProgressMonitor sub= new NullProgressMonitor(); + for (int i= changes.length - 1; i >= 0; i--) { + IChange change= changes[i]; + pm.subTask(change.getName()); + change.getUndoChange().perform(undoContext, sub); + pm.worked(1); + } + } + }, monitor); + } catch (ChangeAbortException e) { + throw new InvocationTargetException(e.getThrowable()); + } catch (CoreException e) { + throw new InvocationTargetException(e); + } finally { + monitor.done(); + } + } + }; + + try { + execContext.run(false, false, op); + } catch (InvocationTargetException e) { + handleUnexpectedException(e); + return false; + } catch (InterruptedException e) { + // not possible. Operation not cancelable. + } + + return true; + } + + private static void handleUnexpectedException(InvocationTargetException e) { + ExceptionHandler.handle(e, RefactoringMessages.getString("RefactoringWizard.refactoring"), RefactoringMessages.getString("RefactoringWizard.unexpected_exception_1")); //$NON-NLS-2$ //$NON-NLS-1$ + } +} diff --git a/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/PreviewWizardPage.java b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/PreviewWizardPage.java new file mode 100644 index 00000000000..8e961c1f4e4 --- /dev/null +++ b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/PreviewWizardPage.java @@ -0,0 +1,368 @@ +/********************************************************************** + * Copyright (c) 2004 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.internal.ui.refactoring; + +import org.eclipse.cdt.internal.corext.refactoring.base.Change; +import org.eclipse.cdt.internal.corext.refactoring.base.ChangeContext; +import org.eclipse.cdt.internal.corext.refactoring.base.IChange; +import org.eclipse.cdt.internal.corext.refactoring.base.ICompositeChange; +import org.eclipse.cdt.internal.corext.refactoring.changes.TextChange; +import org.eclipse.cdt.internal.ui.ICHelpContextIds; +import org.eclipse.cdt.internal.ui.util.ViewerPane; +import org.eclipse.cdt.ui.CElementLabelProvider; +import org.eclipse.compare.CompareUI; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.ToolBarManager; +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.viewers.CheckStateChangedEvent; +import org.eclipse.jface.viewers.ICheckStateListener; +import org.eclipse.jface.viewers.ILabelProvider; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.SashForm; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; +import org.eclipse.ui.help.WorkbenchHelp; +import org.eclipse.ui.part.PageBook; + +/** + * Presents the changes made by the refactoring. + * Consists of a tree of changes and a compare viewer that shows the differences. + */ +public class PreviewWizardPage extends RefactoringWizardPage implements IPreviewWizardPage { + // Dummy root node if input element isn't a composite change. + private static class DummyRootNode extends Change implements ICompositeChange { + private IChange[] fChildren; + + public DummyRootNode(IChange change) { + fChildren= new IChange[] { change }; + } + public IChange[] getChildren() { + return fChildren; + } + public String getName() { + return null; + } + public Object getModifiedLanguageElement() { + return null; + } + public IChange getUndoChange() { + return null; + } + public void perform(ChangeContext context, IProgressMonitor pm) { + } + } + + private static class NullPreviewer implements IChangePreviewViewer { + private Label fLabel; + public void createControl(Composite parent) { + fLabel= new Label(parent, SWT.CENTER | SWT.FLAT); + fLabel.setText(RefactoringMessages.getString("PreviewWizardPage.no_preview")); //$NON-NLS-1$ + } + public void refresh() { + } + public Control getControl() { + return fLabel; + } + public void setInput(Object input) throws CoreException { + } + } + + private class NextChange extends Action { + public NextChange() { + setImageDescriptor(CompareUI.DESC_ETOOL_NEXT); + setDisabledImageDescriptor(CompareUI.DESC_DTOOL_NEXT); + setHoverImageDescriptor(CompareUI.DESC_CTOOL_NEXT); + setToolTipText(RefactoringMessages.getString("PreviewWizardPage.next_Change")); //$NON-NLS-1$ + WorkbenchHelp.setHelp(this, ICHelpContextIds.NEXT_CHANGE_ACTION); + } + public void run() { + fTreeViewer.revealNext(); + } + } + + private class PreviousChange extends Action { + public PreviousChange() { + setImageDescriptor(CompareUI.DESC_ETOOL_PREV); + setDisabledImageDescriptor(CompareUI.DESC_DTOOL_PREV); + setHoverImageDescriptor(CompareUI.DESC_CTOOL_PREV); + setToolTipText(RefactoringMessages.getString("PreviewWizardPage.previous_Change")); //$NON-NLS-1$ + WorkbenchHelp.setHelp(this, ICHelpContextIds.PREVIOUS_CHANGE_ACTION); + } + public void run() { + fTreeViewer.revealPrevious(); + } + } + + private IChange fChange; + private ChangeElement fCurrentSelection; + private PageBook fPageContainer; + private Control fStandardPage; + private Control fNullPage; + private ChangeElementTreeViewer fTreeViewer; +////// +// private PageBook fPreviewContainer; +// private ChangePreviewViewerDescriptor fCurrentDescriptor; +// private IChangePreviewViewer fCurrentPreviewViewer; +// private IChangePreviewViewer fNullPreviewer; +////// + public PreviewWizardPage() { + super(PAGE_NAME); + setDescription(RefactoringMessages.getString("PreviewWizardPage.description")); //$NON-NLS-1$ + } + + public void setChange(IChange change) { + if (fChange == change) + return; + + fChange= change; + setTreeViewerInput(); + } + + protected ChangeElementTreeViewer createTreeViewer(Composite parent) { + return new ChangeElementTreeViewer(parent); + } + + protected ITreeContentProvider createTreeContentProvider() { + return new ChangeElementContentProvider(); + } + + protected ILabelProvider createTreeLabelProvider() { + return new ChangeElementLabelProvider(CElementLabelProvider.SHOW_DEFAULT | CElementLabelProvider.SHOW_SMALL_ICONS); + } + + protected boolean performFinish() { + return getRefactoringWizard().performFinish(new PerformChangeOperation(fChange)); + } + + public boolean canFlipToNextPage() { + return false; + } + + public void createControl(Composite parent) { + initializeDialogUnits(parent); + fPageContainer= new PageBook(parent, SWT.NONE); + fStandardPage= createStandardPreviewPage(fPageContainer); + fNullPage= createNullPage(fPageContainer); + setControl(fPageContainer); + WorkbenchHelp.setHelp(getControl(), ICHelpContextIds.REFACTORING_PREVIEW_WIZARD_PAGE); + } + + private Composite createStandardPreviewPage(Composite parent) { + // XXX The composite is needed to limit the width of the SashForm. See http://bugs.eclipse.org/bugs/show_bug.cgi?id=6854 + Composite result= new Composite(parent, SWT.NONE); + GridLayout layout= new GridLayout(); + layout.marginHeight= 0; layout.marginWidth= 0; + result.setLayout(layout); + + SashForm sashForm= new SashForm(result, SWT.HORIZONTAL); + + ViewerPane pane= new ViewerPane(sashForm, SWT.BORDER | SWT.FLAT); + pane.setText(RefactoringMessages.getString("PreviewWizardPage.changes")); //$NON-NLS-1$ + ToolBarManager tbm= pane.getToolBarManager(); + tbm.add(new NextChange()); + tbm.add(new PreviousChange()); + tbm.update(true); + + fTreeViewer= createTreeViewer(pane); + fTreeViewer.setContentProvider(createTreeContentProvider()); + fTreeViewer.setLabelProvider(createTreeLabelProvider()); + fTreeViewer.addSelectionChangedListener(createSelectionChangedListener()); + fTreeViewer.addCheckStateListener(createCheckStateListener()); + pane.setContent(fTreeViewer.getControl()); + setTreeViewerInput(); +//////// +// fPreviewContainer= new PageBook(sashForm, SWT.NONE); +// fNullPreviewer= new NullPreviewer(); +// fNullPreviewer.createControl(fPreviewContainer); +// fPreviewContainer.showPage(fNullPreviewer.getControl()); +// fCurrentPreviewViewer= fNullPreviewer; +// fCurrentDescriptor= null; +// sashForm.setWeights(new int[]{33, 67}); +//////// + GridData gd= new GridData(GridData.FILL_BOTH); + gd.widthHint= convertWidthInCharsToPixels(80); + sashForm.setLayoutData(gd); + Dialog.applyDialogFont(result); + return result; + } + + private Control createNullPage(Composite parent) { + Composite result= new Composite(parent, SWT.NONE); + GridLayout layout= new GridLayout(); + layout.marginWidth = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_MARGIN); + layout.marginHeight = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_MARGIN); + result.setLayout(layout); + Label label= new Label(result, SWT.CENTER); + label.setText(RefactoringMessages.getString("PreviewWizardPage.no_source_code_change")); //$NON-NLS-1$ + label.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + Dialog.applyDialogFont(result); + return result; + } + + public void setVisible(boolean visible) { + fCurrentSelection= null; + if (hasChanges()) { + fPageContainer.showPage(fStandardPage); + ChangeElement treeViewerInput= (ChangeElement)fTreeViewer.getInput(); + if (visible && treeViewerInput != null) { + IStructuredSelection selection= (IStructuredSelection)fTreeViewer.getSelection(); + if (selection.isEmpty()) { + ITreeContentProvider provider= (ITreeContentProvider)fTreeViewer.getContentProvider(); + Object[] elements= provider.getElements(treeViewerInput); + if (elements != null && elements.length > 0) { + Object element= elements[0]; + if (getRefactoringWizard().getExpandFirstNode()) { + Object[] subElements= provider.getElements(element); + if (subElements != null && subElements.length > 0) { + fTreeViewer.expandToLevel(element, 999); + } + } + fTreeViewer.setSelection(new StructuredSelection(element)); + } + } + } + super.setVisible(visible); + fTreeViewer.getControl().setFocus(); + } else { + fPageContainer.showPage(fNullPage); + super.setVisible(visible); + } + getRefactoringWizard().setPreviewShown(visible); + } + + private void setTreeViewerInput() { + ChangeElement input; + IChange change= computeChangeInput(); + if (change == null) { + input= null; + } else if (change instanceof ICompositeChange && !(change instanceof TextChange)) { + input= new DefaultChangeElement(null, change); + } else { + input= new DefaultChangeElement(null, new DummyRootNode(change)); + } + if (fTreeViewer != null) { + fTreeViewer.setInput(input); + } + } + + private IChange computeChangeInput() { + IChange result= fChange; + if (result == null) + return result; + while (true) { + if (result instanceof ICompositeChange) { + IChange[] children= ((ICompositeChange)result).getChildren(); + if (children.length == 1) { + result= children[0]; + } else { + return result; + } + } else { + return result; + } + } + } + + private ICheckStateListener createCheckStateListener() { + return new ICheckStateListener() { + public void checkStateChanged(CheckStateChangedEvent event){ + ChangeElement element= (ChangeElement)event.getElement(); + if (isChild(fCurrentSelection, element) || isChild(element, fCurrentSelection)) { + showPreview(fCurrentSelection); + } + } + private boolean isChild(ChangeElement element, ChangeElement child) { + while (child != null) { + if (child == element) + return true; + child= child.getParent(); + } + return false; + } + }; + } + + private ISelectionChangedListener createSelectionChangedListener() { + return new ISelectionChangedListener(){ + public void selectionChanged(SelectionChangedEvent event) { + IStructuredSelection sel= (IStructuredSelection) event.getSelection(); + if (sel.size() == 1) { + ChangeElement newSelection= (ChangeElement)sel.getFirstElement(); + if (newSelection != fCurrentSelection) { + fCurrentSelection= newSelection; + showPreview(newSelection); + } + } else { + showPreview(null); + } + } + }; + } + + private void showPreview(ChangeElement element) { +///////////// +// try { +// if (element == null) { + showNullPreviewer(); +// } else { +// ChangePreviewViewerDescriptor descriptor= element.getChangePreviewViewer(); +// if (fCurrentDescriptor != descriptor) { +// IChangePreviewViewer newViewer; +// if (descriptor != null) { +// newViewer= descriptor.createViewer(); +// newViewer.createControl(fPreviewContainer); +// } else { +// newViewer= fNullPreviewer; +// } +// fCurrentDescriptor= descriptor; +// element.feedInput(newViewer); +// if (fCurrentPreviewViewer != null && fCurrentPreviewViewer != fNullPreviewer) +// fCurrentPreviewViewer.getControl().dispose(); +// fCurrentPreviewViewer= newViewer; +// fPreviewContainer.showPage(fCurrentPreviewViewer.getControl()); +// } else { +// element.feedInput(fCurrentPreviewViewer); +// } +// } +// } catch (CoreException e) { +// showNullPreviewer(); +// } +/////////// + } + + private void showNullPreviewer() { +///////// +// fCurrentDescriptor= null; +// fCurrentPreviewViewer= fNullPreviewer; +// fPreviewContainer.showPage(fCurrentPreviewViewer.getControl()); +///////// + } + + public boolean hasChanges() { + if (fChange == null) + return false; + if (fChange instanceof ICompositeChange) + return ((ICompositeChange)fChange).getChildren().length > 0; + return true; + } + +} diff --git a/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/PseudoCChangeElement.java b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/PseudoCChangeElement.java new file mode 100644 index 00000000000..9963cc2b2ce --- /dev/null +++ b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/PseudoCChangeElement.java @@ -0,0 +1,163 @@ +/********************************************************************** + * Copyright (c) 2004 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.internal.ui.refactoring; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.eclipse.cdt.core.model.ICElement; +import org.eclipse.cdt.core.model.ISourceRange; +import org.eclipse.cdt.core.model.ISourceReference; +import org.eclipse.cdt.internal.corext.refactoring.base.IChange; +import org.eclipse.cdt.internal.corext.refactoring.changes.TextChange; +import org.eclipse.cdt.internal.corext.refactoring.changes.TextChange.EditChange; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.jface.text.IRegion; +import org.eclipse.jface.text.Region; +import org.eclipse.jface.util.Assert; + +/* package */ class PseudoCChangeElement extends ChangeElement { + + private ICElement fCElement; + private List fChildren; + + public PseudoCChangeElement(ChangeElement parent, ICElement element) { + super(parent); + fCElement= element; + Assert.isNotNull(fCElement); + } + + /** + * Returns the C element. + * + * @return the C element managed by this node + */ + public ICElement getCElement() { + return fCElement; + } + + /* (non-Cdoc) + * @see org.eclipse.jdt.internal.ui.refactoring.ChangeElement#getChangePreviewViewer() + */ +// public ChangePreviewViewerDescriptor getChangePreviewViewer() throws CoreException { +// DefaultChangeElement element= getStandardChangeElement(); +// if (element == null) +// return null; +// return element.getChangePreviewViewer(); +// } + + /* (non-Javadoc) + * @see org.eclipse.jdt.internal.ui.refactoring.ChangeElement#feedInput(org.eclipse.jdt.internal.ui.refactoring.IChangePreviewViewer) + */ + public void feedInput(IChangePreviewViewer viewer) throws CoreException { + DefaultChangeElement element= getStandardChangeElement(); + if (element != null) { + IChange change= element.getChange(); + if (change instanceof TextChange) { + List edits= collectTextEditChanges(); + viewer.setInput(TextChangePreviewViewer.createInput( + (EditChange[])edits.toArray(new EditChange[edits.size()]), + getTextRange())); + } + } else { + viewer.setInput(null); + } + } + + /* non Java-doc + * @see ChangeElement#setActive + */ + public void setActive(boolean active) { + for (Iterator iter= fChildren.iterator(); iter.hasNext();) { + ChangeElement element= (ChangeElement)iter.next(); + element.setActive(active); + } + } + + /* non Java-doc + * @see ChangeElement.getActive + */ + public int getActive() { + Assert.isTrue(fChildren.size() > 0); + int result= ((ChangeElement)fChildren.get(0)).getActive(); + for (int i= 1; i < fChildren.size(); i++) { + ChangeElement element= (ChangeElement)fChildren.get(i); + result= ACTIVATION_TABLE[element.getActive()][result]; + if (result == PARTLY_ACTIVE) + break; + } + return result; + } + + /* non Java-doc + * @see ChangeElement.getChildren + */ + public ChangeElement[] getChildren() { + if (fChildren == null) + return EMPTY_CHILDREN; + return (ChangeElement[]) fChildren.toArray(new ChangeElement[fChildren.size()]); + } + + /** + * Adds the given TextEditChangeElement as a child to this + * PseudoCChangeElement + * + * @param child the child to be added + */ + public void addChild(TextEditChangeElement child) { + doAddChild(child); + } + + /** + * Adds the given PseudoCChangeElement as a child to this + * PseudoCChangeElement + * + * @param child the child to be added + */ + public void addChild(PseudoCChangeElement child) { + doAddChild(child); + } + + private void doAddChild(ChangeElement child) { + if (fChildren == null) + fChildren= new ArrayList(2); + fChildren.add(child); + } + + private DefaultChangeElement getStandardChangeElement() { + ChangeElement element= getParent(); + while(!(element instanceof DefaultChangeElement) && element != null) { + element= element.getParent(); + } + return (DefaultChangeElement)element; + } + + private List collectTextEditChanges() { + List result= new ArrayList(10); + ChangeElement[] children= getChildren(); + for (int i= 0; i < children.length; i++) { + ChangeElement child= children[i]; + if (child instanceof TextEditChangeElement) { + result.add(((TextEditChangeElement)child).getTextEditChange()); + } else if (child instanceof PseudoCChangeElement) { + result.addAll(((PseudoCChangeElement)child).collectTextEditChanges()); + } + } + return result; + } + + public IRegion getTextRange() throws CoreException { + ISourceRange range= ((ISourceReference)fCElement).getSourceRange(); + return new Region(range.getStartPos(), range.getLength()); + } +} + diff --git a/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/RefactoringErrorDialogUtil.java b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/RefactoringErrorDialogUtil.java new file mode 100644 index 00000000000..a2b31004651 --- /dev/null +++ b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/RefactoringErrorDialogUtil.java @@ -0,0 +1,60 @@ +/********************************************************************** + * Copyright (c) 2004 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.internal.ui.refactoring; + +import org.eclipse.swt.widgets.Shell; + +import org.eclipse.jface.dialogs.MessageDialog; + +import org.eclipse.cdt.internal.ui.refactoring.RefactoringMessages; +import org.eclipse.cdt.internal.ui.refactoring.RefactoringStatusContentProvider; +import org.eclipse.cdt.internal.ui.refactoring.RefactoringStatusEntryLabelProvider; + +import org.eclipse.cdt.internal.corext.refactoring.base.RefactoringStatus; +import org.eclipse.cdt.internal.corext.refactoring.base.RefactoringStatusCodes; +import org.eclipse.cdt.internal.corext.refactoring.base.RefactoringStatusEntry; + +public class RefactoringErrorDialogUtil { + + private RefactoringErrorDialogUtil() { + // no instance. + } + + public static Object open(String dialogTitle, RefactoringStatus status, Shell parentShell) { + if (status.getEntries().size() == 1) { + RefactoringStatusEntry entry= (RefactoringStatusEntry)status.getEntries().get(0); + String message= status.getFirstMessage(RefactoringStatus.FATAL); + + if ( entry.getCode() != RefactoringStatusCodes.OVERRIDES_ANOTHER_METHOD + && entry.getCode() != RefactoringStatusCodes.METHOD_DECLARED_IN_INTERFACE){ + MessageDialog.openInformation(parentShell, dialogTitle, message); + return null; + } + message= message + RefactoringMessages.getString("RefactoringErrorDialogUtil.okToPerformQuestion"); //$NON-NLS-1$ + if (MessageDialog.openQuestion(parentShell, dialogTitle, message)) + return entry.getData(); + return null; + } else { + openListDialog(dialogTitle, status, parentShell); + return null; + } + } + + private static void openListDialog(String dialogTitle, RefactoringStatus status, Shell parentShell) { + ListDialog dialog= new ListDialog(parentShell); + dialog.setInput(status); + dialog.setTitle(dialogTitle); + dialog.setMessage(RefactoringMessages.getString("RefactoringErrorDialogUtil.cannot_perform")); //$NON-NLS-1$ + dialog.setContentProvider(new RefactoringStatusContentProvider()); + dialog.setLabelProvider(new RefactoringStatusEntryLabelProvider()); + dialog.open(); + } +} diff --git a/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/RefactoringMessages.java b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/RefactoringMessages.java new file mode 100644 index 00000000000..82527853112 --- /dev/null +++ b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/RefactoringMessages.java @@ -0,0 +1,49 @@ +/********************************************************************** + * Copyright (c) 2004 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.internal.ui.refactoring; + +import java.text.MessageFormat; +import java.util.MissingResourceException; +import java.util.ResourceBundle; + +public class RefactoringMessages { + + private static final String RESOURCE_BUNDLE= "org.eclipse.cdt.internal.ui.refactoring.refactoringui";//$NON-NLS-1$ + + private static ResourceBundle fgResourceBundle= ResourceBundle.getBundle(RESOURCE_BUNDLE); + + private RefactoringMessages() { + } + + public static String getString(String key) { + try { + return fgResourceBundle.getString(key); + } catch (MissingResourceException e) { + return "!" + key + "!";//$NON-NLS-2$ //$NON-NLS-1$ + } + } + + public static String[] getStrings(String keys[]) { + String[] result= new String[keys.length]; + for (int i= 0; i < keys.length; i++) { + result[i]= getString(keys[i]); + } + return result; + } + + public static String getFormattedString(String key, Object arg) { + return getFormattedString(key, new Object[] { arg }); + } + + public static String getFormattedString(String key, Object[] args) { + return MessageFormat.format(getString(key), args); + } +} diff --git a/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/RefactoringPreferences.java b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/RefactoringPreferences.java new file mode 100644 index 00000000000..78c531282a5 --- /dev/null +++ b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/RefactoringPreferences.java @@ -0,0 +1,56 @@ +/********************************************************************** + * Copyright (c) 2004 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation +***********************************************************************/ + +package org.eclipse.cdt.internal.ui.refactoring; + +import org.eclipse.jface.preference.IPreferenceStore; + +import org.eclipse.cdt.ui.PreferenceConstants; + +import org.eclipse.cdt.internal.corext.refactoring.base.RefactoringStatus; +import org.eclipse.cdt.ui.CUIPlugin; + +public class RefactoringPreferences { + + public static final String PREF_ERROR_PAGE_SEVERITY_THRESHOLD= PreferenceConstants.REFACTOR_ERROR_PAGE_SEVERITY_THRESHOLD; + public static final String PREF_SAVE_ALL_EDITORS= PreferenceConstants.REFACTOR_SAVE_ALL_EDITORS; + + public static int getCheckPassedSeverity() { + String value= CUIPlugin.getDefault().getPreferenceStore().getString(PREF_ERROR_PAGE_SEVERITY_THRESHOLD); + try { + return Integer.valueOf(value).intValue() - 1; + } catch (NumberFormatException e) { + return RefactoringStatus.ERROR; + } + } + + public static int getStopSeverity() { + switch (getCheckPassedSeverity()) { + case RefactoringStatus.OK: + return RefactoringStatus.INFO; + case RefactoringStatus.INFO: + return RefactoringStatus.WARNING; + case RefactoringStatus.WARNING: + return RefactoringStatus.ERROR; + } + return RefactoringStatus.FATAL; + } + + public static boolean getSaveAllEditors() { + IPreferenceStore store= CUIPlugin.getDefault().getPreferenceStore(); + return store.getBoolean(PREF_SAVE_ALL_EDITORS); + } + + public static void setSaveAllEditors(boolean save) { + IPreferenceStore store= CUIPlugin.getDefault().getPreferenceStore(); + store.setValue(RefactoringPreferences.PREF_SAVE_ALL_EDITORS, save); + } +} diff --git a/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/RefactoringSaveHelper.java b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/RefactoringSaveHelper.java new file mode 100644 index 00000000000..22eac99875c --- /dev/null +++ b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/RefactoringSaveHelper.java @@ -0,0 +1,121 @@ +/********************************************************************** + * Copyright (c) 2004 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.internal.ui.refactoring; + +import java.util.Arrays; + +import org.eclipse.core.resources.IWorkspace; +import org.eclipse.core.resources.IWorkspaceDescription; +import org.eclipse.core.resources.IncrementalProjectBuilder; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Shell; + +import org.eclipse.jface.viewers.ILabelProvider; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.jface.window.Window; + +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.actions.GlobalBuildAction; + +import org.eclipse.cdt.ui.CUIPlugin; +import org.eclipse.cdt.internal.ui.refactoring.ListDialog; +import org.eclipse.cdt.internal.ui.util.ExceptionHandler; +import org.eclipse.cdt.internal.ui.refactoring.ListContentProvider; + +public class RefactoringSaveHelper { + + private boolean fFilesSaved; + + public RefactoringSaveHelper() { + super(); + } + + public boolean saveEditors(Shell shell) { + IEditorPart[] dirtyEditors= CUIPlugin.getDirtyEditors(); + if (dirtyEditors.length == 0) + return true; + if (! saveAllDirtyEditors(shell)) + return false; + try { + // Save isn't cancelable. + IWorkspace workspace= ResourcesPlugin.getWorkspace(); + IWorkspaceDescription description= workspace.getDescription(); + boolean autoBuild= description.isAutoBuilding(); + description.setAutoBuilding(false); + workspace.setDescription(description); + try { + CUIPlugin.getDefault().getActiveWorkbenchWindow().getWorkbench().saveAllEditors(false); + fFilesSaved= true; + } finally { + description.setAutoBuilding(autoBuild); + workspace.setDescription(description); + } + return true; + } catch (CoreException e) { + ExceptionHandler.handle(e, shell, + RefactoringMessages.getString("RefactoringStarter.saving"), RefactoringMessages.getString("RefactoringStarter.unexpected_exception")); //$NON-NLS-1$ //$NON-NLS-2$ + return false; + } + } + + public void triggerBuild() { + if (fFilesSaved && ResourcesPlugin.getWorkspace().getDescription().isAutoBuilding()) { + new GlobalBuildAction(CUIPlugin.getDefault().getActiveWorkbenchWindow(), IncrementalProjectBuilder.INCREMENTAL_BUILD).run(); + } + } + + private boolean saveAllDirtyEditors(Shell shell) { + if (RefactoringPreferences.getSaveAllEditors()) //must save everything + return true; + ListDialog dialog= new ListDialog(shell) { + protected Control createDialogArea(Composite parent) { + Composite result= (Composite) super.createDialogArea(parent); + final Button check= new Button(result, SWT.CHECK); + check.setText(RefactoringMessages.getString("RefactoringStarter.always_save")); //$NON-NLS-1$ + check.setSelection(RefactoringPreferences.getSaveAllEditors()); + check.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + RefactoringPreferences.setSaveAllEditors(check.getSelection()); + } + }); + applyDialogFont(result); + return result; + } + }; + dialog.setTitle(RefactoringMessages.getString("RefactoringStarter.save_all_resources")); //$NON-NLS-1$ + dialog.setAddCancelButton(true); + dialog.setLabelProvider(createDialogLabelProvider()); + dialog.setMessage(RefactoringMessages.getString("RefactoringStarter.must_save")); //$NON-NLS-1$ + dialog.setContentProvider(new ListContentProvider()); + dialog.setInput(Arrays.asList(CUIPlugin.getDirtyEditors())); + return dialog.open() == Window.OK; + } + + private ILabelProvider createDialogLabelProvider() { + return new LabelProvider() { + public Image getImage(Object element) { + return ((IEditorPart) element).getTitleImage(); + } + public String getText(Object element) { + return ((IEditorPart) element).getTitle(); + } + }; + } +} diff --git a/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/RefactoringStarter.java b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/RefactoringStarter.java new file mode 100644 index 00000000000..41b5eff55c4 --- /dev/null +++ b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/RefactoringStarter.java @@ -0,0 +1,81 @@ +/********************************************************************** + * Copyright (c) 2004 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.internal.ui.refactoring; + + +import java.lang.reflect.InvocationTargetException; + +import org.eclipse.swt.widgets.Shell; + +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.operation.IRunnableContext; +import org.eclipse.jface.util.Assert; +import org.eclipse.jface.window.Window; + +import org.eclipse.cdt.core.model.CModelException; + +import org.eclipse.cdt.internal.ui.refactoring.CheckConditionsOperation; +import org.eclipse.cdt.internal.ui.refactoring.RefactoringMessages; +import org.eclipse.cdt.internal.ui.refactoring.RefactoringSaveHelper; +import org.eclipse.cdt.internal.ui.refactoring.RefactoringWizard; +import org.eclipse.cdt.internal.ui.refactoring.RefactoringWizardDialog; +import org.eclipse.cdt.internal.ui.refactoring.RefactoringWizardDialog2; +import org.eclipse.cdt.internal.ui.util.BusyIndicatorRunnableContext; +import org.eclipse.cdt.internal.ui.util.ExceptionHandler; + +import org.eclipse.cdt.internal.corext.refactoring.base.Refactoring; +import org.eclipse.cdt.internal.corext.refactoring.base.RefactoringStatus; + +/** + * A helper class to activate the UI of a refactoring + */ +public class RefactoringStarter { + + private RefactoringSaveHelper fSaveHelper= new RefactoringSaveHelper(); + + public Object activate(Refactoring refactoring, RefactoringWizard wizard, Shell parent, String dialogTitle, boolean mustSaveEditors) throws CModelException { + if (! canActivate(mustSaveEditors, parent)) + return null; + RefactoringStatus activationStatus= checkActivation(refactoring); + if (activationStatus.hasFatalError()){ + return RefactoringErrorDialogUtil.open(dialogTitle, activationStatus, parent); + } else { + wizard.setActivationStatus(activationStatus); + Dialog dialog; + if (wizard.hasMultiPageUserInput()) + dialog= new RefactoringWizardDialog(parent, wizard); + else + dialog= new RefactoringWizardDialog2(parent, wizard); + if (dialog.open() == Window.CANCEL) + fSaveHelper.triggerBuild(); + return null; + } + } + + private RefactoringStatus checkActivation(Refactoring refactoring){ + try { + CheckConditionsOperation cco= new CheckConditionsOperation(refactoring, CheckConditionsOperation.ACTIVATION); + IRunnableContext context= new BusyIndicatorRunnableContext(); + context.run(false, false, cco); + return cco.getStatus(); + } catch (InvocationTargetException e) { + ExceptionHandler.handle(e, "Error", RefactoringMessages.getString("RefactoringStarter.unexpected_exception"));//$NON-NLS-1$ //$NON-NLS-2$ + return RefactoringStatus.createFatalErrorStatus(RefactoringMessages.getString("RefactoringStarter.unexpected_exception"));//$NON-NLS-1$ + } catch (InterruptedException e) { + Assert.isTrue(false); + return null; + } + } + + private boolean canActivate(boolean mustSaveEditors, Shell shell) { + return ! mustSaveEditors || fSaveHelper.saveEditors(shell); + } +} diff --git a/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/RefactoringStatusContentProvider.java b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/RefactoringStatusContentProvider.java new file mode 100644 index 00000000000..e37671f3b9f --- /dev/null +++ b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/RefactoringStatusContentProvider.java @@ -0,0 +1,30 @@ +/********************************************************************** + * Copyright (c) 2004 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.internal.ui.refactoring; + +import org.eclipse.jface.viewers.IStructuredContentProvider; +import org.eclipse.jface.viewers.Viewer; + +import org.eclipse.cdt.internal.corext.refactoring.base.RefactoringStatus; + +public class RefactoringStatusContentProvider implements IStructuredContentProvider{ + + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + } + + public void dispose() { + } + + public Object[] getElements(Object obj) { + return ((RefactoringStatus)obj).getEntries().toArray(); + } +} + diff --git a/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/RefactoringStatusDialog.java b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/RefactoringStatusDialog.java new file mode 100644 index 00000000000..006b9e041f8 --- /dev/null +++ b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/RefactoringStatusDialog.java @@ -0,0 +1,104 @@ +/********************************************************************** + * Copyright (c) 2004 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.internal.ui.refactoring; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.ViewForm; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; + +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.dialogs.IDialogConstants; + +import org.eclipse.cdt.internal.corext.refactoring.base.RefactoringStatus; + +class RefactoringStatusDialog extends Dialog { + + private RefactoringStatus fStatus; + private String fWindowTitle; + private boolean fBackButton; + + public RefactoringStatusDialog(Shell parent, RefactoringStatus status, String windowTitle, boolean backButton) { + super(parent); + fStatus= status; + fWindowTitle= windowTitle; + fBackButton= backButton; + setShellStyle(getShellStyle() | SWT.RESIZE); + } + + public RefactoringStatusDialog(Shell parent, ErrorWizardPage page, boolean backButton) { + this(parent, page.getStatus(), parent.getText(), backButton); + } + + protected void configureShell(Shell newShell) { + super.configureShell(newShell); + newShell.setText(fWindowTitle); + } + protected Control createDialogArea(Composite parent) { + Composite result= new Composite(parent, SWT.NONE); + initializeDialogUnits(result); + GridLayout layout= new GridLayout(); + result.setLayout(layout); + GridData gd= new GridData(GridData.FILL_BOTH); + gd.widthHint= 600; + gd.heightHint= 400; + result.setLayoutData(gd); + Color background= parent.getDisplay().getSystemColor(SWT.COLOR_INFO_BACKGROUND); + ViewForm messagePane= new ViewForm(result, SWT.BORDER | SWT.FLAT); + messagePane.marginWidth= layout.marginWidth; + messagePane.marginHeight= layout.marginHeight; + gd= new GridData(GridData.FILL_HORIZONTAL); + // XXX http://bugs.eclipse.org/bugs/show_bug.cgi?id=27572 + Rectangle rect= messagePane.computeTrim(0, 0, 0, convertHeightInCharsToPixels(2) + messagePane.marginHeight * 2); + gd.heightHint= rect.height; + messagePane.setLayoutData(gd); + messagePane.setBackground(background); + Label label= new Label(messagePane, SWT.LEFT | SWT.WRAP); + if (fStatus.hasFatalError()) + label.setText(RefactoringMessages.getString("RefactoringStatusDialog.Cannot_proceed")); //$NON-NLS-1$ + else + label.setText(RefactoringMessages.getString("RefactoringStatusDialog.Please_look")); //$NON-NLS-1$ + label.setBackground(background); + messagePane.setContent(label); + RefactoringStatusViewer viewer= new RefactoringStatusViewer(result, SWT.NONE); + viewer.setLayoutData(new GridData(GridData.FILL_BOTH)); + viewer.setStatus(fStatus); + applyDialogFont(result); + return result; + } + protected void buttonPressed(int buttonId) { + if (buttonId == IDialogConstants.BACK_ID) { + setReturnCode(IDialogConstants.BACK_ID); + close(); + } else { + super.buttonPressed(buttonId); + } + } + + protected void createButtonsForButtonBar(Composite parent) { + if (!fStatus.hasFatalError()) { + if (fBackButton) + createButton(parent, IDialogConstants.BACK_ID, IDialogConstants.BACK_LABEL, false); //$NON-NLS-1$ + createButton(parent, IDialogConstants.OK_ID, RefactoringMessages.getString("RefactoringStatusDialog.Continue"), true); //$NON-NLS-1$ + createButton(parent, IDialogConstants.CANCEL_ID, IDialogConstants.CANCEL_LABEL, false); + } else { + if (fBackButton) + createButton(parent, IDialogConstants.BACK_ID, IDialogConstants.BACK_LABEL, true); //$NON-NLS-1$ + createButton(parent, IDialogConstants.CANCEL_ID, IDialogConstants.CANCEL_LABEL, false); + } + } +} diff --git a/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/RefactoringStatusEntryLabelProvider.java b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/RefactoringStatusEntryLabelProvider.java new file mode 100644 index 00000000000..c6afa5929c0 --- /dev/null +++ b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/RefactoringStatusEntryLabelProvider.java @@ -0,0 +1,36 @@ +/********************************************************************** + * Copyright (c) 2004 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.internal.ui.refactoring; + +import org.eclipse.swt.graphics.Image; + +import org.eclipse.jface.viewers.LabelProvider; + +import org.eclipse.cdt.internal.corext.refactoring.base.RefactoringStatusEntry; +import org.eclipse.cdt.internal.ui.util.Strings; +import org.eclipse.cdt.internal.ui.CPluginImages; + +public class RefactoringStatusEntryLabelProvider extends LabelProvider{ + public String getText(Object element){ + return Strings.removeNewLine(((RefactoringStatusEntry)element).getMessage()); + } + public Image getImage(Object element){ + RefactoringStatusEntry entry= (RefactoringStatusEntry)element; + if (entry.isFatalError()) + return CPluginImages.get(CPluginImages.IMG_OBJS_REFACTORING_FATAL); + else if (entry.isError()) + return CPluginImages.get(CPluginImages.IMG_OBJS_REFACTORING_ERROR); + else if (entry.isWarning()) + return CPluginImages.get(CPluginImages.IMG_OBJS_REFACTORING_WARNING); + else + return CPluginImages.get(CPluginImages.IMG_OBJS_REFACTORING_INFO); + } +} diff --git a/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/RefactoringStatusViewer.java b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/RefactoringStatusViewer.java new file mode 100644 index 00000000000..5301a5469c8 --- /dev/null +++ b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/RefactoringStatusViewer.java @@ -0,0 +1,346 @@ +/********************************************************************** + * Copyright (c) 2004 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.internal.ui.refactoring; + +import java.util.List; + +import org.eclipse.cdt.internal.corext.refactoring.base.Context; +import org.eclipse.cdt.internal.corext.refactoring.base.RefactoringStatus; +import org.eclipse.cdt.internal.corext.refactoring.base.RefactoringStatusEntry; +import org.eclipse.cdt.internal.ui.ICHelpContextIds; +import org.eclipse.cdt.internal.ui.util.PixelConverter; +import org.eclipse.cdt.internal.ui.util.ViewerPane; +import org.eclipse.compare.CompareUI; +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.ToolBarManager; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.viewers.ViewerSorter; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.SashForm; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.TableColumn; +import org.eclipse.ui.help.WorkbenchHelp; +import org.eclipse.ui.model.IWorkbenchAdapter; +import org.eclipse.ui.part.PageBook; + +class RefactoringStatusViewer extends SashForm { + + private static class NullContextViewer implements IStatusContextViewer { + private Label fLabel; + public NullContextViewer() { + } + public void createControl(Composite parent) { + fLabel= new Label(parent, SWT.CENTER | SWT.FLAT); + fLabel.setText(RefactoringMessages.getString("ErrorWizardPage.no_context_information_available")); //$NON-NLS-1$ + } + public void setInput(Context input) { + // do nothing + } + public Control getControl() { + return fLabel; + } + } + + private class NextProblem extends Action { + public NextProblem() { + setImageDescriptor(CompareUI.DESC_ETOOL_NEXT); + setDisabledImageDescriptor(CompareUI.DESC_DTOOL_NEXT); + setHoverImageDescriptor(CompareUI.DESC_CTOOL_NEXT); + setToolTipText(RefactoringMessages.getString("ErrorWizardPage.next_Change")); //$NON-NLS-1$ + WorkbenchHelp.setHelp(this, ICHelpContextIds.NEXT_PROBLEM_ACTION); + } + public void run() { + revealElement(true); + } + public void update() { + boolean enabled= false; + List entries= null; + if (fStatus != null && !(entries= fStatus.getEntries()).isEmpty()) { + int index= fTableViewer.getTable().getSelectionIndex(); + enabled= index == -1 || index < entries.size() - 1; + } + setEnabled(enabled); + } + } + + private class PreviousProblem extends Action { + public PreviousProblem() { + setImageDescriptor(CompareUI.DESC_ETOOL_PREV); + setDisabledImageDescriptor(CompareUI.DESC_DTOOL_PREV); + setHoverImageDescriptor(CompareUI.DESC_CTOOL_PREV); + setToolTipText(RefactoringMessages.getString("ErrorWizardPage.previous_Change")); //$NON-NLS-1$ + WorkbenchHelp.setHelp(this, ICHelpContextIds.PREVIOUS_PROBLEM_ACTION); + } + public void run() { + revealElement(false); + } + public void update() { + boolean enabled= false; + if (fStatus != null && !fStatus.getEntries().isEmpty()) { + int index= fTableViewer.getTable().getSelectionIndex(); + enabled= index == -1 || index > 0; + } + setEnabled(enabled); + } + } + + private static class RefactoringStatusSorter extends ViewerSorter { + public int compare(Viewer viewer, Object e1, Object e2) { + int r1= ((RefactoringStatusEntry)e1).getSeverity(); + int r2= ((RefactoringStatusEntry)e2).getSeverity(); + if (r1 < r2) + return 1; + if (r2 < r1) + return -1; + return 0; + } + + } + + private RefactoringStatus fStatus; + private TableViewer fTableViewer; + private PageBook fContextViewerContainer; + private ViewerPane fContextViewerPane; + private Image fPaneImage; + private StatusContextViewerDescriptor fCurrentDescriptor; + private IStatusContextViewer fCurrentContextViewer; + private NullContextViewer fNullContextViewer; + + private NextProblem fNextProblem; + private PreviousProblem fPreviousProblem; + + public RefactoringStatusViewer(Composite parent, int style) { + super(parent, style | SWT.VERTICAL); + createContents(); + } + + /** + * Sets the refactoring status. + * @param the refactoring status. + */ + public void setStatus(RefactoringStatus status){ + fStatus= status; + if (fTableViewer.getInput() != fStatus) { + fTableViewer.setInput(fStatus); + fTableViewer.getTable().getColumn(0).pack(); + ISelection selection= fTableViewer.getSelection(); + if (selection.isEmpty()) { + RefactoringStatusEntry entry= getFirstEntry(); + if (entry != null) { + fTableViewer.setSelection(new StructuredSelection(entry)); + showContextViewer(entry); + fTableViewer.getControl().setFocus(); + } + } + fNextProblem.update(); + fPreviousProblem.update(); + } + } + + /** + * Returns the currently used RefactoringStatus. + * @return the RefactoringStatus + */ + public RefactoringStatus getStatus() { + return fStatus; + } + + //---- UI creation ---------------------------------------------------------------------- + + public Point computeSize (int wHint, int hHint, boolean changed) { + PixelConverter converter= new PixelConverter(this); + return new Point(converter.convertWidthInCharsToPixels(90), converter.convertHeightInCharsToPixels(25)); + } + + private void createContents() { + GridLayout layout= new GridLayout(); + layout.numColumns= 1; layout.marginWidth= 0; layout.marginHeight= 0; + setLayout(layout); + + ViewerPane contextPane= new ViewerPane(this, SWT.BORDER | SWT.FLAT); + contextPane.setText(RefactoringMessages.getString("RefactoringStatusViewer.Found_problems")); //$NON-NLS-1$ + ToolBarManager tbm= contextPane.getToolBarManager(); + tbm.add(fNextProblem= new NextProblem()); + tbm.add(fPreviousProblem= new PreviousProblem()); + tbm.update(true); + createTableViewer(contextPane); + contextPane.setContent(fTableViewer.getControl()); + + fContextViewerPane= new ViewerPane(this, SWT.BORDER | SWT.FLAT); + fContextViewerContainer= new PageBook(fContextViewerPane, SWT.NONE); + fNullContextViewer= new NullContextViewer(); + fNullContextViewer.createControl(fContextViewerContainer); + fContextViewerContainer.showPage(fNullContextViewer.getControl()); + fCurrentContextViewer= fNullContextViewer; + fContextViewerPane.setContent(fContextViewerContainer); + fCurrentContextViewer= fNullContextViewer; + fCurrentDescriptor= null; + + setWeights(new int[]{35, 65}); + + addDisposeListener(new DisposeListener() { + public void widgetDisposed(DisposeEvent e) { + if (fPaneImage != null) { + fPaneImage.dispose(); + fPaneImage= null; + } + } + }); + } + + private void createTableViewer(Composite parent) { + fTableViewer= new TableViewer(new Table(parent, SWT.SINGLE | SWT.H_SCROLL)); + fTableViewer.setLabelProvider(new RefactoringStatusEntryLabelProvider()); + fTableViewer.setContentProvider(new RefactoringStatusContentProvider()); + fTableViewer.addSelectionChangedListener(new ISelectionChangedListener() { + public void selectionChanged(SelectionChangedEvent event) { + entrySelected(event.getSelection()); + fNextProblem.update(); + fPreviousProblem.update(); + } + }); + fTableViewer.setSorter(new RefactoringStatusSorter()); + Table tableControl= fTableViewer.getTable(); + GridData gd= new GridData(GridData.FILL_BOTH); + tableControl.setLayoutData(gd); + // Add a column so that we can pack it in setVisible. + TableColumn tc= new TableColumn(tableControl, SWT.NONE); + tc.setResizable(false); + } + + //---- Feed status entry into context viewer --------------------------------------------------------- + + private void entrySelected(ISelection s) { + if (!(s instanceof IStructuredSelection)) + return; + Object first= ((IStructuredSelection) s).getFirstElement(); + if (! (first instanceof RefactoringStatusEntry)) + return; + + RefactoringStatusEntry entry= (RefactoringStatusEntry)first; + updateTitle(entry); + showContextViewer(entry); + } + + private void updateTitle(RefactoringStatusEntry first) { + IAdaptable element= getCorrespondingElement(first); + String title= null; + ImageDescriptor imageDescriptor= null; + if (element != null) { + IWorkbenchAdapter adapter= (IWorkbenchAdapter)element.getAdapter(IWorkbenchAdapter.class); + if (adapter != null) { + title= adapter.getLabel(element); + imageDescriptor= adapter.getImageDescriptor(element); + } + } + if (title == null || title.length() == 0) + title= RefactoringMessages.getString("RefactoringStatusViewer.Problem_context"); //$NON-NLS-1$ + fContextViewerPane.setText(title); + if (imageDescriptor != null) { + if (fPaneImage != null) { + fPaneImage.dispose(); + fPaneImage= null; + } + fPaneImage= imageDescriptor.createImage(fContextViewerPane.getDisplay()); + fContextViewerPane.setImage(fPaneImage); + } + } + + private static IAdaptable getCorrespondingElement(RefactoringStatusEntry first){ + if (first.getContext() == null) + return null; + else + return first.getContext().getCorrespondingElement(); + } + + private void showContextViewer(RefactoringStatusEntry entry) { +/* Context context= entry.getContext(); + if (context == null) { + showNullContextViewer(); + } else { + try { + StatusContextViewerDescriptor descriptor= StatusContextViewerDescriptor.get(context); + if (fCurrentDescriptor != descriptor) { + IStatusContextViewer newViewer; + if (descriptor != null) { + newViewer= descriptor.createViewer(); + newViewer.createControl(fContextViewerContainer); + } else { + newViewer= fNullContextViewer; + } + fCurrentDescriptor= descriptor; + newViewer.setInput(context); + if (fCurrentContextViewer != null && fCurrentContextViewer != fNullContextViewer) + fCurrentContextViewer.getControl().dispose(); + fCurrentContextViewer= newViewer; + fContextViewerContainer.showPage(fCurrentContextViewer.getControl()); + } else { + fCurrentContextViewer.setInput(context); + } + } catch (CoreException e) { + showNullContextViewer(); + } + } +*/ } + + private void showNullContextViewer() { + fCurrentContextViewer= fNullContextViewer; + fCurrentDescriptor= null; + fContextViewerContainer.showPage(fCurrentContextViewer.getControl()); + } + + //---- Helpers ---------------------------------------------------------------------------------------- + + private RefactoringStatusEntry getFirstEntry(){ + if (fStatus == null || fStatus.getEntries().isEmpty()) + return null; + return (RefactoringStatusEntry)fStatus.getEntries().get(0); + } + + private void revealElement(boolean next) { + List entries= fStatus.getEntries(); + if (entries.isEmpty()) { + return; + } + int index= fTableViewer.getTable().getSelectionIndex(); + int last= entries.size() - 1; + boolean doIt= true; + if (index == -1) { + index= 0; + } else if (next && index < last) { + index++; + } else if (!next && index > 0) { + index--; + } else { + doIt= false; + } + if (doIt) + fTableViewer.setSelection(new StructuredSelection(entries.get(index))); + } + +} diff --git a/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/RefactoringWizard.java b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/RefactoringWizard.java new file mode 100644 index 00000000000..082f88fbdd0 --- /dev/null +++ b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/RefactoringWizard.java @@ -0,0 +1,510 @@ +/********************************************************************** + * Copyright (c) 2004 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation +***********************************************************************/ + +package org.eclipse.cdt.internal.ui.refactoring; + +import java.lang.reflect.InvocationTargetException; + +import org.eclipse.cdt.internal.corext.Assert; +import org.eclipse.cdt.internal.corext.refactoring.base.IChange; +import org.eclipse.cdt.internal.corext.refactoring.base.Refactoring; +import org.eclipse.cdt.internal.corext.refactoring.base.RefactoringStatus; +import org.eclipse.cdt.internal.ui.util.BusyIndicatorRunnableContext; +import org.eclipse.cdt.internal.ui.util.ExceptionHandler; +import org.eclipse.cdt.ui.CUIPlugin; +import org.eclipse.jface.operation.IRunnableContext; +import org.eclipse.jface.wizard.IWizardPage; +import org.eclipse.jface.wizard.Wizard; +import org.eclipse.ui.PlatformUI; + +public class RefactoringWizard extends Wizard { + + private String fDefaultPageTitle; + private Refactoring fRefactoring; + private IChange fChange; + private RefactoringStatus fActivationStatus= new RefactoringStatus(); + private RefactoringStatus fStatus; + private boolean fHasUserInputPages; + private boolean fExpandFirstNode; + private boolean fIsChangeCreationCancelable; + private boolean fPreviewReview; + private boolean fPreviewShown; + + public RefactoringWizard(Refactoring refactoring) { + this(); + Assert.isNotNull(refactoring); + fRefactoring= refactoring; + } + + public RefactoringWizard(Refactoring refactoring, String defaultPageTitle) { + this(refactoring); + Assert.isNotNull(defaultPageTitle); + fDefaultPageTitle= defaultPageTitle; + } + + + /** + * Creates a new refactoring wizard without initializing its + * state. This constructor should only be used to create a + * refactoring spcified via a plugin manifest file. Clients + * that us this API must make sure that the initialize + * method gets called. + * + * @see #initialize(Refactoring) + */ + public RefactoringWizard() { + setNeedsProgressMonitor(true); + setChangeCreationCancelable(true); + setWindowTitle(RefactoringMessages.getString("RefactoringWizard.title")); //$NON-NLS-1$ +// setDefaultPageImageDescriptor(CPluginImages.DESC_WIZBAN_REFACTOR); + } + + /** + * Initializes the refactoring with the given refactoring. This + * method should be called right after the wizard has been created + * using the default constructor. + * + * @param refactoring the refactoring this wizard is working + * on + * @see #RefactoringWizard() + */ + public void initialize(Refactoring refactoring) { + Assert.isNotNull(refactoring); + fRefactoring= refactoring; + } + + /** + * Sets the default page title to the given value. This value is used + * as a page title for wizard page's which don't provide their own + * page title. Setting this value has only an effect as long as the + * user interface hasn't been created yet. + * + * @param defaultPageTitle the default page title. + * @see Wizard#setDefaultPageImageDescriptor(org.eclipse.jface.resource.ImageDescriptor) + */ + public void setDefaultPageTitle(String defaultPageTitle) { + fDefaultPageTitle= defaultPageTitle; + } + + public void setChangeCreationCancelable(boolean isChangeCreationCancelable){ + fIsChangeCreationCancelable= isChangeCreationCancelable; + } + + //---- Hooks to overide --------------------------------------------------------------- + + /** + * Some refactorings do activation checking when the wizard is going to be opened. + * They do this since activation checking is expensive and can't be performed on + * opening a corresponding menu. Wizards that need activation checking on opening + * should reimplement this method and should return true. This default + * implementation returns false. + * + * @return true if activation checking should be performed on opening; + * otherwise false is returned + */ + protected boolean checkActivationOnOpen() { + return false; + } + + /** + * Hook to add user input pages to the wizard. This default implementation + * adds nothing. + */ + protected void addUserInputPages(){ + } + + /** + * Hook to add the error page to the wizard. This default implementation + * adds an ErrorWizardPage to the wizard. + */ + protected void addErrorPage(){ + addPage(new ErrorWizardPage()); + } + + /** + * Hook to add the page the gives a prefix of the changes to be performed. This default + * implementation adds a PreviewWizardPage to the wizard. + */ + protected void addPreviewPage(){ + addPage(new PreviewWizardPage()); + } + + /** + * Hook to determine if the wizard has more than one user input page without + * actually creating the pages. + * + * @return boolean true if multi page user input exists. + * Otherwise false is returned + */ + public boolean hasMultiPageUserInput() { + return false; + } + + protected int getMessageLineWidthInChars() { + return 80; + } + + protected boolean hasUserInputPages() { + return fHasUserInputPages; + } + + protected boolean hasPreviewPage() { + return true; + } + + protected boolean yesNoStyle() { + return false; + } + + //---- Setter and Getters ------------------------------------------------------------ + + /** + * Returns the refactoring this wizard is using. + */ + public Refactoring getRefactoring(){ + return fRefactoring; + } + + /** + * Sets the change object. + */ + public void setChange(IChange change){ + IPreviewWizardPage page= (IPreviewWizardPage)getPage(IPreviewWizardPage.PAGE_NAME); + if (page != null) + page.setChange(change); + fChange= change; + } + + /** + * Returns the current change object. + */ + public IChange getChange() { + return fChange; + } + + /** + * Sets the refactoring status. + * + * @param status the refactoring status to set. + */ + public void setStatus(RefactoringStatus status) { + ErrorWizardPage page= (ErrorWizardPage)getPage(ErrorWizardPage.PAGE_NAME); + if (page != null) + page.setStatus(status); + fStatus= status; + } + + /** + * Returns the current refactoring status. + */ + public RefactoringStatus getStatus() { + return fStatus; + } + + /** + * Sets the refactoring status returned from input checking. Any previously + * computed activation status is merged into the given status before it is set + * to the error page. + * + * @param status the input status to set. + * @see #getActivationStatus() + */ + public void setInputStatus(RefactoringStatus status) { + RefactoringStatus newStatus= new RefactoringStatus(); + if (fActivationStatus != null) + newStatus.merge(fActivationStatus); + newStatus.merge(status); + setStatus(newStatus); + } + + /** + * Sets the refactoring status returned from activation checking. + * + * @param status the activation status to be set. + */ + public void setActivationStatus(RefactoringStatus status) { + fActivationStatus= status; + setStatus(status); + } + + /** + * Returns the activation status computed during the start up off this + * wizard. This methdod returns null if no activation + * checking has been performed during startup. + * + * @return the activation status computed during startup. + */ + public RefactoringStatus getActivationStatus() { + return fActivationStatus; + } + + /** + * Returns the default page title used for pages that don't + * provide their own page title. + * + * @return the default page title. + */ + public String getDefaultPageTitle() { + return fDefaultPageTitle; + } + + /** + * Defines whether the frist node in the preview page is supposed to be expanded. + * + * @param expand true if the first node is to be expanded. Otherwise + * false + */ + public void setExpandFirstNode(boolean expand) { + fExpandFirstNode= true; + } + + /** + * Returns true if the first node in the preview page is supposed to be + * expanded. Otherwise false is returned. + * + * @return true if the first node in the preview page is supposed to be + * expanded; otherwise false + */ + public boolean getExpandFirstNode() { + return fExpandFirstNode; + } + + /** + * Computes the wizard page that should follow the user input page. This is + * either the error page or the proposed changes page, depending on the + * result of the condition checking. + * + * @return the wizard page that should be shown after the last user input + * page + */ + public IWizardPage computeUserInputSuccessorPage(IWizardPage caller) { + return computeUserInputSuccessorPage(caller, getContainer()); + } + + private IWizardPage computeUserInputSuccessorPage(IWizardPage caller, IRunnableContext context) { + IChange change= createChange(CheckConditionsOperation.INPUT, RefactoringStatus.OK, true, context); + // Status has been updated since we have passed true + RefactoringStatus status= getStatus(); + + // Creating the change has been canceled + if (change == null && status == null) { + setChange(change); + return caller; + } + + // Set change if we don't have fatal errors. + if (!status.hasFatalError()) + setChange(change); + + if (status.isOK()) { + return getPage(IPreviewWizardPage.PAGE_NAME); + } else { + return getPage(ErrorWizardPage.PAGE_NAME); + } + } + + /** + * Initialize all pages with the managed page title. + */ + private void initializeDefaultPageTitles() { + if (fDefaultPageTitle == null) + return; + + IWizardPage[] pages= getPages(); + for (int i= 0; i < pages.length; i++) { + IWizardPage page= pages[i]; + if (page.getTitle() == null) + page.setTitle(fDefaultPageTitle); + } + } + + /** + * Forces the visiting of the preview page. The OK/Finish button will be + * disabled until the user has reached the preview page. + */ + public void setPreviewReview(boolean review) { + fPreviewReview= review; + getContainer().updateButtons(); + } + + public void setPreviewShown(boolean shown) { + fPreviewShown= shown; + getContainer().updateButtons(); + } + + public boolean canFinish() { + if (fPreviewReview && !fPreviewShown) + return false; + return super.canFinish(); + } + + + //---- Change management ------------------------------------------------------------- + + /** + * Creates a new change object for the refactoring. Method returns + * null if the change cannot be created. + * + * @param style the conditions to check before creating the change. + * @param checkPassedSeverity the severity below which the conditions check + * is treated as 'passed' + * @param updateStatus if true the wizard's status is updated + * with the status returned from the CreateChangeOperation. + * if false no status updating is performed. + */ + IChange createChange(int style, int checkPassedSeverity, boolean updateStatus) { + return createChange(style, checkPassedSeverity, updateStatus, getContainer()); + } + + private IChange createChange(int style, int checkPassedSeverity, boolean updateStatus, IRunnableContext context){ + CreateChangeOperation op= new CreateChangeOperation(fRefactoring, style); + op.setCheckPassedSeverity(checkPassedSeverity); + + InvocationTargetException exception= null; + try { + context.run(true, fIsChangeCreationCancelable, op); + } catch (InterruptedException e) { + setStatus(null); + return null; + } catch (InvocationTargetException e) { + exception= e; + } + + if (updateStatus) { + RefactoringStatus status= null; + if (exception != null) { + status= new RefactoringStatus(); + String msg= exception.getMessage(); + if (msg != null) { + status.addFatalError(RefactoringMessages.getFormattedString("RefactoringWizard.see_log", msg)); //$NON-NLS-1$ + } else { + status.addFatalError(RefactoringMessages.getString("RefactoringWizard.Internal_error")); //$NON-NLS-1$ + } + CUIPlugin.getDefault().log(exception); + } else { + status= op.getStatus(); + } + setStatus(status, style); + } else { + if (exception != null) + ExceptionHandler.handle(exception, RefactoringMessages.getString("RefactoringWizard.refactoring"), RefactoringMessages.getString("RefactoringWizard.unexpected_exception")); //$NON-NLS-2$ //$NON-NLS-1$ + } + IChange change= op.getChange(); + return change; + } + + public boolean performFinish(PerformChangeOperation op) { + return PerformRefactoringUtil.performRefactoring(op, fRefactoring, getContainer(), getContainer().getShell()); + } + + //---- Condition checking ------------------------------------------------------------ + + public RefactoringStatus checkInput() { + return internalCheckCondition(getContainer(), CheckConditionsOperation.INPUT); + } + + /** + * Checks the condition for the given style. + * @param style the conditions to check. + * @return the result of the condition check. + * @see CheckConditionsOperation + */ + protected RefactoringStatus internalCheckCondition(IRunnableContext context, int style) { + + CheckConditionsOperation op= new CheckConditionsOperation(fRefactoring, style); + + Exception exception= null; + try { + context.run(true, true, op); + } catch (InterruptedException e) { + exception= e; + } catch (InvocationTargetException e) { + exception= e; + } + RefactoringStatus status= null; + if (exception != null) { + CUIPlugin.getDefault().log(exception); + status= new RefactoringStatus(); + status.addFatalError(RefactoringMessages.getString("RefactoringWizard.internal_error_1")); //$NON-NLS-1$ + } else { + status= op.getStatus(); + } + setStatus(status, style); + return status; + } + + /** + * Sets the status according to the given style flag. + * + * @param status the refactoring status to set. + * @param style a flag indicating if the status is a activation, input checking, or + * precondition checking status. + * @see CheckConditionsOperation + */ + protected void setStatus(RefactoringStatus status, int style) { + if ((style & CheckConditionsOperation.PRECONDITIONS) == CheckConditionsOperation.PRECONDITIONS) + setStatus(status); + else if ((style & CheckConditionsOperation.ACTIVATION) == CheckConditionsOperation.ACTIVATION) + setActivationStatus(status); + else if ((style & CheckConditionsOperation.INPUT) == CheckConditionsOperation.INPUT) + setInputStatus(status); + } + + + //---- Reimplementation of Wizard methods -------------------------------------------- + + public boolean performFinish() { + Assert.isNotNull(fRefactoring); + + RefactoringWizardPage page= (RefactoringWizardPage)getContainer().getCurrentPage(); + return page.performFinish(); + } + + public IWizardPage getPreviousPage(IWizardPage page) { + if (fHasUserInputPages) + return super.getPreviousPage(page); + if (! page.getName().equals(ErrorWizardPage.PAGE_NAME)){ + if (fStatus.isOK()) + return null; + } + return super.getPreviousPage(page); + } + + public IWizardPage getStartingPage() { + if (fHasUserInputPages) + return super.getStartingPage(); + return computeUserInputSuccessorPage(null, PlatformUI.getWorkbench().getActiveWorkbenchWindow()); + } + + public void addPages() { + if (checkActivationOnOpen()) { + internalCheckCondition(new BusyIndicatorRunnableContext(), CheckConditionsOperation.ACTIVATION); + } + if (fActivationStatus.hasFatalError()) { + addErrorPage(); + // Set the status since we added the error page + setStatus(getStatus()); + } else { + Assert.isTrue(getPageCount() == 0); + addUserInputPages(); + if (getPageCount() > 0) + fHasUserInputPages= true; + addErrorPage(); + addPreviewPage(); + } + initializeDefaultPageTitles(); + } + + public void addPage(IWizardPage page) { + Assert.isTrue(page instanceof RefactoringWizardPage); + super.addPage(page); + } +} diff --git a/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/RefactoringWizardDialog.java b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/RefactoringWizardDialog.java new file mode 100644 index 00000000000..10a31ff3320 --- /dev/null +++ b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/RefactoringWizardDialog.java @@ -0,0 +1,101 @@ +/********************************************************************** + * Copyright (c) 2004 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation +***********************************************************************/ + +package org.eclipse.cdt.internal.ui.refactoring; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Shell; + +import org.eclipse.jface.dialogs.DialogSettings; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.dialogs.IDialogSettings; +import org.eclipse.jface.wizard.IWizardPage; +import org.eclipse.jface.wizard.WizardDialog; + +import org.eclipse.cdt.ui.CUIPlugin; + +/** + * A dialog to host refactoring wizards. + */ +public class RefactoringWizardDialog extends WizardDialog { + + private static final String DIALOG_SETTINGS= "RefactoringWizard"; //$NON-NLS-1$ + private static final String WIDTH= "width"; //$NON-NLS-1$ + private static final String HEIGHT= "height"; //$NON-NLS-1$ + + private IDialogSettings fSettings; + + /* + * note: this field must not be initialized - setter is called in the call to super + * and java initializes fields 'after' the call to super is made. so initializing would override setting. + */ + private boolean fMakeNextButtonDefault; + + /** + * Creates a new refactoring wizard dialag with the given wizard. + */ + public RefactoringWizardDialog(Shell parent, RefactoringWizard wizard) { + super(parent, wizard); + setShellStyle(getShellStyle() | SWT.RESIZE); + IDialogSettings settings= CUIPlugin.getDefault().getDialogSettings(); + wizard.setDialogSettings(settings); + fSettings= settings.getSection(DIALOG_SETTINGS); + if (fSettings == null) { + fSettings= new DialogSettings(DIALOG_SETTINGS); + settings.addSection(fSettings); + fSettings.put(WIDTH, 600); + fSettings.put(HEIGHT, 400); + } + int width= 600; + int height= 400; + try { + width= fSettings.getInt(WIDTH); + height= fSettings.getInt(HEIGHT); + } catch (NumberFormatException e) { + } + setMinimumPageSize(width, height); + } + + /* + * @see WizardDialog#finishPressed() + */ + protected void finishPressed() { + IWizardPage page= getCurrentPage(); + Control control= page.getControl().getParent(); + Point size = control.getSize(); + fSettings.put(WIDTH, size.x); + fSettings.put(HEIGHT, size.y); + super.finishPressed(); + } + + /* + * @see IWizardContainer#updateButtons() + */ + public void updateButtons() { + super.updateButtons(); + if (! fMakeNextButtonDefault) + return; + if (getShell() == null) + return; + Button next= getButton(IDialogConstants.NEXT_ID); + if (next.isEnabled()) + getShell().setDefaultButton(next); + } + + /* usually called in the IWizard#setContainer(IWizardContainer) method + */ + public void setMakeNextButtonDefault(boolean makeNextButtonDefault) { + fMakeNextButtonDefault= makeNextButtonDefault; + } +} diff --git a/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/RefactoringWizardDialog2.java b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/RefactoringWizardDialog2.java new file mode 100644 index 00000000000..72c580eaea4 --- /dev/null +++ b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/RefactoringWizardDialog2.java @@ -0,0 +1,581 @@ +/********************************************************************** + * Copyright (c) 2004 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.internal.ui.refactoring; + +import java.lang.reflect.InvocationTargetException; +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.StackLayout; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.Cursor; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; + +import org.eclipse.jface.dialogs.ControlEnableState; +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.dialogs.DialogSettings; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.dialogs.IDialogSettings; +import org.eclipse.jface.dialogs.IMessageProvider; +import org.eclipse.jface.operation.IRunnableWithProgress; +import org.eclipse.jface.operation.ModalContext; +import org.eclipse.jface.util.Assert; +import org.eclipse.jface.wizard.IWizardContainer; +import org.eclipse.jface.wizard.IWizardPage; +import org.eclipse.jface.wizard.ProgressMonitorPart; + +import org.eclipse.core.runtime.NullProgressMonitor; + +import org.eclipse.cdt.ui.CUIPlugin; +import org.eclipse.cdt.internal.ui.CPluginImages; + +public class RefactoringWizardDialog2 extends Dialog implements IWizardContainer { + + private RefactoringWizard fWizard; + private IWizardPage fCurrentPage; + private IWizardPage fVisiblePage; + + private PageBook fPageContainer; + private PageBook fStatusContainer; + private MessageBox fMessageBox; + private ProgressMonitorPart fProgressMonitorPart; + private int fActiveRunningOperations; + private Cursor fWaitCursor; + private Cursor fArrowCursor; + + private static final int PREVIEW_ID= IDialogConstants.CLIENT_ID + 1; + + private int fPreviewWidth; + private int fPreviewHeight; + private IDialogSettings fSettings; + private static final String DIALOG_SETTINGS= "RefactoringWizard.preview"; //$NON-NLS-1$ + private static final String WIDTH= "width"; //$NON-NLS-1$ + private static final String HEIGHT= "height"; //$NON-NLS-1$ + + private static final Image INFO= CPluginImages.get(CPluginImages.IMG_OBJS_REFACTORING_INFO); + private static final Image WARNING= CPluginImages.get(CPluginImages.IMG_OBJS_REFACTORING_WARNING); + private static final Image ERROR= CPluginImages.get(CPluginImages.IMG_OBJS_REFACTORING_ERROR); + + private static class MessageBox extends Composite { + private Label fImage; + private Label fText; + public MessageBox(Composite parent, int style) { + super(parent, style); + GridLayout layout= new GridLayout(); + layout.numColumns= 2; + setLayout(layout); + fImage= new Label(this, SWT.NONE); + fImage.setImage(INFO); + Point size= fImage.computeSize(SWT.DEFAULT, SWT.DEFAULT); + GridData gd= new GridData(); + gd.verticalAlignment= SWT.TOP; + gd.widthHint= size.x; + gd.heightHint= size.y; + fImage.setLayoutData(gd); + fImage.setImage(null); + fText= new Label(this, SWT.WRAP); + fText.setText(" \n "); //$NON-NLS-1$ + size= fText.computeSize(SWT.DEFAULT, SWT.DEFAULT); + gd= new GridData(GridData.FILL_HORIZONTAL); + gd.heightHint= size.y; + gd.verticalAlignment= SWT.TOP; + fText.setLayoutData(gd); + } + public void setMessage(IWizardPage page) { + String msg= page.getErrorMessage(); + int type= IMessageProvider.ERROR; + if (msg == null || msg.length() == 0) { + msg= page.getMessage(); + type= IMessageProvider.NONE; + if (msg != null && page instanceof IMessageProvider) + type = ((IMessageProvider)page).getMessageType(); + } + Image image= null; + switch (type) { + case IMessageProvider.INFORMATION: + image= INFO; + break; + case IMessageProvider.WARNING: + image= WARNING; + break; + case IMessageProvider.ERROR: + image= ERROR; + break; + } + if (msg == null) + msg= ""; //$NON-NLS-1$ + fText.setText(msg); + if (image == null && msg.length() > 0) + image= INFO; + fImage.setImage(image); + } + } + + private static class PageBook extends Composite { + private StackLayout fLayout; + public PageBook(Composite parent, int style) { + super(parent, style); + fLayout= new StackLayout(); + setLayout(fLayout); + fLayout.marginWidth= 5; fLayout.marginHeight= 5; + } + public void showPage(Control page) { + fLayout.topControl= page; + layout(); + } + public Control getTopPage() { + return fLayout.topControl; + } + } + + public RefactoringWizardDialog2(Shell shell, RefactoringWizard wizard) { + super(shell); + Assert.isNotNull(wizard); + setShellStyle(getShellStyle() | SWT.RESIZE); + wizard.setDialogSettings(CUIPlugin.getDefault().getDialogSettings()); + fWizard= wizard; + fWizard.setContainer(this); + fWizard.addPages(); + initSize(); + } + + private void initSize() { + IDialogSettings settings= CUIPlugin.getDefault().getDialogSettings(); + fSettings= settings.getSection(DIALOG_SETTINGS); + if (fSettings == null) { + fSettings= new DialogSettings(DIALOG_SETTINGS); + settings.addSection(fSettings); + fSettings.put(WIDTH, 600); + fSettings.put(HEIGHT, 100); + } + fPreviewWidth= 600; + fPreviewHeight= 100; + try { + fPreviewWidth= fSettings.getInt(WIDTH); + fPreviewHeight= fSettings.getInt(HEIGHT); + } catch (NumberFormatException e) { + } + } + + private void saveSize() { + if (fCurrentPage instanceof PreviewWizardPage) { + Control control= fCurrentPage.getControl().getParent(); + Point size = control.getSize(); + fSettings.put(WIDTH, size.x); + fSettings.put(HEIGHT, size.y); + } + } + + //---- IWizardContainer -------------------------------------------- + + /* (non-Javadoc) + * Method declared on IWizardContainer. + */ + public void showPage(IWizardPage page) { + fCurrentPage= page; + } + + /* (non-Javadoc) + * Method declared on IWizardContainer. + */ + public void updateButtons() { + boolean previewPage= isPreviewPageActive(); + boolean ok= fWizard.canFinish(); + boolean canFlip= fCurrentPage.canFlipToNextPage(); + Button previewButton= getButton(PREVIEW_ID); + Button defaultButton= null; + if (previewButton != null && !previewButton.isDisposed()) { + previewButton.setEnabled(!previewPage); + if (!previewPage) + previewButton.setEnabled(canFlip); + if (previewButton.isEnabled()) + defaultButton= previewButton; + } + Button okButton= getButton(IDialogConstants.OK_ID); + if (okButton != null && !okButton.isDisposed()) { + okButton.setEnabled(ok); + if (ok) + defaultButton= okButton; + } + if (defaultButton != null) { + defaultButton.getShell().setDefaultButton(defaultButton); + } + } + + /* (non-Javadoc) + * Method declared on IWizardContainer. + */ + public void updateMessage() { + if (fStatusContainer == null || fStatusContainer.isDisposed()) + return; + fStatusContainer.showPage(fMessageBox); + fMessageBox.setMessage(fCurrentPage); + } + + /* (non-Javadoc) + * Method declared on IWizardContainer. + */ + public void updateTitleBar() { + // we don't have a title bar. + } + + /* (non-Javadoc) + * Method declared on IWizardContainer. + */ + public void updateWindowTitle() { + getShell().setText(fWizard.getWindowTitle()); + } + + /* (non-Javadoc) + * Method declared on IWizardContainer. + */ + public IWizardPage getCurrentPage() { + return fCurrentPage; + } + + //---- IRunnableContext -------------------------------------------- + + /* (non-Javadoc) + * Method declared on IRunnableContext + */ + public void run(boolean fork, boolean cancelable, IRunnableWithProgress runnable) throws InvocationTargetException, InterruptedException { + if (fProgressMonitorPart == null) { + ModalContext.run(runnable, false, new NullProgressMonitor(), getShell().getDisplay()); + } else { + Object state = null; + if(fActiveRunningOperations == 0) + state = aboutToStart(fork && cancelable); + + fActiveRunningOperations++; + try { + ModalContext.run(runnable, fork, fProgressMonitorPart, getShell().getDisplay()); + } finally { + fActiveRunningOperations--; + //Stop if this is the last one + if(state!= null) + stopped(state); + } + } + } + + private Object aboutToStart(boolean cancelable) { + Map savedState = null; + Shell shell= getShell(); + if (shell != null) { + // Save focus control + Control focusControl = getShell().getDisplay().getFocusControl(); + if (focusControl != null && focusControl.getShell() != getShell()) + focusControl = null; + + Button cancelButton= getButton(IDialogConstants.CANCEL_ID); + // Set the busy cursor to all shells. + Display d = getShell().getDisplay(); + fWaitCursor = new Cursor(d, SWT.CURSOR_WAIT); + setDisplayCursor(d, fWaitCursor); + + // Set the arrow cursor to the cancel component. + fArrowCursor= new Cursor(d, SWT.CURSOR_ARROW); + cancelButton.setCursor(fArrowCursor); + + boolean hasProgressMonitor= fProgressMonitorPart != null; + + // Deactivate shell + savedState= saveUIState(hasProgressMonitor && cancelable); + if (focusControl != null) + savedState.put("focus", focusControl); //$NON-NLS-1$ + + if (hasProgressMonitor) { + fProgressMonitorPart.attachToCancelComponent(cancelButton); + fStatusContainer.showPage(fProgressMonitorPart); + } + // Update the status container since we are blocking the event loop right now. + fStatusContainer.update(); + } + return savedState; + } + + private Map saveUIState(boolean keepCancelEnabled) { + Map savedState= new HashMap(10); + saveEnableStateAndSet(getButton(PREVIEW_ID), savedState, "preview", false); //$NON-NLS-1$ + saveEnableStateAndSet(getButton(IDialogConstants.OK_ID), savedState, "ok", false); //$NON-NLS-1$ + saveEnableStateAndSet(getButton(IDialogConstants.CANCEL_ID), savedState, "cancel", keepCancelEnabled); //$NON-NLS-1$ + savedState.put("page", ControlEnableState.disable(fVisiblePage.getControl())); //$NON-NLS-1$ + return savedState; + } + + private void saveEnableStateAndSet(Control w, Map h, String key, boolean enabled) { + if (w != null) { + h.put(key, new Boolean(w.getEnabled())); + w.setEnabled(enabled); + } + } + + private void setDisplayCursor(Display d, Cursor c) { + Shell[] shells= d.getShells(); + for (int i= 0; i < shells.length; i++) + shells[i].setCursor(c); + } + + private void stopped(Object savedState) { + Shell shell= getShell(); + if (shell != null) { + Button cancelButton= getButton(IDialogConstants.CANCEL_ID); + + if (fProgressMonitorPart != null) + fProgressMonitorPart.removeFromCancelComponent(cancelButton); + + fStatusContainer.showPage(fMessageBox); + Map state = (Map)savedState; + restoreUIState(state); + + setDisplayCursor(shell.getDisplay(), null); + cancelButton.setCursor(null); + fWaitCursor.dispose(); + fWaitCursor = null; + fArrowCursor.dispose(); + fArrowCursor = null; + Control focusControl = (Control)state.get("focus"); //$NON-NLS-1$ + if (focusControl != null) + focusControl.setFocus(); + } + } + + private void restoreUIState(Map state) { + restoreEnableState(getButton(PREVIEW_ID), state, "preview");//$NON-NLS-1$ + restoreEnableState(getButton(IDialogConstants.OK_ID), state, "ok");//$NON-NLS-1$ + restoreEnableState(getButton(IDialogConstants.CANCEL_ID), state, "cancel");//$NON-NLS-1$ + ControlEnableState pageState = (ControlEnableState) state.get("page");//$NON-NLS-1$ + pageState.restore(); + } + + private void restoreEnableState(Control w, Map h, String key) { + if (w != null) { + Boolean b = (Boolean) h.get(key); + if (b != null) + w.setEnabled(b.booleanValue()); + } + } + + //---- Dialog ----------------------------------------------------------- + + public boolean close() { + fWizard.dispose(); + return super.close(); + } + + protected void cancelPressed() { + if (fActiveRunningOperations == 0) { + if (fWizard.performCancel()) + super.cancelPressed(); + } + } + + protected void okPressed() { + IWizardPage current= fCurrentPage; + if (fWizard.performFinish()) { + saveSize(); + super.okPressed(); + return; + } + if (fCurrentPage == current) + return; + Assert.isTrue(ErrorWizardPage.PAGE_NAME.equals(fCurrentPage.getName())); + if (showErrorDialog((ErrorWizardPage)fCurrentPage)) { + if (fWizard.performFinish()) { + super.okPressed(); + return; + } + } + fCurrentPage= current; + } + + private boolean isPreviewPageActive() { + return IPreviewWizardPage.PAGE_NAME.equals(fCurrentPage.getName()); + } + + private void previewPressed() { + IWizardPage current= fCurrentPage; + fCurrentPage= fCurrentPage.getNextPage(); + if (current == fCurrentPage) + return; + String pageName= fCurrentPage.getName(); + if (ErrorWizardPage.PAGE_NAME.equals(pageName)) { + if (showErrorDialog((ErrorWizardPage)fCurrentPage)) { + fCurrentPage= fCurrentPage.getNextPage(); + pageName= fCurrentPage.getName(); + } else { + return; + } + } + if (IPreviewWizardPage.PAGE_NAME.equals(pageName)) { + fCurrentPage.createControl(fPageContainer); + makeVisible(fCurrentPage); + updateButtons(); + if (((PreviewWizardPage)fCurrentPage).hasChanges()) + resize(); + else + getButton(IDialogConstants.OK_ID).setEnabled(false); + } else { + fCurrentPage= current; + } + } + + private boolean showErrorDialog(ErrorWizardPage page) { + RefactoringStatusDialog dialog= new RefactoringStatusDialog(getShell(), page, true); + switch (dialog.open()) { + case IDialogConstants.OK_ID: + return true; + case IDialogConstants.BACK_ID: + fCurrentPage= fCurrentPage.getPreviousPage(); + break; + case IDialogConstants.CANCEL_ID: + super.cancelPressed(); + } + return false; + } + + private void resize() { + Control control= fPageContainer.getTopPage(); + Point size= control.getSize(); + int dw= Math.max(0, fPreviewWidth - size.x); + int dh= Math.max(0, fPreviewHeight - size.y); + int dx = dw / 2; + int dy= dh / 2; + Shell shell= getShell(); + Rectangle rect= shell.getBounds(); + Rectangle display= shell.getDisplay().getClientArea(); + rect.x= Math.max(0, rect.x - dx); + rect.y= Math.max(0, rect.y - dy); + rect.width= Math.min(rect.width + dw, display.width); + rect.height= Math.min(rect.height + dh, display.height); + int xe= rect.x + rect.width; + if (xe > display.width) { + rect.x-= xe - display.width; + } + int ye= rect.y + rect.height; + if (ye > display.height) { + rect.y-= ye - display.height; + } + shell.setBounds(rect); + } + + //---- UI construction --------------------------------------------------- + + protected void configureShell(Shell newShell) { + super.configureShell(newShell); + newShell.setText(fWizard.getDefaultPageTitle()); + } + + protected Control createContents(Composite parent) { + Composite result= new Composite(parent, SWT.NONE); + GridLayout layout= new GridLayout(); + layout.marginHeight= 0; layout.marginWidth= 0; + layout.verticalSpacing= 0; layout.horizontalSpacing= 0; + result.setLayout(layout); + result.setLayoutData(new GridData(GridData.FILL_BOTH)); + + // initialize the dialog units + initializeDialogUnits(result); + + fPageContainer= new PageBook(result, SWT.NONE); + GridData gd= new GridData(GridData.FILL_BOTH); + fPageContainer.setLayoutData(gd); + fCurrentPage= fWizard.getStartingPage(); + dialogArea= fPageContainer; + if (fCurrentPage instanceof PreviewWizardPage) { + gd.widthHint= fPreviewWidth; + gd.heightHint= fPreviewHeight; + } + + fStatusContainer= new PageBook(result, SWT.NONE); + gd= new GridData(GridData.FILL_HORIZONTAL); + gd.widthHint= convertWidthInCharsToPixels(fWizard.getMessageLineWidthInChars()); + fStatusContainer.setLayoutData(gd); + if (fWizard.needsProgressMonitor()) + createProgressMonitorPart(); + createMessageBox(); + fStatusContainer.showPage(fMessageBox); + + buttonBar= createButtonBar(result); + + fCurrentPage.createControl(fPageContainer); + makeVisible(fCurrentPage); + + updateMessage(); + updateButtons(); + applyDialogFont(result); + return result; + } + + private void createProgressMonitorPart() { + // Insert a progress monitor + GridLayout pmlayout= new GridLayout(); + pmlayout.numColumns= 1; + pmlayout.marginHeight= 0; + fProgressMonitorPart= new ProgressMonitorPart(fStatusContainer, pmlayout); + } + + private void createMessageBox() { + fMessageBox= new MessageBox(fStatusContainer, SWT.NONE); + } + + protected void createButtonsForButtonBar(Composite parent) { + if (! (fCurrentPage instanceof PreviewWizardPage) && fWizard.hasPreviewPage()) { + Button preview= createButton(parent, PREVIEW_ID, RefactoringMessages.getString("RefactoringWizardDialog2.buttons.preview.label"), false); //$NON-NLS-1$ + preview.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + previewPressed(); + } + }); + } + + String OK_LABEL= IDialogConstants.OK_LABEL; + String CANCEL_LABEL= IDialogConstants.CANCEL_LABEL; + if (fWizard.yesNoStyle()) { + OK_LABEL= IDialogConstants.YES_LABEL; + CANCEL_LABEL= IDialogConstants.NO_LABEL; + } + createButton( + parent, + IDialogConstants.OK_ID, + OK_LABEL, + true); + createButton( + parent, + IDialogConstants.CANCEL_ID, + CANCEL_LABEL, + false); + Button okButton= getButton(IDialogConstants.OK_ID); + okButton.setFocus(); + } + + private void makeVisible(IWizardPage page) { + if (fVisiblePage == page) + return; + if (fVisiblePage != null) + fVisiblePage.setVisible(false); + fVisiblePage= page; + fPageContainer.showPage(page.getControl()); + fVisiblePage.setVisible(true); + } +} diff --git a/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/RefactoringWizardPage.java b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/RefactoringWizardPage.java new file mode 100644 index 00000000000..0385235eec1 --- /dev/null +++ b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/RefactoringWizardPage.java @@ -0,0 +1,98 @@ +/********************************************************************** + * Copyright (c) 2004 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.internal.ui.refactoring; + +import org.eclipse.jface.dialogs.DialogSettings; +import org.eclipse.jface.dialogs.IDialogSettings; +import org.eclipse.jface.util.Assert; +import org.eclipse.jface.wizard.IWizard; +import org.eclipse.jface.wizard.WizardPage; + +import org.eclipse.cdt.internal.corext.refactoring.base.Refactoring; + +/** + * An abstract superclass for all wizard pages added to a refactoring wizard. The + * class provides access to the refactoring and the refactoring wizard. + * + * @see RefactoringWizard + */ +public abstract class RefactoringWizardPage extends WizardPage { + + public static final String REFACTORING_SETTINGS= "org.eclipse.cdt.ui.refactoring"; //$NON-NLS-1$ + + /** + * Creates a new refactoring wizard page. + * + * @param name the page's name. + * @see org.eclipse.jface.wizard.IWizardPage#getName() + */ + protected RefactoringWizardPage(String name) { + super(name); + } + + /* (non-Javadoc) + * Method declared on IWizardPage. + */ + public void setWizard(IWizard newWizard) { + Assert.isTrue(newWizard instanceof RefactoringWizard); + super.setWizard(newWizard); + } + + /** + * Returns the refactoring used by the wizard to which this page belongs. + * Returns null if the page isn't added to any wizard yet. + * + * @return the refactoring associated with this refactoring wizard page + */ + protected Refactoring getRefactoring() { + RefactoringWizard wizard= getRefactoringWizard(); + if (wizard == null) + return null; + return wizard.getRefactoring(); + } + + /** + * Returns the page's refactoring wizard. + * + * @return the page's refactoring wizard + */ + protected RefactoringWizard getRefactoringWizard() { + return (RefactoringWizard)getWizard(); + } + + /** + * The user has pressed the finish button. Perform the page specific finish + * action. + * + * @return true if finish operation ended without errors. + * Otherwise false is returned. + */ + protected boolean performFinish() { + return true; + } + + /** + * Returns the refactoring dialog settings. + * + * @return the refactoring dialog settings. + */ + protected IDialogSettings getRefactoringSettings() { + IDialogSettings settings= getDialogSettings(); + if (settings == null) + return null; + IDialogSettings result= settings.getSection(REFACTORING_SETTINGS); + if (result == null) { + result= new DialogSettings(REFACTORING_SETTINGS); + settings.addSection(result); + } + return result; + } +} diff --git a/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/RenameElementWizard.java b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/RenameElementWizard.java new file mode 100644 index 00000000000..16b7216204d --- /dev/null +++ b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/RenameElementWizard.java @@ -0,0 +1,25 @@ +/********************************************************************** + * Copyright (c) 2004 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.internal.ui.refactoring; + +import org.eclipse.cdt.internal.ui.ICHelpContextIds; +import org.eclipse.cdt.internal.ui.CPluginImages; +import org.eclipse.cdt.internal.ui.refactoring.RefactoringMessages; + +public class RenameElementWizard extends RenameRefactoringWizard { + public RenameElementWizard() { + super( + RefactoringMessages.getString("RenameTypeWizard.defaultPageTitle"), //$NON-NLS-1$ + RefactoringMessages.getString("RenameTypeWizard.inputPage.description"), //$NON-NLS-1$ + CPluginImages.DESC_WIZBAN_REFACTOR_TYPE, + ICHelpContextIds.RENAME_TYPE_WIZARD_PAGE); + } +} diff --git a/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/RenameInputWizardPage.java b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/RenameInputWizardPage.java new file mode 100644 index 00000000000..b2a53682b0f --- /dev/null +++ b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/RenameInputWizardPage.java @@ -0,0 +1,201 @@ +/********************************************************************** + * Copyright (c) 2004 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.internal.ui.refactoring; + +import org.eclipse.cdt.internal.corext.refactoring.IReferenceUpdating; +import org.eclipse.cdt.internal.corext.refactoring.ITextUpdating; +import org.eclipse.cdt.internal.corext.refactoring.base.Refactoring; +import org.eclipse.cdt.internal.ui.util.RowLayouter; +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.swt.SWT; +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.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Text; +import org.eclipse.ui.help.WorkbenchHelp; + +abstract class RenameInputWizardPage extends TextInputWizardPage { + + private String fHelpContextID; + private Button fUpdateReferences; + private Button fUpdateComments; + private Button fUpdateStrings; + private Button fUpdateQualifiedNames; + private static final String UPDATE_REFERENCES= "updateReferences"; //$NON-NLS-1$ + private static final String UPDATE_COMMENTS= "updateComments"; //$NON-NLS-1$ + private static final String UPDATE_STRINGS= "updateStrings"; //$NON-NLS-1$ + private static final String UPDATE_QUALIFIED_NAMES= "updateQualifiedNames"; //$NON-NLS-1$ + + /** + * Creates a new text input page. + * @param isLastUserPage true if this page is the wizard's last + * user input page. Otherwise false. + * @param initialSetting the initialSetting. + */ + public RenameInputWizardPage(String description, String contextHelpId, boolean isLastUserPage, String initialValue) { + super(description, isLastUserPage, initialValue); + fHelpContextID= contextHelpId; + } + + /* non java-doc + * @see DialogPage#createControl(org.eclipse.swt.widgets.Composite) + */ + public void createControl(Composite parent) { + Composite superComposite= new Composite(parent, SWT.NONE); + setControl(superComposite); + initializeDialogUnits(superComposite); + + superComposite.setLayout(new GridLayout()); + Composite composite= new Composite(superComposite, SWT.NONE); + composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + GridLayout layout= new GridLayout(); + layout.numColumns= 2; + layout.verticalSpacing= 8; + composite.setLayout(layout); + RowLayouter layouter= new RowLayouter(2); + + Label oldNameLabel= new Label(composite, SWT.NONE); + oldNameLabel.setText(getOldNameLabelText()); + + Label oldName= new Label(composite, SWT.NONE); + oldName.setText(fInitialValue); + + Label label= new Label(composite, SWT.NONE); + label.setText(getLabelText()); + + Text text= createTextInputField(composite); + text.selectAll(); + GridData gd= new GridData(GridData.FILL_HORIZONTAL); + gd.widthHint= convertWidthInCharsToPixels(25); + text.setLayoutData(gd); + + + layouter.perform(label, text, 1); + + addOptionalUpdateReferencesCheckbox(composite, layouter); + + Dialog.applyDialogFont(superComposite); + WorkbenchHelp.setHelp(getControl(), fHelpContextID); + + } + + protected boolean saveSettings() { + if (getContainer() instanceof Dialog) + return ((Dialog)getContainer()).getReturnCode() == IDialogConstants.OK_ID; + return true; + } + + public void dispose() { + if (saveSettings()) { + saveBooleanSetting(UPDATE_REFERENCES, fUpdateReferences); + saveBooleanSetting(UPDATE_COMMENTS, fUpdateComments); + saveBooleanSetting(UPDATE_STRINGS, fUpdateStrings); + saveBooleanSetting(UPDATE_QUALIFIED_NAMES, fUpdateQualifiedNames); + } + super.dispose(); + } + + private void addOptionalUpdateReferencesCheckbox(Composite result, RowLayouter layouter) { + final IReferenceUpdating ref= (IReferenceUpdating)getRefactoring().getAdapter(IReferenceUpdating.class); + if (ref == null || !ref.canEnableUpdateReferences()) + return; + String title= RefactoringMessages.getString("RenameInputWizardPage.update_references"); //$NON-NLS-1$ + boolean defaultValue= getBooleanSetting(UPDATE_REFERENCES, ref.getUpdateReferences()); + fUpdateReferences= createCheckbox(result, title, defaultValue, layouter); + ref.setUpdateReferences(fUpdateReferences.getSelection()); + fUpdateReferences.addSelectionListener(new SelectionAdapter(){ + public void widgetSelected(SelectionEvent e) { + ref.setUpdateReferences(fUpdateReferences.getSelection()); + } + }); + } + + private void addOptionalUpdateCommentsAndStringCheckboxes(Composite result, RowLayouter layouter) { + ITextUpdating refactoring= (ITextUpdating)getRefactoring().getAdapter(ITextUpdating.class); + + if (refactoring == null || !refactoring.canEnableTextUpdating()) + return; + + addUpdateCommentsCheckbox(result, layouter, refactoring); + addUpdateStringsCheckbox(result, layouter, refactoring); + } + + private void addUpdateCommentsCheckbox(Composite result, RowLayouter layouter, final ITextUpdating refactoring) { + String title= RefactoringMessages.getString("RenameInputWizardPage.update_comment_references"); //$NON-NLS-1$ + boolean defaultValue= getBooleanSetting(UPDATE_COMMENTS, refactoring.getUpdateComments()); + fUpdateComments= createCheckbox(result, title, defaultValue, layouter); + refactoring.setUpdateComments(fUpdateComments.getSelection()); + fUpdateComments.addSelectionListener(new SelectionAdapter(){ + public void widgetSelected(SelectionEvent e) { + refactoring.setUpdateComments(fUpdateComments.getSelection()); + updateForcePreview(); + } + }); + } + + private void addUpdateStringsCheckbox(Composite result, RowLayouter layouter, final ITextUpdating refactoring) { + String title= RefactoringMessages.getString("RenameInputWizardPage.ppdate_string_references"); //$NON-NLS-1$ + boolean defaultValue= getBooleanSetting(UPDATE_STRINGS, refactoring.getUpdateStrings()); + fUpdateStrings= createCheckbox(result, title, defaultValue, layouter); + refactoring.setUpdateStrings(fUpdateStrings.getSelection()); + fUpdateStrings.addSelectionListener(new SelectionAdapter(){ + public void widgetSelected(SelectionEvent e) { + refactoring.setUpdateStrings(fUpdateStrings.getSelection()); + updateForcePreview(); + } + }); + } + + protected String getLabelText() { + return RefactoringMessages.getString("RenameInputWizardPage.enter_name"); //$NON-NLS-1$ + } + + protected String getOldNameLabelText() { + return RefactoringMessages.getString("RenameInputWizardPage.old_name"); //$NON-NLS-1$ + } + + protected boolean getBooleanSetting(String key, boolean defaultValue) { + String update= getRefactoringSettings().get(key); + if (update != null) + return Boolean.valueOf(update).booleanValue(); + else + return defaultValue; + } + + protected void saveBooleanSetting(String key, Button checkBox) { + if (checkBox != null) + getRefactoringSettings().put(key, checkBox.getSelection()); + } + + private static Button createCheckbox(Composite parent, String title, boolean value, RowLayouter layouter) { + Button checkBox= new Button(parent, SWT.CHECK); + checkBox.setText(title); + checkBox.setSelection(value); + layouter.perform(checkBox); + return checkBox; + } + + private void updateForcePreview() { + boolean forcePreview= false; + Refactoring refactoring= getRefactoring(); + ITextUpdating tu= (ITextUpdating)refactoring.getAdapter(ITextUpdating.class); + if (tu != null) { + forcePreview= tu.getUpdateComments() || tu.getUpdateJavaDoc() || tu.getUpdateStrings(); + } + getRefactoringWizard().setPreviewReview(forcePreview); + } +} diff --git a/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/RenameRefactoringAction.java b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/RenameRefactoringAction.java new file mode 100644 index 00000000000..4cf3d658e7d --- /dev/null +++ b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/RenameRefactoringAction.java @@ -0,0 +1,81 @@ +/********************************************************************** + * Copyright (c) 2004 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.internal.ui.refactoring; + + +import org.eclipse.core.runtime.CoreException; + +import org.eclipse.swt.widgets.Shell; + +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; + +import org.eclipse.ui.IWorkbenchSite; + +import org.eclipse.cdt.internal.corext.refactoring.RenameRefactoring; + +import org.eclipse.cdt.internal.ui.refactoring.UserInterfaceStarter; +import org.eclipse.cdt.internal.ui.util.ExceptionHandler; + +import org.eclipse.cdt.ui.actions.SelectionDispatchAction; + + +public class RenameRefactoringAction extends SelectionDispatchAction { + + public RenameRefactoringAction(IWorkbenchSite site) { + super(site); + setText("Rename ..."); + } + + /* (non-Javadoc) + * @see org.eclipse.jdt.ui.actions.SelectionDispatchAction#selectionChanged(org.eclipse.jface.viewers.IStructuredSelection) + */ + public void selectionChanged(IStructuredSelection selection) { + setEnabled(selection.size() == 1); + } + + + /* (non-Javadoc) + * @see org.eclipse.jdt.ui.actions.SelectionDispatchAction#run(org.eclipse.jface.viewers.IStructuredSelection) + */ + public void run(IStructuredSelection selection) { + Object element= selection.getFirstElement(); + try { + RenameRefactoring refactoring= new RenameRefactoring(element); + run(refactoring, getShell()); + } catch (CoreException e) { + ExceptionHandler.handle(e, getShell(), "Rename Refactoring", "Unexpected Exception occured"); + } + } + + /* (non-Javadoc) + * @see org.eclipse.ui.IActionDelegate#run(org.eclipse.jface.action.IAction) + */ + public void run(IAction action) { + run(); + } + + public void selectionChanged(IAction action, ISelection selection) { + action.setEnabled(true); + } + + public static void run(RenameRefactoring refactoring, Shell parent) throws CoreException { + if (refactoring.isAvailable()) { + UserInterfaceStarter.run(refactoring, parent); + } else { + MessageDialog.openInformation(parent, + "Rename Refactoring", + "No refactoring available to process the selected element."); + } + } +} diff --git a/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/RenameRefactoringWizard.java b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/RenameRefactoringWizard.java new file mode 100644 index 00000000000..47fafa0ea63 --- /dev/null +++ b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/RenameRefactoringWizard.java @@ -0,0 +1,83 @@ +/********************************************************************** + * Copyright (c) 2004 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation +***********************************************************************/ + +package org.eclipse.cdt.internal.ui.refactoring; + +import org.eclipse.core.runtime.CoreException; + +import org.eclipse.jface.resource.ImageDescriptor; + +import org.eclipse.cdt.internal.corext.refactoring.RefactoringStyles; +import org.eclipse.cdt.internal.corext.refactoring.RenameRefactoring; +import org.eclipse.cdt.internal.corext.refactoring.IRenameRefactoring; +import org.eclipse.cdt.internal.corext.refactoring.base.Refactoring; +import org.eclipse.cdt.internal.corext.refactoring.base.RefactoringStatus; + +import org.eclipse.cdt.internal.ui.refactoring.RefactoringMessages; +import org.eclipse.cdt.internal.ui.refactoring.RefactoringWizard; + +public class RenameRefactoringWizard extends RefactoringWizard { + + private final String fInputPageDescription; + private final String fPageContextHelpId; + private final ImageDescriptor fInputPageImageDescriptor; + + public RenameRefactoringWizard(String defaultPageTitle, String inputPageDescription, + ImageDescriptor inputPageImageDescriptor, String pageContextHelpId) { + super(); + setDefaultPageTitle(defaultPageTitle); + fInputPageDescription= inputPageDescription; + fInputPageImageDescriptor= inputPageImageDescriptor; + fPageContextHelpId= pageContextHelpId; + } + + protected boolean hasPreviewPage() { + Refactoring refactoring= getRefactoring(); + if (refactoring instanceof RenameRefactoring) { + return (((RenameRefactoring)refactoring).getStyle() & RefactoringStyles.NEEDS_PREVIEW) != 0; + } + return super.hasPreviewPage(); + } + + /* non java-doc + * @see RefactoringWizard#addUserInputPages + */ + protected void addUserInputPages() { + String initialSetting= getRenameRefactoring().getCurrentName(); + RenameInputWizardPage inputPage= createInputPage(fInputPageDescription, initialSetting); + inputPage.setImageDescriptor(fInputPageImageDescriptor); + addPage(inputPage); + } + + private IRenameRefactoring getRenameRefactoring() { + return (IRenameRefactoring)getRefactoring(); + } + + protected RenameInputWizardPage createInputPage(String message, String initialSetting) { + return new RenameInputWizardPage(message, fPageContextHelpId, true, initialSetting) { + protected RefactoringStatus validateTextField(String text) { + return validateNewName(text); + } + }; + } + + protected RefactoringStatus validateNewName(String newName) { + IRenameRefactoring ref= getRenameRefactoring(); + ref.setNewName(newName); + try{ + return ref.checkNewName(newName); + } catch (CoreException e){ + //XXX: should log the exception + String msg= e.getMessage() == null ? "": e.getMessage(); //$NON-NLS-1$ + return RefactoringStatus.createFatalErrorStatus(RefactoringMessages.getFormattedString("RenameRefactoringWizard.internal_error", msg));//$NON-NLS-1$ + } + } +} diff --git a/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/StatusContextViewerDescriptor.java b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/StatusContextViewerDescriptor.java new file mode 100644 index 00000000000..ef4d66935a8 --- /dev/null +++ b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/StatusContextViewerDescriptor.java @@ -0,0 +1,35 @@ +/********************************************************************** + * Copyright (c) 2004 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.internal.ui.refactoring; + +public class StatusContextViewerDescriptor /*extends AbstractDescriptor */{ + + private static final String EXT_ID= "statusContextViewers"; //$NON-NLS-1$ +/* + private static DescriptorManager fgDescriptions= new DescriptorManager(EXT_ID) { + protected AbstractDescriptor createDescriptor(IConfigurationElement element) { + return new StatusContextViewerDescriptor(element); + } + }; + + public static StatusContextViewerDescriptor get(Object element) throws CoreException { + return (StatusContextViewerDescriptor)fgDescriptions.getDescriptor(element); + } + + public StatusContextViewerDescriptor(IConfigurationElement element) { + super(element); + } + + public IStatusContextViewer createViewer() throws CoreException { + return (IStatusContextViewer)fConfigurationElement.createExecutableExtension(CLASS); + } + */ +} diff --git a/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/TextChangePreviewViewer.java b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/TextChangePreviewViewer.java new file mode 100644 index 00000000000..f955b946cd8 --- /dev/null +++ b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/TextChangePreviewViewer.java @@ -0,0 +1,191 @@ +/********************************************************************** + * Copyright (c) 2004 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.internal.ui.refactoring; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.io.UnsupportedEncodingException; + +import org.eclipse.compare.CompareConfiguration; +import org.eclipse.compare.CompareUI; +import org.eclipse.compare.CompareViewerSwitchingPane; +import org.eclipse.compare.IStreamContentAccessor; +import org.eclipse.compare.ITypedElement; +import org.eclipse.compare.structuremergeviewer.DiffNode; +import org.eclipse.compare.structuremergeviewer.ICompareInput; + +import org.eclipse.core.runtime.CoreException; + +import org.eclipse.core.resources.ResourcesPlugin; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; + +import org.eclipse.jface.text.IRegion; +import org.eclipse.jface.viewers.Viewer; + +import org.eclipse.cdt.internal.corext.refactoring.changes.TextChange; +import org.eclipse.cdt.internal.corext.refactoring.changes.TextChange.EditChange; + +public class TextChangePreviewViewer implements IChangePreviewViewer { + + private ComparePreviewer fViewer; + + private static class TextEditChangeInput { + EditChange change; + int surroundingLines; + + EditChange[] changes; + IRegion range; + } + + private static class ComparePreviewer extends CompareViewerSwitchingPane { + private CompareConfiguration fCompareConfiguration; + public ComparePreviewer(Composite parent) { + super(parent, SWT.BORDER | SWT.FLAT, true); + fCompareConfiguration= new CompareConfiguration(); + fCompareConfiguration.setLeftEditable(false); + fCompareConfiguration.setLeftLabel(RefactoringMessages.getString("ComparePreviewer.original_source")); //$NON-NLS-1$ + fCompareConfiguration.setRightEditable(false); + fCompareConfiguration.setRightLabel(RefactoringMessages.getString("ComparePreviewer.refactored_source")); //$NON-NLS-1$ + } + protected Viewer getViewer(Viewer oldViewer, Object input) { + return CompareUI.findContentViewer(oldViewer, (ICompareInput)input, this, fCompareConfiguration); + } + public void setText(String text) { + /* + Object input= getInput(); + if (input instanceof CompareInput) { + CompareInput cInput= (CompareInput)input; + setImage(fLabelProvider.getImage(cInput.getChangeElement())); + super.setText(fLabelProvider.getText(cInput.getChangeElement())); + } else { + super.setText(text); + setImage(null); + } + */ + super.setText(text); + } + } + + private static class CompareElement implements ITypedElement, IStreamContentAccessor { + private InputStream fContent; + private String fType; + public CompareElement(String content, String type) { + fContent= createInputStream(content); + fType= type; + } + public String getName() { + return RefactoringMessages.getString("ComparePreviewer.element_name"); //$NON-NLS-1$ + } + public Image getImage() { + return null; + } + public String getType() { + return fType; + } + public InputStream getContents() throws CoreException { + return fContent; + } + private static InputStream createInputStream(String s) { + try { + return new ByteArrayInputStream(s.getBytes(ResourcesPlugin.getEncoding())); + } catch (UnsupportedEncodingException e) { + return new ByteArrayInputStream(s.getBytes()); + } + } + } + + public static Object createInput(TextChange change) { + return change; + } + + public static Object createInput(EditChange change, int surroundingLines) { + TextEditChangeInput result= new TextEditChangeInput(); + result.change= change; + result.surroundingLines= surroundingLines; + return result; + } + + public static Object createInput(EditChange[] changes, IRegion range) { + TextEditChangeInput result= new TextEditChangeInput(); + result.changes= changes; + result.range= range; + return result; + } + + + /* (non-Javadoc) + * @see org.eclipse.jdt.internal.ui.refactoring.IChangePreviewViewer#createControl(org.eclipse.swt.widgets.Composite) + */ + public void createControl(Composite parent) { + fViewer= new ComparePreviewer(parent); + } + + /* (non-Javadoc) + * @see org.eclipse.jdt.internal.ui.refactoring.IChangePreviewViewer#getControl() + */ + public Control getControl() { + return fViewer; + } + + /* (non-Javadoc) + * @see org.eclipse.jdt.internal.ui.refactoring.IChangePreviewViewer#setInput(org.eclipse.jdt.internal.ui.refactoring.ChangeElement) + */ + public void setInput(Object input) throws CoreException { + if (input instanceof TextChange) { + TextChange change= (TextChange)input; + setInput(change.getCurrentContent(), change.getPreviewContent(), change.getTextType()); + return; + } else if (input instanceof TextEditChangeInput) { + TextEditChangeInput edi= (TextEditChangeInput)input; + if (edi.change != null && edi.surroundingLines >= 0) { + TextChange.EditChange editChange= edi.change; + TextChange change= editChange.getTextChange(); + setInput(change.getCurrentContent(editChange, 2), + change.getPreviewContent(editChange, 2), + change.getTextType()); + return; + } else if (edi.changes != null && edi.changes.length > 0 && edi.range != null) { + TextChange change= edi.changes[0].getTextChange(); + setInput(change.getCurrentContent(edi.range), + change.getPreviewContent(edi.changes, edi.range), + change.getTextType()); + return; + } + } else { + fViewer.setInput(null); + } + /* + } else if (change instanceof CreateTextFileChange){ + CreateTextFileChange ctfc= (CreateTextFileChange)change; + String type= ctfc.isJavaFile() ? JAVA_TYPE: TEXT_TYPE; + setInput(input, ctfc.getCurrentContent(), ctfc.getPreview(), type); + return; + } + */ + } + + /* (non-Javadoc) + * @see org.eclipse.jdt.internal.ui.refactoring.IChangePreviewViewer#refresh() + */ + public void refresh() { + fViewer.getViewer().refresh(); + } + + private void setInput(String left, String right, String type) { + fViewer.setInput(new DiffNode( + new CompareElement(left, type), + new CompareElement(right, type))); + } +} diff --git a/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/TextEditChangeElement.java b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/TextEditChangeElement.java new file mode 100644 index 00000000000..1be13ad3513 --- /dev/null +++ b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/TextEditChangeElement.java @@ -0,0 +1,116 @@ +/********************************************************************** + * Copyright (c) 2004 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.internal.ui.refactoring; + +import org.eclipse.core.runtime.CoreException; + +import org.eclipse.jface.text.IRegion; +import org.eclipse.jface.util.Assert; + +import org.eclipse.cdt.internal.corext.refactoring.base.IChange; +import org.eclipse.cdt.internal.corext.refactoring.changes.TextChange; +import org.eclipse.cdt.internal.corext.refactoring.changes.TextChange.EditChange; + +/* package */ class TextEditChangeElement extends ChangeElement { + + private static final ChangeElement[] fgChildren= new ChangeElement[0]; + + private EditChange fChange; + + public TextEditChangeElement(ChangeElement parent, EditChange change) { + super(parent); + fChange= change; + Assert.isNotNull(fChange); + } + + /** + * Returns the TextEditChange managed by this node. + * + * @return the TextEditChange + */ + public EditChange getTextEditChange() { + return fChange; + } + + /* (non-Javadoc) + * @see org.eclipse.jdt.internal.ui.refactoring.ChangeElement#getChangePreviewViewer() + */ +// public ChangePreviewViewerDescriptor getChangePreviewViewer() throws CoreException { +// DefaultChangeElement element= getStandardChangeElement(); +// if (element == null) +// return null; +// return element.getChangePreviewViewer(); +// } + + /* (non-Javadoc) + * @see org.eclipse.jdt.internal.ui.refactoring.ChangeElement#feedInput(org.eclipse.jdt.internal.ui.refactoring.IChangePreviewViewer) + */ + public void feedInput(IChangePreviewViewer viewer) throws CoreException { + DefaultChangeElement element= getStandardChangeElement(); + if (element != null) { + IChange change= element.getChange(); + if (change instanceof TextChange) { + IRegion range= getTextRange(this); + Object input= null; + if (range != null) { + input= TextChangePreviewViewer.createInput(new EditChange[] {fChange}, range); + } else { + input= TextChangePreviewViewer.createInput(fChange, 2); + } + viewer.setInput(input); + } + } else { + viewer.setInput(null); + } + } + + /* non Java-doc + * @see ChangeElement#setActive + */ + public void setActive(boolean active) { + fChange.setActive(active); + } + + /* non Java-doc + * @see ChangeElement.getActive + */ + public int getActive() { + return fChange.isActive() ? ACTIVE : INACTIVE; + } + + /* non Java-doc + * @see ChangeElement.getChildren + */ + public ChangeElement[] getChildren() { + return fgChildren; + } + + private DefaultChangeElement getStandardChangeElement() { + ChangeElement element= getParent(); + while(!(element instanceof DefaultChangeElement) && element != null) { + element= element.getParent(); + } + return (DefaultChangeElement)element; + } + + private static IRegion getTextRange(ChangeElement element) throws CoreException { + if (element == null) + return null; + if (element instanceof PseudoCChangeElement) { + return ((PseudoCChangeElement)element).getTextRange(); + } else + if (element instanceof DefaultChangeElement) { + return null; + } + return getTextRange(element.getParent()); + } +} + diff --git a/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/TextInputWizardPage.java b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/TextInputWizardPage.java new file mode 100644 index 00000000000..fd097af7305 --- /dev/null +++ b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/TextInputWizardPage.java @@ -0,0 +1,170 @@ +/********************************************************************** + * Copyright (c) 2004 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation +***********************************************************************/ + +package org.eclipse.cdt.internal.ui.refactoring; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Text; + +import org.eclipse.jface.util.Assert; + +import org.eclipse.cdt.internal.corext.refactoring.base.RefactoringStatus; + +public abstract class TextInputWizardPage extends UserInputWizardPage{ + + protected String fInitialValue; + protected Text fTextField; + + public static final String PAGE_NAME= "TextInputPage";//$NON-NLS-1$ + + /** + * Creates a new text input page. + * @param isLastUserPage true if this page is the wizard's last + * user input page. Otherwise false. + */ + public TextInputWizardPage(String description, boolean isLastUserPage) { + this(description, isLastUserPage, ""); //$NON-NLS-1$ + } + + /** + * Creates a new text input page. + * @param isLastUserPage true if this page is the wizard's last + * user input page. Otherwise false. + * @param initialSetting the initialSetting. + */ + public TextInputWizardPage(String description, boolean isLastUserPage, String initialValue) { + super(PAGE_NAME, isLastUserPage); + Assert.isNotNull(initialValue); + setDescription(description); + fInitialValue= initialValue; + } + + /** + * Returns whether the initial input is valid. Typically it is not, because the + * user is required to provide some information e.g. a new type name etc. + * + * @return true iff the input provided at initialization is valid + */ + protected boolean isInitialInputValid(){ + return false; + } + + /** + * Returns whether an empty string is a valid input. Typically it is not, because + * the user is required to provide some information e.g. a new type name etc. + * + * @return true iff an empty string is valid + */ + protected boolean isEmptyInputValid(){ + return false; + } + + /** + * Returns the content of the text input field. + * + * @return the content of the text input field. Returns null if + * not text input field has been created + */ + protected String getText() { + if (fTextField == null) + return null; + return fTextField.getText(); + } + + /** + * Sets the new text for the text field. Does nothing if the text field has not been created. + * @param text the new value + */ + protected void setText(String text) { + if (fTextField == null) + return; + fTextField.setText(text); + } + + /** + * Performs input validation. Returns a RefactoringStatus which + * describes the result of input validation. Null is interpreted + * as no error. + */ + protected RefactoringStatus validateTextField(String text){ + return null; + } + + protected Text createTextInputField(Composite parent) { + return createTextInputField(parent, SWT.BORDER); + } + + protected Text createTextInputField(Composite parent, int style) { + fTextField= new Text(parent, style); + fTextField.addModifyListener(new ModifyListener() { + public void modifyText(ModifyEvent e) { + textModified(getText()); + } + }); + fTextField.setText(fInitialValue); + return fTextField; + } + + /** + * Checks the page's state and issues a corresponding error message. The page validation + * is computed by calling validatePage. + */ + protected void textModified(String text) { + if (! isEmptyInputValid() && text.equals("")){ //$NON-NLS-1$ + setPageComplete(false); + setErrorMessage(null); + restoreMessage(); + return; + } + if ((! isInitialInputValid()) && text.equals(fInitialValue)){ + setPageComplete(false); + //setErrorMessage(null); + setErrorMessage(RefactoringMessages.getString("RenameInputWizardPage.no_undo")); //$NON-NLS-1$ + restoreMessage(); + return; + } + + setPageComplete(validateTextField(text)); + } + + /** + * Subclasses can override if they want to restore the message differently. + * This implementation calls setMessage(null), which clears the message + * thus exposing the description. + */ + protected void restoreMessage(){ + setMessage(null); + } + + /* (non-Javadoc) + * Method declared in IDialogPage + */ + public void dispose() { + fTextField= null; + } + + /* (non-Javadoc) + * Method declared in WizardPage + */ + public void setVisible(boolean visible) { + if (visible) { + textModified(getText()); + } + super.setVisible(visible); + if (visible && fTextField != null) { + fTextField.setFocus(); + } + } +} + diff --git a/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/UserInputWizardPage.java b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/UserInputWizardPage.java new file mode 100644 index 00000000000..737117027fc --- /dev/null +++ b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/UserInputWizardPage.java @@ -0,0 +1,151 @@ +/********************************************************************** + * Copyright (c) 2004 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation +***********************************************************************/ + +package org.eclipse.cdt.internal.ui.refactoring; + +import org.eclipse.jface.wizard.IWizardPage; + +import org.eclipse.core.runtime.IStatus; + +import org.eclipse.cdt.internal.corext.refactoring.base.Refactoring; +import org.eclipse.cdt.internal.corext.refactoring.base.RefactoringStatus; + +/** + * An abstract wizard page that can be used to implement user input pages for + * refactoring wizards. Usually user input pages are pages shown at the beginning + * of a wizard. As soon as the "last" user input page is left a corresponding + * precondition check is executed. + */ +public abstract class UserInputWizardPage extends RefactoringWizardPage { + + private final boolean fIsLastUserPage; + + /** + * Creates a new user input page. + * @param name the page's name. + * @param isLastUserPage true if this page is the wizard's last + * user input page. Otherwise false. + */ + public UserInputWizardPage(String name, boolean isLastUserPage) { + super(name); + fIsLastUserPage= isLastUserPage; + } + + /** + * Sets the page's complete status depending on the given + * ReactoringStatus. + * + * @param status the RefactoringStatus + */ + public void setPageComplete(RefactoringStatus status) { + getRefactoringWizard().setStatus(status); + + int severity= status.getSeverity(); + if (severity == RefactoringStatus.FATAL){ + setPageComplete(false); + setErrorMessage(status.getFirstMessage(severity)); + } else { + setPageComplete(true); + //setErrorMessage(null); + setErrorMessage(RefactoringMessages.getString("RenameInputWizardPage.no_undo")); //$NON-NLS-1$ + if (severity == RefactoringStatus.OK) + setMessage(null, NONE); + else + setMessage(status.getFirstMessage(severity), getCorrespondingIStatusSeverity(severity)); + } + } + + /* (non-Javadoc) + * Method declared in WizardPage + */ + public void setVisible(boolean visible) { + if (visible) + getRefactoringWizard().setChange(null); + super.setVisible(visible); + } + + /* (non-JavaDoc) + * Method declared in IWizardPage. + */ + public IWizardPage getNextPage() { + if (fIsLastUserPage) + return getRefactoringWizard().computeUserInputSuccessorPage(this); + else + return super.getNextPage(); + } + + /* (non-JavaDoc) + * Method declared in IWizardPage. + */ + public boolean canFlipToNextPage() { + if (fIsLastUserPage) { + // we can't call getNextPage to determine if flipping is allowed since computing + // the next page is quite expensive (checking preconditions and creating a + // change). So we say yes if the page is complete. + return isPageComplete(); + } else { + return super.canFlipToNextPage(); + } + } + + /* (non-JavaDoc) + * Method defined in RefactoringWizardPage + */ + protected boolean performFinish() { + RefactoringWizard wizard= getRefactoringWizard(); + int threshold= RefactoringPreferences.getCheckPassedSeverity(); + RefactoringStatus activationStatus= wizard.getActivationStatus(); + RefactoringStatus inputStatus= null; + RefactoringStatus status= new RefactoringStatus(); + Refactoring refactoring= getRefactoring(); + boolean result= false; + + if (activationStatus != null && activationStatus.getSeverity() > threshold) { + inputStatus= wizard.checkInput(); + } else { + CreateChangeOperation create= new CreateChangeOperation(refactoring, CreateChangeOperation.CHECK_INPUT); + create.setCheckPassedSeverity(threshold); + + PerformChangeOperation perform= new PerformChangeOperation(create); + perform.setCheckPassedSeverity(threshold); + + result= wizard.performFinish(perform); + wizard.setChange(create.getChange()); + if (!result) + return false; + inputStatus= create.getStatus(); + } + + status.merge(activationStatus); + status.merge(inputStatus); + + if (status.getSeverity() > threshold) { + wizard.setStatus(status); + IWizardPage nextPage= wizard.getPage(ErrorWizardPage.PAGE_NAME); + wizard.getContainer().showPage(nextPage); + return false; + } + + return result; + } + + private static int getCorrespondingIStatusSeverity(int severity) { + if (severity == RefactoringStatus.FATAL) + return IStatus.ERROR; + if (severity == RefactoringStatus.ERROR) + return IStatus.WARNING; + if (severity == RefactoringStatus.WARNING) + return IStatus.WARNING; + if (severity == RefactoringStatus.INFO) + return IStatus.INFO; + return IStatus.OK; + } +} diff --git a/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/UserInterfaceStarter.java b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/UserInterfaceStarter.java new file mode 100644 index 00000000000..e18343221b3 --- /dev/null +++ b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/UserInterfaceStarter.java @@ -0,0 +1,82 @@ +/********************************************************************** + * Copyright (c) 2004 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.internal.ui.refactoring; + + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; + +import org.eclipse.swt.widgets.Shell; + +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.util.Assert; + +import org.eclipse.cdt.internal.corext.refactoring.IRefactoringProcessor; +import org.eclipse.cdt.internal.corext.refactoring.base.Refactoring; + +import org.eclipse.cdt.internal.ui.refactoring.RefactoringStarter; + +/** + * Opens the user interface for a given refactoring. + */ +public class UserInterfaceStarter { + + protected static final String WIZARD= "wizard"; //$NON-NLS-1$ + + private IConfigurationElement fConfigElement; + + /** + * Opens the user interface for the given refactoring. The provided + * shell should be used as a parent shell. + * + * @param refactoring the refactoring for which the user interface + * should be opened + * @param parent the parent shell to be used + * + * @exception CoreException if the user interface can't be activated + */ + public static void run(Refactoring refactoring, Shell parent) throws CoreException { + run(refactoring, parent, true); + } + + /** + * Opens the user interface for the given refactoring. The provided + * shell should be used as a parent shell. + * + * @param refactoring the refactoring for which the user interface + * should be opened + * @param parent the parent shell to be used + * @param forceSave true if saving is needed before + * executing the refactoring + * + * @exception CoreException if the user interface can't be activated + */ + public static void run(Refactoring refactoring, Shell parent, boolean forceSave) throws CoreException { + IRefactoringProcessor processor= (IRefactoringProcessor)refactoring.getAdapter(IRefactoringProcessor.class); + // TODO this should change. Either IRefactoring models Refactoring API. + Assert.isNotNull(processor); + UserInterfaceStarter starter= new UserInterfaceStarter(); + if(starter != null) { + starter.activate(refactoring, parent, forceSave); + } else + { + MessageDialog.openInformation(parent, + refactoring.getName(), + "No user interface found"); + } + } + + protected void activate(Refactoring refactoring, Shell parent, boolean save) throws CoreException { + RenameElementWizard wizard= new RenameElementWizard(); + wizard.initialize(refactoring); + new RefactoringStarter().activate(refactoring, wizard, parent, wizard.getDefaultPageTitle(), save); + } +} diff --git a/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/refactoringui.properties b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/refactoringui.properties new file mode 100644 index 00000000000..4de57e1f341 --- /dev/null +++ b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/internal/ui/refactoring/refactoringui.properties @@ -0,0 +1,569 @@ +############################################################################### +# Copyright (c) 2004 Rational Software Corporation and others. +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Common Public License v0.5 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/cpl-v05.html +# +# Contributors: +# IBM Rational Software - Initial API and implementation +############################################################################### +####################################### +# org.eclipse.jdt.internal.ui.refactoring +####################################### + +RefactorActionGroup.no_refactoring_available= + +ErrorWizardPage.no_context_information_available= No context information available +ErrorWizardPage.cannot_proceed= Cannot proceed due to the following problems. +ErrorWizardPage.confirm= Review the information provided in the list below. Click 'Next' to view the next item or 'Finish'. +ErrorWizardPage.next_Change=Next Problem +ErrorWizardPage.previous_Change=Previous Problem + +PreviewWizardPage.no_preview= No preview available +PreviewWizardPage.next_Change= Select Next Change +PreviewWizardPage.previous_Change= Select Previous Change +PreviewWizardPage.changes= Changes to be performed + +ComparePreviewer.element_name= Compare element name +ComparePreviewer.original_source= Original Source +ComparePreviewer.refactored_source= Refactored Source + +PreviewWizardPage.description= The following changes are necessary to perform the refactoring. +PreviewWizardPage.changeElementLabelProvider.textFormat= {0} - {1} +PreviewWizardPage.changeElementLabelProvider.textFormatEdit= {0}: {1} + +RefactoringPreferencePage.description= Refactoring settings: +RefactoringPreferencePage.auto_save= &Save all modified resources automatically prior to refactoring +RefactoringPreferencePage.error= \ &Errors would be present in the workspace after performing the refactoring +RefactoringPreferencePage.fatal_error= \ &Problems occur that prevent the refactoring from being performed +RefactoringPreferencePage.info= \ &Information is generated by the precondition checking +RefactoringPreferencePage.show_error_page= Confirm the execution of the refactoring if +RefactoringPreferencePage.warning= \ &Warnings would be present in the workspace after performing the refactoring + +RefactoringWizard.Internal_error= Internal error while creating a change object. See log for details. +RefactoringWizard.internal_error_1= Internal error during precondition checking. See log for detailed error description +RefactoringWizard.refactoring= Refactoring +RefactoringWizard.see_log= {0}. See log for details. +RefactoringWizard.title= Refactoring +RefactoringWizard.undoing= Undoing changes: +RefactoringWizard.unexpected_exception= Unexpected exception while creating a change object. See log for a detailed error description. +RefactoringWizard.unexpected_exception_1= Unexpected exception while performing the refactoring. See log for a detailed error description. + +RenameInputWizardPage.enter_name= &Enter new name: +RenameInputWizardPage.old_name= Renaming: +RenameInputWizardPage.no_undo=This operation can not be undone! + +RenameRefactoringWizard.internal_error= Internal error during name checking: {0} + +PerformChangeOperation.unrecoverable_error= Unrecoverable error occurred while performing the refactoring. + +####################################### +# org.eclipse.jdt.internal.ui.actions +####################################### + +OpenRefactoringWizardAction.refactoring=Refactoring +OpenRefactoringWizardAction.exception=Unexpected exception occurred. See log for details + +ExtractMethodAction.label=&Extract Method... +ExtractMethodAction.dialog.title=Extract Method + +SurroundWithTryCatchAction.label=Surround with &try/catch Block +SurroundWithTryCatchAction.dialog.title=Surround with try/catch +SurroundWithTryCatchAction.exception=Unexpected exception occurred. See log for details +SurroundWithTryCatchAction.no_exceptions=No uncaught exceptions are thrown by the selected code. Catch java.lang.RuntimeException ? + +RefactoringGroup.rename_method_message=Enter the new name for this method. +RefactoringGroup.rename_method_title=Rename Method +RefactoringGroup.rename_type_message=Enter the new name for this type. +RefactoringGroup.rename_type_title=Rename Type +RefactoringGroup.modify_Parameters_label=Change Method Si&gnature... +RefactoringGroup.pull_Up_label=Pu&ll Up... +RefactoringGroup.move_label=&Move... +RefactoringGroup.rename_resource_message=Enter the new name for this resource. +RefactoringGroup.rename_resource_title=Rename Resource +RefactoringGroup.rename_java_project_message=Enter the new name for this C project. +RefactoringGroup.rename_java_project_title=Rename C Project +RefactoringGroup.rename_source_folder_message=Enter the new name for this source folder. +RefactoringGroup.rename_source_folder_title=Rename Source Folder + +RefactoringErrorDialogUtil.cannot_perform=This operation cannot be performed. + +RefactoringStarter.unexpected_exception=Unexpected exception. See log for details +RefactoringStarter.saving=Saving Resources +RefactoringStarter.always_save=&Always save all modified resources automatically prior to refactoring +RefactoringStarter.save_all_resources=Save all modified resources +RefactoringStarter.must_save=All modified resources have to be saved before this operation.\n Click 'OK' to confirm or click 'Cancel' + +####################################### +# org.eclipse.jdt.internal.ui.changes +####################################### + +ChangeExceptionHandler.abort=Abort +ChangeExceptionHandler.refactoring=Refactoring +ChangeExceptionHandler.undo=Undo +ChangeExceptionHandler.unexpected_exception=An exception has been caught while processing the change ''{0}''. +ChangeExceptionHandler.button_explanation= \n Click \"Undo\" to undo all successfully executed changes.\n Click \"Abort\" to abort the refactoring. +ChangeExceptionHandler.no_details= Exception does not provide a detail message + +####################################### +# org.eclipse.jdt.internal.ui.code +####################################### + +ExtractMethodWizard.extract_method=Extract Method + +ExtractMethodInputPage.access_Modifiers=Access modifier: +ExtractMethodInputPage.public=&public +ExtractMethodInputPage.default=de&fault +ExtractMethodInputPage.protected=pro&tected +ExtractMethodInputPage.private=pri&vate +ExtractMethodInputPage.signature_preview=Signature preview: +ExtractMethodInputPage.description=Enter new method name and specify the method's visibility +ExtractMethodInputPage.label_text=&Method name: +ExtractMethodInputPage.parameters=Pa&rameters: +ExtractMethodInputPage.throwRuntimeExceptions=&Add thrown runtime exceptions to method signature +ExtractMethodInputPage.validation.emptyMethodName=Provide a method name +ExtractMethodInputPage.validation.emptyParameterName=Parameter names cannot be empty +ExtractMethodInputPage.duplicates.none=Repla&ce duplicate code fragments +ExtractMethodInputPage.duplicates.single=Repla&ce 1 duplicate code fragment +ExtractMethodInputPage.duplicates.multi=Repla&ce {0} duplicate code fragments + +InlineMethodWizard.page_title=Inline Method + +####################################### +# org.eclipse.jdt.internal.ui.sef +####################################### + +SelfEncapsulateField.sef=Self Encapsulate Field + +SelfEncapsulateFieldInputPage.description=Create getting and setting methods for the field and use only those to access the field +SelfEncapsulateFieldInputPage.getter_name=&Getter name: +SelfEncapsulateFieldInputPage.setter_name=&Setter name: +SelfEncapsulateFieldInputPage.insert_after=&Insert new methods after: +SelfEncapsulateFieldInputPage.first_method=As first method +SelfEncapsulateFieldInputPage.access_Modifiers=Access modifier: +SelfEncapsulateFieldInputPage.public=&public +SelfEncapsulateFieldInputPage.default=defa&ult +SelfEncapsulateFieldInputPage.protected=pro&tected +SelfEncapsulateFieldInputPage.private=pri&vate +SelfEncapsulateField.field_access=Field access in declaring class: +SelfEncapsulateField.use_setter_getter=us&e setter and getter +SelfEncapsulateField.keep_references=&keep field reference + +####################################### +# org.eclipse.jdt.internal.ui.undo +####################################### + +UndoManagerAction.cannot_be_executed={0} cannot be executed. +UndoManagerAction.error=Error +UndoManagerAction.internal_error=Internal Error in Undo Manager +UndoManagerAction.unsaved_filed=Some of the affected resources are unsaved or read only. Please revert unsaved files and make read only resources writeable. + +UndoRefactoringAction.label=&Undo +UndoRefactoringAction.extendedLabel=Undo - {0} +UndoRefactoringAction.name=Undo + +RedoRefactoringAction.label=&Redo +RedoRefactoringAction.extendedLabel=Redo - {0} +RedoRefactoringAction.name=Redo + +####################################### +# Misc +####################################### + +ExtractTempWizard.defaultPageTitle=Extract Local Variable +ExtractTempInputPage.enter_name=Enter a name for the new local variable +ExtractTempInputPage.variable_name=&Variable name: +ExtractTempInputPage.replace_all=&Replace all occurrences of the selected expression with references to the local variable +ExtractTempInputPage.declare_final=&Declare the local variable as \'final\' +ExtractTempInputPage.signature_preview=Signature Preview: +ExtractTempInputPage.extract_local=Extract local variable +ExtractTempInputPage.exception=Unexpected exception. See log for details + +ExtractConstantInputPage.enter_name=Enter a name for the new constant +ExtractConstantInputPage.constant_name=&Constant name: +ExtractConstantInputPage.replace_all=&Replace all occurrences of the selected expression with references to the constant +ExtractConstantInputPage.qualify_constant_references_with_class_name=&Qualify constant references with class name +ExtractConstantInputPage.signature_preview=Signature Preview: +ExtractConstantInputPage.exception=Unexpected exception. See log for details +ExtractConstantInputPage.access_modifiers=Access modifier: +ExtractConstantInputPage.selection_refers_to_nonfinal_fields=The selected expression refers to non-final or non-static fields + +PromoteTempInputPage.description=Select visibility and name for the new field + +MoveMembersWizard.page_title=Move Static Member(s) + +RenameInputWizardPage.update_references=&Update references to the renamed element +RenameInputWizardPage.ppdate_string_references=U&pdate references in string literals +RenameInputWizardPage.update_comment_references=Up&date references in regular comments +RenameInputWizardPage.update_qualified_names=Update fully &qualified name in non C files (forces preview) + +RefactoringSupportFactory.rename=Rename +RefactoringSupportFactory.rename_Package=Rename Package +RefactoringSupportFactory.package_name=Enter the new name for this package. +RefactoringSupportFactory.rename_Cu=Rename Translation Unit +RefactoringSupportFactory.translation_unit=Enter the new name for this translation unit. + +PullUpInputPage.select_methods=Select the methods to be removed in subtypes after pull up. +PullUpInputPage.pull_Up=Pull Up +PullUpInputPage.pull_up1=Pull Up Methods +PullUpInputPage.exception=Unexpected exception. See log for details + +ExtractTempAction.label=Extract Local &Variable... +ExtractTempAction.extract_temp=Extract Local Variable + +ConvertLocalToField.label=Conv&ert Local Variable to Field... +ConvertLocalToField.title=Convert Local Variable to Field + +ExtractConstantAction.label=Extr&act Constant... +ExtractConstantAction.extract_constant=Extract Constant + +InlineTempAction.inline_temp=Inline Local Variable +InlineTempAction.label=&Inline Local Variable... + +RenameAction.rename=Rename +RenameAction.unavailable=Operation unavailable on the current selection.\nSelect a java project, source folder, resource, package or a translation unit, or a non binary type, field, method, parameter or a local variable. +RenameAction.text=Rena&me... + +RenameInputDialog.update_references=&Update references to the renamed element + +RenameTempAction.rename_Local_Variable=Rename Local Variable +RenameTempAction.choose_new_name=Choose a new name for the local variable + +NewTextRefactoringAction.exception=Unexpected exception occurred. See log for details + +RenameFieldWizard.defaultPageTitle=Rename Field +RenameFieldWizard.inputPage.description=Enter the new name for this field. +RenameFieldInputWizardPage.rename_getter=Rename &getter +RenameFieldInputWizardPage.rename_getter_to=Rename &getter: ''{0}'' to ''{1}'' +RenameFieldInputWizardPage.rename_setter=Rename &setter +RenameFieldInputWizardPage.rename_setter_to=Rename &setter: ''{0}'' to ''{1}'' +RenameFieldInputWizardPage.setter_label={0} ({1}) +RenameFieldInputWizardPage.getter_label={0} ({1}) + +MoveMembersInputPage.descriptionKey={0} member(s) from ''{1}'' +MoveMembersInputPage.destination_single=&Destination type for ''{0}'': +MoveMembersInputPage.destination_multi=&Destination type for {0} selected elements: +MoveMembersInputPage.browse=&Browse... +MoveMembersInputPage.move_Member=Move Member +MoveMembersInputPage.exception=Unexpected exception. See log for details +MoveMembersInputPage.choose_Type=Choose Type +MoveMembersInputPage.dialogMessage=&Choose a type (? = any character, * = any string): +MoveMembersInputPage.upperListLabel=&Matching types: +MoveMembersInputPage.lowerListLabel=&Qualifier: +MoveMembersInputPage.not_found=Destination type does not exist (fully qualified type name expected) +MoveMembersInputPage.invalid_name=Invalid Type Name +MoveMembersInputPage.Invalid_selection=Invalid selection +MoveMembersInputPage.no_binary=Cannot move members to binary types +MoveMembersInputPage.internal_error=Internal error. See log for details. +MoveMembersInputPage.move=Move Members + +RenameCElementAction.exception=Unexpected exception occurred. See log for details +RenameCElementAction.not_available=Operation unavailable on the current selection.\nSelect a java project, source folder, resource, package, translation unit, type, field, method, parameter or a local variable +RenameCElementAction.name=Rename + +MoveAction.text=Mo&ve... + +QualifiedNameComponent.patterns.label= &File name patterns: +QualifiedNameComponent.patterns.description= The patterns are separated by comma (* = any string, ? = any character) + +## Pull Up +PullUpInputPage.hierarchyLabal=Select the methods to be removed in subtypes after pull up.\n{0} method(s) selected. +PullUpInputPage.see_log=See log + +##Change Signature +ChangeSignatureInputPage.change=Change the signature of the selected method and all its overriding methods. +ChangeSignatureInputPage.parameters=Pa&rameters +ChangeSignatureInputPage.exceptions=E&xceptions +ChangeSignatureInputPage.method_Signature_Preview=Method Signature Preview: +ChangeSignatureInputPage.exception=Unexpected exception. See log for details +ChangeSignatureRefactoring.modify_Parameters=Change Method Signature + +RenameTempAction.exception=Unexpected Exception. See log for details +ModifyParametersAction.unavailable=To activate this refactoring, please select the name of a method +OpenRefactoringWizardAction.unavailable=Operation Unavailable +PullUpAction.unavailable=To activate this refactoring, please select the name of an instance method or field +MoveMembersAction.unavailable=To activate this refactoring, please select the name of a static method or field +PullUpInputPage.subtypes=&Subtypes of type ''{0}'' + +RefactoringSupportFactory.error.title=Rename +RefactoringSupportFactory.error.message=Renaming not possible. +MoveMembersAction.error.title=Refactoring +MoveMembersAction.error.message=Operation not possible. +RefactoringErrorDialogUtil.okToPerformQuestion=\n\nOK to perform the operation on this method? + +ChangeParametersControl.table.type=Type +ChangeParametersControl.table.name=Name +ChangeParametersControl.table.defaultValue=Default value +ChangeParametersControl.buttons.move_up=&Up +ChangeParametersControl.buttons.move_down=&Down +ChangeParametersControl.buttons.edit=Ed&it... +ChangeParametersControl.buttons.add=&Add +ChangeParametersControl.buttons.remove=Re&move + +ChangeExceptionsControl.buttons.add=&Add... +ChangeExceptionsControl.buttons.remove=Re&move +ChangeExceptionsControl.choose.title=Add Exception +ChangeExceptionsControl.choose.message=&Choose an Exception (? = any character, * = any string): +ChangeExceptionsControl.not_exception=Not an Exception + +ParameterEditDialog.title=Method Parameter +ParameterEditDialog.message.new=Declaration of Parameter: +ParameterEditDialog.message=Declaration of Parameter ''{0}'': + +ParameterEditDialog.type=&Type: +ParameterEditDialog.type.error= The empty string is not a valid type name. +ParameterEditDialog.name=&Name: +ParameterEditDialog.name.error= Parameter name must not be empty. +ParameterEditDialog.defaultValue=&Default value: +ParameterEditDialog.defaultValue.error= Default value must not be empty. + +InlineTempWizard.defaultPageTitle= Inline Local Variable +InlineTempInputPage.message.one= Inline 1 occurrence of local variable {0} ? +InlineTempInputPage.message.multi= Inline {0} occurrences of local variable {1} ? + +RefactoringWizardDialog2.buttons.preview.label=Previe&w > + +ChangeSignatureInputPage.Change_Signature=Change Signature +ChangeSignatureInputPage.return_type=Re&turn type: + +ConvertAnonymousToNestedInputPage.description=Select the name and modifiers for the new nested class +ConvertAnonymousToNestedInputPage.class_name=&Class name: +ConvertAnonymousToNestedInputPage.declare_final=Decla&re class as \'final\' + +ExtractConstantWizard.defaultPageTitle=Extract Constant +ExtractConstantInputPage.Internal_Error=Internal Error: please see log. + +ExtractInterfaceInputPage.description=Select the name for the new interface and select the members that will be declared in the interface. +ExtractInterfaceInputPage.Interface_name=&Interface name: +ExtractInterfaceInputPage.Members=&Members to declare in the interface: +ExtractInterfaceInputPage.Extract_Interface=Extract Interface +ExtractInterfaceInputPage.Internal_Error=Internal Error. See log for details +ExtractInterfaceInputPage.Select_All=&Select All +ExtractInterfaceInputPage.Deselect_All=&Deselect All +ExtractInterfaceInputPage.change_references=&Change references to the class ''{0}'' into references to the interface (where possible) +ExtractInterfaceWizard.Extract_Interface=Extract Interface + +InlineConstantInputPage.Inline=Inline +InlineConstantInputPage.All_references=&All references +InlineConstantInputPage.Delete_constant=&Delete constant declaration +InlineConstantInputPage.Only_selected=&Only the selected reference +InlineConstantWizard.message=Specify where to inline references to the constant. +InlineConstantWizard.Inline_Constant=Inline Constant +InlineConstantWizard.initializer_refers_to_fields=This constant\'s initializer refers to non-final or non-static fields + +MoveInnerToTopWizard.Move_Inner=Move Member Type to New File +MoveInnerToToplnputPage.description=Specify a name for the field that will be used to access the enclosing instance +MoveInnerToToplnputPage.create_field=&Create field for the enclosing instance +MoveInnerToToplnputPage.instance_final=&Mark the enclosing instance field as \'final\' +MoveInnerToToplnputPage.enter_name=Field &name: + +MoveInstanceMethodInputPage.Original_parameter=&Original receiver parameter name: +MoveInstanceMethodInputPage.New_name=New &method name: +MoveInstanceMethodInputPage.New_receiver=&New receiver for ''{0}'': +MoveInstanceMethodInputPage.Name=Name +MoveInstanceMethodInputPage.Type_Name=Type Name +MoveInstanceMethodWizard.Move_Method=Move Method + +PreviewWizardPage.no_source_code_change=The refactoring does not change any source code. + +PromoteTempInputPage.Field_declaration=Field decla&ration +PromoteTempInputPage.Current_method=&Current method +PromoteTempInputPage.constructors=C&lass constructor(s) +PromoteTempInputPage.Field_name=F&ield name: +PromoteTempInputPage.Initialize=Initialize in +PromoteTempInputPage.declare_static=D&eclare field as \'static\' +PromoteTempInputPage.declare_final=Decl&are field as \'final\' + +RefactoringStatusDialog.Cannot_proceed=Cannot proceed due to the following problems. +RefactoringStatusDialog.Please_look=Review the information provided in the list below. If you want to proceed, please click \'Continue\'. +RefactoringStatusDialog.Continue=Con&tinue +RefactoringStatusViewer.Found_problems=Found problems +RefactoringStatusViewer.Problem_context=Problem context + +UseSupertypeInputPage.Select_supertype=Select the supertype to use +UseSupertypeInputPage.Use_in_instanceof=&Use the selected supertype in \'instanceof\' expressions +UseSupertypeInputPage.Select_supertype_to_use=&Select the supertype to use: +UseSupertypeInputPage.No_updates=No updates possible for the selected supertype +UseSupertypeInputPage.Use_Supertype=Use Supertype +UseSupertypeInputPage.Internal_Error=Internal Error. See log for details +UseSupertypeInputPage.no_possible_updates={0} - no possible updates found +UseSupertypeInputPage.updates_possible_in_file={0} - updates possible in 1 file +UseSupertypeInputPage.updates_possible_in_files={0} - updates possible in {1} files +UseSupertypeWizard.Use_Super_Type_Where_Possible=Use Super Type Where Possible + +VisibilityControlUtil.Access_modifier=Access modifier +VisibilityControlUtil.defa&ult_4=d&efault +VisibilityControlUtil.final=&final +VisibilityControlUtil.synchronized=s&ynchronized + +PullUpWizard.defaultPageTitle=Pull up +PullUpInputPage1.pull_up=pull up +PullUpInputPage1.declare_abstract=declare abstract in destination +PullUpInputPage1.Create_stubs=&Create necessary methods stubs in non-abstract subclasses of the destination class +PullUpInputPage1.Select_destination=&Select destination class: +PullUpInputPage1.Specify_actions=&Specify actions for members: +PullUpInputPage1.Edit=&Edit... +PullUpInputPage1.Add_Required=&Add Required +PullUpInputPage1.Edit_members=Edit Members +PullUpInputPage1.Mark_selected_members=&Mark selected member(s) as: +PullUpInputPage1.Member=Member +PullUpInputPage1.Action=Action +PullUpInputPage1.Select_members_to_pull_up=No members selected to pull up or declare abstract +PullUpInputPage1.page_message=Select the members to pull up and their new declaring class.\n If you select methods, then click 'Next' to specify which matching methods you want to delete. +PullUpInputPage1.status_line={0} member(s) selected. + +PullUpInputPage2.Select=Restore &Defaults +PullUpInputPage2.Source=Source + +PushDownWizard.defaultPageTitle= Push Down +PushDownInputPage.leave_abstract=leave abstract declaration +PushDownInputPage.push_down=push down +PushDownInputPage.Specify_actions=&Specify actions for members: +PushDownInputPage.Member=Member +PushDownInputPage.Action=Action +PushDownInputPage.Edit=&Edit... +PushDownInputPage.Add_Required=&Add Required +PushDownInputPage.Push_Down=Push Down +PushDownInputPage.Internal_Error=Internal Error. See log for details. +PushDownInputPage.Edit_members=Edit Members +PushDownInputPage.Mark_selected_members=&Mark selected member(s) as: +PushDownInputPage.Select_members_to_push_down=No members selected to push down or declare abstract +PushDownInputPage.status_line={0} member(s) selected. + +ChangeSignatureInputPage.Internal_Error=Internal Error. See log for details. + +MoveInstanceMethodAction.dialog_title=Move Method +MoveInstanceMethodAction.Move_Method=Move Method... +MoveInstanceMethodAction.unexpected_exception=Unexpected exception during operation +MoveInstanceMethodAction.No_reference_or_declaration=No method reference or declaration selected. + +InlineConstantAction.dialog_title=Inline Constant +InlineConstantAction.inline_Constant=Inline &Constant... +InlineConstantAction.unexpected_exception=Unexpected exception during operation +InlineConstantAction.no_constant_reference_or_declaration=No constant reference or declaration selected. + +InlineMethodInputPage.description=Specify where to inline the method invocation. +InlineMethodInputPage.inline=Inline +InlineMethodInputPage.all_invocations=All invocations +InlineMethodInputPage.delete_declaration=Delete method declaration +InlineMethodInputPage.only_selected=Only the selected invocation + +InlineMethodAction.dialog_title=Inline Method +InlineMethodAction.inline_Method=I&nline Method... +InlineMethodAction.unexpected_exception=Unexpected exception during operation +InlineMethodAction.no_method_invocation_or_declaration_selected=No method invocation or declaration selected. + +UseSupertypeAction.use_Supertype=Use Supertype &Where Possible... +UseSupertypeAction.to_activate=To activate this refactoring, please select the name of a type +UseSupertypeAction.Refactoring=Refactoring +UseSupertypeAction.not_possible=Operation not possible. + +PushDownAction.Push_Down=Push &Down... +PushDownAction.To_activate=To activate this refactoring, please select the name of an instance method or field +PushDownAction.Refactoring=Refactoring +PushDownAction.not_possible=Operation not possible. + +MoveAction.Move=Move +MoveAction.select=Select a static method, a static field or an instance method that can be moved to a component (parameter or field). + +InlineAction.Inline=&Inline... +InlineAction.dialog_title=Inline +InlineAction.select=Select a method declaration, a method invocation, a static final field or a local variable that you want to inline. + +ExtractInterfaceAction.Extract_Interface=Ex&tract Interface... +ExtractInterfaceAction.To_activate=To activate this refactoring, please select the name of a top level class. +ExtractInterfaceAction.Refactoring=Refactoring +ExtractInterfaceAction.not_possible=Operation not possible. + +ConvertNestedToTopAction.Convert=Move M&ember Type to New File... +ConvertNestedToTopAction.To_activate=To activate this refactoring, please select the name of a nested type. +ConvertNestedToTopAction.Refactoring=Refactoring +ConvertNestedToTopAction.not_possible=Operation not possible. + +ConvertAnonymousToNestedAction.dialog_title=Convert Anonymous Class to Nested Class +ConvertAnonymousToNestedAction.Convert_Anonymous=Convert &Anonymous Class to Nested... +ConvertAnonymousToNestedAction.wizard_title=Convert Anonymous Class to Nested Class + +###################### Temporary Participant Keys ################################# +RenameResourceWizard.defaultPageTitle=Rename Resource +RenameResourceWizard.inputPage.description=Enter the new name for this resource. + +RenameCProject.defaultPageTitle=Rename C Project +RenameCProject.inputPage.description=Enter the new name for this C project. + +RenameSourceFolder.defaultPageTitle=Rename Source Folder +RenameSourceFolder.nputPage.description=Enter the new name for this source folder. + +RenamePackageWizard.defaultPageTitle=Rename Package +RenamePackageWizard.inputPage.description=Enter the new name for this package. + +RenameCuWizard.defaultPageTitle= Rename Translation Unit +RenameCuWizard.inputPage.description= Enter the new name for this translation unit. + +RenameTypeWizard.defaultPageTitle= Rename Element +RenameTypeWizard.inputPage.description= Enter the new name for this element. + +RenameMethodWizard.defaultPageTitle=Rename Method +RenameMethodWizard.inputPage.description= Enter the new name for this method. + +ExtractInterfaceWizard.12=Declare interface methods as ''{0}'' + +ParameterEditDialog.9=''{0}'' is not a valid parameter type name + +UseSupertypeWizard.10=No updates are possible for any of the supertypes + +DeleteWizard.1=Confirm Delete +DeleteWizard.2=Internal error. See log for details. +DeleteWizard.3=Are you sure you want to delete linked resource ''{0}''?\nOnly the workspace link will be deleted. Link target will remain unchanged. +DeleteWizard.4=Are you sure you want to delete {0}? +DeleteWizard.5=Are you sure you want to delete linked resource ''{0}''?\nOnly the workspace link will be deleted. Link target will remain unchanged. +DeleteWizard.6=Are you sure you want to delete linked resource ''{0}''?\nOnly the workspace link will be deleted. Link target will remain unchanged.\n\nNote that all subelements of the selected linked packages and package fragment roots will be removed from the workspace as well. +DeleteWizard.7=Are you sure you want to delete linked resource ''{0}''?\nOnly the workspace link will be deleted. Link target will remain unchanged. +DeleteWizard.8=Are you sure you want to delete {0}? +DeleteWizard.9=Are you sure you want to delete these {0} elements? +DeleteWizard.10=Are you sure you want to delete these {0} elements?\n\nSelection contains linked resources.\nOnly the workspace links will be deleted. Link targets will remain unchanged. +DeleteWizard.11=Are you sure you want to delete these {0} elements?\n\nSelection contains linked packages.\nOnly the workspace links will be deleted. Link targets will remain unchanged.\n\nNote that all subelements of linked packages and package fragment roots will be removed from the workspace as well. +DeleteWizard.12=The selected element(s) do not exist anymore and cannot be deleted. + + +####################################### +# IntroduceParameter +####################################### +IntroduceParameterAction.label=Introduce &Parameter... +IntroduceParameterAction.dialog_title=Introduce Parameter + +IntroduceParameterWizard.defaultPageTitle=Introduce Parameter +IntroduceParameterInputPage.description=Enter the name for the new parameter. +IntroduceParameterInputPage.parameter_name=Parameter Name: + +####################################### +# Introduce Factory +####################################### +IntroduceFactoryAction.label=Introduce &Factory... +IntroduceFactoryAction.dialog_title=Introduce Factory +IntroduceFactoryAction.tooltipText=Introduce a factory to encapsulate object instantiation +IntroduceFactoryAction.description=Creates a factory to encapsulate calls to the selected constructor +IntroduceFactoryAction.use_factory=Introduce Factory +IntroduceFactoryAction.exception=Unknown exception occurred during attempt to Introduce Factory +IntroduceFactoryInputPage.name_factory=Factory options +IntroduceFactoryInputPage.method_name=Factory method name: +IntroduceFactoryInputPage.protectConstructorLabel=Make constructor private + +####################################### +# Generalize Type +####################################### +ChangeTypeAction.label=Generalize Type... +ChangeTypeAction.tooltipText=Generalize variable\'s declared type +ChangeTypeAction.description=Change variable\'s declared type to more general type consistent with usage +ChangeTypeAction.exception=An internal error occurred while attempting to Generalize Type. + +ChangeTypeWizard.title=Generalize Type +ChangeTypeWizard.declCannotBeChanged=Type of selected declaration cannot be changed +ChangeTypeWizard.pleaseChooseType= &Choose new type (types shown in gray cannot be selected): +ChangeTypeWizard.analyzing=Analyzing... +ChangeTypeWizard.internalError=Internal error during computation of valid types +ChangeTypeWizard.computationInterrupted=Computation of valid types was interrupted +ChangeTypeWizard.grayed_types= Type ''{0}'' cannot be used as a replacement for type ''{1}'' +ChangeTypeWizard.with_itself= Cannot replace type ''{0}'' with itself +ChangeTypeInputPage.Select_Type=Press "Compute" to determine allowable supertypes diff --git a/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/ui/refactoring/RenameAction.java b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/ui/refactoring/RenameAction.java new file mode 100644 index 00000000000..8333cc542ae --- /dev/null +++ b/core/org.eclipse.cdt.ui/refactor/org/eclipse/cdt/ui/refactoring/RenameAction.java @@ -0,0 +1,84 @@ +/********************************************************************** + * Copyright (c) 2004 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation +***********************************************************************/ + +package org.eclipse.cdt.ui.refactoring; + +import org.eclipse.cdt.core.model.ICElement; +import org.eclipse.cdt.internal.ui.refactoring.RenameRefactoringAction; +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.ui.IViewActionDelegate; +import org.eclipse.ui.IViewPart; + +/** + * TODO: Provide description for "RefactoringRenameAction". + */ +public class RenameAction extends Action implements IViewActionDelegate { + private IViewPart fView; + private IAction fAction; + + protected IViewPart getView() { + return fView; + } + + protected void setView(IViewPart view) { + fView = view; + } + protected IAction getAction() { + return fAction; + } + + protected void setAction(IAction action) { + fAction = action; + } + /** + * TODO: Implement the "RefactoringRenameAction" constructor. + */ + public RenameAction() { + } + /* (non-Javadoc) + * @see org.eclipse.ui.IViewActionDelegate#init(org.eclipse.ui.IViewPart) + */ + public void init(IViewPart view) { + setView(view); + + } + + /* (non-Javadoc) + * @see org.eclipse.ui.IActionDelegate#run(org.eclipse.jface.action.IAction) + */ + public void run(IAction action) { + RenameRefactoringAction refactoringAction = new RenameRefactoringAction(getView().getSite()); + refactoringAction.run(getSelection()); + } + + /* (non-Javadoc) + * @see org.eclipse.ui.IActionDelegate#selectionChanged(org.eclipse.jface.action.IAction, org.eclipse.jface.viewers.ISelection) + */ + public void selectionChanged(IAction action, ISelection selection) { + setAction(action); + if (!(selection instanceof IStructuredSelection)) { + return; + } + IStructuredSelection sel= (IStructuredSelection)selection; + Object o= sel.getFirstElement(); + if (!(o instanceof ICElement)) { + return; + } + } + + private IStructuredSelection getSelection() { + return (IStructuredSelection)getView().getViewSite().getSelectionProvider().getSelection(); + } + +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/corext/Assert.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/corext/Assert.java new file mode 100644 index 00000000000..fa66f67bd79 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/corext/Assert.java @@ -0,0 +1,140 @@ +/********************************************************************** + * Copyright (c) 2004 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.internal.corext; + +import org.eclipse.cdt.internal.corext.refactoring.RefactoringCoreMessages; + +/** + * Assert is useful for for embedding runtime sanity checks + * in code. The static predicate methods all test a condition and throw some + * type of unchecked exception if the condition does not hold. + *

+ * Assertion failure exceptions, like most runtime exceptions, are + * thrown when something is misbehaving. Assertion failures are invariably + * unspecified behavior; consequently, clients should never rely on + * these being thrown (or not thrown). If you find yourself in the + * position where you need to catch an assertion failure, you have most + * certainly written your program incorrectly. + *

+ *

+ * Note that an assert statement is slated to be added to the + * Java language in JDK 1.4, rending this class obsolete. + *

+ */ +public final class Assert { + + /** + * AssertionFailedException is a runtime exception thrown + * by some of the methods in Assert. + *

+ * This class is not declared public to prevent some misuses; programs that catch + * or otherwise depend on assertion failures are susceptible to unexpected + * breakage when assertions in the code are added or removed. + *

+ */ + private static class AssertionFailedException extends RuntimeException { + + /** + * Constructs a new exception. + */ + public AssertionFailedException() { + } + + /** + * Constructs a new exception with the given message. + */ + public AssertionFailedException(String detail) { + super(detail); + } + } + + /* This class is not intended to be instantiated. */ + private Assert() { + } + + /** + * Asserts that the given object is not null. If this + * is not the case, some kind of unchecked exception is thrown. + *

+ * As a general rule, parameters passed to API methods must not be + * null unless explicitly allowed in the method's + * specification. Similarly, results returned from API methods are never + * null unless explicitly allowed in the method's + * specification. Implementations are encouraged to make regular use of + * Assert.isNotNull to ensure that null + * parameters are detected as early as possible. + *

+ * + * @param object the value to test + */ + public static void isNotNull(Object object) { + // succeed as quickly as possible + if (object != null) { + return; + } + isNotNull(object, ""); //$NON-NLS-1$ + } + + /** + * Asserts that the given object is not null. If this + * is not the case, some kind of unchecked exception is thrown. + * The given message is included in that exception, to aid debugging. + *

+ * As a general rule, parameters passed to API methods must not be + * null unless explicitly allowed in the method's + * specification. Similarly, results returned from API methods are never + * null unless explicitly allowed in the method's + * specification. Implementations are encouraged to make regular use of + * Assert.isNotNull to ensure that null + * parameters are detected as early as possible. + *

+ * + * @param object the value to test + * @param message the message to include in the exception + */ + public static void isNotNull(Object object, String message) { + if (object == null) + throw new AssertionFailedException(RefactoringCoreMessages.getString("Assert.null_argument") + message); //$NON-NLS-1$ + } + + /** + * Asserts that the given boolean is true. If this + * is not the case, some kind of unchecked exception is thrown. + * + * @param expression the outcome of the check + * @return true if the check passes (does not return + * if the check fails) + */ + public static boolean isTrue(boolean expression) { + // succeed as quickly as possible + if (expression) { + return true; + } + return isTrue(expression, ""); //$NON-NLS-1$ + } + + /** + * Asserts that the given boolean is true. If this + * is not the case, some kind of unchecked exception is thrown. + * The given message is included in that exception, to aid debugging. + * + * @param expression the outcome of the check + * @param message the message to include in the exception + * @return true if the check passes (does not return + * if the check fails) + */ + public static boolean isTrue(boolean expression, String message) { + if (!expression) + throw new AssertionFailedException(RefactoringCoreMessages.getString("Assert.assertion_failed") + message); //$NON-NLS-1$ + return expression; + } + +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/corext/CorextMessages.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/corext/CorextMessages.java new file mode 100644 index 00000000000..77e0c54bb9d --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/corext/CorextMessages.java @@ -0,0 +1,42 @@ +/********************************************************************** + * Copyright (c) 2004 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.internal.corext; + +import java.text.MessageFormat; +import java.util.MissingResourceException; +import java.util.ResourceBundle; + +public class CorextMessages { + + private static final String BUNDLE_NAME= CorextMessages.class.getName(); + + private static final ResourceBundle RESOURCE_BUNDLE = + ResourceBundle.getBundle(BUNDLE_NAME); + + private CorextMessages() { + } + + public static String getString(String key) { + try { + return RESOURCE_BUNDLE.getString(key); + } catch (MissingResourceException e) { + return '!' + key + '!'; + } + } + + public static String getFormattedString(String key, Object arg) { + return getFormattedString(key, new Object[] { arg }); + } + + public static String getFormattedString(String key, Object[] args) { + return MessageFormat.format(getString(key), args); + } +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/corext/CorextMessages.properties b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/corext/CorextMessages.properties new file mode 100644 index 00000000000..ef7c0ba7cc9 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/corext/CorextMessages.properties @@ -0,0 +1,17 @@ +############################################################################### +# Copyright (c) 2000, 2003 IBM Corporation and others. +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Common Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/cpl-v10.html +# +# Contributors: +# IBM Corporation - initial API and implementation +############################################################################### +Assertnull_argument=null argument +Assertassertion_failed=assertion failed + +Resources.outOfSyncResources= Some resources are out of sync +Resources.outOfSync= Resource ''{0}'' is out of sync with file system. +Resources.modifiedResources= There are modified resources +Resources.fileModified= File ''{0}'' has been modified since the beginning of the operation diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/corext/textmanipulation/GroupDescription.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/corext/textmanipulation/GroupDescription.java new file mode 100644 index 00000000000..141bf5b0fc4 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/corext/textmanipulation/GroupDescription.java @@ -0,0 +1,75 @@ +/********************************************************************** + * Copyright (c) 2004 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.internal.corext.textmanipulation; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.eclipse.jface.text.IRegion; + +import org.eclipse.text.edits.TextEdit; +import org.eclipse.cdt.internal.corext.Assert; + +public class GroupDescription { + + private String fDescription; + private List fEdits; + + public GroupDescription() { + this( "NO_DESCRIPTION"); //$NON-NLS-1$ + } + + public GroupDescription(String description) { + super(); + Assert.isNotNull(description); + fDescription= description; + fEdits= new ArrayList(3); + } + + public GroupDescription(String description, TextEdit[] edits) { + super(); + Assert.isNotNull(description); + Assert.isNotNull(edits); + fDescription= description; + fEdits= new ArrayList(Arrays.asList(edits)); + } + + public void addTextEdit(TextEdit edit) { + fEdits.add(edit); + } + + public boolean hasTextEdits() { + return fEdits.isEmpty(); + } + + public TextEdit[] getTextEdits() { + return (TextEdit[]) fEdits.toArray(new TextEdit[fEdits.size()]); + } + + /** + * Returns the text range covered by the edits managed via this + * group description. The method requires that the group description + * manages at least one text edit. + */ + public IRegion getTextRange() { + int size= fEdits.size(); + if (size == 1) { + return ((TextEdit)fEdits.get(0)).getRegion(); + } else { + return TextEdit.getCoverage((TextEdit[])fEdits.toArray(new TextEdit[fEdits.size()])); + } + } + + public String getName() { + return fDescription; + } +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/corext/util/CModelUtil.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/corext/util/CModelUtil.java new file mode 100644 index 00000000000..ba757258f08 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/corext/util/CModelUtil.java @@ -0,0 +1,38 @@ +/********************************************************************** + * Copyright (c) 2004 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.internal.corext.util; + +import org.eclipse.cdt.core.model.ITranslationUnit; +import org.eclipse.cdt.core.model.IWorkingCopy; +import org.eclipse.cdt.internal.ui.util.EditorUtility; + +public class CModelUtil { + /** + * Returns the working copy CU of the given CU. If the CU is already a + * working copy or the CU has no working copy the input CU is returned. + */ + public static ITranslationUnit toWorkingCopy(ITranslationUnit unit) { + if (!unit.isWorkingCopy()) { + ITranslationUnit workingCopy= EditorUtility.getWorkingCopy(unit); + if (workingCopy != null) { + return workingCopy; + } + } + return unit; + } + + public static ITranslationUnit toOriginal(ITranslationUnit unit){ + if (unit.isWorkingCopy()) { + return (((IWorkingCopy)unit).getOriginalElement()); + } + return unit; + } +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/CPluginImages.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/CPluginImages.java index f92ab29a801..942b38adab8 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/CPluginImages.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/CPluginImages.java @@ -75,6 +75,7 @@ public class CPluginImages { public static final String IMG_OBJS_CONTAINER= NAME_PREFIX + "container_obj.gif"; //$NON-NLS-1$ public static final String IMG_OBJS_LIBRARY= NAME_PREFIX + "lib_obj.gif"; //$NON-NLS-1$ + // Breakpoint images public static final String IMG_OBJS_BREAKPOINT = NAME_PREFIX + "breakpoint.gif"; //$NON-NLS-1$ public static final String IMG_OBJS_BREAKPOINT_DISABLED = NAME_PREFIX + "breakpoint_disabled.gif"; //$NON-NLS-1$ @@ -164,6 +165,21 @@ public class CPluginImages { public static final ImageDescriptor DESC_OBJS_SEARCH_REF = createManaged(T_OBJ, IMG_OBJS_SEARCH_REF); public static final ImageDescriptor DESC_OBJS_CSEARCH = createManaged(T_OBJ, IMG_OBJS_CSEARCH); + // refactoring + public static final String IMG_OBJS_REFACTORING_FATAL= NAME_PREFIX + "fatalerror_obj.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_REFACTORING_ERROR= NAME_PREFIX + "error_obj.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_REFACTORING_WARNING= NAME_PREFIX + "warning_obj.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_REFACTORING_INFO= NAME_PREFIX + "info_obj.gif"; //$NON-NLS-1$ + public static final ImageDescriptor DESC_WIZBAN_REFACTOR_FIELD= create(T_WIZBAN, "fieldrefact_wiz.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_WIZBAN_REFACTOR_METHOD= create(T_WIZBAN, "methrefact_wiz.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_WIZBAN_REFACTOR_TYPE= create(T_WIZBAN, "typerefact_wiz.gif"); //$NON-NLS-1$ + + public static final ImageDescriptor DESC_OBJS_DEFAULT_CHANGE= create(T_OBJ, "change.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_OBJS_COMPOSITE_CHANGE= create(T_OBJ, "composite_change.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_OBJS_CU_CHANGE= create(T_OBJ, "cu_change.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_OBJS_FILE_CHANGE= create(T_OBJ, "file_change.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_OBJS_TEXT_EDIT= create(T_OBJ, "text_edit.gif"); //$NON-NLS-1$ + public static void initialize() { //createManaged(registry, T_OBJ, IMG_OBJS_TUNIT); //createManaged(registry, T_OBJ, IMG_OBJS_FIELD); diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/ICHelpContextIds.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/ICHelpContextIds.java index 72f852aba58..968648bd6a5 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/ICHelpContextIds.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/ICHelpContextIds.java @@ -23,10 +23,15 @@ public interface ICHelpContextIds { public static final String OPEN_CLASS_WIZARD_ACTION = PREFIX + "open_class_wizard_action"; //$NON-NLS-1$ // Actions - public static final String FILTER_PUBLIC_ACTION = PREFIX + "filter_public_action"; //$NON-NLS-1$ - public static final String FILTER_FIELDS_ACTION = PREFIX + "filter_fields_action"; //$NON-NLS-1$ - public static final String FILTER_STATIC_ACTION = PREFIX + "filter_static_action"; //$NON-NLS-1$ + public static final String FILTER_PUBLIC_ACTION= PREFIX + "filter_public_action"; //$NON-NLS-1$ + public static final String FILTER_FIELDS_ACTION= PREFIX + "filter_fields_action"; //$NON-NLS-1$ + public static final String FILTER_STATIC_ACTION= PREFIX + "filter_static_action"; //$NON-NLS-1$ + public static final String NEXT_CHANGE_ACTION= PREFIX + "next_change_action"; //$NON-NLS-1$ + public static final String PREVIOUS_CHANGE_ACTION=PREFIX + "previous_change_action"; //$NON-NLS-1$ + public static final String NEXT_PROBLEM_ACTION= PREFIX + "next_problem_action"; //$NON-NLS-1$ + public static final String PREVIOUS_PROBLEM_ACTION= PREFIX + "previous_problem_action"; //$NON-NLS-1$ + // Preference/property pages public static final String C_PREF_PAGE = PREFIX + "new_c_pref_page_context"; //$NON-NLS-1$ public static final String C_EDITOR_PREF_PAGE = PREFIX + "new_c_editor_pref_page_context"; //$NON-NLS-1$ @@ -64,4 +69,14 @@ public interface ICHelpContextIds { public static final String MOVE_ACTION = PREFIX + "move_action_context"; //$NON-NLS-1$ public static final String RENAME_ACTION = PREFIX + "rename_action_context"; //$NON-NLS-1$ + + public static final String REFACTORING_PREFERENCE_PAGE= PREFIX + "refactoring_preference_page_context"; //$NON-NLS-1$ + public static final String REFACTORING_ERROR_WIZARD_PAGE= PREFIX + "refactoring_error_wizard_page_context"; //$NON-NLS-1$ + public static final String REFACTORING_PREVIEW_WIZARD_PAGE= PREFIX + "refactoring_preview_wizard_page_context"; //$NON-NLS-1$ + public static final String RENAME_PARAMS_WIZARD_PAGE= PREFIX + "rename_params_wizard_page"; //$NON-NLS-1$ + public static final String RENAME_METHOD_WIZARD_PAGE= PREFIX + "rename_method_wizard_page_context"; //$NON-NLS-1$ + public static final String RENAME_TYPE_WIZARD_PAGE= PREFIX + "rename_type_wizard_page_context"; //$NON-NLS-1$ + public static final String RENAME_FIELD_WIZARD_PAGE= PREFIX + "rename_field_wizard_page_context"; //$NON-NLS-1$ + public static final String RENAME_RESOURCE_WIZARD_PAGE= PREFIX + "rename_resource_wizard_page_context"; //$NON-NLS-1$ + } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/ICStatusConstants.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/ICStatusConstants.java new file mode 100644 index 00000000000..07302a6d9d2 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/ICStatusConstants.java @@ -0,0 +1,49 @@ +/********************************************************************** + * Copyright (c) 2004 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.internal.ui; + +/** + * Defines status codes relevant to the Java UI plug-in. When a + * Core exception is thrown, it contain a status object describing + * the cause of the exception. The status objects originating from the + * Java UI plug-in use the codes defined in this interface. + */ +public interface ICStatusConstants { + + // C UI status constants start at 10000 to make sure that we don't + // collide with resource and java model constants. + + public static final int INTERNAL_ERROR= 10001; + + /** + * Status constant indicating that an exception occurred on + * storing or loading templates. + */ + public static final int TEMPLATE_IO_EXCEPTION = 10002; + + /** + * Status constant indicating that an validateEdit call has changed the + * content of a file on disk. + */ + public static final int VALIDATE_EDIT_CHANGED_CONTENT= 10003; + + /** + * Status constant indicating that a ChangeAbortException has been + * caught. + */ + public static final int CHANGE_ABORTED= 10004; + + /** + * Status constant indicating that an exception occurred while + * parsing template file. + */ + public static final int TEMPLATE_PARSE_EXCEPTION = 10005; + } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/IReconcilingParticipant.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/IReconcilingParticipant.java index 46be9cc94bb..d846d433f8e 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/IReconcilingParticipant.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/IReconcilingParticipant.java @@ -1,13 +1,13 @@ -/******************************************************************************* - * Copyright (c) 2000, 2003 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 +/********************************************************************** + * Copyright (c) 2004 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html + * http://www.eclipse.org/legal/cpl-v05.html * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ + * Contributors: + * IBM Rational Software - Initial API and implementation +***********************************************************************/ package org.eclipse.cdt.internal.ui.editor; diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/util/BusyIndicatorRunnableContext.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/util/BusyIndicatorRunnableContext.java new file mode 100644 index 00000000000..3bdd68b1e22 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/util/BusyIndicatorRunnableContext.java @@ -0,0 +1,134 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.ui.util; + +import java.lang.reflect.InvocationTargetException; + +import org.eclipse.swt.custom.BusyIndicator; + +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.core.runtime.OperationCanceledException; + +import org.eclipse.jface.operation.IRunnableContext; +import org.eclipse.jface.operation.IRunnableWithProgress; +import org.eclipse.jface.operation.ModalContext; + +/** + * A runnable context that shows the busy cursor instead of a progress + * monitor. Note, that the UI thread is blocked even if the runnable + * is executed in a separate thread by passing fork= true + * to the context's run method. Furthermore this context doesn't provide + * any UI to cancel the operation. + */ +public class BusyIndicatorRunnableContext implements IRunnableContext { + + private static class BusyRunnable implements Runnable { + + private static class ThreadContext extends Thread { + IRunnableWithProgress fRunnable; + Throwable fThrowable; + + public ThreadContext(IRunnableWithProgress runnable) { + this(runnable, "BusyCursorRunnableContext-Thread"); //$NON-NLS-1$ + } + protected ThreadContext(IRunnableWithProgress runnable, String name) { + super(name); + fRunnable= runnable; + } + public void run() { + try { + fRunnable.run(new NullProgressMonitor()); + } catch (InvocationTargetException e) { + fThrowable= e; + } catch (InterruptedException e) { + fThrowable= e; + } catch (ThreadDeath e) { + fThrowable= e; + throw e; + } catch (RuntimeException e) { + fThrowable= e; + } catch (Error e) { + fThrowable= e; + } + } + void sync() { + try { + join(); + } catch (InterruptedException e) { + // ok to ignore exception + } + } + } + + public Throwable fThrowable; + private boolean fFork; + private IRunnableWithProgress fRunnable; + public BusyRunnable(boolean fork, IRunnableWithProgress runnable) { + fFork= fork; + fRunnable= runnable; + } + public void run() { + try { + internalRun(fFork, fRunnable); + } catch (InvocationTargetException e) { + fThrowable= e; + } catch (InterruptedException e) { + fThrowable= e; + } + } + private void internalRun(boolean fork, final IRunnableWithProgress runnable) throws InvocationTargetException, InterruptedException { + Thread thread= Thread.currentThread(); + // Do not spawn another thread if we are already in a modal context + // thread or inside a busy context thread. + if (thread instanceof ThreadContext || ModalContext.isModalContextThread(thread)) + fork= false; + + if (fork) { + final ThreadContext t= new ThreadContext(runnable); + t.start(); + t.sync(); + // Check if the separate thread was terminated by an exception + Throwable throwable= t.fThrowable; + if (throwable != null) { + if (throwable instanceof InvocationTargetException) { + throw (InvocationTargetException) throwable; + } else if (throwable instanceof InterruptedException) { + throw (InterruptedException) throwable; + } else if (throwable instanceof OperationCanceledException) { + throw new InterruptedException(); + } else { + throw new InvocationTargetException(throwable); + } + } + } else { + try { + runnable.run(new NullProgressMonitor()); + } catch (OperationCanceledException e) { + throw new InterruptedException(); + } + } + } + } + + /* (non-Javadoc) + * Method declared on IRunnableContext. + */ + public void run(boolean fork, boolean cancelable, IRunnableWithProgress runnable) throws InvocationTargetException, InterruptedException { + BusyRunnable busyRunnable= new BusyRunnable(fork, runnable); + BusyIndicator.showWhile(null, busyRunnable); + Throwable throwable= busyRunnable.fThrowable; + if (throwable instanceof InvocationTargetException) { + throw (InvocationTargetException)throwable; + } else if (throwable instanceof InterruptedException) { + throw (InterruptedException)throwable; + } + } +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/util/Resources.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/util/Resources.java new file mode 100644 index 00000000000..0fb62be244a --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/util/Resources.java @@ -0,0 +1,187 @@ +/********************************************************************** + * Copyright (c) 2004 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.internal.ui.util; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.eclipse.cdt.internal.corext.CorextMessages; +import org.eclipse.cdt.internal.ui.CUIStatus; +import org.eclipse.cdt.internal.ui.ICStatusConstants; +import org.eclipse.cdt.ui.CUIPlugin; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IResourceStatus; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.MultiStatus; +import org.eclipse.core.runtime.Status; + +public class Resources { + + private Resources() { + } + + /** + * Checks if the given resource is in sync with the underlying file system. + * + * @param resource the resource to be checked + * @return IStatus status describing the check's result. If status. + * isOK() returns true then the resource is in sync + */ + public static IStatus checkInSync(IResource resource) { + return checkInSync(new IResource[] {resource}); + } + + /** + * Checks if the given resources are in sync with the underlying file + * system. + * + * @param resources the resources to be checked + * @return IStatus status describing the check's result. If status. + * isOK() returns true then the resources are in sync + */ + public static IStatus checkInSync(IResource[] resources) { + IStatus result= null; + for (int i= 0; i < resources.length; i++) { + IResource resource= resources[i]; + if (!resource.isSynchronized(IResource.DEPTH_INFINITE)) { + result= addOutOfSync(result, resource); + } + } + if (result != null) + return result; + return new Status(IStatus.OK, CUIPlugin.getPluginId(), IStatus.OK, "", null); //$NON-NLS-1$ + } + + /** + * Makes the given resource committable. Committable means that it is + * writeable and that its content hasn't changed by calling + * validateEdit for the given resource on IWorkspace. + * + * @param resource the resource to be checked + * @param context the context passed to validateEdit + * @return status describing the method's result. If status.isOK() returns true then the resources are committable. + * + * @see org.eclipse.core.resources.IWorkspace#validateEdit(org.eclipse.core.resources.IFile[], java.lang.Object) + */ + public static IStatus makeCommittable(IResource resource, Object context) { + return makeCommittable(new IResource[] { resource }, context); + } + + /** + * Makes the given resources committable. Committable means that all + * resources are writeable and that the content of the resources hasn't + * changed by calling validateEdit for a given file on + * IWorkspace. + * + * @param resources the resources to be checked + * @param context the context passed to validateEdit + * @return IStatus status describing the method's result. If status. + * isOK() returns true then the add resources are + * committable + * + * @see org.eclipse.core.resources.IWorkspace#validateEdit(org.eclipse.core.resources.IFile[], java.lang.Object) + */ + public static IStatus makeCommittable(IResource[] resources, Object context) { + List readOnlyFiles= new ArrayList(); + for (int i= 0; i < resources.length; i++) { + IResource resource= resources[i]; + if (resource.getType() == IResource.FILE && resource.isReadOnly()) + readOnlyFiles.add(resource); + } + if (readOnlyFiles.size() == 0) + return new Status(IStatus.OK, CUIPlugin.getPluginId(), IStatus.OK, "", null); //$NON-NLS-1$ + + Map oldTimeStamps= createModificationStampMap(readOnlyFiles); + IStatus status= ResourcesPlugin.getWorkspace().validateEdit( + (IFile[]) readOnlyFiles.toArray(new IFile[readOnlyFiles.size()]), context); + if (!status.isOK()) + return status; + + IStatus modified= null; + Map newTimeStamps= createModificationStampMap(readOnlyFiles); + for (Iterator iter= oldTimeStamps.keySet().iterator(); iter.hasNext();) { + IFile file= (IFile) iter.next(); + if (!oldTimeStamps.get(file).equals(newTimeStamps.get(file))) + modified= addModified(modified, file); + } + if (modified != null) + return modified; + return new Status(IStatus.OK, CUIPlugin.getPluginId(), IStatus.OK, "", null); //$NON-NLS-1$ + } + + private static Map createModificationStampMap(List files){ + Map map= new HashMap(); + for (Iterator iter= files.iterator(); iter.hasNext(); ) { + IFile file= (IFile)iter.next(); + map.put(file, new Long(file.getModificationStamp())); + } + return map; + } + + private static IStatus addModified(IStatus status, IFile file) { + IStatus entry= CUIStatus.createError( + ICStatusConstants.VALIDATE_EDIT_CHANGED_CONTENT, + CorextMessages.getFormattedString("Resources.fileModified", file.getFullPath().toString()), //$NON-NLS-1$ + null); + if (status == null) { + return entry; + } else if (status.isMultiStatus()) { + ((MultiStatus)status).add(entry); + return status; + } else { + MultiStatus result= new MultiStatus(CUIPlugin.getPluginId(), + ICStatusConstants.VALIDATE_EDIT_CHANGED_CONTENT, + CorextMessages.getString("Resources.modifiedResources"), null); //$NON-NLS-1$ + result.add(status); + result.add(entry); + return result; + } + } + + private static IStatus addOutOfSync(IStatus status, IResource resource) { + IStatus entry= new Status( + IStatus.ERROR, + ResourcesPlugin.getPlugin().getDescriptor().getUniqueIdentifier(), + IResourceStatus.OUT_OF_SYNC_LOCAL, + CorextMessages.getFormattedString("Resources.outOfSync", resource.getFullPath().toString()), //$NON-NLS-1$ + null); + if (status == null) { + return entry; + } else if (status.isMultiStatus()) { + ((MultiStatus)status).add(entry); + return status; + } else { + MultiStatus result= new MultiStatus( + ResourcesPlugin.getPlugin().getDescriptor().getUniqueIdentifier(), + IResourceStatus.OUT_OF_SYNC_LOCAL, + CorextMessages.getString("Resources.outOfSyncResources"), null); //$NON-NLS-1$ + result.add(status); + result.add(entry); + return result; + } + } + + public static String[] getLocationOSStrings(IResource[] resources) { + List result= new ArrayList(resources.length); + for (int i= 0; i < resources.length; i++) { + IPath location= resources[i].getLocation(); + if (location != null) + result.add(location.toOSString()); + } + return (String[]) result.toArray(new String[result.size()]); + } +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/util/RowLayouter.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/util/RowLayouter.java new file mode 100644 index 00000000000..522c347b061 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/util/RowLayouter.java @@ -0,0 +1,184 @@ +/********************************************************************** + * Copyright (c) 2004 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.internal.ui.util; + +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Control; + +import org.eclipse.jface.util.Assert; + +/** + * Helper class to layout a number of children if the composite uses a GridLayout. + * If the numbers of widgets to be layouted into one row is smaller than the number of columns + * defined for the grid layout the helper class assigns a corresponing value to the + * GridData.horizontalSpan field. + * + * Additionally a row layouter manages a default GridData object for each column. + * If set this grid data is used for the widget if it doesn't manage its own grid data object. + * + * Call one of the perform methods to assign the correct grid data objects to + * a set of widgets according to the number of columns passed to the layouter's constructor. + */ +public class RowLayouter { + + public int spanHorizontalAlignment= -1; + public int spanGrabExcessHorizontalSpace= -1; + public int spanHorizontalSpan= -1; + public int spanHorizontalIndent= -1; + public int spanWidthHint= -1; + + public int spanVerticalAlignment= -1; + public int spanGrabExcessVerticalSpace= -1; + public int spanVerticalSpan= -1; + public int spanHeightHint= -1; + + private int fNumColumns; + private boolean fOrder; + private Control fLastControl; + private GridData[] fDefaultGridDatas= new GridData[4]; + + public RowLayouter(int numColumns) { + this(numColumns, false); + } + + public RowLayouter(int numColumns, boolean order) { + fNumColumns= numColumns; + fOrder= order; + } + + public void setDefaultSpan() { + spanHorizontalAlignment= GridData.FILL; + spanGrabExcessHorizontalSpace= 1; + } + + public void perform(Control c1) { + perform(new Control[] {c1}, 0); + } + + public void perform(Control c1, Control c2, int span) { + perform(new Control[] {c1, c2}, span); + } + + public void perform(Control c1, Control c2, Control c3, int span) { + perform(new Control[] {c1, c2, c3}, span); + } + + public void perform(Control[] controls, int spanColumn) { + int numColumns= numColumns(); + Assert.isTrue(controls.length <= numColumns); + order(controls); + int gridIndex= 0; + for (int i= 0; i < controls.length; i++) { + Control control= controls[i]; + GridData gd= (GridData)control.getLayoutData(); + if (gd == null) + gd= getGridData(gridIndex); + + if (i == spanColumn) { + int span= numColumns - (controls.length - 1); + gridIndex+= span; + if (gd == null) + gd= new GridData(); + applyDelta(gd); + gd.horizontalSpan= span; + } else { + gridIndex++; + } + control.setLayoutData(gd); + } + } + + private void applyDelta(GridData gd) { + if (spanHorizontalAlignment != -1) + gd.horizontalAlignment= spanHorizontalAlignment; + + if (spanGrabExcessHorizontalSpace != -1) { + if (spanGrabExcessHorizontalSpace == 0) + gd.grabExcessHorizontalSpace= false; + else + gd.grabExcessHorizontalSpace= true; + } + + + if (spanHorizontalSpan != -1) + gd.horizontalSpan= spanHorizontalSpan; + + if (spanHorizontalIndent != -1) + gd.horizontalIndent= spanHorizontalIndent; + + if (spanWidthHint != -1) + gd.widthHint= spanWidthHint; + + if (spanVerticalAlignment != -1) + gd.verticalAlignment= spanVerticalAlignment; + + if (spanGrabExcessVerticalSpace != -1) { + if (spanGrabExcessVerticalSpace == 0) + gd.grabExcessVerticalSpace= false; + else + gd.grabExcessVerticalSpace= true; + } + + if (spanVerticalSpan != -1) + gd.verticalSpan= spanVerticalSpan; + + if (spanHeightHint != -1) + gd.heightHint= spanHeightHint; + } + public void setDefaultGridData(GridData gd, int index) { + if (index >= fDefaultGridDatas.length) { + GridData[] newDatas= new GridData[index + 4]; + System.arraycopy(fDefaultGridDatas, 0, newDatas, 0, fDefaultGridDatas.length); + fDefaultGridDatas= newDatas; + } + fDefaultGridDatas[index]= gd; + } + + public GridData getGridData(int index) { + if (index > fDefaultGridDatas.length) + return null; + + return cloneGridData(fDefaultGridDatas[index]); + } + + public int numColumns() { + return fNumColumns; + } + + protected void order(Control[] controls) { + if (!fOrder) + return; + + for (int i= 0; i < controls.length; i++) { + Control control= controls[i]; + control.moveBelow(fLastControl); + fLastControl= control; + } + } + + protected GridData cloneGridData(GridData gd) { + if (gd == null) + return null; + + GridData result= new GridData(); + result.horizontalAlignment= gd.horizontalAlignment; + result.grabExcessHorizontalSpace= gd.grabExcessHorizontalSpace; + result.horizontalSpan= gd.horizontalSpan; + result.horizontalIndent= gd.horizontalIndent; + result.widthHint= gd.widthHint; + + result.verticalAlignment= gd.verticalAlignment; + result.grabExcessVerticalSpace= gd.grabExcessVerticalSpace; + result.verticalSpan= gd.verticalSpan; + result.heightHint= gd.heightHint; + return result; + } +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/util/ViewerPane.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/util/ViewerPane.java new file mode 100644 index 00000000000..2bafdf20814 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/util/ViewerPane.java @@ -0,0 +1,74 @@ +/********************************************************************** + * Copyright (c) 2004 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.internal.ui.util; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.CLabel; +import org.eclipse.swt.custom.ViewForm; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.ToolBar; + +import org.eclipse.jface.action.ToolBarManager; + +/** + * A ViewerPane is a convenience class which installs a + * CLabel and a Toolbar in a ViewForm. + *

+ */ +public class ViewerPane extends ViewForm { + + private ToolBarManager fToolBarManager; + + public ViewerPane(Composite parent, int style) { + super(parent, style); + + marginWidth= 0; + marginHeight= 0; + + CLabel label= new CLabel(this, SWT.NONE); + setTopLeft(label); + + ToolBar tb= new ToolBar(this, SWT.FLAT); + setTopCenter(tb); + fToolBarManager= new ToolBarManager(tb); + } + + /** + * Sets the receiver's title text. + */ + public void setText(String label) { + CLabel cl= (CLabel) getTopLeft(); + cl.setText(label); + } + + public String getText() { + CLabel cl= (CLabel) getTopLeft(); + return cl.getText(); + } + + /** + * Sets the receiver's title image. + */ + public void setImage(Image image) { + CLabel cl= (CLabel) getTopLeft(); + cl.setImage(image); + } + + public Image getImage() { + CLabel cl= (CLabel) getTopLeft(); + return cl.getImage(); + } + + public ToolBarManager getToolBarManager() { + return fToolBarManager; + } +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/PreferenceConstants.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/PreferenceConstants.java index e826827a712..56ef7215a92 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/PreferenceConstants.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/PreferenceConstants.java @@ -122,6 +122,14 @@ public class PreferenceConstants { */ public final static String EDITOR_TASK_INDICATION_IN_OVERVIEW_RULER= "taskIndicationInOverviewRuler"; //$NON-NLS-1$ + public static final String REFACTOR_ERROR_PAGE_SEVERITY_THRESHOLD= "Refactoring.ErrorPage.severityThreshold"; //$NON-NLS-1$ + public static final String REFACTOR_FATAL_SEVERITY= "4"; //$NON-NLS-1$ + public static final String REFACTOR_ERROR_SEVERITY= "3"; //$NON-NLS-1$ + public static final String REFACTOR_WARNING_SEVERITY= "2"; //$NON-NLS-1$ + public static final String REFACTOR_INFO_SEVERITY= "1"; //$NON-NLS-1$ + public static final String REFACTOR_OK_SEVERITY= "0"; //$NON-NLS-1$ + public static final String REFACTOR_SAVE_ALL_EDITORS= "Refactoring.savealleditors"; //$NON-NLS-1$ + /** * Returns the JDT-UI preference store. * diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/actions/RenameAction.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/actions/RenameAction.java new file mode 100644 index 00000000000..774d33879c2 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/actions/RenameAction.java @@ -0,0 +1,77 @@ +/********************************************************************** + * Copyright (c) 2004 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.ui.actions; + +import org.eclipse.cdt.internal.ui.ICHelpContextIds; +import org.eclipse.cdt.internal.ui.refactoring.RefactoringMessages; +import org.eclipse.cdt.internal.ui.refactoring.RenameRefactoringAction; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.ui.IWorkbenchSite; +import org.eclipse.ui.help.WorkbenchHelp; + + +/** + * Renames a C element or workbench resource. + *

+ * Action is applicable to selections containing elements of type + * ICElement. + * + *

+ * This class may be instantiated; it is not intended to be subclassed. + *

+ * + * @since 2.0 + */ +public class RenameAction extends SelectionDispatchAction { + + private RenameRefactoringAction fRenameCElement; + /** + * Creates a new RenameAction. The action requires + * that the selection provided by the site's selection provider is of type + * org.eclipse.jface.viewers.IStructuredSelection. + * + * @param site the site providing context information for this action + */ + public RenameAction(IWorkbenchSite site) { + super(site); + setText(RefactoringMessages.getString("RenameAction.text")); //$NON-NLS-1$ + fRenameCElement= new RenameRefactoringAction(site); + fRenameCElement.setText(getText()); + WorkbenchHelp.setHelp(this, ICHelpContextIds.RENAME_ACTION); + } + /* + * @see ISelectionChangedListener#selectionChanged(SelectionChangedEvent) + */ + public void selectionChanged(SelectionChangedEvent event) { + fRenameCElement.selectionChanged(event); + setEnabled(computeEnabledState()); + } + + /* + * @see SelectionDispatchAction#update(ISelection) + */ + public void update(ISelection selection) { + fRenameCElement.update(selection); + + setEnabled(computeEnabledState()); + } + + private boolean computeEnabledState(){ + return fRenameCElement.isEnabled(); + } + + public void run(IStructuredSelection selection) { + if (fRenameCElement.isEnabled()) + fRenameCElement.run(selection); + } +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/actions/SelectionDispatchAction.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/actions/SelectionDispatchAction.java new file mode 100644 index 00000000000..fdef4167998 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/actions/SelectionDispatchAction.java @@ -0,0 +1,202 @@ +/********************************************************************** + * Copyright (c) 2004 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.ui.actions; + + +import org.eclipse.swt.widgets.Shell; + +import org.eclipse.jface.action.Action; +import org.eclipse.jface.text.ITextSelection; +import org.eclipse.jface.util.Assert; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.SelectionChangedEvent; + +import org.eclipse.ui.IWorkbenchSite; + +/** + * Action that dispatches the IAction#run() and the + * ISelectionChangedListener#selectionChanged + * according to the type of the selection. + * + *
    + *
  • if selection is of type ITextSelection then + * run(ITextSelection) and selectionChanged(ITextSelection) + * is called.
  • + *
  • if selection is of type IStructuredSelection then + * run(IStructuredSelection) and + * selectionChanged(IStructuredSelection) is called.
  • + *
  • default is to call run(ISelection) and + * selectionChanged(ISelection).
  • + *
+ * + *

+ * Note: This class is not intended to be subclassed outside the JDT UI plugin. + *

+ * + * @since 2.0 + */ +public abstract class SelectionDispatchAction extends Action implements ISelectionChangedListener { + + private IWorkbenchSite fSite; + + /** + * Creates a new action with no text and no image. + *

+ * Configure the action later using the set methods. + *

+ * + * @param site the site this action is working on + */ + protected SelectionDispatchAction(IWorkbenchSite site) { + Assert.isNotNull(site); + fSite= site; + } + + /** + * Returns the site owning this action. + * + * @return the site owning this action + */ + public IWorkbenchSite getSite() { + return fSite; + } + + /** + * Returns the selection provided by the site owning this action. + * + * @return the site's selection + */ + public ISelection getSelection() { + if (getSelectionProvider() != null) + return getSelectionProvider().getSelection(); + else + return null; + } + + /** + * Returns the shell provided by the site owning this action. + * + * @return the site's shell + */ + public Shell getShell() { + return fSite.getShell(); + } + + /** + * Returns the selection provider managed by the site owning this action. + * + * @return the site's selection provider + */ + public ISelectionProvider getSelectionProvider() { + return fSite.getSelectionProvider(); + } + + /** + * Updates the action's enablement state according to the given selection. This + * default implementation calls one of the selectionChanged + * methods depending on the type of the passed selection. + * + * @param selection the selection this action is working on + */ + public void update(ISelection selection) { + dispatchSelectionChanged(selection); + } + + /** + * Notifies this action that the given structured selection has changed. This default + * implementation calls selectionChanged(ISelection selection). + * + * @param selection the new selection + */ + public void selectionChanged(IStructuredSelection selection) { + selectionChanged((ISelection)selection); + } + + /** + * Executes this actions with the given structured selection. This default implementation + * calls run(ISelection selection). + */ + public void run(IStructuredSelection selection) { + run((ISelection)selection); + } + + /** + * Notifies this action that the given text selection has changed. This default + * implementation calls selectionChanged(ISelection selection). + * + * @param selection the new selection + */ + public void selectionChanged(ITextSelection selection) { + selectionChanged((ISelection)selection); + } + + /** + * Executes this actions with the given text selection. This default implementation + * calls run(ISelection selection). + */ + public void run(ITextSelection selection) { + run((ISelection)selection); + } + + /** + * Notifies this action that the given selection has changed. This default + * implementation sets the action's enablement state to false. + * + * @param selection the new selection + */ + public void selectionChanged(ISelection selection) { + setEnabled(false); + } + + /** + * Executes this actions with the given selection. This default implementation + * does nothing. + */ + public void run(ISelection selection) { + } + + /* (non-Javadoc) + * Method declared on IAction. + */ + public void run() { + dispatchRun(getSelection()); + } + + /* (non-Javadoc) + * Method declared on ISelectionChangedListener. + */ + public void selectionChanged(SelectionChangedEvent event) { + dispatchSelectionChanged(event.getSelection()); + } + + private void dispatchSelectionChanged(ISelection selection) { + if (selection instanceof IStructuredSelection) { + selectionChanged((IStructuredSelection)selection); + } else if (selection instanceof ITextSelection) { + selectionChanged((ITextSelection)selection); + } else { + selectionChanged(selection); + } + } + + private void dispatchRun(ISelection selection) { + if (selection instanceof IStructuredSelection) { + run((IStructuredSelection)selection); + } else if (selection instanceof ITextSelection) { + run((ITextSelection)selection); + } else { + run(selection); + } + } +}