1) Fixed calculation of the new indentation method of splitted strings.
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / ui / actions / AddBlockCommentAction.java
1 /*******************************************************************************
2  * Copyright (c) 2000, 2004 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Common Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/cpl-v10.html
7  *
8  * Contributors:
9  *     IBM Corporation - initial API and implementation
10  *******************************************************************************/
11 package net.sourceforge.phpdt.internal.ui.actions;
12
13 import java.util.LinkedList;
14 import java.util.List;
15 import java.util.ResourceBundle;
16
17 import net.sourceforge.phpdt.internal.ui.text.IPHPPartitions;
18 import net.sourceforge.phpeclipse.phpeditor.php.PHPDocumentPartitioner;
19
20 //incastrix
21 //import org.eclipse.jface.text.Assert;
22 import org.eclipse.core.runtime.Assert;
23 import org.eclipse.jface.text.BadLocationException;
24 import org.eclipse.jface.text.BadPartitioningException;
25 import org.eclipse.jface.text.IDocument;
26 import org.eclipse.jface.text.IDocumentExtension3;
27 import org.eclipse.jface.text.ITextSelection;
28 import org.eclipse.jface.text.ITypedRegion;
29 import org.eclipse.ui.texteditor.ITextEditor;
30
31 /**
32  * Action that encloses the editor's current selection with Java block comment
33  * terminators (<code>&#47;&#42;</code> and <code>&#42;&#47;</code>).
34  * 
35  * @since 3.0
36  */
37 public class AddBlockCommentAction extends BlockCommentAction {
38
39         /**
40          * Creates a new instance.
41          * 
42          * @param bundle
43          *            the resource bundle
44          * @param prefix
45          *            a prefix to be prepended to the various resource keys
46          *            (described in <code>ResourceAction</code> constructor), or
47          *            <code>null</code> if none
48          * @param editor
49          *            the text editor
50          */
51         public AddBlockCommentAction(ResourceBundle bundle, String prefix,
52                         ITextEditor editor) {
53                 super(bundle, prefix, editor);
54         }
55
56         /*
57          * @see net.sourceforge.phpdt.internal.ui.actions.BlockCommentAction#runInternal(org.eclipse.jface.text.ITextSelection,
58          *      org.eclipse.jface.text.IDocumentExtension3,
59          *      net.sourceforge.phpdt.internal.ui.actions.BlockCommentAction.Edit.EditFactory)
60          */
61         protected void runInternal(ITextSelection selection,
62                         IDocumentExtension3 docExtension, Edit.EditFactory factory)
63                         throws BadLocationException, BadPartitioningException {
64                 int selectionOffset = selection.getOffset();
65                 int selectionEndOffset = selectionOffset + selection.getLength();
66                 List edits = new LinkedList();
67                 ITypedRegion partition = docExtension.getPartition(
68                                 IPHPPartitions.PHP_PARTITIONING, selectionOffset, false);
69
70                 handleFirstPartition(partition, edits, factory, selectionOffset);
71
72                 while (partition.getOffset() + partition.getLength() < selectionEndOffset) {
73                         partition = handleInteriorPartition(partition, edits, factory,
74                                         docExtension);
75                 }
76
77                 handleLastPartition(partition, edits, factory, selectionEndOffset);
78
79                 executeEdits(edits);
80         }
81
82         /**
83          * Handle the first partition of the selected text.
84          * 
85          * @param partition
86          * @param edits
87          * @param factory
88          * @param offset
89          */
90         private void handleFirstPartition(ITypedRegion partition, List edits,
91                         Edit.EditFactory factory, int offset) throws BadLocationException {
92
93                 int partOffset = partition.getOffset();
94                 String partType = partition.getType();
95
96                 Assert.isTrue(partOffset <= offset, "illegal partition"); //$NON-NLS-1$
97
98                 // first partition: mark start of comment
99                 if (partType == IDocument.DEFAULT_CONTENT_TYPE
100                                 || partType == PHPDocumentPartitioner.PHP_SCRIPT_CODE) {
101                         // Java code: right where selection starts
102                         edits.add(factory.createEdit(offset, 0, getCommentStart()));
103                 } else if (isSpecialPartition(partType)) {
104                         // special types: include the entire partition
105                         edits.add(factory.createEdit(partOffset, 0, getCommentStart()));
106                 } // javadoc: no mark, will only start after comment
107
108         }
109
110         /**
111          * Handles the end of the given partition and the start of the next
112          * partition, which is returned.
113          * 
114          * @param partition
115          * @param edits
116          * @param factory
117          * @param docExtension
118          * @return
119          * @throws BadLocationException
120          * @throws BadPartitioningException
121          */
122         private ITypedRegion handleInteriorPartition(ITypedRegion partition,
123                         List edits, Edit.EditFactory factory,
124                         IDocumentExtension3 docExtension) throws BadPartitioningException,
125                         BadLocationException {
126
127                 // end of previous partition
128                 String partType = partition.getType();
129                 int partEndOffset = partition.getOffset() + partition.getLength();
130                 int tokenLength = getCommentStart().length();
131
132                 boolean wasJavadoc = false; // true if the previous partition is javadoc
133
134                 if (partType == IPHPPartitions.PHP_PHPDOC_COMMENT) {
135
136                         wasJavadoc = true;
137
138                 } else if (partType == IPHPPartitions.PHP_MULTILINE_COMMENT) {
139
140                         // already in a comment - remove ending mark
141                         edits.add(factory.createEdit(partEndOffset - tokenLength,
142                                         tokenLength, "")); //$NON-NLS-1$
143
144                 }
145
146                 // advance to next partition
147                 partition = docExtension.getPartition(IPHPPartitions.PHP_PARTITIONING,
148                                 partEndOffset, false);
149                 partType = partition.getType();
150
151                 // start of next partition
152                 if (wasJavadoc) {
153
154                         // if previous was javadoc, and the current one is not, then add
155                         // block comment start
156                         if (partType == IDocument.DEFAULT_CONTENT_TYPE
157                                         || partType == PHPDocumentPartitioner.PHP_SCRIPT_CODE
158                                         || isSpecialPartition(partType)) {
159                                 edits.add(factory.createEdit(partition.getOffset(), 0,
160                                                 getCommentStart()));
161                         }
162
163                 } else { // !wasJavadoc
164
165                         if (partType == IPHPPartitions.PHP_PHPDOC_COMMENT) {
166                                 // if next is javadoc, end block comment before
167                                 edits.add(factory.createEdit(partition.getOffset(), 0,
168                                                 getCommentEnd()));
169                         } else if (partType == IPHPPartitions.PHP_MULTILINE_COMMENT) {
170                                 // already in a comment - remove startToken
171                                 edits.add(factory.createEdit(partition.getOffset(),
172                                                 getCommentStart().length(), "")); //$NON-NLS-1$
173                         }
174                 }
175
176                 return partition;
177         }
178
179         /**
180          * Handles the end of the last partition.
181          * 
182          * @param partition
183          * @param edits
184          * @param factory
185          * @param endOffset
186          */
187         private void handleLastPartition(ITypedRegion partition, List edits,
188                         Edit.EditFactory factory, int endOffset)
189                         throws BadLocationException {
190
191                 String partType = partition.getType();
192
193                 if (partType == IDocument.DEFAULT_CONTENT_TYPE
194                                 || partType == PHPDocumentPartitioner.PHP_SCRIPT_CODE) {
195                         // normal java: end comment where selection ends
196                         edits.add(factory.createEdit(endOffset, 0, getCommentEnd()));
197                 } else if (isSpecialPartition(partType)) {
198                         // special types: consume entire partition
199                         edits.add(factory.createEdit(partition.getOffset()
200                                         + partition.getLength(), 0, getCommentEnd()));
201                 }
202
203         }
204
205         /**
206          * Returns whether <code>partType</code> is special, i.e. a Java
207          * <code>String</code>,<code>Character</code>, or
208          * <code>Line End Comment</code> partition.
209          * 
210          * @param partType
211          *            the partition type to check
212          * @return <code>true</code> if <code>partType</code> is special,
213          *         <code>false</code> otherwise
214          */
215         private boolean isSpecialPartition(String partType) {
216                 // return partType == IJavaPartitions.JAVA_CHARACTER
217                 return partType == IPHPPartitions.PHP_STRING_DQ
218                                 || partType == IPHPPartitions.PHP_STRING_SQ
219                                 || partType == IPHPPartitions.PHP_STRING_HEREDOC
220                                 || partType == IPHPPartitions.PHP_SINGLELINE_COMMENT;
221         }
222
223         /*
224          * @see net.sourceforge.phpdt.internal.ui.actions.BlockCommentAction#validSelection(org.eclipse.jface.text.ITextSelection)
225          */
226         protected boolean isValidSelection(ITextSelection selection) {
227                 return selection != null && !selection.isEmpty()
228                                 && selection.getLength() > 0;
229         }
230
231 }