blob: d4f5512676a336811ae922153d26a479c8ca0fb0 [file] [log] [blame]
/*=============================================================================#
# Copyright (c) 2021 Stephan Wahlbrink and others.
#
# This program and the accompanying materials are made available under the
# terms of the Eclipse Public License 2.0 which is available at
# https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
# which is available at https://www.apache.org/licenses/LICENSE-2.0.
#
# SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
#
# Contributors:
# Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
#=============================================================================*/
package org.eclipse.statet.ltk.ui.sourceediting.assist;
import static org.eclipse.statet.ltk.ui.LtkUI.BUNDLE_ID;
import java.lang.reflect.InvocationTargetException;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.Position;
import org.eclipse.ltk.core.refactoring.TextChange;
import org.eclipse.text.edits.TextEdit;
import org.eclipse.ui.progress.IProgressService;
import org.eclipse.ui.statushandlers.StatusManager;
import org.eclipse.statet.jcommons.lang.NonNull;
import org.eclipse.statet.jcommons.lang.NonNullByDefault;
import org.eclipse.statet.jcommons.lang.Nullable;
import org.eclipse.statet.ecommons.text.ui.DefaultBrowserInformationInput;
import org.eclipse.statet.internal.ltk.ui.refactoring.TextEditAnnotator;
import org.eclipse.statet.ltk.model.core.element.SourceUnit;
import org.eclipse.statet.ltk.refactoring.core.QuickRefactoring;
import org.eclipse.statet.ltk.ui.refactoring.RefactoringExecutionHelper;
import org.eclipse.statet.ltk.ui.sourceediting.SourceEditor;
@NonNullByDefault
public class QuickRefactoringAssistProposal<TContext extends AssistInvocationContext>
extends CommandAssistProposal<TContext> {
private final QuickRefactoring refactoring;
public QuickRefactoringAssistProposal(final ProposalParameters<TContext> parameters,
final QuickRefactoring refactoring) {
super(parameters);
this.refactoring= refactoring;
check();
}
public QuickRefactoringAssistProposal(final TContext invocationContext, final String commandId,
final String label,
final QuickRefactoring refactoring) {
super(invocationContext, commandId, label, null);
this.refactoring= refactoring;
check();
}
protected void check() {
if (getInvocationContext().getSourceUnit() == null) {
throw new IllegalArgumentException();
}
}
protected QuickRefactoring getRefactoring() {
return this.refactoring;
}
@Override
public @Nullable Object getAdditionalProposalInfo(final IProgressMonitor monitor) {
final SubMonitor m= SubMonitor.convert(monitor, 2 + 2);
try {
final StringBuilder sb= new StringBuilder();
final TextChange change= this.refactoring.createTextChange(m.newChild(2));
change.setKeepPreviewEdits(true);
final IDocument previewDocument= change.getPreviewDocument(m.newChild(1));
final TextEdit rootEdit= change.getPreviewEdit(change.getEdit());
final TextEditAnnotator ea= new TextEditAnnotator(sb, previewDocument);
rootEdit.accept(ea); m.worked(1);
return new DefaultBrowserInformationInput(getDisplayString(),
sb.toString(), DefaultBrowserInformationInput.FORMAT_HTMLSOURCE_INPUT,
getInvocationContext().getTabSize() );
}
catch (final CoreException e) {
StatusManager.getManager().handle(new Status(IStatus.ERROR, BUNDLE_ID, -1,
String.format("An error occured when generating the preview for quick assist '%1$s'.",
getDisplayString() ),
e ));
return null;
}
finally {
m.done();
}
}
@Override
public void apply(final ITextViewer viewer,
final char trigger, final int stateMask, final int offset) {
final var context= getInvocationContext();
@SuppressWarnings("null")
final @NonNull SourceUnit sourceUnit= context.getSourceUnit();
final SourceEditor editor= context.getEditor();
final var textWidget= editor.getViewer().getTextWidget();
if (textWidget == null) {
return;
}
IProgressService execContext= null;
final var serviceLocator= editor.getServiceLocator();
if (serviceLocator != null) {
execContext= serviceLocator.getService(IProgressService.class);
}
if (execContext == null) {
return;
}
final var applyData= getApplyData();
try {
final var refactoring= this.refactoring;
final var helper= new RefactoringExecutionHelper(refactoring,
offset, textWidget.getShell(), execContext );
helper.enableInsertPosition(sourceUnit);
helper.perform(false, false);
final Position position= helper.getInsertPosition();
if (position != null) {
applyData.setSelection(position.getOffset());
}
}
catch (final InterruptedException e) {}
catch (final InvocationTargetException e) {
StatusManager.getManager().handle(new Status(IStatus.ERROR, BUNDLE_ID, -1,
String.format("An error occured when executing quick assist '%1$s'.",
getDisplayString() ),
e ));
}
}
}