1 package net.sourceforge.phpeclipse.phpeditor;
3 /**********************************************************************
4 Copyright (c) 2000, 2002 IBM Corp. and others.
5 All rights reserved. This program and the accompanying materials
6 are made available under the terms of the Common Public License v1.0
7 which accompanies this distribution, and is available at
8 http://www.eclipse.org/legal/cpl-v10.html
11 IBM Corporation - Initial implementation
12 Klaus Hartlage - www.eclipseproject.de
13 **********************************************************************/
15 import java.text.MessageFormat;
16 import java.util.ArrayList;
17 import java.util.List;
19 import org.eclipse.swt.widgets.Composite;
20 import org.eclipse.swt.widgets.Control;
22 import org.eclipse.jface.text.BadLocationException;
23 import org.eclipse.jface.text.BadPositionCategoryException;
24 import org.eclipse.jface.text.DefaultPositionUpdater;
25 import org.eclipse.jface.text.IDocument;
26 import org.eclipse.jface.text.IPositionUpdater;
27 import org.eclipse.jface.text.Position;
28 import org.eclipse.jface.viewers.ISelection;
29 import org.eclipse.jface.viewers.IStructuredSelection;
30 import org.eclipse.jface.viewers.ITreeContentProvider;
31 import org.eclipse.jface.viewers.LabelProvider;
32 import org.eclipse.jface.viewers.SelectionChangedEvent;
33 import org.eclipse.jface.viewers.TreeViewer;
34 import org.eclipse.jface.viewers.Viewer;
36 import org.eclipse.ui.texteditor.IDocumentProvider;
37 import org.eclipse.ui.texteditor.ITextEditor;
38 import org.eclipse.ui.views.contentoutline.ContentOutlinePage;
41 * A content outline page which always represents the content of the
42 * connected editor in 10 segments.
44 public class PHPContentOutlinePage extends ContentOutlinePage {
49 protected static class Segment {
51 public Position position;
53 public Segment(String name, Position position) {
55 this.position = position;
58 public String toString() {
64 * Divides the editor's document into ten segments and provides elements for them.
66 protected class ContentProvider implements ITreeContentProvider {
68 protected final static String SEGMENTS = "__php_segments"; //$NON-NLS-1$
69 protected IPositionUpdater fPositionUpdater = new DefaultPositionUpdater(SEGMENTS);
70 protected List fContent = new ArrayList(10);
72 private String getIdentifier(String text, int firstIndex) {
75 int textLength = text.length();
76 StringBuffer identifier = new StringBuffer();
77 while (i < textLength) {
79 if (Character.isJavaIdentifierPart(c)) {
82 return identifier.toString();
88 protected void parse(IDocument document) {
90 int lines = document.getNumberOfLines();
91 int increment = Math.max(Math.round((float) (lines / 10)), 10);
93 String text = document.get();
96 // lastIndex = text.indexOf("function ", lastIndex);
97 // while (lastIndex > 0) {
100 // i = lastIndex + 9;
101 // while ((i < text.length()) && Character.isJavaIdentifierPart(text.charAt(i))) {
104 // Position p = new Position(lastIndex, i - lastIndex);
105 // document.addPosition(SEGMENTS, p);
106 // fContent.add(new Segment(text.substring(lastIndex, i), p));
107 // // MessageFormat.format("function", new Object[] { new Integer(lastIndex)}), p)); //$NON-NLS-1$
108 // lastIndex = text.indexOf("function", lastIndex + 1);
109 // } catch (BadLocationException e) {
110 // } catch (BadPositionCategoryException e) {
115 boolean lineCommentMode = false;
116 boolean multiLineCommentMode = false;
117 boolean stringMode = false;
118 boolean functionMode = false;
123 int textLength = text.length() - 10;
124 while (i < textLength) {
125 c = text.charAt(i++);
127 lineCommentMode = false;
128 // read until end of line
129 } else if (c == '#') {
130 // read until end of line
131 lineCommentMode = true;
133 } else if (c == '/') {
134 c2 = text.charAt(i++);
136 lineCommentMode = true;
138 } else if (c2 == '*') {
139 multiLineCommentMode = true;
144 } else if (c == '*' && multiLineCommentMode) {
145 c2 = text.charAt(i++);
147 multiLineCommentMode = false;
152 } else if (c == '\\' && stringMode) {
153 c2 = text.charAt(i++);
159 } else if (c == '"') {
167 if (lineCommentMode || multiLineCommentMode || stringMode) {
171 if (functionMode && Character.isJavaIdentifierPart((char) c)) {
172 functionMode = false;
174 identifier = getIdentifier(text, lastIndex);
176 i += identifier.length()-1;
177 Position p = new Position(lastIndex, i - lastIndex);
178 document.addPosition(SEGMENTS, p);
179 fContent.add(new Segment(text.substring(lastIndex, i), p));
180 // MessageFormat.format("function", new Object[] { new Integer(lastIndex)}), p)); //$NON-NLS-1$
181 // lastIndex = text.indexOf("function", lastIndex + 1);
182 } catch (BadLocationException e) {
183 } catch (BadPositionCategoryException e) {
186 } else if (c == 'f') {
187 identifier = getIdentifier(text, i - 1);
188 if (identifier.equals("function")) {
196 // for (int line = 0; line < lines; line += increment) {
198 // int length = increment;
199 // if (line + increment > lines)
200 // length = lines - line;
204 // int offset = document.getLineOffset(line);
205 // int end = document.getLineOffset(line + length);
206 // length = end - offset;
207 // Position p = new Position(offset, length);
208 // document.addPosition(SEGMENTS, p);
209 // fContent.add(new Segment(MessageFormat.format(PHPEditorMessages.getString("OutlinePage.segment.title_pattern"), new Object[] { new Integer(offset)}), p)); //$NON-NLS-1$
211 // } catch (BadPositionCategoryException x) {
212 // } catch (BadLocationException x) {
218 * @see IContentProvider#inputChanged(Viewer, Object, Object)
220 public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
221 if (oldInput != null) {
222 IDocument document = fDocumentProvider.getDocument(oldInput);
223 if (document != null) {
225 document.removePositionCategory(SEGMENTS);
226 } catch (BadPositionCategoryException x) {
228 document.removePositionUpdater(fPositionUpdater);
234 if (newInput != null) {
235 IDocument document = fDocumentProvider.getDocument(newInput);
236 if (document != null) {
237 document.addPositionCategory(SEGMENTS);
238 document.addPositionUpdater(fPositionUpdater);
246 * @see IContentProvider#dispose
248 public void dispose() {
249 if (fContent != null) {
256 * @see IContentProvider#isDeleted(Object)
258 public boolean isDeleted(Object element) {
263 * @see IStructuredContentProvider#getElements(Object)
265 public Object[] getElements(Object element) {
266 return fContent.toArray();
270 * @see ITreeContentProvider#hasChildren(Object)
272 public boolean hasChildren(Object element) {
273 return element == fInput;
277 * @see ITreeContentProvider#getParent(Object)
279 public Object getParent(Object element) {
280 if (element instanceof Segment)
286 * @see ITreeContentProvider#getChildren(Object)
288 public Object[] getChildren(Object element) {
289 if (element == fInput)
290 return fContent.toArray();
291 return new Object[0];
295 protected Object fInput;
296 protected IDocumentProvider fDocumentProvider;
297 protected ITextEditor fTextEditor;
300 * Creates a content outline page using the given provider and the given editor.
302 public PHPContentOutlinePage(IDocumentProvider provider, ITextEditor editor) {
304 fDocumentProvider = provider;
305 fTextEditor = editor;
309 * Method declared on ContentOutlinePage
311 public void createControl(Composite parent) {
313 super.createControl(parent);
315 TreeViewer viewer = getTreeViewer();
316 viewer.setContentProvider(new ContentProvider());
317 viewer.setLabelProvider(new LabelProvider());
318 viewer.addSelectionChangedListener(this);
321 viewer.setInput(fInput);
325 * Method declared on ContentOutlinePage
327 public void selectionChanged(SelectionChangedEvent event) {
329 super.selectionChanged(event);
331 ISelection selection = event.getSelection();
332 if (selection.isEmpty())
333 fTextEditor.resetHighlightRange();
335 Segment segment = (Segment) ((IStructuredSelection) selection).getFirstElement();
336 int start = segment.position.getOffset();
337 int length = segment.position.getLength();
339 fTextEditor.setHighlightRange(start, length, true);
340 } catch (IllegalArgumentException x) {
341 fTextEditor.resetHighlightRange();
347 * Sets the input of the outline page
349 public void setInput(Object input) {
355 * Updates the outline page.
357 public void update() {
358 TreeViewer viewer = getTreeViewer();
360 if (viewer != null) {
361 Control control = viewer.getControl();
362 if (control != null && !control.isDisposed()) {
363 control.setRedraw(false);
364 viewer.setInput(fInput);
366 control.setRedraw(true);