improved syntax highligthing
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpeclipse / phpeditor / PHPContentOutlinePage.java
1 package net.sourceforge.phpeclipse.phpeditor;
2
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
9
10 Contributors:
11     IBM Corporation - Initial implementation
12     Klaus Hartlage - www.eclipseproject.de
13 **********************************************************************/
14
15 import java.text.MessageFormat;
16 import java.util.ArrayList;
17 import java.util.List;
18
19 import org.eclipse.swt.widgets.Composite;
20 import org.eclipse.swt.widgets.Control;
21
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;
35
36 import org.eclipse.ui.texteditor.IDocumentProvider;
37 import org.eclipse.ui.texteditor.ITextEditor;
38 import org.eclipse.ui.views.contentoutline.ContentOutlinePage;
39
40 /**
41  * A content outline page which always represents the content of the
42  * connected editor in 10 segments.
43  */
44 public class PHPContentOutlinePage extends ContentOutlinePage {
45
46         /**
47          * A segment element.
48          */
49         protected static class Segment {
50                 public String name;
51                 public Position position;
52
53                 public Segment(String name, Position position) {
54                         this.name = name;
55                         this.position = position;
56                 }
57
58                 public String toString() {
59                         return name;
60                 }
61         };
62
63         /**
64          * Divides the editor's document into ten segments and provides elements for them.
65          */
66         protected class ContentProvider implements ITreeContentProvider {
67
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);
71
72                 protected void parse(IDocument document) {
73
74                         int lines = document.getNumberOfLines();
75                         int increment = Math.max(Math.round((float) (lines / 10)), 10);
76                         
77       String text = document.get();
78                         int lastIndex = 0;
79       int i=0;
80                         lastIndex = text.indexOf("function ", lastIndex);
81                         while (lastIndex > 0) {
82
83                                 try {
84           i = lastIndex+9;
85           while ((i<text.length())&&Character.isJavaIdentifierPart(text.charAt(i))) {
86             i++;
87           } 
88                                         Position p = new Position(lastIndex, i-lastIndex);
89                                         document.addPosition(SEGMENTS, p);
90                                         fContent.add(new Segment(text.substring(lastIndex,i), p));
91      //     MessageFormat.format("function", new Object[] { new Integer(lastIndex)}), p)); //$NON-NLS-1$
92                                         lastIndex = text.indexOf("function", lastIndex+1);
93                                 } catch (BadLocationException e) {
94                                 } catch (BadPositionCategoryException e) {
95                                 }
96
97                         }
98
99                         //                      for (int line = 0; line < lines; line += increment) {
100                         //
101                         //                              int length = increment;
102                         //                              if (line + increment > lines)
103                         //                                      length = lines - line;
104                         //
105                         //                              try {
106                         //
107                         //                                      int offset = document.getLineOffset(line);
108                         //                                      int end = document.getLineOffset(line + length);
109                         //                                      length = end - offset;
110                         //                                      Position p = new Position(offset, length);
111                         //                                      document.addPosition(SEGMENTS, p);
112                         //                                      fContent.add(new Segment(MessageFormat.format(PHPEditorMessages.getString("OutlinePage.segment.title_pattern"), new Object[] { new Integer(offset)}), p)); //$NON-NLS-1$
113                         //
114                         //                              } catch (BadPositionCategoryException x) {
115                         //                              } catch (BadLocationException x) {
116                         //                              }
117                         //                      }
118                 }
119
120                 /*
121                  * @see IContentProvider#inputChanged(Viewer, Object, Object)
122                  */
123                 public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
124                         if (oldInput != null) {
125                                 IDocument document = fDocumentProvider.getDocument(oldInput);
126                                 if (document != null) {
127                                         try {
128                                                 document.removePositionCategory(SEGMENTS);
129                                         } catch (BadPositionCategoryException x) {
130                                         }
131                                         document.removePositionUpdater(fPositionUpdater);
132                                 }
133                         }
134
135                         fContent.clear();
136
137                         if (newInput != null) {
138                                 IDocument document = fDocumentProvider.getDocument(newInput);
139                                 if (document != null) {
140                                         document.addPositionCategory(SEGMENTS);
141                                         document.addPositionUpdater(fPositionUpdater);
142
143                                         parse(document);
144                                 }
145                         }
146                 }
147
148                 /*
149                  * @see IContentProvider#dispose
150                  */
151                 public void dispose() {
152                         if (fContent != null) {
153                                 fContent.clear();
154                                 fContent = null;
155                         }
156                 }
157
158                 /*
159                  * @see IContentProvider#isDeleted(Object)
160                  */
161                 public boolean isDeleted(Object element) {
162                         return false;
163                 }
164
165                 /*
166                  * @see IStructuredContentProvider#getElements(Object)
167                  */
168                 public Object[] getElements(Object element) {
169                         return fContent.toArray();
170                 }
171
172                 /*
173                  * @see ITreeContentProvider#hasChildren(Object)
174                  */
175                 public boolean hasChildren(Object element) {
176                         return element == fInput;
177                 }
178
179                 /*
180                  * @see ITreeContentProvider#getParent(Object)
181                  */
182                 public Object getParent(Object element) {
183                         if (element instanceof Segment)
184                                 return fInput;
185                         return null;
186                 }
187
188                 /*
189                  * @see ITreeContentProvider#getChildren(Object)
190                  */
191                 public Object[] getChildren(Object element) {
192                         if (element == fInput)
193                                 return fContent.toArray();
194                         return new Object[0];
195                 }
196         };
197
198         protected Object fInput;
199         protected IDocumentProvider fDocumentProvider;
200         protected ITextEditor fTextEditor;
201
202         /**
203          * Creates a content outline page using the given provider and the given editor.
204          */
205         public PHPContentOutlinePage(IDocumentProvider provider, ITextEditor editor) {
206                 super();
207                 fDocumentProvider = provider;
208                 fTextEditor = editor;
209         }
210
211         /* (non-Javadoc)
212          * Method declared on ContentOutlinePage
213          */
214         public void createControl(Composite parent) {
215
216                 super.createControl(parent);
217
218                 TreeViewer viewer = getTreeViewer();
219                 viewer.setContentProvider(new ContentProvider());
220                 viewer.setLabelProvider(new LabelProvider());
221                 viewer.addSelectionChangedListener(this);
222
223                 if (fInput != null)
224                         viewer.setInput(fInput);
225         }
226
227         /* (non-Javadoc)
228          * Method declared on ContentOutlinePage
229          */
230         public void selectionChanged(SelectionChangedEvent event) {
231
232                 super.selectionChanged(event);
233
234                 ISelection selection = event.getSelection();
235                 if (selection.isEmpty())
236                         fTextEditor.resetHighlightRange();
237                 else {
238                         Segment segment = (Segment) ((IStructuredSelection) selection).getFirstElement();
239                         int start = segment.position.getOffset();
240                         int length = segment.position.getLength();
241                         try {
242                                 fTextEditor.setHighlightRange(start, length, true);
243                         } catch (IllegalArgumentException x) {
244                                 fTextEditor.resetHighlightRange();
245                         }
246                 }
247         }
248
249         /**
250          * Sets the input of the outline page
251          */
252         public void setInput(Object input) {
253                 fInput = input;
254                 update();
255         }
256
257         /**
258          * Updates the outline page.
259          */
260         public void update() {
261                 TreeViewer viewer = getTreeViewer();
262
263                 if (viewer != null) {
264                         Control control = viewer.getControl();
265                         if (control != null && !control.isDisposed()) {
266                                 control.setRedraw(false);
267                                 viewer.setInput(fInput);
268                                 viewer.expandAll();
269                                 control.setRedraw(true);
270                         }
271                 }
272         }
273 }