]>
Commit | Line | Data |
---|---|---|
1b2798f6 EK |
1 | /******************************************************************************* |
2 | * Copyright (c) 2000, 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.javaeditor; | |
12 | ||
13 | import java.util.ArrayList; | |
14 | import java.util.HashMap; | |
15 | import java.util.Map; | |
16 | ||
17 | import com.ibm.icu.text.Bidi; | |
18 | ||
19 | import org.eclipse.swt.SWT; | |
20 | import org.eclipse.swt.custom.BidiSegmentEvent; | |
21 | import org.eclipse.swt.custom.BidiSegmentListener; | |
22 | import org.eclipse.swt.custom.StyleRange; | |
23 | import org.eclipse.swt.custom.StyledText; | |
24 | import org.eclipse.swt.graphics.Color; | |
25 | import org.eclipse.swt.graphics.Cursor; | |
26 | import org.eclipse.swt.graphics.Font; | |
27 | import org.eclipse.swt.graphics.Point; | |
28 | import org.eclipse.swt.graphics.RGB; | |
29 | import org.eclipse.swt.layout.GridData; | |
30 | import org.eclipse.swt.widgets.Composite; | |
31 | import org.eclipse.swt.widgets.Control; | |
32 | import org.eclipse.swt.widgets.Display; | |
33 | ||
34 | import org.eclipse.core.runtime.Assert; | |
35 | ||
36 | import org.eclipse.jface.layout.PixelConverter; | |
37 | import org.eclipse.jface.preference.IPreferenceStore; | |
38 | import org.eclipse.jface.preference.PreferenceConverter; | |
39 | import org.eclipse.jface.resource.JFaceResources; | |
40 | import org.eclipse.jface.util.IPropertyChangeListener; | |
41 | import org.eclipse.jface.util.PropertyChangeEvent; | |
42 | ||
43 | import org.eclipse.jface.text.BadLocationException; | |
44 | import org.eclipse.jface.text.Document; | |
45 | import org.eclipse.jface.text.IDocument; | |
46 | import org.eclipse.jface.text.IRegion; | |
47 | import org.eclipse.jface.text.ITextPresentationListener; | |
48 | import org.eclipse.jface.text.ITypedRegion; | |
49 | import org.eclipse.jface.text.Region; | |
50 | import org.eclipse.jface.text.TextUtilities; | |
51 | import org.eclipse.jface.text.formatter.FormattingContextProperties; | |
52 | import org.eclipse.jface.text.formatter.IFormattingContext; | |
53 | import org.eclipse.jface.text.information.IInformationPresenter; | |
54 | import org.eclipse.jface.text.reconciler.IReconciler; | |
55 | import org.eclipse.jface.text.source.IOverviewRuler; | |
56 | import org.eclipse.jface.text.source.IVerticalRuler; | |
57 | import org.eclipse.jface.text.source.SourceViewerConfiguration; | |
58 | import org.eclipse.jface.text.source.projection.ProjectionViewer; | |
59 | ||
60 | import org.eclipse.ui.texteditor.AbstractDecoratedTextEditorPreferenceConstants; | |
61 | import org.eclipse.ui.texteditor.AbstractTextEditor; | |
62 | ||
63 | import org.eclipse.jdt.core.JavaCore; | |
64 | import org.eclipse.jdt.core.JavaModelException; | |
65 | ||
66 | import org.eclipse.jdt.ui.JavaElementLabels; | |
67 | import org.eclipse.jdt.ui.JavaUI; | |
68 | import org.eclipse.jdt.ui.PreferenceConstants; | |
69 | import org.eclipse.jdt.ui.text.IJavaColorConstants; | |
70 | import org.eclipse.jdt.ui.text.IJavaPartitions; | |
71 | import org.eclipse.jdt.ui.text.JavaSourceViewerConfiguration; | |
72 | ||
73 | import org.eclipse.jdt.internal.ui.JavaPlugin; | |
74 | import org.eclipse.jdt.internal.ui.javaeditor.SemanticHighlightingManager.HighlightedPosition; | |
75 | import org.eclipse.jdt.internal.ui.preferences.JavaEditorColoringConfigurationBlock; | |
76 | import org.eclipse.jdt.internal.ui.preferences.JavaSourcePreviewerUpdater; | |
77 | import org.eclipse.jdt.internal.ui.refactoring.ChangeSignatureWizard.ChangeSignatureInputPage; | |
78 | import org.eclipse.jdt.internal.ui.refactoring.IntroduceParameterObjectWizard.IntroduceParameterObjectInputPage; | |
79 | import org.eclipse.jdt.internal.ui.refactoring.IntroduceParameterWizard.IntroduceParameterInputPage; | |
80 | import org.eclipse.jdt.internal.ui.refactoring.RefactoringMessages; | |
81 | import org.eclipse.jdt.internal.ui.refactoring.code.ExtractMethodInputPage; | |
82 | import org.eclipse.jdt.internal.ui.refactoring.code.ReplaceInvocationsInputPage; | |
83 | import org.eclipse.jdt.internal.ui.text.SimpleJavaSourceViewerConfiguration; | |
84 | import org.eclipse.jdt.internal.ui.text.SmartBackspaceManager; | |
85 | import org.eclipse.jdt.internal.ui.text.java.JavaFormattingContext; | |
86 | import org.eclipse.jdt.internal.ui.util.ExceptionHandler; | |
87 | import org.eclipse.jdt.internal.ui.util.RowLayouter; | |
88 | ||
89 | ||
90 | ||
91 | public class JavaSourceViewer extends ProjectionViewer implements IPropertyChangeListener { | |
92 | ||
93 | /** | |
94 | * Text operation code for requesting the outline for the current input. | |
95 | */ | |
96 | public static final int SHOW_OUTLINE= 51; | |
97 | ||
98 | /** | |
99 | * Text operation code for requesting the outline for the element at the current position. | |
100 | */ | |
101 | public static final int OPEN_STRUCTURE= 52; | |
102 | ||
103 | /** | |
104 | * Text operation code for requesting the hierarchy for the current input. | |
105 | */ | |
106 | public static final int SHOW_HIERARCHY= 53; | |
107 | ||
108 | public IInformationPresenter fOutlinePresenter; | |
109 | public IInformationPresenter fStructurePresenter; | |
110 | public IInformationPresenter fHierarchyPresenter; | |
111 | ||
112 | /** | |
113 | * This viewer's foreground color. | |
114 | * @since 3.0 | |
115 | */ | |
116 | private Color fForegroundColor; | |
117 | /** | |
118 | * The viewer's background color. | |
119 | * @since 3.0 | |
120 | */ | |
121 | private Color fBackgroundColor; | |
122 | /** | |
123 | * This viewer's selection foreground color. | |
124 | * @since 3.0 | |
125 | */ | |
126 | private Color fSelectionForegroundColor; | |
127 | /** | |
128 | * The viewer's selection background color. | |
129 | * @since 3.0 | |
130 | */ | |
131 | private Color fSelectionBackgroundColor; | |
132 | /** | |
133 | * The preference store. | |
134 | * | |
135 | * @since 3.0 | |
136 | */ | |
137 | private IPreferenceStore fPreferenceStore; | |
138 | /** | |
139 | * Is this source viewer configured? | |
140 | * | |
141 | * @since 3.0 | |
142 | */ | |
143 | private boolean fIsConfigured; | |
144 | /** | |
145 | * The backspace manager of this viewer. | |
146 | * | |
147 | * @since 3.0 | |
148 | */ | |
149 | private SmartBackspaceManager fBackspaceManager; | |
150 | ||
151 | /** | |
152 | * Whether to delay setting the visual document until the projection has been computed. | |
153 | * <p> | |
154 | * Added for performance optimization. | |
155 | * </p> | |
156 | * @see #prepareDelayedProjection() | |
157 | * @since 3.1 | |
158 | */ | |
159 | private boolean fIsSetVisibleDocumentDelayed= false; | |
160 | ||
161 | /** | |
162 | * BIDI delimtiers. | |
163 | * | |
164 | * @since 3.4 | |
165 | */ | |
166 | private static final String BIDI_DELIMITERS= "[ \\p{Punct}&&[^_]]"; //$NON-NLS-1$ | |
167 | ||
168 | ||
169 | public JavaSourceViewer(Composite parent, IVerticalRuler verticalRuler, IOverviewRuler overviewRuler, boolean showAnnotationsOverview, int styles, IPreferenceStore store) { | |
170 | super(parent, verticalRuler, overviewRuler, showAnnotationsOverview, styles); | |
171 | setPreferenceStore(store); | |
172 | } | |
173 | ||
174 | /* | |
175 | * @see org.eclipse.jface.text.source.SourceViewer#createFormattingContext() | |
176 | * @since 3.0 | |
177 | */ | |
178 | @Override | |
179 | public IFormattingContext createFormattingContext() { | |
180 | ||
181 | // it's ok to use instance preferences here as subclasses replace | |
182 | // with project dependent versions (see CompilationUnitEditor.AdaptedSourceViewer) | |
183 | IFormattingContext context= new JavaFormattingContext(); | |
184 | Map<String, String> map= new HashMap<String, String>(JavaCore.getOptions()); | |
185 | context.setProperty(FormattingContextProperties.CONTEXT_PREFERENCES, map); | |
186 | ||
187 | return context; | |
188 | } | |
189 | ||
190 | /* | |
191 | * @see ITextOperationTarget#doOperation(int) | |
192 | */ | |
193 | @Override | |
194 | public void doOperation(int operation) { | |
195 | if (getTextWidget() == null) | |
196 | return; | |
197 | ||
198 | switch (operation) { | |
199 | case SHOW_OUTLINE: | |
200 | if (fOutlinePresenter != null) | |
201 | fOutlinePresenter.showInformation(); | |
202 | return; | |
203 | case OPEN_STRUCTURE: | |
204 | if (fStructurePresenter != null) | |
205 | fStructurePresenter.showInformation(); | |
206 | return; | |
207 | case SHOW_HIERARCHY: | |
208 | if (fHierarchyPresenter != null) | |
209 | fHierarchyPresenter.showInformation(); | |
210 | return; | |
211 | } | |
212 | ||
213 | super.doOperation(operation); | |
214 | } | |
215 | ||
216 | /* | |
217 | * @see ITextOperationTarget#canDoOperation(int) | |
218 | */ | |
219 | @Override | |
220 | public boolean canDoOperation(int operation) { | |
221 | if (operation == SHOW_OUTLINE) | |
222 | return fOutlinePresenter != null; | |
223 | if (operation == OPEN_STRUCTURE) | |
224 | return fStructurePresenter != null; | |
225 | if (operation == SHOW_HIERARCHY) | |
226 | return fHierarchyPresenter != null; | |
227 | ||
228 | return super.canDoOperation(operation); | |
229 | } | |
230 | ||
231 | /* | |
232 | * @see ISourceViewer#configure(SourceViewerConfiguration) | |
233 | */ | |
234 | @Override | |
235 | public void configure(SourceViewerConfiguration configuration) { | |
236 | ||
237 | /* | |
238 | * Prevent access to colors disposed in unconfigure(), see: | |
239 | * https://bugs.eclipse.org/bugs/show_bug.cgi?id=53641 | |
240 | * https://bugs.eclipse.org/bugs/show_bug.cgi?id=86177 | |
241 | */ | |
242 | StyledText textWidget= getTextWidget(); | |
243 | if (textWidget != null && !textWidget.isDisposed()) { | |
244 | Color foregroundColor= textWidget.getForeground(); | |
245 | if (foregroundColor != null && foregroundColor.isDisposed()) | |
246 | textWidget.setForeground(null); | |
247 | Color backgroundColor= textWidget.getBackground(); | |
248 | if (backgroundColor != null && backgroundColor.isDisposed()) | |
249 | textWidget.setBackground(null); | |
250 | } | |
251 | ||
252 | super.configure(configuration); | |
253 | if (configuration instanceof JavaSourceViewerConfiguration) { | |
254 | JavaSourceViewerConfiguration javaSVCconfiguration= (JavaSourceViewerConfiguration)configuration; | |
255 | javaSVCconfiguration.generated_3385039197972890082(this); | |
256 | ||
257 | } | |
258 | ||
259 | if (fPreferenceStore != null) { | |
260 | fPreferenceStore.addPropertyChangeListener(this); | |
261 | initializeViewerColors(); | |
262 | } | |
263 | ||
264 | fIsConfigured= true; | |
265 | } | |
266 | ||
267 | protected void initializeViewerColors() { | |
268 | if (fPreferenceStore != null) { | |
269 | ||
270 | StyledText styledText= getTextWidget(); | |
271 | ||
272 | // ----------- foreground color -------------------- | |
273 | Color color= fPreferenceStore.getBoolean(AbstractTextEditor.PREFERENCE_COLOR_FOREGROUND_SYSTEM_DEFAULT) | |
274 | ? null | |
275 | : createColor(fPreferenceStore, AbstractTextEditor.PREFERENCE_COLOR_FOREGROUND, styledText.getDisplay()); | |
276 | styledText.setForeground(color); | |
277 | ||
278 | if (fForegroundColor != null) | |
279 | fForegroundColor.dispose(); | |
280 | ||
281 | fForegroundColor= color; | |
282 | ||
283 | // ---------- background color ---------------------- | |
284 | color= fPreferenceStore.getBoolean(AbstractTextEditor.PREFERENCE_COLOR_BACKGROUND_SYSTEM_DEFAULT) | |
285 | ? null | |
286 | : createColor(fPreferenceStore, AbstractTextEditor.PREFERENCE_COLOR_BACKGROUND, styledText.getDisplay()); | |
287 | styledText.setBackground(color); | |
288 | ||
289 | if (fBackgroundColor != null) | |
290 | fBackgroundColor.dispose(); | |
291 | ||
292 | fBackgroundColor= color; | |
293 | ||
294 | // ----------- selection foreground color -------------------- | |
295 | color= fPreferenceStore.getBoolean(AbstractDecoratedTextEditorPreferenceConstants.EDITOR_SELECTION_FOREGROUND_DEFAULT_COLOR) | |
296 | ? null | |
297 | : createColor(fPreferenceStore, AbstractDecoratedTextEditorPreferenceConstants.EDITOR_SELECTION_FOREGROUND_COLOR, styledText.getDisplay()); | |
298 | styledText.setSelectionForeground(color); | |
299 | ||
300 | if (fSelectionForegroundColor != null) | |
301 | fSelectionForegroundColor.dispose(); | |
302 | ||
303 | fSelectionForegroundColor= color; | |
304 | ||
305 | // ---------- selection background color ---------------------- | |
306 | color= fPreferenceStore.getBoolean(AbstractDecoratedTextEditorPreferenceConstants.EDITOR_SELECTION_BACKGROUND_DEFAULT_COLOR) | |
307 | ? null | |
308 | : createColor(fPreferenceStore, AbstractDecoratedTextEditorPreferenceConstants.EDITOR_SELECTION_BACKGROUND_COLOR, styledText.getDisplay()); | |
309 | styledText.setSelectionBackground(color); | |
310 | ||
311 | if (fSelectionBackgroundColor != null) | |
312 | fSelectionBackgroundColor.dispose(); | |
313 | ||
314 | fSelectionBackgroundColor= color; | |
315 | } | |
316 | } | |
317 | ||
318 | /** | |
319 | * Creates a color from the information stored in the given preference store. | |
320 | * Returns <code>null</code> if there is no such information available. | |
321 | * | |
322 | * @param store the store to read from | |
323 | * @param key the key used for the lookup in the preference store | |
324 | * @param display the display used create the color | |
325 | * @return the created color according to the specification in the preference store | |
326 | * @since 3.0 | |
327 | */ | |
328 | private Color createColor(IPreferenceStore store, String key, Display display) { | |
329 | ||
330 | RGB rgb= null; | |
331 | ||
332 | if (store.contains(key)) { | |
333 | ||
334 | if (store.isDefault(key)) | |
335 | rgb= PreferenceConverter.getDefaultColor(store, key); | |
336 | else | |
337 | rgb= PreferenceConverter.getColor(store, key); | |
338 | ||
339 | if (rgb != null) | |
340 | return new Color(display, rgb); | |
341 | } | |
342 | ||
343 | return null; | |
344 | } | |
345 | ||
346 | /** | |
347 | * Sets the viewer's background color to the given control's background color. | |
348 | * The background color is <em>only</em> set if it's visibly distinct from the | |
349 | * default Java source text color. | |
350 | * | |
351 | * @param control the control with the default background color | |
352 | * @since 3.7 | |
353 | */ | |
354 | public void adaptBackgroundColor(Control control) { | |
355 | // workaround for dark editor background color, see https://bugs.eclipse.org/330680 | |
356 | ||
357 | Color defaultColor= control.getBackground(); | |
358 | float[] defaultBgHSB= defaultColor.getRGB().getHSB(); | |
359 | ||
360 | Color javaDefaultColor= JavaUI.getColorManager().getColor(IJavaColorConstants.JAVA_DEFAULT); | |
361 | RGB javaDefaultRGB= javaDefaultColor != null ? javaDefaultColor.getRGB() : new RGB(255, 255, 255); | |
362 | float[] javaDefaultHSB= javaDefaultRGB.getHSB(); | |
363 | ||
364 | if (Math.abs(defaultBgHSB[2] - javaDefaultHSB[2]) >= 0.5f) { | |
365 | getTextWidget().setBackground(defaultColor); | |
366 | if (fBackgroundColor != null) { | |
367 | fBackgroundColor.dispose(); | |
368 | fBackgroundColor= null; | |
369 | } | |
370 | } | |
371 | } | |
372 | ||
373 | ||
374 | /* | |
375 | * @see org.eclipse.jface.text.source.ISourceViewerExtension2#unconfigure() | |
376 | * @since 3.0 | |
377 | */ | |
378 | @Override | |
379 | public void unconfigure() { | |
380 | if (fOutlinePresenter != null) { | |
381 | fOutlinePresenter.uninstall(); | |
382 | fOutlinePresenter= null; | |
383 | } | |
384 | if (fStructurePresenter != null) { | |
385 | fStructurePresenter.uninstall(); | |
386 | fStructurePresenter= null; | |
387 | } | |
388 | if (fHierarchyPresenter != null) { | |
389 | fHierarchyPresenter.uninstall(); | |
390 | fHierarchyPresenter= null; | |
391 | } | |
392 | if (fForegroundColor != null) { | |
393 | fForegroundColor.dispose(); | |
394 | fForegroundColor= null; | |
395 | } | |
396 | if (fBackgroundColor != null) { | |
397 | fBackgroundColor.dispose(); | |
398 | fBackgroundColor= null; | |
399 | } | |
400 | ||
401 | if (fPreferenceStore != null) | |
402 | fPreferenceStore.removePropertyChangeListener(this); | |
403 | ||
404 | super.unconfigure(); | |
405 | ||
406 | fIsConfigured= false; | |
407 | } | |
408 | ||
409 | /* | |
410 | * @see org.eclipse.jface.text.source.SourceViewer#rememberSelection() | |
411 | */ | |
412 | @Override | |
413 | public Point rememberSelection() { | |
414 | return super.rememberSelection(); | |
415 | } | |
416 | ||
417 | /* | |
418 | * @see org.eclipse.jface.text.source.SourceViewer#restoreSelection() | |
419 | */ | |
420 | @Override | |
421 | public void restoreSelection() { | |
422 | super.restoreSelection(); | |
423 | } | |
424 | ||
425 | /* | |
426 | * @see org.eclipse.jface.util.IPropertyChangeListener#propertyChange(org.eclipse.jface.util.PropertyChangeEvent) | |
427 | */ | |
428 | public void propertyChange(PropertyChangeEvent event) { | |
429 | String property = event.getProperty(); | |
430 | if (AbstractTextEditor.PREFERENCE_COLOR_FOREGROUND.equals(property) | |
431 | || AbstractTextEditor.PREFERENCE_COLOR_FOREGROUND_SYSTEM_DEFAULT.equals(property) | |
432 | || AbstractTextEditor.PREFERENCE_COLOR_BACKGROUND.equals(property) | |
433 | || AbstractTextEditor.PREFERENCE_COLOR_BACKGROUND_SYSTEM_DEFAULT.equals(property) | |
434 | || AbstractDecoratedTextEditorPreferenceConstants.EDITOR_SELECTION_FOREGROUND_COLOR.equals(property) | |
435 | || AbstractDecoratedTextEditorPreferenceConstants.EDITOR_SELECTION_FOREGROUND_DEFAULT_COLOR.equals(property) | |
436 | || AbstractDecoratedTextEditorPreferenceConstants.EDITOR_SELECTION_BACKGROUND_COLOR.equals(property) | |
437 | || AbstractDecoratedTextEditorPreferenceConstants.EDITOR_SELECTION_BACKGROUND_DEFAULT_COLOR.equals(property)) | |
438 | { | |
439 | initializeViewerColors(); | |
440 | } | |
441 | } | |
442 | ||
443 | /** | |
444 | * Sets the preference store on this viewer. | |
445 | * | |
446 | * @param store the preference store | |
447 | * | |
448 | * @since 3.0 | |
449 | */ | |
450 | public void setPreferenceStore(IPreferenceStore store) { | |
451 | if (fIsConfigured && fPreferenceStore != null) | |
452 | fPreferenceStore.removePropertyChangeListener(this); | |
453 | ||
454 | fPreferenceStore= store; | |
455 | ||
456 | if (fIsConfigured && fPreferenceStore != null) { | |
457 | fPreferenceStore.addPropertyChangeListener(this); | |
458 | initializeViewerColors(); | |
459 | } | |
460 | } | |
461 | ||
462 | /* | |
463 | * @see org.eclipse.jface.text.source.SourceViewer#createControl(org.eclipse.swt.widgets.Composite, int) | |
464 | */ | |
465 | @Override | |
466 | protected void createControl(Composite parent, int styles) { | |
467 | ||
468 | // Use LEFT_TO_RIGHT unless otherwise specified. | |
469 | if ((styles & SWT.RIGHT_TO_LEFT) == 0 && (styles & SWT.LEFT_TO_RIGHT) == 0) | |
470 | styles |= SWT.LEFT_TO_RIGHT; | |
471 | ||
472 | final int baseLevel= (styles & SWT.RIGHT_TO_LEFT) != 0 ? Bidi.DIRECTION_RIGHT_TO_LEFT : Bidi.DIRECTION_LEFT_TO_RIGHT; | |
473 | ||
474 | super.createControl(parent, styles); | |
475 | ||
476 | fBackspaceManager= new SmartBackspaceManager(); | |
477 | fBackspaceManager.install(this); | |
478 | ||
479 | StyledText text= getTextWidget(); | |
480 | text.addBidiSegmentListener(new BidiSegmentListener() { | |
481 | public void lineGetSegments(BidiSegmentEvent event) { | |
482 | if (redraws()) { | |
483 | try { | |
484 | event.segments= getBidiLineSegments(getDocument(), baseLevel, widgetOffset2ModelOffset(event.lineOffset), event.lineText); | |
485 | } catch (BadLocationException e) { | |
486 | // don't touch the segments | |
487 | } | |
488 | } | |
489 | } | |
490 | }); | |
491 | } | |
492 | ||
493 | /** | |
494 | * Returns the backspace manager for this viewer. | |
495 | * | |
496 | * @return the backspace manager for this viewer, or <code>null</code> if | |
497 | * there is none | |
498 | * @since 3.0 | |
499 | */ | |
500 | public SmartBackspaceManager getBackspaceManager() { | |
501 | return fBackspaceManager; | |
502 | } | |
503 | ||
504 | /* | |
505 | * @see org.eclipse.jface.text.source.SourceViewer#handleDispose() | |
506 | */ | |
507 | @Override | |
508 | protected void handleDispose() { | |
509 | if (fBackspaceManager != null) { | |
510 | fBackspaceManager.uninstall(); | |
511 | fBackspaceManager= null; | |
512 | } | |
513 | super.handleDispose(); | |
514 | } | |
515 | ||
516 | /** | |
517 | * Prepends the text presentation listener at the beginning of the viewer's | |
518 | * list of text presentation listeners. If the listener is already registered | |
519 | * with the viewer this call moves the listener to the beginning of | |
520 | * the list. | |
521 | * | |
522 | * @param listener the text presentation listener | |
523 | * @since 3.0 | |
524 | */ | |
525 | public void prependTextPresentationListener(ITextPresentationListener listener) { | |
526 | ||
527 | Assert.isNotNull(listener); | |
528 | ||
529 | if (fTextPresentationListeners == null) | |
530 | fTextPresentationListeners= new ArrayList<ITextPresentationListener>(); | |
531 | ||
532 | fTextPresentationListeners.remove(listener); | |
533 | fTextPresentationListeners.add(0, listener); | |
534 | } | |
535 | ||
536 | /** | |
537 | * Sets the given reconciler. | |
538 | * | |
539 | * @param reconciler the reconciler | |
540 | * @since 3.0 | |
541 | */ | |
542 | void setReconciler(IReconciler reconciler) { | |
543 | fReconciler= reconciler; | |
544 | } | |
545 | ||
546 | /** | |
547 | * Returns the reconciler. | |
548 | * | |
549 | * @return the reconciler or <code>null</code> if not set | |
550 | * @since 3.0 | |
551 | */ | |
552 | IReconciler getReconciler() { | |
553 | return fReconciler; | |
554 | } | |
555 | ||
556 | /** | |
557 | * Returns a segmentation of the line of the given document appropriate for | |
558 | * Bidi rendering. | |
559 | * | |
560 | * @param document the document | |
561 | * @param baseLevel the base level of the line | |
562 | * @param lineStart the offset of the line | |
563 | * @param lineText Text of the line to retrieve Bidi segments for | |
564 | * @return the line's Bidi segmentation | |
565 | * @throws BadLocationException in case lineOffset is not valid in document | |
566 | */ | |
567 | protected static int[] getBidiLineSegments(IDocument document, int baseLevel, int lineStart, String lineText) throws BadLocationException { | |
568 | ||
569 | if (lineText == null || document == null) | |
570 | return null; | |
571 | ||
572 | int lineLength= lineText.length(); | |
573 | if (lineLength <= 2) | |
574 | return null; | |
575 | ||
576 | // Have ICU compute embedding levels. Consume these levels to reduce | |
577 | // the Bidi impact, by creating selective segments (preceding | |
578 | // character runs with a level mismatching the base level). | |
579 | // XXX: Alternatively, we could apply TextLayout. Pros would be full | |
580 | // synchronization with the underlying StyledText's (i.e. native) Bidi | |
581 | // implementation. Cons are performance penalty because of | |
582 | // unavailability of such methods as isLeftToRight and getLevels. | |
583 | ||
584 | Bidi bidi= new Bidi(lineText, baseLevel); | |
585 | if (bidi.isLeftToRight()) | |
586 | // Bail out if this is not Bidi text. | |
587 | return null; | |
588 | ||
589 | IRegion line= document.getLineInformationOfOffset(lineStart); | |
590 | ITypedRegion[] linePartitioning= TextUtilities.computePartitioning(document, IJavaPartitions.JAVA_PARTITIONING, lineStart, line.getLength(), false); | |
591 | if (linePartitioning == null || linePartitioning.length < 1) | |
592 | return null; | |
593 | ||
594 | int segmentIndex= 1; | |
595 | int[] segments= new int[lineLength + 1]; | |
596 | byte[] levels= bidi.getLevels(); | |
597 | int nPartitions= linePartitioning.length; | |
598 | for (int partitionIndex= 0; partitionIndex < nPartitions; partitionIndex++) { | |
599 | ||
600 | ITypedRegion partition = linePartitioning[partitionIndex]; | |
601 | int lineOffset= partition.getOffset() - lineStart; | |
602 | //Assert.isTrue(lineOffset >= 0 && lineOffset < lineLength); | |
603 | ||
604 | if (lineOffset > 0 | |
605 | && isMismatchingLevel(levels[lineOffset], baseLevel) | |
606 | && isMismatchingLevel(levels[lineOffset - 1], baseLevel)) { | |
607 | // Indicate a Bidi segment at the partition start - provided | |
608 | // levels of both character at the current offset and its | |
609 | // preceding character mismatch the base paragraph level. | |
610 | // Partition end will be covered either by the start of the next | |
611 | // partition, a delimiter inside a next partition, or end of line. | |
612 | segments[segmentIndex++]= lineOffset; | |
613 | } | |
614 | if (IDocument.DEFAULT_CONTENT_TYPE.equals(partition.getType())) { | |
615 | int partitionEnd= Math.min(lineLength, lineOffset + partition.getLength()); | |
616 | while (++lineOffset < partitionEnd) { | |
617 | if (isMismatchingLevel(levels[lineOffset], baseLevel) | |
618 | && String.valueOf(lineText.charAt(lineOffset)).matches(BIDI_DELIMITERS)) { | |
619 | // For default content types, indicate a segment before | |
620 | // a delimiting character with a mismatching embedding | |
621 | // level. | |
622 | segments[segmentIndex++]= lineOffset; | |
623 | } | |
624 | } | |
625 | } | |
626 | } | |
627 | if (segmentIndex <= 1) | |
628 | return null; | |
629 | ||
630 | segments[0]= 0; | |
631 | if (segments[segmentIndex - 1] != lineLength) | |
632 | segments[segmentIndex++]= lineLength; | |
633 | ||
634 | if (segmentIndex == segments.length) | |
635 | return segments; | |
636 | ||
637 | int[] newSegments= new int[segmentIndex]; | |
638 | System.arraycopy(segments, 0, newSegments, 0, segmentIndex); | |
639 | return newSegments; | |
640 | } | |
641 | ||
642 | /** | |
643 | * Checks if the given embedding level is consistent with the base level. | |
644 | * | |
645 | * @param level Character embedding level to check. | |
646 | * @param baseLevel Base level (direction) of the text. | |
647 | * @return <code>true</code> if the character level is odd and the base | |
648 | * level is even OR the character level is even and the base level | |
649 | * is odd, and return <code>false</code> otherwise. | |
650 | * | |
651 | * @since 3.4 | |
652 | */ | |
653 | private static boolean isMismatchingLevel(int level, int baseLevel) { | |
654 | return ((level ^ baseLevel) & 1) != 0; | |
655 | } | |
656 | ||
657 | /** | |
658 | * Delays setting the visual document until after the projection has been computed. | |
659 | * This method must only be called before the document is set on the viewer. | |
660 | * <p> | |
661 | * This is a performance optimization to reduce the computation of | |
662 | * the text presentation triggered by <code>setVisibleDocument(IDocument)</code>. | |
663 | * </p> | |
664 | * | |
665 | * @see #setVisibleDocument(IDocument) | |
666 | * @since 3.1 | |
667 | */ | |
668 | void prepareDelayedProjection() { | |
669 | Assert.isTrue(!fIsSetVisibleDocumentDelayed); | |
670 | fIsSetVisibleDocumentDelayed= true; | |
671 | } | |
672 | ||
673 | /** | |
674 | * {@inheritDoc} | |
675 | * <p> | |
676 | * This is a performance optimization to reduce the computation of | |
677 | * the text presentation triggered by {@link #setVisibleDocument(IDocument)} | |
678 | * </p> | |
679 | * @see #prepareDelayedProjection() | |
680 | * @since 3.1 | |
681 | */ | |
682 | @Override | |
683 | protected void setVisibleDocument(IDocument document) { | |
684 | if (fIsSetVisibleDocumentDelayed) { | |
685 | fIsSetVisibleDocumentDelayed= false; | |
686 | IDocument previous= getVisibleDocument(); | |
687 | enableProjection(); // will set the visible document if anything is folded | |
688 | IDocument current= getVisibleDocument(); | |
689 | // if the visible document was not replaced, continue as usual | |
690 | if (current != null && current != previous) | |
691 | return; | |
692 | } | |
693 | ||
694 | super.setVisibleDocument(document); | |
695 | } | |
696 | ||
697 | /** | |
698 | * {@inheritDoc} | |
699 | * <p> | |
700 | * Performance optimization: since we know at this place | |
701 | * that none of the clients expects the given range to be | |
702 | * untouched we reuse the given range as return value. | |
703 | * </p> | |
704 | */ | |
705 | @Override | |
706 | protected StyleRange modelStyleRange2WidgetStyleRange(StyleRange range) { | |
707 | IRegion region= modelRange2WidgetRange(new Region(range.start, range.length)); | |
708 | if (region != null) { | |
709 | // don't clone the style range, but simply reuse it. | |
710 | range.start= region.getOffset(); | |
711 | range.length= region.getLength(); | |
712 | return range; | |
713 | } | |
714 | return null; | |
715 | } | |
716 | ||
717 | public void generated_7127017217677160176(SemanticHighlightingManager semantichighlightingmanager) { | |
718 | semantichighlightingmanager.fPresenter= new SemanticHighlightingPresenter(); | |
719 | semantichighlightingmanager.fPresenter.install(this, semantichighlightingmanager.fPresentationReconciler); | |
720 | ||
721 | if (semantichighlightingmanager.fEditor != null) { | |
722 | semantichighlightingmanager.fReconciler= new SemanticHighlightingReconciler(); | |
723 | semantichighlightingmanager.fReconciler.install(semantichighlightingmanager.fEditor, this, semantichighlightingmanager.fPresenter, semantichighlightingmanager.fSemanticHighlightings, semantichighlightingmanager.fHighlightings); | |
724 | } else { | |
725 | semantichighlightingmanager.fPresenter.updatePresentation(null, semantichighlightingmanager.createHardcodedPositions(), new HighlightedPosition[0]); | |
726 | } | |
727 | } | |
728 | ||
729 | public void generated_5570417209883044548(SimpleJavaSourceViewerConfiguration configuration) { | |
730 | configure(configuration); | |
731 | setEditable(false); | |
732 | } | |
733 | ||
734 | public void generated_3988790723016811232() { | |
735 | setRedraw(true); | |
736 | restoreSelection(); | |
737 | } | |
738 | ||
739 | public void generated_918383712412400893() { | |
740 | setRedraw(true); | |
741 | restoreSelection(); | |
742 | } | |
743 | ||
744 | public void generated_6112532825547636144(SemanticHighlightingPresenter semantichighlightingpresenter) { | |
745 | prependTextPresentationListener(semantichighlightingpresenter); | |
746 | addTextInputListener(semantichighlightingpresenter); | |
747 | semantichighlightingpresenter.manageDocument(getDocument()); | |
748 | } | |
749 | ||
750 | public void generated_6224309490797512190(SemanticHighlightingPresenter semantichighlightingpresenter) { | |
751 | removeTextPresentationListener(semantichighlightingpresenter); | |
752 | semantichighlightingpresenter.releaseDocument(getDocument()); | |
753 | semantichighlightingpresenter.invalidateTextPresentation(); | |
754 | semantichighlightingpresenter.resetState(); | |
755 | ||
756 | removeTextInputListener(semantichighlightingpresenter); | |
757 | } | |
758 | ||
759 | public Control generated_3512280688113340390(JavaEditorColoringConfigurationBlock javaeditorcoloringconfigurationblock, IPreferenceStore store) { | |
760 | SimpleJavaSourceViewerConfiguration configuration= new SimpleJavaSourceViewerConfiguration(javaeditorcoloringconfigurationblock.fColorManager, store, null, IJavaPartitions.JAVA_PARTITIONING, false); | |
761 | configure(configuration); | |
762 | // fake 1.5 source to get 1.5 features right. | |
763 | configuration.handlePropertyChangeEvent(new PropertyChangeEvent(javaeditorcoloringconfigurationblock, JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_4, JavaCore.VERSION_1_5)); | |
764 | Font font= JFaceResources.getFont(PreferenceConstants.EDITOR_TEXT_FONT); | |
765 | getTextWidget().setFont(font); | |
766 | new JavaSourcePreviewerUpdater(this, configuration, store); | |
767 | ||
768 | setEditable(false); | |
769 | Cursor arrowCursor= getTextWidget().getDisplay().getSystemCursor(SWT.CURSOR_ARROW); | |
770 | getTextWidget().setCursor(arrowCursor); | |
771 | ||
772 | // Don't set caret to 'null' as this causes https://bugs.eclipse.org/293263 | |
773 | // fPreviewViewer.getTextWidget().setCaret(null); | |
774 | ||
775 | String content= javaeditorcoloringconfigurationblock.loadPreviewContentFromFile("ColorSettingPreviewCode.txt"); //$NON-NLS-1$ | |
776 | IDocument document= new Document(content); | |
777 | JavaPlugin.getDefault().getJavaTextTools().setupJavaDocumentPartitioner(document, IJavaPartitions.JAVA_PARTITIONING); | |
778 | setDocument(document); | |
779 | ||
780 | javaeditorcoloringconfigurationblock.installSemanticHighlighting(); | |
781 | ||
782 | ||
783 | return getControl(); | |
784 | } | |
785 | ||
786 | public void generated_8140236244215241165(IntroduceParameterInputPage introduceparameterinputpage, Composite composite, IPreferenceStore store) { | |
787 | configure(new JavaSourceViewerConfiguration(JavaPlugin.getDefault().getJavaTextTools().getColorManager(), store, null, null)); | |
788 | getTextWidget().setFont(JFaceResources.getFont(PreferenceConstants.EDITOR_TEXT_FONT)); | |
789 | adaptBackgroundColor(composite); | |
790 | setDocument(introduceparameterinputpage.fSignaturePreviewDocument); | |
791 | setEditable(false); | |
792 | ||
793 | //Layouting problems with wrapped text: see https://bugs.eclipse.org/bugs/show_bug.cgi?id=9866 | |
794 | Control signaturePreviewControl= getControl(); | |
795 | PixelConverter pixelConverter= new PixelConverter(signaturePreviewControl); | |
796 | GridData gdata= new GridData(GridData.FILL_BOTH); | |
797 | gdata.widthHint= pixelConverter.convertWidthInCharsToPixels(50); | |
798 | gdata.heightHint= pixelConverter.convertHeightInCharsToPixels(2); | |
799 | signaturePreviewControl.setLayoutData(gdata); | |
800 | } | |
801 | ||
802 | public void generated_6891703842874860934(IntroduceParameterInputPage introduceparameterinputpage) { | |
803 | try{ | |
804 | int top= getTextWidget().getTopPixel(); | |
805 | introduceparameterinputpage.fSignaturePreviewDocument.set(introduceparameterinputpage.getIntroduceParameterRefactoring().getMethodSignaturePreview()); | |
806 | getTextWidget().setTopPixel(top); | |
807 | } catch (JavaModelException e){ | |
808 | ExceptionHandler.handle(e, RefactoringMessages.IntroduceParameterWizard_defaultPageTitle, RefactoringMessages.ChangeSignatureInputPage_exception); | |
809 | } | |
810 | } | |
811 | ||
812 | public Control generated_6915887440640051112(ChangeSignatureInputPage changesignatureinputpage, Composite composite, IPreferenceStore store) { | |
813 | configure(new JavaSourceViewerConfiguration(JavaPlugin.getDefault().getJavaTextTools().getColorManager(), store, null, null)); | |
814 | getTextWidget().setFont(JFaceResources.getFont(PreferenceConstants.EDITOR_TEXT_FONT)); | |
815 | adaptBackgroundColor(composite); | |
816 | setDocument(changesignatureinputpage.fSignaturePreviewDocument); | |
817 | setEditable(false); | |
818 | ||
819 | //Layouting problems with wrapped text: see https://bugs.eclipse.org/bugs/show_bug.cgi?id=9866 | |
820 | Control signaturePreviewControl= getControl(); | |
821 | return signaturePreviewControl; | |
822 | } | |
823 | ||
824 | public void generated_8053947708737811240(ChangeSignatureInputPage changesignatureinputpage) throws JavaModelException { | |
825 | int top= getTextWidget().getTopPixel(); | |
826 | changesignatureinputpage.fSignaturePreviewDocument.set(changesignatureinputpage.getChangeMethodSignatureProcessor().getNewMethodSignature()); | |
827 | getTextWidget().setTopPixel(top); | |
828 | } | |
829 | ||
830 | public Control generated_4759959990122637820(IntroduceParameterObjectInputPage introduceparameterobjectinputpage, Composite composite, IPreferenceStore store) { | |
831 | configure(new JavaSourceViewerConfiguration(JavaPlugin.getDefault().getJavaTextTools().getColorManager(), store, null, null)); | |
832 | getTextWidget().setFont(JFaceResources.getFont(PreferenceConstants.EDITOR_TEXT_FONT)); | |
833 | adaptBackgroundColor(composite); | |
834 | setDocument(introduceparameterobjectinputpage.fSignaturePreviewDocument); | |
835 | setEditable(false); | |
836 | ||
837 | // Layouting problems with wrapped text: see | |
838 | // https://bugs.eclipse.org/bugs/show_bug.cgi?id=9866 | |
839 | Control signaturePreviewControl= getControl(); | |
840 | return signaturePreviewControl; | |
841 | } | |
842 | ||
843 | public void generated_3772308884544259120(IntroduceParameterObjectInputPage introduceparameterobjectinputpage) throws JavaModelException { | |
844 | int top= getTextWidget().getTopPixel(); | |
845 | introduceparameterobjectinputpage.fSignaturePreviewDocument.set(introduceparameterobjectinputpage.fProcessor.getNewMethodSignature()); | |
846 | getTextWidget().setTopPixel(top); | |
847 | } | |
848 | ||
849 | public void generated_3272343075298364199(Composite parent, IPreferenceStore store, ReplaceInvocationsInputPage replaceinvocationsinputpage) { | |
850 | configure(new JavaSourceViewerConfiguration(JavaPlugin.getDefault().getJavaTextTools().getColorManager(), store, null, null)); | |
851 | getTextWidget().setFont(JFaceResources.getFont(PreferenceConstants.EDITOR_TEXT_FONT)); | |
852 | adaptBackgroundColor(parent); | |
853 | String signatureLabel= JavaElementLabels.getElementLabel(replaceinvocationsinputpage.fRefactoring.getMethod(), ReplaceInvocationsInputPage.LABEL_FLAGS); | |
854 | setDocument(new Document(signatureLabel)); | |
855 | setEditable(false); | |
856 | ||
857 | Control signatureControl= getControl(); | |
858 | PixelConverter pixelConverter= new PixelConverter(signatureControl); | |
859 | GridData gdata= new GridData(GridData.FILL_HORIZONTAL); | |
860 | gdata.widthHint= pixelConverter.convertWidthInCharsToPixels(50); | |
861 | signatureControl.setLayoutData(gdata); | |
862 | } | |
863 | ||
864 | public Document generated_2060298929755158601(IPreferenceStore store, ReplaceInvocationsInputPage replaceinvocationsinputpage) { | |
865 | configure(new JavaSourceViewerConfiguration(JavaPlugin.getDefault().getJavaTextTools().getColorManager(), store, null, null)); | |
866 | getTextWidget().setFont(JFaceResources.getFont(PreferenceConstants.EDITOR_TEXT_FONT)); | |
867 | Document bodyDocument= new Document(replaceinvocationsinputpage.getInitialBody()); | |
868 | setDocument(bodyDocument); | |
869 | setEditable(true); | |
870 | ||
871 | Control bodyControl= getControl(); | |
872 | PixelConverter pixelConverter= new PixelConverter(bodyControl); | |
873 | GridData gdata= new GridData(GridData.FILL_BOTH); | |
874 | gdata.widthHint= pixelConverter.convertWidthInCharsToPixels(50); | |
875 | gdata.minimumHeight= pixelConverter.convertHeightInCharsToPixels(5); | |
876 | bodyControl.setLayoutData(gdata); | |
877 | bodyControl.setFocus(); | |
878 | return bodyDocument; | |
879 | } | |
880 | ||
881 | public void generated_1537857327547168031(ExtractMethodInputPage extractmethodinputpage, Composite composite, RowLayouter layouter, IPreferenceStore store) { | |
882 | configure(new JavaSourceViewerConfiguration(JavaPlugin.getDefault().getJavaTextTools().getColorManager(), store, null, null)); | |
883 | getTextWidget().setFont(JFaceResources.getFont(PreferenceConstants.EDITOR_TEXT_FONT)); | |
884 | adaptBackgroundColor(composite); | |
885 | setDocument(extractmethodinputpage.fSignaturePreviewDocument); | |
886 | setEditable(false); | |
887 | ||
888 | //Layouting problems with wrapped text: see https://bugs.eclipse.org/bugs/show_bug.cgi?id=9866 | |
889 | Control signaturePreviewControl= getControl(); | |
890 | PixelConverter pixelConverter= new PixelConverter(signaturePreviewControl); | |
891 | GridData gdata= new GridData(GridData.FILL_BOTH); | |
892 | gdata.widthHint= pixelConverter.convertWidthInCharsToPixels(50); | |
893 | gdata.heightHint= pixelConverter.convertHeightInCharsToPixels(2); | |
894 | signaturePreviewControl.setLayoutData(gdata); | |
895 | layouter.perform(signaturePreviewControl); | |
896 | } | |
897 | ||
898 | public void generated_7703893380234708108(ExtractMethodInputPage extractmethodinputpage, String text) { | |
899 | int top= getTextWidget().getTopPixel(); | |
900 | String signature; | |
901 | try { | |
902 | signature= extractmethodinputpage.fRefactoring.getSignature(text); | |
903 | } catch (IllegalArgumentException e) { | |
904 | signature= ""; //$NON-NLS-1$ | |
905 | } | |
906 | extractmethodinputpage.fSignaturePreviewDocument.set(signature); | |
907 | getTextWidget().setTopPixel(top); | |
908 | } | |
909 | ||
910 | } |