/******************************************************************************* * Copyright (c) 2007 Exadel, Inc. and Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is 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: * Exadel, Inc. and Red Hat, Inc. - initial API and implementation ******************************************************************************/ package org.jboss.tools.common.model.ui.objecteditor; import java.util.HashSet; import java.util.Set; import org.eclipse.jface.viewers.ColumnLayoutData; import org.eclipse.jface.viewers.ColumnWeightData; import org.eclipse.jface.viewers.TableLayout; import org.eclipse.jface.viewers.TableViewer; import org.eclipse.swt.SWT; import org.eclipse.swt.SWTException; import org.eclipse.swt.events.ControlAdapter; import org.eclipse.swt.events.ControlEvent; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableColumn; import org.eclipse.swt.widgets.TableItem; import org.jboss.tools.common.model.ui.ModelUIPlugin; public class XTable { protected XTableProvider provider; protected XTableImageProvider imageProvider; protected int style = SWT.FULL_SELECTION | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER; protected boolean autoResizeColumns = false; protected boolean lock = false; protected TableViewer tv; protected boolean isHeaderVisible = true; public void dispose() { if (provider!=null) provider.dispose(); provider = null; if (imageProvider!=null) imageProvider.dispose(); imageProvider = null; tv = null; } public void setAutoResize(boolean b) { autoResizeColumns = b; } public void setTableProvider(XTableProvider provider) { this.provider = provider; if(provider instanceof XTableImageProvider) { imageProvider = (XTableImageProvider)provider; } } public TableViewer getViewer() { return tv; } public void setMultiSelected() { style |= SWT.MULTI; } public Control createControl(Composite parent) { return createControl(parent, style); } public Control createControl(Composite parent, int style) { this.style = style; Table table = new Table(parent, style); int k = provider.getColumnCount(); TableLayout layout = new TableLayout(); table.setLayout(layout); int prefferedColumnWidth = 0; for (int i = 0; i < k; i++) { prefferedColumnWidth += provider.getWidthHint(i); } widths = new int[k]; for (int i = 0; i < k; i++) { widths[i] = provider.getWidthHint(i)*100/prefferedColumnWidth; } ColumnLayoutData layoutData; for (int i = 0; i < k; i++) { TableColumn c = new TableColumn(table, SWT.NONE); c.setText(provider.getColumnName(i)); layoutData = new ColumnWeightData(widths[i], true); layout.addColumnData(layoutData); } table.setHeaderVisible(isHeaderVisible); table.setLinesVisible(true); tv = new TableViewer(table); if(k < 3 || autoResizeColumns) { table.addControlListener(new Resize(table)); } return table; } public void updateLayout() { if(resizeLock) return; Table table = getTable(); if(table == null || table.isDisposed()) return; resizeLock = true; try { updateLayoutInternal(table); } finally { resizeLock = false; } } private void updateLayoutInternal(Table table) { int k = provider.getColumnCount(); int[] newWidth = new int[k]; int delta = 0; if(table.isVisible()) { int w = table.getClientArea().width - 1; int cw = 0, hs = 0; for (int i = 0; i < table.getColumnCount(); i++) { cw += table.getColumn(i).getWidth(); hs += getWidthHint(i); } for (int i = 0; i < table.getColumnCount(); i++) { TableColumn c = table.getColumn(i); int dw = (w - cw) * getWidthHint(i) / hs; newWidth[i] = c.getWidth() + dw; delta += Math.abs(dw); } if(delta < 5) newWidth = widths; } else { newWidth = widths; } for (int i = 0; i < k; i++) { if(newWidth[i] < 0) return; } TableLayout layout = new TableLayout(); for (int i = 0; i < k; i++) { layout.addColumnData(new ColumnWeightData(newWidth[i], true)); } widths = newWidth; table.setLayout(layout); table.layout(); } int[] widths = null; protected int getWidthHint(int i) { return (widths == null || widths.length < 2 || widths[i] == 0) ? 10 : widths[i]; } public Control getControl() { return getTable(); } public Table getTable() { return (tv == null) ? null : tv.getTable(); } public boolean isActive() { Table t = getTable(); return t != null && !t.isDisposed(); } private boolean resizeLock = false; public synchronized void update() { Table table = getTable(); if(table == null || table.isDisposed()) return; int r = table.getSelectionIndex(); TableItem item = null; resizeLock = true; for (int i = 0; i < provider.getRowCount(); i++) { if(table.getItemCount() > i) { item = table.getItem(i); } else { item = new TableItem(table, SWT.BORDER, i); } String[] vs = new String[table.getColumnCount()]; for (int j = 0; j < vs.length; j++) { vs[j] = toVisualValue(provider.getValueAt(i, j)); } item.setText(vs); if(imageProvider != null) { item.setImage(imageProvider.getImage(i)); } Object data = provider.getDataAt(i); if(data != null) item.setData(data); Color color = provider.getColor(i); if(color != null) item.setForeground(color); } if(table.getTopIndex() > provider.getRowCount()) { int ti = provider.getRowCount() - 20; if(ti < 0) ti = 0; table.setTopIndex(ti); } table.remove(provider.getRowCount(), table.getItemCount()- 1); if(r >= 0) try { table.setSelection(r); } catch (SWTException e) { //ignore } resizeLock = false; } public static String toVisualValue(String v) { if(v == null) return ""; //$NON-NLS-1$ if(v.indexOf('\n') >= 0) v = v.replace('\n', ' '); if(v.indexOf('\t') >= 0) v = v.replace('\t', ' '); if(v.indexOf('\r') >= 0) v = v.replace('\r', ' '); return v; } public int getSelectionIndex() { return getTable().getSelectionIndex(); } public void setSelection(int i) { getTable().setSelection(i); } protected Set<String> getKeys() { Set<String> set = new HashSet<String>(); Table table = getTable(); int c = (table == null || table.isDisposed()) ? 0 : table.getItemCount(); for (int i = 0; i < c; i++) set.add(getTable().getItem(i).getText(0)); return set; } protected int getAddedKey(Set set) { Table table = getTable(); if(table == null || table.isDisposed()) return -1; int c = table.getItemCount(); for (int i = 0; i < c; i++) if(!set.contains(getTable().getItem(i).getText(0))) return i; return -1; } class Resize extends ControlAdapter { Resize(Table table) { table.addControlListener(this); } public void controlResized(ControlEvent e) { updateColumnWidth(); } private void updateColumnWidth() { updateLayout(); } } public void setHeaderVisible(boolean b) { if(isHeaderVisible == b) return; isHeaderVisible = b; if(isActive()) getTable().setHeaderVisible(isHeaderVisible); } }