/*******************************************************************************
* Copyright (c) 2016 Obeo.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Obeo - initial API and implementation
*******************************************************************************/
package org.eclipse.eef.ide.ui.internal.widgets.quickfix;
import java.lang.reflect.InvocationTargetException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.eef.EEFValidationRuleDescription;
import org.eclipse.eef.core.api.controllers.InvalidValidationRuleResultData;
import org.eclipse.eef.ide.ui.internal.EEFIdeUiPlugin;
import org.eclipse.eef.ide.ui.internal.Icons;
import org.eclipse.eef.ide.ui.internal.Messages;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.wizard.IWizardPage;
import org.eclipse.jface.wizard.Wizard;
import org.eclipse.ui.forms.IMessage;
/**
* The wizard used to display and launch the quick fixes.
*
* @author sbegaudeau
*/
public class EEFQuickFixWizard extends Wizard {
/**
* The number of ticks that can be consumed by each sub task.
*/
private static final int SUBMONITOR_TASK_WORK = 10;
/**
* The messages displayed to the end user.
*/
private IMessage[] messages;
/**
* The page displaying all the validation messages.
*/
private EEFValidationMessagesPage validationMessagesPage;
/**
* The page displaying all the quick fixes.
*/
private EEFQuickFixPage quickFixPage;
/**
* The constructor.
*
* @param messages
* The messages displayed to the end user
*/
public EEFQuickFixWizard(IMessage[] messages) {
this.messages = messages;
this.setWindowTitle(Messages.EEFQuickFixWizard_windowTitle);
this.setDefaultPageImageDescriptor(EEFIdeUiPlugin.getPlugin().getImageDescriptor(Icons.QUICK_FIX));
this.setNeedsProgressMonitor(true);
}
/**
* {@inheritDoc}
*
* @see org.eclipse.jface.wizard.Wizard#addPages()
*/
@Override
public void addPages() {
super.addPages();
if (this.messages.length == 1) {
// We have only one validation rule violated, let's show only the fix available
IMessage message = this.messages[0];
if (message.getKey() instanceof EEFValidationRuleDescription && message.getData() instanceof InvalidValidationRuleResultData) {
EEFValidationRuleDescription validationRule = (EEFValidationRuleDescription) message.getKey();
InvalidValidationRuleResultData data = (InvalidValidationRuleResultData) message.getData();
this.quickFixPage = new EEFQuickFixPage(message, validationRule, data);
this.addPage(this.quickFixPage);
}
} else {
// We have multiple validation rules violated, the user must select the one to fix
this.validationMessagesPage = new EEFValidationMessagesPage(this.messages);
this.addPage(this.validationMessagesPage);
}
}
/**
* {@inheritDoc}
*
* @see org.eclipse.jface.wizard.Wizard#getNextPage(org.eclipse.jface.wizard.IWizardPage)
*/
@Override
public IWizardPage getNextPage(IWizardPage page) {
// If we do not have a single message, we need to customize this
if (this.messages.length != 1 && page instanceof EEFValidationMessagesPage) {
EEFValidationMessagesPage validationRulesPage = (EEFValidationMessagesPage) page;
IMessage message = validationRulesPage.getSelectedMessage();
// The second page will show the quick fixes of the message of the first page
if (message.getKey() instanceof EEFValidationRuleDescription && message.getData() instanceof InvalidValidationRuleResultData) {
EEFValidationRuleDescription validationRule = (EEFValidationRuleDescription) message.getKey();
if (validationRule.getFixes().size() > 0) {
InvalidValidationRuleResultData data = (InvalidValidationRuleResultData) message.getData();
this.quickFixPage = new EEFQuickFixPage(message, validationRule, data);
this.quickFixPage.setWizard(this);
return this.quickFixPage;
}
}
}
return super.getNextPage(page);
}
/**
* {@inheritDoc}
*
* @see org.eclipse.jface.wizard.Wizard#getPreviousPage(org.eclipse.jface.wizard.IWizardPage)
*/
@Override
public IWizardPage getPreviousPage(IWizardPage page) {
// If we do not have a single message, we need to customize this too
if (this.messages.length != -1 && page == this.quickFixPage) {
// Make sure that we can navigate back and forth with the same IMessage
this.validationMessagesPage = new EEFValidationMessagesPage(this.messages, quickFixPage.getSelectedMessage());
this.validationMessagesPage.setWizard(this);
this.quickFixPage = null;
return this.validationMessagesPage;
}
return super.getPreviousPage(page);
}
/**
* {@inheritDoc}
*
* @see org.eclipse.jface.wizard.Wizard#needsPreviousAndNextButtons()
*/
@Override
public boolean needsPreviousAndNextButtons() {
return this.messages.length > 1;
}
/**
* {@inheritDoc}
*
* @see org.eclipse.jface.wizard.Wizard#canFinish()
*/
@Override
public boolean canFinish() {
boolean canFinish = this.getContainer().getCurrentPage() == this.quickFixPage;
canFinish = canFinish && (this.validationMessagesPage == null || this.validationMessagesPage.isPageComplete());
canFinish = canFinish && (this.quickFixPage != null && this.quickFixPage.isPageComplete());
return canFinish;
}
/**
* {@inheritDoc}
*
* @see org.eclipse.jface.wizard.Wizard#performFinish()
*/
@Override
public boolean performFinish() {
IRunnableWithProgress runnable = new IRunnableWithProgress() {
@Override
public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
SubMonitor subMonitor = SubMonitor.convert(monitor, Messages.EEFQuickFixWizard_applyQuickFix, SUBMONITOR_TASK_WORK + 1);
subMonitor.worked(1);
if (EEFQuickFixWizard.this.quickFixPage != null) {
// Use submonitor.split once we get to Neon as the minimum target platfom
EEFQuickFixWizard.this.getShell().getDisplay().readAndDispatch();
EEFQuickFixWizard.this.quickFixPage.performFinish(subMonitor.newChild(SUBMONITOR_TASK_WORK));
}
}
};
boolean finishedProperly = true;
try {
this.getContainer().run(false, true, runnable);
} catch (InvocationTargetException e) {
finishedProperly = false;
EEFIdeUiPlugin.getPlugin().error(e.getMessage(), e);
} catch (InterruptedException e) {
finishedProperly = false;
EEFIdeUiPlugin.getPlugin().error(e.getMessage(), e);
}
return finishedProperly;
}
}