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