// ============================================================================ // // 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.tableviewer; import java.beans.PropertyChangeListener; import java.beans.PropertyChangeSupport; import java.util.Iterator; import java.util.List; import org.eclipse.jface.viewers.CellEditor; import org.eclipse.jface.viewers.ColumnPixelData; import org.eclipse.jface.viewers.IBaseLabelProvider; import org.eclipse.jface.viewers.IContentProvider; import org.eclipse.jface.viewers.TableLayout; import org.eclipse.jface.viewers.TableViewer; import org.eclipse.jface.viewers.ViewerComparator; import org.eclipse.swt.SWT; import org.eclipse.swt.events.KeyEvent; import org.eclipse.swt.events.KeyListener; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableColumn; import org.talend.core.model.metadata.builder.connection.MetadataColumn; import org.talend.dataquality.PluginConstant; import org.talend.dataquality.analysis.Analysis; import org.talend.dataquality.record.linkage.ui.action.RemoveMatchKeyDefinitionAction; import org.talend.dataquality.record.linkage.ui.i18n.internal.DefaultMessagesImpl; import org.talend.dataquality.record.linkage.ui.section.GroupStatisticsRowCompartor; import org.talend.dataquality.record.linkage.utils.MatchAnalysisConstant; import org.talend.dataquality.rules.KeyDefinition; /** * created by zshen on Aug 6, 2013 Detailled comment * */ public abstract class AbstractMatchAnalysisTableViewer<T> extends TableViewer { private static final int DEFAULT_TABLE_HEIGHT_HIME = 130; protected Table innerTable = null; boolean isAddColumn = true; protected PropertyChangeSupport listeners = new PropertyChangeSupport(this); /** * DOC zshen MatchAnalysisTabveViewer constructor comment. * * @param parent * @param style */ public AbstractMatchAnalysisTableViewer(Composite parent, int style, boolean isAddColumn) { super(parent, style); innerTable = this.getTable(); this.isAddColumn = isAddColumn; initListener(); } /** * DOC zshen Comment method "initListener". */ private void initListener() { innerTable.addKeyListener(new KeyListener() { @Override public void keyPressed(KeyEvent e) { char character = e.character; if (SWT.DEL == character) { new RemoveMatchKeyDefinitionAction<T>(AbstractMatchAnalysisTableViewer.this).run(); listeners.firePropertyChange(MatchAnalysisConstant.ISDIRTY_PROPERTY, true, false); } } @Override public void keyReleased(KeyEvent e) { // don't need to implement is now } }); } public void initTable(List<String> headers) { initTable(headers, null, false); } /** * * DOC zshen Comment method "initTable". * * @param headers the name of column * @param columnMap all of columns which can be used by current Table * @param pixelDataOfHeaders the width of the column */ public void initTable(List<String> headers, List<MetadataColumn> columnMap, boolean withSorter) { TableLayout tLayout = new TableLayout(); innerTable.setLayout(tLayout); innerTable.setHeaderVisible(true); innerTable.setLinesVisible(true); GridData gd = new GridData(GridData.FILL_BOTH); innerTable.setLayoutData(gd); for (int index = 0; index < headers.size(); index++) { final int sortIndex = index; String columnLabel = getInternationalizedLabel(headers.get(index)); if (columnLabel != null) { if (columnLabel.length() == 1) { columnLabel = columnLabel + PluginConstant.SPACE_STRING + PluginConstant.SPACE_STRING; } tLayout.addColumnData(new ColumnPixelData(columnLabel.length() * getHeaderDisplayWeight(index))); final TableColumn tableColumn = new TableColumn(innerTable, SWT.LEFT); tableColumn.setText(columnLabel); if (withSorter) { final ViewerComparator comparator = getComparator(); tableColumn.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { ((GroupStatisticsRowCompartor) comparator).setColumn(sortIndex); int dir = getTable().getSortDirection(); if (getTable().getSortColumn() == tableColumn) { dir = dir == SWT.UP ? SWT.DOWN : SWT.UP; } else { dir = SWT.DOWN; } getTable().setSortDirection(dir); getTable().setSortColumn(tableColumn); refresh(); } }); } } } CellEditor[] editors = getCellEditor(headers, columnMap); // add menu addContextMenu(); AbstractMatchCellModifier<T> cellModifier = getTableCellModifier(); if (cellModifier != null) { cellModifier.setColumnMap(columnMap); this.setCellModifier(cellModifier); } this.setCellEditors(editors); this.setColumnProperties(headers.toArray(new String[headers.size()])); this.setContentProvider(getTableContentProvider()); this.setLabelProvider(getTableLabelProvider()); GridData tableGD = new GridData(GridData.FILL_BOTH); tableGD.heightHint = getTableHeightHint(); innerTable.setLayoutData(tableGD); } private String getInternationalizedLabel(String str) { // if the str is %, just return it, need not to do internationalization return MatchAnalysisConstant.PERCENTAGE.equals(str) ? str : DefaultMessagesImpl.getString(str); } /** * * @return */ protected int getTableHeightHint() { return DEFAULT_TABLE_HEIGHT_HIME; // 130 by defaut. } /** * DOC zshen Comment method "selectAllItem". * * @param bkdList */ public void selectAllItem(List<KeyDefinition> bkdList) { this.setSelectionToWidget(bkdList, true); } /* * (non-Javadoc) * * @see org.eclipse.jface.viewers.ColumnViewer#update(java.lang.Object, java.lang.String[]) */ @Override public void update(Object element, String[] properties) { super.update(element, properties); listeners.firePropertyChange(MatchAnalysisConstant.ISDIRTY_PROPERTY, true, false); } public void noticeColumnSelectChange() { listeners.firePropertyChange(MatchAnalysisConstant.MATCH_RULE_TAB_SWITCH, true, false); } /* * (non-Javadoc) * * @see org.eclipse.jface.viewers.AbstractTableViewer#remove(java.lang.Object) */ @Override public void remove(Object element) { super.remove(element); listeners.firePropertyChange(MatchAnalysisConstant.ISDIRTY_PROPERTY, true, false); } /** * DOC zhao Comment method "addContextMenu". */ abstract public void addContextMenu(); /** * Getter for isAddColumn. * * @return the isAddColumn */ public boolean isAddColumn() { return this.isAddColumn; } public void addPropertyChangeListener(PropertyChangeListener listener) { listeners.addPropertyChangeListener(listener); } public void removePropertyChangeListener(PropertyChangeListener listener) { listeners.addPropertyChangeListener(listener); } /** * DOC zshen Comment method "getDisplayWeight". * * @return */ abstract protected int getHeaderDisplayWeight(); /** * get the header display weight according to the index. * * @param index * @return */ protected int getHeaderDisplayWeight(int index) { return getHeaderDisplayWeight(); } /** * DOC zshen Comment method "getTableLabelProvider". * * @return */ abstract protected IBaseLabelProvider getTableLabelProvider(); /** * DOC zshen Comment method "getTableContentProvider". * * @return */ abstract protected IContentProvider getTableContentProvider(); /** * DOC zshen Comment method "getTableCellModifier". * * @return */ abstract protected AbstractMatchCellModifier<T> getTableCellModifier(); /** * DOC zshen Comment method "getCellEditor". * * @param headers * @return */ abstract protected CellEditor[] getCellEditor(List<String> headers, List<MetadataColumn> columnMap); /** * * add new Element * * @param columnName the name of column * @param analysis the context of this add operation perform on. */ abstract public boolean addElement(String columnName, Analysis analysis); /** * * add new Element * * @param columnName the name of column * @param analysis the context of this add operation perform on. */ public boolean addElement(String columnName, List<T> keyList) { T keyDef = createNewKeyDefinition(columnName); keyList.add(keyDef); add(keyDef); return true; } /** * * add new Element * * @param columnName the name of column * @param analysis the context of this add operation perform on. */ public boolean addElement(T keyDef, List<T> keyList) { keyList.add(keyDef); add(keyDef); return true; } /** * create a new KeyDefinition * * @param columnName * @return */ abstract protected T createNewKeyDefinition(String columnName); /** * remove Element * * @param columnName the name of column */ abstract public void removeElement(String columnName, List<T> keyList); /** * remove Element * * @param columnName the element of column */ public void removeElement(T keyDef, List<T> keyList) { Iterator<T> keysIterator = keyList.iterator(); while (keysIterator.hasNext()) { T tmpKeyDef = keysIterator.next(); if (keyDef.equals(tmpKeyDef)) { keyList.remove(keyDef); // Update table view. remove(keyDef); listeners.firePropertyChange(MatchAnalysisConstant.MATCH_RULE_TAB_SWITCH, true, false); break; } } } /** * * move up element * * @param keyDef * @param matchRuleDef */ public void moveUpElement(T keyDef, List<T> keyList) { Iterator<T> keysIterator = keyList.iterator(); while (keysIterator.hasNext()) { T tmpKeyDef = keysIterator.next(); if (keyDef.equals(tmpKeyDef)) { int indexForElement = indexForElement(tmpKeyDef); if (indexForElement - 2 >= 0) { // modify model moveUpFromModel(keyDef, keyList, indexForElement); // modify table viewer remove(keyDef); insert(keyDef, indexForElement - 1); } break; } } } /** * DOC zhao Comment method "moveFromModel". * * @param keyDef * @param keyList * @param indexForElement */ protected void moveUpFromModel(T keyDef, List<T> keyList, int indexForElement) { keyList.remove(keyDef); keyList.add(indexForElement - 2, keyDef); } /** * * move down element * * @param keyDef * @param matchRuleDef */ public void moveDownElement(T keyDef, List<T> keyList) { Iterator<T> keysIterator = keyList.iterator(); while (keysIterator.hasNext()) { T tmpKeyDef = keysIterator.next(); if (keyDef.equals(tmpKeyDef)) { int indexForElement = indexForElement(tmpKeyDef); if (indexForElement < keyList.size()) { moveDownFromModel(keyDef, keyList, indexForElement); // modify table viewer remove(keyDef); insert(keyDef, indexForElement + 1); } break; } } } /** * DOC zhao Comment method "moveDownFromModel". * * @param keyDef * @param keyList * @param indexForElement */ protected void moveDownFromModel(T keyDef, List<T> keyList, int indexForElement) { // modify model keyList.remove(keyDef); if (indexForElement == keyList.size()) { keyList.add(keyDef); } else { keyList.add(indexForElement, keyDef); } } }