// ============================================================================ // // Copyright (C) 2006-2012 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.core.ui.context; import java.util.ArrayList; import java.util.Collections; import java.util.List; import org.eclipse.jface.layout.GridDataFactory; import org.eclipse.jface.layout.GridLayoutFactory; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.viewers.CellEditor; import org.eclipse.jface.viewers.ICellEditorListener; import org.eclipse.jface.viewers.ITableLabelProvider; import org.eclipse.jface.viewers.TextCellEditor; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.jface.viewers.Viewer; import org.eclipse.jface.viewers.ViewerSorter; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.TreeEditor; 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.Control; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Text; import org.eclipse.swt.widgets.ToolBar; import org.eclipse.swt.widgets.ToolItem; import org.eclipse.swt.widgets.Tree; import org.eclipse.swt.widgets.TreeColumn; import org.eclipse.swt.widgets.TreeItem; import org.talend.commons.ui.runtime.image.ImageProvider; import org.talend.commons.ui.swt.tooltip.AbstractTreeTooltip; import org.talend.core.language.ECodeLanguage; import org.talend.core.language.LanguageManager; import org.talend.core.model.metadata.types.PerlTypesManager; import org.talend.core.model.process.IContext; import org.talend.core.model.process.IContextManager; import org.talend.core.model.process.IContextParameter; import org.talend.core.model.utils.ContextParameterUtils; import org.talend.core.prefs.ITalendCorePrefConstants; import org.talend.core.runtime.i18n.Messages; import org.talend.core.ui.context.model.ContextValueErrorChecker; import org.talend.core.ui.context.model.ContextViewerProvider; import org.talend.core.ui.context.model.table.ContextTableCellModifier; import org.talend.core.ui.context.model.table.ContextTableConstants; import org.talend.core.ui.context.model.table.GroupByNothingTableProvider; import org.talend.core.ui.context.model.table.GroupBySourceTableProvider; /** * DOC zwang class global comment. Detailled comment <br/> * */ public class ContextTableValuesComposite extends AbstractContextTabEditComposite { public static final int CONTEXT_COLUMN_WIDTH = 200; private TreeViewer viewer; private ContextViewerProvider provider; private IContextModelManager modelManager = null; private ContextTableCellModifier cellModifier; private DefaultCellEditorFactory cellFactory; private ConfigureContextAction configContext; private ToolItem contextConfigButton; private CellEditor[] cellEditors; private ContextValueErrorChecker valueChecker; private static final int VALUES_INDEX = 1; /** * Constructor. * * @param parent * @param style */ public ContextTableValuesComposite(Composite parent, IContextModelManager manager) { super(parent, SWT.NONE); modelManager = manager; cellFactory = new DefaultCellEditorFactory(this); this.setBackground(parent.getBackground()); this.setLayout(GridLayoutFactory.swtDefaults().spacing(0, 0).create()); initializeUI(); } /** * zwang Comment method "initializeUI". * * @param viewer */ private void initializeUI() { final ToolBar toolBar = new ToolBar(this, SWT.FLAT | SWT.NO_BACKGROUND); GridDataFactory.swtDefaults().align(SWT.RIGHT, SWT.TOP).applyTo(toolBar); createToolBar(toolBar); viewer = new TreeViewer(this, SWT.FULL_SELECTION | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER); Tree tree = viewer.getTree(); tree.setHeaderVisible(true); tree.setLinesVisible(true); tree.setLayoutData(new GridData(GridData.FILL_BOTH)); createColumnsAndCellEditors(tree, getContexts()); tree.layout(); boolean isRepositoryContext = (modelManager instanceof ContextComposite) && ((ContextComposite) modelManager).isRepositoryContext(); cellModifier = new ContextTableCellModifier(this, isRepositoryContext); viewer.setCellModifier(cellModifier); provider = new ContextViewerProvider(); changeContextProvider(); final TreeEditor treeEditor = new TreeEditor(viewer.getTree()); // viewer.getTree().addMouseListener(new MouseAdapter() { // // @Override // public void mouseDown(MouseEvent e) { // if (modelManager.isReadOnly()) { // return; // } // Point pt = new Point(e.x, e.y); // if (e.x > 0 && e.x < (viewer.getTree().getColumnCount()) * ContextTableValuesComposite.CONTEXT_COLUMN_WIDTH) // { // createEditorListener(treeEditor, e.x / CONTEXT_COLUMN_WIDTH); // } // TreeItem item = viewer.getTree().getItem(pt); // // deactivate the current cell editor // if (cellEditor != null && !cellEditor.getControl().isDisposed()) { // deactivateCellEditor(treeEditor, e.x / CONTEXT_COLUMN_WIDTH); // } // if (item != null && !item.isDisposed()) { // Rectangle rect = item.getBounds(viewer.getTree().getColumnCount() - 1); // // if (e.x > 0 && e.x < (viewer.getTree().getColumnCount()) * ContextTableValuesComposite.CONTEXT_COLUMN_WIDTH) // { // handleSelect(item, viewer.getTree(), treeEditor, viewer.getTree().getColumnCount() - 1, e.x // / CONTEXT_COLUMN_WIDTH); // } // } // // } // }); valueChecker = new ContextValueErrorChecker(viewer); if (LanguageManager.getCurrentLanguage() == ECodeLanguage.PERL) { createTreeTooltip(tree); } } /** * cli Comment method "changeContextProvider". */ private void changeContextProvider() { boolean groupBySource = false; IPreferenceStore preferenceStore = getPreferenceStore(); if (preferenceStore != null) { groupBySource = preferenceStore.getBoolean(ITalendCorePrefConstants.CONTEXT_GROUP_BY_SOURCE); } if (groupBySource) { provider.setProvider(new GroupBySourceTableProvider(this)); } else { provider.setProvider(new GroupByNothingTableProvider(this)); } viewer.setLabelProvider(provider); viewer.setContentProvider(provider); addSorter(viewer); } /** * bqian Comment method "createTreeTooltip". * * @param tree */ protected void createTreeTooltip(final Tree tree) { new AbstractTreeTooltip(tree) { /* * (non-Javadoc) * * @see * org.talend.commons.ui.swt.tooltip.AbstractTreeTooltip#getTooltipContent(org.eclipse.swt.widgets.TreeItem) */ @Override public String getTooltipContent(TreeItem item) { String property = ""; //$NON-NLS-1$ if (properties != null && properties.length > VALUES_INDEX) { property = properties[VALUES_INDEX]; } IContextParameter para = cellModifier.getRealParameter(property, item.getData()); if (para.getType().equalsIgnoreCase(PerlTypesManager.STRING)) { return Messages.getString("PromptDialog.stringTip"); //$NON-NLS-1$ } return null; } }; } private void addSorter(final TreeViewer viewer2) { final Tree table = viewer2.getTree(); Listener sortListener = new Listener() { private int direction = 1; public void handleEvent(Event e) { final TreeColumn column = (TreeColumn) e.widget; if (column == table.getSortColumn()) { direction = -direction; } if (direction == 1) { table.setSortDirection(SWT.UP); } else { table.setSortDirection(SWT.DOWN); } table.setSortColumn(column); viewer2.setSorter(new ViewerSorter() { int index = 0; @Override public void sort(Viewer viewer, Object[] elements) { boolean found = false; // find the sort column index for (index = 0; index < table.getColumns().length; index++) { if (table.getColumn(index) == table.getSortColumn()) { found = true; break; } } if (!found) { index = 0; // first one as default } super.sort(viewer, elements); } @Override public int compare(Viewer viewer, Object e1, Object e2) { ITableLabelProvider labelProvider = (ITableLabelProvider) viewer2.getLabelProvider(); String columnText = labelProvider.getColumnText(e1, index) != null ? labelProvider.getColumnText(e1, index) : ""; //$NON-NLS-1$ String columnText2 = labelProvider.getColumnText(e2, index) != null ? labelProvider.getColumnText(e2, index) : ""; //$NON-NLS-1$ return getComparator().compare(columnText, columnText2) * direction; } }); } }; table.getColumn(0).addListener(SWT.Selection, sortListener); if (getContexts().size() > 0) { for (int i = 0; i < getContexts().size(); i++) { table.getColumn(i + 1).addListener(SWT.Selection, sortListener); } } table.setSortColumn(table.getColumn(0)); table.setSortDirection(SWT.UP); } private void activateCellEditor(final TreeItem item, final Tree tree, final TreeEditor treeEditor, int columnIndex, int column) { IContextParameter para = cellModifier.getRealParameter(properties[column], item.getData()); if (para == null) { return; } valueChecker.checkErrors(item, column, para); if (!para.isBuiltIn()) { // not built-in return; } cellEditor = cellFactory.getCustomCellEditor(para, tree); if (cellEditor == null) { // unable to create the editor return; } // activate the cell editor cellEditor.activate(); // if the cell editor has no control we can stop now Control control = cellEditor.getControl(); if (control == null) { cellEditor.deactivate(); cellEditor = null; return; } Text textControl = valueChecker.getTextControl(control); if (textControl != null) { if (ContextParameterUtils.isPasswordType(para)) { textControl.setEchoChar('*'); } else { textControl.setEchoChar((char) 0); } } valueChecker.register(control); // add our editor listener cellEditor.addListener(createEditorListener(treeEditor, column)); // set the layout of the tree editor to match the cell editor CellEditor.LayoutData layout = cellEditor.getLayoutData(); treeEditor.horizontalAlignment = layout.horizontalAlignment; treeEditor.grabHorizontal = layout.grabHorizontal; treeEditor.minimumWidth = layout.minimumWidth; treeEditor.setEditor(control, item, column); // give focus to the cell editor cellEditor.setFocus(); } protected void handleSelect(final TreeItem item, final Tree tree, final TreeEditor treeEditor, int columnIndex, int column) { // get the new selection activateCellEditor(item, tree, treeEditor, columnIndex, column); } public boolean isGroupBySource() { boolean isRepositoryContext = false; if (modelManager != null) { isRepositoryContext = (modelManager instanceof ContextComposite) && ((ContextComposite) modelManager).isRepositoryContext(); } boolean value = getPreferenceStore().getBoolean(ITalendCorePrefConstants.CONTEXT_GROUP_BY_SOURCE); return value && !isRepositoryContext; } private void deactivateCellEditor(final TreeEditor tableEditor, int columnIndex) { tableEditor.setEditor(null, null, columnIndex); if (cellEditor != null) { Control control = cellEditor.getControl(); if (control != null) { valueChecker.unregister(control); } cellEditor.deactivate(); cellEditor.removeListener(editorListener); cellEditor = null; } } private ICellEditorListener createEditorListener(final TreeEditor tableEditor, final int columnIndex) { editorListener = new ICellEditorListener() { public void cancelEditor() { deactivateCellEditor(tableEditor, columnIndex); } public void editorValueChanged(boolean oldValidState, boolean newValidState) { } public void applyEditorValue() { editing = true; } }; return editorListener; } /** * bqian Comment method "createMenuBar". * * @param toolBar */ private void createToolBar(final ToolBar toolBar) { configContext = new ConfigureContextAction(modelManager, this.getShell()); contextConfigButton = new ToolItem(toolBar, SWT.PUSH); contextConfigButton.setImage(ImageProvider.getImage(configContext.getImageDescriptor())); contextConfigButton.setToolTipText(configContext.getText()); contextConfigButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { configContext.run(); } }); } @Override public void setEnabled(boolean enabled) { configContext.setEnabled(enabled); } private ICellEditorListener editorListener; private CellEditor cellEditor; private String[] properties; private boolean editing; /** * bqian Comment method "getContexts". * * @return */ public List<IContext> getContexts() { List<IContext> contexts = new ArrayList<IContext>(); IContextManager cm = modelManager.getContextManager(); if (cm != null) { contexts = cm.getListContext(); } return contexts; } public IContextModelManager getContextModelManager() { return this.modelManager; } public TreeViewer getViewer() { return this.viewer; } public ContextValueErrorChecker getValueChecker() { return this.valueChecker; } @Override public void refresh() { if (editing) { viewer.refresh(); editing = false; return; } final Tree tree = viewer.getTree(); TreeColumn[] columns = tree.getColumns(); for (TreeColumn tableColumn : columns) { tableColumn.dispose(); } List<IContext> contextList = getContexts(); createColumnsAndCellEditors(tree, contextList); changeContextProvider(); List<IContextParameter> contextTemplate = ContextTemplateComposite.computeContextTemplate(contextList); viewer.setInput(contextTemplate); viewer.expandAll(); contextConfigButton.setEnabled(!modelManager.isReadOnly()); // (feature 1597) checkItemValueErrors(tree.getItems()); } /** * cli Comment method "createColumnsAndCellEditors". */ private void createColumnsAndCellEditors(final Tree tree, List<IContext> contextList) { TreeColumn column = new TreeColumn(tree, SWT.NONE); column.setText(Messages.getString("ConextTableValuesComposite.nameLabel")); //$NON-NLS-1$ column.setWidth(ContextTableValuesComposite.CONTEXT_COLUMN_WIDTH); for (IContext context : contextList) { column = new TreeColumn(tree, SWT.NONE); column.setText(context.getName()); column.setWidth(ContextTableValuesComposite.CONTEXT_COLUMN_WIDTH); } cellEditors = new CellEditor[getContexts().size() + 1]; for (int i = 0; i < getContexts().size() + 1; i++) { if (i == 0) { cellEditors[i] = null; } else { cellEditors[i] = new TextCellEditor(tree); } } properties = new String[contextList.size() + 1]; properties[0] = ContextTableConstants.COLUMN_NAME_PROPERTY; for (int i = 0; i < contextList.size(); i++) { properties[i + 1] = contextList.get(i).getName(); } viewer.setColumnProperties(properties); viewer.setCellEditors(cellEditors); } public String[] getColumnProperties() { return this.properties; } private void checkItemValueErrors(final TreeItem[] items) { if (items == null) { return; } for (TreeItem item : items) { for (int i = 1; i < viewer.getColumnProperties().length; i++) { IContextParameter para = cellModifier.getRealParameter((String) viewer.getColumnProperties()[i], item.getData()); if (para != null && para instanceof IContextParameter) { valueChecker.checkErrors(item, i, para); } } checkItemValueErrors(item.getItems()); } } /** * Clear the data in this viewer. * * @param jobContextManager2 */ public void clear() { final Tree tree = viewer.getTree(); TreeColumn[] columns = tree.getColumns(); for (TreeColumn tableColumn : columns) { tableColumn.dispose(); } viewer.setInput(Collections.EMPTY_LIST); } /** * DOC zli ContextCompare class global comment. Detailled comment */ private class ContextCompare implements java.util.Comparator<IContext> { /* * (non-Javadoc) * * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object) */ public int compare(IContext o1, IContext o2) { String name1 = o1.getName().toUpperCase(); String name2 = o2.getName().toUpperCase(); return name1.compareTo(name2); } } }