// ============================================================================ // // Copyright (C) 2006-2016 Talend Inc. - www.talend.com // // This source code is available under agreement available at // %InstallDIR%\features\org.talend.rcp.branding.%PRODUCTNAME%\%PRODUCTNAME%license.txt // // You should have received a copy of the agreement // along with this program; if not, write to Talend SA // 9 rue Pages 92150 Suresnes, France // // ============================================================================ package org.talend.dataquality.record.linkage.ui.composite.table; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.TreeMap; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.eclipse.jface.viewers.ArrayContentProvider; import org.eclipse.jface.viewers.ITableColorProvider; import org.eclipse.jface.viewers.ITableLabelProvider; import org.eclipse.jface.viewers.LabelProvider; import org.eclipse.jface.viewers.TableViewer; import org.eclipse.jface.viewers.TableViewerColumn; import org.eclipse.nebula.widgets.nattable.util.GUIHelper; import org.eclipse.swt.SWT; import org.eclipse.swt.events.ControlAdapter; import org.eclipse.swt.events.ControlEvent; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Label; import org.talend.core.service.IMatchRuleUIService; import org.talend.dataquality.PluginConstant; import org.talend.dataquality.record.linkage.ui.MatchRuleUIService; import org.talend.dataquality.record.linkage.ui.composite.utils.ImageLib; import org.talend.dataquality.record.linkage.ui.i18n.internal.DefaultMessagesImpl; /** * DOC Administrator class global comment. Detailled comment */ public class MatchRuleDataTable extends Composite { private static final Log log = LogFactory.getLog(MatchRuleDataTable.class); private List<String[]> viewData = new ArrayList<String[]>(); private List<String[]> displayViewData; // TDQ-8774 change the type of GID from int to string private List<String> disGIDList = new ArrayList<String>(); private final Map<String, Integer> itemCount = new HashMap<String, Integer>(); protected TableViewer dataViewer; public static final Color[] COLOR_LIST = MatchRuleColorRegistry.getColorsForSwt(); private int gidColumn, grpSizeColumn, masterColumn; private int page = 0; private int rowCount = 10; private int totalPage = 0; private String[] viewColumn; private Button firstBtn, previousBtn, nextBtn, lastBtn; private Label index; // TDQ-9297: Set the default value of "hide groups less than" to 2 instead of 1 private int disGroupSize = PluginConstant.HIDDEN_GROUP_LESS_THAN_DEFAULT; private List<Integer> groupSizeList = new ArrayList<Integer>(); private final ControlAdapter matchRuleTableResizeListener = new MatchRuleTableResizeListener(); private IMatchRuleUIService uiService = null; /** * Getter for uiService. * * @return the uiService */ public IMatchRuleUIService getUiService() { return this.uiService; } /** * Sets the uiService. * * @param uiService the uiService to set */ public void setUiService(IMatchRuleUIService uiService) { this.uiService = uiService; } /** * DOC yyi DataTable constructor comment. */ public MatchRuleDataTable(Composite parent, String[] viewColumn) { super(parent, SWT.NONE); GridLayout layout = new GridLayout(); layout.marginHeight = 0; layout.marginWidth = 0; this.setLayout(layout); this.viewColumn = viewColumn; initTableData(); } private void intiTableData(List<String[]> viewData) { for (String[] value : viewData) { if (Boolean.valueOf(value[masterColumn])) { itemCount.put(value[gidColumn], Integer.parseInt(value[grpSizeColumn])); } } } public boolean initTableData() { // MOD yyi 2012-01-11 TDQ-4362:fix the bug when checking the distance detail option List<String> header = java.util.Arrays.asList(viewColumn); this.gidColumn = header.indexOf("GID"); //$NON-NLS-1$ this.grpSizeColumn = header.indexOf("GRP_SIZE"); //$NON-NLS-1$ this.masterColumn = header.indexOf("MASTER"); //$NON-NLS-1$ createTable(); createPagination(); if (this.getUiService() != null) { MatchRuleUIService service = (MatchRuleUIService) this.getUiService(); refresh(viewData, service.computeGroupSize2FreqMap(viewData, header)); } return true; } /** * DOC yyi Comment method "createTable". */ private void createTable() { GridLayout layout = new GridLayout(); Composite composite = new Composite(this, SWT.BORDER); layout.marginHeight = 0; layout.marginWidth = 0; composite.setLayout(layout); composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, Boolean.TRUE, Boolean.TRUE)); dataViewer = new TableViewer(composite, SWT.FULL_SELECTION | SWT.NO_SCROLL | SWT.H_SCROLL | SWT.MULTI | SWT.BORDER); dataViewer.getTable().setHeaderVisible(true); dataViewer.getControl().setLayoutData(new GridData(GridData.FILL_BOTH)); for (String title : viewColumn) { TableViewerColumn column = new TableViewerColumn(dataViewer, SWT.NONE); column.getColumn().setText(title); column.getColumn().setWidth(150); column.getColumn().setMoveable(true); } dataViewer.setContentProvider(new ArrayContentProvider()); dataViewer.setLabelProvider(new DataLabelProvider()); dataViewer.getTable().addControlListener(matchRuleTableResizeListener); } private void reComputePageSize() { // resize rowcount int tableHeight = dataViewer.getTable().getClientArea().height; int itemHeight = dataViewer.getTable().getItemHeight(); rowCount = (int) Math.floor(tableHeight / itemHeight - 1); rowCount = rowCount < 1 ? 1 : rowCount; totalPage = (int) Math.ceil(1.0 * getDisplayViewData().size() / rowCount); // load page after resize page = 0; } /** * Getter for displayViewData. * * @return the displayViewData */ private List<String[]> getDisplayViewData() { if (this.displayViewData == null) { this.displayViewData = new ArrayList<String[]>(); } return this.displayViewData; } private List<String[]> filterDisViewData() { displayViewData = new ArrayList<String[]>(); for (String[] dataArray : viewData) { if (canDisplay(dataArray)) { displayViewData.add(dataArray); } } return displayViewData; } private boolean canDisplay(String[] dataArray) { try { if (getDisGIDList().contains(String.valueOf(dataArray[gidColumn]))) { return true; } if (getDisGroupSize() <= Integer.parseInt(dataArray[grpSizeColumn])) { getDisGIDList().add(String.valueOf(dataArray[gidColumn])); return true; } } catch (NumberFormatException e) { log.error(e, e); } return false; } /** * Getter for disGIDList. * * @return the disGIDList */ public List<String> getDisGIDList() { return this.disGIDList; } /** * Getter for disGroupSize. * * @return the disGroupSize */ private int getDisGroupSize() { return this.disGroupSize; } /** * Sets the disGroupSize. * * @param disGroupSize the disGroupSize to set */ public void setDisGroupSize(int disGroupSize) { this.disGroupSize = disGroupSize; } /** * DOC yyi Comment method "createPagination". */ private void createPagination() { GridLayout layout = new GridLayout(5, false); Composite pagination = new Composite(this, SWT.NONE); pagination.setLayout(layout); GridData data = new GridData(SWT.END, SWT.CENTER, true, false); pagination.setLayoutData(data); data = new GridData(); data.widthHint = 100; firstBtn = new Button(pagination, SWT.NONE); firstBtn.setText(DefaultMessagesImpl.getString("DataTable.first")); //$NON-NLS-1$ firstBtn.setLayoutData(data); firstBtn.addSelectionListener(new PageButtonAdapter(0)); previousBtn = new Button(pagination, SWT.NONE); previousBtn.setText(DefaultMessagesImpl.getString("DataTable.previous")); //$NON-NLS-1$ previousBtn.setLayoutData(data); previousBtn.addSelectionListener(new PageButtonAdapter(1)); nextBtn = new Button(pagination, SWT.NONE); nextBtn.setText(DefaultMessagesImpl.getString("DataTable.next")); //$NON-NLS-1$ nextBtn.setLayoutData(data); nextBtn.addSelectionListener(new PageButtonAdapter(2)); lastBtn = new Button(pagination, SWT.NONE); lastBtn.setText(DefaultMessagesImpl.getString("DataTable.last")); //$NON-NLS-1$ lastBtn.setLayoutData(data); lastBtn.addSelectionListener(new PageButtonAdapter(3)); index = new Label(pagination, SWT.NONE); } protected void loadPage(int page) { List<String[]> itemPage = new ArrayList<String[]>(); for (int i = page * rowCount; i < Math.min((page + 1) * rowCount, getDisplayViewData().size()); i++) { itemPage.add(getDisplayViewData().get(i)); } if (itemPage.size() >= 0) { // remove matchRuleTableResizeListener to avoid unHandle loop when H_SCORLL will be appear or disappear dataViewer.getTable().removeControlListener(matchRuleTableResizeListener); this.dataViewer.setInput(itemPage); dataViewer.getTable().addControlListener(matchRuleTableResizeListener); // ~ } updateButons(); } public void refresh(List<String[]> newViewData, TreeMap<Object, Long> groupSize2groupFrequency) { this.viewData = newViewData; initGroupSizeArray(groupSize2groupFrequency, getDisGroupSize()); clearDisGIDList(); filterDisViewData(); intiTableData(getDisplayViewData()); reComputePageSize(); loadPage(page); this.dataViewer.refresh(); } /** * DOC xqliu Comment method "buildGroupSizeArray". * * @param groupSize2groupFrequency * @param minGroupSize */ private void initGroupSizeArray(TreeMap<Object, Long> groupSize2groupFrequency, int minGroupSize) { groupSizeList.clear(); for (Object obj : groupSize2groupFrequency.keySet()) { int grpSize = Integer.valueOf(obj.toString()); if (grpSize >= minGroupSize) { groupSizeList.add(grpSize); } } Collections.sort(groupSizeList, new Comparator<Integer>() { @Override public int compare(Integer o1, Integer o2) { return o1 - o2; } }); } /** * DOC zshen Comment method "clearDisGIDList". */ private void clearDisGIDList() { getDisGIDList().clear(); } /** * DOC yyi DataTable class global comment. Detailled comment */ class DataLabelProvider extends LabelProvider implements ITableLabelProvider, ITableColorProvider { private static final String GRP_SIZE = "GRP_SIZE"; //$NON-NLS-1$ private Image masterImage = ImageLib.getImage(ImageLib.MASTER_IMAGE); @Override public Image getColumnImage(Object element, int columnIndex) { String isMaster = ((String[]) element)[masterColumn]; if (columnIndex == 0) { if (Boolean.parseBoolean(isMaster)) { return masterImage; } else { return null; } } else { return null; } } @Override public String getColumnText(Object element, int columnIndex) { if (GRP_SIZE.equals(viewColumn[columnIndex]) && "0".equals(((String[]) element)[columnIndex])) { //$NON-NLS-1$ return ""; //$NON-NLS-1$ } else { return ((String[]) element)[columnIndex]; } } Color textColor = GUIHelper.COLOR_BLACK; @Override public Color getForeground(Object element, int columnIndex) { String isMaster = ((String[]) element)[masterColumn]; if (Boolean.parseBoolean(isMaster)) { return GUIHelper.COLOR_BLACK; } else { return ImageLib.COLOR_GREY; } } @Override public org.eclipse.swt.graphics.Color getBackground(Object element, int columnIndex) { int grpSizeValue = getGrpSize(((String[]) element)[gidColumn]); return COLOR_LIST[Math.abs((grpSizeValue - 1) % COLOR_LIST.length)]; } private int getGrpSize(String grpId) { if (itemCount == null) { return 0; } return itemCount.get(grpId); } } protected void updateButons() { firstBtn.setEnabled(true); previousBtn.setEnabled(true); lastBtn.setEnabled(true); nextBtn.setEnabled(true); // When the first time the wizard is opened, the table is empty, the next and last button should be in disable // status. if (totalPage == 0 || 0 == page) { firstBtn.setEnabled(false); previousBtn.setEnabled(false); } if (totalPage == 0 || totalPage == page + 1) { lastBtn.setEnabled(false); nextBtn.setEnabled(false); } index.setText(DefaultMessagesImpl.getString("DataTable.index", (page + 1), (totalPage))); //$NON-NLS-1$ index.getParent().layout(); } /** * DOC yyi DataTable class global comment. Detailled comment */ class PageButtonAdapter extends SelectionAdapter { private final int type; public PageButtonAdapter(int type) { this.type = type; } /* * (non-Javadoc) * * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent) */ @Override public void widgetSelected(SelectionEvent e) { switch (type) { case 0: page = 0; break; case 1: if (page > 0) { page--; } break; case 2: if (page < totalPage) { page++; } break; case 3: // MOD yyi 2011-10-31 last page page = totalPage - 1; break; } loadPage(page); } } private class MatchRuleTableResizeListener extends ControlAdapter { /* * (non-Javadoc) * * @see org.eclipse.swt.events.ControlAdapter#controlResized(org.eclipse.swt.events.ControlEvent) */ @Override public void controlResized(ControlEvent e) { reComputePageSize(); loadPage(page); dataViewer.getTable().layout(); } } }