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

Collapse All | Expand All

(-)plugin.xml (-94 / +15 lines)
Lines 83-89 Link Here
83
			target="org.eclipse.core.runtime.xml, org.eclipse.wst.xml.core.xmlsource" />
83
			target="org.eclipse.core.runtime.xml, org.eclipse.wst.xml.core.xmlsource" />
84
		<provisionalDefinition
84
		<provisionalDefinition
85
			type="activecontexts"
85
			type="activecontexts"
86
			value="org.eclipse.core.runtime.xml, org.eclipse.wst.xml.navigation, org.eclipse.wst.xml.cleanup, org.eclipse.wst.xml.comments, org.eclipse.wst.xml.selection, org.eclipse.wst.xml.dependencies, org.eclipse.wst.xml.grammar, org.eclipse.wst.xml.expand, org.eclipse.wst.xml.occurrences"
86
			value="org.eclipse.core.runtime.xml, org.eclipse.wst.xml.navigation, org.eclipse.wst.xml.cleanup, org.eclipse.wst.xml.selection, org.eclipse.wst.xml.dependencies, org.eclipse.wst.xml.grammar, org.eclipse.wst.xml.expand, org.eclipse.wst.xml.occurrences"
87
        	target="org.eclipse.core.runtime.xml" />
87
        	target="org.eclipse.core.runtime.xml" />
88
	</extension>
88
	</extension>
89
	
89
	
Lines 107-118 Link Here
107
			id="org.eclipse.wst.xml.cleanup">
107
			id="org.eclipse.wst.xml.cleanup">
108
		</context>
108
		</context>
109
		<context
109
		<context
110
			name="%scope.structured.text.editor.xml.comments.name"
111
			parentId="org.eclipse.wst.sse.ui.structuredTextEditorScope"
112
			description="%scope.structured.text.editor.xml.comments.description"
113
			id="org.eclipse.wst.xml.comments">
114
		</context>
115
		<context
116
			name="%scope.structured.text.editor.xml.selection.name"
110
			name="%scope.structured.text.editor.xml.selection.name"
117
			parentId="org.eclipse.wst.sse.ui.structuredTextEditorScope"
111
			parentId="org.eclipse.wst.sse.ui.structuredTextEditorScope"
118
			description="%scope.structured.text.editor.xml.selection.description"
112
			description="%scope.structured.text.editor.xml.selection.description"
Lines 1005-1057 Link Here
1005
           </command>
999
           </command>
1006
        </toolbar>
1000
        </toolbar>
1007
     </menuContribution>
1001
     </menuContribution>
1008
     
1009
     <menuContribution locationURI="menu:sourceMenuId?after=sourceBegin">
1010
			<command commandId="org.eclipse.wst.sse.ui.toggle.comment"
1011
			         id="ToggleComment"
1012
			         mnemonic="%command.toggle.comment.mnemonic"
1013
			         style="push">
1014
				<visibleWhen checkEnabled="false">
1015
					<reference definitionId="org.eclipse.wst.xml.ui.comments"/>
1016
				</visibleWhen>
1017
			</command>
1018
			<command commandId="org.eclipse.wst.sse.ui.add.block.comment"
1019
			         id="AddBlockComment"
1020
			         mnemonic="%command.add.block.comment.mnemonic"
1021
			         style="push">
1022
				<visibleWhen checkEnabled="false">
1023
					<reference definitionId="org.eclipse.wst.xml.ui.comments"/>
1024
				</visibleWhen>
1025
			</command>
1026
			<command commandId="org.eclipse.wst.sse.ui.remove.block.comment"
1027
			         id="RemoveBlockComment"
1028
			         mnemonic="%command.remove.block.comment.mnemonic"
1029
			         style="push">
1030
				<visibleWhen checkEnabled="false">
1031
					<reference definitionId="org.eclipse.wst.xml.ui.comments"/>
1032
				</visibleWhen>
1033
			</command>
1034
		</menuContribution>
1035
		
1036
		<menuContribution
1037
	           locationURI="popup:sourcePopupMenuId?after=sourceBegin">
1038
				<command commandId="org.eclipse.wst.sse.ui.toggle.comment" id="ToggleComment" style="push">
1039
					<visibleWhen checkEnabled="false">
1040
						<reference definitionId="org.eclipse.wst.xml.ui.comments"></reference>
1041
					</visibleWhen>
1042
				</command>
1043
				<command commandId="org.eclipse.wst.sse.ui.add.block.comment" id="AddBlockComment" style="push">
1044
					<visibleWhen checkEnabled="false">
1045
						<reference definitionId="org.eclipse.wst.xml.ui.comments"></reference>
1046
					</visibleWhen>
1047
				</command>
1048
				<command commandId="org.eclipse.wst.sse.ui.remove.block.comment" id="RemoveBlockComment" style="push">
1049
					<visibleWhen checkEnabled="false">
1050
						<reference definitionId="org.eclipse.wst.xml.ui.comments"></reference>
1051
					</visibleWhen>
1052
				</command>
1053
				<separator name="format" visible="true"></separator>
1054
		</menuContribution>
1055
	</extension>
1002
	</extension>
1056
	
1003
	
1057
	<extension point="org.eclipse.core.expressions.definitions">
1004
	<extension point="org.eclipse.core.expressions.definitions">
Lines 1085-1100 Link Here
1085
	</extension>
1032
	</extension>
1086
	
1033
	
1087
	<extension point="org.eclipse.core.expressions.definitions">
1034
	<extension point="org.eclipse.core.expressions.definitions">
1088
		<definition id="org.eclipse.wst.xml.ui.comments">
1089
			<with variable="activeContexts">
1090
				<iterate operator="or">
1091
					<equals value="org.eclipse.wst.xml.comments"/>
1092
				</iterate>
1093
			</with>
1094
		</definition>
1095
	</extension>
1096
	
1097
	<extension point="org.eclipse.core.expressions.definitions">
1098
		<definition id="org.eclipse.wst.xml.ui.cleanup">
1035
		<definition id="org.eclipse.wst.xml.ui.cleanup">
1099
			<with variable="activeContexts">
1036
			<with variable="activeContexts">
1100
				<iterate operator="or">
1037
				<iterate operator="or">
Lines 1182-1217 Link Here
1182
          </enabledWhen>
1119
          </enabledWhen>
1183
       </handler>
1120
       </handler>
1184
       <handler
1121
       <handler
1185
             class="org.eclipse.wst.xml.ui.internal.handlers.ToggleCommentHandler"
1186
             commandId="org.eclipse.wst.sse.ui.toggle.comment">
1187
          <activeWhen>
1188
              <reference definitionId="org.eclipse.wst.xml.ui.comments"/>
1189
          </activeWhen>
1190
          <enabledWhen>
1191
              <reference definitionId="org.eclipse.wst.xml.ui.comments"/>
1192
          </enabledWhen>
1193
       </handler>
1194
       <handler
1195
             class="org.eclipse.wst.xml.ui.internal.handlers.AddBlockCommentHandler"
1196
             commandId="org.eclipse.wst.sse.ui.add.block.comment">
1197
          <activeWhen>
1198
              <reference definitionId="org.eclipse.wst.xml.ui.comments"/>
1199
          </activeWhen>
1200
          <enabledWhen>
1201
              <reference definitionId="org.eclipse.wst.xml.ui.comments"/>
1202
          </enabledWhen>
1203
       </handler>
1204
       <handler
1205
             class="org.eclipse.wst.xml.ui.internal.handlers.RemoveBlockCommentHandler"
1206
             commandId="org.eclipse.wst.sse.ui.remove.block.comment">
1207
          <activeWhen>
1208
              <reference definitionId="org.eclipse.wst.xml.ui.comments"/>
1209
          </activeWhen>
1210
          <enabledWhen>
1211
              <reference definitionId="org.eclipse.wst.xml.ui.comments"/>
1212
          </enabledWhen>
1213
       </handler>
1214
       <handler
1215
             class="org.eclipse.wst.xml.ui.internal.handlers.StructuredSelectEnclosingXMLHandler"
1122
             class="org.eclipse.wst.xml.ui.internal.handlers.StructuredSelectEnclosingXMLHandler"
1216
             commandId="org.eclipse.wst.sse.ui.structure.select.enclosing">
1123
             commandId="org.eclipse.wst.sse.ui.structure.select.enclosing">
1217
          <activeWhen>
1124
          <activeWhen>
Lines 1670-1675 Link Here
1670
    </inserter>
1577
    </inserter>
1671
 </extension>
1578
 </extension>
1672
 <extension
1579
 <extension
1580
       point="org.eclipse.wst.sse.ui.commentingStrategy">
1581
    <blockCommentingStrategy
1582
          prefix="&lt;!--"
1583
          suffix="--&gt;">
1584
       <contentType
1585
             id="org.eclipse.core.runtime.xml"
1586
             associatedCommentPartitionTypeID="org.eclipse.wst.xml.XML_COMMENT">
1587
          <allowablePartitionTypes
1588
                anyPartitionType="true">
1589
          </allowablePartitionTypes>
1590
       </contentType>
1591
    </blockCommentingStrategy>
1592
 </extension>
1593
 <extension
1673
       point="org.eclipse.wst.sse.ui.completionProposal">
1594
       point="org.eclipse.wst.sse.ui.completionProposal">
1674
    <proposalCategory
1595
    <proposalCategory
1675
          icon="icons/full/obj16/tag-generic.gif"
1596
          icon="icons/full/obj16/tag-generic.gif"
(-)plugin.properties (-6 lines)
Lines 136-147 Link Here
136
Colors.cdataBorder=CDATA Border
136
Colors.cdataBorder=CDATA Border
137
Colors.cdataText=CDATA Text
137
Colors.cdataText=CDATA Text
138
Colors.entityReference=Entity Reference
138
Colors.entityReference=Entity Reference
139
140
# Menu contributions
141
command.toggle.comment.mnemonic=T
142
command.add.block.comment.mnemonic=A
143
command.remove.block.comment.mnemonic=R
144
145
# content assist
139
# content assist
146
proposalCategory.xmlTags=XML Tag Proposals
140
proposalCategory.xmlTags=XML Tag Proposals
147
proposalCategory.xmlTemplates=XML Template Proposals
141
proposalCategory.xmlTemplates=XML Template Proposals
(-)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 (-2 / +37 lines)
Lines 63-69 Link Here
63
			target="org.eclipse.wst.html.core.htmlsource" />
63
			target="org.eclipse.wst.html.core.htmlsource" />
64
		<provisionalDefinition
64
		<provisionalDefinition
65
			type="activecontexts"
65
			type="activecontexts"
66
			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"
66
			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.selection, org.eclipse.wst.sse.comments"
67
        	target="org.eclipse.wst.html.core.htmlsource" />
67
        	target="org.eclipse.wst.html.core.htmlsource" />
68
	</extension>
68
	</extension>
69
	<extension
69
	<extension
Lines 617-623 Link Here
617
			</enabledWhen>
617
			</enabledWhen>
618
		</handler>
618
		</handler>
619
	</extension>
619
	</extension>
620
	
620
621
	<extension
622
       point="org.eclipse.wst.sse.ui.commentingStrategy">
623
    <blockCommentingStrategy
624
          prefix="&lt;!--"
625
          suffix="--&gt;">
626
       <contentType
627
             id="org.eclipse.wst.html.core.htmlsource"
628
             associatedCommentPartitionTypeID="org.eclipse.wst.html.HTML_COMMENT">
629
          <requiredPartitionTypes
630
                requireAll="false">
631
             <partitionType
632
                   id="org.eclipse.wst.html.HTML_DEFAULT">
633
             </partitionType>
634
             <partitionType
635
                   id="org.eclipse.wst.html.HTML_DECLARATION">
636
             </partitionType>
637
             <partitionType
638
                   id="org.eclipse.wst.html.SCRIPT.EVENTHANDLER">
639
             </partitionType>
640
             <partitionType
641
                   id="org.eclipse.wst.xml.XML_PI">
642
             </partitionType>
643
          </requiredPartitionTypes>
644
          <allowablePartitionTypes
645
                anyPartitionType="false">
646
             <partitionType
647
                   id="org.eclipse.wst.css.STYLE">
648
             </partitionType>
649
             <partitionType
650
                   id="org.eclipse.wst.html.SCRIPT">
651
             </partitionType>
652
          </allowablePartitionTypes>
653
       </contentType>
654
    </blockCommentingStrategy>
655
 </extension>
621
	<!-- Set up a definition for HTML Content Types -->
656
	<!-- Set up a definition for HTML Content Types -->
622
	<extension point="org.eclipse.core.expressions.definitions">
657
	<extension point="org.eclipse.core.expressions.definitions">
623
		<definition id="org.eclipse.wst.html.ui.htmlContentType.definition">
658
		<definition id="org.eclipse.wst.html.ui.htmlContentType.definition">
(-)plugin.xml (-90 / +39 lines)
Lines 50-56 Link Here
50
			target="org.eclipse.wst.css.core.csssource" />
50
			target="org.eclipse.wst.css.core.csssource" />
51
		<provisionalDefinition
51
		<provisionalDefinition
52
			type="activecontexts"
52
			type="activecontexts"
53
			value="org.eclipse.wst.css.core.csssource"
53
			value="org.eclipse.wst.css.core.csssource, org.eclipse.wst.sse.comments"
54
			target="org.eclipse.wst.css.core.csssource" />
54
			target="org.eclipse.wst.css.core.csssource" />
55
	</extension>
55
	</extension>
56
	
56
	
Lines 267-314 Link Here
267
			</enabledWhen>
267
			</enabledWhen>
268
		</handler>
268
		</handler>
269
		<handler
269
		<handler
270
             class="org.eclipse.wst.css.ui.internal.handlers.ToggleCommentHandler"
271
             commandId="org.eclipse.wst.sse.ui.toggle.comment">
272
             <activeWhen>
273
             	<reference
274
                    definitionId="org.eclipse.wst.css.ui.cssSourceContributions.definition">
275
             	</reference>
276
             </activeWhen>
277
             <enabledWhen>
278
             	<reference
279
                    definitionId="org.eclipse.wst.css.ui.cssSourceContributions.definition">
280
             	</reference>
281
             </enabledWhen>
282
       </handler>
283
       <handler
284
             class="org.eclipse.wst.css.ui.internal.handlers.AddBlockCommentHandler"
285
             commandId="org.eclipse.wst.sse.ui.add.block.comment">
286
             <activeWhen>
287
             	<reference
288
                    definitionId="org.eclipse.wst.css.ui.cssSourceContributions.definition">
289
             	</reference>
290
             </activeWhen>
291
             <enabledWhen>
292
             	<reference
293
                    definitionId="org.eclipse.wst.css.ui.cssSourceContributions.definition">
294
             	</reference>
295
             </enabledWhen>
296
       </handler>
297
       <handler
298
             class="org.eclipse.wst.css.ui.internal.handlers.RemoveBlockCommentHandler"
299
             commandId="org.eclipse.wst.sse.ui.remove.block.comment">
300
             <activeWhen>
301
             	<reference
302
                    definitionId="org.eclipse.wst.css.ui.cssSourceContributions.definition">
303
             	</reference>
304
             </activeWhen>
305
             <enabledWhen>
306
             	<reference
307
                    definitionId="org.eclipse.wst.css.ui.cssSourceContributions.definition">
308
             	</reference>
309
             </enabledWhen>
310
       </handler>
311
		<handler
312
			class="org.eclipse.wst.css.ui.internal.handlers.StructuredSelectEnclosingHandler"
270
			class="org.eclipse.wst.css.ui.internal.handlers.StructuredSelectEnclosingHandler"
313
			commandId="org.eclipse.wst.sse.ui.structure.select.enclosing">
271
			commandId="org.eclipse.wst.sse.ui.structure.select.enclosing">
314
			<activeWhen>
272
			<activeWhen>
Lines 351-403 Link Here
351
		</handler>
309
		</handler>
352
	</extension>
310
	</extension>
353
311
354
	<extension point="org.eclipse.ui.menus">
355
		<menuContribution
356
	       locationURI="popup:sourcePopupMenuId?before=sourceBegin">
357
			<command commandId="org.eclipse.wst.sse.ui.toggle.comment" id="ToggleComment" style="push">
358
				<visibleWhen checkEnabled="false">
359
					<reference definitionId="org.eclipse.wst.css.ui.cssSourceContributions.definition"/>
360
				</visibleWhen>
361
			</command>
362
			<command commandId="org.eclipse.wst.sse.ui.add.block.comment" id="AddBlockComment" style="push">
363
				<visibleWhen checkEnabled="false">
364
					<reference definitionId="org.eclipse.wst.css.ui.cssSourceContributions.definition" />
365
				</visibleWhen>
366
			</command>
367
			<command commandId="org.eclipse.wst.sse.ui.remove.block.comment" id="RemoveBlockComment" style="push">
368
				<visibleWhen checkEnabled="false">
369
					<reference definitionId="org.eclipse.wst.css.ui.cssSourceContributions.definition" />
370
				</visibleWhen>
371
			</command>
372
		</menuContribution>
373
374
		<menuContribution locationURI="menu:sourceMenuId?before=sourceBegin">
375
			<command commandId="org.eclipse.wst.sse.ui.toggle.comment"
376
			         id="ToggleComment"
377
			         mnemonic="%command.toggle.comment.mnemonic"
378
			         style="push">
379
				<visibleWhen checkEnabled="false">
380
					<reference definitionId="org.eclipse.wst.css.ui.cssSourceContributions.definition"/>
381
				</visibleWhen>
382
			</command>
383
			<command commandId="org.eclipse.wst.sse.ui.add.block.comment"
384
			         id="AddBlockComment"
385
			         mnemonic="%command.add.block.comment.mnemonic"
386
			         style="push">
387
				<visibleWhen checkEnabled="false">
388
					<reference definitionId="org.eclipse.wst.css.ui.cssSourceContributions.definition"/>
389
				</visibleWhen>
390
			</command>
391
			<command commandId="org.eclipse.wst.sse.ui.remove.block.comment"
392
			         id="RemoveBlockComment"
393
			         mnemonic="%command.remove.block.comment.mnemonic"
394
			         style="push">
395
				<visibleWhen checkEnabled="false">
396
					<reference definitionId="org.eclipse.wst.css.ui.cssSourceContributions.definition"/>
397
				</visibleWhen>
398
			</command>
399
		</menuContribution>
400
	</extension>
401
	<!-- CSS editor actions -->
312
	<!-- CSS editor actions -->
402
	<extension point="org.eclipse.ui.editorActions">
313
	<extension point="org.eclipse.ui.editorActions">
403
		<!--<editorContribution
314
		<!--<editorContribution
Lines 701-706 Link Here
701
		</inserter>
612
		</inserter>
702
	</extension>
613
	</extension>
703
 <extension
614
 <extension
615
       point="org.eclipse.wst.sse.ui.commentingStrategy">
616
    <blockCommentingStrategy
617
          prefix="/*"
618
          suffix="*/">
619
       <contentType
620
             id="org.eclipse.wst.html.core.htmlsource">
621
          <allowablePartitionTypes
622
                anyPartitionType="false">
623
          </allowablePartitionTypes>
624
          <requiredPartitionTypes
625
                requireAll="true">
626
             <partitionType
627
                   id="org.eclipse.wst.css.STYLE">
628
             </partitionType>
629
          </requiredPartitionTypes>
630
       </contentType>
631
       <contentType
632
             associatedCommentPartitionTypeID="org.eclipse.wst.css.COMMENT"
633
             id="org.eclipse.wst.css.core.csssource">
634
          <allowablePartitionTypes
635
                anyPartitionType="true">
636
          </allowablePartitionTypes>
637
       </contentType>
638
       <contentType
639
             id="org.eclipse.jst.jsp.core.jspsource">
640
          <allowablePartitionTypes
641
                anyPartitionType="false">
642
          </allowablePartitionTypes>
643
          <requiredPartitionTypes
644
                requireAll="true">
645
             <partitionType
646
                   id="org.eclipse.wst.css.STYLE">
647
             </partitionType>
648
          </requiredPartitionTypes>
649
       </contentType>
650
    </blockCommentingStrategy>
651
 </extension>
652
 <extension
704
       point="org.eclipse.wst.sse.ui.completionProposal">
653
       point="org.eclipse.wst.sse.ui.completionProposal">
705
    <proposalCategory
654
    <proposalCategory
706
          icon="icons/full/obj16/tag_selector.gif"
655
          icon="icons/full/obj16/tag_selector.gif"
(-)plugin.properties (-4 lines)
Lines 57-66 Link Here
57
scope.structured.text.editor.css.name=Editing CSS Source
57
scope.structured.text.editor.css.name=Editing CSS Source
58
scope.structured.text.editor.css.description=Editing CSS Source
58
scope.structured.text.editor.css.description=Editing CSS Source
59
59
60
command.toggle.comment.mnemonic=T
61
command.remove.block.comment.mnemonic=R
62
command.add.block.comment.mnemonic=A
63
64
Colors.atmarkRule=At Mark Rule
60
Colors.atmarkRule=At Mark Rule
65
Colors.selector=Selector
61
Colors.selector=Selector
66
Colors.media=Media
62
Colors.media=Media
(-)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 (-1 / +96 lines)
Lines 75-81 Link Here
75
			target="org.eclipse.jst.jsp.core.jspsource" />
75
			target="org.eclipse.jst.jsp.core.jspsource" />
76
		<provisionalDefinition
76
		<provisionalDefinition
77
			type="activecontexts"
77
			type="activecontexts"
78
			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"
78
			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.selection, , org.eclipse.wst.sse.comments"
79
        	target="org.eclipse.jst.jsp.core.jspsource" />
79
        	target="org.eclipse.jst.jsp.core.jspsource" />
80
80
81
		<contentOutlineConfiguration
81
		<contentOutlineConfiguration
Lines 1072-1077 Link Here
1072
		</inserter>
1072
		</inserter>
1073
	</extension>
1073
	</extension>
1074
 <extension
1074
 <extension
1075
       point="org.eclipse.wst.sse.ui.commentingStrategy">
1076
    <blockCommentingStrategy
1077
          prefix="&lt;!--"
1078
          suffix="--&gt;">
1079
       <contentType
1080
             associatedCommentPartitionTypeID="org.eclipse.wst.html.HTML_COMMENT"
1081
             id="org.eclipse.jst.jsp.core.jspsource">
1082
          <requiredPartitionTypes
1083
                requireAll="false">
1084
             <partitionType
1085
                   id="org.eclipse.wst.html.HTML_DEFAULT">
1086
             </partitionType>
1087
             <partitionType
1088
                   id="org.eclipse.wst.html.HTML_DECLARATION">
1089
             </partitionType>
1090
             <partitionType
1091
                   id="org.eclipse.wst.html.SCRIPT.EVENTHANDLER">
1092
             </partitionType>
1093
             <partitionType
1094
                   id="org.eclipse.wst.xml.XML_PI">
1095
             </partitionType>
1096
          </requiredPartitionTypes>
1097
          <allowablePartitionTypes
1098
                anyPartitionType="false">
1099
             <partitionType
1100
                   id="org.eclipse.wst.css.STYLE">
1101
             </partitionType>
1102
             <partitionType
1103
                   id="org.eclipse.wst.html.SCRIPT">
1104
             </partitionType>
1105
          </allowablePartitionTypes>
1106
       </contentType>
1107
    </blockCommentingStrategy>
1108
    <blockCommentingStrategy
1109
          prefix="&lt;%--"
1110
          suffix="--%&gt;">
1111
       <contentType
1112
             associatedCommentPartitionTypeID="org.eclipse.jst.jsp.JSP_COMMENT"
1113
             id="org.eclipse.jst.jsp.core.jspsource">
1114
          <requiredPartitionTypes
1115
                requireAll="false">
1116
             <partitionType
1117
                   id="org.eclipse.jst.jsp.JSP_DIRECTIVE">
1118
             </partitionType>
1119
             <partitionType
1120
                   id="org.eclipse.jst.jsp.DEFAULT_JSP">
1121
             </partitionType>
1122
             <partitionType
1123
                   id="org.eclipse.jst.jsp.SCRIPT.DELIMITER">
1124
             </partitionType>
1125
             <partitionType
1126
                   id="org.eclipse.jst.jsp.SCRIPT.JSP_EL">
1127
             </partitionType>
1128
             <partitionType
1129
                   id="org.eclipse.jst.jsp.SCRIPT.JSP_EL2">
1130
             </partitionType>
1131
          </requiredPartitionTypes>
1132
          <allowablePartitionTypes
1133
                anyPartitionType="true">
1134
          </allowablePartitionTypes>
1135
       </contentType>
1136
    </blockCommentingStrategy>
1137
    <blockCommentingStrategy
1138
          prefix="/*"
1139
          suffix="*/">
1140
       <contentType
1141
             id="org.eclipse.jst.jsp.core.jspsource">
1142
          <requiredPartitionTypes
1143
                requireAll="false">
1144
             <partitionType
1145
                   id="org.eclipse.jst.jsp.SCRIPT.JAVA">
1146
             </partitionType>
1147
          </requiredPartitionTypes>
1148
          <allowablePartitionTypes
1149
                anyPartitionType="false">
1150
          </allowablePartitionTypes>
1151
       </contentType>
1152
    </blockCommentingStrategy>
1153
    <lineCommentingStrategy
1154
          prefix="//">
1155
       <contentType
1156
             id="org.eclipse.jst.jsp.core.jspsource">
1157
          <requiredPartitionTypes
1158
                requireAll="false">
1159
             <partitionType
1160
                   id="org.eclipse.jst.jsp.SCRIPT.JAVA">
1161
             </partitionType>
1162
          </requiredPartitionTypes>
1163
          <allowablePartitionTypes
1164
                anyPartitionType="false">
1165
          </allowablePartitionTypes>
1166
       </contentType>
1167
    </lineCommentingStrategy>
1168
 </extension>
1169
 <extension
1075
       point="org.eclipse.wst.sse.ui.completionProposal">
1170
       point="org.eclipse.wst.sse.ui.completionProposal">
1076
    <proposalCategory
1171
    <proposalCategory
1077
          icon="icons/full/obj16/tag-template.gif"
1172
          icon="icons/full/obj16/tag-template.gif"
(-)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?
(-)plugin.xml (-1 / +67 lines)
Lines 210-215 Link Here
210
			description="%scope.structuredTextEditor.description"
210
			description="%scope.structuredTextEditor.description"
211
			id="org.eclipse.wst.sse.ui.structuredTextEditorScope">
211
			id="org.eclipse.wst.sse.ui.structuredTextEditorScope">
212
		</context>
212
		</context>
213
		<context
214
			name="%scope.structuredTextEditor.comments.name"
215
			parentId="org.eclipse.wst.sse.ui.structuredTextEditorScope"
216
			description="%scope.structuredTextEditor.comments.description"
217
			id="org.eclipse.wst.sse.comments">
218
		</context>
213
	</extension>
219
	</extension>
214
	<!-- Keybindings for source editor -->
220
	<!-- Keybindings for source editor -->
215
	<extension point="org.eclipse.ui.bindings">
221
	<extension point="org.eclipse.ui.bindings">
Lines 531-536 Link Here
531
		id="quickFixProcessor" 
537
		id="quickFixProcessor" 
532
		name="%quickFixProcessor" 
538
		name="%quickFixProcessor" 
533
		schema="schema/quickFixProcessor.exsd"/>
539
		schema="schema/quickFixProcessor.exsd"/>
540
 <extension-point id="commentingStrategy" name="%Commenting_Strategy_Extension.name" schema="schema/commentingStrategy.exsd"/>
534
 <extension-point id="completionProposal" name="%Completion_Proposal.name" schema="schema/completionProposal.exsd"/>
541
 <extension-point id="completionProposal" name="%Completion_Proposal.name" schema="schema/completionProposal.exsd"/>
535
 <extension-point id="completionProposalCategoriesConfiguration" name="%Completion_Proposal_Categories_Configuration.name" schema="schema/completionProposalCategoriesConfiguration.exsd"/>
542
 <extension-point id="completionProposalCategoriesConfiguration" name="%Completion_Proposal_Categories_Configuration.name" schema="schema/completionProposalCategoriesConfiguration.exsd"/>
536
 
543
 
Lines 661-668 Link Here
661
			</command>
668
			</command>
662
		</menuContribution>
669
		</menuContribution>
663
670
664
	     <menuContribution
671
		<menuContribution
665
	           locationURI="popup:sourcePopupMenuId?after=sourceBegin">
672
	           locationURI="popup:sourcePopupMenuId?after=sourceBegin">
673
			<command
674
					commandId="org.eclipse.wst.sse.ui.toggle.comment"
675
					id="ToggleComment"
676
					style="push">
677
				<visibleWhen checkEnabled="false">
678
					<reference definitionId="org.eclipse.wst.sse.ui.commentingActiveContext.definition"></reference>
679
				</visibleWhen>
680
			</command>
681
			<command
682
					commandId="org.eclipse.wst.sse.ui.add.block.comment"
683
					id="AddBlockComment"
684
					style="push">
685
				<visibleWhen checkEnabled="false">
686
					<reference definitionId="org.eclipse.wst.sse.ui.commentingActiveContext.definition"></reference>
687
				</visibleWhen>
688
			</command>
689
			<command
690
					commandId="org.eclipse.wst.sse.ui.remove.block.comment"
691
					id="RemoveBlockComment"
692
					style="push">
693
				<visibleWhen checkEnabled="false">
694
					<reference definitionId="org.eclipse.wst.sse.ui.commentingActiveContext.definition"></reference>
695
				</visibleWhen>
696
			</command>
697
			<separator name="format" visible="true"></separator>
666
				<command
698
				<command
667
			           commandId="org.eclipse.wst.sse.ui.cleanup.document"
699
			           commandId="org.eclipse.wst.sse.ui.cleanup.document"
668
			           id="CleanupDocument"
700
			           id="CleanupDocument"
Lines 691-696 Link Here
691
				</command>
723
				</command>
692
				
724
				
693
	     </menuContribution>
725
	     </menuContribution>
726
			<menuContribution locationURI="menu:sourceMenuId?after=sourceBegin">
727
				<command commandId="org.eclipse.wst.sse.ui.toggle.comment"
728
						id="ToggleComment"
729
				    mnemonic="%command.toggle.comment.mnemonic"
730
				    style="push">
731
					<visibleWhen checkEnabled="false">
732
						<reference definitionId="org.eclipse.wst.sse.ui.commentingActiveContext.definition"/>
733
					</visibleWhen>
734
				</command>
735
				<command commandId="org.eclipse.wst.sse.ui.add.block.comment"
736
						id="AddBlockComment"
737
				    mnemonic="%command.add.block.comment.mnemonic"
738
				    style="push">
739
					<visibleWhen checkEnabled="false">
740
						<reference definitionId="org.eclipse.wst.sse.ui.commentingActiveContext.definition"/>
741
					</visibleWhen>
742
				</command>
743
				<command commandId="org.eclipse.wst.sse.ui.remove.block.comment"
744
						id="RemoveBlockComment"
745
						mnemonic="%command.remove.block.comment.mnemonic"
746
						style="push">
747
					<visibleWhen checkEnabled="false">
748
						<reference definitionId="org.eclipse.wst.sse.ui.commentingActiveContext.definition"/>
749
					</visibleWhen>
750
				</command>
751
			</menuContribution>
694
	</extension>
752
	</extension>
695
	<extension
753
	<extension
696
       point="org.eclipse.ui.commands">
754
       point="org.eclipse.ui.commands">
Lines 730-735 Link Here
730
	           </iterate>
788
	           </iterate>
731
            </with>
789
            </with>
732
		</definition>
790
		</definition>
791
	  <definition 
792
	  		id="org.eclipse.wst.sse.ui.commentingActiveContext.definition">
793
	  	<with variable="activeContexts">
794
				<iterate operator="or">
795
					<equals value="org.eclipse.wst.sse.comments"/>
796
				</iterate>
797
			</with>
798
	  </definition>
733
	</extension>
799
	</extension>
734
	
800
	
735
	<!-- Define theme -->
801
	<!-- Define theme -->
(-)plugin.properties (+6 lines)
Lines 30-46 Link Here
30
Character_Pairing.name=Character Pairing Extension
30
Character_Pairing.name=Character Pairing Extension
31
Completion_Proposal.name=Completion Proposal
31
Completion_Proposal.name=Completion Proposal
32
Completion_Proposal_Categories_Configuration.name=Completion Proposal Categories Configuration
32
Completion_Proposal_Categories_Configuration.name=Completion Proposal Categories Configuration
33
Commenting_Strategy_Extension.name=Commenting Strategy Extension
33
##########################################################################
34
##########################################################################
34
# These strings are used in Workbench Keys Preferences
35
# These strings are used in Workbench Keys Preferences
35
##########################################################################
36
##########################################################################
36
scope.structuredTextEditor.name=Editing in Structured Text Editors
37
scope.structuredTextEditor.name=Editing in Structured Text Editors
37
scope.structuredTextEditor.description=Editing in Structured Text Editors
38
scope.structuredTextEditor.description=Editing in Structured Text Editors
39
scope.structuredTextEditor.comments.description=Source Comments in Structured Text Editors
40
scope.structuredTextEditor.comments.name=Source Comments in Structured Text Editors
38
command.toggle.comment.name=Toggle Comment
41
command.toggle.comment.name=Toggle Comment
39
command.toggle.comment.description=Toggle Comment
42
command.toggle.comment.description=Toggle Comment
43
command.toggle.comment.mnemonic=T
40
command.add.block.comment.name=Add Block Comment
44
command.add.block.comment.name=Add Block Comment
41
command.add.block.comment.description=Add Block Comment
45
command.add.block.comment.description=Add Block Comment
46
command.add.block.comment.mnemonic=A
42
command.remove.block.comment.name=Remove Block Comment
47
command.remove.block.comment.name=Remove Block Comment
43
command.remove.block.comment.description=Remove Block Comment
48
command.remove.block.comment.description=Remove Block Comment
49
command.remove.block.comment.mnemonic=R
44
command.cleanup.document.name=Cleanup Document...
50
command.cleanup.document.name=Cleanup Document...
45
command.cleanup.document.description=Cleanup document
51
command.cleanup.document.description=Cleanup document
46
command.cleanup.document.mnemonic=C
52
command.cleanup.document.mnemonic=C
(-)src/org/eclipse/wst/sse/ui/StructuredTextEditor.java (-7 / +21 lines)
Lines 189-194 Link Here
189
import org.eclipse.wst.sse.ui.internal.editor.SelectionConvertor;
189
import org.eclipse.wst.sse.ui.internal.editor.SelectionConvertor;
190
import org.eclipse.wst.sse.ui.internal.editor.StructuredModelDocumentProvider;
190
import org.eclipse.wst.sse.ui.internal.editor.StructuredModelDocumentProvider;
191
import org.eclipse.wst.sse.ui.internal.extension.BreakpointProviderBuilder;
191
import org.eclipse.wst.sse.ui.internal.extension.BreakpointProviderBuilder;
192
import org.eclipse.wst.sse.ui.internal.handlers.AddBlockCommentHandler;
193
import org.eclipse.wst.sse.ui.internal.handlers.RemoveBlockCommentHandler;
194
import org.eclipse.wst.sse.ui.internal.handlers.ToggleLineCommentHandler;
192
import org.eclipse.wst.sse.ui.internal.hyperlink.OpenHyperlinkAction;
195
import org.eclipse.wst.sse.ui.internal.hyperlink.OpenHyperlinkAction;
193
import org.eclipse.wst.sse.ui.internal.preferences.EditorPreferenceNames;
196
import org.eclipse.wst.sse.ui.internal.preferences.EditorPreferenceNames;
194
import org.eclipse.wst.sse.ui.internal.projection.AbstractStructuredFoldingStrategy;
197
import org.eclipse.wst.sse.ui.internal.projection.AbstractStructuredFoldingStrategy;
Lines 1365-1378 Link Here
1365
1368
1366
		computeAndSetDoubleClickAction();
1369
		computeAndSetDoubleClickAction();
1367
		
1370
		
1368
		IHandler handler = new GotoMatchingBracketHandler();
1371
		//add handlers to handler service
1369
	    IHandlerService handlerService = (IHandlerService) getSite().getService(IHandlerService.class);
1372
		IHandlerService handlerService = (IHandlerService) getSite().getService(IHandlerService.class);
1370
	    if (handlerService != null)
1373
		if (handlerService != null) {
1371
	      handlerService.activateHandler(ActionDefinitionIds.GOTO_MATCHING_BRACKET, handler);
1374
			
1372
	    if (handlerService != null) {
1375
			IHandler gotoHandler = new GotoMatchingBracketHandler();
1373
	    	fOutlineHandler = new QuickOutlineHandler();
1376
			handlerService.activateHandler(ActionDefinitionIds.GOTO_MATCHING_BRACKET, gotoHandler);
1377
			
1378
			fOutlineHandler = new QuickOutlineHandler();
1374
	    	handlerService.activateHandler(ActionDefinitionIds.SHOW_OUTLINE, fOutlineHandler);
1379
	    	handlerService.activateHandler(ActionDefinitionIds.SHOW_OUTLINE, fOutlineHandler);
1375
	    }
1380
			
1381
			IHandler toggleCommentHandler = new ToggleLineCommentHandler();
1382
			handlerService.activateHandler(ActionDefinitionIds.TOGGLE_COMMENT, toggleCommentHandler);
1383
			
1384
			IHandler addCommentBlockHandler = new AddBlockCommentHandler();
1385
			handlerService.activateHandler(ActionDefinitionIds.ADD_BLOCK_COMMENT, addCommentBlockHandler);
1386
			
1387
			IHandler removeCommentBlockHandler = new RemoveBlockCommentHandler();
1388
			handlerService.activateHandler(ActionDefinitionIds.REMOVE_BLOCK_COMMENT, removeCommentBlockHandler);
1389
		}
1376
1390
1377
		fShowPropertiesAction = new ShowPropertiesAction(getEditorPart(), getSelectionProvider());
1391
		fShowPropertiesAction = new ShowPropertiesAction(getEditorPart(), getSelectionProvider());
1378
		fFoldingGroup = new FoldingActionGroup(this, getSourceViewer());
1392
		fFoldingGroup = new FoldingActionGroup(this, getSourceViewer());
(-)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=
(-)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 (+83 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.IRegion;
15
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;
16
17
/**
18
 * <p>Represents a Line Comment commenting strategy</p>
19
 */
20
public class LineCommentingStrategy extends CommentingStrategy {
21
	/** the prefix of the line comment associated with this strategy */
22
	private String fPrefix;
23
	
24
	/**
25
	 * @param prefix the prefix of the line comment associated with this strategy
26
	 */
27
	public LineCommentingStrategy(String prefix) {
28
		super();
29
		this.fPrefix = prefix;
30
	}
31
	
32
	/**
33
	 * <p>Assumes that the given offset is at the begining of a line and adds the line
34
	 * comment prefix there</p>
35
	 * 
36
	 * @see org.eclipse.wst.sse.ui.internal.comment.CommentingStrategy#apply(
37
	 * 	org.eclipse.wst.sse.core.internal.provisional.IStructuredModel, int, int)
38
	 */
39
	public void apply(IStructuredDocument document, int offset, int length)
40
			throws BadLocationException {
41
		
42
		document.replace(offset, 0, this.fPrefix + " ");
43
	}
44
45
	/**
46
	 * <p>Assumes that the given offset is at the beginning of a line that is commented and removes
47
	 * the comment prefix from the beginning of the line, leading whitespace on the line will not
48
	 * prevent this method from finishing correctly</p>
49
	 * 
50
	 * @see org.eclipse.wst.sse.ui.internal.comment.CommentingStrategy#remove(
51
	 * 	org.eclipse.wst.sse.core.internal.provisional.IStructuredModel, int, int, boolean)
52
	 */
53
	public void remove(IStructuredDocument document, int offset, int length, boolean removeEnclosing) throws BadLocationException{
54
		String content = document.get(offset, length);
55
		int innerOffset = content.indexOf(this.fPrefix);
56
		if(innerOffset > 0) {
57
			offset += innerOffset;
58
		}
59
		
60
		uncomment(document, offset, this.fPrefix, -1,  null);
61
	}
62
	
63
	/**
64
	 * <p>A region is already commented if it begins with the the associated prefix ignoring any
65
	 * leading whitespace</p>
66
	 * 
67
	 * @see org.eclipse.wst.sse.ui.internal.comment.CommentingStrategy#alreadyCommenting(
68
	 * 	org.eclipse.jface.text.IDocument, org.eclipse.jface.text.IRegion)
69
	 */
70
	public boolean alreadyCommenting(IStructuredDocument document, IRegion region)
71
			throws BadLocationException {
72
		
73
		String regionContent = document.get(region.getOffset(), region.getLength()).trim();
74
		return regionContent.startsWith(this.fPrefix);
75
	}
76
	
77
	/**
78
	 * @see org.eclipse.wst.sse.ui.internal.comment.CommentingStrategy#clone()
79
	 */
80
	public Object clone() {
81
		return new LineCommentingStrategy(this.fPrefix);
82
	}
83
}
(-)src/org/eclipse/wst/sse/ui/internal/handlers/ToggleLineCommentHandler.java (+281 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.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
42
/**
43
 * <p>A comment handler to toggle line comments, this means that if a
44
 * comment already exists on a line then toggling it will remove the comment,
45
 * if the line in question is not already commented then it will not be commented.
46
 * If multiple lines are selected each will be commented separately.  The handler
47
 * first attempts to find a {@link LineCommentingStrategy} for a line, if it can
48
 * not find one then it will try and find a {@link BlockCommentingStrategy} to
49
 * wrap just that line in.</p>
50
 * 
51
 * <p>If a great number of lines are being toggled then a progress dialog will be
52
 * displayed because this can be a timely process</p>
53
 */
54
public final class ToggleLineCommentHandler extends AbstractCommentHandler {
55
	/** if toggling more then this many lines then use a busy indicator */
56
	private static final int TOGGLE_LINES_MAX_NO_BUSY_INDICATOR = 10;
57
	
58
	/**
59
	 * @see org.eclipse.wst.sse.ui.internal.handlers.AbstractCommentHandler#processAction(
60
	 * 	org.eclipse.ui.texteditor.ITextEditor, org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument,
61
	 * 	org.eclipse.jface.text.ITextSelection)
62
	 */
63
	protected void processAction(ITextEditor textEditor,
64
			final IStructuredDocument document, ITextSelection textSelection) {
65
		
66
		IStructuredModel model = null;
67
		DocumentRewriteSession session = null;
68
		boolean changed = false;
69
		
70
		try {
71
			// get text selection lines info
72
			int selectionStartLine = textSelection.getStartLine();
73
			int selectionEndLine = textSelection.getEndLine();
74
			
75
			int selectionEndLineOffset = document.getLineOffset(selectionEndLine);
76
			int selectionEndOffset = textSelection.getOffset() + textSelection.getLength();
77
78
			// adjust selection end line
79
			if ((selectionEndLine > selectionStartLine) && (selectionEndLineOffset == selectionEndOffset)) {
80
				selectionEndLine--;
81
			}
82
83
			// save the selection position since it will be changing
84
			Position selectionPosition = null;
85
			selectionPosition = new Position(textSelection.getOffset(), textSelection.getLength());
86
			document.addPosition(selectionPosition);
87
88
			
89
			model = StructuredModelManager.getModelManager().getModelForEdit(document);
90
			if (model != null) {
91
				//makes it so one undo will undo all the edits to the document
92
				model.beginRecording(this, SSEUIMessages.ToggleComment_label, SSEUIMessages.ToggleComment_description);
93
				
94
				//keeps listeners from doing anything until updates are all done
95
				model.aboutToChangeModel();
96
				if(document instanceof IDocumentExtension4) {
97
					session = ((IDocumentExtension4)document).startRewriteSession(DocumentRewriteSessionType.UNRESTRICTED);
98
				}
99
				changed = true;
100
				
101
				//get the display for the editor if we can
102
				Display display = null;
103
				if(textEditor instanceof StructuredTextEditor) {
104
					StructuredTextViewer viewer = ((StructuredTextEditor)textEditor).getTextViewer();
105
					if(viewer != null) {
106
						display = viewer.getControl().getDisplay();
107
					}
108
				}
109
				
110
				//create the toggling operation
111
				IRunnableWithProgress toggleCommentsRunnable = new ToggleLinesRunnable(
112
						model.getContentTypeIdentifier(), document, selectionStartLine, selectionEndLine, display);
113
				
114
				//if toggling lots of lines then use progress monitor else just run the operation
115
				if((selectionEndLine - selectionStartLine) > TOGGLE_LINES_MAX_NO_BUSY_INDICATOR && display != null) {
116
					ProgressMonitorDialog dialog = new ProgressMonitorDialog(display.getActiveShell());
117
					dialog.run(false, true, toggleCommentsRunnable);
118
				} else {
119
					toggleCommentsRunnable.run(new NullProgressMonitor());
120
				}
121
			}
122
		} catch (InvocationTargetException e) {
123
			Logger.logException("Problem running toggle comment progess dialog.", e);  //$NON-NLS-1$
124
		} catch (InterruptedException e) {
125
			Logger.logException("Problem running toggle comment progess dialog.", e);  //$NON-NLS-1$
126
		} catch (BadLocationException e) {
127
			Logger.logException("The given selection " + textSelection + " must be invalid", e); //$NON-NLS-1$ //$NON-NLS-2$
128
		} finally {
129
			//clean everything up
130
			if(session != null && document instanceof IDocumentExtension4) {
131
				((IDocumentExtension4)document).stopRewriteSession(session);
132
			}
133
			
134
			if(model != null) {
135
				model.endRecording(this);
136
				if(changed) {
137
					model.changedModel();
138
				}
139
				model.releaseFromEdit();
140
			}
141
		}
142
	}
143
	
144
	/**
145
	 * <p>The actual line toggling takes place in a runnable so it can be
146
	 * run as part of a progress dialog if there are many lines to toggle
147
	 * and thus the operation will take a noticeable amount of time the user
148
	 * should be aware of, this also allows for the operation to be canceled 
149
	 * by the user</p>
150
	 * 
151
	 */
152
	private static class ToggleLinesRunnable implements IRunnableWithProgress {
153
		/** the content type for the document being commented */
154
		private String fContentType;
155
		
156
		/** the document that the lines will be toggled on */
157
		private IStructuredDocument fDocument;
158
		
159
		/** the first line in the document to toggle */
160
		private int fSelectionStartLine;
161
		
162
		/** the last line in the document to toggle */
163
		private int fSelectionEndLine;
164
		
165
		/** the display, so that it can be updated during a long operation */
166
		private Display fDisplay;
167
		
168
		/**
169
		 * @param model {@link IStructuredModel} that the lines will be toggled on
170
		 * @param document {@link IDocument} that the lines will be toggled on
171
		 * @param selectionStartLine first line in the document to toggle
172
		 * @param selectionEndLine last line in the document to toggle
173
		 * @param display {@link Display}, so that it can be updated during a long operation
174
		 */
175
		protected ToggleLinesRunnable(String contentTypeIdentifier, IStructuredDocument document,
176
				int selectionStartLine, int selectionEndLine, Display display) {
177
			
178
			this.fContentType = contentTypeIdentifier;
179
			this.fDocument = document;
180
			this.fSelectionStartLine = selectionStartLine;
181
			this.fSelectionEndLine = selectionEndLine;
182
			this.fDisplay = display;
183
		}
184
		
185
		/**
186
		 * @see org.eclipse.jface.operation.IRunnableWithProgress#run(org.eclipse.core.runtime.IProgressMonitor)
187
		 */
188
		public void run(IProgressMonitor monitor) {
189
			//start work
190
			monitor.beginTask(SSEUIMessages.ToggleComment_progress,
191
					this.fSelectionEndLine-this.fSelectionStartLine);
192
			try {
193
				//toggle each line so long as task not canceled
194
				for (int line = this.fSelectionStartLine;
195
						line <= this.fSelectionEndLine && !monitor.isCanceled(); ++line) {
196
					
197
					//allows the user to be able to click the cancel button
198
					readAndDispatch(this.fDisplay);
199
					
200
					//get the line region
201
					IRegion lineRegion = this.fDocument.getLineInformation(line);
202
					
203
					//don't toggle empty lines
204
					String content = this.fDocument.get(lineRegion.getOffset(), lineRegion.getLength());
205
					if (content.trim().length() > 0) {
206
						//try to get a line comment type
207
						ITypedRegion[] lineTypedRegions =
208
							this.fDocument.computePartitioning(lineRegion.getOffset(), lineRegion.getLength());
209
						CommentingStrategy commentType = CommentingStrategyRegistry.getDefault().getLineCommentingStrategy(
210
								this.fContentType, lineTypedRegions);
211
						
212
						//could not find line comment type so find block comment type to use on line
213
						if(commentType == null) {
214
							commentType = CommentingStrategyRegistry.getDefault().getBlockCommentingStrategy(
215
									this.fContentType, lineTypedRegions);
216
						}
217
						
218
						//toggle the comment on the line
219
						if(commentType != null) {
220
							if(commentType.alreadyCommenting(this.fDocument, lineTypedRegions)) {
221
								commentType.remove(this.fDocument, lineRegion.getOffset(), lineRegion.getLength(), true);
222
							} else {
223
								commentType.apply(this.fDocument, lineRegion.getOffset(), lineRegion.getLength());
224
							}
225
						}
226
					}
227
					monitor.worked(1);
228
				}
229
			} catch(BadLocationException e) {
230
				Logger.logException("Bad location while toggling comments.", e);  //$NON-NLS-1$
231
			}
232
			//done work
233
			monitor.done();
234
		}
235
		
236
		/**
237
		 * <p>When calling {@link Display#readAndDispatch()} the game is off as to whose code you maybe
238
		 * calling into because of event handling/listeners/etc.  The only important thing is that
239
		 * the UI has been given a chance to react to user clicks.  Thus the logging of most {@link Exception}s
240
		 * and {@link Error}s as caused by {@link Display#readAndDispatch()} because they are not caused
241
		 * by this code and do not effect it.</p>
242
		 * 
243
		 * @param display the {@link Display} to call <code>readAndDispatch</code>
244
		 * on with exception/error handling.
245
		 */
246
		private void readAndDispatch(Display display) {
247
			try {
248
				display.readAndDispatch();
249
			}
250
			catch (Exception e) {
251
				Logger.log(Logger.WARNING,
252
						"Exception caused by readAndDispatch, not caused by or fatal to caller", e);
253
			}
254
			catch (LinkageError e) {
255
				Logger.log(Logger.WARNING,
256
						"LinkageError caused by readAndDispatch, not caused by or fatal to caller", e);
257
			}
258
			catch (VirtualMachineError e) {
259
				// re-throw these
260
				throw e;
261
			}
262
			catch (ThreadDeath e) {
263
				// re-throw these
264
				throw e;
265
			}
266
			catch (Error e) {
267
				// catch every error, except for a few that we don't want to handle
268
				Logger.log(Logger.WARNING,
269
						"Error caused by readAndDispatch, not caused by or fatal to caller", e);
270
			}
271
		}
272
	}
273
	
274
	/**
275
	 * @see org.eclipse.core.commands.AbstractHandler#isEnabled()
276
	 */
277
	public boolean isEnabled() {
278
		// TODO: IAN: fill this in
279
		return super.isEnabled();
280
	}
281
}
(-)src/org/eclipse/wst/sse/ui/internal/handlers/RemoveBlockCommentHandler.java (+84 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.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
28
/**
29
 * <p>A comment handler to remove block comments</p>
30
 */
31
public final class RemoveBlockCommentHandler extends
32
		AbstractCommentHandler {
33
34
	/**
35
	 * @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)
36
	 */
37
	protected void processAction(ITextEditor textEditor, IStructuredDocument document, ITextSelection textSelection) {
38
		
39
		IStructuredModel model = null;
40
		boolean changed = false;
41
		DocumentRewriteSession session = null;
42
		try {
43
			model = StructuredModelManager.getModelManager().getModelForEdit(document);
44
			
45
			if(model != null) {
46
				//makes it so one undo will undo all the edits to the document
47
				model.beginRecording(this, SSEUIMessages.RemoveBlockComment_label,
48
						SSEUIMessages.RemoveBlockComment_label);
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(
54
							DocumentRewriteSessionType.UNRESTRICTED);
55
				}
56
				changed = true;
57
				
58
				ITypedRegion[] typedRegions = document.computePartitioning(
59
						textSelection.getOffset(), textSelection.getLength());
60
				CommentingStrategy commentType = CommentingStrategyRegistry.getDefault().getBlockCommentingStrategy(
61
						model.getContentTypeIdentifier(), typedRegions);
62
				
63
				if(commentType != null) {
64
					commentType.remove(document, textSelection.getOffset(), textSelection.getLength(), true);
65
				}
66
			}
67
		} catch (BadLocationException e) {
68
			Logger.logException("The given selection " + textSelection + " must be invalid", e); //$NON-NLS-1$ //$NON-NLS-2$
69
		} finally {
70
			//clean everything up
71
			if(session != null && document instanceof IDocumentExtension4) {
72
				((IDocumentExtension4)document).stopRewriteSession(session);
73
			}
74
			
75
			if(model != null) {
76
				model.endRecording(this);
77
				if(changed) {
78
					model.changedModel();
79
				}
80
				model.releaseFromEdit();
81
			}
82
		}
83
	}
84
}
(-)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.text.IStructuredDocument;
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 document {@link IStructuredDocument} 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(IStructuredDocument document, 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 document {@link IStructuredDocument} 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(IStructuredDocument document, 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 IStructuredDocument} 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(IStructuredDocument 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(IStructuredDocument 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/internal/handlers/AddBlockCommentHandler.java (+80 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.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
28
/**
29
 * <p>A comment handler to add block comments</p>
30
 */
31
public final class AddBlockCommentHandler extends
32
		AbstractCommentHandler {
33
34
	/**
35
	 * @see org.eclipse.wst.sse.ui.internal.handlers.AbstractCommentHandler#processAction(
36
	 * 	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
		IStructuredModel model = null;
40
		boolean changed = false;
41
		DocumentRewriteSession session = null;
42
		
43
		try {
44
			model = StructuredModelManager.getModelManager().getModelForEdit(document);
45
			if(model != null) {
46
				//makes it so one undo will undo all the edits to the document
47
				model.beginRecording(this, SSEUIMessages.AddBlockComment_label, SSEUIMessages.AddBlockComment_description);
48
				
49
				//keeps listeners from doing anything until updates are all done
50
				model.aboutToChangeModel();
51
				if(document instanceof IDocumentExtension4) {
52
					session = ((IDocumentExtension4)document).startRewriteSession(DocumentRewriteSessionType.UNRESTRICTED);
53
				}
54
				changed = true;
55
				
56
				ITypedRegion[] typedRegions = document.computePartitioning(textSelection.getOffset(), textSelection.getLength());
57
				CommentingStrategy commentType = CommentingStrategyRegistry.getDefault().getBlockCommentingStrategy(model.getContentTypeIdentifier(), typedRegions);
58
				
59
				if(commentType != null) {
60
					commentType.apply(document, textSelection.getOffset(), textSelection.getLength());
61
				}
62
			}
63
		} catch (BadLocationException e) {
64
			Logger.logException("The given selection " + textSelection + " must be invalid", e); //$NON-NLS-1$ //$NON-NLS-2$
65
		} finally {
66
			//clean everything up
67
			if(session != null && document instanceof IDocumentExtension4) {
68
				((IDocumentExtension4)document).stopRewriteSession(session);
69
			}
70
			
71
			if(model != null) {
72
				model.endRecording(this);
73
				if(changed) {
74
					model.changedModel();
75
				}
76
				model.releaseFromEdit();
77
			}
78
		}
79
	}
80
}
(-)schema/commentingStrategy.exsd (+267 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
            <choice>
109
               <element ref="requiredPartitionTypes"/>
110
               <element ref="allowablePartitionTypes"/>
111
               <sequence>
112
                  <element ref="requiredPartitionTypes"/>
113
                  <element ref="allowablePartitionTypes"/>
114
               </sequence>
115
            </choice>
116
         </sequence>
117
         <attribute name="id" type="string" use="required">
118
            <annotation>
119
               <documentation>
120
                  The ID of the content type
121
               </documentation>
122
               <appInfo>
123
                  <meta.attribute kind="identifier" basedOn="org.eclipse.core.contenttype.contentTypes/content-type/@id"/>
124
               </appInfo>
125
            </annotation>
126
         </attribute>
127
         <attribute name="associatedCommentPartitionTypeID" type="string">
128
            <annotation>
129
               <documentation>
130
                  The partition type ID of the comment partition that is associated with the strategy in this content type
131
               </documentation>
132
            </annotation>
133
         </attribute>
134
      </complexType>
135
   </element>
136
137
   <element name="requiredPartitionTypes">
138
      <annotation>
139
         <documentation>
140
            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.
141
         </documentation>
142
      </annotation>
143
      <complexType>
144
         <sequence minOccurs="1" maxOccurs="unbounded">
145
            <element ref="partitionType"/>
146
         </sequence>
147
         <attribute name="requireAll" type="boolean" use="default" value="false">
148
            <annotation>
149
               <documentation>
150
                  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
151
               </documentation>
152
            </annotation>
153
         </attribute>
154
      </complexType>
155
   </element>
156
157
   <element name="allowablePartitionTypes">
158
      <annotation>
159
         <documentation>
160
            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;.  If this list is not provided then it is assumed the value of &lt;code&gt;anyPartitionType&lt;/code&gt; is false.
161
         </documentation>
162
      </annotation>
163
      <complexType>
164
         <sequence minOccurs="0" maxOccurs="unbounded">
165
            <element ref="partitionType"/>
166
         </sequence>
167
         <attribute name="anyPartitionType" type="boolean" use="default" value="false">
168
            <annotation>
169
               <documentation>
170
                  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.
171
               </documentation>
172
            </annotation>
173
         </attribute>
174
      </complexType>
175
   </element>
176
177
   <element name="partitionType">
178
      <annotation>
179
         <documentation>
180
            A partition type associated with the parenting content type
181
         </documentation>
182
      </annotation>
183
      <complexType>
184
         <attribute name="id" type="string" use="required">
185
            <annotation>
186
               <documentation>
187
                  The ID of the partition type.
188
               </documentation>
189
            </annotation>
190
         </attribute>
191
      </complexType>
192
   </element>
193
194
195
   <annotation>
196
      <appInfo>
197
         <meta.section type="examples"/>
198
      </appInfo>
199
      <documentation>
200
         &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;
201
  &lt;blockCommentingStrategy
202
      prefix=&quot;&amp;lt;!--&quot;
203
      suffix=&quot;--&amp;gt;&quot;&gt;
204
    &lt;contentType
205
        id=&quot;org.eclipse.core.runtime.xml&quot;
206
        associatedCommentPartitionTypeID=&quot;org.eclipse.wst.xml.XML_COMMENT&quot;&gt;
207
      &lt;allowablePartitionTypes
208
          anyPartitionType=&quot;true&quot;&gt;
209
      &lt;/allowablePartitionTypes&gt;
210
    &lt;/contentType&gt;
211
  &lt;/blockCommentingStrategy&gt;
212
&lt;/extension&gt;&lt;/pre&gt;
213
214
&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;
215
  &lt;blockCommentingStrategy
216
      prefix=&quot;/*&quot;
217
      suffix=&quot;*/&quot;&gt;
218
    &lt;contentType
219
        associatedCommentPartitionTypeID=&quot;org.eclipse.wst.css.COMMENT&quot;
220
        id=&quot;org.eclipse.wst.css.core.csssource&quot;&gt;
221
      &lt;allowablePartitionTypes
222
          anyPartitionType=&quot;true&quot;&gt;
223
      &lt;/allowablePartitionTypes&gt;
224
    &lt;/contentType&gt;
225
    &lt;contentType
226
        id=&quot;org.eclipse.wst.html.core.htmlsource&quot;&gt;
227
      &lt;allowablePartitionTypes
228
          anyPartitionType=&quot;false&quot;&gt;
229
      &lt;/allowablePartitionTypes&gt;
230
      &lt;requiredPartitionTypes
231
          requireAll=&quot;true&quot;&gt;
232
        &lt;partitionType
233
            id=&quot;org.eclipse.wst.css.STYLE&quot;&gt;
234
        &lt;/partitionType&gt;
235
      &lt;/requiredPartitionTypes&gt;
236
    &lt;/contentType&gt;
237
  &lt;/blockCommentingStrategy&gt;
238
&lt;/extension&gt;&lt;/pre&gt;
239
      </documentation>
240
   </annotation>
241
242
   <annotation>
243
      <appInfo>
244
         <meta.section type="apiinfo"/>
245
      </appInfo>
246
      <documentation>
247
         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.
248
&lt;ul&gt;
249
&lt;li&gt;&lt;code&gt;org.eclipse.wst.sse.ui.handlers.AddBlockCommentHandler&lt;/code&gt;&lt;/li&gt;
250
&lt;li&gt;&lt;code&gt;org.eclipse.wst.sse.ui.handlers.RemoveBlockCommentHandler&lt;/code&gt;&lt;/li&gt;
251
&lt;li&gt;&lt;code&gt;org.eclipse.wst.sse.ui.handlers.ToggleLineCommentHandler&lt;/code&gt;&lt;/li&gt;
252
&lt;/ul&gt;
253
      </documentation>
254
   </annotation>
255
256
257
   <annotation>
258
      <appInfo>
259
         <meta.section type="copyright"/>
260
      </appInfo>
261
      <documentation>
262
         Copyright (c) 2010 IBM Corporation and others.
263
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;
264
      </documentation>
265
   </annotation>
266
267
</schema>
(-)src/org/eclipse/wst/sse/ui/internal/comment/CommentingStrategyRegistry.java (+361 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.core.runtime.content.IContentType;
28
import org.eclipse.jface.text.ITypedRegion;
29
import org.eclipse.wst.sse.ui.internal.Logger;
30
import org.eclipse.wst.sse.ui.internal.SSEUIPlugin;
31
32
/**
33
 * <p>The registry of {@link CommentingStrategy}s defined by the <code>org.eclipse.wst.sse.ui.commentinStrategy</code>
34
 * extension point.</p>
35
 */
36
public class CommentingStrategyRegistry {
37
	/** The extension schema name of the extension point */
38
	private static final String EXTENSION_POINT = "commentingStrategy"; //$NON-NLS-1$
39
	
40
	/** The extension schema name of proposal block comment child elements. */
41
	private static final String ELEM_PROPOSAL_BLOCK_COMMENTING_STRATEGY = "blockCommentingStrategy"; //$NON-NLS-1$
42
	
43
	/** The extension schema name of proposal line comment child elements. */
44
	private static final String ELEM_PROPOSAL_LINE_COMMENTING_STRATEGY = "lineCommentingStrategy"; //$NON-NLS-1$
45
	
46
	/** The extension schema name of the content type child elements. */
47
	private static final String ELEM_CONTENT_TYPE = "contentType"; //$NON-NLS-1$
48
	
49
	/** The extension schema name of the required partition types child elements */
50
	private static final String ELEM_REQUIRED_PARTITION_TYPES= "requiredPartitionTypes"; //$NON-NLS-1$
51
	
52
	/** The extension schema name of the allowable partition types child elements */
53
	private static final String ELEM_ALLOWABLE_PARTITION_TYPES= "allowablePartitionTypes"; //$NON-NLS-1$
54
	
55
	/** The extension schema name of partition type child elements */
56
	private static final String ELEM_PARTITION_TYPE= "partitionType"; //$NON-NLS-1$
57
	
58
	/** The extension schema name of the prefix attribute */
59
	private static final String ATTR_PREFIX = "prefix"; //$NON-NLS-1$
60
	
61
	/** The extension schema name of the suffix attribute */
62
	private static final String ATTR_SUFFIX = "suffix"; //$NON-NLS-1$
63
	
64
	/** The extension schema name of the associatedCommentPartitionTypeID attribute */
65
	private static final String ATTR_ASSOCIATED_COMMENT_PARTITION_TPYPE_ID = "associatedCommentPartitionTypeID"; //$NON-NLS-1$
66
	
67
	/** The extension schema name of the anyPartitionType attribute */
68
	private static final String ATTR_ANY_PARTITION_TYPE = "anyPartitionType";  //$NON-NLS-1$
69
	
70
	/** The extension schema name of the requireAll attribute */
71
	private static final String ATTR_REQUIRE_ALL = "requireAll"; //$NON-NLS-1$
72
	
73
	/** The extension schema name for ID attribute */
74
	private static final String ATTR_ID= "id"; //$NON-NLS-1$
75
	
76
	/** the singleton instance of the registry */
77
	private static CommentingStrategyRegistry fSingleton = null;
78
	
79
	/** <code>true</code> if this registry has been loaded. */
80
	private boolean fLoaded;
81
	
82
	/**
83
	 * <p>Registry of content type IDs to {@link BlockCommentingStrategy}s</p>
84
	 * 
85
	 * <code>{@link Map}&lt{@link String}, {@link List}&lt{@link BlockContentType}&gt&gt</code>
86
	 * <ul>
87
	 * <li><b>key:</b> content type ID</li>
88
	 * <li><b>value:</b> {@link List} of associated {@link BlockContentType}s</li>
89
	 * <ul>
90
	 */
91
	private Map fBlockCommentTypes;
92
	
93
	/**
94
	 * <p>Registry of content type IDs to {@link LineCommentingStrategy}s</p>
95
	 *
96
	 * <code>{@link Map}&lt{@link String}, {@link List}&lt{@link LineContentType}&gt&gt</code>
97
	 * <ul>
98
	 * <li><b>key:</b> content type ID</li>
99
	 * <li><b>value:</b> {@link List} of associated {@link LineContentType}s</li>
100
	 * <ul>
101
	 */
102
	private Map fLineCommentTypes;
103
	
104
	/**
105
	 * @return the single instance of the {@link CommentingStrategyRegistry}
106
	 */
107
	public static synchronized CommentingStrategyRegistry getDefault() {
108
		if(fSingleton == null) {
109
			fSingleton = new CommentingStrategyRegistry();
110
		}
111
		
112
		return fSingleton;
113
	}
114
	
115
	/**
116
	 * Singleton constructor for the registry
117
	 */
118
	private CommentingStrategyRegistry() {
119
		this.fLoaded = false;
120
		this.fBlockCommentTypes = new HashMap();
121
		this.fLineCommentTypes = new HashMap();
122
	}
123
	
124
	/**
125
	 * @param contentTypeID get only {@link BlockCommentingStrategy}s associated with this content type
126
	 * @param regions get only {@link BlockCommentingStrategy}s associated with these types of regions
127
	 * @return all the {@link BlockCommentingStrategy}s associated with the given content type and regions
128
	 */
129
	public CommentingStrategy getBlockCommentingStrategy(String contentTypeID, ITypedRegion[] regions) {
130
		return getCommentingStrategy(contentTypeID, regions, this.fBlockCommentTypes);
131
	}
132
	
133
	/**
134
	 * @param contentTypeID get only {@link LineCommentingStrategy}s associated with this content type
135
	 * @param regions get only {@link LineCommentingStrategy}s associated with these types of regions
136
	 * @return all the {@link LineCommentingStrategy}s associated with the given content type and regions
137
	 */
138
	public CommentingStrategy getLineCommentingStrategy(String contentTypeID, ITypedRegion[] regions) {
139
		return getCommentingStrategy(contentTypeID, regions, this.fLineCommentTypes);
140
	}
141
	
142
	/**
143
	 * <p>get all the {@link CommentingStrategy}s associated with the given content type and regions
144
	 * from the given registry</p>
145
	 * 
146
	 * @param contentTypeID  get only {@link CommentingStrategy}s associated with this content type
147
	 * @param regions get only {@link CommentingStrategy}s associated with these types of regions
148
	 * @param registry get the {@link CommentingStrategy}s from this registry
149
	 * @return all the {@link CommentingStrategy}s associated with the given content type and regions
150
	 * from the given registry
151
	 */
152
	private CommentingStrategy getCommentingStrategy(String contentTypeID, ITypedRegion[] regions, Map registry) {
153
		ensureExtensionPointRead();
154
		
155
		CommentingStrategy match = null;
156
		IContentType contentType = Platform.getContentTypeManager().getContentType(contentTypeID);
157
		
158
		/* get all the commenting strategies for the given content type id,
159
		 * including those registered for parent content types
160
		 */
161
		List possibleCommentingStrategies = new ArrayList();
162
		while(contentType != null) {
163
			List contentTypeCommentingStrategies = (List)registry.get(contentType.getId());
164
			if(contentTypeCommentingStrategies != null && contentTypeCommentingStrategies.size() > 0) {
165
				possibleCommentingStrategies.addAll(contentTypeCommentingStrategies);
166
			}
167
			contentType = contentType.getBaseType();
168
		}
169
		
170
		/* find the commenting strategy applicable for the given regions,
171
		 * because strategies were added starting from the most specific
172
		 * content type first, the most specific strategy will always be chosen
173
		 */
174
		for(int i = 0; i < possibleCommentingStrategies.size() && match == null; ++i) {
175
			CommentingStrategy commentType = (CommentingStrategy)possibleCommentingStrategies.get(i);
176
			if(commentType.isApplicableFor(regions)) {
177
				match = commentType;
178
			}
179
		}
180
		
181
		return match;
182
	}
183
	
184
	/**
185
	 * <p>Ensures that the extensions are read and this registry is built</p>
186
	 */
187
	private void ensureExtensionPointRead() {
188
		if(!fLoaded) {
189
			load();
190
			fLoaded = true;
191
		}
192
	}
193
	
194
	/**
195
	 * <p>Load the extension points into the registry</p>
196
	 */
197
	private void load() {
198
		IExtensionRegistry extensionRegistry = Platform.getExtensionRegistry();
199
		List extensionElements = new ArrayList(Arrays.asList(extensionRegistry.getConfigurationElementsFor(SSEUIPlugin.ID, EXTENSION_POINT)));
200
	
201
		//for each extension
202
		for (Iterator iter= extensionElements.iterator(); iter.hasNext();) {
203
			IConfigurationElement element = (IConfigurationElement) iter.next();
204
			try {
205
				CommentingStrategy newCommentingStrategy = null;
206
				Map commentingStrategyRegistry = null;
207
				//either a block or line commenting strategy
208
				if(element.getName().equals(ELEM_PROPOSAL_BLOCK_COMMENTING_STRATEGY)) {
209
					String prefix = element.getAttribute(ATTR_PREFIX);
210
					checkExtensionAttributeNotNull(prefix, ATTR_PREFIX, element);
211
					
212
					String suffix = element.getAttribute(ATTR_SUFFIX);
213
					checkExtensionAttributeNotNull(suffix, ATTR_SUFFIX, element);
214
					
215
					if(prefix != null && suffix != null) {
216
						newCommentingStrategy = new BlockCommentingStrategy(prefix, suffix);
217
						commentingStrategyRegistry = this.fBlockCommentTypes;
218
					}
219
				} else if(element.getName().equals(ELEM_PROPOSAL_LINE_COMMENTING_STRATEGY)) {
220
					String prefix = element.getAttribute(ATTR_PREFIX);
221
					checkExtensionAttributeNotNull(prefix, ATTR_PREFIX, element);
222
					
223
					if(prefix != null) {
224
						newCommentingStrategy = new LineCommentingStrategy(prefix);
225
						commentingStrategyRegistry = this.fLineCommentTypes;
226
					}
227
				}
228
				
229
				//add the new strategy to the registry
230
				if(commentingStrategyRegistry != null && newCommentingStrategy != null) {
231
					addCommentingStrategyToRegistry(element, commentingStrategyRegistry, newCommentingStrategy);
232
				} else {
233
					Logger.log(Logger.WARNING, "Invalid CommentingStrategy extension: " + element); //$NON-NLS-1$
234
				}
235
			} catch (CoreException e) {
236
				Logger.logException(e);
237
			} catch (InvalidRegistryObjectException x) {
238
				/* Element is not valid any longer as the contributing plug-in was unloaded or for
239
				 * some other reason. Do not include the extension in the list and log it
240
				 */
241
				String message = "The extension ''" + element.toString() + "'' is invalid."; //$NON-NLS-1$ //$NON-NLS-2$
242
				IStatus status= new Status(IStatus.WARNING, SSEUIPlugin.ID, IStatus.WARNING, message, x);
243
				Logger.log(status);
244
			}
245
		}
246
	}
247
	
248
	/**
249
	 * <p>Checks that the given attribute value is not <code>null</code>.</p>
250
	 *
251
	 * @param value the object to check if not null
252
	 * @param attribute the attribute
253
	 * 
254
	 * @throws InvalidRegistryObjectException if the registry element is no longer valid
255
	 * @throws CoreException if <code>value</code> is <code>null</code>
256
	 */
257
	private static void checkExtensionAttributeNotNull(Object value, String attribute,
258
			IConfigurationElement element) throws InvalidRegistryObjectException, CoreException {
259
		
260
		if (value == null) {
261
			String message = "The extension \"" + element.getDeclaringExtension().getUniqueIdentifier() + //$NON-NLS-1$
262
				"\" from plug-in \"" + element.getContributor().getName() + //$NON-NLS-1$
263
				"\" did not specify a value for the required \"" + attribute + //$NON-NLS-1$
264
				"\" attribute for the element \"" + element.getName() + "\". Disabling the extension."; //$NON-NLS-1$ //$NON-NLS-2$
265
			IStatus status= new Status(IStatus.WARNING, SSEUIPlugin.ID, IStatus.OK, message, null);
266
			throw new CoreException(status);
267
		}
268
	}
269
	
270
	/**
271
	 * <p>Using the content type element children of the given element add a copy of the given
272
	 * base commenting strategy to the given registry</p>
273
	 * 
274
	 * @param element a {@link IConfigurationElement} with contentType element children
275
	 * @param commentingStrategyRegistry {@link Map} of content type ids to {@link CommentingStrategy}s to register
276
	 * the given {@link CommentingStrategy} with based on the <code>element</code>
277
	 * @param baseCommentingStrategy {@link CommentingStrategy} that will be cloned and configured for each
278
	 * content type in the given <code>element</code>
279
	 */
280
	private static void addCommentingStrategyToRegistry(IConfigurationElement element,
281
			Map commentingStrategyRegistry, CommentingStrategy baseCommentingStrategy) {
282
		
283
		//get all the content type elements
284
		IConfigurationElement[] contentTypeElements = element.getChildren(ELEM_CONTENT_TYPE);
285
		if(contentTypeElements.length > 0) {
286
			for(int contentTypeIndex = 0; contentTypeIndex < contentTypeElements.length; ++contentTypeIndex) {
287
				try {
288
					String contentTypeID = contentTypeElements[contentTypeIndex].getAttribute(ATTR_ID);
289
					checkExtensionAttributeNotNull(contentTypeID, ATTR_ID, contentTypeElements[contentTypeIndex]);
290
					
291
					List commentTypes = (List)commentingStrategyRegistry.get(contentTypeID);
292
					if(commentTypes == null) {
293
						commentTypes = new ArrayList();
294
						commentingStrategyRegistry.put(contentTypeID, commentTypes);
295
					}
296
					
297
					//this element is required
298
					List allowablePartitionTypeIDs = new ArrayList();
299
					IConfigurationElement[] allowablePartitionTypes =
300
						contentTypeElements[contentTypeIndex].getChildren(ELEM_ALLOWABLE_PARTITION_TYPES);
301
					boolean anyPartitionType = false;
302
					//determine anyPartitionType attribute value
303
					String anyPartitionTypeValue = allowablePartitionTypes[0].getAttribute(ATTR_ANY_PARTITION_TYPE);
304
					if(anyPartitionTypeValue != null) {
305
						anyPartitionType = Boolean.valueOf(anyPartitionTypeValue).booleanValue();
306
					}
307
					
308
					//get the optional partition types
309
					allowablePartitionTypes = allowablePartitionTypes[0].getChildren(ELEM_PARTITION_TYPE);
310
					if(allowablePartitionTypes.length > 0) {
311
						for (int partitionTypeIndex = 0; partitionTypeIndex < allowablePartitionTypes.length; ++partitionTypeIndex) {
312
							String partitionTypeID = allowablePartitionTypes[partitionTypeIndex].getAttribute(ATTR_ID);
313
							checkExtensionAttributeNotNull(partitionTypeID, ATTR_ID, allowablePartitionTypes[partitionTypeIndex]);
314
							
315
							allowablePartitionTypeIDs.add(partitionTypeID);
316
						}
317
					}
318
					
319
					//this element is optional
320
					List requiredPartitionTypeIDs = new ArrayList();
321
					IConfigurationElement[] requiredPartitionTypes =
322
						contentTypeElements[contentTypeIndex].getChildren(ELEM_REQUIRED_PARTITION_TYPES);
323
					boolean requireAll = false;
324
					if(requiredPartitionTypes.length > 0) {
325
						//determine requireAll attribute value
326
						String requireAllValue = requiredPartitionTypes[0].getAttribute(ATTR_REQUIRE_ALL);
327
						if(requireAllValue != null) {
328
							requireAll = Boolean.valueOf(requireAllValue).booleanValue();
329
						}
330
						
331
						//get the required partition types
332
						requiredPartitionTypes = requiredPartitionTypes[0].getChildren(ELEM_PARTITION_TYPE);
333
						if(requiredPartitionTypes.length > 0) {
334
							for (int partitionTypeIndex = 0; partitionTypeIndex < requiredPartitionTypes.length; ++partitionTypeIndex) {
335
								String partitionTypeID = requiredPartitionTypes[partitionTypeIndex].getAttribute(ATTR_ID);
336
								checkExtensionAttributeNotNull(partitionTypeID, ATTR_ID, requiredPartitionTypes[partitionTypeIndex]);
337
								
338
								requiredPartitionTypeIDs.add(partitionTypeID);
339
							}
340
						}
341
					}
342
					
343
					//get the optional associated comment partition type ID
344
					String associatedCommentPartitionTypeID =
345
						contentTypeElements[contentTypeIndex].getAttribute(ATTR_ASSOCIATED_COMMENT_PARTITION_TPYPE_ID);
346
					
347
					//register the strategy
348
					CommentingStrategy newCommentingStrategy = (CommentingStrategy)baseCommentingStrategy.clone();
349
					newCommentingStrategy.setPartitionInformation(allowablePartitionTypeIDs, anyPartitionType,
350
							requiredPartitionTypeIDs, requireAll, associatedCommentPartitionTypeID);
351
					commentTypes.add(newCommentingStrategy);
352
				} catch(CoreException e) {
353
					Logger.logException(e);
354
				}
355
			}
356
		} else {
357
			Logger.log(Logger.WARNING, "The commmentying strategy element: " + element +//$NON-NLS-1$
358
					" does not contain any requried " + ELEM_CONTENT_TYPE + "s"); //$NON-NLS-1$ //$NON-NLS-2$
359
		}
360
	}
361
}
(-)src/org/eclipse/wst/sse/ui/internal/comment/BlockCommentingStrategy.java (+138 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.IRegion;
17
import org.eclipse.jface.text.ITypedRegion;
18
import org.eclipse.jface.text.Region;
19
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;
20
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion;
21
import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegion;
22
import org.eclipse.wst.sse.ui.internal.Logger;
23
24
/**
25
 * <p>Represents a Block Comment commenting strategy</p>
26
 */
27
public class BlockCommentingStrategy extends CommentingStrategy {
28
	/** the prefix of the block comment associated with this strategy */
29
	private String fPrefix;
30
	
31
	/** the suffix of the block comment associated with this strategy */
32
	private String fSuffix;
33
	
34
	/**
35
	 * @param prefix the prefix of the block comment associated with this strategy
36
	 * @param suffix the suffix of the block comment associated with this strategy
37
	 */
38
	public BlockCommentingStrategy(String prefix, String suffix) {
39
		super();
40
		this.fPrefix = prefix;
41
		this.fSuffix = suffix;
42
	}
43
44
	/**
45
	 * <p>When applying a block comment it also removes any block comments associated
46
	 * with this strategy that would now be enclosed by the new block comment</p>
47
	 * 
48
	 * @see org.eclipse.wst.sse.ui.internal.comment.CommentingStrategy#apply(
49
	 * 	org.eclipse.wst.sse.core.internal.provisional.IStructuredModel, int, int)
50
	 */
51
	public void apply(IStructuredDocument document, int offset, int length) throws BadLocationException {
52
		int commentPrefixOffset = offset;
53
		int commentSuffixOffset = commentPrefixOffset + length;
54
		
55
		try {
56
			document.replace(commentSuffixOffset, 0, " " + this.fSuffix); //$NON-NLS-1$
57
			this.remove(document, commentPrefixOffset + this.fPrefix.length(), length, false);
58
			document.replace(commentPrefixOffset, 0, this.fPrefix + " "); //$NON-NLS-1$
59
		}
60
		catch (BadLocationException e) {
61
			Logger.log(Logger.WARNING_DEBUG, e.getMessage(), e);
62
		}
63
	}
64
65
	/**
66
	 * @see org.eclipse.wst.sse.ui.internal.comment.CommentingStrategy#remove(
67
	 * 	org.eclipse.jface.text.IDocument, int, int)
68
	 */
69
	public void remove(IStructuredDocument document, int offset, int length, boolean removeEnclosing) throws BadLocationException {
70
		IRegion region = new Region(offset, length);
71
		ITypedRegion[] typedRegions = document.computePartitioning(region.getOffset(), region.getLength());
72
		List commentRegions = this.getAssociatedCommentedRegions(typedRegions);
73
		
74
		//remove in reverse order as to not effect offset of other regions
75
		for(int i = commentRegions.size()-1; i >= 0; --i) {
76
			try {
77
				//get the comment region
78
				ITypedRegion typedRegion = (ITypedRegion)commentRegions.get(i);
79
				IRegion commentRegion = new Region(typedRegion.getOffset(), typedRegion.getLength());
80
81
				/* because of the nature of structured regions the comment region could actually be a
82
				 * sub region that needs to be drilled down too
83
				 */
84
				if(!this.alreadyCommenting(document, commentRegion)) {
85
					IStructuredDocumentRegion structuredRegion =
86
						document.getRegionAtCharacterOffset(commentRegion.getOffset());
87
					
88
					commentRegion = new Region(structuredRegion.getStartOffset(), structuredRegion.getLength());
89
					
90
					if(!this.alreadyCommenting(document, commentRegion)) {
91
						ITextRegion enclosedRegion = structuredRegion.getRegionAtCharacterOffset(typedRegion.getOffset());
92
						int enclosedOffset = structuredRegion.getStartOffset(enclosedRegion);
93
						commentRegion = new Region(enclosedOffset, structuredRegion.getTextEndOffset(enclosedRegion)-enclosedOffset);
94
					}
95
				}
96
				
97
				//at this point should have found the comment region, if not there is an issue
98
				if(this.alreadyCommenting(document, commentRegion)) {
99
					String regionContent = document.get(commentRegion.getOffset(), commentRegion.getLength());
100
					
101
					//if found the comment prefix and suffix then uncomment, otherwise log error
102
					int commentPrefixOffset = commentRegion.getOffset() + regionContent.indexOf(this.fPrefix);
103
					int commentSuffixOffset = commentRegion.getOffset();
104
					commentSuffixOffset += regionContent.lastIndexOf(this.fSuffix);
105
					
106
					//remove comment block depending on if its an enclosing comment block and weather that is allowed
107
					if(removeEnclosing || (commentPrefixOffset >= offset && commentSuffixOffset <= offset+length)) {
108
						uncomment(document, commentPrefixOffset, this.fPrefix, commentSuffixOffset, this.fSuffix);
109
					}
110
				} else {
111
					Logger.log(Logger.ERROR,
112
							"BlockCommentingStrategy#remove could not find the commenting region to remove"); //$NON-NLS-1$
113
				}
114
			} catch(BadLocationException e) {
115
				Logger.logException("This shoudl only ever happen if somethign has gone wrong with the partitioning", e); //$NON-NLS-1$
116
			}
117
		}
118
	}
119
	
120
	/**
121
	 * <p>A region is already commented by this strategy if it starts with the strategy's associated
122
	 * prefix and ends with its associated suffix, ignoring any trailing or leading whitespace</p>
123
	 * 
124
	 * @see org.eclipse.wst.sse.ui.internal.comment.CommentingStrategy#alreadyCommenting(
125
	 * 	org.eclipse.jface.text.IDocument, org.eclipse.jface.text.IRegion)
126
	 */
127
	public boolean alreadyCommenting(IStructuredDocument document, IRegion region) throws BadLocationException {
128
		String regionContent = document.get(region.getOffset(), region.getLength()).trim();
129
		return regionContent.startsWith(this.fPrefix) && regionContent.endsWith(this.fSuffix);
130
	}
131
	
132
	/**
133
	 * @see org.eclipse.wst.sse.ui.internal.comment.CommentingStrategy#clone()
134
	 */
135
	public Object clone() {
136
		return new BlockCommentingStrategy(this.fPrefix, this.fSuffix);
137
	}
138
}

Return to bug 86520