a lot of fixes
[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.*;
31 import org.eclipse.jface.viewers.ISelection;
32 import org.eclipse.jface.viewers.IStructuredSelection;
33 import org.eclipse.jface.viewers.ITreeContentProvider;
34 import org.eclipse.jface.viewers.LabelProvider;
35 import org.eclipse.jface.viewers.SelectionChangedEvent;
36 import org.eclipse.jface.viewers.TreeViewer;
37 import org.eclipse.jface.viewers.Viewer;
38 import org.eclipse.swt.graphics.Image;
39 import org.eclipse.swt.widgets.Composite;
40 import org.eclipse.ui.texteditor.IDocumentProvider;
41 import org.eclipse.ui.texteditor.ITextEditor;
42
43 import test.PHPParserManager;
44 import test.PHPParserSuperclass;
45
46 /**
47  * A content outline page which always represents the functions of the
48  * connected PHPEditor.
49  */
50 public class PHPContentOutlinePage extends AbstractContentOutlinePage {
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 OutlineableWithChildren && !(o2 instanceof OutlineableWithChildren)) {
57         return 1;
58       }
59       if (o2 instanceof OutlineableWithChildren && !(o1 instanceof OutlineableWithChildren)) {
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 OutlineableWithChildren) {
185         return !((OutlineableWithChildren) 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 OutlineableWithChildren)
207         return ((OutlineableWithChildren) 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 IDocumentProvider fDocumentProvider;
234   protected ITextEditor fTextEditor;
235   protected PHPEditor fEditor;
236   protected ContentProvider fContentProvider;
237
238   /**
239    * Creates a content outline page using the given provider and the given editor.
240    */
241   public PHPContentOutlinePage(IDocumentProvider provider, ITextEditor editor) {
242     super();
243     fContentProvider = null;
244     fDocumentProvider = provider;
245     fTextEditor = editor;
246     if (editor instanceof PHPEditor)
247       fEditor = (PHPEditor) editor;
248   }
249
250   /* (non-Javadoc)
251    * Method declared on ContentOutlinePage
252    */
253   public void createControl(Composite parent) {
254
255     super.createControl(parent);
256
257     TreeViewer viewer = getTreeViewer();
258
259     fContentProvider = new ContentProvider();
260     viewer.setContentProvider(fContentProvider);
261     viewer.setLabelProvider(new OutlineLabelProvider());
262
263     viewer.addSelectionChangedListener(this);
264
265     if (fInput != null)
266       viewer.setInput(fInput);
267   }
268
269   /* (non-Javadoc)
270    * Method declared on ContentOutlinePage
271    */
272   public void selectionChanged(SelectionChangedEvent event) {
273
274     super.selectionChanged(event);
275
276     ISelection selection = event.getSelection();
277     if (selection.isEmpty())
278       fTextEditor.resetHighlightRange();
279     else {
280       Outlineable segment = (Outlineable) ((IStructuredSelection) selection).getFirstElement();
281       int start = segment.getPosition().getOffset();
282       int length = segment.getPosition().getLength();
283       try {
284         fTextEditor.setHighlightRange(start, length, true);
285       } catch (IllegalArgumentException x) {
286         fTextEditor.resetHighlightRange();
287       }
288     }
289   }
290   
291   public Object[] getVariables() {
292     if (fContentProvider != null) {
293       return fContentProvider.getVariables();
294     }
295     return null;
296   }
297   //  public ContentProvider getContentProvider() {
298   //    return contentProvider;
299   //  }
300
301 }