/*******************************************************************************
* Copyright (c) 2004, 2015 IBM Corporation and others.
* 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:
* IBM - Initial API and implementation
* Markus Schorn (Wind River Systems)
* Patrik Suzzi <psuzzi@gmail.com> - Bug 460683
*******************************************************************************/
package org.jboss.tools.runtime.ui.internal.dialogs;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IProgressMonitorWithBlocking;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.IJobChangeEvent;
import org.eclipse.core.runtime.jobs.IJobChangeListener;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.core.runtime.jobs.JobChangeAdapter;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.BusyIndicator;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.TraverseEvent;
import org.eclipse.swt.events.TraverseListener;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.internal.IPreferenceConstants;
import org.eclipse.ui.internal.WorkbenchMessages;
import org.eclipse.ui.internal.WorkbenchPlugin;
import org.eclipse.ui.internal.progress.ProgressManager;
import org.eclipse.ui.internal.progress.ProgressMonitorFocusJobDialog;
import org.eclipse.ui.progress.IProgressConstants;
import org.eclipse.ui.progress.WorkbenchJob;
import org.jboss.tools.runtime.ui.RuntimeUIActivator;
/**
* The ProgressMonitorFocusJobDialog is a dialog that shows progress for a
* particular job in a modal dialog so as to give a user accustomed to a modal
* UI a more familiar feel.
*/
public class FastProgressMonitorFocusJobDialog extends ProgressMonitorFocusJobDialog {
/**
* Create a new instance of the receiver with progress reported on the job.
*
* @param parentShell
* The shell this is parented from.
*/
public FastProgressMonitorFocusJobDialog(Shell parentShell) {
super(parentShell);
}
public void run(boolean fork, boolean cancelable,
Job j) throws InvocationTargetException,
InterruptedException {
Field jeorb;
IRunnableWithProgress runnable = runnableWithProgress(j);
Exception ex = null;
try {
jeorb = ProgressMonitorFocusJobDialog.class.getDeclaredField("job");
jeorb.setAccessible(true);
jeorb.set(this, j);
super.run(fork, cancelable, runnable);
return;
} catch (NoSuchFieldException e) {
ex = e;
} catch (SecurityException e) {
ex = e;
} catch (IllegalArgumentException e) {
ex = e;
} catch (IllegalAccessException e) {
ex = e;
}
if( ex != null ) {
RuntimeUIActivator.pluginLog().logWarning("Unable to create FastProgressMonitorFocusJobDialog", ex);
}
// Something went wrong with the reflection probably...
// let's open a real dialog for them, even if its slow
new ProgressMonitorFocusJobDialog(getParentShell()).run(fork, cancelable, runnable);
}
private IRunnableWithProgress runnableWithProgress(final Job longJob) {
IRunnableWithProgress runnable = new IRunnableWithProgress(){
public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
addRunableMonitorAsListener(longJob, getBlockingProgressMonitor(monitor));
longJob.join();
}
};
return runnable;
}
private IProgressMonitorWithBlocking getBlockingProgressMonitor(final IProgressMonitor monitor) {
IProgressMonitorWithBlocking listener = new IProgressMonitorWithBlocking(){
public void beginTask(String name, int totalWork) {
monitor.beginTask(name, totalWork);
}
public void done() {
monitor.done();
}
public void internalWorked(double work) {
monitor.internalWorked(work);
}
public boolean isCanceled() {
return monitor.isCanceled();
}
public void setCanceled(boolean value) {
monitor.setCanceled(value);
}
public void setTaskName(String name) {
monitor.setTaskName(name);
}
public void subTask(String name) {
monitor.subTask(name);
}
public void worked(int work) {
monitor.worked(work);
}
public void setBlocked(IStatus reason) {
if( monitor instanceof IProgressMonitorWithBlocking) {
((IProgressMonitorWithBlocking)monitor).setBlocked(reason);
}
}
public void clearBlocked() {
if( monitor instanceof IProgressMonitorWithBlocking) {
((IProgressMonitorWithBlocking)monitor).clearBlocked();
}
}
};
return listener;
}
private void addRunableMonitorAsListener(Job longJob, IProgressMonitorWithBlocking listener) {
IProgressMonitorWithBlocking jobMonitor = ProgressManager.getInstance().progressFor(longJob);
try {
Class jMon = Class.forName("org.eclipse.ui.internal.progress.ProgressManager$JobMonitor");
Class[] cArg = new Class[]{IProgressMonitorWithBlocking.class};
Method m = jMon.getDeclaredMethod("addProgressListener", cArg);
m.setAccessible(true);
m.invoke(jobMonitor, listener);
System.out.println(jMon);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}