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