bugfixes
[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.Outlineable;
22 import net.sourceforge.phpdt.internal.compiler.parser.OutlineableWithChildren;
23 import net.sourceforge.phpdt.internal.compiler.parser.PHPOutlineInfo;
24 import net.sourceforge.phpdt.internal.compiler.parser.PHPSegment;
25 import net.sourceforge.phpdt.internal.compiler.parser.PHPSegmentWithChildren;
26 import net.sourceforge.phpdt.internal.ui.viewsupport.ImageDescriptorRegistry;
27 import net.sourceforge.phpeclipse.PHPeclipsePlugin;
28
29 import org.eclipse.jface.resource.ImageDescriptor;
30 import org.eclipse.jface.text.BadPositionCategoryException;
31 import org.eclipse.jface.text.DefaultPositionUpdater;
32 import org.eclipse.jface.text.IDocument;
33 import org.eclipse.jface.text.IPositionUpdater;
34 import org.eclipse.jface.viewers.ISelection;
35 import org.eclipse.jface.viewers.IStructuredSelection;
36 import org.eclipse.jface.viewers.ITreeContentProvider;
37 import org.eclipse.jface.viewers.LabelProvider;
38 import org.eclipse.jface.viewers.SelectionChangedEvent;
39 import org.eclipse.jface.viewers.TreeViewer;
40 import org.eclipse.jface.viewers.Viewer;
41 import org.eclipse.swt.graphics.Image;
42 import org.eclipse.swt.widgets.Composite;
43 import org.eclipse.ui.texteditor.IDocumentProvider;
44 import org.eclipse.ui.texteditor.ITextEditor;
45
46 import test.PHPParserManager;
47 import test.PHPParserSuperclass;
48
49 /**
50  * A content outline page which always represents the functions of the
51  * connected PHPEditor.
52  */
53 public class PHPContentOutlinePage extends AbstractContentOutlinePage {
54   private static final String ERROR = "error"; //$NON-NLS-1$
55   private static final String WARNING = "warning"; //$NON-NLS-1$
56
57   protected static class SegmentComparator implements Comparator {
58     public int compare(Object o1, Object o2) {
59       if (o1 instanceof PHPSegmentWithChildren && !(o2 instanceof PHPSegmentWithChildren)) {
60         return 1;
61       }
62       if (o2 instanceof PHPSegmentWithChildren && !(o1 instanceof PHPSegmentWithChildren)) {
63         return -1;
64       }
65       return ((Outlineable) o1).toString().compareToIgnoreCase(((Outlineable) o2).toString());
66     }
67   }
68
69   /**
70    * Divides the editor's document into ten segments and provides elements for them.
71    */
72   protected class ContentProvider implements ITreeContentProvider {
73
74     protected final static String SEGMENTS = "__php_segments"; //$NON-NLS-1$
75     protected IPositionUpdater fPositionUpdater = new DefaultPositionUpdater(SEGMENTS);
76     protected List fContent = new ArrayList(10);
77     protected TreeSet fVariables = new TreeSet();
78
79     //    private String getIdentifier(String text, int firstIndex) {
80     //      int i = firstIndex;
81     //      char c;
82     //      int textLength = text.length();
83     //      StringBuffer identifier = new StringBuffer();
84     //      while (i < textLength) {
85     //        c = text.charAt(i++);
86     //        if (Scanner.isPHPIdentifierPart(c) || (c == '$')) {
87     //          identifier.append(c);
88     //        } else if ((i == firstIndex + 1) && (c == '$')) {
89     //          identifier.append(c);
90     //        } else {
91     //          return identifier.toString();
92     //        }
93     //      }
94     //      return null;
95     //    }
96
97     protected void parse(IDocument document) {
98
99       //      int lines = document.getNumberOfLines();
100       //      int increment = Math.max(Math.round((float) (lines / 10)), 10);
101
102       String name;
103       int index;
104       String text = document.get();
105       PHPParserSuperclass parser = PHPParserManager.getParser(null);
106
107       PHPOutlineInfo outlineInfo = parser.parseInfo(fInput, text);
108       fVariables = outlineInfo.getVariables();
109
110       OutlineableWithChildren declarations = outlineInfo.getDeclarations();
111       Outlineable temp;
112       for (int i = 0; i < declarations.size(); i++) {
113         temp = declarations.get(i);
114         fContent.add(temp);
115       }
116       Collections.sort(fContent, new SegmentComparator());
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 Outlineable) {
198         return ((Outlineable) 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 Outlineable) {
229         ImageDescriptor descriptor = ((Outlineable) element).getImage();
230         return fRegistry.get(descriptor);
231       }
232       return null;
233     }
234   }
235
236   protected IDocumentProvider fDocumentProvider;
237   protected ITextEditor fTextEditor;
238   protected PHPEditor fEditor;
239   protected ContentProvider fContentProvider;
240
241   /**
242    * Creates a content outline page using the given provider and the given editor.
243    */
244   public PHPContentOutlinePage(IDocumentProvider provider, ITextEditor editor) {
245     super();
246     fContentProvider = null;
247     fDocumentProvider = provider;
248     fTextEditor = editor;
249     if (editor instanceof PHPEditor)
250       fEditor = (PHPEditor) editor;
251   }
252
253   /* (non-Javadoc)
254    * Method declared on ContentOutlinePage
255    */
256   public void createControl(Composite parent) {
257
258     super.createControl(parent);
259
260     TreeViewer viewer = getTreeViewer();
261
262     fContentProvider = new ContentProvider();
263     viewer.setContentProvider(fContentProvider);
264     viewer.setLabelProvider(new OutlineLabelProvider());
265
266     viewer.addSelectionChangedListener(this);
267
268     if (fInput != null)
269       viewer.setInput(fInput);
270   }
271
272   /* (non-Javadoc)
273    * Method declared on ContentOutlinePage
274    */
275   public void selectionChanged(SelectionChangedEvent event) {
276
277     super.selectionChanged(event);
278
279     ISelection selection = event.getSelection();
280     if (selection.isEmpty())
281       fTextEditor.resetHighlightRange();
282     else {
283       PHPSegment segment = (PHPSegment) ((IStructuredSelection) selection).getFirstElement();
284       int start = segment.getPosition().getOffset();
285       int length = segment.getPosition().getLength();
286       try {
287         fTextEditor.setHighlightRange(start, length, true);
288       } catch (IllegalArgumentException x) {
289         fTextEditor.resetHighlightRange();
290       }
291     }
292   }
293   
294   public Object[] getVariables() {
295     if (fContentProvider != null) {
296       return fContentProvider.getVariables();
297     }
298     return null;
299   }
300   //  public ContentProvider getContentProvider() {
301   //    return contentProvider;
302   //  }
303
304 }