| /*=============================================================================# |
| # 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 )); |
| } |
| } |
| |
| } |