package com.onpositive.commons.ui.viewers;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import org.eclipse.jface.layout.TreeColumnLayout;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.jface.viewers.ColumnPixelData;
import org.eclipse.jface.viewers.ColumnWeightData;
import org.eclipse.jface.viewers.IOpenListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.OpenEvent;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.TreePath;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.TreeEvent;
import org.eclipse.swt.events.TreeListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.TextLayout;
import org.eclipse.swt.graphics.TextStyle;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeColumn;
import org.eclipse.swt.widgets.TreeItem;
import org.eclipse.swt.widgets.Widget;
public abstract class ConfigurableViewer {
private int[] columnOrder;
private final class ExpandRunnable implements Runnable {
private final TreePath item;
private ExpandRunnable(TreePath item) {
this.item = item;
}
public void run() {
ITreeContentProvider ts = (ITreeContentProvider) viewer
.getContentProvider();
Object[] children = ts.getChildren(item.getLastSegment());
if (children != null && children.length == 1) {
TreePath ps = item.createChildPath(children[0]);
viewer.expandToLevel(ps, 2);
Display.getCurrent().asyncExec(new ExpandRunnable(ps));
}
}
}
public abstract IPreferenceStore getPreferenceStore();
class Locking {
private Tree table;
private ColumnMovementListener columnMovementListener = new ColumnMovementListener();
private Set lockedColumns = new HashSet();
private class ColumnMovementListener implements Listener {
public void handleEvent(Event event) {
Set movedColumns = new HashSet(2);
int[] newColumnOrder = table.getColumnOrder();
if (newColumnOrder.length > columnOrder.length) {
int[] no = new int[newColumnOrder.length];
System.arraycopy(columnOrder, 0, no, 0, columnOrder.length);
for (int b = columnOrder.length; b < newColumnOrder.length; b++) {
no[b] = newColumnOrder[b];
}
columnOrder = newColumnOrder;
}
for (int i = 0; i < newColumnOrder.length; ++i) {
if (columnOrder[i] != newColumnOrder[i]) {
movedColumns.add(table.getColumn(newColumnOrder[i]));
}
}
boolean lockedWasMoved = false;
for (Iterator iter = movedColumns.iterator(); iter.hasNext();) {
Object movedColumn = iter.next();
if (lockedColumns.contains(movedColumn)) {
lockedWasMoved = true;
break;
}
}
if (lockedWasMoved) {
table.setColumnOrder(columnOrder);
} else {
columnOrder = newColumnOrder;
}
}
}
public Locking(Tree table, int[] lockedColumnIdxs) {
super();
this.table = table;
columnOrder = table.getColumnOrder();
for (int i = 0; i < lockedColumnIdxs.length; ++i) {
int idx = lockedColumnIdxs[i];
TreeColumn columnAdapter = table.getColumn(idx);
columnAdapter.setMoveable(false);
lockedColumns.add(columnAdapter);
}
int colCount = table.getColumnCount();
for (int i = 0; i < colCount; ++i) {
table.getColumn(i)
.addListener(SWT.Move, columnMovementListener);
}
}
}
private Composite owner;
private TreeViewer viewer;
private ViewerConfiguration config;
private TreeColumn nameColumn;
private Object input;
private TreeColumnLayout layout;
private IFilter filter;
private Color matchColor = new Color(Display.getDefault(), 160, 160, 220);
private static Color pathColor = new Color(Display.getDefault(), 160, 160,
160);
private int[] columnSizes;
public ConfigurableViewer(Composite owner) {
this.owner = owner;
}
public void setInput(Object input) {
this.input = input;
if (viewer != null) {
viewer.setInput(input);
}
}
public void setFilter(IFilter filter) {
this.filter = filter;
}
private IPropertyChangeListener listener;
protected boolean showPath = true;
public void configure(ViewerConfiguration configuration) {
// owner.setRedraw(false);
layout = new TreeColumnLayout();
owner.setLayout(layout);
showPath = getPreferenceStore().getBoolean(
IPreferenceConstants.SHOW_PATH);
try {
if (viewer != null) {
viewer.getControl().dispose();
}
this.config = configuration;
viewer = new TreeViewer(owner);
listener = new IPropertyChangeListener() {
public void propertyChange(PropertyChangeEvent event) {
if (event.getProperty().equals(
IPreferenceConstants.SHOW_PATH)) {
showPath = getPreferenceStore().getBoolean(
IPreferenceConstants.SHOW_PATH);
viewer.getTree().redraw();
}
}
};
getPreferenceStore().addPropertyChangeListener(listener);
viewer.getTree().addDisposeListener(new DisposeListener() {
public void widgetDisposed(DisposeEvent e) {
getPreferenceStore().removePropertyChangeListener(listener);
String name = "columnOrderFor" + config.getName();
String getOrderString = getOrderString(columnOrder);
getPreferenceStore().setValue(name, getOrderString);
name = "columnSizesFor" + config.getName();
getOrderString = getOrderString(columnSizes);
getPreferenceStore().setValue(name, getOrderString);
}
});
viewer.getTree().addListener(SWT.EraseItem, new Listener() {
public void handleEvent(Event event) {
event.detail &= ~SWT.FOREGROUND;
// event.detail &= ~SWT.SELECTED;
}
});
viewer.addOpenListener(new IOpenListener() {
public void open(OpenEvent event) {
IStructuredSelection selection = (IStructuredSelection) event
.getSelection();
Object firstElement = selection.getFirstElement();
onOpen(firstElement);
}
});
viewer.getTree().addTreeListener(new TreeListener() {
public void treeCollapsed(TreeEvent e) {
}
public void treeExpanded(TreeEvent e) {
boolean boolean1 = getPreferenceStore().getBoolean(
IPreferenceConstants.ENABLE_AUTO_EXPAND);
if (boolean1) {
ArrayList<Object> ls = new ArrayList<Object>();
TreeItem it = (TreeItem) e.item;
while (it != null) {
ls.add(it.getData());
it = it.getParentItem();
}
Collections.reverse(ls);
Display.getCurrent().asyncExec(
new ExpandRunnable(new TreePath(ls.toArray())));
}
}
});
viewer.getTree().addListener(SWT.MeasureItem, new Listener() {
public void handleEvent(Event event) {
event.width = event.gc.getClipping().width;
}
});
viewer.getTree().addListener(SWT.PaintItem, new Listener() {
public void handleEvent(Event event) {
try {
if (event.index == 0) {
renderFirstColumn(event);
} else {
config.getColumns()[event.index - 1].paint(event);
}
} catch (Exception e) {
e.printStackTrace();
}
}
});
viewer.setLabelProvider(new LabelProvider() {
public Image getImage(Object element) {
return getDefaultImage();
}
public String getText(Object element) {
return null;
}
});
viewer.setUseHashlookup(true);
createColumns();
viewer.addSelectionChangedListener(new ISelectionChangedListener() {
public void selectionChanged(SelectionChangedEvent event) {
fireChanged(event);
}
});
viewer.setContentProvider(new DeferedContentProvider(
(ITreeContentProvider) configuration.getContentProvider()));
String string = getPreferenceStore().getString(
"columnOrderFor" + config.getName());
if (string != null && string.length() > 0) {
String[] split = string.split(",");
int[] result = new int[split.length];
for (int a = 0; a < result.length; a++) {
result[a] = Integer.parseInt(split[a]);
}
if (viewer.getTree().getColumnCount() >= result.length) {
try{
viewer.getTree().setColumnOrder(result);
}catch (Exception e) {
}
}
}
viewer.setInput(input);
viewer.getTree().setHeaderVisible(true);
viewer.getTree().setLinesVisible(true);
owner.layout(true, true);
string = getPreferenceStore().getString(
"columnSizesFor" + config.getName());
if (string != null && string.length() > 0) {
String[] split = string.split(",");
int[] result = new int[split.length];
for (int a = 0; a < result.length; a++) {
result[a] = Integer.parseInt(split[a]);
}
if (viewer.getTree().getColumnCount() >= result.length) {
for (int a = 0; a < result.length; a++) {
if (result[a]==0){
result[a]=50;
}
viewer.getTree().getColumn(a).setWidth(result[a]);
}
}
}
} finally {
// owner.setRedraw(true);
}
}
protected abstract Image getDefaultImage();
protected abstract void onOpen(Object firstElement);
protected String getOrderString(int[] columnOrder2) {
StringBuilder bld = new StringBuilder();
for (int a = 0; a < columnOrder2.length; a++) {
bld.append(columnOrder2[a]);
if (a != columnOrder2.length - 1)
bld.append(',');
}
return bld.toString();
}
public void expandToLevel(int level) {
if (viewer != null) {
viewer.expandToLevel(level);
}
}
protected void fireChanged(SelectionChangedEvent event) {
for (ISelectionChangedListener l : listeners) {
l.selectionChanged(event);
}
}
static TextLayout tlayout = new TextLayout(Display.getDefault());
public static class RenderInfo {
public int blackLength;
String fullText;
public RenderInfo(int blackLength, String fullText) {
super();
this.blackLength = blackLength;
this.fullText = fullText;
}
}
protected void renderFirstColumn(Event event) {
Object element = event.item.getData();
Object trace = (Object) element;
if (trace == null) {
return;
}
boolean matches = true;
if (filter != null) {
if (!filter.accept(trace)) {
matches = false;
}
}
Image image = getImage(trace);
if (image != null) {
event.gc.drawImage(image, event.x, event.y);
}
// File file = new File(trace.getFile());
RenderInfo ri = getRenderInfo(trace);
String text = ri.fullText;
int blackLength = ri.blackLength;
String string = getImplicitFilterString(trace);
if (!matches) {
event.gc.setForeground(pathColor);
text += string;
}
tlayout.setText(text);
tlayout.setStyle(new TextStyle(null, pathColor, null), blackLength,
text.length());
if (!matches) {
tlayout.setStyle(new TextStyle(null, matchColor, null), text
.length()
- string.length(), text.length());
}
if (filter != null) {
Point match = filter.match(getName(trace));
if (match != null) {
tlayout.setStyle(new TextStyle(null, null, matchColor),
match.x, match.y + match.x - 1);
}
}
tlayout.draw(event.gc, event.x + getMaxSize(), event.y);
}
protected int getMaxSize() {
return 16;
}
protected abstract RenderInfo getRenderInfo(Object trace);
protected abstract String getImplicitFilterString(Object trace);
protected abstract Image getImage(Object trace);
protected abstract String getName(Object o1);
private boolean isImportTrace(String traceName) {
if (traceName.equals("require_once()")
|| traceName.equals("include_once()")
|| traceName.equals("require()")
|| traceName.equals("include()")) {
return true;
}
return false;
}
private void createColumns() {
nameColumn = new TreeColumn(viewer.getTree(), getTitleAlignment());
nameColumn.setText(getTitle());
new TreeSortController(viewer, nameColumn, new Comparator<Object>() {
public int compare(Object o1, Object o2) {
return getName(o1).compareTo(getName(o2));
}
}, true);
GC gc = new GC(owner);
layout.setColumnData(nameColumn, new ColumnWeightData(1, 200, true));
for (final DataColumn column : config.getColumns()) {
Widget createColumn = createColumn(column);
int ms = Math.max(column.getSizeChar(), column.getName().length()) + 1;
int another = (gc.getFontMetrics().getAverageCharWidth() + 1) * ms;
layout.setColumnData(createColumn, new ColumnPixelData(another));
TreeSortController treeSortController = new TreeSortController(
viewer, (TreeColumn) createColumn,
new Comparator<Object>() {
public int compare(Object o1, Object o2) {
return column.compare(o1, o2);
}
}, true);
}
new Locking(viewer.getTree(), new int[0]);
columnSizes = new int[viewer.getTree().getColumnCount()];
for (int a = 0; a < columnSizes.length; a++) {
final int b = a;
viewer.getTree().getColumn(a).addListener(SWT.Resize,
new Listener() {
public void handleEvent(Event event) {
columnSizes[b] = viewer.getTree().getColumn(b)
.getWidth();
}
});
}
gc.dispose();
}
protected int getTitleAlignment() {
return SWT.CENTER;
}
protected String getTitle() {
return "Name";
}
private Widget createColumn(DataColumn column) {
TreeColumn c = new TreeColumn((Tree) viewer.getControl(),
getTitleAlignment());
c.setText(column.getName());
c.setResizable(true);
c.setMoveable(true);
return c;
}
public void refresh() {
owner.setRedraw(false);
if (viewer != null) {
try {
viewer.setContentProvider(new ITreeContentProvider() {
public Object[] getChildren(Object parentElement) {
return new Object[] {};
}
public Object getParent(Object element) {
return null;
}
public boolean hasChildren(Object element) {
return false;
}
public Object[] getElements(Object inputElement) {
return new Object[] {};
}
public void dispose() {
}
public void inputChanged(Viewer viewer, Object oldInput,
Object newInput) {
}
});
viewer.setContentProvider(new DeferedContentProvider(
(ITreeContentProvider) config.getContentProvider()));
} catch (Exception e) {
}
}
owner.setRedraw(true);
}
ArrayList<ISelectionChangedListener> listeners = new ArrayList<ISelectionChangedListener>();
public ISelectionProvider getSelectionProvider() {
return new ISelectionProvider() {
public void addSelectionChangedListener(
ISelectionChangedListener listener) {
listeners.add(listener);
}
public ISelection getSelection() {
if (viewer != null) {
return viewer.getSelection();
}
return null;
}
public void removeSelectionChangedListener(
ISelectionChangedListener listener) {
listeners.remove(listener);
}
public void setSelection(ISelection selection) {
if (viewer != null) {
viewer.setSelection(selection);
}
}
};
}
public TreeViewer getTreeViewer() {
return viewer;
}
}