first version of 'Code Assist" template engine
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / ui / text / template / TemplateProposal.java
1 /*
2  * (c) Copyright IBM Corp. 2000, 2001.
3  * All Rights Reserved.
4  */
5 package net.sourceforge.phpdt.internal.ui.text.template;
6
7 import net.sourceforge.phpdt.internal.corext.template.Template;
8 import net.sourceforge.phpdt.internal.corext.template.TemplateBuffer;
9 import net.sourceforge.phpdt.internal.corext.template.TemplateContext;
10 import net.sourceforge.phpdt.internal.corext.template.TemplateMessages;
11 import net.sourceforge.phpdt.internal.corext.template.TemplatePosition;
12 import net.sourceforge.phpeclipse.PHPeclipsePlugin;
13 import org.eclipse.core.runtime.CoreException;
14 import net.sourceforge.phpdt.internal.corext.template.java.CompilationUnitContext;
15 import net.sourceforge.phpdt.internal.corext.template.java.JavaTemplateMessages;
16 import org.eclipse.jface.dialogs.MessageDialog;
17 import org.eclipse.jface.text.BadLocationException;
18 import org.eclipse.jface.text.IDocument;
19 import org.eclipse.jface.text.IRegion;
20 import org.eclipse.jface.text.ITextViewer;
21 import org.eclipse.jface.text.contentassist.IContextInformation;
22 import org.eclipse.swt.graphics.Image;
23 import org.eclipse.swt.graphics.Point;
24 import org.eclipse.swt.widgets.Shell;
25 //import org.eclipse.jdt.internal.ui.JavaPlugin;
26 import net.sourceforge.phpdt.internal.ui.text.java.IJavaCompletionProposal;
27 //import org.eclipse.jdt.internal.ui.text.link.LinkedPositionManager;
28 //import org.eclipse.jdt.internal.ui.text.link.LinkedPositionUI;
29 //import org.eclipse.jdt.internal.ui.util.ExceptionHandler;
30
31 /**
32  * A template proposal.
33  */
34 public class TemplateProposal implements IJavaCompletionProposal {
35
36         private final Template fTemplate;
37         private final TemplateContext fContext;
38         private final ITextViewer fViewer;
39 //      private final Image fImage;
40         private final IRegion fRegion;
41
42         private TemplateBuffer fTemplateBuffer;
43         private String fOldText;
44 //      private IRegion fSelectedRegion; // initialized by apply()
45                 
46         /**
47          * Creates a template proposal with a template and its context.
48          * @param template  the template
49          * @param context   the context in which the template was requested.
50          * @param image     the icon of the proposal.
51          */     
52         public TemplateProposal(Template template, TemplateContext context, IRegion region, ITextViewer viewer){ //, Image image) {
53 //              Assert.isNotNull(template);
54 //              Assert.isNotNull(context);
55 //              Assert.isNotNull(region);
56 //              Assert.isNotNull(viewer);
57                 
58                 fTemplate= template;
59                 fContext= context;
60                 fViewer= viewer;
61 //              fImage= image;
62                 fRegion= region;
63         }
64
65         /*
66          * @see ICompletionProposal#apply(IDocument)
67          */
68         public void apply(IDocument document) {
69             try {               
70                     if (fTemplateBuffer == null)
71                                 fTemplateBuffer= fContext.evaluate(fTemplate);
72
73                         int start= fRegion.getOffset();
74                         int end= fRegion.getOffset() + fRegion.getLength();
75                         
76                         // insert template string
77                         String templateString= fTemplateBuffer.getString();     
78                         document.replace(start, end - start, templateString);   
79
80                         // translate positions
81         //              LinkedPositionManager manager= new LinkedPositionManager(document);
82                         TemplatePosition[] variables= fTemplateBuffer.getVariables();
83                         for (int i= 0; i != variables.length; i++) {
84                                 TemplatePosition variable= variables[i];
85
86                                 if (variable.isResolved())
87                                         continue;
88                                 
89                                 int[] offsets= variable.getOffsets();
90                                 int length= variable.getLength();
91                                 
92 //                              for (int j= 0; j != offsets.length; j++)
93 //                                      manager.addPosition(offsets[j] + start, length);
94                         }
95                         
96 //                      LinkedPositionUI editor= new LinkedPositionUI(fViewer, manager);
97 //                      editor.setFinalCaretOffset(getCaretOffset(fTemplateBuffer) + start);
98 //                      editor.enter();
99
100 //                      fSelectedRegion= editor.getSelectedRegion();
101                         
102                 } catch (BadLocationException e) {
103                         PHPeclipsePlugin.log(e);        
104                         openErrorDialog(e);                         
105
106             } catch (CoreException e) {
107                         handleException(e);
108             }       
109         }
110         
111         private static int getCaretOffset(TemplateBuffer buffer) {
112             TemplatePosition[] variables= buffer.getVariables();
113                 for (int i= 0; i != variables.length; i++) {
114                         TemplatePosition variable= variables[i];
115                         
116                         if (variable.getName().equals(JavaTemplateMessages.getString("GlobalVariables.variable.name.cursor"))) //$NON-NLS-1$
117                                 return variable.getOffsets()[0];
118                 }
119
120                 return buffer.getString().length();
121         }
122         
123         /*
124          * @see ICompletionProposal#getSelection(IDocument)
125          */
126         public Point getSelection(IDocument document) {
127 //              return new Point(fSelectedRegion.getOffset(), fSelectedRegion.getLength());
128           return null;
129   }
130
131         /*
132          * @see ICompletionProposal#getAdditionalProposalInfo()
133          */
134         public String getAdditionalProposalInfo() {
135             try {
136                         if (fTemplateBuffer == null)
137                                 fTemplateBuffer= fContext.evaluate(fTemplate);
138
139                         return textToHTML(fTemplateBuffer.getString());
140
141             } catch (CoreException e) {
142                         handleException(e);                 
143                         return null;
144             }
145         }
146
147         /*
148          * @see ICompletionProposal#getDisplayString()
149          */
150         public String getDisplayString() {
151                 return fTemplate.getName() + TemplateMessages.getString("TemplateProposal.delimiter") + fTemplate.getDescription(); // $NON-NLS-1$ //$NON-NLS-1$
152         }
153
154         /*
155          * @see ICompletionProposal#getImage()
156          */
157         public Image getImage() {
158 //              return fImage;
159      return null;
160         }
161
162         /*
163          * @see ICompletionProposal#getContextInformation()
164          */
165         public IContextInformation getContextInformation() {
166                 return null;
167         }
168
169         private static String textToHTML(String string) {
170                 StringBuffer buffer= new StringBuffer(string.length());
171                 buffer.append("<pre>"); //$NON-NLS-1$
172         
173                 for (int i= 0; i != string.length(); i++) {
174                         char ch= string.charAt(i);
175                         
176                         switch (ch) {
177                                 case '&':
178                                         buffer.append("&amp;"); //$NON-NLS-1$
179                                         break;
180                                         
181                                 case '<':
182                                         buffer.append("&lt;"); //$NON-NLS-1$
183                                         break;
184
185                                 case '>':
186                                         buffer.append("&gt;"); //$NON-NLS-1$
187                                         break;
188
189                                 case '\t':
190                                         buffer.append("    "); //$NON-NLS-1$
191                                         break;
192
193                                 case '\n':
194                                         buffer.append("<br>"); //$NON-NLS-1$
195                                         break;
196
197                                 default:
198                                         buffer.append(ch);
199                                         break;
200                         }
201                 }
202
203                 buffer.append("</pre>"); //$NON-NLS-1$
204                 return buffer.toString();
205         }
206
207         private void openErrorDialog(BadLocationException e) {
208                 Shell shell= fViewer.getTextWidget().getShell();
209                 MessageDialog.openError(shell, TemplateMessages.getString("TemplateEvaluator.error.title"), e.getMessage()); //$NON-NLS-1$
210         }
211
212         private void handleException(CoreException e) {
213                 Shell shell= fViewer.getTextWidget().getShell();
214     PHPeclipsePlugin.log(e);
215 //              ExceptionHandler.handle(e, shell, TemplateMessages.getString("TemplateEvaluator.error.title"), null); //$NON-NLS-1$
216         }
217
218         /*
219          * @see IJavaCompletionProposal#getRelevance()
220          */
221         public int getRelevance() {
222
223                 if (fContext instanceof CompilationUnitContext) {
224                         CompilationUnitContext context= (CompilationUnitContext) fContext;
225                         switch (context.getCharacterBeforeStart()) { 
226                         // high relevance after whitespace
227                         case ' ':
228                         case '\r':
229                         case '\n':
230                         case '\t':
231                                 return 90;
232
233                         default:
234                                 return 0;
235                         }
236                 } else {
237                         return 90;                      
238                 }
239         }
240
241 }