]>
Commit | Line | Data |
---|---|---|
1b2798f6 EK |
1 | /******************************************************************************* |
2 | * Copyright (c) 2008, 2011 IBM Corporation and others. | |
3 | * All rights reserved. This program and the accompanying materials | |
4 | * are made available under the terms of the Eclipse Public License v1.0 | |
5 | * which accompanies this distribution, and is available at | |
6 | * http://www.eclipse.org/legal/epl-v10.html | |
7 | * | |
8 | * Contributors: | |
9 | * IBM Corporation - initial API and implementation | |
10 | *******************************************************************************/ | |
11 | package org.eclipse.jdt.internal.ui.viewsupport; | |
12 | ||
13 | import java.util.Iterator; | |
14 | ||
15 | import org.eclipse.swt.events.VerifyEvent; | |
16 | import org.eclipse.swt.graphics.Image; | |
17 | import org.eclipse.swt.graphics.Point; | |
18 | ||
19 | import org.eclipse.core.runtime.CoreException; | |
20 | import org.eclipse.core.runtime.IStatus; | |
21 | import org.eclipse.core.runtime.Status; | |
22 | ||
23 | import org.eclipse.text.edits.MalformedTreeException; | |
24 | import org.eclipse.text.edits.TextEdit; | |
25 | ||
26 | import org.eclipse.jface.text.BadLocationException; | |
27 | import org.eclipse.jface.text.DocumentEvent; | |
28 | import org.eclipse.jface.text.IDocument; | |
29 | import org.eclipse.jface.text.IRegion; | |
30 | import org.eclipse.jface.text.ITextViewer; | |
31 | import org.eclipse.jface.text.contentassist.ICompletionProposalExtension2; | |
32 | import org.eclipse.jface.text.contentassist.IContextInformation; | |
33 | import org.eclipse.jface.text.link.ILinkedModeListener; | |
34 | import org.eclipse.jface.text.link.LinkedModeModel; | |
35 | import org.eclipse.jface.text.link.LinkedModeUI; | |
36 | import org.eclipse.jface.text.link.LinkedModeUI.ExitFlags; | |
37 | import org.eclipse.jface.text.link.LinkedPosition; | |
38 | import org.eclipse.jface.text.link.LinkedPositionGroup; | |
39 | import org.eclipse.jface.text.link.ProposalPosition; | |
40 | ||
41 | import org.eclipse.ui.IEditorPart; | |
42 | ||
43 | import org.eclipse.ui.texteditor.link.EditorLinkedModeUI; | |
44 | ||
45 | import org.eclipse.jdt.internal.corext.fix.LinkedProposalModel; | |
46 | import org.eclipse.jdt.internal.corext.fix.LinkedProposalPositionGroup; | |
47 | ||
48 | import org.eclipse.jdt.ui.JavaUI; | |
49 | import org.eclipse.jdt.ui.text.java.IJavaCompletionProposal; | |
50 | ||
51 | import org.eclipse.jdt.internal.ui.JavaPlugin; | |
52 | import org.eclipse.jdt.internal.ui.javaeditor.EditorHighlightingSynchronizer; | |
53 | import org.eclipse.jdt.internal.ui.javaeditor.JavaEditor; | |
54 | ||
55 | /** | |
56 | * Does the setup of the linked mode from a {@link LinkedProposalModel} | |
57 | */ | |
58 | public class LinkedProposalModelPresenter { | |
59 | ||
60 | public LinkedProposalModelPresenter() { | |
61 | } | |
62 | ||
63 | public void enterLinkedMode(ITextViewer viewer, IEditorPart editor, boolean switchedEditor, LinkedProposalModel linkedProposalModel) throws BadLocationException { | |
64 | IDocument document= viewer.getDocument(); | |
65 | ||
66 | LinkedModeModel model= new LinkedModeModel(); | |
67 | boolean added= false; | |
68 | ||
69 | Iterator<LinkedProposalPositionGroup> iterator= linkedProposalModel.getPositionGroupIterator(); | |
70 | while (iterator.hasNext()) { | |
71 | LinkedProposalPositionGroup curr= iterator.next(); | |
72 | ||
73 | LinkedPositionGroup group= new LinkedPositionGroup(); | |
74 | ||
75 | LinkedProposalPositionGroup.PositionInformation[] positions= curr.getPositions(); | |
76 | if (positions.length > 0) { | |
77 | LinkedProposalPositionGroup.Proposal[] linkedModeProposals= curr.getProposals(); | |
78 | if (linkedModeProposals.length <= 1) { | |
79 | for (int i= 0; i < positions.length; i++) { | |
80 | LinkedProposalPositionGroup.PositionInformation pos= positions[i]; | |
81 | pos.generated_3793137176654314040(document, group); | |
82 | } | |
83 | } else { | |
84 | LinkedPositionProposalImpl[] proposalImpls= new LinkedPositionProposalImpl[linkedModeProposals.length]; | |
85 | for (int i= 0; i < linkedModeProposals.length; i++) { | |
86 | proposalImpls[i]= new LinkedPositionProposalImpl(linkedModeProposals[i], model); | |
87 | } | |
88 | ||
89 | for (int i= 0; i < positions.length; i++) { | |
90 | LinkedProposalPositionGroup.PositionInformation pos= positions[i]; | |
91 | if (pos.getOffset() != -1) { | |
92 | group.addPosition(new ProposalPosition(document, pos.getOffset(), pos.getLength(), pos.getSequenceRank(), proposalImpls)); | |
93 | } | |
94 | } | |
95 | } | |
96 | model.addGroup(group); | |
97 | added= true; | |
98 | } | |
99 | } | |
100 | ||
101 | model.forceInstall(); | |
102 | ||
103 | if (editor instanceof JavaEditor) { | |
104 | model.addLinkingListener(new EditorHighlightingSynchronizer((JavaEditor) editor)); | |
105 | } | |
106 | ||
107 | if (added) { // only set up UI if there are any positions set | |
108 | LinkedModeUI ui= new EditorLinkedModeUI(model, viewer); | |
109 | LinkedProposalPositionGroup.PositionInformation endPosition= linkedProposalModel.getEndPosition(); | |
110 | if (endPosition != null && endPosition.getOffset() != -1) { | |
111 | ui.setExitPosition(viewer, endPosition.getOffset() + endPosition.getLength(), 0, Integer.MAX_VALUE); | |
112 | } else if (! switchedEditor) { | |
113 | int cursorPosition= viewer.getSelectedRange().x; | |
114 | if (cursorPosition != 0) { | |
115 | ui.setExitPosition(viewer, cursorPosition, 0, Integer.MAX_VALUE); | |
116 | } | |
117 | } | |
118 | ui.setExitPolicy(new LinkedModeExitPolicy()); | |
119 | ui.enter(); | |
120 | ||
121 | IRegion region= ui.getSelectedRegion(); | |
122 | viewer.setSelectedRange(region.getOffset(), region.getLength()); | |
123 | viewer.revealRange(region.getOffset(), region.getLength()); | |
124 | } | |
125 | } | |
126 | ||
127 | private static class LinkedPositionProposalImpl implements ICompletionProposalExtension2, IJavaCompletionProposal { | |
128 | ||
129 | private final LinkedProposalPositionGroup.Proposal fProposal; | |
130 | private final LinkedModeModel fLinkedPositionModel; | |
131 | ||
132 | ||
133 | public LinkedPositionProposalImpl(LinkedProposalPositionGroup.Proposal proposal, LinkedModeModel model) { | |
134 | fProposal= proposal; | |
135 | fLinkedPositionModel= model; | |
136 | } | |
137 | ||
138 | /* (non-Javadoc) | |
139 | * @see org.eclipse.jface.text.contentassist.ICompletionProposalExtension2#apply(org.eclipse.jface.text.ITextViewer, char, int, int) | |
140 | */ | |
141 | public void apply(ITextViewer viewer, char trigger, int stateMask, int offset) { | |
142 | IDocument doc= viewer.getDocument(); | |
143 | LinkedPosition position= fLinkedPositionModel.findPosition(new LinkedPosition(doc, offset, 0)); | |
144 | if (position != null) { | |
145 | try { | |
146 | try { | |
147 | TextEdit edit= fProposal.computeEdits(offset, position, trigger, stateMask, fLinkedPositionModel); | |
148 | if (edit != null) { | |
149 | edit.apply(position.getDocument(), 0); | |
150 | } | |
151 | } catch (MalformedTreeException e) { | |
152 | throw new CoreException(new Status(IStatus.ERROR, JavaUI.ID_PLUGIN, IStatus.ERROR, "Unexpected exception applying edit", e)); //$NON-NLS-1$ | |
153 | } catch (BadLocationException e) { | |
154 | throw new CoreException(new Status(IStatus.ERROR, JavaUI.ID_PLUGIN, IStatus.ERROR, "Unexpected exception applying edit", e)); //$NON-NLS-1$ | |
155 | } | |
156 | } catch (CoreException e) { | |
157 | JavaPlugin.log(e); | |
158 | } | |
159 | } | |
160 | } | |
161 | ||
162 | /* (non-Javadoc) | |
163 | * @see org.eclipse.jface.text.contentassist.ICompletionProposal#getDisplayString() | |
164 | */ | |
165 | public String getDisplayString() { | |
166 | return fProposal.getDisplayString(); | |
167 | } | |
168 | ||
169 | /* (non-Javadoc) | |
170 | * @see org.eclipse.jface.text.contentassist.ICompletionProposal#getImage() | |
171 | */ | |
172 | public Image getImage() { | |
173 | return fProposal.getImage(); | |
174 | } | |
175 | ||
176 | /* (non-Javadoc) | |
177 | * @see org.eclipse.jdt.ui.text.java.IJavaCompletionProposal#getRelevance() | |
178 | */ | |
179 | public int getRelevance() { | |
180 | return fProposal.getRelevance(); | |
181 | } | |
182 | ||
183 | /* (non-Javadoc) | |
184 | * @see org.eclipse.jface.text.contentassist.ICompletionProposal#apply(org.eclipse.jface.text.IDocument) | |
185 | */ | |
186 | public void apply(IDocument document) { | |
187 | // not called | |
188 | } | |
189 | ||
190 | /* (non-Javadoc) | |
191 | * @see org.eclipse.jface.text.contentassist.ICompletionProposal#getAdditionalProposalInfo() | |
192 | */ | |
193 | public String getAdditionalProposalInfo() { | |
194 | return fProposal.getAdditionalProposalInfo(); | |
195 | } | |
196 | ||
197 | public Point getSelection(IDocument document) { return null; } | |
198 | public IContextInformation getContextInformation() { return null; } | |
199 | public void selected(ITextViewer viewer, boolean smartToggle) {} | |
200 | public void unselected(ITextViewer viewer) {} | |
201 | ||
202 | /* | |
203 | * @see org.eclipse.jface.text.contentassist.ICompletionProposalExtension2#validate(org.eclipse.jface.text.IDocument, int, org.eclipse.jface.text.DocumentEvent) | |
204 | */ | |
205 | public boolean validate(IDocument document, int offset, DocumentEvent event) { | |
206 | // ignore event | |
207 | String insert= getDisplayString(); | |
208 | ||
209 | int off; | |
210 | LinkedPosition pos= fLinkedPositionModel.findPosition(new LinkedPosition(document, offset, 0)); | |
211 | if (pos != null) { | |
212 | off= pos.getOffset(); | |
213 | } else { | |
214 | off= Math.max(0, offset - insert.length()); | |
215 | } | |
216 | int length= offset - off; | |
217 | ||
218 | if (offset <= document.getLength()) { | |
219 | try { | |
220 | String content= document.get(off, length); | |
221 | if (insert.startsWith(content)) | |
222 | return true; | |
223 | } catch (BadLocationException e) { | |
224 | JavaPlugin.log(e); | |
225 | // and ignore and return false | |
226 | } | |
227 | } | |
228 | return false; | |
229 | } | |
230 | } | |
231 | ||
232 | private static class LinkedModeExitPolicy implements LinkedModeUI.IExitPolicy { | |
233 | public ExitFlags doExit(LinkedModeModel model, VerifyEvent event, int offset, int length) { | |
234 | if (event.character == '=') { | |
235 | return new ExitFlags(ILinkedModeListener.EXIT_ALL, true); | |
236 | } | |
237 | return null; | |
238 | } | |
239 | } | |
240 | ||
241 | } |