package net.sourceforge.phpeclipse.phpeditor; /********************************************************************** Copyright (c) 2000, 2002 IBM Corp. and others. All rights reserved. This program and the accompanying materials are made available under the terms of the Common Public License v1.0 which accompanies this distribution, and is available at http://www.eclipse.org/legal/cpl-v10.html Contributors: IBM Corporation - Initial implementation Klaus Hartlage - www.eclipseproject.de **********************************************************************/ import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.TreeSet; import net.sourceforge.phpdt.internal.ui.viewsupport.ImageDescriptorRegistry; import net.sourceforge.phpeclipse.PHPeclipsePlugin; import net.sourceforge.phpeclipse.phpeditor.phpparser.PHPClassDeclaration; import net.sourceforge.phpeclipse.phpeditor.phpparser.PHPOutlineInfo; import net.sourceforge.phpeclipse.phpeditor.phpparser.PHPParser; import net.sourceforge.phpeclipse.phpeditor.phpparser.PHPSegment; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.jface.text.BadPositionCategoryException; import org.eclipse.jface.text.DefaultPositionUpdater; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.IPositionUpdater; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.ITreeContentProvider; import org.eclipse.jface.viewers.LabelProvider; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.jface.viewers.Viewer; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.ui.texteditor.IDocumentProvider; import org.eclipse.ui.texteditor.ITextEditor; import org.eclipse.ui.views.contentoutline.ContentOutlinePage; /** * A content outline page which always represents the functions of the * connected PHPEditor. */ public class PHPContentOutlinePage extends ContentOutlinePage { private static final String ERROR = "error"; //$NON-NLS-1$ private static final String WARNING = "warning"; //$NON-NLS-1$ protected static class SegmentComparator implements Comparator { public int compare(Object o1, Object o2) { if (o1 instanceof PHPClassDeclaration && !(o2 instanceof PHPClassDeclaration)) { return 1; } if (o2 instanceof PHPClassDeclaration && !(o1 instanceof PHPClassDeclaration)) { return -1; } return ((PHPSegment) o1).toString().compareToIgnoreCase(((PHPSegment) o2).toString()); } } /** * Divides the editor's document into ten segments and provides elements for them. */ protected class ContentProvider implements ITreeContentProvider { protected final static String SEGMENTS = "__php_segments"; //$NON-NLS-1$ protected IPositionUpdater fPositionUpdater = new DefaultPositionUpdater(SEGMENTS); protected List fContent = new ArrayList(10); protected TreeSet fVariables = new TreeSet(); // private String getIdentifier(String text, int firstIndex) { // int i = firstIndex; // char c; // int textLength = text.length(); // StringBuffer identifier = new StringBuffer(); // while (i < textLength) { // c = text.charAt(i++); // if (Character.isJavaIdentifierPart(c) || (c == '$')) { // identifier.append(c); // } else if ((i == firstIndex + 1) && (c == '$')) { // identifier.append(c); // } else { // return identifier.toString(); // } // } // return null; // } protected void parse(IDocument document) { // int lines = document.getNumberOfLines(); // int increment = Math.max(Math.round((float) (lines / 10)), 10); String name; int index; String text = document.get(); PHPParser parser = new PHPParser(null); PHPOutlineInfo outlineInfo = parser.parseInfo(fInput, text); fVariables = outlineInfo.getVariables(); PHPClassDeclaration declarations = outlineInfo.getDeclarations(); PHPSegment temp; for (int i = 0; i < declarations.size(); i++) { temp = declarations.get(i); fContent.add(temp); } Collections.sort(fContent, new SegmentComparator()); } /* * @see IContentProvider#inputChanged(Viewer, Object, Object) */ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { if (oldInput != null) { IDocument document = fDocumentProvider.getDocument(oldInput); if (document != null) { try { document.removePositionCategory(SEGMENTS); } catch (BadPositionCategoryException x) { } document.removePositionUpdater(fPositionUpdater); } } fContent.clear(); fVariables.clear(); if (newInput != null) { IDocument document = fDocumentProvider.getDocument(newInput); if (document != null) { document.addPositionCategory(SEGMENTS); document.addPositionUpdater(fPositionUpdater); parse(document); } } } /* * @see IContentProvider#dispose */ public void dispose() { if (fContent != null) { fContent.clear(); fContent = null; } if (fVariables != null) { fVariables.clear(); fVariables = null; } } /* * @see IContentProvider#isDeleted(Object) */ public boolean isDeleted(Object element) { return false; } /** * returns all PHP variables */ public Object[] getVariables() { return fVariables.toArray(); } /* * @see IStructuredContentProvider#getElements(Object) */ public Object[] getElements(Object element) { return fContent.toArray(); } /* * @see ITreeContentProvider#hasChildren(Object) */ public boolean hasChildren(Object element) { if (element instanceof PHPClassDeclaration) { return !((PHPClassDeclaration) element).getList().isEmpty(); } return element == fInput; } /* * @see ITreeContentProvider#getParent(Object) */ public Object getParent(Object element) { if (element instanceof PHPSegment) { return ((PHPSegment) element).getParent(); } return null; } /* * @see ITreeContentProvider#getChildren(Object) */ public Object[] getChildren(Object element) { if (element == fInput) return fContent.toArray(); if (element instanceof PHPClassDeclaration) return ((PHPClassDeclaration) element).getList().toArray(); return new Object[0]; } }; protected class OutlineLabelProvider extends LabelProvider { private ImageDescriptorRegistry fRegistry; public OutlineLabelProvider() { fRegistry = PHPeclipsePlugin.getImageDescriptorRegistry(); ; } /** * The LabelProvider implementation of this * ILabelProvider method returns null. Subclasses may * override. */ public Image getImage(Object element) { if (element instanceof PHPSegment) { ImageDescriptor descriptor = ((PHPSegment) element).getImage(); return fRegistry.get(descriptor); } return null; } } protected Object fInput; protected IDocumentProvider fDocumentProvider; protected ITextEditor fTextEditor; protected PHPEditor fEditor; protected ContentProvider contentProvider; /** * Creates a content outline page using the given provider and the given editor. */ public PHPContentOutlinePage(IDocumentProvider provider, ITextEditor editor) { super(); contentProvider = null; fDocumentProvider = provider; fTextEditor = editor; if (editor instanceof PHPEditor) fEditor = (PHPEditor) editor; } /* (non-Javadoc) * Method declared on ContentOutlinePage */ public void createControl(Composite parent) { super.createControl(parent); TreeViewer viewer = getTreeViewer(); contentProvider = new ContentProvider(); viewer.setContentProvider(contentProvider); viewer.setLabelProvider(new OutlineLabelProvider()); viewer.addSelectionChangedListener(this); if (fInput != null) viewer.setInput(fInput); } /* (non-Javadoc) * Method declared on ContentOutlinePage */ public void selectionChanged(SelectionChangedEvent event) { super.selectionChanged(event); ISelection selection = event.getSelection(); if (selection.isEmpty()) fTextEditor.resetHighlightRange(); else { PHPSegment segment = (PHPSegment) ((IStructuredSelection) selection).getFirstElement(); int start = segment.getPosition().getOffset(); int length = segment.getPosition().getLength(); try { fTextEditor.setHighlightRange(start, length, true); } catch (IllegalArgumentException x) { fTextEditor.resetHighlightRange(); } } } /** * Sets the input of the outline page */ public void setInput(Object input) { fInput = input; update(); } /** * Updates the outline page. */ public void update() { TreeViewer viewer = getTreeViewer(); if (viewer != null) { Control control = viewer.getControl(); if (control != null && !control.isDisposed()) { control.setRedraw(false); viewer.setInput(fInput); viewer.expandAll(); control.setRedraw(true); } } } public Object[] getVariables() { if (contentProvider != null) { return contentProvider.getVariables(); } return null; } // public ContentProvider getContentProvider() { // return contentProvider; // } }