### Eclipse Workspace Patch 1.0 #P org.eclipse.wst.html.ui Index: plugin.xml =================================================================== RCS file: /cvsroot/webtools/sourceediting/plugins/org.eclipse.wst.html.ui/plugin.xml,v retrieving revision 1.88 diff -u -r1.88 plugin.xml --- plugin.xml 26 Aug 2009 20:50:16 -0000 1.88 +++ plugin.xml 14 Sep 2009 20:14:17 -0000 @@ -60,7 +60,7 @@ target="org.eclipse.wst.html.core.htmlsource" /> + + @@ -536,6 +542,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: plugin.properties =================================================================== RCS file: /cvsroot/webtools/sourceediting/plugins/org.eclipse.wst.html.ui/plugin.properties,v retrieving revision 1.29 diff -u -r1.29 plugin.properties --- plugin.properties 12 Mar 2009 00:43:43 -0000 1.29 +++ plugin.properties 14 Sep 2009 20:14:17 -0000 @@ -70,9 +70,15 @@ scope.structured.text.editor.html.description=Editing HTML Source scope.structured.text.editor.html.occurrences.name=HTML Source Occurrences scope.structured.text.editor.html.occurrences.description=HTML Source Occurrences +scope.structured.text.editor.html.comments.name=HTML Source Comments +scope.structured.text.editor.html.comments.description=HTML Source Comments Colors.scriptAreaBorder=Script Area Border hyperlinkDetector.anchor.name=Anchors hyperlink.target.script.name=HTML Client Script hyperlink.target.eventhandler.name=HTML Event Handlers +# Menu contributions +command.toggle.comment.mnemonic=T +command.add.block.comment.mnemonic=A +command.remove.block.comment.mnemonic=R Index: src/org/eclipse/wst/html/ui/internal/handlers/AddHTMLBlockCommentHandler.java =================================================================== RCS file: src/org/eclipse/wst/html/ui/internal/handlers/AddHTMLBlockCommentHandler.java diff -N src/org/eclipse/wst/html/ui/internal/handlers/AddHTMLBlockCommentHandler.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/org/eclipse/wst/html/ui/internal/handlers/AddHTMLBlockCommentHandler.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright (c) 2008, 2009 Standards for Technology in Automotive Retail 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: + * David Carver - initial API and implementation, bug 212330 + * IBM Corporation - additional contributions + * + *******************************************************************************/ +package org.eclipse.wst.html.ui.internal.handlers; + +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.ITextSelection; +import org.eclipse.ui.texteditor.ITextEditor; +import org.eclipse.wst.html.ui.internal.Logger; + +/** + * The handler used to add a block comment to an XML file + */ +public class AddHTMLBlockCommentHandler extends AbstractHTMLCommentHandler { + + /** + * Default constructor must exist because sub classes are created by java reflection + */ + public AddHTMLBlockCommentHandler() { + super(); + } + + /** + * Adds a block comment to the given text selection based on the types in the text selection + * + * @see org.eclipse.wst.sse.ui.internal.handlers.AbstractStructuredCommentHandler#processAction(org.eclipse.ui.texteditor.ITextEditor, org.eclipse.jface.text.IDocument, org.eclipse.jface.text.ITextSelection) + */ + protected void processAction(ITextEditor textEditor, IDocument document, ITextSelection textSelection) { + try { + processAddBlockCommentAction(this, textEditor, document, textSelection); + } catch (BadLocationException e) { + Logger.log(Logger.WARNING, e.getMessage(), e); + } + } +} Index: src/org/eclipse/wst/html/ui/internal/handlers/RemoveHTMLBlockCommentHandler.java =================================================================== RCS file: src/org/eclipse/wst/html/ui/internal/handlers/RemoveHTMLBlockCommentHandler.java diff -N src/org/eclipse/wst/html/ui/internal/handlers/RemoveHTMLBlockCommentHandler.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/org/eclipse/wst/html/ui/internal/handlers/RemoveHTMLBlockCommentHandler.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright (c) 2008, 2009 Standards for Technology in Automotive Retail 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: + * David Carver - initial API and implementation, bug 212330 + * IBM Corporation - additional contributions + * + *******************************************************************************/ +package org.eclipse.wst.html.ui.internal.handlers; + +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.ITextSelection; +import org.eclipse.ui.texteditor.ITextEditor; +import org.eclipse.wst.html.ui.internal.Logger; + +/** + * The handler used to remove a block comment to a XML file + */ +public class RemoveHTMLBlockCommentHandler extends AbstractHTMLCommentHandler { + + /** + * Default constructor must exist because sub classes are created by java reflection + */ + public RemoveHTMLBlockCommentHandler() { + super(); + } + + /** + * Removes all block comments from the given text selection + * + * @see org.eclipse.wst.sse.ui.internal.handlers.AbstractStructuredCommentHandler#processAction(org.eclipse.ui.texteditor.ITextEditor, org.eclipse.jface.text.IDocument, org.eclipse.jface.text.ITextSelection) + */ + protected void processAction(ITextEditor textEditor, IDocument document, ITextSelection textSelection) { + try { + processRemoveBlockCommentAction(textEditor, document, textSelection); + } catch (BadLocationException e) { + Logger.log(Logger.WARNING, e.getMessage(), e); + } + } +} Index: src/org/eclipse/wst/html/ui/internal/handlers/AbstractHTMLCommentHandler.java =================================================================== RCS file: src/org/eclipse/wst/html/ui/internal/handlers/AbstractHTMLCommentHandler.java diff -N src/org/eclipse/wst/html/ui/internal/handlers/AbstractHTMLCommentHandler.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/org/eclipse/wst/html/ui/internal/handlers/AbstractHTMLCommentHandler.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,156 @@ +/******************************************************************************* + * Copyright (c) 2008, 2009 Standards for Technology in Automotive Retail 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: + * David Carver - initial API and implementation, bug 212330 + * IBM Corporation - additional contributions + * + *******************************************************************************/ +package org.eclipse.wst.html.ui.internal.handlers; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.jface.text.ITypedRegion; +import org.eclipse.wst.html.core.text.IHTMLPartitions; +import org.eclipse.wst.sse.ui.internal.handlers.AbstractStructuredCommentHandler; +import org.eclipse.wst.xml.core.text.IXMLPartitions; +import org.eclipse.wst.xml.ui.internal.handlers.AbstractXMLCommentHandler; + +/** + * The abstract comment handler for HTML files. + * + * @see AbstractStructuredCommentHandler + */ +public abstract class AbstractHTMLCommentHandler extends AbstractXMLCommentHandler { + protected static final String SCRIPT_LINE_COMMENT_PREFIX = "//"; //$NON-NLS-1$ + protected static final String SCRIPT_BLOCK_COMMENT_PREFIX = "/*"; //$NON-NLS-1$ + protected static final String SCRIPT_BLOCK_COMMENT_SUFFIX = "*/"; //$NON-NLS-1$ + + private static final String[] POSSIBLE_COMMENT_PREFIXES = { + XML_BLOCK_COMMENT_PREFIX, SCRIPT_LINE_COMMENT_PREFIX, SCRIPT_BLOCK_COMMENT_PREFIX + }; + + private static final String[] POSSIBLE_COMMENT_SUFFIXES = { + XML_BLOCK_COMMENT_SUFFIX, SCRIPT_BLOCK_COMMENT_SUFFIX + }; + + private static final String[] HTML_COMMENT_PARTITION_TYPES = { + IXMLPartitions.XML_COMMENT, IHTMLPartitions.HTML_COMMENT + }; + + private static final List SCRIPT_PARTITION_TYPES = new ArrayList(); + static { + SCRIPT_PARTITION_TYPES.add(IHTMLPartitions.SCRIPT); + } + + /** + * Default constructor must exist because sub classes are created by java reflection + */ + public AbstractHTMLCommentHandler() { + super(); + } + + /** + * script regions have line comments + * + * (non-Javadoc) + * @see org.eclipse.wst.sse.ui.internal.handlers.AbstractStructuredCommentHandler#getLineCommentPrefix(java.util.List) + */ + protected String getLineCommentPrefix(ITypedRegion[] regions) { + String openComment = null; + + if(regions.length == 1) { + String type = regions[0].getType(); + if(type == IHTMLPartitions.SCRIPT) { + openComment = SCRIPT_LINE_COMMENT_PREFIX; + } + } + + return openComment; + } + + /** + * There is only one type of start comment in XML + * + * (non-Javadoc) + * @see org.eclipse.wst.sse.ui.internal.handlers.AbstractStructuredCommentHandler#getBlockCommentPrefix(java.util.List) + */ + protected String getBlockCommentPrefix(ITypedRegion[] regions) { + String commentPrefix = null; + + List copy = new ArrayList(regions.length); + for(int i = 0; i < regions.length; ++i) { + copy.add(regions[i].getType()); + } + + boolean hadScriptTypes = copy.removeAll(SCRIPT_PARTITION_TYPES); + + //if only script regions then script comment prefix + //else ask parent comment handler + if(hadScriptTypes && copy.size() == 0) { + commentPrefix = SCRIPT_BLOCK_COMMENT_PREFIX; + } else { + commentPrefix = super.getBlockCommentPrefix(regions); + } + + return commentPrefix; + } + + /** + * There is only one type of comment suffix in XML + * + * (non-Javadoc) + * @see org.eclipse.wst.sse.ui.internal.handlers.AbstractStructuredCommentHandler#getBlockCommentSuffix(java.util.List) + */ + protected String getBlockCommentSuffix(ITypedRegion[] regions) { + String commentSuffix = null; + + List copy = new ArrayList(regions.length); + for(int i = 0; i < regions.length; ++i) { + copy.add(regions[i].getType()); + } + + boolean hadScriptTypes = copy.removeAll(SCRIPT_PARTITION_TYPES); + + //if only script regions then script comment prefix + //else ask parent comment handler + if(hadScriptTypes && copy.size() == 0) { + commentSuffix = SCRIPT_BLOCK_COMMENT_SUFFIX; + } else { + commentSuffix = super.getBlockCommentSuffix(regions); + } + + return commentSuffix; + } + + /** + * @see org.eclipse.wst.sse.ui.internal.handlers.AbstractStructuredCommentHandler#getPossibleCommentOpenings() + */ + protected String[] getPossibleCommentPrefixes() { + return POSSIBLE_COMMENT_PREFIXES; + } + + /** + * @see org.eclipse.wst.sse.ui.internal.handlers.AbstractStructuredCommentHandler#getPossibleCommentClosings() + */ + protected String[] getPossibleCommentSuffixes() { + return POSSIBLE_COMMENT_SUFFIXES; + } + + /** + *

LIMITATION: there needs to be a partition type for commented JAVA and SCRIPT regions (BUG ######) + * this effects being able to remove comment blocks in JAVA and SCRIPT regions as well as undesired behavior + * when adding a comment block to already commented JAVA and SCRIPT regions. Once new partition types + * are created for commented JAVA and SCRIPT regions they should be returned here as well.

+ * + * @see org.eclipse.wst.sse.ui.internal.handlers.AbstractStructuredCommentHandler#getCommentTypes() + */ + protected String[] getCommentPartitionTypes() { + return HTML_COMMENT_PARTITION_TYPES; + } +} Index: src/org/eclipse/wst/html/ui/internal/handlers/ToggleHTMLCommentHandler.java =================================================================== RCS file: src/org/eclipse/wst/html/ui/internal/handlers/ToggleHTMLCommentHandler.java diff -N src/org/eclipse/wst/html/ui/internal/handlers/ToggleHTMLCommentHandler.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/org/eclipse/wst/html/ui/internal/handlers/ToggleHTMLCommentHandler.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright (c) 2008, 2009 Standards for Technology in Automotive Retail 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: + * David Carver - initial API and implementation, bug 212330 + * IBM Corporation - additional contributions + * + *******************************************************************************/ +package org.eclipse.wst.html.ui.internal.handlers; + +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.ITextSelection; +import org.eclipse.ui.texteditor.ITextEditor; +import org.eclipse.wst.html.ui.internal.Logger; + +/** + * The handler used to toggle per line comments + */ +public class ToggleHTMLCommentHandler extends AbstractHTMLCommentHandler { + + /** + * Default constructor must exist because sub classes are created by java reflection + */ + public ToggleHTMLCommentHandler() { + super(); + } + + /** + * Break the selection down into lines and toggle the commenting for each line + * + * @see org.eclipse.jst.jsp.ui.internal.handlers.AbstractJSPCommentHandler#processAction(org.eclipse.ui.texteditor.ITextEditor, org.eclipse.jface.text.IDocument, org.eclipse.jface.text.ITextSelection) + */ + protected void processAction(ITextEditor textEditor, IDocument document, ITextSelection textSelection) { + try { + processToggleCommentAction(textEditor, document, textSelection); + } catch (BadLocationException e) { + Logger.log(Logger.WARNING, e.getMessage(), e); + } + } +} #P org.eclipse.jst.jsp.ui Index: plugin.xml =================================================================== RCS file: /cvsroot/webtools/sourceediting/plugins/org.eclipse.jst.jsp.ui/plugin.xml,v retrieving revision 1.91 diff -u -r1.91 plugin.xml --- plugin.xml 9 Sep 2009 04:31:19 -0000 1.91 +++ plugin.xml 14 Sep 2009 20:14:18 -0000 @@ -72,7 +72,7 @@ target="org.eclipse.jst.jsp.core.jspsource" /> + + @@ -1018,10 +1024,58 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + @@ -1032,6 +1086,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1047,4 +1132,15 @@ + + + + + + + + + + + Index: plugin.properties =================================================================== RCS file: /cvsroot/webtools/sourceediting/plugins/org.eclipse.jst.jsp.ui/plugin.properties,v retrieving revision 1.25 diff -u -r1.25 plugin.properties --- plugin.properties 21 May 2009 22:02:24 -0000 1.25 +++ plugin.properties 14 Sep 2009 20:14:17 -0000 @@ -50,6 +50,8 @@ scope.structured.text.editor.jsp.description=Editing JSP Source scope.jsp.core.jspsource.name=JSP Source scope.jsp.core.jspsource.description=JSP Source +scope.structured.text.editor.jsp.comments.name=JSP Source Comments +scope.structured.text.editor.jsp.comments.description=JSP Source Comments JSP_Type_Rename_Participant_Extension_Element.name=JSP Type Rename Participant JSP_Method_Rename_Participant_Extension_Element.name=JSP Method Rename Participant JSP_Package_Rename_Participant_Extension_Element.name=JSP Package Rename Participant @@ -62,6 +64,7 @@ JSP_Attribute_value_context_type_Extension_Element.name=JSP Attribute value JSP_Query_Participant_Extension_Element.name=JSP Query Participant JSP_Extension_Element.label=JSP + #org.eclipse.ui.newWizards extension point _UI_WIZARD_NAME = JSP _UI_WIZARD_CREATE_NEW_FILE = Create a new JavaServer Page @@ -104,3 +107,8 @@ ## Java_Element_hyperlink=Java Element Taglib_hyperlink=Tag Library Descriptor + +# Menu contributions +command.toggle.comment.mnemonic=T +command.add.block.comment.mnemonic=A +command.remove.block.comment.mnemonic=R Index: src/org/eclipse/jst/jsp/ui/internal/handlers/AddJSPBlockCommentHandler.java =================================================================== RCS file: src/org/eclipse/jst/jsp/ui/internal/handlers/AddJSPBlockCommentHandler.java diff -N src/org/eclipse/jst/jsp/ui/internal/handlers/AddJSPBlockCommentHandler.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/org/eclipse/jst/jsp/ui/internal/handlers/AddJSPBlockCommentHandler.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright (c) 2009 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 + * + *******************************************************************************/ +package org.eclipse.jst.jsp.ui.internal.handlers; + +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.ITextSelection; +import org.eclipse.jst.jsp.ui.internal.Logger; +import org.eclipse.ui.texteditor.ITextEditor; + +/** + *

The handler used to add a block comment to a JSP file

+ */ +public class AddJSPBlockCommentHandler extends AbstractJSPCommentHandler { + + /** + * Default constructor must exist because sub classes are created by java reflection + */ + public AddJSPBlockCommentHandler() { + super(); + } + + + /** + * Adds a block comment to the given text selection based on the types in the text selection + * + * @see org.eclipse.wst.sse.ui.internal.handlers.AbstractStructuredCommentHandler#processAction(org.eclipse.ui.texteditor.ITextEditor, org.eclipse.jface.text.IDocument, org.eclipse.jface.text.ITextSelection) + */ + protected void processAction(ITextEditor textEditor, IDocument document, ITextSelection textSelection) { + try { + processAddBlockCommentAction(this, textEditor, document, textSelection); + } catch (BadLocationException e) { + Logger.log(Logger.WARNING, e.getMessage(), e); + } + } +} Index: src/org/eclipse/jst/jsp/ui/internal/handlers/ToggleJSPCommentHandler.java =================================================================== RCS file: src/org/eclipse/jst/jsp/ui/internal/handlers/ToggleJSPCommentHandler.java diff -N src/org/eclipse/jst/jsp/ui/internal/handlers/ToggleJSPCommentHandler.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/org/eclipse/jst/jsp/ui/internal/handlers/ToggleJSPCommentHandler.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright (c) 2009 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 + * + *******************************************************************************/ +package org.eclipse.jst.jsp.ui.internal.handlers; + +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.ITextSelection; +import org.eclipse.jst.jsp.ui.internal.Logger; +import org.eclipse.ui.texteditor.ITextEditor; + +/** + * The handler used to toggle per line comments + */ +public class ToggleJSPCommentHandler extends AbstractJSPCommentHandler { + + /** + * Default constructor must exist because sub classes are created by java reflection + */ + public ToggleJSPCommentHandler() { + super(); + } + + /** + * Break the selection down into lines and toggle the commenting for each line + * + * @see org.eclipse.jst.jsp.ui.internal.handlers.AbstractJSPCommentHandler#processAction(org.eclipse.ui.texteditor.ITextEditor, org.eclipse.jface.text.IDocument, org.eclipse.jface.text.ITextSelection) + */ + protected void processAction(ITextEditor textEditor, IDocument document, ITextSelection textSelection) { + try { + processToggleCommentAction(textEditor, document, textSelection); + } catch (BadLocationException e) { + Logger.log(Logger.WARNING, e.getMessage(), e); + } + } +} Index: src/org/eclipse/jst/jsp/ui/internal/handlers/RemoveJSPBlockCommentHandler.java =================================================================== RCS file: src/org/eclipse/jst/jsp/ui/internal/handlers/RemoveJSPBlockCommentHandler.java diff -N src/org/eclipse/jst/jsp/ui/internal/handlers/RemoveJSPBlockCommentHandler.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/org/eclipse/jst/jsp/ui/internal/handlers/RemoveJSPBlockCommentHandler.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright (c) 2009 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 + * + *******************************************************************************/ +package org.eclipse.jst.jsp.ui.internal.handlers; + +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.ITextSelection; +import org.eclipse.jst.jsp.ui.internal.Logger; +import org.eclipse.ui.texteditor.ITextEditor; + +/** + * The handler used to remove a block comment to a JSP file + */ +public class RemoveJSPBlockCommentHandler extends AbstractJSPCommentHandler { + + /** + * Default constructor must exist because sub classes are created by java reflection + */ + public RemoveJSPBlockCommentHandler() { + super(); + } + + /** + * Removes all block comments from the given text selection + * + * @see org.eclipse.wst.sse.ui.internal.handlers.AbstractStructuredCommentHandler#processAction(org.eclipse.ui.texteditor.ITextEditor, org.eclipse.jface.text.IDocument, org.eclipse.jface.text.ITextSelection) + */ + protected void processAction(ITextEditor textEditor, IDocument document, ITextSelection textSelection) { + try { + processRemoveBlockCommentAction(textEditor, document, textSelection); + } catch (BadLocationException e) { + Logger.log(Logger.WARNING, e.getMessage(), e); + } + } +} Index: src/org/eclipse/jst/jsp/ui/internal/handlers/AbstractJSPCommentHandler.java =================================================================== RCS file: src/org/eclipse/jst/jsp/ui/internal/handlers/AbstractJSPCommentHandler.java diff -N src/org/eclipse/jst/jsp/ui/internal/handlers/AbstractJSPCommentHandler.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/org/eclipse/jst/jsp/ui/internal/handlers/AbstractJSPCommentHandler.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,168 @@ +/******************************************************************************* + * Copyright (c) 2009 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 + * + *******************************************************************************/ +package org.eclipse.jst.jsp.ui.internal.handlers; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.jface.text.ITypedRegion; +import org.eclipse.jst.jsp.core.text.IJSPPartitions; +import org.eclipse.wst.html.core.text.IHTMLPartitions; +import org.eclipse.wst.sse.ui.internal.handlers.AbstractStructuredCommentHandler; + +/** + * The abstract comment handler for JSP files. + * + * @see AbstractStructuredCommentHandler + */ +public abstract class AbstractJSPCommentHandler extends AbstractStructuredCommentHandler { + protected static final String HTML_BLOCK_COMMENT_PREFIX = ""; //$NON-NLS-1$ + + protected static final String JSP_BLOCK_COMMENT_PREFIX = "<%--"; //$NON-NLS-1$ + protected static final String JSP_BLOCK_COMMENT_SUFFIX = "--%>"; //$NON-NLS-1$ + + protected static final String JAVA_LINE_COMMENT_PREFIX = "//"; //$NON-NLS-1$ + protected static final String JAVA_BLOCK_COMMENT_PREFIX = "/*"; //$NON-NLS-1$ + protected static final String JAVA_BLOCK_COMMENT_SUFFIX = "*/"; //$NON-NLS-1$ + + private static final String[] POSSIBLE_COMMENT_PREFIXES = { + HTML_BLOCK_COMMENT_PREFIX, JSP_BLOCK_COMMENT_PREFIX, + JAVA_BLOCK_COMMENT_PREFIX, JAVA_LINE_COMMENT_PREFIX + }; + + private static final String[] POSSIBLE_COMMENT_SUFFIXES = { + HTML_BLOCK_COMMENT_SUFFIX, JSP_BLOCK_COMMENT_SUFFIX, JAVA_BLOCK_COMMENT_SUFFIX + }; + + private static final List JAVA_PARTITION_TYPES = new ArrayList(); + private static final List JSP_PARTITION_TYPES = new ArrayList(); + static { + JAVA_PARTITION_TYPES.add(IJSPPartitions.JSP_CONTENT_JAVA); + JAVA_PARTITION_TYPES.add(IHTMLPartitions.SCRIPT); + JSP_PARTITION_TYPES.add(IJSPPartitions.JSP_COMMENT); + JSP_PARTITION_TYPES.add(IJSPPartitions.JSP_DIRECTIVE); + JSP_PARTITION_TYPES.add(IJSPPartitions.JSP_CONTENT_DELIMITER); + JSP_PARTITION_TYPES.add(IJSPPartitions.JSP_DEFAULT); + } + + private static final String[] JSP_COMMENT_PARTITION_TYPES = { + IJSPPartitions.JSP_COMMENT, IHTMLPartitions.HTML_COMMENT + }; + + /** + * Default constructor must exist because sub classes are created by java reflection + */ + public AbstractJSPCommentHandler() { + super(); + } + + /** + * @see org.eclipse.wst.sse.ui.internal.handlers.AbstractStructuredCommentHandler#getLineCommentPrefix(org.eclipse.jface.text.ITypedRegion[]) + */ + protected String getLineCommentPrefix(ITypedRegion[] regions) { + String openComment = null; + + if(regions.length == 1) { + String type = regions[0].getType(); + if(type == IJSPPartitions.JSP_CONTENT_JAVA || type == IHTMLPartitions.SCRIPT) { + openComment = JAVA_LINE_COMMENT_PREFIX; + } + } + + return openComment; + } + + /** + * @see org.eclipse.wst.sse.ui.internal.handlers.AbstractStructuredCommentHandler#getBlockCommentPrefix(org.eclipse.jface.text.ITypedRegion[]) + */ + protected String getBlockCommentPrefix(ITypedRegion[] regions) { + String commentPrefix = null; + + List copy = new ArrayList(regions.length); + for(int i = 0; i < regions.length; ++i) { + copy.add(regions[i].getType()); + } + + boolean hadJavaTypes = copy.removeAll(JAVA_PARTITION_TYPES); + boolean hadJSPTypes = copy.removeAll(JSP_PARTITION_TYPES); + + /* if only java regions then java comment prefix + * else if had java regions or jsp regions then jsp comment prefix + * else html regions only so html comment prefix + */ + if(hadJavaTypes && copy.size() == 0) { + commentPrefix = JAVA_BLOCK_COMMENT_PREFIX; + } else if(hadJavaTypes || hadJSPTypes) { + commentPrefix = JSP_BLOCK_COMMENT_PREFIX; + } else { + commentPrefix = HTML_BLOCK_COMMENT_PREFIX; + } + + return commentPrefix; + } + + /** + * @see org.eclipse.wst.sse.ui.internal.handlers.AbstractStructuredCommentHandler#getBlockCommentSuffix(org.eclipse.jface.text.ITypedRegion[]) + */ + protected String getBlockCommentSuffix(ITypedRegion[] regions) { + String commentSuffix = null; + + List copy = new ArrayList(regions.length); + for(int i = 0; i < regions.length; ++i) { + copy.add(regions[i].getType()); + } + + boolean hadJavaTypes = copy.removeAll(JAVA_PARTITION_TYPES); + boolean hadJSPTypes = copy.removeAll(JSP_PARTITION_TYPES); + + /* if only java regions then java comment suffix + * else if had java regions or jsp regions then jsp comment suffix + * else html regions only so html comment suffix + */ + if(hadJavaTypes && copy.size() == 0) { + commentSuffix = JAVA_BLOCK_COMMENT_SUFFIX; + } else if(hadJavaTypes || hadJSPTypes) { + commentSuffix = JSP_BLOCK_COMMENT_SUFFIX; + } else { + commentSuffix = HTML_BLOCK_COMMENT_SUFFIX; + } + + return commentSuffix; + } + + /** + * @see org.eclipse.wst.sse.ui.internal.handlers.AbstractStructuredCommentHandler#getPossibleCommentPrefixes() + */ + protected String[] getPossibleCommentPrefixes() { + return POSSIBLE_COMMENT_PREFIXES; + } + + /** + * @see org.eclipse.wst.sse.ui.internal.handlers.AbstractStructuredCommentHandler#getPossibleCommentSuffixes() + */ + protected String[] getPossibleCommentSuffixes() { + return POSSIBLE_COMMENT_SUFFIXES; + } + + /** + *

LIMITATION: there needs to be a partition type for commented JAVA and SCRIPT regions (BUG ######) + * this effects being able to remove comment blocks in JAVA and SCRIPT regions as well as undesired behavior + * when adding a comment block to already commented JAVA and SCRIPT regions. Once new partition types + * are created for commented JAVA and SCRIPT regions they should be returned here as well.

+ * + * @see org.eclipse.wst.sse.ui.internal.handlers.AbstractStructuredCommentHandler#getCommentPartitionTypes() + */ + protected String[] getCommentPartitionTypes() { + return JSP_COMMENT_PARTITION_TYPES; + } +} #P org.eclipse.wst.sse.ui Index: src/org/eclipse/wst/sse/ui/internal/SSEUIMessages.java =================================================================== RCS file: /cvsroot/webtools/sourceediting/plugins/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/SSEUIMessages.java,v retrieving revision 1.23 diff -u -r1.23 SSEUIMessages.java --- src/org/eclipse/wst/sse/ui/internal/SSEUIMessages.java 26 Jan 2009 22:45:18 -0000 1.23 +++ src/org/eclipse/wst/sse/ui/internal/SSEUIMessages.java 14 Sep 2009 20:14:18 -0000 @@ -90,6 +90,7 @@ public static String ToggleComment_tooltip; public static String ToggleComment_image; public static String ToggleComment_description; + public static String ToggleComment_progress; public static String AddBlockComment_label; public static String AddBlockComment_tooltip; public static String AddBlockComment_image; Index: src/org/eclipse/wst/sse/ui/internal/SSEUIPluginResources.properties =================================================================== RCS file: /cvsroot/webtools/sourceediting/plugins/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/SSEUIPluginResources.properties,v retrieving revision 1.27 diff -u -r1.27 SSEUIPluginResources.properties --- src/org/eclipse/wst/sse/ui/internal/SSEUIPluginResources.properties 10 Aug 2009 15:42:30 -0000 1.27 +++ src/org/eclipse/wst/sse/ui/internal/SSEUIPluginResources.properties 14 Sep 2009 20:14:18 -0000 @@ -62,6 +62,7 @@ ToggleComment_tooltip=Toggle Comment ToggleComment_image= ToggleComment_description=Toggle Comment +ToggleComment_progress=Toggling line comments... AddBlockComment_label=Add &Block Comment AddBlockComment_tooltip=Add Block Comment AddBlockComment_image= Index: src/org/eclipse/wst/sse/ui/internal/handlers/StructuredCommentHandlerHelpers.java =================================================================== RCS file: src/org/eclipse/wst/sse/ui/internal/handlers/StructuredCommentHandlerHelpers.java diff -N src/org/eclipse/wst/sse/ui/internal/handlers/StructuredCommentHandlerHelpers.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/org/eclipse/wst/sse/ui/internal/handlers/StructuredCommentHandlerHelpers.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,209 @@ +package org.eclipse.wst.sse.ui.internal.handlers; + +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.IRegion; +import org.eclipse.jface.text.ITextSelection; +import org.eclipse.jface.text.Position; +import org.eclipse.jface.text.TextSelection; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.ui.texteditor.ITextEditor; +import org.eclipse.wst.sse.ui.internal.Logger; + +/** + * Static helper functions for structured comment handlers. + */ +public class StructuredCommentHandlerHelpers { + /** + *

This method modifies the given document to place the given comment + * prefix at the given comment prefix offset and the given comment + * suffix at the given comment suffix offset. In the case of adding + * a line comment that does not have a suffix, pass null + * for the comment suffix and it and its associated offset will + * be ignored.

+ * + *

NOTE: it is a good idea if a model is at hand when calling this to + * warn the model of an impending update

+ * + * @param document the document to add the comment to + * @param commentPrefixOffset the offset of the comment prefix + * @param commentSuffixOffset the offset of the comment suffix + * (ignored if commentSuffix is null) + * @param commentPrefix the prefix of the comment to add at its associated given offset + * @param commentSuffix the suffix of the comment to add at its associated given offset, + * or null if there is not suffix to add for this comment + */ + protected static void comment(IDocument document, int commentPrefixOffset, int commentSuffixOffset, String commentPrefix, String commentSuffix) { + try { + + if(commentSuffix != null) { + document.replace(commentSuffixOffset, 0, commentSuffix); + } + document.replace(commentPrefixOffset, 0, commentPrefix); + removeEnclosedCommentPrefixesAndSuffixes(document, commentPrefixOffset, commentSuffixOffset - commentPrefixOffset, commentPrefix, commentSuffix); + } + catch (BadLocationException e) { + Logger.log(Logger.WARNING_DEBUG, e.getMessage(), e); + } + } + + /** + *

This method modifies the given document to remove the given comment + * prefix at the given comment prefix offset and the given comment + * suffix at the given comment suffix offset. In the case of removing + * a line comment that does not have a suffix, pass null + * for the comment suffix and it and its associated offset will + * be ignored.

+ * + *

NOTE: it is a good idea if a model is at hand when calling this to + * warn the model of an impending update

+ * + * @param document the document to remove the comment from + * @param commentPrefixOffset the offset of the comment prefix + * @param commentSuffixOffset the offset of the comment suffix + * (ignored if commentSuffix is null) + * @param commentPrefix the prefix of the comment to remove from its associated given offset + * @param commentSuffix the suffix of the comment to remove from its associated given offset, + * or null if there is not suffix to remove for this comment + */ + protected static void uncomment(IDocument document, int commentPrefixOffset, int commentSuffixOffset, String commentPrefix, String commentSuffix) { + try { + + document.replace(commentPrefixOffset, commentPrefix.length(), ""); //$NON-NLS-1$ + + if(commentSuffix != null) { + document.replace(commentSuffixOffset, commentSuffix.length(), ""); //$NON-NLS-1$ + } + + removeEnclosedCommentPrefixesAndSuffixes(document, commentPrefixOffset, commentSuffixOffset - commentPrefixOffset, commentPrefix, commentSuffix); + } + catch (BadLocationException e) { + Logger.log(Logger.WARNING_DEBUG, e.getMessage(), e); + } + } + + /** + * When commenting a region it is best to remove any already existing comments + * of the same comment format that will be inclosed by the region to be commented + * to avoid any overlap that may cause a comment to start or more likely end early. + * Thus the purpose of this method given an offset and a length will remove all + * occurrences of the given comment prefix and suffix from the range. The + * given offset should be the offset of where the new comment starts, the method + * will automatically leave the surrounding comment prefix and suffix. + * + * @param document the document to remove any extra comment prefixes or suffixes from + * @param commentPrefixOffset the offset of the newly added comment prefix + * @param commentLength the length of the newly commented region + * @param commentPrefix the comment prefix that should be removed if found in the newly commented range + * @param commentSuffix the comment suffix that should be removed if found in the newly commented range. + * This can be null if there is no comment suffix for this type of comment. + * + * @throws BadLocationException + */ + protected static void removeEnclosedCommentPrefixesAndSuffixes(IDocument document, int commentPrefixOffset, int commentLength, String commentPrefix, String commentSuffix) throws BadLocationException { + int innerOffset = commentPrefixOffset; + int innerLength = commentLength; + + //adjust the offset for the surrounding comment prefix + innerOffset += commentPrefix.length(); + + int adjustedLength = innerLength; + String string; + int index; + + // remove enclosed comment prefixes + string = document.get(innerOffset, innerLength); + index = string.lastIndexOf(commentPrefix); + while (index != -1) { + document.replace(innerOffset + index, commentPrefix.length(), ""); //$NON-NLS-1$ + index = string.lastIndexOf(commentPrefix, index - 1); + adjustedLength -= commentPrefix.length(); + } + + // remove enclosed comment suffixes + if(commentSuffix != null) { + string = document.get(innerOffset, adjustedLength); + index = string.lastIndexOf(commentSuffix); + while (index != -1) { + document.replace(innerOffset + index, commentSuffix.length(), ""); //$NON-NLS-1$ + index = string.lastIndexOf(commentSuffix, index - 1); + } + } + } + + /** + * Updates the current user selection in the given textEditor + * + * @param textEditor the text editor to set the user selection in + * @param selectionPosition the new user selection + * @param document the document the new user selection is in + */ + protected static void updateCurrentSelection(ITextEditor textEditor, Position selectionPosition, IDocument document) { + // update the selection if text selection changed + if (selectionPosition != null) { + ITextSelection selection = null; + + selection = new TextSelection(document, selectionPosition.getOffset(), selectionPosition.getLength()); + + ISelectionProvider provider = textEditor.getSelectionProvider(); + if (provider != null) { + provider.setSelection(selection); + } + document.removePosition(selectionPosition); + } + } + + /** + * Get the content of the given region in the given document + * + * @param document get the content of the given region from this + * @param region get the content of this from the given document + * @return the content of the given region from the given document + * @throws BadLocationException if the given region is not in the given document + */ + protected static String getRegionContent(IDocument document, IRegion region) throws BadLocationException { + return document.get(region.getOffset(), region.getLength()); + } + + /** + * Convenience method to determine if the given line + * starts with any of the given options. + * + * @param line the determine if this starts with any of the given options + * @param options check to see if the given line starts with any of these + * @return true if the given line + * starts with any of the given options, false otherwise. + */ + protected static String startsWith(String line, String[] options) { + String startsWith = null; + + for(int i = 0; i < options.length && startsWith == null; ++i) { + if( line.startsWith(options[i])) { + startsWith = options[i]; + } + } + + return startsWith; + } + + /** + * Convenience method to determine if the given line + * ends with any of the given options. + * + * @param line the determine if this ends with any of the given options + * @param options check to see if the given line ends with any of these + * @return true if the given line + * ends with any of the given options, false otherwise. + */ + protected static String endsWith(String line, String[] options) { + String endsWith = null; + + for(int i = 0; i < options.length && endsWith == null; ++i) { + if(line.endsWith(options[i])) { + endsWith = options[i]; + } + } + + return endsWith; + } +} Index: src/org/eclipse/wst/sse/ui/internal/handlers/AbstractStructuredCommentHandler.java =================================================================== RCS file: src/org/eclipse/wst/sse/ui/internal/handlers/AbstractStructuredCommentHandler.java diff -N src/org/eclipse/wst/sse/ui/internal/handlers/AbstractStructuredCommentHandler.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/org/eclipse/wst/sse/ui/internal/handlers/AbstractStructuredCommentHandler.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,601 @@ +/******************************************************************************* + * Copyright (c) 2009 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 + * + *******************************************************************************/ +package org.eclipse.wst.sse.ui.internal.handlers; + +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.jface.dialogs.ProgressMonitorDialog; +import org.eclipse.jface.operation.IRunnableWithProgress; +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.DocumentRewriteSession; +import org.eclipse.jface.text.DocumentRewriteSessionType; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.IDocumentExtension4; +import org.eclipse.jface.text.IRegion; +import org.eclipse.jface.text.ITextSelection; +import org.eclipse.jface.text.ITypedRegion; +import org.eclipse.jface.text.Position; +import org.eclipse.jface.text.Region; +import org.eclipse.jface.text.TextSelection; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.handlers.HandlerUtil; +import org.eclipse.ui.texteditor.ITextEditor; +import org.eclipse.wst.sse.core.StructuredModelManager; +import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel; +import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion; +import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegion; +import org.eclipse.wst.sse.ui.StructuredTextEditor; +import org.eclipse.wst.sse.ui.internal.Logger; +import org.eclipse.wst.sse.ui.internal.SSEUIMessages; +import org.eclipse.wst.sse.ui.internal.StructuredTextViewer; + +/** + * This class contains all of the shared functionality for structured comment handlers + */ +public abstract class AbstractStructuredCommentHandler extends AbstractHandler { + + /** + * Default constructor must exist because sub classes are created by java reflection + */ + public AbstractStructuredCommentHandler() { + super(); + } + + /** + *

Gets the important information out of the event and passes it onto + * the internal method processAction.

+ * + *

It is suggested that this function not be overridden and instead + * implementers should put all functionality in their implementation + * of processAction

+ * + * (non-Javadoc) + * @see org.eclipse.wst.xml.ui.internal.handlers.CommentHandler#execute(org.eclipse.core.commands.ExecutionEvent) + */ + public Object execute(ExecutionEvent event) throws ExecutionException { + IEditorPart editor = HandlerUtil.getActiveEditor(event); + ITextEditor textEditor = null; + if (editor instanceof ITextEditor) + textEditor = (ITextEditor) editor; + else { + Object o = editor.getAdapter(ITextEditor.class); + if (o != null) + textEditor = (ITextEditor) o; + } + if (textEditor != null) { + IDocument document = textEditor.getDocumentProvider().getDocument(textEditor.getEditorInput()); + if (document != null) { + // get current text selection + ITextSelection textSelection = getCurrentSelection(textEditor); + if (textSelection.isEmpty()) { + return null; + } + + //call the implementers code to deal with the event + processAction(textEditor, document, textSelection); + } + } + return null; + } + + /** + * This method is called by the public execute method whenever the comment handler + * is invoked. This method should be used for the logic of handling the + * structured comment event + * + * @param textEditor the text editor the initiating event was caused in + * @param document the document the text editor is editing + * @param textSelection the user selection when the event was caused + */ + protected abstract void processAction(ITextEditor textEditor, IDocument document, ITextSelection textSelection); + + /** + * Given a list of partition types in a user selection should return + * the appropriate line comment prefix, or null if there is not one + * + * @param types the partition types in the user selection + * @return the appropriate line comment prefix, or null if there is not one + */ + protected abstract String getLineCommentPrefix(ITypedRegion[] regions); + + /** + *

Given a list of typed regions in a user selection should return + * the appropriate block comment prefix, or null if there is not one.

+ * + *

IMPORTANT: If there is a block comment prefix for a list of types there + * should also be a block comment suffix for that same list of types

+ * + * @param regions the typed regions in the user selection + * @return the appropriate block comment prefix, or null if there is not one + */ + protected abstract String getBlockCommentPrefix(ITypedRegion[] regions); + + /** + *

Given a list of typed regions in a user selection should return + * the appropriate block comment suffix, or null if there is not one.

+ * + *

IMPORTANT: If there is a block comment prefix returned by + * getBlockCommentPrefix then this method needs to return + * the appropriate block comment suffix for the prefix that + * getBlockCommentPrefix would return if invoked.

+ * + * @param types the typed regions in the user selection + * @return the appropriate block comment suffix, or null if there is not one + */ + protected abstract String getBlockCommentSuffix(ITypedRegion[] regions); + + /** + * Should return all possible comment suffixes that could + * possible appear in the document type that this handler + * is being implemented for. This includes both + * line and block comment prefixes. + * + * @return all possible comment prefixes + */ + protected abstract String[] getPossibleCommentPrefixes(); + + /** + * Should return all possible comment suffixes that could + * possible appear in the document type that this handler + * is being implemented for. + * + * @return all possible comment suffixes + */ + protected abstract String[] getPossibleCommentSuffixes(); + + /** + * Should return all partition types that represent commented + * partitions for the document type that this handler is being + * implemented for + * + * @return all partition types that represent commented partitions + */ + protected abstract String[] getCommentPartitionTypes(); + + + + /** + * Determines if all of the given typed regions are comment regions. + * This is useful for deciding if an entire user highlighted region + * is already commented or not. + * + * @param regions the typed regions to check to see if they are all comment regions + * @return true if all of the given regions are comment regions + * false otherwise. + */ + protected boolean isEntireRegionCommented(ITypedRegion[] regions) { + String[] commentTypes = getCommentPartitionTypes(); + boolean alreadyCommented = regions.length > 0 && commentTypes.length > 0; + + for(int type = 0; type < regions.length && alreadyCommented; ++type) { + alreadyCommented &= isTypeCommentType(regions[type].getType()); + } + + return alreadyCommented; + } + + /** + * Given typed regions returns a list of only those who's partition type + * is a comment partition type. This is useful for finding already commented + * regions in a user selection. + * + * @param typedRegions the regions to find those regions that who's + * partition type is a comment partition type + * @return a List of the ITypedRegions who's type + * is a comment partition type + */ + protected List getCommentedRegions(ITypedRegion[] typedRegions) { + List commentedRegions = new ArrayList(); + + for(int i = 0; i < typedRegions.length; ++i) { + if(isTypeCommentType(typedRegions[i].getType())) { + commentedRegions.add(typedRegions[i]); + } + } + + return commentedRegions; + } + + /** + * Determine if the given partition type is a comment partition type + * + * @param type check to see if this partition type is a comment partition type + * @return true if the given type is a comment partition type, + * false otherwise. + */ + private boolean isTypeCommentType(String type) { + String[] commentTypes = getCommentPartitionTypes(); + boolean isCommentType = false; + + for(int commentType = 0; commentType < commentTypes.length && !isCommentType; ++commentType) { + isCommentType |= (type == commentTypes[commentType]); + } + + return isCommentType; + } + + /** + * Gets the current user selection in the given textEditor + * + * @param textEditor get the user selection from here + * @return the current user selection in textEdtior + */ + private static ITextSelection getCurrentSelection(ITextEditor textEditor) { + ISelectionProvider provider = textEditor.getSelectionProvider(); + if (provider != null) { + ISelection selection = provider.getSelection(); + if (selection instanceof ITextSelection) { + return (ITextSelection) selection; + } + } + return TextSelection.emptySelection(); + } + + /** + * if toggling more then this many lines then use a busy indicator + */ + private static final int TOGGLE_LINES_MAX_NO_BUSY_INDICATOR = 10; + + /** + * Adds a block comment to the given text selection based on the types in the text selection + * using the given handler + * + * @param handler the AbstractStructuredCommentHandler to use for adding the comment block + * @param textEditor the editor to add the comment block to + * @param document the document the textEditor is editing + * @param textSelection the user selection in the given textEditor to add a commenting block to + * + * @throws BadLocationException if something goes wrong with placing the new block comment + * prefix and suffix this exception will be thrown. + * + * @see org.eclipse.wst.sse.ui.internal.handlers.AbstractStructuredCommentHandler#processAction(org.eclipse.ui.texteditor.ITextEditor, org.eclipse.jface.text.IDocument, org.eclipse.jface.text.ITextSelection) + */ + protected void processAddBlockCommentAction(AbstractStructuredCommentHandler handler, ITextEditor textEditor, IDocument document, ITextSelection textSelection) throws BadLocationException { + IStructuredModel model = StructuredModelManager.getModelManager().getExistingModelForEdit(document); + if (model != null) { + try { + IRegion region = new Region(textSelection.getOffset(), textSelection.getLength()); + String regionContent = StructuredCommentHandlerHelpers.getRegionContent(document, region); + String commentPrefix = StructuredCommentHandlerHelpers.startsWith(regionContent, handler.getPossibleCommentPrefixes()); + + ITypedRegion[] typedRegions = document.computePartitioning(region.getOffset(), region.getLength()); + + boolean alreadyCommented = handler.isEntireRegionCommented(typedRegions); + + //if selection not already commented + if(commentPrefix == null && !alreadyCommented) { + commentPrefix = handler.getBlockCommentPrefix(typedRegions); + String commentSuffix = handler.getBlockCommentSuffix(typedRegions); + + int commentPrefixOffset = region.getOffset(); + int commentSuffixOffset = commentPrefixOffset + region.getLength() + commentPrefix.length(); + + model.aboutToChangeModel(); + StructuredCommentHandlerHelpers.comment(document, commentPrefixOffset, commentSuffixOffset, commentPrefix, commentSuffix); + } + } finally { + model.changedModel(); + model.releaseFromEdit(); + } + } + } + + /** + * Removes all block comments from the given text selection using the given handler + * + * @param handler the AbstractStructuredCommentHandler to use for removing the comment block + * @param textEditor the editor to remove the comment block from + * @param document the document the textEditor is editing + * @param textSelection the user selection in the given textEditor + * to remove the commenting block from + * + * @throws BadLocationException if something goes wrong with finding the new block comment + * prefix and suffix to remove this exception will be thrown. This is not thrown if the user + * selection is not in a comment block and they request to remove a non-existing comment block, + * it is only thrown if a request is made in a valid comment block but for some reason the prefix + * and or suffix can not be found and/or removed. + * + * @see org.eclipse.wst.sse.ui.internal.handlers.AbstractStructuredCommentHandler#processAction(org.eclipse.ui.texteditor.ITextEditor, org.eclipse.jface.text.IDocument, org.eclipse.jface.text.ITextSelection) + */ + protected void processRemoveBlockCommentAction(ITextEditor textEditor, IDocument document, ITextSelection textSelection) throws BadLocationException { + IStructuredModel model = StructuredModelManager.getModelManager().getExistingModelForEdit(document); + if (model != null) { + try { + IRegion region = new Region(textSelection.getOffset(), textSelection.getLength()); + + ITypedRegion[] typedRegions = document.computePartitioning(region.getOffset(), region.getLength()); + List commentRegions = getCommentedRegions(typedRegions); + + //remove in reverse order as to not effect offset of other regions + model.aboutToChangeModel(); + for(int i = commentRegions.size()-1; i >= 0; --i) { + ITypedRegion typedRegion = (ITypedRegion)commentRegions.get(i); + IRegion commentRegion = new Region(typedRegion.getOffset(), typedRegion.getLength()); + + String regionContent = StructuredCommentHandlerHelpers.getRegionContent(document, commentRegion); + String commentPrefix = StructuredCommentHandlerHelpers.startsWith(regionContent, getPossibleCommentPrefixes()); + String commentSuffix = StructuredCommentHandlerHelpers.endsWith(regionContent, getPossibleCommentSuffixes()); + + /*if the user did not highlight the entire region with the comment then we + *need to ask the model for the structured region that the user selected + *in to find the opening and closing comment blocks to remove + */ + if(commentPrefix == null || commentSuffix == null) { + IStructuredDocumentRegion structuredRegion = + model.getStructuredDocument().getRegionAtCharacterOffset( + typedRegion.getOffset()); + + commentRegion = new Region(structuredRegion.getStartOffset(), structuredRegion.getLength()); + + regionContent = StructuredCommentHandlerHelpers.getRegionContent(document, commentRegion); + commentPrefix = StructuredCommentHandlerHelpers.startsWith(regionContent, getPossibleCommentPrefixes()); + commentSuffix = StructuredCommentHandlerHelpers.endsWith(regionContent, getPossibleCommentSuffixes()); + + /*if still can't find prefix or suffix maybe the comment region is an enclosed region in + * the returned region. + */ + if(commentPrefix == null || commentSuffix == null) { + ITextRegion enclosedRegion = structuredRegion.getRegionAtCharacterOffset(typedRegion.getOffset()); + int enclosedOffset = structuredRegion.getStartOffset(enclosedRegion); + commentRegion = new Region(enclosedOffset, structuredRegion.getTextEndOffset(enclosedRegion)-enclosedOffset); + + regionContent = StructuredCommentHandlerHelpers.getRegionContent(document, commentRegion); + commentPrefix = StructuredCommentHandlerHelpers.startsWith(regionContent, getPossibleCommentPrefixes()); + commentSuffix = StructuredCommentHandlerHelpers.endsWith(regionContent, getPossibleCommentSuffixes()); + } + } + + //if found the comment prefix and suffix then uncomment, otherwise log error + if(commentPrefix != null && commentSuffix != null) { + int commentPrefixOffset = commentRegion.getOffset() + regionContent.indexOf(commentPrefix); + int commentSuffixOffset = commentRegion.getOffset() - commentPrefix.length(); + commentSuffixOffset += regionContent.lastIndexOf(commentSuffix); + + //remove comment block + StructuredCommentHandlerHelpers.uncomment(document, commentPrefixOffset, commentSuffixOffset, commentPrefix, commentSuffix); + } else { + throw new BadLocationException("Could not find comment prefix and or suffix to uncomment");//$NON-NLS-1$ + } + } + } + finally { + model.changedModel(); + model.releaseFromEdit(); + } + } + } + + + /** + * Break the selection down into lines and toggle the commenting for each line using the given handler + * + * @param handler the AbstractStructuredCommentHandler to use for toggling commenting + * @param textEditor the editor to toggle commenting in + * @param document the document the textEditor is editing + * @param textSelection the user selection in the given textEditor to toggle commenting in + * + * @throws BadLocationException if something goes wrong with placing or removing the commenting + * this exception will be thrown. + * + * @see org.eclipse.jst.jsp.ui.internal.handlers.AbstractJSPCommentHandler#processAction(org.eclipse.ui.texteditor.ITextEditor, org.eclipse.jface.text.IDocument, org.eclipse.jface.text.ITextSelection) + */ + protected void processToggleCommentAction(ITextEditor textEditor, IDocument document, ITextSelection textSelection) throws BadLocationException { + // get text selection lines info + int selectionStartLine = textSelection.getStartLine(); + int selectionEndLine = textSelection.getEndLine(); + + int selectionEndLineOffset = document.getLineOffset(selectionEndLine); + int selectionEndOffset = textSelection.getOffset() + textSelection.getLength(); + + // adjust selection end line + if ((selectionEndLine > selectionStartLine) && (selectionEndLineOffset == selectionEndOffset)) { + selectionEndLine--; + } + + // save the selection position since it will be changing + Position selectionPosition = null; + selectionPosition = new Position(textSelection.getOffset(), textSelection.getLength()); + document.addPosition(selectionPosition); + + //get the display for the editor if we can + Display display = null; + if(textEditor instanceof StructuredTextEditor) { + StructuredTextViewer viewer = ((StructuredTextEditor)textEditor).getTextViewer(); + if(viewer != null) { + display = viewer.getControl().getDisplay(); + } + } + + //toggle each line + processToggleCommentAction(document, selectionStartLine, selectionEndLine, display); + + StructuredCommentHandlerHelpers.updateCurrentSelection(textEditor, selectionPosition, document); + } + + /** + * + * For all of the lines between selectionStartLine and selectionEndLine + * inclusive, toggle the commenting on that line. + * + * @param handler the AbstractStructuredCommentHandler to use for toggling commenting + * @param document the document to toggle the commenting in + * @param selectionStartLine the first line to start comment toggling + * @param selectionEndLine the last line to comment toggle + * @param display the display to display busy information on + * + * @throws BadLocationException + */ + private void processToggleCommentAction(final IDocument document, final int selectionStartLine, final int selectionEndLine, final Display display) throws BadLocationException { + IStructuredModel model = StructuredModelManager.getModelManager().getExistingModelForEdit(document); + if (model != null) { + DocumentRewriteSession session = null; + try { + /* notify listeners a bunch of changes are about to happen, + * so wait until they are all done to react. + */ + model.aboutToChangeModel(); + if(document instanceof IDocumentExtension4) { + session = ((IDocumentExtension4)document).startRewriteSession(DocumentRewriteSessionType.UNRESTRICTED); + } + + //create our toggling operation + IRunnableWithProgress toggleCommentsRunnable = new IRunnableWithProgress() { + public void run(IProgressMonitor monitor) { + //start work + monitor.beginTask(SSEUIMessages.ToggleComment_progress, selectionEndLine-selectionStartLine); + try { + //toggle each line so long as task not canceled + for (int line = selectionStartLine; line <= selectionEndLine && !monitor.isCanceled(); ++line) { + //allows the user to be able to click the cancel button + readAndDispatch(display); + + //get the line region + IRegion lineRegion = document.getLineInformation(line); + + //don't toggle empty lines + String content = StructuredCommentHandlerHelpers.getRegionContent(document, lineRegion); + if (content.trim().length() > 0) { + //toggle the commenting on the line + toggleLineComment(document, lineRegion); + } + monitor.worked(1); + } + } catch(BadLocationException e) { + Logger.logException("Bad location while toggling comments.", e); //$NON-NLS-1$ + } + //done work + monitor.done(); + } + }; + + //if toggling more then TOGGLE_LINES_MAX_NO_BUSY_INDICATOR then use progress monitor + //else just run the operation + if((selectionEndLine - selectionStartLine) > TOGGLE_LINES_MAX_NO_BUSY_INDICATOR) { + ProgressMonitorDialog dialog = new ProgressMonitorDialog(display.getActiveShell()); + dialog.run(false, true, toggleCommentsRunnable); + } else { + toggleCommentsRunnable.run(new NullProgressMonitor()); + } + } catch (InvocationTargetException e) { + Logger.logException("Problem running toggle comment progess dialog.", e); //$NON-NLS-1$ + } catch (InterruptedException e) { + Logger.logException("Problem running toggle comment progess dialog.", e); //$NON-NLS-1$ + } + finally { + //clean everything up + if(document instanceof IDocumentExtension4) { + ((IDocumentExtension4)document).stopRewriteSession(session); + } + model.changedModel(); + model.releaseFromEdit(); + } + } + } + + /** + *

Given a document and a region representing one line in that document + * comments that line if it is not commented or un-comments it if it is + * already commented. When commenting an uncommented line it will first + * try to use a line only comment, if there is not a line only comment + * prefix appropriate for the given region then it will surround the line + * with a block comment.

+ * + *

NOTE: it is a good idea if a model is at hand when calling this to + * warn the model of an impending update

+ * + * @param handler the AbstractStructuredCommentHandler to use for toggling commenting + * @param document the document with the line to be commented or uncommented + * @param lineRegion the region representing the line to be commented or uncommented + * + * @throws BadLocationException thrown if the given region is a bad location in the given document + */ + protected void toggleLineComment(IDocument document, IRegion lineRegion) throws BadLocationException { + + String regionContent = StructuredCommentHandlerHelpers.getRegionContent(document, lineRegion); + String openComment = StructuredCommentHandlerHelpers.startsWith(regionContent, getPossibleCommentPrefixes()); + String closeComment = StructuredCommentHandlerHelpers.endsWith(regionContent, getPossibleCommentSuffixes()); + + //if there is an opening comment then remove comment + //else add comment + if (openComment != null) { + String lineContent = document.get(lineRegion.getOffset(), lineRegion.getLength()); + int openCommentOffset = lineRegion.getOffset() + lineContent.indexOf(openComment); + int closeCommentOffset = lineRegion.getOffset() - openComment.length(); + if(closeComment != null) { + closeCommentOffset += lineContent.lastIndexOf(closeComment); + } + StructuredCommentHandlerHelpers.uncomment(document, openCommentOffset, closeCommentOffset, openComment, closeComment); + } + else { + ITypedRegion[] typedRegions = document.computePartitioning(lineRegion.getOffset(), lineRegion.getLength()); + + openComment = getLineCommentPrefix(typedRegions); + closeComment = null; + + //if there is no line comment prefix then use a block comment + if(openComment == null) { + openComment = getBlockCommentPrefix(typedRegions); + closeComment = getBlockCommentSuffix(typedRegions); + } + + //add the comment prefix & suffix + int commentPrefixOffset = lineRegion.getOffset(); + int commentSuffixOffset = commentPrefixOffset + lineRegion.getLength(); + StructuredCommentHandlerHelpers.comment(document, commentPrefixOffset, commentSuffixOffset, openComment, closeComment); + } + } + + /** + *

When calling {@link Display#readAndDispatch()} the game is off as to whose code you maybe + * calling into because of event handling/listeners/etc. The only important thing is that + * we given the UI a chance to react to user clicks. Thus we log most {@link Exception}s and + * {@link Error}s as caused by {@link Display#readAndDispatch()} because they are not caused + * by this code and do not effect it.

+ * + * @param display the {@link Display} to call readAndDispatch + * on with exception/error handling. + */ + private static void readAndDispatch(Display display) { + try { + display.readAndDispatch(); + } + catch (Exception e) { + Logger.log(Logger.WARNING, "Exception caused by readAndDispatch, not caused by or fatal to caller", e); + } + catch (LinkageError e) { + Logger.log(Logger.WARNING, "LinkageError caused by readAndDispatch, not caused by or fatal to caller", e); + } + catch (VirtualMachineError e) { + // rethrow these + throw e; + } + catch (ThreadDeath e) { + // rethrow these + throw e; + } + catch (Error e) { + // catch every error, except for a few that we don't want to + // handle + Logger.log(Logger.WARNING, "Error caused by readAndDispatch, not caused by or fatal to caller", e); + } + } +} #P org.eclipse.wst.xml.ui Index: plugin.xml =================================================================== RCS file: /cvsroot/webtools/sourceediting/plugins/org.eclipse.wst.xml.ui/plugin.xml,v retrieving revision 1.109 diff -u -r1.109 plugin.xml --- plugin.xml 26 Aug 2009 20:50:25 -0000 1.109 +++ plugin.xml 14 Sep 2009 20:14:21 -0000 @@ -1179,7 +1179,7 @@ @@ -1189,7 +1189,7 @@ @@ -1199,7 +1199,7 @@ Index: src/org/eclipse/wst/xml/ui/internal/handlers/CommentHandler.java =================================================================== RCS file: src/org/eclipse/wst/xml/ui/internal/handlers/CommentHandler.java diff -N src/org/eclipse/wst/xml/ui/internal/handlers/CommentHandler.java --- src/org/eclipse/wst/xml/ui/internal/handlers/CommentHandler.java 27 Mar 2008 02:58:48 -0000 1.2 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,103 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2008 Standards for Technology in Automotive Retail 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: - * David Carver - initial API and implementation, bug 212330 - * - *******************************************************************************/ -package org.eclipse.wst.xml.ui.internal.handlers; - -import org.eclipse.core.commands.AbstractHandler; -import org.eclipse.core.commands.ExecutionEvent; -import org.eclipse.core.commands.ExecutionException; -import org.eclipse.core.commands.IHandler; -import org.eclipse.jface.text.BadLocationException; -import org.eclipse.jface.text.IDocument; -import org.eclipse.jface.text.ITextSelection; -import org.eclipse.jface.text.TextSelection; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.ISelectionProvider; -import org.eclipse.ui.IEditorPart; -import org.eclipse.ui.handlers.HandlerUtil; -import org.eclipse.ui.texteditor.ITextEditor; -import org.eclipse.wst.xml.ui.internal.Logger; - -public class CommentHandler extends AbstractHandler implements IHandler { - static final String CLOSE_COMMENT = "-->"; //$NON-NLS-1$ - static final String OPEN_COMMENT = ""; //$NON-NLS-1$ + + private static final String[] POSSIBLE_COMMENT_PREFIXES = { + XML_BLOCK_COMMENT_PREFIX + }; + + private static final String[] POSSIBLE_COMMENT_SUFFIXES = { + XML_BLOCK_COMMENT_SUFFIX + }; + + private static final String[] XML_COMMENT_PARTITION_TYPES = { + IXMLPartitions.XML_COMMENT + }; + + /** + * Default constructor must exist because sub classes are created by java reflection + */ + public AbstractXMLCommentHandler() { + super(); + } + + /** + * There are no line comments in XML + * + * (non-Javadoc) + * @see org.eclipse.wst.sse.ui.internal.handlers.AbstractStructuredCommentHandler#getLineCommentPrefix(java.util.List) + */ + protected String getLineCommentPrefix(ITypedRegion[] regions) { + return null; + } + + /** + * There is only one type of start comment in XML + * + * (non-Javadoc) + * @see org.eclipse.wst.sse.ui.internal.handlers.AbstractStructuredCommentHandler#getBlockCommentPrefix(java.util.List) + */ + protected String getBlockCommentPrefix(ITypedRegion[] regions) { + return XML_BLOCK_COMMENT_PREFIX; + } + + /** + * There is only one type of comment suffix in XML + * + * (non-Javadoc) + * @see org.eclipse.wst.sse.ui.internal.handlers.AbstractStructuredCommentHandler#getBlockCommentSuffix(java.util.List) + */ + protected String getBlockCommentSuffix(ITypedRegion[] regions) { + return XML_BLOCK_COMMENT_SUFFIX; + } + + /** + * @see org.eclipse.wst.sse.ui.internal.handlers.AbstractStructuredCommentHandler#getPossibleCommentOpenings() + */ + protected String[] getPossibleCommentPrefixes() { + return POSSIBLE_COMMENT_PREFIXES; + } + + /** + * @see org.eclipse.wst.sse.ui.internal.handlers.AbstractStructuredCommentHandler#getPossibleCommentClosings() + */ + protected String[] getPossibleCommentSuffixes() { + return POSSIBLE_COMMENT_SUFFIXES; + } + + /** + * @see org.eclipse.wst.sse.ui.internal.handlers.AbstractStructuredCommentHandler#getCommentTypes() + */ + protected String[] getCommentPartitionTypes() { + return XML_COMMENT_PARTITION_TYPES; + } +} Index: src/org/eclipse/wst/xml/ui/internal/handlers/AddXMLBlockCommentHandler.java =================================================================== RCS file: src/org/eclipse/wst/xml/ui/internal/handlers/AddXMLBlockCommentHandler.java diff -N src/org/eclipse/wst/xml/ui/internal/handlers/AddXMLBlockCommentHandler.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/org/eclipse/wst/xml/ui/internal/handlers/AddXMLBlockCommentHandler.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright (c) 2008, 2009 Standards for Technology in Automotive Retail 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: + * David Carver - initial API and implementation, bug 212330 + * IBM Corporation - additional contributions + * + *******************************************************************************/ +package org.eclipse.wst.xml.ui.internal.handlers; + +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.ITextSelection; +import org.eclipse.ui.texteditor.ITextEditor; +import org.eclipse.wst.xml.ui.internal.Logger; + +/** + * The handler used to add a block comment to an XML file + */ +public class AddXMLBlockCommentHandler extends AbstractXMLCommentHandler { + + /** + * Default constructor must exist because sub classes are created by java reflection + */ + public AddXMLBlockCommentHandler() { + super(); + } + + /** + * Adds a block comment to the given text selection based on the types in the text selection + * + * @see org.eclipse.wst.sse.ui.internal.handlers.AbstractStructuredCommentHandler#processAction(org.eclipse.ui.texteditor.ITextEditor, org.eclipse.jface.text.IDocument, org.eclipse.jface.text.ITextSelection) + */ + protected void processAction(ITextEditor textEditor, IDocument document, ITextSelection textSelection) { + try { + processAddBlockCommentAction(this, textEditor, document, textSelection); + } catch (BadLocationException e) { + Logger.log(Logger.WARNING, e.getMessage(), e); + } + } +}