blob: 31baf7e72c4e8f5adc1bd4e292238162f219ca03 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2007, 2020 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
* Alexander Fedorov <alexander.fedorov@arsysop.ru> - ongoing support
*******************************************************************************/
package org.eclipse.ui.internal.views.markers;
import java.lang.reflect.InvocationTargetException;
import java.util.Collection;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Consumer;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.e4.ui.internal.workspace.markers.Translation;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.viewers.StructuredViewer;
import org.eclipse.jface.wizard.Wizard;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IMarkerResolution;
import org.eclipse.ui.internal.ide.IDEInternalWorkbenchImages;
import org.eclipse.ui.views.markers.WorkbenchMarkerResolution;
import org.eclipse.ui.views.markers.internal.MarkerMessages;
/**
* QuickFixWizard is the wizard for quick fixes.
*
* @since 3.4
*
*/
class QuickFixWizard extends Wizard {
private IMarker[] selectedMarkers;
private Map<IMarkerResolution, Collection<IMarker>> resolutionMap;
private String description;
private final Consumer<StructuredViewer> showMarkers;
private final Consumer<Throwable> reporter;
private QuickFixPage quickFixPage;
/**
* Create the wizard with the map of resolutions.
*
* @param description the description of the problem
* @param selectedMarkers the markers that were selected
* @param resolutions Map key {@link IMarkerResolution} value
* {@link IMarker} []
* @param showMarkers the consumer to show markers
* @param reporter used to report failures during
* {@link Wizard#performFinish()} call
*/
public QuickFixWizard(String description, IMarker[] selectedMarkers,
Map<IMarkerResolution, Collection<IMarker>> resolutions, Consumer<StructuredViewer> showMarkers,
Consumer<Throwable> reporter) {
Objects.requireNonNull(reporter);
this.selectedMarkers= selectedMarkers;
this.resolutionMap = resolutions;
this.description = description;
this.showMarkers = showMarkers;
this.reporter = reporter;
setDefaultPageImageDescriptor(IDEInternalWorkbenchImages
.getImageDescriptor(IDEInternalWorkbenchImages.IMG_DLGBAN_QUICKFIX_DLG));
setNeedsProgressMonitor(true);
}
@Override
public void addPages() {
quickFixPage = new QuickFixPage(description, selectedMarkers, resolutionMap, showMarkers);
addPage(quickFixPage);
}
@Override
public boolean performFinish() {
Optional<IMarkerResolution> resolution = quickFixPage.getSelectedMarkerResolution();
if (!resolution.isPresent()) {
return true; // for backward compatibility
}
final IMarker[] markers = quickFixPage.getCheckedMarkers();
if (markers.length == 0) {
return true; // for backward compatibility
}
IRunnableWithProgress finishRunnable = monitor -> processResolution(resolution.get(), markers, monitor);
try {
getContainer().run(false, true, finishRunnable);
} catch (InvocationTargetException | InterruptedException e) {
reporter.accept(e);
return false;
}
return true;
}
/**
* Runs the resolution in UI thread. It should be in UI because a lot of
* resolutions expect to be executed in the UI thread at the moment. We can
* think about some interface to mark resolutions that are ready to be executed
* outside of the UI thread.
*
* @param resolution the resolution to run
* @param markers the array of markers to resolve
* @param monitor progress callback
*/
private void processResolution(final IMarkerResolution resolution, final IMarker[] markers,
IProgressMonitor monitor) {
monitor.beginTask(MarkerMessages.MarkerResolutionDialog_Fixing, markers.length);
ensureRepaint();
if (resolution instanceof WorkbenchMarkerResolution) {
((WorkbenchMarkerResolution) resolution).run(markers, monitor);
} else {
Translation translation = new Translation();
for (IMarker marker : markers) {
ensureRepaint();
if (monitor.isCanceled()) {
return;
}
monitor.subTask(translation.message(marker).orElse("")); //$NON-NLS-1$
resolution.run(marker);
monitor.worked(1);
}
}
}
/**
* org.eclipse.jface.wizard.ProgressMonitorPart needs to take a breath
*/
private void ensureRepaint() {
final Display display = getShell().getDisplay();
boolean dispatch = true;
while (dispatch) {
dispatch = display.readAndDispatch();
}
}
}