f1d9ee59c1a618a7cbd6e8666ae7623e0a8e56e2
[phpeclipse.git] / net.sourceforge.phpeclipse.ui / 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 //incastrix
17 //import net.sourceforge.phpdt.internal.corext.Assert;
18 import org.eclipse.core.runtime.Assert;
19 import net.sourceforge.phpdt.internal.corext.template.php.CompilationUnitContext;
20 import net.sourceforge.phpdt.internal.corext.template.php.CompilationUnitContextType;
21 import net.sourceforge.phpdt.internal.ui.PHPUiImages;
22 import net.sourceforge.phpeclipse.ui.WebUI;
23 //import net.sourceforge.phpeclipse.PHPeclipsePlugin;
24
25 import org.eclipse.jface.text.BadLocationException;
26 import org.eclipse.jface.text.IDocument;
27 import org.eclipse.jface.text.IRegion;
28 import org.eclipse.jface.text.ITextViewer;
29 import org.eclipse.jface.text.Region;
30 import org.eclipse.jface.text.templates.GlobalTemplateVariables;
31 import org.eclipse.jface.text.templates.Template;
32 import org.eclipse.jface.text.templates.TemplateContextType;
33 import org.eclipse.swt.graphics.Point;
34
35 public class TemplateEngine {
36
37         private static final String $_LINE_SELECTION = "${" + GlobalTemplateVariables.LineSelection.NAME + "}"; //$NON-NLS-1$ //$NON-NLS-2$
38
39         private static final String $_WORD_SELECTION = "${" + GlobalTemplateVariables.WordSelection.NAME + "}"; //$NON-NLS-1$ //$NON-NLS-2$
40
41         /** The context type. */
42         private TemplateContextType fContextType;
43
44         /** The result proposals. */
45         private ArrayList fProposals = new ArrayList();
46
47         /**
48          * Creates the template engine for a particular context type. See
49          * <code>TemplateContext</code> for supported context types.
50          */
51         public TemplateEngine(TemplateContextType contextType) {
52                 Assert.isNotNull(contextType);
53                 fContextType = contextType;
54         }
55
56         /**
57          * Empties the collector.
58          */
59         public void reset() {
60                 fProposals.clear();
61         }
62
63         /**
64          * Returns the array of matching templates.
65          */
66         public TemplateProposal[] getResults() {
67                 return (TemplateProposal[]) fProposals
68                                 .toArray(new TemplateProposal[fProposals.size()]);
69         }
70
71         /**
72          * Inspects the context of the compilation unit around
73          * <code>completionPosition</code> and feeds the collector with proposals.
74          * 
75          * @param viewer
76          *            the text viewer
77          * @param completionPosition
78          *            the context position in the document of the text viewer
79          * @param compilationUnit
80          *            the compilation unit (may be <code>null</code>)
81          */
82         public void complete(ITextViewer viewer, int completionPosition,
83                         ICompilationUnit compilationUnit) {
84                 IDocument document = viewer.getDocument();
85
86                 if (!(fContextType instanceof CompilationUnitContextType))
87                         return;
88
89                 Point selection = viewer.getSelectedRange();
90
91                 // remember selected text
92                 String selectedText = null;
93                 if (selection.y != 0) {
94                         try {
95                                 selectedText = document.get(selection.x, selection.y);
96                         } catch (BadLocationException e) {
97                         }
98                 }
99
100                 CompilationUnitContext context = ((CompilationUnitContextType) fContextType)
101                                 .createContext(document, completionPosition, selection.y,
102                                                 compilationUnit);
103                 context.setVariable("selection", selectedText); //$NON-NLS-1$
104                 int start = context.getStart();
105                 int end = context.getEnd();
106                 IRegion region = new Region(start, end - start);
107
108                 Template[] templates = WebUI.getDefault().getTemplateStore()
109                                 .getTemplates();
110
111                 if (selection.y == 0) {
112                         for (int i = 0; i != templates.length; i++)
113                                 if (context.canEvaluate(templates[i]))
114                                         fProposals.add(new TemplateProposal(templates[i], context,
115                                                         region, PHPUiImages
116                                                                         .get(PHPUiImages.IMG_OBJS_TEMPLATE)));
117
118                 } else {
119
120                         if (context.getKey().length() == 0)
121                                 context.setForceEvaluation(true);
122
123                         boolean multipleLinesSelected = areMultipleLinesSelected(viewer);
124
125                         for (int i = 0; i != templates.length; i++) {
126                                 Template template = templates[i];
127                                 if (context.canEvaluate(template)
128                                                 && template.getContextTypeId().equals(
129                                                                 context.getContextType().getId())
130                                                 && (!multipleLinesSelected
131                                                                 && template.getPattern().indexOf(
132                                                                                 $_WORD_SELECTION) != -1 || (multipleLinesSelected && template
133                                                                 .getPattern().indexOf($_LINE_SELECTION) != -1))) {
134                                         fProposals.add(new TemplateProposal(templates[i], context,
135                                                         region, PHPUiImages
136                                                                         .get(PHPUiImages.IMG_OBJS_TEMPLATE)));
137                                 }
138                         }
139                 }
140         }
141
142         /**
143          * Returns <code>true</code> if one line is completely selected or if
144          * multiple lines are selected. Being completely selected means that all
145          * characters except the new line characters are selected.
146          * 
147          * @return <code>true</code> if one or multiple lines are selected
148          * @since 2.1
149          */
150         private boolean areMultipleLinesSelected(ITextViewer viewer) {
151                 if (viewer == null)
152                         return false;
153
154                 Point s = viewer.getSelectedRange();
155                 if (s.y == 0)
156                         return false;
157
158                 try {
159
160                         IDocument document = viewer.getDocument();
161                         int startLine = document.getLineOfOffset(s.x);
162                         int endLine = document.getLineOfOffset(s.x + s.y);
163                         IRegion line = document.getLineInformation(startLine);
164                         return startLine != endLine
165                                         || (s.x == line.getOffset() && s.y == line.getLength());
166
167                 } catch (BadLocationException x) {
168                         return false;
169                 }
170         }
171 }