772e4b3f218852f78068c9b53801cdf2286174b3
[phpeclipse.git] / net.sourceforge.phpeclipse.ui / src / net / sourceforge / phpdt / internal / ui / text / template / contentassist / MultiVariableGuess.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 import java.util.Iterator;
15 import java.util.List;
16
17 //incastrix
18 //import org.eclipse.jface.text.Assert;
19 import org.eclipse.core.runtime.Assert;
20 import org.eclipse.jface.text.BadLocationException;
21 import org.eclipse.jface.text.DocumentEvent;
22 import org.eclipse.jface.text.IDocument;
23 import org.eclipse.jface.text.ITextViewer;
24 import org.eclipse.jface.text.contentassist.ICompletionProposal;
25 import org.eclipse.jface.text.contentassist.ICompletionProposalExtension2;
26 import org.eclipse.jface.text.contentassist.IContextInformation;
27 import org.eclipse.swt.graphics.Image;
28 import org.eclipse.swt.graphics.Point;
29
30 /**
31  * Global state for templates. Selecting a proposal for the master template
32  * variable will cause the value (and the proposals) for the slave variables to
33  * change.
34  * 
35  * @see MultiVariable
36  */
37 public class MultiVariableGuess {
38
39         /**
40          * Implementation of the <code>ICompletionProposal</code> interface and
41          * extension.
42          */
43         class Proposal implements ICompletionProposal,
44                         ICompletionProposalExtension2 {
45
46                 /** The string to be displayed in the completion proposal popup */
47                 private String fDisplayString;
48
49                 /** The replacement string */
50                 String fReplacementString;
51
52                 /** The replacement offset */
53                 private int fReplacementOffset;
54
55                 /** The replacement length */
56                 private int fReplacementLength;
57
58                 /** The cursor position after this proposal has been applied */
59                 private int fCursorPosition;
60
61                 /** The image to be displayed in the completion proposal popup */
62                 private Image fImage;
63
64                 /** The context information of this proposal */
65                 private IContextInformation fContextInformation;
66
67                 /** The additional info of this proposal */
68                 private String fAdditionalProposalInfo;
69
70                 /**
71                  * Creates a new completion proposal based on the provided information.
72                  * The replacement string is considered being the display string too.
73                  * All remaining fields are set to <code>null</code>.
74                  * 
75                  * @param replacementString
76                  *            the actual string to be inserted into the document
77                  * @param replacementOffset
78                  *            the offset of the text to be replaced
79                  * @param replacementLength
80                  *            the length of the text to be replaced
81                  * @param cursorPosition
82                  *            the position of the cursor following the insert relative
83                  *            to replacementOffset
84                  */
85                 public Proposal(String replacementString, int replacementOffset,
86                                 int replacementLength, int cursorPosition) {
87                         this(replacementString, replacementOffset, replacementLength,
88                                         cursorPosition, null, null, null, null);
89                 }
90
91                 /**
92                  * Creates a new completion proposal. All fields are initialized based
93                  * on the provided information.
94                  * 
95                  * @param replacementString
96                  *            the actual string to be inserted into the document
97                  * @param replacementOffset
98                  *            the offset of the text to be replaced
99                  * @param replacementLength
100                  *            the length of the text to be replaced
101                  * @param cursorPosition
102                  *            the position of the cursor following the insert relative
103                  *            to replacementOffset
104                  * @param image
105                  *            the image to display for this proposal
106                  * @param displayString
107                  *            the string to be displayed for the proposal
108                  * @param contextInformation
109                  *            the context information associated with this proposal
110                  * @param additionalProposalInfo
111                  *            the additional information associated with this proposal
112                  */
113                 public Proposal(String replacementString, int replacementOffset,
114                                 int replacementLength, int cursorPosition, Image image,
115                                 String displayString, IContextInformation contextInformation,
116                                 String additionalProposalInfo) {
117                         Assert.isNotNull(replacementString);
118                         Assert.isTrue(replacementOffset >= 0);
119                         Assert.isTrue(replacementLength >= 0);
120                         Assert.isTrue(cursorPosition >= 0);
121
122                         fReplacementString = replacementString;
123                         fReplacementOffset = replacementOffset;
124                         fReplacementLength = replacementLength;
125                         fCursorPosition = cursorPosition;
126                         fImage = image;
127                         fDisplayString = displayString;
128                         fContextInformation = contextInformation;
129                         fAdditionalProposalInfo = additionalProposalInfo;
130                 }
131
132                 /*
133                  * @see ICompletionProposal#apply(IDocument)
134                  */
135                 public void apply(IDocument document) {
136                         try {
137                                 document.replace(fReplacementOffset, fReplacementLength,
138                                                 fReplacementString);
139                         } catch (BadLocationException x) {
140                                 // ignore
141                         }
142                 }
143
144                 /*
145                  * @see ICompletionProposal#getSelection(IDocument)
146                  */
147                 public Point getSelection(IDocument document) {
148                         return new Point(fReplacementOffset + fCursorPosition, 0);
149                 }
150
151                 /*
152                  * @see ICompletionProposal#getContextInformation()
153                  */
154                 public IContextInformation getContextInformation() {
155                         return fContextInformation;
156                 }
157
158                 /*
159                  * @see ICompletionProposal#getImage()
160                  */
161                 public Image getImage() {
162                         return fImage;
163                 }
164
165                 /*
166                  * @see ICompletionProposal#getDisplayString()
167                  */
168                 public String getDisplayString() {
169                         if (fDisplayString != null)
170                                 return fDisplayString;
171                         return fReplacementString;
172                 }
173
174                 /*
175                  * @see ICompletionProposal#getAdditionalProposalInfo()
176                  */
177                 public String getAdditionalProposalInfo() {
178                         return fAdditionalProposalInfo;
179                 }
180
181                 /*
182                  * @see org.eclipse.jface.text.contentassist.ICompletionProposalExtension2#apply(org.eclipse.jface.text.ITextViewer,
183                  *      char, int, int)
184                  */
185                 public void apply(ITextViewer viewer, char trigger, int stateMask,
186                                 int offset) {
187                         apply(viewer.getDocument());
188                 }
189
190                 /*
191                  * @see org.eclipse.jface.text.contentassist.ICompletionProposalExtension2#selected(org.eclipse.jface.text.ITextViewer,
192                  *      boolean)
193                  */
194                 public void selected(ITextViewer viewer, boolean smartToggle) {
195                 }
196
197                 /*
198                  * @see org.eclipse.jface.text.contentassist.ICompletionProposalExtension2#unselected(org.eclipse.jface.text.ITextViewer)
199                  */
200                 public void unselected(ITextViewer viewer) {
201                 }
202
203                 /*
204                  * @see org.eclipse.jface.text.contentassist.ICompletionProposalExtension2#validate(org.eclipse.jface.text.IDocument,
205                  *      int, org.eclipse.jface.text.DocumentEvent)
206                  */
207                 public boolean validate(IDocument document, int offset,
208                                 DocumentEvent event) {
209                         try {
210                                 String content = document.get(fReplacementOffset,
211                                                 fReplacementLength);
212                                 if (content.startsWith(fReplacementString))
213                                         return true;
214                         } catch (BadLocationException e) {
215                                 // ignore concurrently modified document
216                         }
217                         return false;
218                 }
219         }
220
221         private final List fSlaves = new ArrayList();
222
223         private MultiVariable fMaster;
224
225         /**
226          * @param mv
227          */
228         public MultiVariableGuess(MultiVariable mv) {
229                 fMaster = mv;
230         }
231
232         /**
233          * @param variable
234          * @return
235          */
236         public ICompletionProposal[] getProposals(MultiVariable variable,
237                         int offset, int length) {
238                 if (variable.equals(fMaster)) {
239                         String[] choices = variable.getValues();
240
241                         ICompletionProposal[] ret = new ICompletionProposal[choices.length];
242                         for (int i = 0; i < ret.length; i++) {
243                                 ret[i] = new Proposal(choices[i], offset, length, offset
244                                                 + length) {
245
246                                         /*
247                                          * @see org.eclipse.jface.text.link.MultiVariableGuess.Proposal#apply(org.eclipse.jface.text.IDocument)
248                                          */
249                                         public void apply(IDocument document) {
250                                                 super.apply(document);
251
252                                                 try {
253                                                         Object old = fMaster.getSet();
254                                                         fMaster.setSet(fReplacementString);
255                                                         if (!fReplacementString.equals(old)) {
256                                                                 for (Iterator it = fSlaves.iterator(); it
257                                                                                 .hasNext();) {
258                                                                         VariablePosition pos = (VariablePosition) it
259                                                                                         .next();
260                                                                         String[] values = pos.getVariable()
261                                                                                         .getValues(fReplacementString);
262                                                                         if (values != null)
263                                                                                 document.replace(pos.getOffset(), pos
264                                                                                                 .getLength(), values[0]);
265                                                                 }
266                                                         }
267                                                 } catch (BadLocationException e) {
268                                                         // ignore and continue
269                                                 }
270
271                                         }
272                                 };
273                         }
274
275                         return ret;
276
277                 } else {
278
279                         String[] choices = variable.getValues(fMaster.getSet());
280
281                         if (choices == null || choices.length < 2)
282                                 return null;
283
284                         ICompletionProposal[] ret = new ICompletionProposal[choices.length];
285                         for (int i = 0; i < ret.length; i++) {
286                                 ret[i] = new Proposal(choices[i], offset, length, offset
287                                                 + length);
288                         }
289
290                         return ret;
291                 }
292         }
293
294         /**
295          * @param position
296          */
297         public void addSlave(VariablePosition position) {
298                 fSlaves.add(position);
299         }
300
301 }