| /******************************************************************************* |
| * Copyright (c) 2007, 2017 IBM Corporation and others. |
| * |
| * This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License 2.0 |
| * which accompanies this distribution, and is available at |
| * https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.compare.internal; |
| |
| import java.util.HashMap; |
| import java.util.Map; |
| |
| import org.eclipse.jface.preference.IPreferenceStore; |
| import org.eclipse.jface.text.WhitespaceCharacterPainter; |
| import org.eclipse.jface.text.source.SourceViewer; |
| import org.eclipse.jface.util.PropertyChangeEvent; |
| import org.eclipse.ui.editors.text.EditorsUI; |
| import org.eclipse.ui.texteditor.AbstractTextEditor; |
| |
| public class ShowWhitespaceAction extends TextEditorPropertyAction { |
| |
| private Map<MergeSourceViewer, WhitespaceCharacterPainter> fPainters; |
| private boolean isWhitespaceShowing; |
| private boolean[] fNeedsPainters; |
| /** @since 3.7 */ |
| private boolean fShowLeadingSpaces; |
| /** @since 3.7 */ |
| private boolean fShowEnclosedSpaces; |
| /** @since 3.7 */ |
| private boolean fShowTrailingSpaces; |
| /** @since 3.7 */ |
| private boolean fShowLeadingIdeographicSpaces; |
| /** @since 3.7 */ |
| private boolean fShowEnclosedIdeographicSpaces; |
| /** @since 3.7 */ |
| private boolean fShowTrailingIdeographicSpace; |
| /** @since 3.7 */ |
| private boolean fShowLeadingTabs; |
| /** @since 3.7 */ |
| private boolean fShowEnclosedTabs; |
| /** @since 3.7 */ |
| private boolean fShowTrailingTabs; |
| /** @since 3.7 */ |
| private boolean fShowCarriageReturn; |
| /** @since 3.7 */ |
| private boolean fShowLineFeed; |
| /** @since 3.7 */ |
| private IPreferenceStore fStore = EditorsUI.getPreferenceStore(); |
| /** @since 3.7 */ |
| private int fAlpha; |
| |
| public ShowWhitespaceAction(MergeSourceViewer[] viewers, boolean[] needsPainters) { |
| super(CompareMessages.ShowWhitespaceAction_0, viewers, AbstractTextEditor.PREFERENCE_SHOW_WHITESPACE_CHARACTERS); |
| fNeedsPainters = needsPainters; |
| synchronizeWithPreference(); |
| } |
| |
| @Override |
| protected void synchronizeWithPreference() { |
| boolean checked = false; |
| if (fStore != null) { |
| checked = fStore.getBoolean(getPreferenceKey()); |
| fShowLeadingSpaces = fStore.getBoolean(AbstractTextEditor.PREFERENCE_SHOW_LEADING_SPACES); |
| fShowEnclosedSpaces = fStore.getBoolean(AbstractTextEditor.PREFERENCE_SHOW_ENCLOSED_SPACES); |
| fShowTrailingSpaces = fStore.getBoolean(AbstractTextEditor.PREFERENCE_SHOW_TRAILING_SPACES); |
| fShowLeadingIdeographicSpaces = fStore.getBoolean(AbstractTextEditor.PREFERENCE_SHOW_LEADING_IDEOGRAPHIC_SPACES); |
| fShowEnclosedIdeographicSpaces = fStore.getBoolean(AbstractTextEditor.PREFERENCE_SHOW_ENCLOSED_IDEOGRAPHIC_SPACES); |
| fShowTrailingIdeographicSpace = fStore.getBoolean(AbstractTextEditor.PREFERENCE_SHOW_TRAILING_IDEOGRAPHIC_SPACES); |
| fShowLeadingTabs = fStore.getBoolean(AbstractTextEditor.PREFERENCE_SHOW_LEADING_TABS); |
| fShowEnclosedTabs = fStore.getBoolean(AbstractTextEditor.PREFERENCE_SHOW_ENCLOSED_TABS); |
| fShowTrailingTabs = fStore.getBoolean(AbstractTextEditor.PREFERENCE_SHOW_TRAILING_TABS); |
| fShowCarriageReturn = fStore.getBoolean(AbstractTextEditor.PREFERENCE_SHOW_CARRIAGE_RETURN); |
| fShowLineFeed = fStore.getBoolean(AbstractTextEditor.PREFERENCE_SHOW_LINE_FEED); |
| fAlpha = fStore.getInt(AbstractTextEditor.PREFERENCE_WHITESPACE_CHARACTER_ALPHA_VALUE); |
| } |
| if (checked != isChecked()) { |
| if (toggleState(checked)) |
| setChecked(checked); |
| } else if (fNeedsPainters != null && checked) { |
| hideWhitespace(); |
| showWhitespace(); |
| } |
| } |
| |
| @Override |
| public void propertyChange(PropertyChangeEvent event) { |
| String property = event.getProperty(); |
| if (property.equals(getPreferenceKey()) || AbstractTextEditor.PREFERENCE_SHOW_LEADING_SPACES.equals(property) || AbstractTextEditor.PREFERENCE_SHOW_ENCLOSED_SPACES.equals(property) |
| || AbstractTextEditor.PREFERENCE_SHOW_TRAILING_SPACES.equals(property) || AbstractTextEditor.PREFERENCE_SHOW_LEADING_IDEOGRAPHIC_SPACES.equals(property) |
| || AbstractTextEditor.PREFERENCE_SHOW_ENCLOSED_IDEOGRAPHIC_SPACES.equals(property) || AbstractTextEditor.PREFERENCE_SHOW_TRAILING_IDEOGRAPHIC_SPACES.equals(property) |
| || AbstractTextEditor.PREFERENCE_SHOW_LEADING_TABS.equals(property) || AbstractTextEditor.PREFERENCE_SHOW_ENCLOSED_TABS.equals(property) |
| || AbstractTextEditor.PREFERENCE_SHOW_TRAILING_TABS.equals(property) || AbstractTextEditor.PREFERENCE_SHOW_CARRIAGE_RETURN.equals(property) |
| || AbstractTextEditor.PREFERENCE_SHOW_LINE_FEED.equals(property) || AbstractTextEditor.PREFERENCE_WHITESPACE_CHARACTER_ALPHA_VALUE.equals(property)) { |
| synchronizeWithPreference(); |
| } |
| } |
| |
| @Override |
| protected boolean toggleState(boolean checked) { |
| if (fNeedsPainters == null) |
| return false; // Not initialized yet |
| if (checked) { |
| showWhitespace(); |
| } else { |
| hideWhitespace(); |
| } |
| return true; |
| } |
| |
| private synchronized Map<MergeSourceViewer, WhitespaceCharacterPainter> getPainters() { |
| if (fPainters == null) |
| fPainters = new HashMap<>(); |
| return fPainters; |
| } |
| |
| private void showWhitespace() { |
| if (isWhitespaceShowing) |
| return; |
| try { |
| Map<MergeSourceViewer, WhitespaceCharacterPainter> painters = getPainters(); |
| MergeSourceViewer[] viewers = getViewers(); |
| for (int i = 0; i < viewers.length; i++) { |
| if (fNeedsPainters[i]) { |
| MergeSourceViewer viewer = viewers[i]; |
| SourceViewer sourceViewer = viewer.getSourceViewer(); |
| WhitespaceCharacterPainter painter; |
| if (fStore != null) { |
| painter = new WhitespaceCharacterPainter(sourceViewer, fShowLeadingSpaces, fShowEnclosedSpaces, fShowTrailingSpaces, fShowLeadingIdeographicSpaces, |
| fShowEnclosedIdeographicSpaces, fShowTrailingIdeographicSpace, fShowLeadingTabs, fShowEnclosedTabs, fShowTrailingTabs, fShowCarriageReturn, fShowLineFeed, fAlpha); |
| } else { |
| painter = new WhitespaceCharacterPainter(sourceViewer); |
| } |
| sourceViewer.addPainter(painter); |
| painters.put(viewer, painter); |
| } |
| } |
| } finally { |
| isWhitespaceShowing = true; |
| } |
| } |
| |
| private void hideWhitespace() { |
| Map<MergeSourceViewer, WhitespaceCharacterPainter> painters = getPainters(); |
| for (MergeSourceViewer viewer : painters.keySet()) { |
| WhitespaceCharacterPainter painter = painters.get(viewer); |
| if (painter != null) { |
| viewer.getSourceViewer().removePainter(painter); |
| painter.deactivate(true); |
| } |
| } |
| painters.clear(); |
| isWhitespaceShowing = false; |
| } |
| |
| } |