Added state reset
[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.util.ArrayList;
16 import java.util.Collections;
17 import java.util.Comparator;
18 import java.util.List;
19 import java.util.TreeSet;
20
21 import net.sourceforge.phpdt.internal.compiler.parser.PHPOutlineInfo;
22 import net.sourceforge.phpdt.internal.compiler.parser.PHPSegment;
23 import net.sourceforge.phpdt.internal.compiler.parser.PHPSegmentWithChildren;
24 import net.sourceforge.phpdt.internal.ui.viewsupport.ImageDescriptorRegistry;
25 import net.sourceforge.phpeclipse.PHPeclipsePlugin;
26
27 import org.eclipse.jface.resource.ImageDescriptor;
28 import org.eclipse.jface.text.BadPositionCategoryException;
29 import org.eclipse.jface.text.DefaultPositionUpdater;
30 import org.eclipse.jface.text.IDocument;
31 import org.eclipse.jface.text.IPositionUpdater;
32 import org.eclipse.jface.viewers.ISelection;
33 import org.eclipse.jface.viewers.IStructuredSelection;
34 import org.eclipse.jface.viewers.ITreeContentProvider;
35 import org.eclipse.jface.viewers.LabelProvider;
36 import org.eclipse.jface.viewers.SelectionChangedEvent;
37 import org.eclipse.jface.viewers.TreeViewer;
38 import org.eclipse.jface.viewers.Viewer;
39 import org.eclipse.swt.graphics.Image;
40 import org.eclipse.swt.widgets.Composite;
41 import org.eclipse.swt.widgets.Control;
42 import org.eclipse.ui.texteditor.IDocumentProvider;
43 import org.eclipse.ui.texteditor.ITextEditor;
44 import org.eclipse.ui.views.contentoutline.ContentOutlinePage;
45 import test.PHPParserSuperclass;
46 import test.PHPParserManager;
47
48 /**
49  * A content outline page which always represents the functions of the
50  * connected PHPEditor.
51  */
52 public class PHPContentOutlinePage extends ContentOutlinePage {
53   private static final String ERROR = "error"; //$NON-NLS-1$
54   private static final String WARNING = "warning"; //$NON-NLS-1$
55
56   protected static class SegmentComparator implements Comparator {
57     public int compare(Object o1, Object o2) {
58       if (o1 instanceof PHPSegmentWithChildren && !(o2 instanceof PHPSegmentWithChildren)) {
59         return 1;
60       }
61       if (o2 instanceof PHPSegmentWithChildren && !(o1 instanceof PHPSegmentWithChildren)) {
62         return -1;
63       }
64       return ((PHPSegment) o1).toString().compareToIgnoreCase(((PHPSegment) o2).toString());
65     }
66   }
67
68   /**
69    * Divides the editor's document into ten segments and provides elements for them.
70    */
71   protected class ContentProvider implements ITreeContentProvider {
72
73     protected final static String SEGMENTS = "__php_segments"; //$NON-NLS-1$
74     protected IPositionUpdater fPositionUpdater = new DefaultPositionUpdater(SEGMENTS);
75     protected List fContent = new ArrayList(10);
76     protected TreeSet fVariables = new TreeSet();
77
78     //    private String getIdentifier(String text, int firstIndex) {
79     //      int i = firstIndex;
80     //      char c;
81     //      int textLength = text.length();
82     //      StringBuffer identifier = new StringBuffer();
83     //      while (i < textLength) {
84     //        c = text.charAt(i++);
85     //        if (Scanner.isPHPIdentifierPart(c) || (c == '$')) {
86     //          identifier.append(c);
87     //        } else if ((i == firstIndex + 1) && (c == '$')) {
88     //          identifier.append(c);
89     //        } else {
90     //          return identifier.toString();
91     //        }
92     //      }
93     //      return null;
94     //    }
95
96     protected void parse(IDocument document) {
97
98       //      int lines = document.getNumberOfLines();
99       //      int increment = Math.max(Math.round((float) (lines / 10)), 10);
100
101       String name;
102       int index;
103       String text = document.get();
104       PHPParserSuperclass parser = PHPParserManager.getParser(null);
105
106       PHPOutlineInfo outlineInfo = parser.parseInfo(fInput, text);
107       fVariables = outlineInfo.getVariables();
108
109       PHPSegmentWithChildren declarations = outlineInfo.getDeclarations();
110       PHPSegment temp;
111       for (int i = 0; i < declarations.size(); i++) {
112         temp = declarations.get(i);
113         fContent.add(temp);
114       }
115       Collections.sort(fContent, new SegmentComparator());
116
117     }
118
119     /*
120      * @see IContentProvider#inputChanged(Viewer, Object, Object)
121      */
122     public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
123       if (oldInput != null) {
124         IDocument document = fDocumentProvider.getDocument(oldInput);
125         if (document != null) {
126           try {
127             document.removePositionCategory(SEGMENTS);
128           } catch (BadPositionCategoryException x) {
129           }
130           document.removePositionUpdater(fPositionUpdater);
131         }
132       }
133
134       fContent.clear();
135       fVariables.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       if (fVariables != null) {
157         fVariables.clear();
158         fVariables = null;
159       }
160     }
161
162     /*
163      * @see IContentProvider#isDeleted(Object)
164      */
165     public boolean isDeleted(Object element) {
166       return false;
167     }
168
169     /**
170      * returns all PHP variables
171      */
172     public Object[] getVariables() {
173       return fVariables.toArray();
174     }
175
176     /*
177      * @see IStructuredContentProvider#getElements(Object)
178      */
179     public Object[] getElements(Object element) {
180       return fContent.toArray();
181     }
182
183     /*
184      * @see ITreeContentProvider#hasChildren(Object)
185      */
186     public boolean hasChildren(Object element) {
187       if (element instanceof PHPSegmentWithChildren) {
188         return !((PHPSegmentWithChildren) element).getList().isEmpty();
189       }
190       return element == fInput;
191     }
192
193     /*
194      * @see ITreeContentProvider#getParent(Object)
195      */
196     public Object getParent(Object element) {
197       if (element instanceof PHPSegment) {
198         return ((PHPSegment) element).getParent();
199       }
200       return null;
201     }
202
203     /*
204      * @see ITreeContentProvider#getChildren(Object)
205      */
206     public Object[] getChildren(Object element) {
207       if (element == fInput)
208         return fContent.toArray();
209       if (element instanceof PHPSegmentWithChildren)
210         return ((PHPSegmentWithChildren) element).getList().toArray();
211       return new Object[0];
212     }
213   };
214
215   protected class OutlineLabelProvider extends LabelProvider {
216     private ImageDescriptorRegistry fRegistry;
217
218     public OutlineLabelProvider() {
219       fRegistry = PHPeclipsePlugin.getImageDescriptorRegistry();
220       ;
221     }
222     /**
223     * The <code>LabelProvider</code> implementation of this 
224     * <code>ILabelProvider</code> method returns <code>null</code>. Subclasses may 
225     * override.
226     */
227     public Image getImage(Object element) {
228       if (element instanceof PHPSegment) {
229         ImageDescriptor descriptor = ((PHPSegment) element).getImage();
230         return fRegistry.get(descriptor);
231       }
232       return null;
233     }
234   }
235
236   protected Object fInput;
237   protected IDocumentProvider fDocumentProvider;
238   protected ITextEditor fTextEditor;
239   protected PHPEditor fEditor;
240   protected ContentProvider contentProvider;
241
242   /**
243    * Creates a content outline page using the given provider and the given editor.
244    */
245   public PHPContentOutlinePage(IDocumentProvider provider, ITextEditor editor) {
246     super();
247     contentProvider = null;
248     fDocumentProvider = provider;
249     fTextEditor = editor;
250     if (editor instanceof PHPEditor)
251       fEditor = (PHPEditor) editor;
252   }
253
254   /* (non-Javadoc)
255    * Method declared on ContentOutlinePage
256    */
257   public void createControl(Composite parent) {
258
259     super.createControl(parent);
260
261     TreeViewer viewer = getTreeViewer();
262
263     contentProvider = new ContentProvider();
264     viewer.setContentProvider(contentProvider);
265     viewer.setLabelProvider(new OutlineLabelProvider());
266
267     viewer.addSelectionChangedListener(this);
268
269     if (fInput != null)
270       viewer.setInput(fInput);
271   }
272
273   /* (non-Javadoc)
274    * Method declared on ContentOutlinePage
275    */
276   public void selectionChanged(SelectionChangedEvent event) {
277
278     super.selectionChanged(event);
279
280     ISelection selection = event.getSelection();
281     if (selection.isEmpty())
282       fTextEditor.resetHighlightRange();
283     else {
284       PHPSegment segment = (PHPSegment) ((IStructuredSelection) selection).getFirstElement();
285       int start = segment.getPosition().getOffset();
286       int length = segment.getPosition().getLength();
287       try {
288         fTextEditor.setHighlightRange(start, length, true);
289       } catch (IllegalArgumentException x) {
290         fTextEditor.resetHighlightRange();
291       }
292     }
293   }
294
295   /**
296    * Sets the input of the outline page
297    */
298   public void setInput(Object input) {
299     fInput = input;
300     update();
301   }
302
303   /**
304    * Updates the outline page.
305    */
306   public void update() {
307     TreeViewer viewer = getTreeViewer();
308
309     if (viewer != null) {
310       Control control = viewer.getControl();
311       if (control != null && !control.isDisposed()) {
312         control.setRedraw(false);
313         viewer.setInput(fInput);
314         viewer.expandAll();
315         control.setRedraw(true);
316       }
317     }
318   }
319   
320   public Object[] getVariables() {
321     if (contentProvider != null) {
322       return contentProvider.getVariables();
323     }
324     return null;
325   }
326   //  public ContentProvider getContentProvider() {
327   //    return contentProvider;
328   //  }
329
330 }