### Eclipse Workspace Patch 1.0 #P org.eclipse.ui.workbench.texteditor Index: src/org/eclipse/ui/texteditor/ITextEditorActionDefinitionIds.java =================================================================== RCS file: /home/eclipse/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/ITextEditorActionDefinitionIds.java,v retrieving revision 1.25 diff -u -r1.25 ITextEditorActionDefinitionIds.java --- src/org/eclipse/ui/texteditor/ITextEditorActionDefinitionIds.java 28 Mar 2006 16:36:53 -0000 1.25 +++ src/org/eclipse/ui/texteditor/ITextEditorActionDefinitionIds.java 17 Jun 2006 04:51:44 -0000 @@ -135,6 +135,40 @@ */ String LOWER_CASE= "org.eclipse.ui.edit.text.lowerCase"; //$NON-NLS-1$ + /** + * Action definition id of the capitalize case action. + * Value: "org.eclipse.ui.edit.text.capitalizeCase" + * @since 3.3 + */ + String CAPITALIZE_CASE= "org.eclipse.ui.edit.text.capitalizeCase"; //$NON-NLS-1$ + + /** + * Action definition id of the invert case action. + * Value: "org.eclipse.ui.edit.text.invertCase" + * @since 3.3 + */ + String INVERT_CASE= "org.eclipse.ui.edit.text.invertCase"; //$NON-NLS-1$ + + /** + * Action definition id of the upper camel case action. + * Value: "org.eclipse.ui.edit.text.upperCamelCase" + * @since 3.3 + */ + String UPPER_CAMEL_CASE= "org.eclipse.ui.edit.text.upperCamelCase"; //$NON-NLS-1$ + + /** + * Action definition id of the lower camel case action. + * Value: "org.eclipse.ui.edit.text.lowerCamelCase" + * @since 3.3 + */ + String LOWER_CAMEL_CASE= "org.eclipse.ui.edit.text.lowerCamelCase"; //$NON-NLS-1$ + + /** + * Action definition id of the constant case action. + * Value: "org.eclipse.ui.edit.text.constantCase" + * @since 3.3 + */ + String CONSTANT_CASE= "org.eclipse.ui.edit.text.constantCase"; //$NON-NLS-1$ // navigation Index: src/org/eclipse/ui/texteditor/IAbstractTextEditorHelpContextIds.java =================================================================== RCS file: /home/eclipse/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/IAbstractTextEditorHelpContextIds.java,v retrieving revision 1.22 diff -u -r1.22 IAbstractTextEditorHelpContextIds.java --- src/org/eclipse/ui/texteditor/IAbstractTextEditorHelpContextIds.java 28 Mar 2006 16:36:53 -0000 1.22 +++ src/org/eclipse/ui/texteditor/IAbstractTextEditorHelpContextIds.java 17 Jun 2006 04:51:43 -0000 @@ -306,6 +306,41 @@ /** * Help context id for the action. + * Value: "org.eclipse.ui.capitalize_case_action_context" + * @since 3.3 + */ + String CAPITALIZE_CASE_ACTION= PREFIX + "capitalize_case" + ACTION_POSTFIX; //$NON-NLS-1$ + + /** + * Help context id for the action. + * Value: "org.eclipse.ui.invert_case_action_context" + * @since 3.3 + */ + String INVERT_CASE_ACTION= PREFIX + "invert_case" + ACTION_POSTFIX; //$NON-NLS-1$ + + /** + * Help context id for the action. + * Value: "org.eclipse.ui.upper_camel_case_action_context" + * @since 3.3 + */ + String UPPER_CAMEL_CASE_ACTION= PREFIX + "upper_camel_case" + ACTION_POSTFIX; //$NON-NLS-1$ + + /** + * Help context id for the action. + * Value: "org.eclipse.ui.lower_camel_case_action_context" + * @since 3.3 + */ + String LOWER_CAMEL_CASE_ACTION= PREFIX + "lower_camel_case" + ACTION_POSTFIX; //$NON-NLS-1$ + + /** + * Help context id for the action. + * Value: "org.eclipse.ui.constant_case_action_context" + * @since 3.3 + */ + String CONSTANT_CASE_ACTION= PREFIX + "constant_case" + ACTION_POSTFIX; //$NON-NLS-1$ + + /** + * Help context id for the action. * Value: "org.eclipse.ui.smart_enter_action_context" * @since 3.0 */ Index: src/org/eclipse/ui/texteditor/AbstractTextEditor.java =================================================================== RCS file: /home/eclipse/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/AbstractTextEditor.java,v retrieving revision 1.201 diff -u -r1.201 AbstractTextEditor.java --- src/org/eclipse/ui/texteditor/AbstractTextEditor.java 15 Jun 2006 07:46:36 -0000 1.201 +++ src/org/eclipse/ui/texteditor/AbstractTextEditor.java 17 Jun 2006 04:51:43 -0000 @@ -10,6 +10,7 @@ * Chris.Dennis@invidi.com - http://bugs.eclipse.org/bugs/show_bug.cgi?id=29027 * Michel Ishizuka (cqw10305@nifty.com) - http://bugs.eclipse.org/bugs/show_bug.cgi?id=68963 * Genady Beryozkin, me@genady.org - https://bugs.eclipse.org/bugs/show_bug.cgi?id=11668 + * Sebastian Davids, sdavids@gmx.de - http://bugs.eclipse.org/bugs/show_bug.cgi?id=125825 *******************************************************************************/ package org.eclipse.ui.texteditor; @@ -4546,6 +4547,31 @@ action.setActionDefinitionId(ITextEditorActionDefinitionIds.LOWER_CASE); setAction(ITextEditorActionConstants.LOWER_CASE, action); + action= new InvertCaseAction(EditorMessages.getBundleForConstructedKeys(), "Editor.InvertCase.", this); //$NON-NLS-1$ + action.setHelpContextId(IAbstractTextEditorHelpContextIds.INVERT_CASE_ACTION); + action.setActionDefinitionId(ITextEditorActionDefinitionIds.INVERT_CASE); + setAction(ITextEditorActionConstants.INVERT_CASE, action); + + action= new CapitalizeCaseAction(EditorMessages.getBundleForConstructedKeys(), "Editor.CapitalizeCase.", this); //$NON-NLS-1$ + action.setHelpContextId(IAbstractTextEditorHelpContextIds.CAPITALIZE_CASE_ACTION); + action.setActionDefinitionId(ITextEditorActionDefinitionIds.CAPITALIZE_CASE); + setAction(ITextEditorActionConstants.CAPITALIZE_CASE, action); + + action= new CamelCaseAction(EditorMessages.getBundleForConstructedKeys(), "Editor.LowerCamelCase.", this, false); //$NON-NLS-1$ + action.setHelpContextId(IAbstractTextEditorHelpContextIds.LOWER_CAMEL_CASE_ACTION); + action.setActionDefinitionId(ITextEditorActionDefinitionIds.LOWER_CAMEL_CASE); + setAction(ITextEditorActionConstants.LOWER_CAMEL_CASE, action); + + action= new CamelCaseAction(EditorMessages.getBundleForConstructedKeys(), "Editor.UpperCamelCase.", this, true); //$NON-NLS-1$ + action.setHelpContextId(IAbstractTextEditorHelpContextIds.UPPER_CAMEL_CASE_ACTION); + action.setActionDefinitionId(ITextEditorActionDefinitionIds.UPPER_CAMEL_CASE); + setAction(ITextEditorActionConstants.UPPER_CAMEL_CASE, action); + + action= new ConstantCaseAction(EditorMessages.getBundleForConstructedKeys(), "Editor.ConstantCase.", this); //$NON-NLS-1$ + action.setHelpContextId(IAbstractTextEditorHelpContextIds.CONSTANT_CASE_ACTION); + action.setActionDefinitionId(ITextEditorActionDefinitionIds.CONSTANT_CASE); + setAction(ITextEditorActionConstants.CONSTANT_CASE, action); + action= new InsertLineAction(EditorMessages.getBundleForConstructedKeys(), "Editor.SmartEnter.", this, false); //$NON-NLS-1$ action.setHelpContextId(IAbstractTextEditorHelpContextIds.SMART_ENTER_ACTION); action.setActionDefinitionId(ITextEditorActionDefinitionIds.SMART_ENTER); @@ -4613,6 +4639,11 @@ markAsSelectionDependentAction(ITextEditorActionConstants.SHIFT_RIGHT_TAB, true); markAsSelectionDependentAction(ITextEditorActionConstants.UPPER_CASE, true); markAsSelectionDependentAction(ITextEditorActionConstants.LOWER_CASE, true); + markAsSelectionDependentAction(ITextEditorActionConstants.INVERT_CASE, true); + markAsSelectionDependentAction(ITextEditorActionConstants.CAPITALIZE_CASE, true); + markAsSelectionDependentAction(ITextEditorActionConstants.LOWER_CAMEL_CASE, true); + markAsSelectionDependentAction(ITextEditorActionConstants.UPPER_CAMEL_CASE, true); + markAsSelectionDependentAction(ITextEditorActionConstants.CONSTANT_CASE, true); markAsPropertyDependentAction(ITextEditorActionConstants.UNDO, true); markAsPropertyDependentAction(ITextEditorActionConstants.REDO, true); Index: src/org/eclipse/ui/texteditor/CaseAction.java =================================================================== RCS file: /home/eclipse/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/CaseAction.java,v retrieving revision 1.9 diff -u -r1.9 CaseAction.java --- src/org/eclipse/ui/texteditor/CaseAction.java 17 Jun 2005 15:48:42 -0000 1.9 +++ src/org/eclipse/ui/texteditor/CaseAction.java 17 Jun 2006 04:51:43 -0000 @@ -7,23 +7,17 @@ * * Contributors: * IBM Corporation - initial API and implementation + * Sebastian Davids - bug 125825 *******************************************************************************/ package org.eclipse.ui.texteditor; import java.util.ResourceBundle; -import org.eclipse.swt.custom.StyledText; -import org.eclipse.swt.graphics.Point; - -import org.eclipse.jface.text.BadLocationException; -import org.eclipse.jface.text.IDocument; -import org.eclipse.jface.text.source.ISourceViewer; - /** * Action that converts the current selection to lower case or upper case. * @since 3.0 */ -public class CaseAction extends TextEditorAction implements IUpdate { +public class CaseAction extends AbstractCaseAction { /** true if this action converts to upper case, false otherwise. */ private boolean fToUpper; @@ -37,76 +31,19 @@ * @param prefix a prefix to be prepended to the various resource keys * (described in ResourceAction constructor), or null if none * @param editor the text editor - * @param toUpper true if this is an uppercase action, false otherwise. + * @param toUpper true if this is an upper case action, false otherwise * * @see ResourceAction#ResourceAction(ResourceBundle, String) */ public CaseAction(ResourceBundle bundle, String prefix, AbstractTextEditor editor, boolean toUpper) { super(bundle, prefix, editor); fToUpper= toUpper; - update(); } - + /* - * @see org.eclipse.jface.action.IAction#run() + * @see org.eclipse.ui.texteditor.AbstractCaseAction#changeCase(String) */ - public void run() { - ITextEditor editor= getTextEditor(); - if (editor == null) - return; - - if (!validateEditorInputState()) - return; - - ISourceViewer viewer= ((AbstractTextEditor) editor).getSourceViewer(); - if (viewer == null) - return; - - IDocument document= viewer.getDocument(); - if (document == null) - return; - - StyledText st= viewer.getTextWidget(); - if (st == null) - return; - - Point sel= viewer.getSelectedRange(); - if (sel == null) - return; - - try { - // if the selection is empty, we select the word / string using the viewer's - // double-click strategy - if (sel.y == 0) { - - // TODO find a better way to do this although there are multiple partitionings on a single document - -// String partition= getContentType(viewer, document, sel.x); -// SourceViewerConfiguration svc= fEditor.getSourceViewerConfiguration(); // never null when viewer instantiated -// ITextDoubleClickStrategy dcs= svc.getDoubleClickStrategy(viewer, partition); -// if (dcs != null) { -// dcs.doubleClicked(viewer); -// sel= viewer.getSelectedRange(); -// } - - if (sel.y == 0) - return; // if the selection is still empty, we're done - } - - String target= document.get(sel.x, sel.y); - String replacement= (fToUpper ? target.toUpperCase() : target.toLowerCase()); - if (!target.equals(replacement)) { - document.replace(sel.x, target.length(), replacement); - } - } catch (BadLocationException x) { - // ignore and return - return; - } - - // reinstall selection and move it into view - viewer.setSelectedRange(sel.x, sel.y); - // don't use the viewer's reveal feature in order to avoid jumping around - st.showSelection(); + protected String changeCase(String input) { + return fToUpper ? input.toUpperCase() : input.toLowerCase(); } - } Index: src/org/eclipse/ui/texteditor/ITextEditorActionConstants.java =================================================================== RCS file: /home/eclipse/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/ITextEditorActionConstants.java,v retrieving revision 1.30 diff -u -r1.30 ITextEditorActionConstants.java --- src/org/eclipse/ui/texteditor/ITextEditorActionConstants.java 6 Apr 2006 07:37:09 -0000 1.30 +++ src/org/eclipse/ui/texteditor/ITextEditorActionConstants.java 17 Jun 2006 04:51:44 -0000 @@ -228,6 +228,41 @@ String LOWER_CASE= "LowerCase"; //$NON-NLS-1$ /** + * Name of the action to invert the case of a selection + * Value: "InvertCase" + * @since 3.3 + */ + String INVERT_CASE= "InvertCase"; //$NON-NLS-1$ + + /** + * Name of the action to turn a selection to capitalized case + * Value: "CapitalizeCase" + * @since 3.3 + */ + String CAPITALIZE_CASE= "CapitalizeCase"; //$NON-NLS-1$ + + /** + * Name of the action to turn a selection to upper camel case + * Value: "UpperCamelCase" + * @since 3.3 + */ + String UPPER_CAMEL_CASE= "UpperCamelCase"; //$NON-NLS-1$ + + /** + * Name of the action to turn a selection to lower camel case + * Value: "LowerCamelCase" + * @since 3.3 + */ + String LOWER_CAMEL_CASE= "LowerCamelCase"; //$NON-NLS-1$ + + /** + * Name of the action to turn a selection to constant case + * Value: "ConstantCase" + * @since 3.3 + */ + String CONSTANT_CASE= "ConstantCase"; //$NON-NLS-1$ + + /** * Name of the action to find next. * Value: "FindNext" * @since 2.0 Index: plugin.xml =================================================================== RCS file: /home/eclipse/org.eclipse.ui.workbench.texteditor/plugin.xml,v retrieving revision 1.78 diff -u -r1.78 plugin.xml --- plugin.xml 3 May 2006 09:41:13 -0000 1.78 +++ plugin.xml 17 Jun 2006 04:51:39 -0000 @@ -385,6 +385,36 @@ id="org.eclipse.ui.edit.text.lowerCase"> + + + + + + + + + + - initial API and implementation + *******************************************************************************/ +package org.eclipse.ui.texteditor; + +import java.util.ResourceBundle; + +import org.eclipse.ui.internal.texteditor.Strings; + +/** + * Action that converts the current selection to constant case. + * + * @since 3.3 + */ +public class ConstantCaseAction extends AbstractCaseAction { + + /** + * Creates and initializes the action for the given text editor. The action + * configures its visual representation from the given resource bundle. + * + * @param bundle + * the resource bundle + * @param prefix + * a prefix to be prepended to the various resource keys + * (described in ResourceAction constructor), or + * null if none + * @param editor + * the text editor + * + * @see ResourceAction#ResourceAction(ResourceBundle, String) + */ + public ConstantCaseAction(ResourceBundle bundle, String prefix, + AbstractTextEditor editor) { + super(bundle, prefix, editor); + } + + /* + * @see org.eclipse.ui.texteditor.AbstractCaseAction#changeCase(String) + */ + protected String changeCase(String input) { + return Strings.constantCase(input); + } +} Index: src/org/eclipse/ui/texteditor/AbstractCaseAction.java =================================================================== RCS file: src/org/eclipse/ui/texteditor/AbstractCaseAction.java diff -N src/org/eclipse/ui/texteditor/AbstractCaseAction.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/org/eclipse/ui/texteditor/AbstractCaseAction.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,139 @@ +/******************************************************************************* + * Copyright (c) 2006 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + * Sebastian Davids - bug 125825 + *******************************************************************************/ +package org.eclipse.ui.texteditor; + +import java.util.ResourceBundle; + +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.source.ISourceViewer; +import org.eclipse.swt.custom.StyledText; +import org.eclipse.swt.graphics.Point; + +/** + * Abstract action that converts the current text selection to a different case. + *

+ * Subclasses should override {@link #changeCase(String)} to convert the + * selection to a specific case. + *

+ * + * @since 3.3 + */ +/* package */abstract class AbstractCaseAction extends TextEditorAction { + + /** + * Creates and initializes the action for the given text editor. The action + * configures its visual representation from the given resource bundle. + * + * @param bundle + * the resource bundle + * @param prefix + * a prefix to be prepended to the various resource keys + * (described in ResourceAction constructor), or + * null if none + * @param editor + * the text editor + * + * @see ResourceAction#ResourceAction(ResourceBundle, String) + */ + protected AbstractCaseAction(ResourceBundle bundle, String prefix, + ITextEditor editor) { + super(bundle, prefix, editor); + update(); + } + + /* + * @see org.eclipse.jface.action.IAction#run() + */ + public void run() { + ITextEditor editor = getTextEditor(); + if (editor == null) + return; + + if (!validateEditorInputState()) + return; + + ISourceViewer viewer = ((AbstractTextEditor) editor).getSourceViewer(); + if (viewer == null) + return; + + IDocument document = viewer.getDocument(); + if (document == null) + return; + + StyledText st = viewer.getTextWidget(); + if (st == null) + return; + + Point sel = viewer.getSelectedRange(); + if (sel == null) + return; + + try { + // if the selection is empty, we select the word / string using the + // viewer's + // double-click strategy + if (sel.y == 0) { + + // TODO find a better way to do this although there are multiple + // partitionings on a single document + + // String partition= getContentType(viewer, document, sel.x); + // SourceViewerConfiguration svc= + // fEditor.getSourceViewerConfiguration(); // never null when + // viewer instantiated + // ITextDoubleClickStrategy dcs= + // svc.getDoubleClickStrategy(viewer, partition); + // if (dcs != null) { + // dcs.doubleClicked(viewer); + // sel= viewer.getSelectedRange(); + // } + + if (sel.y == 0) + return; // if the selection is still empty, we're done + } + + String target = document.get(sel.x, sel.y); + String replacement = changeCase(target); + if (!target.equals(replacement)) { + document.replace(sel.x, target.length(), replacement); + // the replacement might be larger than the original + int adjustment = replacement.length() - target.length(); + if (adjustment > 0) + sel.y += adjustment; + } + } catch (BadLocationException x) { + // ignore and return + return; + } + + // reinstall selection and move it into view + viewer.setSelectedRange(sel.x, sel.y); + // don't use the viewer's reveal feature in order to avoid jumping + // around + st.showSelection(); + } + + /** + * Template method subclasses should override to convert the given String to + * a specific case. + *

+ * Since case mappings are not always 1:1 char mappings, the resulting + * String may be a different length than the String input. + *

+ * + * @param input + * the String to be converted; must not be null + * @return the replacement String in different case + */ + protected abstract String changeCase(String input); +} Index: src/org/eclipse/ui/texteditor/InvertCaseAction.java =================================================================== RCS file: src/org/eclipse/ui/texteditor/InvertCaseAction.java diff -N src/org/eclipse/ui/texteditor/InvertCaseAction.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/org/eclipse/ui/texteditor/InvertCaseAction.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,50 @@ +/******************************************************************************* + * Copyright (c) 2006 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sebastian Davids - initial API and implementation + *******************************************************************************/ +package org.eclipse.ui.texteditor; + +import java.util.ResourceBundle; + +import org.eclipse.ui.internal.texteditor.Strings; + +/** + * Action that inverts the case of the current selection. + * + * @since 3.3 + */ +public class InvertCaseAction extends AbstractCaseAction { + + /** + * Creates and initializes the action for the given text editor. The action + * configures its visual representation from the given resource bundle. + * + * @param bundle + * the resource bundle + * @param prefix + * a prefix to be prepended to the various resource keys + * (described in ResourceAction constructor), or + * null if none + * @param editor + * the text editor + * + * @see ResourceAction#ResourceAction(ResourceBundle, String) + */ + public InvertCaseAction(ResourceBundle bundle, String prefix, + AbstractTextEditor editor) { + super(bundle, prefix, editor); + } + + /* + * @see org.eclipse.ui.texteditor.AbstractCaseAction#changeCase(String) + */ + protected String changeCase(String input) { + return Strings.invertCase(input); + } +} Index: src/org/eclipse/ui/texteditor/CamelCaseAction.java =================================================================== RCS file: src/org/eclipse/ui/texteditor/CamelCaseAction.java diff -N src/org/eclipse/ui/texteditor/CamelCaseAction.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/org/eclipse/ui/texteditor/CamelCaseAction.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,50 @@ +/******************************************************************************* + * Copyright (c) 2006 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sebastian Davids - initial API and implementation + *******************************************************************************/ +package org.eclipse.ui.texteditor; + +import java.util.ResourceBundle; + +import org.eclipse.ui.internal.texteditor.Strings; + +/** + * Action that converts the current selection to lower camel case or upper camel case. + * @since 3.3 + */ +public class CamelCaseAction extends AbstractCaseAction { + + /** true if this action converts to upper camel case, false otherwise. */ + private boolean fToUpper; + + /** + * Creates and initializes the action for the given text editor. + * The action configures its visual representation from the given resource + * bundle. + * + * @param bundle the resource bundle + * @param prefix a prefix to be prepended to the various resource keys + * (described in ResourceAction constructor), or null if none + * @param editor the text editor + * @param toUpper true if this is an upper camel case action, false otherwise + * + * @see ResourceAction#ResourceAction(ResourceBundle, String) + */ + public CamelCaseAction(ResourceBundle bundle, String prefix, AbstractTextEditor editor, boolean toUpper) { + super(bundle, prefix, editor); + fToUpper= toUpper; + } + + /* + * @see org.eclipse.ui.texteditor.AbstractCaseAction#changeCase(String) + */ + protected String changeCase(String input) { + return fToUpper ? Strings.upperCamelCase(input) : Strings.lowerCamelCase(input); + } +} Index: src/org/eclipse/ui/internal/texteditor/Strings.java =================================================================== RCS file: src/org/eclipse/ui/internal/texteditor/Strings.java diff -N src/org/eclipse/ui/internal/texteditor/Strings.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/org/eclipse/ui/internal/texteditor/Strings.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,395 @@ +/******************************************************************************* + * Copyright (c) 2006 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: + * Sebastian Davids - initial API and implementation + *******************************************************************************/ +package org.eclipse.ui.internal.texteditor; + +import java.util.StringTokenizer; + +/** + * Helper class to provide String manipulation functions not available in + * standard JDK. + * + * @since 3.3 + */ +public class Strings { + + private Strings() { + // Do not instantiate + } + + /** + * Capitalizes the given String. + *

+ * Since case mappings are not always 1:1 char mappings, the resulting + * String may be a different length than the String input. + *

+ *

+ * Rules: + *

+ *
    + *
  • the first character will be converted to upper case
  • + *
  • each letter directly after a whitespace will be converted to upper + * case
  • + *
+ *

+ * Examples: + *

+ * + *
+	 * Strings.capitalize(null)                = null
+	 * Strings.capitalize("to be capitalized") = "To Be Capitalized"
+	 * Strings.capitalize("§")                 = "SS"
+	 * Strings.capitalize("a\tba")             = "A\tBa"
+	 * 
+ * + * @param input + * the String to be capitalized, may be null + * @return the capitalized String or null if null String + * input + * @see java.lang.String#toUpperCase() + */ + public static String capitalize(String input) { + if (input == null) + return null; + + int len = input.length(); + + if (len == 0) + return input; + + if (len == 1) + return input.toUpperCase(); + + StringTokenizer st = new StringTokenizer(input, " \t\n\r\f", true); //$NON-NLS-1$ + + // common case has no 1:M mappings so initialize buffer w/ + // length of original String to avoid resizing + StringBuffer result = new StringBuffer(input.length()); + + while (st.hasMoreTokens()) + appendCapitalized(result, st.nextToken()); + + return result.toString(); + } + + /** + * Converts the given String to constant case. + *

+ * Since case mappings are not always 1:1 char mappings, the resulting + * String may be a different length than the String input. + *

+ *

+ * Rules: + *

+ *
    + *
  • all letters will be converted to upper case
  • + *
  • each upper case letter in the input String will be prefixed by an _ + * in the result
  • + *
  • if the first character of the input String is an upper case letter + * then it wil not be prefixed by _ in the result
  • + *
+ *

+ * Examples: + *

+ * + *
+	 * Strings.constantCase(null)                        = null
+	 * Strings.constantCase("toConstantCase")            = "TO_CONSTANT_CASE"
+	 * Strings.constantCase("NoLeadingUnderscore")       = "NO_LEADING_UNDERSCORE"
+	 * Strings.constantCase("__someExtra__Underscores_") = "__SOME_EXTRA___UNDERSCORES_"
+	 * 
+ * + * @param input + * the String to be converted to constant case, may be null + * @return the constant case String or null if null String + * input + */ + public static String constantCase(String input) { + if (input == null) + return null; + + int len = input.length(); + + if (len == 0) + return input; + + if (len == 1) + return input.toUpperCase(); + + // it is likely that the result is longer than the input; + // nethertheless do not set a larger initial size and depend on + // StringBuffer's resize strategy + StringBuffer buffer = new StringBuffer(input.length()); + + // toUpperCase on an entire String is more performant than + // several String.valueOf(c).toUpperCase() calls in a loop; + // so we first just copy and insert _'s + + // first letter should not be prefixed by _ + buffer.append(input.charAt(0)); + + // now prefix the remaining + for (int i = 1; i < len; i++) { + char c = input.charAt(i); + if (Character.isUpperCase(c)) + buffer.append('_'); + buffer.append(c); + } + + // now convert to uppercase + return buffer.toString().toUpperCase(); + } + + /** + * Inverts the case of the given String's letters. + *

+ * Since case mappings are not always 1:1 char mappings, the resulting + * String may be a different length than the String input. + *

+ *

+ * This operation is not symmetric; + * Strings.invertCase(Strings.invertCase(input)) might not be + * equal to input. + *

+ *

+ * Rules: + *

+ *
    + *
  • each lower case letter will be converted to upper case
  • + *
  • each upper case letter will be converted to lower case
  • + *
+ *

+ * Examples: + *

+ * + *
+	 * Strings.invertCase(null)             = null
+	 * Strings.invertCase("To Be Inverted") = "tO bE iNVERTED"
+	 * Strings.invertCase("tO bE iNVERTED") = "To Be Inverted"
+	 * Strings.invertCase("Maße")           = "mASSE"
+	 * Strings.invertCase("mASSE")          = "Masse"
+	 * Strings.invertCase("StringsTest")    = "sTRINGStEST"
+	 * 
+ * + * @param input + * the String to be inverted, may be null + * @return the inverted String or null if null String input + * @see java.lang.String#toLowerCase() + * @see java.lang.String#toUpperCase() + * @see java.lang.Character#isLetter(char) + */ + public static String invertCase(String input) { + if (input == null) + return null; + + int len = input.length(); + + if (len == 0) + return input; + + int i; + char c; + + // skip to first lower case letter + for (i = 0; i < len; i++) { + c = input.charAt(i); + if (Character.isLetter(c) && Character.isLowerCase(c)) + break; + } + + // only upper case letters in String? + if (i == len) + return input.toLowerCase(); + + // common case has no 1:M mappings so initialize buffer w/ + // length of original String to avoid resizing + StringBuffer result = new StringBuffer(len); + + // append upper case letters before first lower case letter + result.append(input.substring(0, i).toLowerCase()); + + // convert the remaining characters + for (; i < len; i++) { + c = input.charAt(i); + if (Character.isLetter(c)) { + // String.toUpper/Lower insure 1:M mappings + String letter = String.valueOf(c); + if (Character.isLowerCase(c)) + result.append(letter.toUpperCase()); + else + result.append(letter.toLowerCase()); + } else + result.append(c); + } + + return result.toString(); + } + + /** + * Converts the given String to lower camel case. + *

+ * Since case mappings are not always 1:1 char mappings, the resulting + * String may be a different length than the String input. + *

+ *

+ * Rules: + *

+ *
    + *
  • the first letter will be converted to lower case
  • + *
  • the character _ will be removed unless it is followed by another _ + * or if it is a trailing _
  • + *
  • a letter following an _ will be converted to upper case
  • + *
  • all other letters will be in converted to lower case
  • + *
+ *

+ * Examples: + *

+ * + *
+	 * Strings.lowerCamelCase(null)                        = null
+	 * Strings.lowerCamelCase("TO_LOWER_CAMEL_CASE")       = "toLowerCamelCase"
+	 * Strings.lowerCamelCase("_Leading")                  = "leading"
+	 * Strings.lowerCamelCase("__someExtra__underscores_") = "_Someextra_Underscores_"
+	 * 
+ * + * @param input + * the String to be converted to lower camel case, may be null + * @return the lower camel case String or null if null String + * input + */ + public static String lowerCamelCase(String input) { + return internalCamelCase(input, false); + } + + /** + * Converts the given String to upper camel case. + *

+ * Since case mappings are not always 1:1 char mappings, the resulting + * String may be a different length than the String input. + *

+ *

+ * Rules: + *

+ *
    + *
  • the character _ will be removed unless it is followed by another _ + * or if it is a trailing _
  • + *
  • a letter following an _ will be converted to upper case
  • + *
  • all other letters will be in converted to lower case
  • + *
+ *

+ * Examples: + *

+ * + *
+	 * Strings.upperCamelCase(null)                        = null
+	 * Strings.upperCamelCase("TO_UPPER_CAMEL_CASE")       = "ToUpperCamelCase"
+	 * Strings.upperCamelCase("_leading")                  = "Leading"
+	 * Strings.upperCamelCase("__someExtra__underscores_") = "_Someextra_Underscores_"
+	 * 
+ * + * @param input + * the String to be converted to upper camel case, may be null + * @return the upper camel case String or null if null String + * input + */ + public static String upperCamelCase(String input) { + return internalCamelCase(input, true); + } + + /** + * Converts the given String to upper or lower camel case. + * + * @param input + * the String to be converted, may be null + * @param toUpper + * true if the input should be converted to upper + * camel case, false otherwise + * @return the converted String or null if null String input + */ + private static String internalCamelCase(String input, boolean toUpper) { + if (input == null) + return null; + + if (input.length() == 0) + return input; + + // the result mainly consists of lower case letters; + // toLowerCase on the entire String is more performant than + // several String.valueOf(c).toLowerCase() calls in the loop below + String lower = input.toLowerCase(); + int len = lower.length(); + StringBuffer buffer = new StringBuffer(len); + for (int i = 0; i < len; i++) { + char c = lower.charAt(i); + if (c == '_') { + int j = i + 1; + for (; j < len; j++) { + c = lower.charAt(j); + if (c == '_') { + // keep additional _'s + buffer.append('_'); + } else { + if (toUpper || j > 1) { + // String.toUpper insures 1:M mappings + buffer.append(String.valueOf(c).toUpperCase()); + } else { + // keep result's first character in lower case + buffer.append(c); + } + break; + } + } + if (j == len) { + // keep trailing _ + buffer.append('_'); + } + i = j; + } else { + // letters are lower case already so just append + buffer.append(lower.charAt(i)); + } + } + if (toUpper) { + buffer + .replace(0, 1, String.valueOf(buffer.charAt(0)) + .toUpperCase()); + } + return buffer.toString(); + } + + /** + * Appends the given String to the buffer; the first character of the String + * will be appended in upper case if it is a letter. + * + * @param buffer + * the StringBuffer the capitalized input String + * will be appended to + * @param input + * the String to be capitalized + */ + private static void appendCapitalized(StringBuffer buffer, String input) { + char firstChar = input.charAt(0); + + if (!Character.isLetter(firstChar)) { + buffer.append(input); + return; + } + + // capitalize first char of token + // String.toUpper insures 1:M mappings + buffer.append(String.valueOf(firstChar).toUpperCase()); + + int len = input.length(); + + // append remaining chars of token + if (len > 1) + buffer.append(input.substring(1, len)); + } +} Index: src/org/eclipse/ui/texteditor/CapitalizeCaseAction.java =================================================================== RCS file: src/org/eclipse/ui/texteditor/CapitalizeCaseAction.java diff -N src/org/eclipse/ui/texteditor/CapitalizeCaseAction.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/org/eclipse/ui/texteditor/CapitalizeCaseAction.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,50 @@ +/******************************************************************************* + * Copyright (c) 2006 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sebastian Davids - initial API and implementation + *******************************************************************************/ +package org.eclipse.ui.texteditor; + +import java.util.ResourceBundle; + +import org.eclipse.ui.internal.texteditor.Strings; + +/** + * Action that capitalizes the current selection. + * + * @since 3.3 + */ +public class CapitalizeCaseAction extends AbstractCaseAction { + + /** + * Creates and initializes the action for the given text editor. The action + * configures its visual representation from the given resource bundle. + * + * @param bundle + * the resource bundle + * @param prefix + * a prefix to be prepended to the various resource keys + * (described in ResourceAction constructor), or + * null if none + * @param editor + * the text editor + * + * @see ResourceAction#ResourceAction(ResourceBundle, String) + */ + public CapitalizeCaseAction(ResourceBundle bundle, String prefix, + AbstractTextEditor editor) { + super(bundle, prefix, editor); + } + + /* + * @see org.eclipse.ui.texteditor.AbstractCaseAction#changeCase(String) + */ + protected String changeCase(String input) { + return Strings.capitalize(input); + } +}