blob: 46cf64608acb05f200b38843906e8c1e9d06fcc3 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2002, 2013 GEBIT Gesellschaft fuer EDV-Beratung
* und Informatik-Technologien mbH,
* Berlin, Duesseldorf, Frankfurt (Germany) 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:
* GEBIT Gesellschaft fuer EDV-Beratung und Informatik-Technologien mbH - initial API and implementation
* IBM Corporation - bug fixes
* John-Mason P. Shackelford - bug 40255
* Rob Dingwell - bug 68886
*******************************************************************************/
package org.eclipse.ant.internal.ui.editor;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.eclipse.ant.internal.core.IAntCoreConstants;
import org.eclipse.ant.internal.ui.AntSourceViewerConfiguration;
import org.eclipse.ant.internal.ui.editor.formatter.XmlDocumentFormattingStrategy;
import org.eclipse.ant.internal.ui.editor.formatter.XmlElementFormattingStrategy;
import org.eclipse.ant.internal.ui.editor.text.AntDocumentSetupParticipant;
import org.eclipse.ant.internal.ui.editor.text.AntEditorPartitionScanner;
import org.eclipse.ant.internal.ui.editor.text.AntInformationProvider;
import org.eclipse.ant.internal.ui.editor.text.NotifyingReconciler;
import org.eclipse.ant.internal.ui.editor.text.XMLAnnotationHover;
import org.eclipse.ant.internal.ui.editor.text.XMLReconcilingStrategy;
import org.eclipse.ant.internal.ui.editor.text.XMLTextHover;
import org.eclipse.ant.internal.ui.preferences.AntEditorPreferenceConstants;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.jface.preference.JFacePreferences;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.text.DefaultInformationControl;
import org.eclipse.jface.text.IAutoEditStrategy;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IInformationControlCreator;
import org.eclipse.jface.text.ITextHover;
import org.eclipse.jface.text.contentassist.ContentAssistant;
import org.eclipse.jface.text.contentassist.IContentAssistant;
import org.eclipse.jface.text.formatter.IContentFormatter;
import org.eclipse.jface.text.formatter.MultiPassContentFormatter;
import org.eclipse.jface.text.information.IInformationPresenter;
import org.eclipse.jface.text.information.IInformationProvider;
import org.eclipse.jface.text.information.InformationPresenter;
import org.eclipse.jface.text.reconciler.IReconciler;
import org.eclipse.jface.text.source.IAnnotationHover;
import org.eclipse.jface.text.source.ISourceViewer;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.swt.graphics.Color;
/**
* The source viewer configuration for the Ant Editor.
*/
public class AntEditorSourceViewerConfiguration extends AntSourceViewerConfiguration {
private AntEditor fEditor;
private XMLTextHover fTextHover;
private ContentAssistant fContentAssistant;
private AntAutoEditStrategy[] fAutoEditorStategies;
/**
* Creates an instance with the specified color manager.
*/
public AntEditorSourceViewerConfiguration(AntEditor editor) {
super();
fEditor = editor;
}
@Override
public IContentAssistant getContentAssistant(ISourceViewer sourceViewer) {
fContentAssistant = new ContentAssistant();
AntEditorCompletionProcessor processor = new AntEditorCompletionProcessor(fEditor.getAntModel());
fContentAssistant.setContentAssistProcessor(processor, IDocument.DEFAULT_CONTENT_TYPE);
fContentAssistant.setContentAssistProcessor(processor, AntEditorPartitionScanner.XML_TAG);
fContentAssistant.setDocumentPartitioning(AntDocumentSetupParticipant.ANT_PARTITIONING);
String triggers = fPreferenceStore.getString(AntEditorPreferenceConstants.CODEASSIST_AUTOACTIVATION_TRIGGERS);
if (triggers != null) {
processor.setCompletionProposalAutoActivationCharacters(triggers.toCharArray());
}
fContentAssistant.enableAutoInsert(fPreferenceStore.getBoolean(AntEditorPreferenceConstants.CODEASSIST_AUTOINSERT));
fContentAssistant.enableAutoActivation(fPreferenceStore.getBoolean(AntEditorPreferenceConstants.CODEASSIST_AUTOACTIVATION));
fContentAssistant.setAutoActivationDelay(fPreferenceStore.getInt(AntEditorPreferenceConstants.CODEASSIST_AUTOACTIVATION_DELAY));
fContentAssistant.setProposalPopupOrientation(IContentAssistant.PROPOSAL_OVERLAY);
fContentAssistant.setContextInformationPopupOrientation(IContentAssistant.CONTEXT_INFO_ABOVE);
fContentAssistant.setInformationControlCreator(getInformationControlCreator(sourceViewer));
Color background = JFaceResources.getColorRegistry().get(JFacePreferences.CONTENT_ASSIST_BACKGROUND_COLOR);
fContentAssistant.setContextInformationPopupBackground(background);
fContentAssistant.setContextSelectorBackground(background);
Color foreground = JFaceResources.getColorRegistry().get(JFacePreferences.CONTENT_ASSIST_FOREGROUND_COLOR);
fContentAssistant.setContextInformationPopupForeground(foreground);
fContentAssistant.setContextSelectorForeground(foreground);
IInformationControlCreator creator = getInformationControlCreator(sourceViewer);
fContentAssistant.setInformationControlCreator(creator);
fContentAssistant.setRepeatedInvocationMode(true);
fContentAssistant.setStatusLineVisible(true);
fContentAssistant.setShowEmptyList(true);
fContentAssistant.addCompletionListener(processor);
return fContentAssistant;
}
@Override
public IReconciler getReconciler(ISourceViewer sourceViewer) {
NotifyingReconciler reconciler = new NotifyingReconciler(new XMLReconcilingStrategy(fEditor));
reconciler.setDelay(XMLReconcilingStrategy.DELAY);
reconciler.addReconcilingParticipant(fEditor);
return reconciler;
}
@Override
public IAnnotationHover getAnnotationHover(ISourceViewer sourceViewer) {
return new XMLAnnotationHover();
}
@Override
public IInformationControlCreator getInformationControlCreator(ISourceViewer sourceViewer) {
return parent -> new DefaultInformationControl(parent, false);
}
@Override
public ITextHover getTextHover(ISourceViewer sourceViewer, String contentType) {
if (fTextHover == null) {
fTextHover = new XMLTextHover(fEditor);
}
return fTextHover;
}
protected void changeConfiguration(PropertyChangeEvent event) {
String p = event.getProperty();
if (AntEditorPreferenceConstants.CODEASSIST_AUTOACTIVATION.equals(p)) {
boolean enabled = fPreferenceStore.getBoolean(AntEditorPreferenceConstants.CODEASSIST_AUTOACTIVATION);
fContentAssistant.enableAutoActivation(enabled);
} else if (AntEditorPreferenceConstants.CODEASSIST_AUTOACTIVATION_DELAY.equals(p) && fContentAssistant != null) {
int delay = fPreferenceStore.getInt(AntEditorPreferenceConstants.CODEASSIST_AUTOACTIVATION_DELAY);
fContentAssistant.setAutoActivationDelay(delay);
} else if (AntEditorPreferenceConstants.CODEASSIST_AUTOINSERT.equals(p) && fContentAssistant != null) {
boolean enabled = fPreferenceStore.getBoolean(AntEditorPreferenceConstants.CODEASSIST_AUTOINSERT);
fContentAssistant.enableAutoInsert(enabled);
} else if (AntEditorPreferenceConstants.CODEASSIST_AUTOACTIVATION_TRIGGERS.equals(p)) {
changeContentAssistProcessor();
}
}
private void changeContentAssistProcessor() {
String triggers = fPreferenceStore.getString(AntEditorPreferenceConstants.CODEASSIST_AUTOACTIVATION_TRIGGERS);
if (triggers != null) {
AntEditorCompletionProcessor cp = (AntEditorCompletionProcessor) fContentAssistant.getContentAssistProcessor(IDocument.DEFAULT_CONTENT_TYPE);
if (cp != null) {
cp.setCompletionProposalAutoActivationCharacters(triggers.toCharArray());
}
}
}
@Override
public IContentFormatter getContentFormatter(ISourceViewer sourceViewer) {
MultiPassContentFormatter formatter = new MultiPassContentFormatter(getConfiguredDocumentPartitioning(sourceViewer), IDocument.DEFAULT_CONTENT_TYPE);
formatter.setMasterStrategy(new XmlDocumentFormattingStrategy());
formatter.setSlaveStrategy(new XmlElementFormattingStrategy(), AntEditorPartitionScanner.XML_TAG);
// formatter.setSlaveStrategy(new XmlCommentFormattingStrategy(), AntEditorPartitionScanner.XML_COMMENT);
return formatter;
}
@Override
public IInformationPresenter getInformationPresenter(ISourceViewer sourceViewer) {
InformationPresenter presenter = new InformationPresenter(getInformationPresenterControlCreator());
presenter.setDocumentPartitioning(getConfiguredDocumentPartitioning(sourceViewer));
IInformationProvider provider = new AntInformationProvider(new XMLTextHover(fEditor));
presenter.setInformationProvider(provider, IDocument.DEFAULT_CONTENT_TYPE);
presenter.setInformationProvider(provider, AntEditorPartitionScanner.XML_CDATA);
presenter.setInformationProvider(provider, AntEditorPartitionScanner.XML_COMMENT);
presenter.setInformationProvider(provider, AntEditorPartitionScanner.XML_DTD);
presenter.setInformationProvider(provider, AntEditorPartitionScanner.XML_TAG);
presenter.setSizeConstraints(60, 10, true, true);
return presenter;
}
/**
* Returns the information presenter control creator. The creator is a factory creating the presenter controls for the given source viewer. This
* implementation always returns a creator for <code>DefaultInformationControl</code> instances.
*
* @return an information control creator
* @since 3.1
*/
public static IInformationControlCreator getInformationPresenterControlCreator() {
return parent -> new DefaultInformationControl(parent, true);
}
@Override
public String[] getIndentPrefixes(ISourceViewer sourceViewer, String contentType) {
List<String> list = new ArrayList<>();
// prefix[0] is either '\t' or ' ' x tabWidth, depending on useSpaces
int tabWidth = getTabWidth(sourceViewer);
boolean useSpaces = fEditor.isTabsToSpacesConversionEnabled();
for (int i = 0; i <= tabWidth; i++) {
StringBuilder prefix = new StringBuilder();
if (useSpaces) {
for (int j = 0; j + i < tabWidth; j++) {
prefix.append(' ');
}
if (i != 0) {
prefix.append('\t');
}
} else {
for (int j = 0; j < i; j++) {
prefix.append(' ');
}
if (i != tabWidth) {
prefix.append('\t');
}
}
list.add(prefix.toString());
}
list.add(IAntCoreConstants.EMPTY_STRING);
return list.toArray(new String[list.size()]);
}
@Override
public IAutoEditStrategy[] getAutoEditStrategies(ISourceViewer sourceViewer, String contentType) {
if (AntEditorPartitionScanner.XML_COMMENT.equals(contentType)) {
return super.getAutoEditStrategies(sourceViewer, contentType);
}
if (fAutoEditorStategies == null) {
fAutoEditorStategies = new AntAutoEditStrategy[] { new AntAutoEditStrategy(fEditor.getAntModel()) };
}
return fAutoEditorStategies;
}
@Override
protected Map<String, IAdaptable> getHyperlinkDetectorTargets(ISourceViewer sourceViewer) {
Map<String, IAdaptable> targets = super.getHyperlinkDetectorTargets(sourceViewer);
targets.put("org.eclipse.ant.ui.buildFiles", fEditor); //$NON-NLS-1$
return targets;
}
}