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