View | Details | Raw Unified | Return to bug 86520 | Differences between
and this patch

Collapse All | Expand All

(-)src/org/eclipse/wst/sse/ui/internal/Logger.java (-3 / +21 lines)
Lines 1-5 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2001, 2006 IBM Corporation and others.
2
 * Copyright (c) 2001, 2010 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
Lines 75-84 Link Here
75
		}
75
		}
76
		message = (message != null) ? message : "null"; //$NON-NLS-1$
76
		message = (message != null) ? message : "null"; //$NON-NLS-1$
77
		Status statusObj = new Status(severity, PLUGIN_ID, severity, message, exception);
77
		Status statusObj = new Status(severity, PLUGIN_ID, severity, message, exception);
78
		_log(statusObj);
79
	}
80
	
81
	/**
82
	 * Adds {@link IStatus} to the log.
83
	 * 
84
	 * @param statusObj {@link IStatus} to add to the log
85
	 */
86
	protected static void _log(IStatus statusObj) {
78
		Bundle bundle = Platform.getBundle(PLUGIN_ID);
87
		Bundle bundle = Platform.getBundle(PLUGIN_ID);
79
		if (bundle != null) 
88
		if (bundle != null) {
80
			Platform.getLog(bundle).log(statusObj);
89
			Platform.getLog(bundle).log(statusObj);
81
90
		}
82
	}
91
	}
83
92
84
	/**
93
	/**
Lines 138-143 Link Here
138
	public static void log(int level, String message, Throwable exception) {
147
	public static void log(int level, String message, Throwable exception) {
139
		_log(level, message, exception);
148
		_log(level, message, exception);
140
	}
149
	}
150
	
151
	/**
152
	 * <p>Allows an already constructed status to be logged</p>
153
	 * 
154
	 * @param status {@link IStatus} to log.
155
	 */
156
	public static void log(IStatus status) {
157
		_log(status);
158
	}
141
159
142
	public static void logException(String message, Throwable exception) {
160
	public static void logException(String message, Throwable exception) {
143
		_log(ERROR, message, exception);
161
		_log(ERROR, message, exception);
(-)src/org/eclipse/wst/sse/ui/internal/SSEUIMessages.java (+1 lines)
Lines 90-95 Link Here
90
	public static String ToggleComment_tooltip;
90
	public static String ToggleComment_tooltip;
91
	public static String ToggleComment_image;
91
	public static String ToggleComment_image;
92
	public static String ToggleComment_description;
92
	public static String ToggleComment_description;
93
	public static String ToggleComment_progress;
93
	public static String AddBlockComment_label;
94
	public static String AddBlockComment_label;
94
	public static String AddBlockComment_tooltip;
95
	public static String AddBlockComment_tooltip;
95
	public static String AddBlockComment_image;
96
	public static String AddBlockComment_image;
(-)src/org/eclipse/wst/sse/ui/internal/SSEUIPluginResources.properties (+1 lines)
Lines 62-67 Link Here
62
ToggleComment_tooltip=Toggle Comment
62
ToggleComment_tooltip=Toggle Comment
63
ToggleComment_image=
63
ToggleComment_image=
64
ToggleComment_description=Toggle Comment
64
ToggleComment_description=Toggle Comment
65
ToggleComment_progress=Toggling line comments...
65
AddBlockComment_label=Add &Block Comment
66
AddBlockComment_label=Add &Block Comment
66
AddBlockComment_tooltip=Add Block Comment
67
AddBlockComment_tooltip=Add Block Comment
67
AddBlockComment_image=
68
AddBlockComment_image=
(-)plugin.xml (-1 / +49 lines)
Lines 519-524 Link Here
519
		id="quickFixProcessor" 
519
		id="quickFixProcessor" 
520
		name="%quickFixProcessor" 
520
		name="%quickFixProcessor" 
521
		schema="schema/quickFixProcessor.exsd"/>
521
		schema="schema/quickFixProcessor.exsd"/>
522
 <extension-point id="commentingStrategy" name="%Commenting_Strategy_Extension.name" schema="schema/commentingStrategy.exsd"/>
522
 
523
 
523
	<extension point="org.eclipse.ui.menus">
524
	<extension point="org.eclipse.ui.menus">
524
		<menuContribution locationURI="menu:org.eclipse.ui.main.menu?after=edit">
525
		<menuContribution locationURI="menu:org.eclipse.ui.main.menu?after=edit">
Lines 647-654 Link Here
647
			</command>
648
			</command>
648
		</menuContribution>
649
		</menuContribution>
649
650
650
	     <menuContribution
651
		<menuContribution
651
	           locationURI="popup:sourcePopupMenuId?after=sourceBegin">
652
	           locationURI="popup:sourcePopupMenuId?after=sourceBegin">
653
			<command
654
					commandId="org.eclipse.wst.sse.ui.toggle.comment"
655
					id="ToggleComment"
656
					style="push">
657
				<visibleWhen checkEnabled="false">
658
					<reference definitionId="org.eclipse.wst.sse.ui.sseActiveContext.definition"></reference>
659
				</visibleWhen>
660
			</command>
661
			<command commandId="org.eclipse.wst.sse.ui.add.block.comment" id="AddBlockComment" style="push">
662
				<visibleWhen checkEnabled="false">
663
					<reference definitionId="org.eclipse.wst.sse.ui.sseActiveContext.definition"></reference>
664
				</visibleWhen>
665
			</command>
666
			<command commandId="org.eclipse.wst.sse.ui.remove.block.comment" id="RemoveBlockComment" style="push">
667
				<visibleWhen checkEnabled="false">
668
					<reference definitionId="org.eclipse.wst.sse.ui.sseActiveContext.definition"></reference>
669
				</visibleWhen>
670
			</command>
671
			<separator name="format" visible="true"></separator>
652
				<command
672
				<command
653
			           commandId="org.eclipse.wst.sse.ui.cleanup.document"
673
			           commandId="org.eclipse.wst.sse.ui.cleanup.document"
654
			           id="CleanupDocument"
674
			           id="CleanupDocument"
Lines 677-682 Link Here
677
				</command>
697
				</command>
678
				
698
				
679
	     </menuContribution>
699
	     </menuContribution>
700
			<menuContribution locationURI="menu:sourceMenuId?after=sourceBegin">
701
				<command commandId="org.eclipse.wst.sse.ui.toggle.comment"
702
						id="ToggleComment"
703
				    mnemonic="%command.toggle.comment.mnemonic"
704
				    style="push">
705
					<visibleWhen checkEnabled="false">
706
						<reference definitionId="org.eclipse.wst.sse.ui.sseActiveContext.definition"/>
707
					</visibleWhen>
708
				</command>
709
				<command commandId="org.eclipse.wst.sse.ui.add.block.comment"
710
						id="AddBlockComment"
711
				    mnemonic="%command.add.block.comment.mnemonic"
712
				    style="push">
713
					<visibleWhen checkEnabled="false">
714
						<reference definitionId="org.eclipse.wst.sse.ui.sseActiveContext.definition"/>
715
					</visibleWhen>
716
				</command>
717
				<command commandId="org.eclipse.wst.sse.ui.remove.block.comment"
718
						id="RemoveBlockComment"
719
						mnemonic="%command.remove.block.comment.mnemonic"
720
						style="push">
721
					<visibleWhen checkEnabled="false">
722
						<reference definitionId="org.eclipse.wst.sse.ui.sseActiveContext.definition"/>
723
					</visibleWhen>
724
				</command>
725
				</menuContribution>
726
				
727
680
	</extension>
728
	</extension>
681
	<extension
729
	<extension
682
       point="org.eclipse.ui.commands">
730
       point="org.eclipse.ui.commands">
(-)plugin.properties (+8 lines)
Lines 28-38 Link Here
28
quickFixProcessor=Quick Fix Processor Extension
28
quickFixProcessor=Quick Fix Processor Extension
29
Semantic_Highlighting_Extension.name=Semantic Highlighting Extension
29
Semantic_Highlighting_Extension.name=Semantic Highlighting Extension
30
Character_Pairing.name=Character Pairing Extension
30
Character_Pairing.name=Character Pairing Extension
31
Commenting_Strategy_Extension.name=Commenting Strategy Extension
31
##########################################################################
32
##########################################################################
32
# These strings are used in Workbench Keys Preferences
33
# These strings are used in Workbench Keys Preferences
33
##########################################################################
34
##########################################################################
34
scope.structuredTextEditor.name=Editing in Structured Text Editors
35
scope.structuredTextEditor.name=Editing in Structured Text Editors
35
scope.structuredTextEditor.description=Editing in Structured Text Editors
36
scope.structuredTextEditor.description=Editing in Structured Text Editors
37
scope.structuredTextEditor.comments.description=Source Comments in Structured Text Editors
38
scope.structuredTextEditor.comments.name=Source Comments in Structured Text Editors
36
command.toggle.comment.name=Toggle Comment
39
command.toggle.comment.name=Toggle Comment
37
command.toggle.comment.description=Toggle Comment
40
command.toggle.comment.description=Toggle Comment
38
command.add.block.comment.name=Add Block Comment
41
command.add.block.comment.name=Add Block Comment
Lines 105-107 Link Here
105
Colors.content_assist_proposals_foreground=Content Assist Proposals Foreground
108
Colors.content_assist_proposals_foreground=Content Assist Proposals Foreground
106
Colors.content_assist_parameters_background=Content Assist Parameters Background
109
Colors.content_assist_parameters_background=Content Assist Parameters Background
107
Colors.content_assist_parameters_foreground=Content Assist Parameters Foreground
110
Colors.content_assist_parameters_foreground=Content Assist Parameters Foreground
111
112
# Menu contributions
113
command.toggle.comment.mnemonic=T
114
command.add.block.comment.mnemonic=A
115
command.remove.block.comment.mnemonic=Rs
(-)META-INF/MANIFEST.MF (+1 lines)
Lines 7-12 Link Here
7
Bundle-Vendor: %providerName
7
Bundle-Vendor: %providerName
8
Bundle-Localization: plugin
8
Bundle-Localization: plugin
9
Export-Package: org.eclipse.wst.sse.ui,
9
Export-Package: org.eclipse.wst.sse.ui,
10
 org.eclipse.wst.sse.ui.handlers,
10
 org.eclipse.wst.sse.ui.internal;x-friends:="org.eclipse.wst.dtd.ui,org.eclipse.wst.xml.ui,org.eclipse.wst.xsd.ui",
11
 org.eclipse.wst.sse.ui.internal;x-friends:="org.eclipse.wst.dtd.ui,org.eclipse.wst.xml.ui,org.eclipse.wst.xsd.ui",
11
 org.eclipse.wst.sse.ui.internal.actions;x-friends:="org.eclipse.wst.dtd.ui,org.eclipse.wst.xml.ui,org.eclipse.wst.xsd.ui",
12
 org.eclipse.wst.sse.ui.internal.actions;x-friends:="org.eclipse.wst.dtd.ui,org.eclipse.wst.xml.ui,org.eclipse.wst.xsd.ui",
12
 org.eclipse.wst.sse.ui.internal.contentassist;x-friends:="org.eclipse.wst.dtd.ui,org.eclipse.wst.xml.ui,org.eclipse.wst.xsd.ui",
13
 org.eclipse.wst.sse.ui.internal.contentassist;x-friends:="org.eclipse.wst.dtd.ui,org.eclipse.wst.xml.ui,org.eclipse.wst.xsd.ui",
(-)src/org/eclipse/wst/sse/ui/internal/handlers/AbstractCommentHandler.java (+96 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2010 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * 
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *     
11
 *******************************************************************************/
12
package org.eclipse.wst.sse.ui.internal.handlers;
13
14
import org.eclipse.core.commands.AbstractHandler;
15
import org.eclipse.core.commands.ExecutionEvent;
16
import org.eclipse.core.commands.ExecutionException;
17
import org.eclipse.jface.text.IDocument;
18
import org.eclipse.jface.text.ITextSelection;
19
import org.eclipse.jface.text.TextSelection;
20
import org.eclipse.jface.viewers.ISelection;
21
import org.eclipse.jface.viewers.ISelectionProvider;
22
import org.eclipse.ui.IEditorPart;
23
import org.eclipse.ui.handlers.HandlerUtil;
24
import org.eclipse.ui.texteditor.ITextEditor;
25
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;
26
27
/**
28
 * This class contains all of the shared functionality for comment handlers
29
 */
30
public abstract class AbstractCommentHandler extends AbstractHandler {
31
32
	/**
33
	 * <p>Default constructor must exist because sub classes are created by java reflection</p>
34
	 */
35
	public AbstractCommentHandler() {
36
		super();
37
	}
38
39
	/**
40
	 * <p>Gets the important information out of the event and passes it onto 
41
	 * the internal method {@link #processAction}</p>
42
	 * 
43
	 * @see org.eclipse.wst.xml.ui.internal.handlers.CommentHandler#execute(org.eclipse.core.commands.ExecutionEvent)
44
	 */
45
	public final Object execute(ExecutionEvent event) throws ExecutionException {
46
		IEditorPart editor = HandlerUtil.getActiveEditor(event);
47
		ITextEditor textEditor = null;
48
		if (editor instanceof ITextEditor)
49
			textEditor = (ITextEditor) editor;
50
		else {
51
			Object o = editor.getAdapter(ITextEditor.class);
52
			if (o != null)
53
				textEditor = (ITextEditor) o;
54
		}
55
		if (textEditor != null) {
56
			IDocument document = textEditor.getDocumentProvider().getDocument(textEditor.getEditorInput());
57
			if (document != null && document instanceof IStructuredDocument) {
58
				// get current text selection
59
				ITextSelection textSelection = getCurrentSelection(textEditor);
60
				if (!textSelection.isEmpty()) {
61
					//call the implementers code to deal with the event
62
					processAction(textEditor, (IStructuredDocument)document, textSelection);
63
				}
64
			}
65
		}
66
		return null;
67
	}
68
69
	/**
70
	 * <p>This method is called by the public {@link #execute} method whenever
71
	 * the comment handler is invoked.  This method should be used for the
72
	 * logic of handling the structured comment event.</p>
73
	 * 
74
	 * @param textEditor the text editor the initiating event was caused in
75
	 * @param document the document the text editor is editing
76
	 * @param textSelection the user selection when the event was caused
77
	 */
78
	protected abstract void processAction(ITextEditor textEditor, IStructuredDocument document, ITextSelection textSelection);
79
	
80
	/**
81
	 * <p>Gets the current user selection in the given {@link ITextEditor}</p>
82
	 * 
83
	 * @param textEditor get the user selection from here
84
	 * @return the current user selection in <code>textEdtior</code>
85
	 */
86
	private static ITextSelection getCurrentSelection(ITextEditor textEditor) {
87
		ISelectionProvider provider = textEditor.getSelectionProvider();
88
		if (provider != null) {
89
			ISelection selection = provider.getSelection();
90
			if (selection instanceof ITextSelection) {
91
				return (ITextSelection) selection;
92
			}
93
		}
94
		return TextSelection.emptySelection();
95
	}
96
}
(-)src/org/eclipse/wst/sse/ui/internal/comment/LineCommentingStrategy.java (+86 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2010 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * 
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.wst.sse.ui.internal.comment;
12
13
import org.eclipse.jface.text.BadLocationException;
14
import org.eclipse.jface.text.IDocument;
15
import org.eclipse.jface.text.IRegion;
16
import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
17
18
/**
19
 * <p>Represents a Line Comment commenting strategy</p>
20
 */
21
public class LineCommentingStrategy extends CommentingStrategy {
22
	/** the prefix of the line comment associated with this strategy */
23
	private String fPrefix;
24
	
25
	/**
26
	 * @param prefix the prefix of the line comment associated with this strategy
27
	 */
28
	public LineCommentingStrategy(String prefix) {
29
		super();
30
		this.fPrefix = prefix;
31
	}
32
	
33
	/**
34
	 * <p>Assumes that the given offset is at the begining of a line and adds the line
35
	 * comment prefix there</p>
36
	 * 
37
	 * @see org.eclipse.wst.sse.ui.internal.comment.CommentingStrategy#apply(
38
	 * 	org.eclipse.wst.sse.core.internal.provisional.IStructuredModel, int, int)
39
	 */
40
	public void apply(IStructuredModel model, int offset, int length)
41
			throws BadLocationException {
42
		
43
		IDocument document = model.getStructuredDocument();
44
		document.replace(offset, 0, this.fPrefix + " ");
45
	}
46
47
	/**
48
	 * <p>Assumes that the given offset is at the beginning of a line that is commented and removes
49
	 * the comment prefix from the beginning of the line, leading whitespace on the line will not
50
	 * prevent this method from finishing correctly</p>
51
	 * 
52
	 * @see org.eclipse.wst.sse.ui.internal.comment.CommentingStrategy#remove(
53
	 * 	org.eclipse.wst.sse.core.internal.provisional.IStructuredModel, int, int, boolean)
54
	 */
55
	public void remove(IStructuredModel model, int offset, int length, boolean removeEnclosing) throws BadLocationException{
56
		IDocument document = model.getStructuredDocument();
57
		String content = document.get(offset, length);
58
		int innerOffset = content.indexOf(this.fPrefix);
59
		if(innerOffset > 0) {
60
			offset += innerOffset;
61
		}
62
		
63
		uncomment(model.getStructuredDocument(), offset, this.fPrefix, -1,  null);
64
	}
65
	
66
	/**
67
	 * <p>A region is already commented if it begins with the the associated prefix ignoring any
68
	 * leading whitespace</p>
69
	 * 
70
	 * @see org.eclipse.wst.sse.ui.internal.comment.CommentingStrategy#alreadyCommenting(
71
	 * 	org.eclipse.jface.text.IDocument, org.eclipse.jface.text.IRegion)
72
	 */
73
	public boolean alreadyCommenting(IDocument document, IRegion region)
74
			throws BadLocationException {
75
		
76
		String regionContent = document.get(region.getOffset(), region.getLength()).trim();
77
		return regionContent.startsWith(this.fPrefix);
78
	}
79
	
80
	/**
81
	 * @see org.eclipse.wst.sse.ui.internal.comment.CommentingStrategy#clone()
82
	 */
83
	public Object clone() {
84
		return new LineCommentingStrategy(this.fPrefix);
85
	}
86
}
(-)src/org/eclipse/wst/sse/ui/handlers/AddBlockCommentHandler.java (+81 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2010 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * 
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.wst.sse.ui.handlers;
12
13
import org.eclipse.jface.text.BadLocationException;
14
import org.eclipse.jface.text.DocumentRewriteSession;
15
import org.eclipse.jface.text.DocumentRewriteSessionType;
16
import org.eclipse.jface.text.IDocumentExtension4;
17
import org.eclipse.jface.text.ITextSelection;
18
import org.eclipse.jface.text.ITypedRegion;
19
import org.eclipse.ui.texteditor.ITextEditor;
20
import org.eclipse.wst.sse.core.StructuredModelManager;
21
import org.eclipse.wst.sse.core.internal.Logger;
22
import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
23
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;
24
import org.eclipse.wst.sse.ui.internal.SSEUIMessages;
25
import org.eclipse.wst.sse.ui.internal.comment.CommentingStrategy;
26
import org.eclipse.wst.sse.ui.internal.comment.CommentingStrategyRegistry;
27
import org.eclipse.wst.sse.ui.internal.handlers.AbstractCommentHandler;
28
29
/**
30
 * <p>A comment handler to add block comments</p>
31
 */
32
public final class AddBlockCommentHandler extends
33
		AbstractCommentHandler {
34
35
	/**
36
	 * @see org.eclipse.wst.sse.ui.internal.handlers.AbstractCommentHandler#processAction(
37
	 * 	org.eclipse.ui.texteditor.ITextEditor, org.eclipse.jface.text.IDocument, org.eclipse.jface.text.ITextSelection)
38
	 */
39
	protected void processAction(ITextEditor textEditor, IStructuredDocument document, ITextSelection textSelection) {
40
		IStructuredModel model = null;
41
		boolean changed = false;
42
		DocumentRewriteSession session = null;
43
		
44
		try {
45
			model = StructuredModelManager.getModelManager().getModelForEdit(document);
46
			if(model != null) {
47
				//makes it so one undo will undo all the edits to the document
48
				model.beginRecording(this, SSEUIMessages.AddBlockComment_label, SSEUIMessages.AddBlockComment_description);
49
				
50
				//keeps listeners from doing anything until updates are all done
51
				model.aboutToChangeModel();
52
				if(document instanceof IDocumentExtension4) {
53
					session = ((IDocumentExtension4)document).startRewriteSession(DocumentRewriteSessionType.UNRESTRICTED);
54
				}
55
				changed = true;
56
				
57
				ITypedRegion[] typedRegions = document.computePartitioning(textSelection.getOffset(), textSelection.getLength());
58
				CommentingStrategy commentType = CommentingStrategyRegistry.getDefault().getBlockCommentingStrategy(model.getContentTypeIdentifier(), typedRegions);
59
				
60
				if(commentType != null) {
61
					commentType.apply(model, textSelection.getOffset(), textSelection.getLength());
62
				}
63
			}
64
		} catch (BadLocationException e) {
65
			Logger.logException("The given selection " + textSelection + " must be invalid", e); //$NON-NLS-1$ //$NON-NLS-2$
66
		} finally {
67
			//clean everything up
68
			if(session != null && document instanceof IDocumentExtension4) {
69
				((IDocumentExtension4)document).stopRewriteSession(session);
70
			}
71
			
72
			if(model != null) {
73
				model.endRecording(this);
74
				if(changed) {
75
					model.changedModel();
76
				}
77
				model.releaseFromEdit();
78
			}
79
		}
80
	}
81
}
(-)src/org/eclipse/wst/sse/ui/internal/comment/CommentingStrategy.java (+380 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2010 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * 
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.wst.sse.ui.internal.comment;
12
13
import java.util.ArrayList;
14
import java.util.Collections;
15
import java.util.List;
16
17
import org.eclipse.jface.text.BadLocationException;
18
import org.eclipse.jface.text.IDocument;
19
import org.eclipse.jface.text.IRegion;
20
import org.eclipse.jface.text.ITypedRegion;
21
import org.eclipse.jface.text.Region;
22
import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
23
import org.eclipse.wst.sse.ui.internal.Logger;
24
25
/**
26
 * <p>Defines a commenting strategy defined by the <code>org.eclipse.wst.sse.ui.commentinStrategy</code>
27
 * extension point and tracked by the {@link CommentingStrategyRegistry}.  Though it is important to
28
 * note it is note a one to one relationship of {@link CommentingStrategy}s to extensions, there is actually
29
 * one {@link CommentingStrategy} for each content type defined for each 
30
 * <code>org.eclipse.wst.sse.ui.commentinStrategy</code> extension.<p>
31
 * 
32
 * <p>The expected use case is that a {@link CommentingStrategy} is created off the basic configuration
33
 * of the extension point and then cloned for each associated content type and then each clone has
34
 * its partition information set using {@link #setPartitionInformation}.
35
 * Then the {@link CommentingStrategyRegistry} can be used to retrieve applicable {@link CommentingStrategy}s
36
 * and apply them to documents.</p>
37
 * 
38
 * <p>It is important to note that any instance of a {@link CommentingStrategy} is only valid for a specific
39
 * content type ID but this relationship is tracked by the {@link CommentingStrategyRegistry} and not by
40
 * the strategy itself.  Thus any reference to the strategy being valid for specific or general partition
41
 * types is implying it is already only valid for a specific content type</p>
42
 */
43
public abstract class CommentingStrategy {
44
	/** <code>true</code> if this strategy has any required partition types, <code>false</code> otherwise */
45
	private boolean fHasRequiredPartitionTypes;
46
	
47
	/** 
48
	 * <p><code>true</code> if for this strategy to be valid all of the required partition types must be seen,
49
	 * <code>false</code> if only at least one of the required partition types must be seen for this
50
	 * strategy to be valid.</p>
51
	 * 
52
	 * @see #fRequriedPartitionTypeIDs
53
	 */
54
	private boolean fRequireAllRequiredPartitionTypes;
55
	
56
	/**
57
	 * <p>required partition type IDs that must be seen for this strategy to be valid, the number of them
58
	 * that must be seen for the strategy to be valid is determined by {@link #fRequireAllRequiredPartitionTypes}
59
	 * this requirement is waved if the optional {@link #fAssociatedCommentPartitionTypeID} is specified and
60
	 * present because this strategy must be valid if its {@link #fAssociatedCommentPartitionTypeID} is present</p>
61
	 * 
62
	 * @see #fRequireAllRequiredPartitionTypes
63
	 * @see #fAssociatedCommentPartitionTypeID
64
	 */
65
	private List fRequriedPartitionTypeIDs;
66
	
67
	/**
68
	 * <p>if <code>true</code> then {@link #fAllowablePartitionTypeIDs} is ignored because
69
	 * this strategy is valid for any partition type, if <code>false</code> then this
70
	 * strategy is only valid for those partition types listed in {@link #fAllowablePartitionTypeIDs}</p>
71
	 * 
72
	 * @see #fAllowablePartitionTypeIDs
73
	 */
74
	private boolean fAllPartitionTypesAllowable;
75
	
76
	/**
77
	 * <p>the partition types that this strategy is valid for, it is also automatically valid for
78
	 * any partition types listed in {@link #fRequriedPartitionTypeIDs} and the optionally
79
	 * specified {@link #fAssociatedCommentPartitionTypeID}</p>
80
	 * 
81
	 * @see #fAllPartitionTypesAllowable
82
	 * @see #fRequriedPartitionTypeIDs
83
	 * @see #fAssociatedCommentPartitionTypeID
84
	 */
85
	private List fAllowablePartitionTypeIDs;
86
	
87
	/**
88
	 * an optional associated comment partition type ID, if this partition type is seen then the
89
	 * the {@link #fRequriedPartitionTypeIDs} requirement is waved as to weather this strategy is
90
	 * valid or not
91
	 * 
92
	 * @see #fRequriedPartitionTypeIDs
93
	 */
94
	private String fAssociatedCommentPartitionTypeID;
95
	
96
	/**
97
	 * <p>Default constructor, the specific initialization is done by
98
	 * {@link #setPartitionInformation}</p>
99
	 */
100
	public CommentingStrategy() {
101
		this.fAssociatedCommentPartitionTypeID = null;
102
		this.fRequriedPartitionTypeIDs = Collections.EMPTY_LIST;
103
		this.fAllowablePartitionTypeIDs = Collections.EMPTY_LIST;
104
		this.fHasRequiredPartitionTypes = false;
105
		this.fRequireAllRequiredPartitionTypes = false;
106
		this.fAllPartitionTypesAllowable = false;
107
	}
108
	
109
	/**
110
	 * <p>Used to set up the partition information for this strategy</p>
111
	 * <p>This information is used to determine if a strategy is valid for a set of
112
	 * {@link ITypedRegion}s.</p>
113
	 * 
114
	 * @param allowablePartitionTypeIDs the partition types this strategy is valid for, the strategy will also
115
	 * be considered valid for any of the required partition types
116
	 * @param allPartitionTypesAllowable if <code>true</code> then this strategy is valid for any partition types
117
	 * thus ignoring the <code>allowablePartitionTypeIDs</code>, <code>false</code> otherwise
118
	 * @param requiredPartitionTypeIDs partition type IDs that must be seen for this strategy to be valid, there
119
	 * are exceptions to this rule, see {@link #isApplicableFor(ITypedRegion[])}
120
	 * @param requireAllRequiredPartitionTypes <code>true</code> if all of the <code>requiredPartitionTypeIDs must
121
	 * be seen for this strategy to be valid, <code>false</code> otherwise, there are exceptions to these rules, see
122
	 * {@link #isApplicableFor(ITypedRegion[])}
123
	 * @param associatedCommentPartitionTypeID optional comment partition type associated with this strategy,
124
	 * maybe <code>null</code>
125
	 * 
126
	 * @see #isApplicableFor(ITypedRegion[])
127
	 */
128
	protected final void setPartitionInformation(List allowablePartitionTypeIDs, boolean allPartitionTypesAllowable,
129
			List requiredPartitionTypeIDs, boolean requireAllRequiredPartitionTypes, String associatedCommentPartitionTypeID) {
130
		
131
		this.fAllPartitionTypesAllowable = allPartitionTypesAllowable;
132
		this.fRequireAllRequiredPartitionTypes = requireAllRequiredPartitionTypes;
133
		
134
		this.fRequriedPartitionTypeIDs = requiredPartitionTypeIDs;
135
		if(this.fRequriedPartitionTypeIDs == null) {
136
			this.fRequriedPartitionTypeIDs = Collections.EMPTY_LIST;
137
		}
138
		
139
		this.fHasRequiredPartitionTypes = this.fRequriedPartitionTypeIDs.size() != 0;
140
		
141
		this.fAllowablePartitionTypeIDs = allowablePartitionTypeIDs;
142
		if(this.fAllowablePartitionTypeIDs == null) {
143
			this.fAllowablePartitionTypeIDs = Collections.EMPTY_LIST;
144
		}
145
		
146
		this.fAssociatedCommentPartitionTypeID = associatedCommentPartitionTypeID;
147
	}
148
	
149
	/**
150
	 * <p>Applies this strategy to the given model starting at the given offset for the given length</p>
151
	 * 
152
	 * @param model {@link IStructuredModel} to apply this strategy too
153
	 * @param offset the offset to start this comment at
154
	 * @param length the length of the region to apply this comment too
155
	 * 
156
	 * @throws BadLocationException it is not the fault of the strategy if callers passes a bad
157
	 * <code>offset</code> and/or <code>length</code> for the given <code>model</code>
158
	 */
159
	public abstract void apply(IStructuredModel model, int offset, int length) throws BadLocationException;
160
	
161
	/**
162
	 * <p>Remove any comments associated with this strategy from the given model for the given offset to
163
	 * the given length.  Weather a comment surrounding the given range should be removed can also be
164
	 * specified</p>
165
	 * 
166
	 * @param model {@link IStructuredModel} to remove comments associated with this strategy from
167
	 * @param offset the location to start removing comments associated with this strategy from
168
	 * @param length the length of the region to remove associated comments from
169
	 * @param removeEnclosing weather a comment should be removed if it incloses the region specified
170
	 * by the given <code>offset</code> and <code>length</code>
171
	 * 
172
	 * @throws BadLocationException it is not the fault of the strategy if callers passes a bad
173
	 * <code>offset</code> and/or <code>length</code> for the given <code>model</code>
174
	 */
175
	public abstract void remove(IStructuredModel model, int offset, int length, boolean removeEnclosing) throws BadLocationException;
176
	
177
	/**
178
	 * <p>Determines if the given region is a comment region commented by this strategy.</p>
179
	 * 
180
	 * @param document {@link IDocument} containing the given <code>region</code>
181
	 * @param region determine if this region is a comment region commented by this strategy
182
	 * @return <code>true</code> if the given <code>region</code> has already been
183
	 * commented by this strategy, <code>false</code> otherwise
184
	 * 
185
	 * @throws BadLocationException it is not the fault of the strategy if callers passes a bad
186
	 * <code>offset</code> and/or <code>length</code> for the given <code>model</code>
187
	 */
188
	public abstract boolean alreadyCommenting(IDocument document, IRegion region) throws BadLocationException;
189
	
190
	/** 
191
	 * <p>Implementers should return a copy of themselves</p>
192
	 * <p>Allows the {@link CommentingStrategyRegistry} to create a {@link CommentingStrategy} for
193
	 * each of its associated content types.</p>
194
	 * 
195
	 * @return implementers should return an object of type {@link CommentingStrategy}
196
	 * 
197
	 * @see java.lang.Object#clone()
198
	 */
199
	public abstract Object clone();
200
	
201
	/**
202
	 * <p>Determines if this strategy is applicable for the given regions for either commenting or un-commenting. 
203
	 * For this strategy to be applicable the given regions must contain at least one or all of the
204
	 * {@link #fRequriedPartitionTypeIDs} (depending on the value of {@link #fRequireAllRequiredPartitionTypes})
205
	 * or contain at least one region of type {@link #fAssociatedCommentPartitionTypeID}.  Also if the value of
206
	 * {@link #fAllPartitionTypesAllowable} is <code>false</code> the given regions must all be of type
207
	 * {@link #fAllowablePartitionTypeIDs} and/or {@link #fRequriedPartitionTypeIDs} and/or
208
	 * {@link #fAssociatedCommentPartitionTypeID} otherwise the regions can be of any type except for they still
209
	 * must beet the required partition type requirements</p>
210
	 * 
211
	 * @param regions determine if this strategy is applicable for these regions
212
	 * @return <code>true</code> if this strategy is applicable for the given <code>regions</code>
213
	 * <code>false</code> otherwise.
214
	 */
215
	public final boolean isApplicableFor(ITypedRegion[] regions) {
216
		List partitionTypeIDs = getPartitionTypeIDs(regions);
217
		
218
		boolean foundAssociatedCommentPartitions = false;
219
		if(this.fAssociatedCommentPartitionTypeID != null) {
220
			foundAssociatedCommentPartitions = partitionTypeIDs.contains(this.fAssociatedCommentPartitionTypeID);
221
			if(foundAssociatedCommentPartitions) {
222
				//remove all instances of the comment partition type
223
				boolean removed;
224
				do {
225
					removed = partitionTypeIDs.remove(this.fAssociatedCommentPartitionTypeID);
226
				} while(removed);
227
			}
228
		}
229
		
230
		//determine if required partitions requirements are met
231
		boolean requiredPartitionsRequirementsMet = false;
232
		if(this.fHasRequiredPartitionTypes) {
233
			/* either all specified required partitions must be found,
234
			 * or just at least one of them must be found
235
			 */
236
			if(this.fRequireAllRequiredPartitionTypes) {
237
				requiredPartitionsRequirementsMet =
238
					partitionTypeIDs.containsAll(this.fRequriedPartitionTypeIDs);
239
				partitionTypeIDs.removeAll(this.fRequriedPartitionTypeIDs);
240
			} else {
241
				requiredPartitionsRequirementsMet =
242
					partitionTypeIDs.removeAll(this.fRequriedPartitionTypeIDs);
243
			}
244
		} else {
245
			requiredPartitionsRequirementsMet = true;
246
		}
247
		
248
		//determine if allowable partitions requirements are met
249
		boolean allowablePartitionsRequirementsMet = false;
250
		if(this.fAllPartitionTypesAllowable) {
251
			allowablePartitionsRequirementsMet = true;
252
		} else {
253
			partitionTypeIDs.removeAll(this.fAllowablePartitionTypeIDs);
254
			
255
			//at this point all required partitions and allowable partitions have been removed
256
			allowablePartitionsRequirementsMet = partitionTypeIDs.size() == 0;
257
		}
258
		
259
		return (requiredPartitionsRequirementsMet || foundAssociatedCommentPartitions) && allowablePartitionsRequirementsMet;
260
	}
261
	
262
	/**
263
	 * <p>Convenience method to take a list of regions and create one encompassing region to pass to
264
	 * {@link #alreadyCommenting(IDocument, IRegion)}</p>
265
	 * 
266
	 * @param document {@link IDocument} that contains the given <code>regions</code>
267
	 * @param regions {@link IRegion}s to combine into one region and pass onto
268
	 * {@link #alreadyCommenting(IDocument, IRegion)}
269
	 * 
270
	 * @return the result of a call to {@link #alreadyCommenting(IDocument, IRegion)} combining
271
	 * all of the given <code>regions</code> into one region
272
	 * 
273
	 * @throws BadLocationException it is not the fault of the strategy if callers passes a bad
274
	 * <code>offset</code> and/or <code>length</code> for the given <code>model</code>
275
	 */
276
	public final boolean alreadyCommenting(IDocument document, IRegion[] regions) throws BadLocationException {
277
		boolean alreadyCommenting = false;
278
		if(regions != null && regions.length > 0) {
279
			//create one region spanning all the given regions
280
			int offset = regions[0].getOffset();
281
			int length = regions[regions.length-1].getOffset() +
282
					regions[regions.length-1].getLength() - offset;
283
		
284
			IRegion region = new Region(offset, length);
285
			alreadyCommenting = this.alreadyCommenting(document, region);
286
		}
287
		
288
		return alreadyCommenting;
289
	}
290
	/**
291
	 * <p>Given a list of {@link ITypedRegion}s returns the sub set of that list that
292
	 * are of the comment region type associated with this strategy</p>
293
	 * 
294
	 * @param typedRegions {@link ITypedRegion}s to filter down to only the comment regions
295
	 * associated with this strategy
296
	 * 
297
	 * @return {@link List} of {@link ITypedRegion}s from the given <code>typedRegions</code>
298
	 * that are of the comment partition type associated with this strategy
299
	 */
300
	protected List getAssociatedCommentedRegions(ITypedRegion[] typedRegions) {
301
		List commentedRegions = new ArrayList();
302
		
303
		for(int i = 0; i < typedRegions.length; ++i) {
304
			if(typedRegions[i].getType().equals(this.fAssociatedCommentPartitionTypeID)) {
305
				commentedRegions.add(typedRegions[i]);
306
			}
307
		}
308
		
309
		return commentedRegions;
310
	}
311
	
312
	/**
313
	 * <p>Given a list of {@link ITypedRegion}s returns a list of the partition
314
	 * type IDs taken from the given regions.</p>
315
	 * 
316
	 * @param regions {@link ITypedRegion}s to get the partition type IDs from
317
	 * @return {@link List} of the partition type IDs taken from the given <code>regions</code>
318
	 */
319
	private static List getPartitionTypeIDs(ITypedRegion[] regions) {
320
		List partitionTypes = new ArrayList(regions.length);
321
		for(int i = 0; i < regions.length; ++i) {
322
			partitionTypes.add(regions[i].getType());
323
		}
324
		
325
		return partitionTypes;
326
	}
327
	
328
	/**
329
	 * <p>This method modifies the given document to remove the given comment
330
	 * prefix at the given comment prefix offset and the given comment
331
	 * suffix at the given comment suffix offset.  In the case of removing
332
	 * a line comment that does not have a suffix, pass <code>null</code>
333
	 * for the comment suffix and it and its associated offset will
334
	 * be ignored.</p>
335
	 * 
336
	 * <p><b>NOTE:</b> it is a good idea if a model is at hand when calling this to
337
	 * warn the model of an impending update</p>
338
	 * 
339
	 * @param document the document to remove the comment from
340
	 * @param commentPrefixOffset the offset of the comment prefix
341
	 * @param commentSuffixOffset the offset of the comment suffix
342
	 * (ignored if <code>commentSuffix</code> is <code>null</code>)
343
	 * @param commentPrefix the prefix of the comment to remove from its associated given offset
344
	 * @param commentSuffix the suffix of the comment to remove from its associated given offset,
345
	 * or null if there is not suffix to remove for this comment
346
	 */
347
	protected static void uncomment(IDocument document, int commentPrefixOffset, String commentPrefix,
348
			int commentSuffixOffset,  String commentSuffix) {
349
		
350
		try {
351
			//determine if there is a space after the comment prefix that should also be removed
352
			int commentPrefixLength = commentPrefix.length();
353
			String postCommentPrefixChar = document.get(commentPrefixOffset + commentPrefix.length(), 1);
354
			if(postCommentPrefixChar.equals(" ")) {
355
				commentPrefixLength++;
356
			}
357
			
358
			//remove the comment prefix
359
			document.replace(commentPrefixOffset, commentPrefixLength, ""); //$NON-NLS-1$
360
			
361
			if(commentSuffix != null) {
362
				commentSuffixOffset -= commentPrefixLength;
363
				
364
				//determine if there is a space before the comment suffix that should also be removed
365
				int commentSuffixLength = commentSuffix.length();
366
				String preCommentSuffixChar = document.get(commentSuffixOffset-1, 1);
367
				if(preCommentSuffixChar.equals(" ")) {
368
					commentSuffixLength++;
369
					commentSuffixOffset--;
370
				}
371
				
372
				//remove the comment suffix
373
				document.replace(commentSuffixOffset, commentSuffixLength, ""); //$NON-NLS-1$
374
			}
375
		}
376
		catch (BadLocationException e) {
377
			Logger.log(Logger.WARNING_DEBUG, e.getMessage(), e);
378
		}
379
	}
380
}
(-)src/org/eclipse/wst/sse/ui/handlers/ToggleLineCommentHandler.java (+282 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2010 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * 
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.wst.sse.ui.handlers;
12
13
import java.lang.reflect.InvocationTargetException;
14
15
import org.eclipse.core.runtime.IProgressMonitor;
16
import org.eclipse.core.runtime.NullProgressMonitor;
17
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
18
import org.eclipse.jface.operation.IRunnableWithProgress;
19
import org.eclipse.jface.text.BadLocationException;
20
import org.eclipse.jface.text.DocumentRewriteSession;
21
import org.eclipse.jface.text.DocumentRewriteSessionType;
22
import org.eclipse.jface.text.IDocument;
23
import org.eclipse.jface.text.IDocumentExtension4;
24
import org.eclipse.jface.text.IRegion;
25
import org.eclipse.jface.text.ITextSelection;
26
import org.eclipse.jface.text.ITypedRegion;
27
import org.eclipse.jface.text.Position;
28
import org.eclipse.swt.widgets.Display;
29
import org.eclipse.ui.texteditor.ITextEditor;
30
import org.eclipse.wst.sse.core.StructuredModelManager;
31
import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
32
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;
33
import org.eclipse.wst.sse.ui.StructuredTextEditor;
34
import org.eclipse.wst.sse.ui.internal.Logger;
35
import org.eclipse.wst.sse.ui.internal.SSEUIMessages;
36
import org.eclipse.wst.sse.ui.internal.StructuredTextViewer;
37
import org.eclipse.wst.sse.ui.internal.comment.BlockCommentingStrategy;
38
import org.eclipse.wst.sse.ui.internal.comment.CommentingStrategy;
39
import org.eclipse.wst.sse.ui.internal.comment.CommentingStrategyRegistry;
40
import org.eclipse.wst.sse.ui.internal.comment.LineCommentingStrategy;
41
import org.eclipse.wst.sse.ui.internal.handlers.AbstractCommentHandler;
42
43
/**
44
 * <p>A comment handler to toggle line comments, this means that if a
45
 * comment already exists on a line then toggling it will remove the comment,
46
 * if the line in question is not already commented then it will not be commented.
47
 * If multiple lines are selected each will be commented separately.  The handler
48
 * first attempts to find a {@link LineCommentingStrategy} for a line, if it can
49
 * not find one then it will try and find a {@link BlockCommentingStrategy} to
50
 * wrap just that line in.</p>
51
 * 
52
 * <p>If a great number of lines are being toggled then a progress dialog will be
53
 * displayed because this can be a timely process</p>
54
 */
55
public final class ToggleLineCommentHandler extends AbstractCommentHandler {
56
	/** if toggling more then this many lines then use a busy indicator */
57
	private static final int TOGGLE_LINES_MAX_NO_BUSY_INDICATOR = 10;
58
	
59
	/**
60
	 * @see org.eclipse.wst.sse.ui.internal.handlers.AbstractCommentHandler#processAction(
61
	 * 	org.eclipse.ui.texteditor.ITextEditor, org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument,
62
	 * 	org.eclipse.jface.text.ITextSelection)
63
	 */
64
	protected void processAction(ITextEditor textEditor,
65
			final IStructuredDocument document, ITextSelection textSelection) {
66
		
67
		IStructuredModel model = null;
68
		DocumentRewriteSession session = null;
69
		boolean changed = false;
70
		
71
		try {
72
			// get text selection lines info
73
			int selectionStartLine = textSelection.getStartLine();
74
			int selectionEndLine = textSelection.getEndLine();
75
			
76
			int selectionEndLineOffset = document.getLineOffset(selectionEndLine);
77
			int selectionEndOffset = textSelection.getOffset() + textSelection.getLength();
78
79
			// adjust selection end line
80
			if ((selectionEndLine > selectionStartLine) && (selectionEndLineOffset == selectionEndOffset)) {
81
				selectionEndLine--;
82
			}
83
84
			// save the selection position since it will be changing
85
			Position selectionPosition = null;
86
			selectionPosition = new Position(textSelection.getOffset(), textSelection.getLength());
87
			document.addPosition(selectionPosition);
88
89
			
90
			model = StructuredModelManager.getModelManager().getModelForEdit(document);
91
			if (model != null) {
92
				//makes it so one undo will undo all the edits to the document
93
				model.beginRecording(this, SSEUIMessages.ToggleComment_label, SSEUIMessages.ToggleComment_description);
94
				
95
				//keeps listeners from doing anything until updates are all done
96
				model.aboutToChangeModel();
97
				if(document instanceof IDocumentExtension4) {
98
					session = ((IDocumentExtension4)document).startRewriteSession(DocumentRewriteSessionType.UNRESTRICTED);
99
				}
100
				changed = true;
101
				
102
				//get the display for the editor if we can
103
				Display display = null;
104
				if(textEditor instanceof StructuredTextEditor) {
105
					StructuredTextViewer viewer = ((StructuredTextEditor)textEditor).getTextViewer();
106
					if(viewer != null) {
107
						display = viewer.getControl().getDisplay();
108
					}
109
				}
110
				
111
				//create the toggling operation
112
				IRunnableWithProgress toggleCommentsRunnable =
113
					new ToggleLinesRunnable(model, document, selectionStartLine, selectionEndLine, display);
114
				
115
				//if toggling lots of lines then use progress monitor else just run the operation
116
				if((selectionEndLine - selectionStartLine) > TOGGLE_LINES_MAX_NO_BUSY_INDICATOR && display != null) {
117
					ProgressMonitorDialog dialog = new ProgressMonitorDialog(display.getActiveShell());
118
					dialog.run(false, true, toggleCommentsRunnable);
119
				} else {
120
					toggleCommentsRunnable.run(new NullProgressMonitor());
121
				}
122
			}
123
		} catch (InvocationTargetException e) {
124
			Logger.logException("Problem running toggle comment progess dialog.", e);  //$NON-NLS-1$
125
		} catch (InterruptedException e) {
126
			Logger.logException("Problem running toggle comment progess dialog.", e);  //$NON-NLS-1$
127
		} catch (BadLocationException e) {
128
			Logger.logException("The given selection " + textSelection + " must be invalid", e); //$NON-NLS-1$ //$NON-NLS-2$
129
		} finally {
130
			//clean everything up
131
			if(session != null && document instanceof IDocumentExtension4) {
132
				((IDocumentExtension4)document).stopRewriteSession(session);
133
			}
134
			
135
			if(model != null) {
136
				model.endRecording(this);
137
				if(changed) {
138
					model.changedModel();
139
				}
140
				model.releaseFromEdit();
141
			}
142
		}
143
	}
144
	
145
	/**
146
	 * <p>The actual line toggling takes place in a runnable so it can be
147
	 * run as part of a progress dialog if there are many lines to toggle
148
	 * and thus the operation will take a noticeable amount of time the user
149
	 * should be aware of, this also allows for the operation to be canceled 
150
	 * by the user</p>
151
	 * 
152
	 */
153
	private static class ToggleLinesRunnable implements IRunnableWithProgress {
154
		/** the model that the lines will be toggled on */
155
		private IStructuredModel fModel;
156
		
157
		/** the document that the lines will be toggled on */
158
		private IDocument fDocument;
159
		
160
		/** the first line in the document to toggle */
161
		private int fSelectionStartLine;
162
		
163
		/** the last line in the document to toggle */
164
		private int fSelectionEndLine;
165
		
166
		/** the display, so that it can be updated during a long operation */
167
		private Display fDisplay;
168
		
169
		/**
170
		 * @param model {@link IStructuredModel} that the lines will be toggled on
171
		 * @param document {@link IDocument} that the lines will be toggled on
172
		 * @param selectionStartLine first line in the document to toggle
173
		 * @param selectionEndLine last line in the document to toggle
174
		 * @param display {@link Display}, so that it can be updated during a long operation
175
		 */
176
		protected ToggleLinesRunnable(IStructuredModel model, IDocument document,
177
				int selectionStartLine, int selectionEndLine, Display display) {
178
			
179
			this.fModel = model;
180
			this.fDocument = document;
181
			this.fSelectionStartLine = selectionStartLine;
182
			this.fSelectionEndLine = selectionEndLine;
183
			this.fDisplay = display;
184
		}
185
		
186
		/**
187
		 * @see org.eclipse.jface.operation.IRunnableWithProgress#run(org.eclipse.core.runtime.IProgressMonitor)
188
		 */
189
		public void run(IProgressMonitor monitor) {
190
			//start work
191
			monitor.beginTask(SSEUIMessages.ToggleComment_progress,
192
					this.fSelectionEndLine-this.fSelectionStartLine);
193
			try {
194
				//toggle each line so long as task not canceled
195
				for (int line = this.fSelectionStartLine;
196
						line <= this.fSelectionEndLine && !monitor.isCanceled(); ++line) {
197
					
198
					//allows the user to be able to click the cancel button
199
					readAndDispatch(this.fDisplay);
200
					
201
					//get the line region
202
					IRegion lineRegion = this.fDocument.getLineInformation(line);
203
					
204
					//don't toggle empty lines
205
					String content = this.fDocument.get(lineRegion.getOffset(), lineRegion.getLength());
206
					if (content.trim().length() > 0) {
207
						//try to get a line comment type
208
						ITypedRegion[] lineTypedRegions =
209
							this.fDocument.computePartitioning(lineRegion.getOffset(), lineRegion.getLength());
210
						CommentingStrategy commentType = CommentingStrategyRegistry.getDefault().getLineCommentingStrategy(
211
								this.fModel.getContentTypeIdentifier(), lineTypedRegions);
212
						
213
						//could not find line comment type so find block comment type to use on line
214
						if(commentType == null) {
215
							commentType = CommentingStrategyRegistry.getDefault().getBlockCommentingStrategy(
216
									this.fModel.getContentTypeIdentifier(), lineTypedRegions);
217
						}
218
						
219
						//toggle the comment on the line
220
						if(commentType != null) {
221
							if(commentType.alreadyCommenting(this.fDocument, lineTypedRegions)) {
222
								commentType.remove(this.fModel, lineRegion.getOffset(), lineRegion.getLength(), true);
223
							} else {
224
								commentType.apply(this.fModel, lineRegion.getOffset(), lineRegion.getLength());
225
							}
226
						}
227
					}
228
					monitor.worked(1);
229
				}
230
			} catch(BadLocationException e) {
231
				Logger.logException("Bad location while toggling comments.", e);  //$NON-NLS-1$
232
			}
233
			//done work
234
			monitor.done();
235
		}
236
		
237
		/**
238
		 * <p>When calling {@link Display#readAndDispatch()} the game is off as to whose code you maybe
239
		 * calling into because of event handling/listeners/etc.  The only important thing is that
240
		 * the UI has been given a chance to react to user clicks.  Thus the logging of most {@link Exception}s
241
		 * and {@link Error}s as caused by {@link Display#readAndDispatch()} because they are not caused
242
		 * by this code and do not effect it.</p>
243
		 * 
244
		 * @param display the {@link Display} to call <code>readAndDispatch</code>
245
		 * on with exception/error handling.
246
		 */
247
		private void readAndDispatch(Display display) {
248
			try {
249
				display.readAndDispatch();
250
			}
251
			catch (Exception e) {
252
				Logger.log(Logger.WARNING,
253
						"Exception caused by readAndDispatch, not caused by or fatal to caller", e);
254
			}
255
			catch (LinkageError e) {
256
				Logger.log(Logger.WARNING,
257
						"LinkageError caused by readAndDispatch, not caused by or fatal to caller", e);
258
			}
259
			catch (VirtualMachineError e) {
260
				// re-throw these
261
				throw e;
262
			}
263
			catch (ThreadDeath e) {
264
				// re-throw these
265
				throw e;
266
			}
267
			catch (Error e) {
268
				// catch every error, except for a few that we don't want to handle
269
				Logger.log(Logger.WARNING,
270
						"Error caused by readAndDispatch, not caused by or fatal to caller", e);
271
			}
272
		}
273
	}
274
	
275
	/**
276
	 * @see org.eclipse.core.commands.AbstractHandler#isEnabled()
277
	 */
278
	public boolean isEnabled() {
279
		// TODO: IAN: fill this in
280
		return super.isEnabled();
281
	}
282
}
(-)schema/commentingStrategy.exsd (+261 lines)
Added Link Here
1
<?xml version='1.0' encoding='UTF-8'?>
2
<!-- Schema file written by PDE -->
3
<schema targetNamespace="org.eclipse.wst.sse.ui" xmlns="http://www.w3.org/2001/XMLSchema">
4
<annotation>
5
      <appInfo>
6
         <meta.schema plugin="org.eclipse.wst.sse.ui" id="commentingStrategy" name="Commenting Strategy"/>
7
      </appInfo>
8
      <documentation>
9
         This extension point allows the contribution of commenting strategy&apos;s to participate in the commenting actions, such as adding and removing commenting blocks and toggling line comments.
10
      </documentation>
11
   </annotation>
12
13
   <element name="extension">
14
      <annotation>
15
         <appInfo>
16
            <meta.element />
17
         </appInfo>
18
      </annotation>
19
      <complexType>
20
         <sequence>
21
            <choice minOccurs="1" maxOccurs="unbounded">
22
               <element ref="blockCommentingStrategy" minOccurs="0" maxOccurs="unbounded"/>
23
               <element ref="lineCommentingStrategy" minOccurs="0" maxOccurs="unbounded"/>
24
            </choice>
25
         </sequence>
26
         <attribute name="point" type="string" use="required">
27
            <annotation>
28
               <documentation>
29
                  
30
               </documentation>
31
            </annotation>
32
         </attribute>
33
         <attribute name="id" type="string">
34
            <annotation>
35
               <documentation>
36
                  an optional identifier of the extension instance
37
               </documentation>
38
            </annotation>
39
         </attribute>
40
         <attribute name="name" type="string">
41
            <annotation>
42
               <documentation>
43
                  
44
               </documentation>
45
               <appInfo>
46
                  <meta.attribute translatable="true"/>
47
               </appInfo>
48
            </annotation>
49
         </attribute>
50
      </complexType>
51
   </element>
52
53
   <element name="blockCommentingStrategy">
54
      <annotation>
55
         <documentation>
56
            Defines a block commenting strategy
57
         </documentation>
58
      </annotation>
59
      <complexType>
60
         <sequence minOccurs="1" maxOccurs="unbounded">
61
            <element ref="contentType"/>
62
         </sequence>
63
         <attribute name="prefix" type="string" use="required">
64
            <annotation>
65
               <documentation>
66
                  The prefix of the block comment this strategy impliments
67
               </documentation>
68
            </annotation>
69
         </attribute>
70
         <attribute name="suffix" type="string" use="required">
71
            <annotation>
72
               <documentation>
73
                  The suffix of the block comment this strategy impliments
74
               </documentation>
75
            </annotation>
76
         </attribute>
77
      </complexType>
78
   </element>
79
80
   <element name="lineCommentingStrategy">
81
      <annotation>
82
         <documentation>
83
            Deefines a line commenting strategy
84
         </documentation>
85
      </annotation>
86
      <complexType>
87
         <sequence minOccurs="1" maxOccurs="unbounded">
88
            <element ref="contentType"/>
89
         </sequence>
90
         <attribute name="prefix" type="string" use="required">
91
            <annotation>
92
               <documentation>
93
                  The prefix of the block comment this strategy impliments
94
               </documentation>
95
            </annotation>
96
         </attribute>
97
      </complexType>
98
   </element>
99
100
   <element name="contentType">
101
      <annotation>
102
         <documentation>
103
            A content type that the strategy is applicable for
104
         </documentation>
105
      </annotation>
106
      <complexType>
107
         <sequence>
108
            <element ref="allowablePartitionTypes"/>
109
            <element ref="requiredPartitionTypes" minOccurs="0" maxOccurs="1"/>
110
         </sequence>
111
         <attribute name="id" type="string" use="required">
112
            <annotation>
113
               <documentation>
114
                  The ID of the content type
115
               </documentation>
116
               <appInfo>
117
                  <meta.attribute kind="identifier" basedOn="org.eclipse.core.contenttype.contentTypes/content-type/@id"/>
118
               </appInfo>
119
            </annotation>
120
         </attribute>
121
         <attribute name="associatedCommentPartitionTypeID" type="string">
122
            <annotation>
123
               <documentation>
124
                  The partition type ID of the comment partition that is associated with the strategy in this content type
125
               </documentation>
126
            </annotation>
127
         </attribute>
128
      </complexType>
129
   </element>
130
131
   <element name="requiredPartitionTypes">
132
      <annotation>
133
         <documentation>
134
            List of partition types in the associated content type that are requried for the strategy to be applicable.  Depending on the value of the &lt;code&gt;requireAll&lt;/code&gt; attribute either all or only at least one of these partition types must be present in a selection for the strategy to be applicable.
135
         </documentation>
136
      </annotation>
137
      <complexType>
138
         <sequence minOccurs="1" maxOccurs="unbounded">
139
            <element ref="partitionType"/>
140
         </sequence>
141
         <attribute name="requireAll" type="boolean" use="default" value="false">
142
            <annotation>
143
               <documentation>
144
                  If &lt;code&gt;true&lt;/code&gt; then all of the required partition types must be present in a user selection for the strategy to be valid, if &lt;code&gt;false&lt;/code&gt; only at least one of the required partition types must be present in the a user selection for the strategy to be valid.  These conditions are shortucted if the &lt;code&gt;associatedCommentPartitiontTypeID&lt;/code&gt; for the &lt;code&gt;contentType&lt;/code&gt; that thes required partition types are associated with is present in the user selection
145
               </documentation>
146
            </annotation>
147
         </attribute>
148
      </complexType>
149
   </element>
150
151
   <element name="allowablePartitionTypes">
152
      <annotation>
153
         <documentation>
154
            The partition types that are allowed in a user selection for the strategy to be valid.  It is assumed that any partition types listed in the &lt;code&gt;requiredPartitionTypes&lt;/code&gt; are also allowable.  This list is ignored if the value of &lt;code&gt;anyPartitionType&lt;/code&gt; is &lt;code&gt;true&lt;/code&gt;
155
         </documentation>
156
      </annotation>
157
      <complexType>
158
         <sequence minOccurs="0" maxOccurs="unbounded">
159
            <element ref="partitionType"/>
160
         </sequence>
161
         <attribute name="anyPartitionType" type="boolean" use="default" value="false">
162
            <annotation>
163
               <documentation>
164
                  If &lt;code&gt;true&lt;/code&gt; then the strategy is valid for any partition type in the associated &lt;code&gt;contentType&lt;/code&gt;, this means that any &lt;code&gt;partionType&lt;/code&gt;s listed here would be ignored.  If &lt;code&gt;false&lt;/code&gt; then only the &lt;code&gt;partitionType&lt;/code&gt;s listed here are allowed in a user selection (allong with any specified requried partition types) for the strategy to be valid.
165
               </documentation>
166
            </annotation>
167
         </attribute>
168
      </complexType>
169
   </element>
170
171
   <element name="partitionType">
172
      <annotation>
173
         <documentation>
174
            A partition type associated with the parenting content type
175
         </documentation>
176
      </annotation>
177
      <complexType>
178
         <attribute name="id" type="string" use="required">
179
            <annotation>
180
               <documentation>
181
                  The ID of the partition type.
182
               </documentation>
183
            </annotation>
184
         </attribute>
185
      </complexType>
186
   </element>
187
188
189
   <annotation>
190
      <appInfo>
191
         <meta.section type="examples"/>
192
      </appInfo>
193
      <documentation>
194
         &lt;p&gt;&lt;b&gt;Example 1:&lt;/b&gt; A simple example for block comments on XML documents&lt;/p&gt;&lt;pre&gt;&lt;extension point=&quot;org.eclipse.wst.sse.ui.commentingStrategy&quot;&gt;
195
  &lt;blockCommentingStrategy
196
      prefix=&quot;&amp;lt;!--&quot;
197
      suffix=&quot;--&amp;gt;&quot;&gt;
198
    &lt;contentType
199
        id=&quot;org.eclipse.core.runtime.xml&quot;
200
        associatedCommentPartitionTypeID=&quot;org.eclipse.wst.xml.XML_COMMENT&quot;&gt;
201
      &lt;allowablePartitionTypes
202
          anyPartitionType=&quot;true&quot;&gt;
203
      &lt;/allowablePartitionTypes&gt;
204
    &lt;/contentType&gt;
205
  &lt;/blockCommentingStrategy&gt;
206
&lt;/extension&gt;&lt;/pre&gt;
207
208
&lt;p&gt;&lt;b&gt;Example 2:&lt;/b&gt; A more complex example for adding CSS comenting to both CSS and HTML documents&lt;/p&gt;&lt;pre&gt;&lt;extension point=&quot;org.eclipse.wst.sse.ui.commentingStrategy&quot;&gt;
209
  &lt;blockCommentingStrategy
210
      prefix=&quot;/*&quot;
211
      suffix=&quot;*/&quot;&gt;
212
    &lt;contentType
213
        associatedCommentPartitionTypeID=&quot;org.eclipse.wst.css.COMMENT&quot;
214
        id=&quot;org.eclipse.wst.css.core.csssource&quot;&gt;
215
      &lt;allowablePartitionTypes
216
          anyPartitionType=&quot;true&quot;&gt;
217
      &lt;/allowablePartitionTypes&gt;
218
    &lt;/contentType&gt;
219
    &lt;contentType
220
        id=&quot;org.eclipse.wst.html.core.htmlsource&quot;&gt;
221
      &lt;allowablePartitionTypes
222
          anyPartitionType=&quot;false&quot;&gt;
223
      &lt;/allowablePartitionTypes&gt;
224
      &lt;requiredPartitionTypes
225
          requireAll=&quot;true&quot;&gt;
226
        &lt;partitionType
227
            id=&quot;org.eclipse.wst.css.STYLE&quot;&gt;
228
        &lt;/partitionType&gt;
229
      &lt;/requiredPartitionTypes&gt;
230
    &lt;/contentType&gt;
231
  &lt;/blockCommentingStrategy&gt;
232
&lt;/extension&gt;&lt;/pre&gt;
233
      </documentation>
234
   </annotation>
235
236
   <annotation>
237
      <appInfo>
238
         <meta.section type="apiinfo"/>
239
      </appInfo>
240
      <documentation>
241
         The user of this extension point does not need to impliment any classes themselves but for their contributions to work in any given content type then the following handlers must be registered for the content type in question by using the &lt;code&gt;org.eclipse.ui.handlers&lt;/code&gt; extension point.
242
&lt;ul&gt;
243
&lt;li&gt;&lt;code&gt;org.eclipse.wst.sse.ui.handlers.AddBlockCommentHandler&lt;/code&gt;&lt;/li&gt;
244
&lt;li&gt;&lt;code&gt;org.eclipse.wst.sse.ui.handlers.RemoveBlockCommentHandler&lt;/code&gt;&lt;/li&gt;
245
&lt;li&gt;&lt;code&gt;org.eclipse.wst.sse.ui.handlers.ToggleLineCommentHandler&lt;/code&gt;&lt;/li&gt;
246
&lt;/ul&gt;
247
      </documentation>
248
   </annotation>
249
250
251
   <annotation>
252
      <appInfo>
253
         <meta.section type="copyright"/>
254
      </appInfo>
255
      <documentation>
256
         Copyright (c) 2010 IBM Corporation and others.
257
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 &lt;a href=&quot;http://www.eclipse.org/legal/epl-v10.html&quot;&gt;http://www.eclipse.org/legal/epl-v10.html&lt;/a&gt;
258
      </documentation>
259
   </annotation>
260
261
</schema>
(-)src/org/eclipse/wst/sse/ui/internal/comment/CommentingStrategyRegistry.java (+352 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2010 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * 
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.wst.sse.ui.internal.comment;
12
13
import java.util.ArrayList;
14
import java.util.Arrays;
15
import java.util.HashMap;
16
import java.util.Iterator;
17
import java.util.List;
18
import java.util.Map;
19
20
import org.eclipse.core.runtime.CoreException;
21
import org.eclipse.core.runtime.IConfigurationElement;
22
import org.eclipse.core.runtime.IExtensionRegistry;
23
import org.eclipse.core.runtime.IStatus;
24
import org.eclipse.core.runtime.InvalidRegistryObjectException;
25
import org.eclipse.core.runtime.Platform;
26
import org.eclipse.core.runtime.Status;
27
import org.eclipse.jface.text.ITypedRegion;
28
import org.eclipse.wst.sse.ui.internal.Logger;
29
import org.eclipse.wst.sse.ui.internal.SSEUIPlugin;
30
31
/**
32
 * <p>The registry of {@link CommentingStrategy}s defined by the <code>org.eclipse.wst.sse.ui.commentinStrategy</code>
33
 * extension point.</p>
34
 */
35
public class CommentingStrategyRegistry {
36
	/** The extension schema name of the extension point */
37
	private static final String EXTENSION_POINT = "commentingStrategy"; //$NON-NLS-1$
38
	
39
	/** The extension schema name of proposal block comment child elements. */
40
	private static final String ELEM_PROPOSAL_BLOCK_COMMENTING_STRATEGY = "blockCommentingStrategy"; //$NON-NLS-1$
41
	
42
	/** The extension schema name of proposal line comment child elements. */
43
	private static final String ELEM_PROPOSAL_LINE_COMMENTING_STRATEGY = "lineCommentingStrategy"; //$NON-NLS-1$
44
	
45
	/** The extension schema name of the content type child elements. */
46
	private static final String ELEM_CONTENT_TYPE = "contentType"; //$NON-NLS-1$
47
	
48
	/** The extension schema name of the required partition types child elements */
49
	private static final String ELEM_REQUIRED_PARTITION_TYPES= "requiredPartitionTypes"; //$NON-NLS-1$
50
	
51
	/** The extension schema name of the allowable partition types child elements */
52
	private static final String ELEM_ALLOWABLE_PARTITION_TYPES= "allowablePartitionTypes"; //$NON-NLS-1$
53
	
54
	/** The extension schema name of partition type child elements */
55
	private static final String ELEM_PARTITION_TYPE= "partitionType"; //$NON-NLS-1$
56
	
57
	/** The extension schema name of the prefix attribute */
58
	private static final String ATTR_PREFIX = "prefix"; //$NON-NLS-1$
59
	
60
	/** The extension schema name of the suffix attribute */
61
	private static final String ATTR_SUFFIX = "suffix"; //$NON-NLS-1$
62
	
63
	/** The extension schema name of the associatedCommentPartitionTypeID attribute */
64
	private static final String ATTR_ASSOCIATED_COMMENT_PARTITION_TPYPE_ID = "associatedCommentPartitionTypeID"; //$NON-NLS-1$
65
	
66
	/** The extension schema name of the anyPartitionType attribute */
67
	private static final String ATTR_ANY_PARTITION_TYPE = "anyPartitionType";  //$NON-NLS-1$
68
	
69
	/** The extension schema name of the requireAll attribute */
70
	private static final String ATTR_REQUIRE_ALL = "requireAll"; //$NON-NLS-1$
71
	
72
	/** The extension schema name for ID attribute */
73
	private static final String ATTR_ID= "id"; //$NON-NLS-1$
74
	
75
	/** the singleton instance of the registry */
76
	private static CommentingStrategyRegistry fSingleton = null;
77
	
78
	/** <code>true</code> if this registry has been loaded. */
79
	private boolean fLoaded;
80
	
81
	/**
82
	 * <p>Registry of content type IDs to {@link BlockCommentingStrategy}s</p>
83
	 * 
84
	 * <code>{@link Map}&lt{@link String}, {@link List}&lt{@link BlockContentType}&gt&gt</code>
85
	 * <ul>
86
	 * <li><b>key:</b> content type ID</li>
87
	 * <li><b>value:</b> List of associated {@link BlockContentType}s</li>
88
	 * <ul>
89
	 */
90
	private Map fBlockCommentTypes;
91
	
92
	/**
93
	 * <p>Registry of content type IDs to {@link LineCommentingStrategy}s</p>
94
	 *
95
	 * <code>{@link Map}&lt{@link String}, {@link List}&lt{@link LineContentType}&gt&gt</code>
96
	 * <ul>
97
	 * <li><b>key:</b> content type ID</li>
98
	 * <li><b>value:</b> List of associated {@link LineContentType}s</li>
99
	 * <ul>
100
	 */
101
	private Map fLineCommentTypes;
102
	
103
	/**
104
	 * @return the single instance of the {@link CommentingStrategyRegistry}
105
	 */
106
	public static synchronized CommentingStrategyRegistry getDefault() {
107
		if(fSingleton == null) {
108
			fSingleton = new CommentingStrategyRegistry();
109
		}
110
		
111
		return fSingleton;
112
	}
113
	
114
	/**
115
	 * Singleton constructor for the registry
116
	 */
117
	private CommentingStrategyRegistry() {
118
		this.fLoaded = false;
119
		this.fBlockCommentTypes = new HashMap();
120
		this.fLineCommentTypes = new HashMap();
121
	}
122
	
123
	/**
124
	 * @param contentTypeID get only {@link BlockCommentingStrategy}s associated with this content type
125
	 * @param regions get only {@link BlockCommentingStrategy}s associated with these types of regions
126
	 * @return all the {@link BlockCommentingStrategy}s associated with the given content type and regions
127
	 */
128
	public CommentingStrategy getBlockCommentingStrategy(String contentTypeID, ITypedRegion[] regions) {
129
		return getCommentingStrategy(contentTypeID, regions, this.fBlockCommentTypes);
130
	}
131
	
132
	/**
133
	 * @param contentTypeID get only {@link LineCommentingStrategy}s associated with this content type
134
	 * @param regions get only {@link LineCommentingStrategy}s associated with these types of regions
135
	 * @return all the {@link LineCommentingStrategy}s associated with the given content type and regions
136
	 */
137
	public CommentingStrategy getLineCommentingStrategy(String contentTypeID, ITypedRegion[] regions) {
138
		return getCommentingStrategy(contentTypeID, regions, this.fLineCommentTypes);
139
	}
140
	
141
	/**
142
	 * <p>get all the {@link CommentingStrategy}s associated with the given content type and regions
143
	 * from the given registry</p>
144
	 * 
145
	 * @param contentTypeID  get only {@link CommentingStrategy}s associated with this content type
146
	 * @param regions get only {@link CommentingStrategy}s associated with these types of regions
147
	 * @param registry get the {@link CommentingStrategy}s from this registry
148
	 * @return all the {@link CommentingStrategy}s associated with the given content type and regions
149
	 * from the given registry
150
	 */
151
	private CommentingStrategy getCommentingStrategy(String contentTypeID, ITypedRegion[] regions, Map registry) {
152
		ensureExtensionPointRead();
153
		
154
		CommentingStrategy match = null;
155
		List commentingStrategys = (List)registry.get(contentTypeID);
156
		if(commentingStrategys != null) {
157
			for(int i = 0; i < commentingStrategys.size() && match == null; ++i) {
158
				CommentingStrategy commentType = (CommentingStrategy)commentingStrategys.get(i);
159
				if(commentType.isApplicableFor(regions)) {
160
					match = commentType;
161
				}
162
			}
163
		}
164
		
165
		return match;
166
	}
167
	
168
	/**
169
	 * <p>Ensures that the extensions are read and this registry is built</p>
170
	 */
171
	private void ensureExtensionPointRead() {
172
		if(!fLoaded) {
173
			load();
174
			fLoaded = true;
175
		}
176
	}
177
	
178
	/**
179
	 * <p>Load the extension points into the registry</p>
180
	 */
181
	private void load() {
182
		IExtensionRegistry extensionRegistry = Platform.getExtensionRegistry();
183
		List extensionElements = new ArrayList(Arrays.asList(extensionRegistry.getConfigurationElementsFor(SSEUIPlugin.ID, EXTENSION_POINT)));
184
	
185
		//for each extension
186
		for (Iterator iter= extensionElements.iterator(); iter.hasNext();) {
187
			IConfigurationElement element = (IConfigurationElement) iter.next();
188
			try {
189
				CommentingStrategy newCommentingStrategy = null;
190
				Map commentingStrategyRegistry = null;
191
				//either a block or line commenting strategy
192
				if(element.getName().equals(ELEM_PROPOSAL_BLOCK_COMMENTING_STRATEGY)) {
193
					String prefix = element.getAttribute(ATTR_PREFIX);
194
					checkExtensionAttributeNotNull(prefix, ATTR_PREFIX, element);
195
					
196
					String suffix = element.getAttribute(ATTR_SUFFIX);
197
					checkExtensionAttributeNotNull(suffix, ATTR_SUFFIX, element);
198
					
199
					if(prefix != null && suffix != null) {
200
						newCommentingStrategy = new BlockCommentingStrategy(prefix, suffix);
201
						commentingStrategyRegistry = this.fBlockCommentTypes;
202
					}
203
				} else if(element.getName().equals(ELEM_PROPOSAL_LINE_COMMENTING_STRATEGY)) {
204
					String prefix = element.getAttribute(ATTR_PREFIX);
205
					checkExtensionAttributeNotNull(prefix, ATTR_PREFIX, element);
206
					
207
					if(prefix != null) {
208
						newCommentingStrategy = new LineCommentingStrategy(prefix);
209
						commentingStrategyRegistry = this.fLineCommentTypes;
210
					}
211
				}
212
				
213
				//add the new strategy to the registry
214
				if(commentingStrategyRegistry != null && newCommentingStrategy != null) {
215
					addCommentingStrategyToRegistry(element, commentingStrategyRegistry, newCommentingStrategy);
216
				} else {
217
					Logger.log(Logger.WARNING, "Invalid CommentingStrategy extension: " + element); //$NON-NLS-1$
218
				}
219
			} catch (CoreException e) {
220
				Logger.logException(e);
221
			} catch (InvalidRegistryObjectException x) {
222
				/* Element is not valid any longer as the contributing plug-in was unloaded or for
223
				 * some other reason. Do not include the extension in the list and log it
224
				 */
225
				String message = "The extension ''" + element.toString() + "'' is invalid."; //$NON-NLS-1$ //$NON-NLS-2$
226
				IStatus status= new Status(IStatus.WARNING, SSEUIPlugin.ID, IStatus.WARNING, message, x);
227
				Logger.log(status);
228
			}
229
		}
230
	}
231
	
232
	/**
233
	 * <p>Checks that the given attribute value is not <code>null</code>.</p>
234
	 *
235
	 * @param value the object to check if not null
236
	 * @param attribute the attribute
237
	 * 
238
	 * @throws InvalidRegistryObjectException if the registry element is no longer valid
239
	 * @throws CoreException if <code>value</code> is <code>null</code>
240
	 */
241
	private static void checkExtensionAttributeNotNull(Object value, String attribute,
242
			IConfigurationElement element) throws InvalidRegistryObjectException, CoreException {
243
		
244
		if (value == null) {
245
			String message = "The extension \"" + element.getDeclaringExtension().getUniqueIdentifier() + //$NON-NLS-1$
246
				"\" from plug-in \"" + element.getContributor().getName() + //$NON-NLS-1$
247
				"\" did not specify a value for the required \"" + attribute + //$NON-NLS-1$
248
				"\" attribute for the element \"" + element.getName() + "\". Disabling the extension."; //$NON-NLS-1$ //$NON-NLS-2$
249
			IStatus status= new Status(IStatus.WARNING, SSEUIPlugin.ID, IStatus.OK, message, null);
250
			throw new CoreException(status);
251
		}
252
	}
253
	
254
	/**
255
	 * <p>Using the content type element children of the given element add a copy of the given
256
	 * base commenting strategy to the given registry</p>
257
	 * 
258
	 * @param element a {@link IConfigurationElement} with contentType element children
259
	 * @param commentingStrategyRegistry {@link Map} of content type ids to {@link CommentingStrategy}s to register
260
	 * the given {@link CommentingStrategy} with based on the <code>element</code>
261
	 * @param baseCommentingStrategy {@link CommentingStrategy} that will be cloned and configured for each
262
	 * content type in the given <code>element</code>
263
	 */
264
	private static void addCommentingStrategyToRegistry(IConfigurationElement element,
265
			Map commentingStrategyRegistry, CommentingStrategy baseCommentingStrategy) {
266
		
267
		//get all the content type elements
268
		IConfigurationElement[] contentTypeElements = element.getChildren(ELEM_CONTENT_TYPE);
269
		if(contentTypeElements.length > 0) {
270
			for(int contentTypeIndex = 0; contentTypeIndex < contentTypeElements.length; ++contentTypeIndex) {
271
				try {
272
					String contentTypeID = contentTypeElements[contentTypeIndex].getAttribute(ATTR_ID);
273
					checkExtensionAttributeNotNull(contentTypeID, ATTR_ID, contentTypeElements[contentTypeIndex]);
274
					
275
					List commentTypes = (List)commentingStrategyRegistry.get(contentTypeID);
276
					if(commentTypes == null) {
277
						commentTypes = new ArrayList();
278
						commentingStrategyRegistry.put(contentTypeID, commentTypes);
279
					}
280
					
281
					//this element is required
282
					List allowablePartitionTypeIDs = new ArrayList();
283
					IConfigurationElement[] allowablePartitionTypes =
284
						contentTypeElements[contentTypeIndex].getChildren(ELEM_ALLOWABLE_PARTITION_TYPES);
285
					boolean anyPartitionType = false;
286
					if(allowablePartitionTypes.length > 0) {
287
						//determine anyPartitionType attribute value
288
						String anyPartitionTypeValue = allowablePartitionTypes[0].getAttribute(ATTR_ANY_PARTITION_TYPE);
289
						if(anyPartitionTypeValue != null) {
290
							anyPartitionType = Boolean.valueOf(anyPartitionTypeValue).booleanValue();
291
						}
292
						
293
						//get the optional partition types
294
						allowablePartitionTypes = allowablePartitionTypes[0].getChildren(ELEM_PARTITION_TYPE);
295
						if(allowablePartitionTypes.length > 0) {
296
							for (int partitionTypeIndex = 0; partitionTypeIndex < allowablePartitionTypes.length; ++partitionTypeIndex) {
297
								String partitionTypeID = allowablePartitionTypes[partitionTypeIndex].getAttribute(ATTR_ID);
298
								checkExtensionAttributeNotNull(partitionTypeID, ATTR_ID, allowablePartitionTypes[partitionTypeIndex]);
299
								
300
								allowablePartitionTypeIDs.add(partitionTypeID);
301
							}
302
						}
303
						
304
						//this element is optional
305
						List requiredPartitionTypeIDs = new ArrayList();
306
						IConfigurationElement[] requiredPartitionTypes =
307
							contentTypeElements[contentTypeIndex].getChildren(ELEM_REQUIRED_PARTITION_TYPES);
308
						boolean requireAll = false;
309
						if(requiredPartitionTypes.length > 0) {
310
							//determine requireAll attribute value
311
							String requireAllValue = requiredPartitionTypes[0].getAttribute(ATTR_REQUIRE_ALL);
312
							if(requireAllValue != null) {
313
								requireAll = Boolean.valueOf(requireAllValue).booleanValue();
314
							}
315
							
316
							//get the required partition types
317
							requiredPartitionTypes = requiredPartitionTypes[0].getChildren(ELEM_PARTITION_TYPE);
318
							if(requiredPartitionTypes.length > 0) {
319
								for (int partitionTypeIndex = 0; partitionTypeIndex < requiredPartitionTypes.length; ++partitionTypeIndex) {
320
									String partitionTypeID = requiredPartitionTypes[partitionTypeIndex].getAttribute(ATTR_ID);
321
									checkExtensionAttributeNotNull(partitionTypeID, ATTR_ID, requiredPartitionTypes[partitionTypeIndex]);
322
									
323
									requiredPartitionTypeIDs.add(partitionTypeID);
324
								}
325
							}
326
						}
327
						
328
						//get the optional associated comment partition type ID
329
						String associatedCommentPartitionTypeID =
330
							contentTypeElements[contentTypeIndex].getAttribute(ATTR_ASSOCIATED_COMMENT_PARTITION_TPYPE_ID);
331
						
332
						//register the strategy
333
						CommentingStrategy newCommentingStrategy = (CommentingStrategy)baseCommentingStrategy.clone();
334
						newCommentingStrategy.setPartitionInformation(allowablePartitionTypeIDs, anyPartitionType,
335
								requiredPartitionTypeIDs, requireAll, associatedCommentPartitionTypeID);
336
						commentTypes.add(newCommentingStrategy);
337
						
338
					} else {
339
						Logger.log(Logger.WARNING, "The " + ELEM_ALLOWABLE_PARTITION_TYPES +
340
								" element was not specified for one of the " + ELEM_CONTENT_TYPE +"s in " + //$NON-NLS-1$ //$NON-NLS-2$
341
								element + " affected extension will not be loaded" ); //$NON-NLS-1$
342
					}
343
				} catch(CoreException e) {
344
					Logger.logException(e);
345
				}
346
			}
347
		} else {
348
			Logger.log(Logger.WARNING, "The commmentying strategy element: " + element +//$NON-NLS-1$
349
					" does not contain any requried " + ELEM_CONTENT_TYPE + "s"); //$NON-NLS-1$ //$NON-NLS-2$
350
		}
351
	}
352
}
(-)src/org/eclipse/wst/sse/ui/internal/comment/BlockCommentingStrategy.java (+142 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2010 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * 
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.wst.sse.ui.internal.comment;
12
13
import java.util.List;
14
15
import org.eclipse.jface.text.BadLocationException;
16
import org.eclipse.jface.text.IDocument;
17
import org.eclipse.jface.text.IRegion;
18
import org.eclipse.jface.text.ITypedRegion;
19
import org.eclipse.jface.text.Region;
20
import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
21
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion;
22
import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegion;
23
import org.eclipse.wst.sse.ui.internal.Logger;
24
25
/**
26
 * <p>Represents a Block Comment commenting strategy</p>
27
 */
28
public class BlockCommentingStrategy extends CommentingStrategy {
29
	/** the prefix of the block comment associated with this strategy */
30
	private String fPrefix;
31
	
32
	/** the suffix of the block comment associated with this strategy */
33
	private String fSuffix;
34
	
35
	/**
36
	 * @param prefix the prefix of the block comment associated with this strategy
37
	 * @param suffix the suffix of the block comment associated with this strategy
38
	 */
39
	public BlockCommentingStrategy(String prefix, String suffix) {
40
		super();
41
		this.fPrefix = prefix;
42
		this.fSuffix = suffix;
43
	}
44
45
	/**
46
	 * <p>When applying a block comment it also removes any block comments associated
47
	 * with this strategy that would now be enclosed by the new block comment</p>
48
	 * 
49
	 * @see org.eclipse.wst.sse.ui.internal.comment.CommentingStrategy#apply(
50
	 * 	org.eclipse.wst.sse.core.internal.provisional.IStructuredModel, int, int)
51
	 */
52
	public void apply(IStructuredModel model, int offset, int length) throws BadLocationException {
53
		IDocument document = model.getStructuredDocument();
54
		int commentPrefixOffset = offset;
55
		int commentSuffixOffset = commentPrefixOffset + length;
56
		
57
		try {
58
			document.replace(commentSuffixOffset, 0, " " + this.fSuffix); //$NON-NLS-1$
59
			this.remove(model, commentPrefixOffset + this.fPrefix.length(), length, false);
60
			document.replace(commentPrefixOffset, 0, this.fPrefix + " "); //$NON-NLS-1$
61
		}
62
		catch (BadLocationException e) {
63
			Logger.log(Logger.WARNING_DEBUG, e.getMessage(), e);
64
		}
65
	}
66
67
	/**
68
	 * @see org.eclipse.wst.sse.ui.internal.comment.CommentingStrategy#remove(
69
	 * 	org.eclipse.jface.text.IDocument, int, int)
70
	 */
71
	public void remove(IStructuredModel model, int offset, int length, boolean removeEnclosing) throws BadLocationException {
72
		IDocument document = model.getStructuredDocument();
73
74
		IRegion region = new Region(offset, length);
75
		ITypedRegion[] typedRegions = document.computePartitioning(region.getOffset(), region.getLength());
76
		List commentRegions = this.getAssociatedCommentedRegions(typedRegions);
77
		
78
		//remove in reverse order as to not effect offset of other regions
79
		for(int i = commentRegions.size()-1; i >= 0; --i) {
80
			try {
81
				//get the comment region
82
				ITypedRegion typedRegion = (ITypedRegion)commentRegions.get(i);
83
				IRegion commentRegion = new Region(typedRegion.getOffset(), typedRegion.getLength());
84
85
				/* because of the nature of structured regions the comment region could actually be a
86
				 * sub region that needs to be drilled down too
87
				 */
88
				if(!this.alreadyCommenting(document, commentRegion)) {
89
					IStructuredDocumentRegion structuredRegion =
90
						model.getStructuredDocument().getRegionAtCharacterOffset(commentRegion.getOffset());
91
					
92
					commentRegion = new Region(structuredRegion.getStartOffset(), structuredRegion.getLength());
93
					
94
					if(!this.alreadyCommenting(document, commentRegion)) {
95
						ITextRegion enclosedRegion = structuredRegion.getRegionAtCharacterOffset(typedRegion.getOffset());
96
						int enclosedOffset = structuredRegion.getStartOffset(enclosedRegion);
97
						commentRegion = new Region(enclosedOffset, structuredRegion.getTextEndOffset(enclosedRegion)-enclosedOffset);
98
					}
99
				}
100
				
101
				//at this point should have found the comment region, if not there is an issue
102
				if(this.alreadyCommenting(document, commentRegion)) {
103
					String regionContent = document.get(commentRegion.getOffset(), commentRegion.getLength());
104
					
105
					//if found the comment prefix and suffix then uncomment, otherwise log error
106
					int commentPrefixOffset = commentRegion.getOffset() + regionContent.indexOf(this.fPrefix);
107
					int commentSuffixOffset = commentRegion.getOffset();
108
					commentSuffixOffset += regionContent.lastIndexOf(this.fSuffix);
109
					
110
					//remove comment block depending on if its an enclosing comment block and weather that is allowed
111
					if(removeEnclosing || (commentPrefixOffset >= offset && commentSuffixOffset <= offset+length)) {
112
						uncomment(document, commentPrefixOffset, this.fPrefix, commentSuffixOffset, this.fSuffix);
113
					}
114
				} else {
115
					Logger.log(Logger.ERROR,
116
							"BlockCommentingStrategy#remove could not find the commenting region to remove"); //$NON-NLS-1$
117
				}
118
			} catch(BadLocationException e) {
119
				Logger.logException("This shoudl only ever happen if somethign has gone wrong with the partitioning", e); //$NON-NLS-1$
120
			}
121
		}
122
	}
123
	
124
	/**
125
	 * <p>A region is already commented by this strategy if it starts with the strategy's associated
126
	 * prefix and ends with its associated suffix, ignoring any trailing or leading whitespace</p>
127
	 * 
128
	 * @see org.eclipse.wst.sse.ui.internal.comment.CommentingStrategy#alreadyCommenting(
129
	 * 	org.eclipse.jface.text.IDocument, org.eclipse.jface.text.IRegion)
130
	 */
131
	public boolean alreadyCommenting(IDocument document, IRegion region) throws BadLocationException {
132
		String regionContent = document.get(region.getOffset(), region.getLength()).trim();
133
		return regionContent.startsWith(this.fPrefix) && regionContent.endsWith(this.fSuffix);
134
	}
135
	
136
	/**
137
	 * @see org.eclipse.wst.sse.ui.internal.comment.CommentingStrategy#clone()
138
	 */
139
	public Object clone() {
140
		return new BlockCommentingStrategy(this.fPrefix, this.fSuffix);
141
	}
142
}
(-)src/org/eclipse/wst/sse/ui/handlers/RemoveBlockCommentHandler.java (+85 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2010 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * 
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.wst.sse.ui.handlers;
12
13
import org.eclipse.jface.text.BadLocationException;
14
import org.eclipse.jface.text.DocumentRewriteSession;
15
import org.eclipse.jface.text.DocumentRewriteSessionType;
16
import org.eclipse.jface.text.IDocumentExtension4;
17
import org.eclipse.jface.text.ITextSelection;
18
import org.eclipse.jface.text.ITypedRegion;
19
import org.eclipse.ui.texteditor.ITextEditor;
20
import org.eclipse.wst.sse.core.StructuredModelManager;
21
import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
22
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;
23
import org.eclipse.wst.sse.ui.internal.Logger;
24
import org.eclipse.wst.sse.ui.internal.SSEUIMessages;
25
import org.eclipse.wst.sse.ui.internal.comment.CommentingStrategy;
26
import org.eclipse.wst.sse.ui.internal.comment.CommentingStrategyRegistry;
27
import org.eclipse.wst.sse.ui.internal.handlers.AbstractCommentHandler;
28
29
/**
30
 * <p>A comment handler to remove block comments</p>
31
 */
32
public final class RemoveBlockCommentHandler extends
33
		AbstractCommentHandler {
34
35
	/**
36
	 * @see org.eclipse.wst.sse.ui.internal.handlers.AbstractCommentHandler#processAction(org.eclipse.ui.texteditor.ITextEditor, org.eclipse.jface.text.IDocument, org.eclipse.jface.text.ITextSelection)
37
	 */
38
	protected void processAction(ITextEditor textEditor, IStructuredDocument document, ITextSelection textSelection) {
39
		
40
		IStructuredModel model = null;
41
		boolean changed = false;
42
		DocumentRewriteSession session = null;
43
		try {
44
			model = StructuredModelManager.getModelManager().getModelForEdit(document);
45
			
46
			if(model != null) {
47
				//makes it so one undo will undo all the edits to the document
48
				model.beginRecording(this, SSEUIMessages.RemoveBlockComment_label,
49
						SSEUIMessages.RemoveBlockComment_label);
50
				
51
				//keeps listeners from doing anything until updates are all done
52
				model.aboutToChangeModel();
53
				if(document instanceof IDocumentExtension4) {
54
					session = ((IDocumentExtension4)document).startRewriteSession(
55
							DocumentRewriteSessionType.UNRESTRICTED);
56
				}
57
				changed = true;
58
				
59
				ITypedRegion[] typedRegions = document.computePartitioning(
60
						textSelection.getOffset(), textSelection.getLength());
61
				CommentingStrategy commentType = CommentingStrategyRegistry.getDefault().getBlockCommentingStrategy(
62
						model.getContentTypeIdentifier(), typedRegions);
63
				
64
				if(commentType != null) {
65
					commentType.remove(model, textSelection.getOffset(), textSelection.getLength(), true);
66
				}
67
			}
68
		} catch (BadLocationException e) {
69
			Logger.logException("The given selection " + textSelection + " must be invalid", e); //$NON-NLS-1$ //$NON-NLS-2$
70
		} finally {
71
			//clean everything up
72
			if(session != null && document instanceof IDocumentExtension4) {
73
				((IDocumentExtension4)document).stopRewriteSession(session);
74
			}
75
			
76
			if(model != null) {
77
				model.endRecording(this);
78
				if(changed) {
79
					model.changedModel();
80
				}
81
				model.releaseFromEdit();
82
			}
83
		}
84
	}
85
}
(-)plugin.xml (-1 / +65 lines)
Lines 663-669 Link Here
663
            id="org.eclipse.wst.jsdt.internal.web.ui.convertProjects">
663
            id="org.eclipse.wst.jsdt.internal.web.ui.convertProjects">
664
      	</action>
664
      	</action>
665
   		</objectContribution>
665
   		</objectContribution>
666
   </extension> 
666
   </extension>
667
    <extension
668
          point="org.eclipse.wst.sse.ui.commentingStrategy">
669
       <blockCommentingStrategy
670
             prefix="/*"
671
             suffix="*/">
672
          <contentType
673
                id="org.eclipse.wst.html.core.htmlsource">
674
             <requiredPartitionTypes
675
                   requireAll="false">
676
                <partitionType
677
                      id="org.eclipse.wst.html.SCRIPT">
678
                </partitionType>
679
             </requiredPartitionTypes>
680
             <allowablePartitionTypes
681
                   anyPartitionType="false">
682
             </allowablePartitionTypes>
683
          </contentType>
684
          <contentType
685
                id="org.eclipse.jst.jsp.core.jspsource">
686
             <requiredPartitionTypes
687
                   requireAll="false">
688
                <partitionType
689
                      id="org.eclipse.wst.html.SCRIPT">
690
                </partitionType>
691
                <partitionType
692
                      id="org.eclipse.jst.jsp.SCRIPT.JAVASCRIPT">
693
                </partitionType>
694
             </requiredPartitionTypes>
695
             <allowablePartitionTypes
696
                   anyPartitionType="false">
697
             </allowablePartitionTypes>
698
          </contentType>
699
       </blockCommentingStrategy>
700
       <lineCommentingStrategy
701
             prefix="//">
702
          <contentType
703
                id="org.eclipse.wst.html.core.htmlsource">
704
             <requiredPartitionTypes
705
                   requireAll="false">
706
                <partitionType
707
                      id="org.eclipse.wst.html.SCRIPT">
708
                </partitionType>
709
             </requiredPartitionTypes>
710
             <allowablePartitionTypes
711
                   anyPartitionType="false">
712
             </allowablePartitionTypes>
713
          </contentType>
714
          <contentType
715
                id="org.eclipse.jst.jsp.core.jspsource">
716
             <requiredPartitionTypes
717
                   requireAll="false">
718
                <partitionType
719
                      id="org.eclipse.wst.html.SCRIPT">
720
                </partitionType>
721
                <partitionType
722
                      id="org.eclipse.jst.jsp.SCRIPT.JAVASCRIPT">
723
                </partitionType>
724
             </requiredPartitionTypes>
725
             <allowablePartitionTypes
726
                   anyPartitionType="false">
727
             </allowablePartitionTypes>
728
          </contentType>
729
       </lineCommentingStrategy>
730
    </extension> 
667
731
668
  	 <!-- Uncomment for Standalone + HTML as seperate options -->
732
  	 <!-- Uncomment for Standalone + HTML as seperate options -->
669
  	 <!--
733
  	 <!--
(-)plugin.xml (-2 / +131 lines)
Lines 72-78 Link Here
72
			target="org.eclipse.jst.jsp.core.jspsource" />
72
			target="org.eclipse.jst.jsp.core.jspsource" />
73
		<provisionalDefinition
73
		<provisionalDefinition
74
			type="activecontexts"
74
			type="activecontexts"
75
			value="org.eclipse.jst.jsp.core.jspsource, org.eclipse.jst.jsp.ui.structured.text.editor.jsp.scope, org.eclipse.wst.html.core.htmlsource, org.eclipse.core.runtime.xml, org.eclipse.wst.xml.navigation, org.eclipse.wst.xml.comments, org.eclipse.wst.xml.selection"
75
			value="org.eclipse.jst.jsp.core.jspsource, org.eclipse.jst.jsp.ui.structured.text.editor.jsp.scope, org.eclipse.wst.html.core.htmlsource, org.eclipse.core.runtime.xml, org.eclipse.wst.xml.navigation, org.eclipse.jst.jsp.comments, org.eclipse.wst.xml.selection"
76
        	target="org.eclipse.jst.jsp.core.jspsource" />
76
        	target="org.eclipse.jst.jsp.core.jspsource" />
77
77
78
		<contentOutlineConfiguration
78
		<contentOutlineConfiguration
Lines 485-490 Link Here
485
			description="%scope.jsp.core.jspsource.description"
485
			description="%scope.jsp.core.jspsource.description"
486
			id="org.eclipse.jst.jsp.core.jspsource">
486
			id="org.eclipse.jst.jsp.core.jspsource">
487
		</context>
487
		</context>
488
		<context
489
			name="%scope.structured.text.editor.jsp.comments.name"
490
			parentId="org.eclipse.wst.sse.ui.structuredTextEditorScope"
491
			description="%scope.structured.text.editor.jsp.comments.description"
492
			id="org.eclipse.jst.jsp.comments">
493
		</context>
488
	</extension>
494
	</extension>
489
	
495
	
490
	<!-- Keybindings for jsp source editor -->
496
	<!-- Keybindings for jsp source editor -->
Lines 1021-1028 Link Here
1021
		</menuContribution>
1027
		</menuContribution>
1022
	</extension>
1028
	</extension>
1023
	
1029
	
1024
	<!-- Enable the FormatHandler for JSP Content Type -->
1025
	<extension point="org.eclipse.ui.handlers">
1030
	<extension point="org.eclipse.ui.handlers">
1031
		<!-- Enable the FormatHandler for JSP Content Type -->
1026
		<handler 
1032
		<handler 
1027
			class="org.eclipse.wst.sse.ui.internal.handlers.FormatHandler"
1033
			class="org.eclipse.wst.sse.ui.internal.handlers.FormatHandler"
1028
			commandId="org.eclipse.wst.sse.ui.format">
1034
			commandId="org.eclipse.wst.sse.ui.format">
Lines 1033-1038 Link Here
1033
				<reference definitionId="org.eclipse.wst.jsp.ui.jspContentType.definition"></reference>
1039
				<reference definitionId="org.eclipse.wst.jsp.ui.jspContentType.definition"></reference>
1034
			</enabledWhen>
1040
			</enabledWhen>
1035
		</handler>
1041
		</handler>
1042
		<handler
1043
			class="org.eclipse.wst.sse.ui.handlers.ToggleLineCommentHandler"
1044
			commandId="org.eclipse.wst.sse.ui.toggle.comment">
1045
			<activeWhen>
1046
				<reference definitionId="org.eclipse.jst.jsp.ui.comments"/>
1047
			</activeWhen>
1048
			<enabledWhen>
1049
				<reference definitionId="org.eclipse.jst.jsp.ui.comments"/>
1050
			</enabledWhen>
1051
		</handler>
1052
		<handler
1053
			class="org.eclipse.wst.sse.ui.handlers.AddBlockCommentHandler"
1054
			commandId="org.eclipse.wst.sse.ui.add.block.comment">
1055
			<activeWhen>
1056
				<reference definitionId="org.eclipse.jst.jsp.ui.comments"/>
1057
			</activeWhen>
1058
			<enabledWhen>
1059
				<reference definitionId="org.eclipse.jst.jsp.ui.comments"/>
1060
			</enabledWhen>
1061
		</handler>
1062
		<handler
1063
			class="org.eclipse.wst.sse.ui.handlers.RemoveBlockCommentHandler"
1064
			commandId="org.eclipse.wst.sse.ui.remove.block.comment">
1065
			<activeWhen>
1066
				<reference definitionId="org.eclipse.jst.jsp.ui.comments"/>
1067
			</activeWhen>
1068
			<enabledWhen>
1069
				<reference definitionId="org.eclipse.jst.jsp.ui.comments"/>
1070
			</enabledWhen>
1071
		</handler>
1036
	</extension>
1072
	</extension>
1037
	
1073
	
1038
	<!-- Set up a definition for JSP Content Types -->
1074
	<!-- Set up a definition for JSP Content Types -->
Lines 1047-1052 Link Here
1047
			</iterate>
1083
			</iterate>
1048
		</definition>
1084
		</definition>
1049
	</extension>
1085
	</extension>
1086
	<!-- Set up a definition for JSP Comments handler -->
1087
	<extension point="org.eclipse.core.expressions.definitions">
1088
		<definition id="org.eclipse.jst.jsp.ui.comments">
1089
			<with variable="activeContexts">
1090
				<iterate operator="or">
1091
					<equals value="org.eclipse.jst.jsp.comments"/>
1092
				</iterate>
1093
			</with>
1094
		</definition>
1095
	</extension>
1050
	<extension point="org.eclipse.wst.sse.ui.characterPairing">
1096
	<extension point="org.eclipse.wst.sse.ui.characterPairing">
1051
		<inserter class="org.eclipse.wst.html.ui.internal.text.CharacterPairInserter" id="org.eclipse.wst.jsp.ui.inserter">
1097
		<inserter class="org.eclipse.wst.html.ui.internal.text.CharacterPairInserter" id="org.eclipse.wst.jsp.ui.inserter">
1052
			<contentTypeIdentifier
1098
			<contentTypeIdentifier
Lines 1071-1074 Link Here
1071
			</contentTypeIdentifier>
1117
			</contentTypeIdentifier>
1072
		</inserter>
1118
		</inserter>
1073
	</extension>
1119
	</extension>
1120
 <extension
1121
       point="org.eclipse.wst.sse.ui.commentingStrategy">
1122
    <blockCommentingStrategy
1123
          prefix="&lt;!--"
1124
          suffix="--&gt;">
1125
       <contentType
1126
             associatedCommentPartitionTypeID="org.eclipse.wst.html.HTML_COMMENT"
1127
             id="org.eclipse.jst.jsp.core.jspsource">
1128
          <allowablePartitionTypes
1129
                anyPartitionType="false">
1130
             <partitionType
1131
                   id="org.eclipse.wst.html.HTML_DEFAULT">
1132
             </partitionType>
1133
             <partitionType
1134
                   id="org.eclipse.wst.xml.XML_PI">
1135
             </partitionType>
1136
             <partitionType
1137
                   id="org.eclipse.wst.html.HTML_DECLARATION">
1138
             </partitionType>
1139
          </allowablePartitionTypes>
1140
       </contentType>
1141
    </blockCommentingStrategy>
1142
    <blockCommentingStrategy
1143
          prefix="&lt;%--"
1144
          suffix="--%&gt;">
1145
       <contentType
1146
             associatedCommentPartitionTypeID="org.eclipse.jst.jsp.JSP_COMMENT"
1147
             id="org.eclipse.jst.jsp.core.jspsource">
1148
          <requiredPartitionTypes
1149
                requireAll="false">
1150
             <partitionType
1151
                   id="org.eclipse.jst.jsp.JSP_DIRECTIVE">
1152
             </partitionType>
1153
             <partitionType
1154
                   id="org.eclipse.jst.jsp.DEFAULT_JSP">
1155
             </partitionType>
1156
             <partitionType
1157
                   id="org.eclipse.jst.jsp.SCRIPT.DELIMITER">
1158
             </partitionType>
1159
             <partitionType
1160
                   id="org.eclipse.jst.jsp.SCRIPT.JSP_EL">
1161
             </partitionType>
1162
             <partitionType
1163
                   id="org.eclipse.jst.jsp.SCRIPT.JSP_EL2">
1164
             </partitionType>
1165
          </requiredPartitionTypes>
1166
          <allowablePartitionTypes
1167
                anyPartitionType="true">
1168
          </allowablePartitionTypes>
1169
       </contentType>
1170
    </blockCommentingStrategy>
1171
    <blockCommentingStrategy
1172
          prefix="/*"
1173
          suffix="*/">
1174
       <contentType
1175
             id="org.eclipse.jst.jsp.core.jspsource">
1176
          <requiredPartitionTypes
1177
                requireAll="false">
1178
             <partitionType
1179
                   id="org.eclipse.jst.jsp.SCRIPT.JAVA">
1180
             </partitionType>
1181
          </requiredPartitionTypes>
1182
          <allowablePartitionTypes
1183
                anyPartitionType="false">
1184
          </allowablePartitionTypes>
1185
       </contentType>
1186
    </blockCommentingStrategy>
1187
    <lineCommentingStrategy
1188
          prefix="//">
1189
       <contentType
1190
             id="org.eclipse.jst.jsp.core.jspsource">
1191
          <requiredPartitionTypes
1192
                requireAll="false">
1193
             <partitionType
1194
                   id="org.eclipse.jst.jsp.SCRIPT.JAVA">
1195
             </partitionType>
1196
          </requiredPartitionTypes>
1197
          <allowablePartitionTypes
1198
                anyPartitionType="false">
1199
          </allowablePartitionTypes>
1200
       </contentType>
1201
    </lineCommentingStrategy>
1202
 </extension>
1074
</plugin>
1203
</plugin>
(-)plugin.properties (+2 lines)
Lines 50-55 Link Here
50
scope.structured.text.editor.jsp.description=Editing JSP Source
50
scope.structured.text.editor.jsp.description=Editing JSP Source
51
scope.jsp.core.jspsource.name=JSP Source
51
scope.jsp.core.jspsource.name=JSP Source
52
scope.jsp.core.jspsource.description=JSP Source
52
scope.jsp.core.jspsource.description=JSP Source
53
scope.structured.text.editor.jsp.comments.name=JSP Source Comments
54
scope.structured.text.editor.jsp.comments.description=JSP Source Comments
53
JSP_Type_Rename_Participant_Extension_Element.name=JSP Type Rename Participant
55
JSP_Type_Rename_Participant_Extension_Element.name=JSP Type Rename Participant
54
JSP_Method_Rename_Participant_Extension_Element.name=JSP Method Rename Participant
56
JSP_Method_Rename_Participant_Extension_Element.name=JSP Method Rename Participant
55
JSP_Package_Rename_Participant_Extension_Element.name=JSP Package Rename Participant
57
JSP_Package_Rename_Participant_Extension_Element.name=JSP Package Rename Participant
(-)plugin.xml (-51 / +58 lines)
Lines 48-54 Link Here
48
		<provisionalDefinition
48
		<provisionalDefinition
49
			type="activecontexts"
49
			type="activecontexts"
50
			value="org.eclipse.wst.css.core.csssource"
50
			value="org.eclipse.wst.css.core.csssource"
51
			target="org.eclipse.wst.css.core.csssource" />
51
			target="org.eclipse.wst.css.core.csssource, org.eclipse.wst.css.comments" />
52
	</extension>
52
	</extension>
53
	
53
	
54
	<extension point="org.eclipse.ui.contexts">
54
	<extension point="org.eclipse.ui.contexts">
Lines 58-63 Link Here
58
			description="%scope.structured.text.editor.css.description"
58
			description="%scope.structured.text.editor.css.description"
59
			id="org.eclipse.wst.css.core.csssource">
59
			id="org.eclipse.wst.css.core.csssource">
60
		</context>
60
		</context>
61
		<context
62
			name="%scope.structured.text.editor.css.comments.name"
63
			parentId="org.eclipse.wst.sse.ui.structuredTextEditorScope"
64
			description="%scope.structured.text.editor.css.comments.description"
65
			id="org.eclipse.wst.css.comments">
66
		</context>
61
	</extension>
67
	</extension>
62
	
68
	
63
	<extension
69
	<extension
Lines 242-248 Link Here
242
			</enabledWhen>
248
			</enabledWhen>
243
		</handler>
249
		</handler>
244
		<handler
250
		<handler
245
             class="org.eclipse.wst.css.ui.internal.handlers.ToggleCommentHandler"
251
             class="org.eclipse.wst.sse.ui.handlers.ToggleLineCommentHandler"
246
             commandId="org.eclipse.wst.sse.ui.toggle.comment">
252
             commandId="org.eclipse.wst.sse.ui.toggle.comment">
247
             <activeWhen>
253
             <activeWhen>
248
             	<reference
254
             	<reference
Lines 256-262 Link Here
256
             </enabledWhen>
262
             </enabledWhen>
257
       </handler>
263
       </handler>
258
       <handler
264
       <handler
259
             class="org.eclipse.wst.css.ui.internal.handlers.AddBlockCommentHandler"
265
             class="org.eclipse.wst.sse.ui.handlers.AddBlockCommentHandler"
260
             commandId="org.eclipse.wst.sse.ui.add.block.comment">
266
             commandId="org.eclipse.wst.sse.ui.add.block.comment">
261
             <activeWhen>
267
             <activeWhen>
262
             	<reference
268
             	<reference
Lines 270-276 Link Here
270
             </enabledWhen>
276
             </enabledWhen>
271
       </handler>
277
       </handler>
272
       <handler
278
       <handler
273
             class="org.eclipse.wst.css.ui.internal.handlers.RemoveBlockCommentHandler"
279
             class="org.eclipse.wst.sse.ui.handlers.RemoveBlockCommentHandler"
274
             commandId="org.eclipse.wst.sse.ui.remove.block.comment">
280
             commandId="org.eclipse.wst.sse.ui.remove.block.comment">
275
             <activeWhen>
281
             <activeWhen>
276
             	<reference
282
             	<reference
Lines 326-378 Link Here
326
		</handler>
332
		</handler>
327
	</extension>
333
	</extension>
328
334
329
	<extension point="org.eclipse.ui.menus">
330
		<menuContribution
331
	       locationURI="popup:sourcePopupMenuId?before=sourceBegin">
332
			<command commandId="org.eclipse.wst.sse.ui.toggle.comment" id="ToggleComment" style="push">
333
				<visibleWhen checkEnabled="false">
334
					<reference definitionId="org.eclipse.wst.css.ui.cssSourceContributions.definition"/>
335
				</visibleWhen>
336
			</command>
337
			<command commandId="org.eclipse.wst.sse.ui.add.block.comment" id="AddBlockComment" style="push">
338
				<visibleWhen checkEnabled="false">
339
					<reference definitionId="org.eclipse.wst.css.ui.cssSourceContributions.definition" />
340
				</visibleWhen>
341
			</command>
342
			<command commandId="org.eclipse.wst.sse.ui.remove.block.comment" id="RemoveBlockComment" style="push">
343
				<visibleWhen checkEnabled="false">
344
					<reference definitionId="org.eclipse.wst.css.ui.cssSourceContributions.definition" />
345
				</visibleWhen>
346
			</command>
347
		</menuContribution>
348
349
		<menuContribution locationURI="menu:sourceMenuId?before=sourceBegin">
350
			<command commandId="org.eclipse.wst.sse.ui.toggle.comment"
351
			         id="ToggleComment"
352
			         mnemonic="%command.toggle.comment.mnemonic"
353
			         style="push">
354
				<visibleWhen checkEnabled="false">
355
					<reference definitionId="org.eclipse.wst.css.ui.cssSourceContributions.definition"/>
356
				</visibleWhen>
357
			</command>
358
			<command commandId="org.eclipse.wst.sse.ui.add.block.comment"
359
			         id="AddBlockComment"
360
			         mnemonic="%command.add.block.comment.mnemonic"
361
			         style="push">
362
				<visibleWhen checkEnabled="false">
363
					<reference definitionId="org.eclipse.wst.css.ui.cssSourceContributions.definition"/>
364
				</visibleWhen>
365
			</command>
366
			<command commandId="org.eclipse.wst.sse.ui.remove.block.comment"
367
			         id="RemoveBlockComment"
368
			         mnemonic="%command.remove.block.comment.mnemonic"
369
			         style="push">
370
				<visibleWhen checkEnabled="false">
371
					<reference definitionId="org.eclipse.wst.css.ui.cssSourceContributions.definition"/>
372
				</visibleWhen>
373
			</command>
374
		</menuContribution>
375
	</extension>
376
	<!-- CSS editor actions -->
335
	<!-- CSS editor actions -->
377
	<extension point="org.eclipse.ui.editorActions">
336
	<extension point="org.eclipse.ui.editorActions">
378
		<!--<editorContribution
337
		<!--<editorContribution
Lines 446-451 Link Here
446
		</definition>
405
		</definition>
447
	</extension>
406
	</extension>
448
	
407
	
408
	<extension point="org.eclipse.core.expressions.definitions">
409
		<definition id="org.eclipse.wst.css.ui.comments">
410
			<with variable="activeContexts">
411
				<iterate operator="or">
412
					<equals value="org.eclipse.wst.css.comments"/>
413
				</iterate>
414
			</with>
415
		</definition>
416
	</extension>
417
	
449
	<!-- Define theme -->
418
	<!-- Define theme -->
450
	<extension
419
	<extension
451
		point="org.eclipse.ui.themes">
420
		point="org.eclipse.ui.themes">
Lines 585-588 Link Here
585
			</contentTypeIdentifier>
554
			</contentTypeIdentifier>
586
		</inserter>
555
		</inserter>
587
	</extension>
556
	</extension>
557
 <extension
558
       point="org.eclipse.wst.sse.ui.commentingStrategy">
559
    <blockCommentingStrategy
560
          prefix="/*"
561
          suffix="*/">
562
       <contentType
563
             id="org.eclipse.wst.html.core.htmlsource">
564
          <allowablePartitionTypes
565
                anyPartitionType="false">
566
          </allowablePartitionTypes>
567
          <requiredPartitionTypes
568
                requireAll="true">
569
             <partitionType
570
                   id="org.eclipse.wst.css.STYLE">
571
             </partitionType>
572
          </requiredPartitionTypes>
573
       </contentType>
574
       <contentType
575
             associatedCommentPartitionTypeID="org.eclipse.wst.css.COMMENT"
576
             id="org.eclipse.wst.css.core.csssource">
577
          <allowablePartitionTypes
578
                anyPartitionType="true">
579
          </allowablePartitionTypes>
580
       </contentType>
581
       <contentType
582
             id="org.eclipse.jst.jsp.core.jspsource">
583
          <allowablePartitionTypes
584
                anyPartitionType="false">
585
          </allowablePartitionTypes>
586
          <requiredPartitionTypes
587
                requireAll="true">
588
             <partitionType
589
                   id="org.eclipse.wst.css.STYLE">
590
             </partitionType>
591
          </requiredPartitionTypes>
592
       </contentType>
593
    </blockCommentingStrategy>
594
 </extension>
588
</plugin>
595
</plugin>
(-)plugin.properties (-4 / +2 lines)
Lines 54-63 Link Here
54
54
55
scope.structured.text.editor.css.name=Editing CSS Source
55
scope.structured.text.editor.css.name=Editing CSS Source
56
scope.structured.text.editor.css.description=Editing CSS Source
56
scope.structured.text.editor.css.description=Editing CSS Source
57
57
scope.structured.text.editor.css.comments.name=CSS Source Comments
58
command.toggle.comment.mnemonic=T
58
scope.structured.text.editor.css.comments.description=CSS Source Comments
59
command.remove.block.comment.mnemonic=R
60
command.add.block.comment.mnemonic=A
61
59
62
Colors.atmarkRule=At Mark Rule
60
Colors.atmarkRule=At Mark Rule
63
Colors.selector=Selector
61
Colors.selector=Selector
(-)src/org/eclipse/wst/css/ui/internal/handlers/ToggleCommentHandler.java (-159 lines)
Removed Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2009 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.wst.css.ui.internal.handlers;
12
13
import org.eclipse.jface.text.BadLocationException;
14
import org.eclipse.jface.text.IDocument;
15
import org.eclipse.jface.text.IRegion;
16
import org.eclipse.jface.text.ITextSelection;
17
import org.eclipse.jface.text.Position;
18
import org.eclipse.jface.text.TextSelection;
19
import org.eclipse.jface.viewers.ISelectionProvider;
20
import org.eclipse.ui.texteditor.ITextEditor;
21
import org.eclipse.wst.css.ui.internal.Logger;
22
import org.eclipse.wst.sse.core.StructuredModelManager;
23
import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
24
import org.eclipse.wst.css.ui.internal.CSSUIMessages;
25
26
public class ToggleCommentHandler extends AbstractCommentHandler {
27
28
	protected void processAction(ITextEditor textEditor, IDocument document, ITextSelection textSelection) {
29
		// get text selection lines info
30
		int selectionStartLine = textSelection.getStartLine();
31
		int selectionEndLine = textSelection.getEndLine();
32
		try {
33
			int selectionEndLineOffset = document.getLineOffset(selectionEndLine);
34
			int selectionEndOffset = textSelection.getOffset() + textSelection.getLength();
35
36
			// adjust selection end line
37
			if ((selectionEndLine > selectionStartLine) && (selectionEndLineOffset == selectionEndOffset)) {
38
				selectionEndLine--;
39
			}
40
41
		}
42
		catch (BadLocationException e) {
43
			Logger.log(Logger.WARNING_DEBUG, e.getMessage(), e);
44
		}
45
46
		// save the selection position since it will be changing
47
		Position selectionPosition = null;
48
		boolean updateStartOffset = false;
49
		try {
50
			selectionPosition = new Position(textSelection.getOffset(), textSelection.getLength());
51
			document.addPosition(selectionPosition);
52
53
			// extra check if commenting from beginning of line
54
			int selectionStartLineOffset = document.getLineOffset(selectionStartLine);
55
			if ((textSelection.getLength() > 0) && (selectionStartLineOffset == textSelection.getOffset()) && !isCommentLine(document, selectionStartLine)) {
56
				updateStartOffset = true;
57
			}
58
		}
59
		catch (BadLocationException e) {
60
			Logger.log(Logger.WARNING_DEBUG, e.getMessage(), e);
61
		}
62
63
		processAction(document, selectionStartLine, selectionEndLine);
64
65
		updateCurrentSelection(textEditor, selectionPosition, document, updateStartOffset);
66
	}
67
68
	private void processAction(IDocument document, int selectionStartLine, int selectionEndLine) {
69
		IStructuredModel model = StructuredModelManager.getModelManager().getExistingModelForEdit(document);
70
		if (model != null) {
71
			try {
72
				model.beginRecording(this, CSSUIMessages.ToggleComment_tooltip);
73
				model.aboutToChangeModel();
74
75
				for (int i = selectionStartLine; i <= selectionEndLine; i++) {
76
					try {
77
						if (document.getLineLength(i) > 0) {
78
							if (isCommentLine(document, i)) {
79
								int lineOffset = document.getLineOffset(i);
80
								IRegion region = document.getLineInformation(i);
81
								String string = document.get(region.getOffset(), region.getLength());
82
								int openCommentOffset = lineOffset + string.indexOf(OPEN_COMMENT);
83
								int closeCommentOffset = lineOffset + string.indexOf(CLOSE_COMMENT) - OPEN_COMMENT.length();
84
								uncomment(document, openCommentOffset, closeCommentOffset);
85
							}
86
							else {
87
								int openCommentOffset = document.getLineOffset(i);
88
								int lineDelimiterLength = document.getLineDelimiter(i) == null ? 0 : document.getLineDelimiter(i).length();
89
								int closeCommentOffset = openCommentOffset + document.getLineLength(i) - lineDelimiterLength + OPEN_COMMENT.length();
90
								comment(document, openCommentOffset, closeCommentOffset);
91
							}
92
						}
93
					}
94
					catch (BadLocationException e) {
95
						Logger.log(Logger.WARNING_DEBUG, e.getMessage(), e);
96
					}
97
				}
98
			}
99
			finally {
100
				model.changedModel();
101
				model.endRecording(this);
102
				model.releaseFromEdit();
103
			}
104
		}
105
	}
106
107
	private void updateCurrentSelection(ITextEditor textEditor, Position selectionPosition, IDocument document, boolean updateStartOffset) {
108
		// update the selection if text selection changed
109
		if (selectionPosition != null) {
110
			ITextSelection selection = null;
111
			if (updateStartOffset) {
112
				selection = new TextSelection(document, selectionPosition.getOffset() - OPEN_COMMENT.length(), selectionPosition.getLength() + OPEN_COMMENT.length());
113
			}
114
			else {
115
				selection = new TextSelection(document, selectionPosition.getOffset(), selectionPosition.getLength());
116
			}
117
			ISelectionProvider provider = textEditor.getSelectionProvider();
118
			if (provider != null) {
119
				provider.setSelection(selection);
120
			}
121
			document.removePosition(selectionPosition);
122
		}
123
	}
124
125
	private boolean isCommentLine(IDocument document, int line) {
126
		boolean isComment = false;
127
128
		try {
129
			IRegion region = document.getLineInformation(line);
130
			String string = document.get(region.getOffset(), region.getLength()).trim();
131
			isComment = (string.length() >= OPEN_COMMENT.length() + CLOSE_COMMENT.length()) && string.startsWith(OPEN_COMMENT) && string.endsWith(CLOSE_COMMENT);
132
		}
133
		catch (BadLocationException e) {
134
			Logger.log(Logger.WARNING_DEBUG, e.getMessage(), e);
135
		}
136
		return isComment;
137
	}
138
139
	private void comment(IDocument document, int openCommentOffset, int closeCommentOffset) {
140
		try {
141
			document.replace(openCommentOffset, 0, OPEN_COMMENT);
142
			document.replace(closeCommentOffset, 0, CLOSE_COMMENT);
143
			removeOpenCloseComments(document, openCommentOffset + OPEN_COMMENT.length(), closeCommentOffset - openCommentOffset - CLOSE_COMMENT.length());
144
		}
145
		catch (BadLocationException e) {
146
			Logger.log(Logger.WARNING_DEBUG, e.getMessage(), e);
147
		}
148
	}
149
150
	private void uncomment(IDocument document, int openCommentOffset, int closeCommentOffset) {
151
		try {
152
			document.replace(openCommentOffset, OPEN_COMMENT.length(), ""); //$NON-NLS-1$
153
			document.replace(closeCommentOffset, CLOSE_COMMENT.length(), ""); //$NON-NLS-1$
154
		}
155
		catch (BadLocationException e) {
156
			Logger.log(Logger.WARNING_DEBUG, e.getMessage(), e);
157
		}
158
	}
159
}
(-)src/org/eclipse/wst/css/ui/internal/handlers/AbstractCommentHandler.java (-102 lines)
Removed Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2009 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.wst.css.ui.internal.handlers;
12
13
import org.eclipse.core.commands.AbstractHandler;
14
import org.eclipse.core.commands.ExecutionEvent;
15
import org.eclipse.core.commands.ExecutionException;
16
import org.eclipse.jface.text.BadLocationException;
17
import org.eclipse.jface.text.IDocument;
18
import org.eclipse.jface.text.ITextSelection;
19
import org.eclipse.jface.text.TextSelection;
20
import org.eclipse.jface.viewers.ISelection;
21
import org.eclipse.jface.viewers.ISelectionProvider;
22
import org.eclipse.ui.IEditorPart;
23
import org.eclipse.ui.handlers.HandlerUtil;
24
import org.eclipse.ui.texteditor.ITextEditor;
25
import org.eclipse.wst.css.ui.internal.Logger;
26
27
public class AbstractCommentHandler extends AbstractHandler {
28
29
	static final String OPEN_COMMENT = "/*"; //$NON-NLS-1$
30
	static final String CLOSE_COMMENT = "*/"; //$NON-NLS-1$
31
32
	public Object execute(ExecutionEvent event) throws ExecutionException {
33
		ITextEditor textEditor = getTextEditor(event);
34
		if (textEditor != null) {
35
			IDocument document = textEditor.getDocumentProvider().getDocument(textEditor.getEditorInput());
36
			if (document != null) {
37
				// get current text selection
38
				ITextSelection textSelection = getCurrentSelection(textEditor);
39
				if (textSelection.isEmpty()) {
40
					return null;
41
				}
42
43
				processAction(textEditor, document, textSelection);
44
			}
45
		}
46
47
		return null;
48
	}
49
50
	protected void processAction(ITextEditor editor, IDocument document, ITextSelection textSelection) {
51
	}
52
53
	protected ITextEditor getTextEditor(ExecutionEvent event) {
54
		IEditorPart editor = HandlerUtil.getActiveEditor(event);
55
		ITextEditor textEditor = null;
56
		if (editor instanceof ITextEditor)
57
			textEditor = (ITextEditor) editor;
58
		else {
59
			Object o = editor.getAdapter(ITextEditor.class);
60
			if (o != null)
61
				textEditor = (ITextEditor) o;
62
		}
63
		return textEditor;
64
	}
65
66
	protected ITextSelection getCurrentSelection(ITextEditor textEditor) {
67
		ISelectionProvider provider = textEditor.getSelectionProvider();
68
		if (provider != null) {
69
			ISelection selection = provider.getSelection();
70
			if (selection instanceof ITextSelection) {
71
				return (ITextSelection) selection;
72
			}
73
		}
74
		return TextSelection.emptySelection();
75
	}
76
77
	protected void removeOpenCloseComments(IDocument document, int offset, int length) {
78
		try {
79
			int adjusted_length = length;
80
81
			// remove open comments
82
			String string = document.get(offset, length);
83
			int index = string.lastIndexOf(OPEN_COMMENT);
84
			while (index != -1) {
85
				document.replace(offset + index, OPEN_COMMENT.length(), ""); //$NON-NLS-1$
86
				index = string.lastIndexOf(OPEN_COMMENT, index - 1);
87
				adjusted_length -= OPEN_COMMENT.length();
88
			}
89
90
			// remove close comments
91
			string = document.get(offset, adjusted_length);
92
			index = string.lastIndexOf(CLOSE_COMMENT);
93
			while (index != -1) {
94
				document.replace(offset + index, CLOSE_COMMENT.length(), ""); //$NON-NLS-1$
95
				index = string.lastIndexOf(CLOSE_COMMENT, index - 1);
96
			}
97
		}
98
		catch (BadLocationException e) {
99
			Logger.log(Logger.WARNING_DEBUG, e.getMessage(), e);
100
		}
101
	}
102
}
(-)src/org/eclipse/wst/css/ui/internal/handlers/AddBlockCommentHandler.java (-74 lines)
Removed Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2009 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.wst.css.ui.internal.handlers;
12
13
import org.eclipse.jface.text.BadLocationException;
14
import org.eclipse.jface.text.IDocument;
15
import org.eclipse.jface.text.ITextSelection;
16
import org.eclipse.ui.texteditor.ITextEditor;
17
import org.eclipse.wst.css.core.internal.parserz.CSSRegionContexts;
18
import org.eclipse.wst.css.ui.internal.Logger;
19
import org.eclipse.wst.sse.core.StructuredModelManager;
20
import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
21
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;
22
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion;
23
import org.eclipse.wst.css.ui.internal.CSSUIMessages;
24
25
public class AddBlockCommentHandler extends AbstractCommentHandler {
26
27
	protected void processAction(ITextEditor textEditor, IDocument document, ITextSelection textSelection) {
28
		IStructuredModel model = StructuredModelManager.getModelManager().getExistingModelForEdit(document);
29
		if (model != null && document instanceof IStructuredDocument) {
30
			try {
31
				IStructuredDocument doc = (IStructuredDocument) document;
32
				IStructuredDocumentRegion startRegion = doc.getRegionAtCharacterOffset(textSelection.getOffset());
33
				IStructuredDocumentRegion endRegion = doc.getRegionAtCharacterOffset(textSelection.getOffset() + textSelection.getLength());
34
35
				if (startRegion == null) {
36
					return;
37
				}
38
				if ((endRegion == null) && (textSelection.getLength() > 0)) {
39
					endRegion = doc.getRegionAtCharacterOffset(textSelection.getOffset() + textSelection.getLength() - 1);
40
				}
41
				if (endRegion == null) {
42
					return;
43
				}
44
45
				int openCommentOffset = startRegion.getStartOffset();
46
				int closeCommentOffset = endRegion.getEndOffset() + CLOSE_COMMENT.length();
47
48
				if ((textSelection.getLength() == 0) && (startRegion.getType() == CSSRegionContexts.CSS_COMMENT)) {
49
					return;
50
				}
51
52
				model.beginRecording(this, CSSUIMessages.AddBlockComment_tooltip);
53
				model.aboutToChangeModel();
54
55
				try {
56
					document.replace(openCommentOffset, 0, OPEN_COMMENT);
57
					document.replace(closeCommentOffset, 0, CLOSE_COMMENT);
58
					super.removeOpenCloseComments(document, openCommentOffset + OPEN_COMMENT.length(), closeCommentOffset - openCommentOffset - CLOSE_COMMENT.length());
59
				}
60
				catch (BadLocationException e) {
61
					Logger.log(Logger.WARNING_DEBUG, e.getMessage(), e);
62
				}
63
				finally {
64
					model.changedModel();
65
					model.endRecording(this);
66
				}
67
			}
68
			finally {
69
				model.releaseFromEdit();
70
			}
71
		}
72
	}
73
74
}
(-)src/org/eclipse/wst/css/ui/internal/handlers/RemoveBlockCommentHandler.java (-77 lines)
Removed Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2009 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.wst.css.ui.internal.handlers;
12
13
import org.eclipse.jface.text.BadLocationException;
14
import org.eclipse.jface.text.IDocument;
15
import org.eclipse.jface.text.ITextSelection;
16
import org.eclipse.ui.texteditor.ITextEditor;
17
import org.eclipse.wst.css.core.internal.parserz.CSSRegionContexts;
18
import org.eclipse.wst.css.ui.internal.Logger;
19
import org.eclipse.wst.sse.core.StructuredModelManager;
20
import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
21
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;
22
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion;
23
import org.eclipse.wst.css.ui.internal.CSSUIMessages;
24
25
public class RemoveBlockCommentHandler extends AbstractCommentHandler {
26
27
	protected void processAction(ITextEditor textEditor, IDocument document, ITextSelection textSelection) {
28
		IStructuredModel model = StructuredModelManager.getModelManager().getExistingModelForEdit(document);
29
		if (model != null && document instanceof IStructuredDocument) {
30
			try {
31
				IStructuredDocument doc = (IStructuredDocument) document;
32
				IStructuredDocumentRegion startRegion = doc.getRegionAtCharacterOffset(textSelection.getOffset());
33
				IStructuredDocumentRegion endRegion = doc.getRegionAtCharacterOffset(textSelection.getOffset() + textSelection.getLength());
34
35
				if ((startRegion == null) || (endRegion == null)) {
36
					return;
37
				}
38
39
				int openCommentOffset = startRegion.getStartOffset();
40
				int closeCommentOffset = endRegion.getEndOffset() - OPEN_COMMENT.length() - CLOSE_COMMENT.length();
41
42
				model.beginRecording(this, CSSUIMessages.RemoveBlockComment_tooltip);
43
				model.aboutToChangeModel();
44
45
				try {
46
					if (textSelection.getLength() == 0) {
47
						if (startRegion.getType() == CSSRegionContexts.CSS_COMMENT) {
48
							document.replace(openCommentOffset, OPEN_COMMENT.length(), ""); //$NON-NLS-1$
49
							document.replace(closeCommentOffset, CLOSE_COMMENT.length(), ""); //$NON-NLS-1$
50
						}
51
					}
52
					else {
53
						if (startRegion.getType() == CSSRegionContexts.CSS_COMMENT) {
54
							document.replace(openCommentOffset, OPEN_COMMENT.length(), ""); //$NON-NLS-1$
55
						}
56
57
						if (endRegion.getType() == CSSRegionContexts.CSS_COMMENT) {
58
							document.replace(closeCommentOffset, CLOSE_COMMENT.length(), ""); //$NON-NLS-1$
59
						}
60
					}
61
					removeOpenCloseComments(document, openCommentOffset + OPEN_COMMENT.length(), closeCommentOffset - openCommentOffset - CLOSE_COMMENT.length());
62
				}
63
				catch (BadLocationException e) {
64
					Logger.log(Logger.WARNING_DEBUG, e.getMessage(), e);
65
				}
66
				finally {
67
					model.changedModel();
68
					model.endRecording(this);
69
				}
70
			}
71
			finally {
72
				model.releaseFromEdit();
73
			}
74
		}
75
	}
76
77
}
(-)plugin.xml (-50 / +17 lines)
Lines 1002-1054 Link Here
1002
           </command>
1002
           </command>
1003
        </toolbar>
1003
        </toolbar>
1004
     </menuContribution>
1004
     </menuContribution>
1005
     
1006
     <menuContribution locationURI="menu:sourceMenuId?after=sourceBegin">
1007
			<command commandId="org.eclipse.wst.sse.ui.toggle.comment"
1008
			         id="ToggleComment"
1009
			         mnemonic="%command.toggle.comment.mnemonic"
1010
			         style="push">
1011
				<visibleWhen checkEnabled="false">
1012
					<reference definitionId="org.eclipse.wst.xml.ui.comments"/>
1013
				</visibleWhen>
1014
			</command>
1015
			<command commandId="org.eclipse.wst.sse.ui.add.block.comment"
1016
			         id="AddBlockComment"
1017
			         mnemonic="%command.add.block.comment.mnemonic"
1018
			         style="push">
1019
				<visibleWhen checkEnabled="false">
1020
					<reference definitionId="org.eclipse.wst.xml.ui.comments"/>
1021
				</visibleWhen>
1022
			</command>
1023
			<command commandId="org.eclipse.wst.sse.ui.remove.block.comment"
1024
			         id="RemoveBlockComment"
1025
			         mnemonic="%command.remove.block.comment.mnemonic"
1026
			         style="push">
1027
				<visibleWhen checkEnabled="false">
1028
					<reference definitionId="org.eclipse.wst.xml.ui.comments"/>
1029
				</visibleWhen>
1030
			</command>
1031
		</menuContribution>
1032
		
1033
		<menuContribution
1034
	           locationURI="popup:sourcePopupMenuId?after=sourceBegin">
1035
				<command commandId="org.eclipse.wst.sse.ui.toggle.comment" id="ToggleComment" style="push">
1036
					<visibleWhen checkEnabled="false">
1037
						<reference definitionId="org.eclipse.wst.xml.ui.comments"></reference>
1038
					</visibleWhen>
1039
				</command>
1040
				<command commandId="org.eclipse.wst.sse.ui.add.block.comment" id="AddBlockComment" style="push">
1041
					<visibleWhen checkEnabled="false">
1042
						<reference definitionId="org.eclipse.wst.xml.ui.comments"></reference>
1043
					</visibleWhen>
1044
				</command>
1045
				<command commandId="org.eclipse.wst.sse.ui.remove.block.comment" id="RemoveBlockComment" style="push">
1046
					<visibleWhen checkEnabled="false">
1047
						<reference definitionId="org.eclipse.wst.xml.ui.comments"></reference>
1048
					</visibleWhen>
1049
				</command>
1050
				<separator name="format" visible="true"></separator>
1051
		</menuContribution>
1052
	</extension>
1005
	</extension>
1053
	
1006
	
1054
	<extension point="org.eclipse.core.expressions.definitions">
1007
	<extension point="org.eclipse.core.expressions.definitions">
Lines 1179-1185 Link Here
1179
          </enabledWhen>
1132
          </enabledWhen>
1180
       </handler>
1133
       </handler>
1181
       <handler
1134
       <handler
1182
             class="org.eclipse.wst.xml.ui.internal.handlers.ToggleCommentHandler"
1135
             class="org.eclipse.wst.sse.ui.handlers.ToggleLineCommentHandler"
1183
             commandId="org.eclipse.wst.sse.ui.toggle.comment">
1136
             commandId="org.eclipse.wst.sse.ui.toggle.comment">
1184
          <activeWhen>
1137
          <activeWhen>
1185
              <reference definitionId="org.eclipse.wst.xml.ui.comments"/>
1138
              <reference definitionId="org.eclipse.wst.xml.ui.comments"/>
Lines 1189-1195 Link Here
1189
          </enabledWhen>
1142
          </enabledWhen>
1190
       </handler>
1143
       </handler>
1191
       <handler
1144
       <handler
1192
             class="org.eclipse.wst.xml.ui.internal.handlers.AddBlockCommentHandler"
1145
             class="org.eclipse.wst.sse.ui.handlers.AddBlockCommentHandler"
1193
             commandId="org.eclipse.wst.sse.ui.add.block.comment">
1146
             commandId="org.eclipse.wst.sse.ui.add.block.comment">
1194
          <activeWhen>
1147
          <activeWhen>
1195
              <reference definitionId="org.eclipse.wst.xml.ui.comments"/>
1148
              <reference definitionId="org.eclipse.wst.xml.ui.comments"/>
Lines 1199-1205 Link Here
1199
          </enabledWhen>
1152
          </enabledWhen>
1200
       </handler>
1153
       </handler>
1201
       <handler
1154
       <handler
1202
             class="org.eclipse.wst.xml.ui.internal.handlers.RemoveBlockCommentHandler"
1155
             class="org.eclipse.wst.sse.ui.handlers.RemoveBlockCommentHandler"
1203
             commandId="org.eclipse.wst.sse.ui.remove.block.comment">
1156
             commandId="org.eclipse.wst.sse.ui.remove.block.comment">
1204
          <activeWhen>
1157
          <activeWhen>
1205
              <reference definitionId="org.eclipse.wst.xml.ui.comments"/>
1158
              <reference definitionId="org.eclipse.wst.xml.ui.comments"/>
Lines 1661-1665 Link Here
1661
       </contentTypeIdentifier>
1614
       </contentTypeIdentifier>
1662
    </inserter>
1615
    </inserter>
1663
 </extension>
1616
 </extension>
1617
 <extension
1618
       point="org.eclipse.wst.sse.ui.commentingStrategy">
1619
    <blockCommentingStrategy
1620
          prefix="&lt;!--"
1621
          suffix="--&gt;">
1622
       <contentType
1623
             id="org.eclipse.core.runtime.xml"
1624
             associatedCommentPartitionTypeID="org.eclipse.wst.xml.XML_COMMENT">
1625
          <allowablePartitionTypes
1626
                anyPartitionType="true">
1627
          </allowablePartitionTypes>
1628
       </contentType>
1629
    </blockCommentingStrategy>
1630
 </extension>
1664
1631
1665
</plugin>
1632
</plugin>
(-)plugin.properties (-6 / +1 lines)
Lines 132-140 Link Here
132
Colors.piBorder=Processing Instruction Border
132
Colors.piBorder=Processing Instruction Border
133
Colors.cdataBorder=CDATA Border
133
Colors.cdataBorder=CDATA Border
134
Colors.cdataText=CDATA Text
134
Colors.cdataText=CDATA Text
135
Colors.entityReference=Entity Reference
135
Colors.entityReference=Entity Reference
136
137
# Menu contributions
138
command.toggle.comment.mnemonic=T
139
command.add.block.comment.mnemonic=A
140
command.remove.block.comment.mnemonic=R
(-)src/org/eclipse/wst/xml/ui/internal/handlers/CommentHandler.java (-103 lines)
Removed Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 Standards for Technology in Automotive Retail and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     David Carver - initial API and implementation, bug 212330
10
 *     
11
 *******************************************************************************/
12
package org.eclipse.wst.xml.ui.internal.handlers;
13
14
import org.eclipse.core.commands.AbstractHandler;
15
import org.eclipse.core.commands.ExecutionEvent;
16
import org.eclipse.core.commands.ExecutionException;
17
import org.eclipse.core.commands.IHandler;
18
import org.eclipse.jface.text.BadLocationException;
19
import org.eclipse.jface.text.IDocument;
20
import org.eclipse.jface.text.ITextSelection;
21
import org.eclipse.jface.text.TextSelection;
22
import org.eclipse.jface.viewers.ISelection;
23
import org.eclipse.jface.viewers.ISelectionProvider;
24
import org.eclipse.ui.IEditorPart;
25
import org.eclipse.ui.handlers.HandlerUtil;
26
import org.eclipse.ui.texteditor.ITextEditor;
27
import org.eclipse.wst.xml.ui.internal.Logger;
28
29
public class CommentHandler extends AbstractHandler implements IHandler {
30
	static final String CLOSE_COMMENT = "-->"; //$NON-NLS-1$
31
	static final String OPEN_COMMENT = "<!--"; //$NON-NLS-1$
32
33
	public CommentHandler() {
34
		super();
35
	}
36
37
	public Object execute(ExecutionEvent event) throws ExecutionException {
38
		IEditorPart editor = HandlerUtil.getActiveEditor(event);
39
		ITextEditor textEditor = null;
40
		if (editor instanceof ITextEditor)
41
			textEditor = (ITextEditor) editor;
42
		else {
43
			Object o = editor.getAdapter(ITextEditor.class);
44
			if (o != null)
45
				textEditor = (ITextEditor) o;
46
		}
47
		if (textEditor != null) {
48
			IDocument document = textEditor.getDocumentProvider().getDocument(textEditor.getEditorInput());
49
			if (document != null) {
50
				// get current text selection
51
				ITextSelection textSelection = getCurrentSelection(textEditor);
52
				if (textSelection.isEmpty()) {
53
					return null;
54
				}
55
56
				processAction(textEditor, document, textSelection);
57
			}
58
		}
59
60
		return null;
61
	}
62
63
	protected ITextSelection getCurrentSelection(ITextEditor textEditor) {
64
		ISelectionProvider provider = textEditor.getSelectionProvider();
65
		if (provider != null) {
66
			ISelection selection = provider.getSelection();
67
			if (selection instanceof ITextSelection) {
68
				return (ITextSelection) selection;
69
			}
70
		}
71
		return TextSelection.emptySelection();
72
	}
73
74
	void processAction(ITextEditor textEditor, IDocument document, ITextSelection textSelection) {
75
		// Implementations to over ride.
76
	}
77
78
	protected void removeOpenCloseComments(IDocument document, int offset, int length) {
79
		try {
80
			int adjusted_length = length;
81
82
			// remove open comments
83
			String string = document.get(offset, length);
84
			int index = string.lastIndexOf(OPEN_COMMENT);
85
			while (index != -1) {
86
				document.replace(offset + index, OPEN_COMMENT.length(), ""); //$NON-NLS-1$
87
				index = string.lastIndexOf(OPEN_COMMENT, index - 1);
88
				adjusted_length -= OPEN_COMMENT.length();
89
			}
90
91
			// remove close comments
92
			string = document.get(offset, adjusted_length);
93
			index = string.lastIndexOf(CLOSE_COMMENT);
94
			while (index != -1) {
95
				document.replace(offset + index, CLOSE_COMMENT.length(), ""); //$NON-NLS-1$
96
				index = string.lastIndexOf(CLOSE_COMMENT, index - 1);
97
			}
98
		}
99
		catch (BadLocationException e) {
100
			Logger.log(Logger.WARNING_DEBUG, e.getMessage(), e);
101
		}
102
	}
103
}
(-)src/org/eclipse/wst/xml/ui/internal/handlers/RemoveBlockCommentHandler.java (-84 lines)
Removed Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 Standards for Technology in Automotive Retail and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     David Carver - initial API and implementation, bug 212330
10
 *     
11
 *******************************************************************************/
12
package org.eclipse.wst.xml.ui.internal.handlers;
13
14
import org.eclipse.core.commands.IHandler;
15
import org.eclipse.jface.text.BadLocationException;
16
import org.eclipse.jface.text.IDocument;
17
import org.eclipse.jface.text.ITextSelection;
18
import org.eclipse.ui.texteditor.ITextEditor;
19
import org.eclipse.wst.sse.core.StructuredModelManager;
20
import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
21
import org.eclipse.wst.sse.core.internal.provisional.IndexedRegion;
22
import org.eclipse.wst.xml.core.internal.document.CommentImpl;
23
import org.eclipse.wst.xml.ui.internal.Logger;
24
import org.eclipse.wst.xml.ui.internal.XMLUIMessages;
25
26
/**
27
 * @author dcarver
28
 * 
29
 */
30
public class RemoveBlockCommentHandler extends CommentHandler implements IHandler {
31
32
	public RemoveBlockCommentHandler() {
33
		super();
34
	}
35
36
	void processAction(ITextEditor textEditor, IDocument document, ITextSelection textSelection) {
37
		IStructuredModel model = StructuredModelManager.getModelManager().getExistingModelForEdit(document);
38
		if (model != null) {
39
			try {
40
				IndexedRegion selectionStartIndexedRegion = model.getIndexedRegion(textSelection.getOffset());
41
				IndexedRegion selectionEndIndexedRegion = model.getIndexedRegion(textSelection.getOffset() + textSelection.getLength());
42
43
				if ((selectionStartIndexedRegion == null) || (selectionEndIndexedRegion == null)) {
44
					return;
45
				}
46
47
				int openCommentOffset = selectionStartIndexedRegion.getStartOffset();
48
				int closeCommentOffset = selectionEndIndexedRegion.getEndOffset() - OPEN_COMMENT.length() - CLOSE_COMMENT.length();
49
50
				model.beginRecording(this, XMLUIMessages.RemoveBlockComment_tooltip);
51
				model.aboutToChangeModel();
52
53
				try {
54
					if (textSelection.getLength() == 0) {
55
						if (selectionStartIndexedRegion instanceof CommentImpl) {
56
							document.replace(openCommentOffset, OPEN_COMMENT.length(), ""); //$NON-NLS-1$
57
							document.replace(closeCommentOffset, CLOSE_COMMENT.length(), ""); //$NON-NLS-1$
58
						}
59
					}
60
					else {
61
						if (selectionStartIndexedRegion instanceof CommentImpl) {
62
							document.replace(openCommentOffset, OPEN_COMMENT.length(), ""); //$NON-NLS-1$
63
						}
64
65
						if (selectionEndIndexedRegion instanceof CommentImpl) {
66
							document.replace(closeCommentOffset, CLOSE_COMMENT.length(), ""); //$NON-NLS-1$
67
						}
68
					}
69
					removeOpenCloseComments(document, openCommentOffset + OPEN_COMMENT.length(), closeCommentOffset - openCommentOffset - CLOSE_COMMENT.length());
70
				}
71
				catch (BadLocationException e) {
72
					Logger.log(Logger.WARNING_DEBUG, e.getMessage(), e);
73
				}
74
				finally {
75
					model.changedModel();
76
					model.endRecording(this);
77
				}
78
			}
79
			finally {
80
				model.releaseFromEdit();
81
			}
82
		}
83
	}
84
}
(-)src/org/eclipse/wst/xml/ui/internal/handlers/AddBlockCommentHandler.java (-77 lines)
Removed Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 Standards for Technology in Automotive Retail and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     David Carver - initial API and implementation, bug 212330
10
 *     
11
 *******************************************************************************/
12
package org.eclipse.wst.xml.ui.internal.handlers;
13
14
import org.eclipse.core.commands.IHandler;
15
import org.eclipse.jface.text.BadLocationException;
16
import org.eclipse.jface.text.IDocument;
17
import org.eclipse.jface.text.ITextSelection;
18
import org.eclipse.ui.texteditor.ITextEditor;
19
import org.eclipse.wst.sse.core.StructuredModelManager;
20
import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
21
import org.eclipse.wst.sse.core.internal.provisional.IndexedRegion;
22
import org.eclipse.wst.xml.core.internal.document.CommentImpl;
23
import org.eclipse.wst.xml.ui.internal.Logger;
24
import org.eclipse.wst.xml.ui.internal.XMLUIMessages;
25
26
public class AddBlockCommentHandler extends CommentHandler implements IHandler {
27
28
	public AddBlockCommentHandler() {
29
		super();
30
	}
31
32
	void processAction(ITextEditor textEditor, IDocument document, ITextSelection textSelection) {
33
		IStructuredModel model = StructuredModelManager.getModelManager().getExistingModelForEdit(document);
34
		if (model != null) {
35
			try {
36
				IndexedRegion selectionStartIndexedRegion = model.getIndexedRegion(textSelection.getOffset());
37
				IndexedRegion selectionEndIndexedRegion = model.getIndexedRegion(textSelection.getOffset() + textSelection.getLength());
38
39
				if (selectionStartIndexedRegion == null) {
40
					return;
41
				}
42
				if ((selectionEndIndexedRegion == null) && (textSelection.getLength() > 0)) {
43
					selectionEndIndexedRegion = model.getIndexedRegion(textSelection.getOffset() + textSelection.getLength() - 1);
44
				}
45
				if (selectionEndIndexedRegion == null) {
46
					return;
47
				}
48
49
				int openCommentOffset = selectionStartIndexedRegion.getStartOffset();
50
				int closeCommentOffset = selectionEndIndexedRegion.getEndOffset() + OPEN_COMMENT.length();
51
52
				if ((textSelection.getLength() == 0) && (selectionStartIndexedRegion instanceof CommentImpl)) {
53
					return;
54
				}
55
56
				model.beginRecording(this, XMLUIMessages.AddBlockComment_tooltip);
57
				model.aboutToChangeModel();
58
59
				try {
60
					document.replace(openCommentOffset, 0, OPEN_COMMENT);
61
					document.replace(closeCommentOffset, 0, CLOSE_COMMENT);
62
					super.removeOpenCloseComments(document, openCommentOffset + OPEN_COMMENT.length(), closeCommentOffset - openCommentOffset - CLOSE_COMMENT.length());
63
				}
64
				catch (BadLocationException e) {
65
					Logger.log(Logger.WARNING_DEBUG, e.getMessage(), e);
66
				}
67
				finally {
68
					model.changedModel();
69
					model.endRecording(this);
70
				}
71
			}
72
			finally {
73
				model.releaseFromEdit();
74
			}
75
		}
76
	}
77
}
(-)src/org/eclipse/wst/xml/ui/internal/handlers/ToggleCommentHandler.java (-193 lines)
Removed Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 Standards for Technology in Automotive Retail and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     David Carver - initial API and implementation, bug 212330
10
 *     
11
 *******************************************************************************/
12
package org.eclipse.wst.xml.ui.internal.handlers;
13
14
import org.eclipse.core.commands.ExecutionEvent;
15
import org.eclipse.core.commands.ExecutionException;
16
import org.eclipse.core.commands.IHandler;
17
import org.eclipse.jface.text.BadLocationException;
18
import org.eclipse.jface.text.IDocument;
19
import org.eclipse.jface.text.IRegion;
20
import org.eclipse.jface.text.ITextSelection;
21
import org.eclipse.jface.text.Position;
22
import org.eclipse.jface.text.TextSelection;
23
import org.eclipse.jface.viewers.ISelectionProvider;
24
import org.eclipse.ui.IEditorPart;
25
import org.eclipse.ui.handlers.HandlerUtil;
26
import org.eclipse.ui.texteditor.ITextEditor;
27
import org.eclipse.wst.sse.core.StructuredModelManager;
28
import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
29
import org.eclipse.wst.xml.ui.internal.Logger;
30
import org.eclipse.wst.xml.ui.internal.XMLUIMessages;
31
32
public class ToggleCommentHandler extends CommentHandler implements IHandler {
33
	public ToggleCommentHandler() {
34
		super();
35
	}
36
37
	public Object execute(ExecutionEvent event) throws ExecutionException {
38
		IEditorPart editor = HandlerUtil.getActiveEditor(event);
39
		ITextEditor textEditor = null;
40
		if (editor instanceof ITextEditor)
41
			textEditor = (ITextEditor) editor;
42
		else {
43
			Object o = editor.getAdapter(ITextEditor.class);
44
			if (o != null)
45
				textEditor = (ITextEditor) o;
46
		}
47
		if (textEditor != null) {
48
			IDocument document = textEditor.getDocumentProvider().getDocument(textEditor.getEditorInput());
49
			if (document != null) {
50
				// get current text selection
51
				ITextSelection textSelection = getCurrentSelection(textEditor);
52
				if (textSelection.isEmpty()) {
53
					return null;
54
				}
55
56
				processAction(textEditor, document, textSelection);
57
			}
58
		}
59
		return null;
60
	}
61
62
	void processAction(ITextEditor textEditor, IDocument document, ITextSelection textSelection) {
63
		// get text selection lines info
64
		int selectionStartLine = textSelection.getStartLine();
65
		int selectionEndLine = textSelection.getEndLine();
66
		try {
67
			int selectionEndLineOffset = document.getLineOffset(selectionEndLine);
68
			int selectionEndOffset = textSelection.getOffset() + textSelection.getLength();
69
70
			// adjust selection end line
71
			if ((selectionEndLine > selectionStartLine) && (selectionEndLineOffset == selectionEndOffset)) {
72
				selectionEndLine--;
73
			}
74
75
		}
76
		catch (BadLocationException e) {
77
			Logger.log(Logger.WARNING_DEBUG, e.getMessage(), e);
78
		}
79
80
		// save the selection position since it will be changing
81
		Position selectionPosition = null;
82
		boolean updateStartOffset = false;
83
		try {
84
			selectionPosition = new Position(textSelection.getOffset(), textSelection.getLength());
85
			document.addPosition(selectionPosition);
86
87
			// extra check if commenting from beginning of line
88
			int selectionStartLineOffset = document.getLineOffset(selectionStartLine);
89
			if ((textSelection.getLength() > 0) && (selectionStartLineOffset == textSelection.getOffset()) && !isCommentLine(document, selectionStartLine)) {
90
				updateStartOffset = true;
91
			}
92
		}
93
		catch (BadLocationException e) {
94
			Logger.log(Logger.WARNING_DEBUG, e.getMessage(), e);
95
		}
96
97
		processAction(document, selectionStartLine, selectionEndLine);
98
99
		updateCurrentSelection(textEditor, selectionPosition, document, updateStartOffset);
100
	}
101
102
	private void processAction(IDocument document, int selectionStartLine, int selectionEndLine) {
103
		IStructuredModel model = StructuredModelManager.getModelManager().getExistingModelForEdit(document);
104
		if (model != null) {
105
			try {
106
				model.beginRecording(this, XMLUIMessages.ToggleComment_tooltip);
107
				model.aboutToChangeModel();
108
109
				for (int i = selectionStartLine; i <= selectionEndLine; i++) {
110
					try {
111
						if (document.getLineLength(i) > 0) {
112
							if (isCommentLine(document, i)) {
113
								int lineOffset = document.getLineOffset(i);
114
								IRegion region = document.getLineInformation(i);
115
								String string = document.get(region.getOffset(), region.getLength());
116
								int openCommentOffset = lineOffset + string.indexOf(OPEN_COMMENT);
117
								int closeCommentOffset = lineOffset + string.indexOf(CLOSE_COMMENT) - OPEN_COMMENT.length();
118
								uncomment(document, openCommentOffset, closeCommentOffset);
119
							}
120
							else {
121
								int openCommentOffset = document.getLineOffset(i);
122
								int lineDelimiterLength = document.getLineDelimiter(i) == null ? 0 : document.getLineDelimiter(i).length();
123
								int closeCommentOffset = openCommentOffset + document.getLineLength(i) - lineDelimiterLength + OPEN_COMMENT.length();
124
								comment(document, openCommentOffset, closeCommentOffset);
125
							}
126
						}
127
					}
128
					catch (BadLocationException e) {
129
						Logger.log(Logger.WARNING_DEBUG, e.getMessage(), e);
130
					}
131
				}
132
			}
133
			finally {
134
				model.changedModel();
135
				model.endRecording(this);
136
				model.releaseFromEdit();
137
			}
138
		}
139
	}
140
141
	private boolean isCommentLine(IDocument document, int line) {
142
		boolean isComment = false;
143
144
		try {
145
			IRegion region = document.getLineInformation(line);
146
			String string = document.get(region.getOffset(), region.getLength()).trim();
147
			isComment = (string.length() >= OPEN_COMMENT.length() + CLOSE_COMMENT.length()) && string.startsWith(OPEN_COMMENT) && string.endsWith(CLOSE_COMMENT);
148
		}
149
		catch (BadLocationException e) {
150
			Logger.log(Logger.WARNING_DEBUG, e.getMessage(), e);
151
		}
152
		return isComment;
153
	}
154
155
	private void comment(IDocument document, int openCommentOffset, int closeCommentOffset) {
156
		try {
157
			document.replace(openCommentOffset, 0, OPEN_COMMENT);
158
			document.replace(closeCommentOffset, 0, CLOSE_COMMENT);
159
			removeOpenCloseComments(document, openCommentOffset + OPEN_COMMENT.length(), closeCommentOffset - openCommentOffset - CLOSE_COMMENT.length());
160
		}
161
		catch (BadLocationException e) {
162
			Logger.log(Logger.WARNING_DEBUG, e.getMessage(), e);
163
		}
164
	}
165
166
	private void uncomment(IDocument document, int openCommentOffset, int closeCommentOffset) {
167
		try {
168
			document.replace(openCommentOffset, OPEN_COMMENT.length(), ""); //$NON-NLS-1$
169
			document.replace(closeCommentOffset, CLOSE_COMMENT.length(), ""); //$NON-NLS-1$
170
		}
171
		catch (BadLocationException e) {
172
			Logger.log(Logger.WARNING_DEBUG, e.getMessage(), e);
173
		}
174
	}
175
176
	private void updateCurrentSelection(ITextEditor textEditor, Position selectionPosition, IDocument document, boolean updateStartOffset) {
177
		// update the selection if text selection changed
178
		if (selectionPosition != null) {
179
			ITextSelection selection = null;
180
			if (updateStartOffset) {
181
				selection = new TextSelection(document, selectionPosition.getOffset() - OPEN_COMMENT.length(), selectionPosition.getLength() + OPEN_COMMENT.length());
182
			}
183
			else {
184
				selection = new TextSelection(document, selectionPosition.getOffset(), selectionPosition.getLength());
185
			}
186
			ISelectionProvider provider = textEditor.getSelectionProvider();
187
			if (provider != null) {
188
				provider.setSelection(selection);
189
			}
190
			document.removePosition(selectionPosition);
191
		}
192
	}
193
}
(-)plugin.xml (-4 / +72 lines)
Lines 60-66 Link Here
60
			target="org.eclipse.wst.html.core.htmlsource" />
60
			target="org.eclipse.wst.html.core.htmlsource" />
61
		<provisionalDefinition
61
		<provisionalDefinition
62
			type="activecontexts"
62
			type="activecontexts"
63
			value="org.eclipse.wst.html.core.htmlsource, org.eclipse.wst.html.occurrences, org.eclipse.core.runtime.xml, org.eclipse.wst.xml.navigation, org.eclipse.wst.xml.comments, org.eclipse.wst.xml.selection"
63
			value="org.eclipse.wst.html.core.htmlsource, org.eclipse.wst.html.occurrences, org.eclipse.core.runtime.xml, org.eclipse.wst.xml.navigation, org.eclipse.wst.html.comments, org.eclipse.wst.xml.selection"
64
        	target="org.eclipse.wst.html.core.htmlsource" />
64
        	target="org.eclipse.wst.html.core.htmlsource" />
65
	</extension>
65
	</extension>
66
	<extension
66
	<extension
Lines 275-280 Link Here
275
			description="%scope.structured.text.editor.html.occurrences.description"
275
			description="%scope.structured.text.editor.html.occurrences.description"
276
			id="org.eclipse.wst.html.occurrences">
276
			id="org.eclipse.wst.html.occurrences">
277
		</context>
277
		</context>
278
		<context
279
			name="%scope.structured.text.editor.html.comments.name"
280
			parentId="org.eclipse.wst.sse.ui.structuredTextEditorScope"
281
			description="%scope.structured.text.editor.html.comments.description"
282
			id="org.eclipse.wst.html.comments">
283
		</context>
278
	</extension>
284
	</extension>
279
	
285
	
280
	<!-- initialize html ui preferences -->
286
	<!-- initialize html ui preferences -->
Lines 536-542 Link Here
536
             	</reference>
542
             	</reference>
537
             </enabledWhen>
543
             </enabledWhen>
538
       </handler>
544
       </handler>
539
       
545
       <handler
546
			class="org.eclipse.wst.sse.ui.handlers.ToggleLineCommentHandler"
547
			commandId="org.eclipse.wst.sse.ui.toggle.comment">
548
			<activeWhen>
549
				<reference definitionId="org.eclipse.wst.html.ui.comments"/>
550
			</activeWhen>
551
			<enabledWhen>
552
				<reference definitionId="org.eclipse.wst.html.ui.comments"/>
553
			</enabledWhen>
554
		</handler>
555
		<handler
556
			class="org.eclipse.wst.sse.ui.handlers.AddBlockCommentHandler"
557
			commandId="org.eclipse.wst.sse.ui.add.block.comment">
558
			<activeWhen>
559
				<reference definitionId="org.eclipse.wst.html.ui.comments"/>
560
			</activeWhen>
561
			<enabledWhen>
562
				<reference definitionId="org.eclipse.wst.html.ui.comments"/>
563
			</enabledWhen>
564
		</handler>
565
		<handler
566
			class="org.eclipse.wst.sse.ui.handlers.RemoveBlockCommentHandler"
567
			commandId="org.eclipse.wst.sse.ui.remove.block.comment">
568
			<activeWhen>
569
				<reference definitionId="org.eclipse.wst.html.ui.comments"/>
570
			</activeWhen>
571
			<enabledWhen>
572
				<reference definitionId="org.eclipse.wst.html.ui.comments"/>
573
			</enabledWhen>
574
		</handler>
540
	</extension>
575
	</extension>
541
	
576
	
542
	<extension
577
	<extension
Lines 582-588 Link Here
582
            </with>
617
            </with>
583
		</definition>
618
		</definition>
584
	</extension>
619
	</extension>
585
	
620
	<!-- Set up a definition for HTML Comments handler -->
621
	<extension point="org.eclipse.core.expressions.definitions">
622
		<definition id="org.eclipse.wst.html.ui.comments">
623
			<with variable="activeContexts">
624
				<iterate operator="or">
625
					<equals value="org.eclipse.wst.html.comments"/>
626
				</iterate>
627
			</with>
628
		</definition>
629
	</extension>
630
586
	<!-- Define theme - Many of the color overrides and definitions come from 
631
	<!-- Define theme - Many of the color overrides and definitions come from 
587
	     the XML plugin -->
632
	     the XML plugin -->
588
	<extension
633
	<extension
Lines 636-640 Link Here
636
			</contentTypeIdentifier>
681
			</contentTypeIdentifier>
637
		</inserter>
682
		</inserter>
638
	</extension>
683
	</extension>
639
	
684
685
	<extension
686
       point="org.eclipse.wst.sse.ui.commentingStrategy">
687
    <blockCommentingStrategy
688
          prefix="&lt;!--"
689
          suffix="--&gt;">
690
       <contentType
691
             id="org.eclipse.wst.html.core.htmlsource"
692
             associatedCommentPartitionTypeID="org.eclipse.wst.html.HTML_COMMENT">
693
          <allowablePartitionTypes
694
                anyPartitionType="false">
695
             <partitionType
696
                   id="org.eclipse.wst.html.HTML_DEFAULT">
697
             </partitionType>
698
             <partitionType
699
                   id="org.eclipse.wst.html.HTML_DECLARATION">
700
             </partitionType>
701
             <partitionType
702
                   id="org.eclipse.wst.xml.XML_PI">
703
             </partitionType>
704
          </allowablePartitionTypes>
705
       </contentType>
706
    </blockCommentingStrategy>
707
 </extension>
640
</plugin>
708
</plugin>
(-)plugin.properties (+2 lines)
Lines 70-75 Link Here
70
scope.structured.text.editor.html.description=Editing HTML Source
70
scope.structured.text.editor.html.description=Editing HTML Source
71
scope.structured.text.editor.html.occurrences.name=HTML Source Occurrences
71
scope.structured.text.editor.html.occurrences.name=HTML Source Occurrences
72
scope.structured.text.editor.html.occurrences.description=HTML Source Occurrences
72
scope.structured.text.editor.html.occurrences.description=HTML Source Occurrences
73
scope.structured.text.editor.html.comments.name=HTML Source Comments
74
scope.structured.text.editor.html.comments.description=HTML Source Comments
73
75
74
Colors.scriptAreaBorder=Script Area Border
76
Colors.scriptAreaBorder=Script Area Border
75
hyperlinkDetector.anchor.name=Anchors
77
hyperlinkDetector.anchor.name=Anchors
(-)src/org/eclipse/wst/html/core/text/IHTMLPartitions.java (-1 / +5 lines)
Lines 1-5 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2005, 2007 IBM Corporation and others.
2
 * Copyright (c) 2005, 2010 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
Lines 26-31 Link Here
26
26
27
	String SCRIPT = "org.eclipse.wst.html.SCRIPT"; //$NON-NLS-1$
27
	String SCRIPT = "org.eclipse.wst.html.SCRIPT"; //$NON-NLS-1$
28
	String SCRIPT_EVENTHANDLER = SCRIPT + ".EVENTHANDLER"; //$NON-NLS-1$
28
	String SCRIPT_EVENTHANDLER = SCRIPT + ".EVENTHANDLER"; //$NON-NLS-1$
29
	
30
	/**
31
	 * @deprecated this partition type is not used locally any longer
32
	 */
29
	String STYLE = "org.eclipse.wst.html.STYLE"; //$NON-NLS-1$
33
	String STYLE = "org.eclipse.wst.html.STYLE"; //$NON-NLS-1$
30
34
31
	// ISSUE: I think meta tag areas are here too?
35
	// ISSUE: I think meta tag areas are here too?

Return to bug 86520