blob: bf04cf473ac0b0fdca84ba6ee2bed17ca8cc3752 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2009 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 Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.wst.xsd.ui.internal.adt.outline;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.PlatformUI;
import org.eclipse.wst.xsd.ui.internal.adapters.CategoryAdapter;
import org.eclipse.wst.xsd.ui.internal.adt.facade.IADTObject;
/**
* This job holds a queue of updates (affected nodes) for the XSD editor's
* outline view. When a new request comes in, the current run is cancelled,
* the new request is added to the queue, then the job is re-scheduled.
* This class is loosely based on RefreshStructureJob.
*/
class ADTContentOutlineRefreshJob extends Job
{
/**
* The delay time in milliseconds.
*/
private static final long UPDATE_DELAY = 300;
private final List nodesToRefresh = new ArrayList(5);
private final TreeViewer viewer;
public ADTContentOutlineRefreshJob(Viewer viewer)
{
super("Refreshing XSD outline"); //$NON-NLS-1$
setPriority(Job.LONG);
setSystem(true);
this.viewer = (TreeViewer)viewer;
}
private synchronized void addRefreshRequest(IADTObject adtObject)
{
if (nodesToRefresh.contains(adtObject))
{
return;
}
nodesToRefresh.add(adtObject);
}
protected void canceling()
{
nodesToRefresh.clear();
super.canceling();
}
private void doRefresh(final IADTObject adtObject)
{
final Display display = PlatformUI.getWorkbench().getDisplay();
display.asyncExec(new Runnable()
{
public void run()
{
boolean isValidViewer = viewer != null && !viewer.getControl().isDisposed();
if (isValidViewer)
{
viewer.refresh(adtObject);
// Needlessly revealing the category nodes causes a lot of UI flicker.
if (!(adtObject instanceof CategoryAdapter))
{
viewer.reveal(adtObject);
}
}
}
});
}
private synchronized IADTObject[] getNodesToRefresh()
{
IADTObject[] toRefresh = new IADTObject [nodesToRefresh.size()];
nodesToRefresh.toArray(toRefresh);
nodesToRefresh.clear();
return toRefresh;
}
public void refresh(IADTObject adtObject)
{
if (adtObject == null)
{
return;
}
addRefreshRequest(adtObject);
schedule(UPDATE_DELAY);
}
protected IStatus run(IProgressMonitor monitor)
{
IStatus status = Status.OK_STATUS;
try
{
performRefreshes(monitor);
}
finally
{
monitor.done();
}
return status;
}
private void performRefreshes(IProgressMonitor monitor)
{
IADTObject[] nodes = getNodesToRefresh();
for (int index = 0; index < nodes.length; index++)
{
if (monitor.isCanceled())
{
throw new OperationCanceledException();
}
IADTObject node = nodes[index];
doRefresh(node);
}
}
}