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