/*
* JBoss, Home of Professional Open Source.
*
* See the LEGAL.txt file distributed with this work for information regarding copyright ownership and licensing.
*
* See the AUTHORS.txt file distributed with this work for a full listing of individual contributors.
*/
package org.teiid.designer.ui.filter;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
import org.eclipse.jface.viewers.IFilter;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.StructuredViewer;
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.jface.viewers.deferred.DeferredContentProvider;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.List;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.ui.forms.widgets.FormToolkit;
/**
* @since 8.0
*/
public abstract class StructuredViewerFilterer {
public static final int DEFAULT_FILTER_DELAY_TIME = 400;
private ViewerFilter myVFilter;
private IFilter myIFilter;
private Map currentViewers = new HashMap();
Timer lastTimer;
private int delayMillis = DEFAULT_FILTER_DELAY_TIME;
public abstract Control addControl( Composite parent,
FormToolkit ftk );
protected abstract ViewerFilter createViewerFilter();
protected abstract IFilter createVirtualFilter();
private void init( boolean virtual ) {
if (virtual) {
if (myIFilter == null) {
myIFilter = createVirtualFilter();
} // endif
} else {
// not virtual:
if (myVFilter == null) {
myVFilter = createViewerFilter();
} // endif
} // endif
}
/** Convenience method for when you don't have a FormToolKit */
public Control addControl( Composite parent ) {
return addControl(parent, null);
}
public void attachToViewer( StructuredViewer viewer,
boolean autoSelectFirstMatch ) {
init(false);
viewer.addFilter(myVFilter);
currentViewers.put(viewer, new ViewerInfo(viewer, null, autoSelectFirstMatch));
}
public void attachToVirtualViewer( StructuredViewer viewer,
DeferredContentProvider dcp,
boolean autoSelectFirstMatch ) {
init(true);
currentViewers.put(viewer, new ViewerInfo(viewer, dcp, autoSelectFirstMatch));
}
public void removeFromViewer( StructuredViewer viewer ) {
init(false);
viewer.removeFilter(myVFilter);
currentViewers.remove(viewer);
}
public void updateFilter() {
Iterator itor = currentViewers.values().iterator();
while (itor.hasNext()) {
final ViewerInfo vi = (ViewerInfo)itor.next();
if (vi.viewer.getControl().isDisposed()) continue;
if (vi.dcp == null) {
// non-virtual:
vi.viewer.refresh();
autoSelectIfNeeded(vi);
} else {
// virtual:
vi.dcp.setFilter(myIFilter);
// schedule a selection in a little while:
Thread selector = new Thread("filter selector") {//$NON-NLS-1$
@Override
public void run() {
try {
Thread.sleep(300);
Display.getDefault().asyncExec(new Runnable() {
@Override
public void run() {
autoSelectIfNeeded(vi);
}
}); // endAnon Runnable
} catch (InterruptedException err) {
} // endtry
}
}; // endanon Thread
selector.setDaemon(true);
selector.setPriority(Thread.NORM_PRIORITY - 2);
selector.start();
} // endif
} // endwhile -- all viewers
}
static void autoSelectIfNeeded( ViewerInfo vi ) {
if (vi.autoSelect && vi.viewer.getSelection().isEmpty()) {
// we want to auto-select, and there is no current selection, so
// select the first entry:
Control c = vi.viewer.getControl();
Object toSelect = null;
if (c instanceof Table) {
Table t = (Table)c;
if (t.getItemCount() > 0) {
toSelect = t.getItem(0).getData();
} // endif -- has items
} else if (c instanceof List) {
List l = (List)c;
if (l.getItemCount() > 0) {
toSelect = l.getItem(0);
} // endif -- has items
} else if (c instanceof Tree) {
Tree t = (Tree)c;
if (t.getItemCount() > 0) {
toSelect = t.getTopItem().getData();
} // endif -- has items
} // endif -- instanceof switch
if (toSelect != null) {
// we have something to select:
vi.viewer.setSelection(new StructuredSelection(toSelect));
} // endif
} // endif -- autoselect
}
public void setDelayTime( int millis ) {
delayMillis = millis;
}
public void scheduleUpdate() {
// cancel last update request, if present:
if (lastTimer != null) {
lastTimer.cancel();
lastTimer = null;
} // endif
if (delayMillis > 0) {
// schedule an update for specified milliseconds later:
lastTimer = new Timer(true);
TimerTask tt = new TimerTask() {
@Override
public void run() {
Display.getDefault().syncExec(new Runnable() {
@Override
public void run() {
updateFilter();
}
});
if (lastTimer != null) {
lastTimer.cancel();
}
lastTimer = null;
}
};
lastTimer.schedule(tt, delayMillis);
} else {
// delay set to 0 or less; run right away:
updateFilter();
} // endif
}
private static class ViewerInfo {
StructuredViewer viewer;
DeferredContentProvider dcp;
boolean autoSelect;
public ViewerInfo( StructuredViewer viewer,
DeferredContentProvider dcp,
boolean select ) {
this.viewer = viewer;
this.dcp = dcp;
this.autoSelect = select;
}
}
}