Syntax highlighting is changeable.
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / ui / text / template / contentassist / TemplateEngine.java
1 /*******************************************************************************
2  * Copyright (c) 2000, 2004 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials 
4  * are made available under the terms of the Common Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/cpl-v10.html
7  * 
8  * Contributors:
9  *     IBM Corporation - initial API and implementation
10  *******************************************************************************/
11 package net.sourceforge.phpdt.internal.ui.text.template.contentassist;
12
13 import java.util.ArrayList;
14
15 import net.sourceforge.phpdt.core.ICompilationUnit;
16 import net.sourceforge.phpdt.internal.corext.Assert;
17 import net.sourceforge.phpdt.internal.corext.template.php.CompilationUnitContext;
18 import net.sourceforge.phpdt.internal.corext.template.php.CompilationUnitContextType;
19 import net.sourceforge.phpdt.internal.ui.PHPUiImages;
20 import net.sourceforge.phpeclipse.PHPeclipsePlugin;
21
22 import org.eclipse.jface.text.BadLocationException;
23 import org.eclipse.jface.text.IDocument;
24 import org.eclipse.jface.text.IRegion;
25 import org.eclipse.jface.text.ITextViewer;
26 import org.eclipse.jface.text.Region;
27 import org.eclipse.jface.text.templates.GlobalTemplateVariables;
28 import org.eclipse.jface.text.templates.Template;
29 import org.eclipse.jface.text.templates.TemplateContextType;
30 import org.eclipse.swt.graphics.Point;
31
32 public class TemplateEngine {
33
34         private static final String $_LINE_SELECTION= "${" + GlobalTemplateVariables.LineSelection.NAME + "}"; //$NON-NLS-1$ //$NON-NLS-2$
35         private static final String $_WORD_SELECTION= "${" + GlobalTemplateVariables.WordSelection.NAME + "}"; //$NON-NLS-1$ //$NON-NLS-2$
36
37         /** The context type. */
38         private TemplateContextType fContextType;
39         /** The result proposals. */
40         private ArrayList fProposals= new ArrayList();
41
42         /**
43          * Creates the template engine for a particular context type.
44          * See <code>TemplateContext</code> for supported context types.
45          */
46         public TemplateEngine(TemplateContextType contextType) {
47                 Assert.isNotNull(contextType);
48                 fContextType= contextType;
49         }
50
51         /**
52          * Empties the collector.
53          */
54         public void reset() {
55                 fProposals.clear();
56         }
57
58         /**
59          * Returns the array of matching templates.
60          */
61         public TemplateProposal[] getResults() {
62                 return (TemplateProposal[]) fProposals.toArray(new TemplateProposal[fProposals.size()]);
63         }
64
65         /**
66          * Inspects the context of the compilation unit around <code>completionPosition</code>
67          * and feeds the collector with proposals.
68          * @param viewer the text viewer
69          * @param completionPosition the context position in the document of the text viewer
70          * @param compilationUnit the compilation unit (may be <code>null</code>)
71          */
72         public void complete(ITextViewer viewer, int completionPosition, ICompilationUnit compilationUnit) {
73             IDocument document= viewer.getDocument();
74             
75                 if (!(fContextType instanceof CompilationUnitContextType))
76                         return;
77
78                 Point selection= viewer.getSelectedRange();
79
80                 // remember selected text
81                 String selectedText= null;
82                 if (selection.y != 0) {
83                         try {
84                                 selectedText= document.get(selection.x, selection.y);
85                         } catch (BadLocationException e) {}
86                 }
87
88                 
89                 CompilationUnitContext context= ((CompilationUnitContextType) fContextType).createContext(document, completionPosition, selection.y, compilationUnit);
90                 context.setVariable("selection", selectedText); //$NON-NLS-1$
91                 int start= context.getStart();
92                 int end= context.getEnd();
93                 IRegion region= new Region(start, end - start);
94
95                 Template[] templates= PHPeclipsePlugin.getDefault().getTemplateStore().getTemplates(); 
96
97                 if (selection.y == 0) {
98                         for (int i= 0; i != templates.length; i++)
99                                 if (context.canEvaluate(templates[i]))
100                                         fProposals.add(new TemplateProposal(templates[i], context, region, PHPUiImages.get(PHPUiImages.IMG_OBJS_TEMPLATE)));
101
102                 } else {
103
104                         if (context.getKey().length() == 0)
105                                 context.setForceEvaluation(true);
106
107                         boolean multipleLinesSelected= areMultipleLinesSelected(viewer);
108                                 
109                         for (int i= 0; i != templates.length; i++) {
110                                 Template template= templates[i];                                
111                                 if (context.canEvaluate(template) &&
112                                         template.getContextTypeId().equals(context.getContextType().getId()) &&                         
113                                         (!multipleLinesSelected && template.getPattern().indexOf($_WORD_SELECTION) != -1 || (multipleLinesSelected && template.getPattern().indexOf($_LINE_SELECTION) != -1)))
114                                 {
115                                         fProposals.add(new TemplateProposal(templates[i], context, region, PHPUiImages.get(PHPUiImages.IMG_OBJS_TEMPLATE)));
116                                 }
117                         }
118                 }
119         }
120         
121         /**
122          * Returns <code>true</code> if one line is completely selected or if multiple lines are selected.
123          * Being completely selected means that all characters except the new line characters are 
124          * selected.
125          * 
126          * @return <code>true</code> if one or multiple lines are selected
127          * @since 2.1
128          */
129         private boolean areMultipleLinesSelected(ITextViewer viewer) {
130                 if (viewer == null)
131                         return false;
132                 
133                 Point s= viewer.getSelectedRange();
134                 if (s.y == 0)
135                         return false;
136                         
137                 try {
138                         
139                         IDocument document= viewer.getDocument();
140                         int startLine= document.getLineOfOffset(s.x);
141                         int endLine= document.getLineOfOffset(s.x + s.y);
142                         IRegion line= document.getLineInformation(startLine);
143                         return startLine != endLine || (s.x == line.getOffset() && s.y == line.getLength());
144                 
145                 } catch (BadLocationException x) {
146                         return false;
147                 }
148         }
149 }