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