/******************************************************************************* * Copyright (c) 2004, 2007 Boeing. * All rights reserved. This program and the accompanying materials * are 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: * Boeing - initial API and implementation *******************************************************************************/ package org.eclipse.nebula.widgets.xviewer; import java.text.MessageFormat; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.logging.Level; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.IJobChangeEvent; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.core.runtime.jobs.JobChangeAdapter; import org.eclipse.jface.action.Action; import org.eclipse.jface.action.IToolBarManager; import org.eclipse.jface.action.MenuManager; import org.eclipse.jface.viewers.ColumnViewerEditor; import org.eclipse.jface.viewers.IBaseLabelProvider; import org.eclipse.jface.viewers.IDoubleClickListener; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.ITreeContentProvider; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.jface.viewers.ViewerCell; import org.eclipse.jface.viewers.ViewerRow; import org.eclipse.jface.viewers.ViewerSorter; import org.eclipse.nebula.widgets.xviewer.action.TableCustomizationAction; import org.eclipse.nebula.widgets.xviewer.action.TableCustomizationDropDownAction; import org.eclipse.nebula.widgets.xviewer.column.XViewerDaysTillTodayColumn; import org.eclipse.nebula.widgets.xviewer.column.XViewerDiffsBetweenColumnsColumn; import org.eclipse.nebula.widgets.xviewer.core.model.CustomizeData; import org.eclipse.nebula.widgets.xviewer.core.model.XViewerColumn; import org.eclipse.nebula.widgets.xviewer.customize.ColumnFilterDataUI; import org.eclipse.nebula.widgets.xviewer.customize.CustomizeManager; import org.eclipse.nebula.widgets.xviewer.customize.FilterDataUI; import org.eclipse.nebula.widgets.xviewer.customize.SearchDataUI; import org.eclipse.nebula.widgets.xviewer.edit.XViewerEditAdapter; import org.eclipse.nebula.widgets.xviewer.util.Pair; import org.eclipse.nebula.widgets.xviewer.util.internal.HtmlUtil; import org.eclipse.nebula.widgets.xviewer.util.internal.XViewerLib; import org.eclipse.nebula.widgets.xviewer.util.internal.XViewerLog; import org.eclipse.nebula.widgets.xviewer.util.internal.XViewerMenuDetectListener; import org.eclipse.nebula.widgets.xviewer.util.internal.XViewerMouseListener; import org.eclipse.nebula.widgets.xviewer.util.internal.dialog.HtmlDialog; import org.eclipse.swt.SWT; import org.eclipse.swt.events.MouseAdapter; import org.eclipse.swt.events.MouseEvent; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Label; 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.ui.part.ViewPart; /** * @author Donald G. Dunne */ public class XViewer extends TreeViewer { public static final String MENU_GROUP_PRE = "XVIEWER MENU GROUP PRE"; //$NON-NLS-1$ public static final String MENU_GROUP_POST = "XVIEWER MENU GROUP POST"; //$NON-NLS-1$ private Label statusLabel; private final MenuManager menuManager; private static boolean ctrlKeyDown = false; private static boolean altKeyDown = false; protected final IXViewerFactory xViewerFactory; private final FilterDataUI filterDataUI; private final SearchDataUI searchDataUI; private final ColumnFilterDataUI columnFilterDataUI; private static boolean ctrlKeyListenersSet = false; private XViewerGradient xViewerGradient = null; private XViewerEditAdapter editAdapter = null; private boolean columnMultiEditEnabled = false; private CustomizeManager customizeMgr; private TreeColumn rightClickSelectedColumn = null; private Integer rightClickSelectedColumnNum = null; private TreeItem rightClickSelectedItem = null; private Color searchColor; private boolean forcePend = false; private static final Map<Composite, Composite> parentToTopComposites = new HashMap<Composite, Composite>(); public XViewer(Composite parent, int style, IXViewerFactory xViewerFactory) { this(parent, style, xViewerFactory, false, false); } public XViewer(Tree tree, IXViewerFactory xViewerFactory) { this(tree, xViewerFactory, false, false); } public XViewer(Composite parent, int style, IXViewerFactory xViewerFactory, boolean filterRealTime, boolean searchRealTime) { this(new Tree(createTopComposite(xViewerFactory, parent), style), xViewerFactory, filterRealTime, searchRealTime); } /** * Create top if search block should be at top; return parent regardless but cache composite to use */ private static Composite createTopComposite(IXViewerFactory xViewerFactory, Composite parent) { if (xViewerFactory.isSearhTop()) { Composite topComposite = new Composite(parent, SWT.NONE); topComposite.setLayout(XViewerLib.getZeroMarginLayout(11, false)); topComposite.setLayoutData(new GridData(SWT.FILL, SWT.None, true, false)); parentToTopComposites.put(parent, topComposite); } else { parentToTopComposites.put(parent, parent); } return parent; } public XViewer(Tree tree, IXViewerFactory xViewerFactory, boolean filterRealTime, boolean searchRealTime) { super(tree); this.xViewerFactory = xViewerFactory; this.menuManager = new MenuManager(); this.menuManager.setRemoveAllWhenShown(true); this.menuManager.createContextMenu(tree.getParent()); if (xViewerFactory.isFilterUiAvailable()) { this.filterDataUI = new FilterDataUI(this, filterRealTime); } else { this.filterDataUI = null; } if (xViewerFactory.isSearchUiAvailable()) { this.searchDataUI = new SearchDataUI(this, searchRealTime); } else { this.searchDataUI = null; } this.columnFilterDataUI = new ColumnFilterDataUI(this); try { customizeMgr = new CustomizeManager(this, xViewerFactory); } catch (Exception ex) { XViewerLog.logAndPopup(Activator.class, Level.SEVERE, ex); } createSupportWidgets(parentToTopComposites.get(tree.getParent())); parentToTopComposites.remove(tree.getParent()); tree.setHeaderVisible(true); tree.setLinesVisible(true); setUseHashlookup(true); setupCtrlKeyListener(); if (xViewerFactory.isCellGradientOn()) { xViewerGradient = new XViewerGradient(this); } } @Override protected ColumnViewerEditor createViewerEditor() { return super.createViewerEditor(); } private static List<XViewerComputedColumn> computedColumns = new ArrayList<XViewerComputedColumn>(); public Collection<XViewerComputedColumn> getComputedColumns() { if (computedColumns.size() == 0) { computedColumns.add(new XViewerDaysTillTodayColumn()); computedColumns.add(new XViewerDiffsBetweenColumnsColumn()); } return computedColumns; } public Collection<XViewerComputedColumn> getComputedColumns(XViewerColumn xCol) { List<XViewerComputedColumn> matchCols = new ArrayList<XViewerComputedColumn>(); for (XViewerColumn computedCol : getComputedColumns()) { if (((XViewerComputedColumn) computedCol).isApplicableFor(xCol)) { matchCols.add((XViewerComputedColumn) computedCol); } } return matchCols; } public void dispose() { if (statusLabel != null && !statusLabel.isDisposed()) { statusLabel.dispose(); } if (searchComp != null && !searchComp.isDisposed()) { searchComp.dispose(); } //Remote Display filter Display.getCurrent().removeFilter(SWT.KeyDown, displayKeysListener); Display.getCurrent().removeFilter(SWT.KeyUp, displayKeysListener); Display.getCurrent().removeFilter(SWT.FocusOut, displayFocusListener); //Dispose Menu if (menuManager != null) { menuManager.removeAll(); menuManager.dispose(); } } @Override public void setLabelProvider(IBaseLabelProvider labelProvider) { if (!(labelProvider instanceof IXViewerLabelProvider)) { throw new IllegalArgumentException( "Label Provider must extend XViewerLabelProvider or XViewerStyledTextLabelProvider"); //$NON-NLS-1$ } super.setLabelProvider(labelProvider); } public void addCustomizeToViewToolbar(final ViewPart viewPart) { addCustomizeToViewToolbar(viewPart.getViewSite().getActionBars().getToolBarManager()); } public void updateMenuActionsForTable() { // provided for subclass implementation } public void updateMenuActionsForHeader() { // provided for subclass implementation } public Action getCustomizeAction() { return new TableCustomizationDropDownAction(this); } public Action getCustomizeActionWithoutDropDown() { return new TableCustomizationAction(this); } public void addCustomizeToViewToolbar(IToolBarManager toolbarManager) { toolbarManager.add(new TableCustomizationDropDownAction(this)); } protected void createSupportWidgets(Composite parent) { searchColor = Display.getDefault().getSystemColor(SWT.COLOR_YELLOW); searchComp = null; if (searchDataUI != null || filterDataUI != null || xViewerFactory.isLoadedStatusLabelAvailable()) { searchComp = new Composite(parent, SWT.NONE); searchComp.setLayout(XViewerLib.getZeroMarginLayout(11, false)); searchComp.setLayoutData(new GridData(SWT.FILL, SWT.None, true, false)); if (filterDataUI != null) { filterDataUI.createWidgets(searchComp); Label sep1 = new Label(searchComp, SWT.SEPARATOR); GridData gd = new GridData(SWT.RIGHT, SWT.NONE, false, false); gd.heightHint = 16; sep1.setLayoutData(gd); } if (searchDataUI != null) { searchDataUI.createWidgets(searchComp); Label sep2 = new Label(searchComp, SWT.SEPARATOR); GridData gd = new GridData(SWT.RIGHT, SWT.NONE, false, false); gd.heightHint = 16; sep2.setLayoutData(gd); } if (xViewerFactory.isLoadedStatusLabelAvailable()) { statusLabel = new Label(searchComp, SWT.NONE); statusLabel.setText(" "); //$NON-NLS-1$ statusLabel.setLayoutData(new GridData(SWT.FILL, SWT.NONE, true, false)); statusLabel.addMouseListener(getCustomizationMouseListener()); } } this.addDoubleClickListener(new IDoubleClickListener() { @Override public void doubleClick(org.eclipse.jface.viewers.DoubleClickEvent event) { handleDoubleClick(); }; }); mouseListener = new XViewerMouseListener(this); getTree().addMouseListener(mouseListener); getTree().addListener(SWT.MenuDetect, new XViewerMenuDetectListener(this)); getTree().setMenu(getMenuManager().getMenu()); columnFilterDataUI.createWidgets(); customizeMgr.loadCustomization(); } public void handleDoubleClick(TreeColumn col, TreeItem item) { // provided for subclass implementation } public void handleDoubleClick() { // provided for subclass implementation } public int getCurrentColumnWidth(XViewerColumn xCol) { for (TreeColumn col : getTree().getColumns()) { if (col.getText().equals(xCol.getName())) { return col.getWidth(); } } return 0; } /** * Called to set the input to the XViewer. This method MUST be used to ensure that XViewer loads properly. Especially * with the use of IXViewerPreComputedColumn. */ public final void setInputXViewer(Object input) { // Allow pre-computed columns to prior to supplying Viewer with new input refreshColumnsWithPreCompute(input); } /** * This is called after all preComputed columns are done loading. */ private void superInputChanged(Object input) { if (getTree() != null && !getTree().isDisposed()) { super.setInput(input); } } private List<Object> getInputObjects(Object input) { List<Object> objects = new LinkedList<Object>(); if (input instanceof Collection) { Collection<?> collection = (Collection<?>) input; for (Object obj : collection) { objects.add(obj); } } else if (input instanceof Object[]) { Object[] arr = (Object[]) input; for (Object obj : arr) { objects.add(obj); } } return objects; } public void refreshColumnsWithPreCompute() { refreshColumnsWithPreCompute(getInput()); } public void refreshColumnsWithPreCompute(final Object input) { final List<Object> inputObjects = getInputObjects(input); final XViewer xViewer = this; this.loading = true; if (!inputObjects.isEmpty()) { if (forcePend) { performPreCompute(inputObjects); performLoad(inputObjects, xViewer); } else { Job job = new Job("Refreshing Columns") { @Override protected IStatus run(IProgressMonitor monitor) { performPreCompute(inputObjects); return Status.OK_STATUS; } }; job.setSystem(false); job.addJobChangeListener(new JobChangeAdapter() { @Override public void done(IJobChangeEvent event) { Display.getDefault().asyncExec(new Runnable() { @Override public void run() { performLoad(input, xViewer); } }); } }); job.schedule(); } } } private void performPreCompute(final List<Object> inputObjects) { List<XViewerColumn> currentVisibleTableColumns = getCustomizeMgr().getCurrentVisibleTableColumns(); for (XViewerColumn column : currentVisibleTableColumns) { if (column instanceof IXViewerPreComputedColumn) { IXViewerPreComputedColumn preComputedColumn = (IXViewerPreComputedColumn) column; if (column.getPreComputedValueMap() == null) { column.setPreComputedValueMap(new HashMap<Long, String>(inputObjects.size())); } else { column.getPreComputedValueMap().clear(); } if (!inputObjects.isEmpty()) { try { preComputedColumn.populateCachedValues(inputObjects, column.getPreComputedValueMap()); } catch (Exception ex) { XViewerLog.log(Activator.class, Level.SEVERE, String.format("Error performing pre-compute for column %s", column), ex); } } } } } private void performLoad(final Object input, final XViewer xViewer) { if (xViewer.getTree() != null && !xViewer.getTree().isDisposed()) { xViewer.superInputChanged(input); loading = false; updateStatusLabel(); } } /** * Will be called when Alt-Left-Click is done within table cell * * @return true if handled */ public boolean handleAltLeftClick(TreeColumn treeColumn, TreeItem treeItem) { if (treeColumn.getData() instanceof XViewerColumn) { if ((XViewerColumn) treeColumn.getData() instanceof IAltLeftClickProvider) { return ((IAltLeftClickProvider) (XViewerColumn) treeColumn.getData()).handleAltLeftClick(treeColumn, treeItem); } } return false; } /** * Will be called when click is within the first 18 pixels of the cell rectangle where the icon would be. This method * will be called in addition to handleLeftClick since both are true. * * @return true if handled */ public boolean handleLeftClickInIconArea(TreeColumn treeColumn, TreeItem treeItem) { return false; } /** * Will be called when a cell obtains a mouse left-click. This method will be called in addition to * handleLeftClickInIconArea if both are true */ public boolean handleLeftClick(TreeColumn treeColumn, TreeItem treeItem) { return false; } public void handleColumnMultiEdit(TreeColumn treeColumn, Collection<TreeItem> treeItems) { if (treeColumn.getData() instanceof XViewerColumn) { if ((XViewerColumn) treeColumn.getData() instanceof IMultiColumnEditProvider) { ((IMultiColumnEditProvider) (XViewerColumn) treeColumn.getData()).handleColumnMultiEdit(treeColumn, treeItems); } } } public boolean isColumnMultiEditable(TreeColumn treeColumn, Collection<TreeItem> treeItems) { if (!isColumnMultiEditEnabled()) { return false; } return (((XViewerColumn) treeColumn.getData()).isMultiColumnEditable()); } /** * If true, "Remove Selected from View" and "Remove Non-Selected from View" menu options will be shown. */ public boolean isRemoveItemsMenuOptionEnabled() { return true; } public XViewerColumn getXTreeColumn(int columnIndex) { return (XViewerColumn) getTree().getColumn(columnIndex).getData(); } // Only create one listener for all XViewers private void setupCtrlKeyListener() { if (ctrlKeyListenersSet == false) { ctrlKeyListenersSet = true; Display.getCurrent().addFilter(SWT.KeyDown, displayKeysListener); Display.getCurrent().addFilter(SWT.KeyUp, displayKeysListener); Display.getCurrent().addFilter(SWT.FocusOut, displayFocusListener); } } Listener displayKeysListener = new Listener() { @Override public void handleEvent(org.eclipse.swt.widgets.Event event) { if (event.keyCode == SWT.CTRL) { if (event.type == SWT.KeyDown) { ctrlKeyDown = true; } else if (event.type == SWT.KeyUp) { ctrlKeyDown = false; } } if (event.keyCode == SWT.ALT) { if (event.type == SWT.KeyDown) { altKeyDown = true; } else if (event.type == SWT.KeyUp) { altKeyDown = false; } } } }; Listener displayFocusListener = new Listener() { @Override public void handleEvent(Event event) { // Clear when focus is lost ctrlKeyDown = false; altKeyDown = false; } }; private Composite searchComp; private XViewerMouseListener mouseListener; private boolean loading; public void resetDefaultSorter() { customizeMgr.resetDefaultSorter(); } /** * Override this method if need to perform other tasks upon remove */ @SuppressWarnings("unchecked") public void remove(Collection<Object> objects) { Object input = getInput(); if (input instanceof Collection<?>) { Collection<Object> inputObj = (Collection<Object>) getInput(); for (Object obj : objects) { super.remove(obj); inputObj.remove(obj); } } } /** * setInputXViewer(Object input) should be called for setting input to XViewer. * * @param objects */ @Deprecated public void load(Collection<Object> objects) { setInputXViewer(objects); } @Override public void setSorter(ViewerSorter sorter) { super.setSorter(sorter); updateStatusLabel(); } public MenuManager getMenuManager() { return this.menuManager; } public int getVisibleItemCount(TreeItem items[]) { int cnt = items.length; for (TreeItem item : items) { if (item.getExpanded()) { cnt += getVisibleItemCount(item.getItems()); } } return cnt; } public int getVisibleItemCount() { TreeItem[] items = getTree().getItems(); int cnt = items.length; for (TreeItem item : items) { if (item.getExpanded()) { cnt += getVisibleItemCount(item.getItems()); } } return cnt; } public List<TreeItem> getVisibleItems() { List<TreeItem> toReturn = new ArrayList<TreeItem>(); getVisibleItems(toReturn, getTree().getItems()); return toReturn; } private void getVisibleItems(List<TreeItem> toReturn, TreeItem items[]) { for (TreeItem item : items) { toReturn.add(item); if (item.getExpanded()) { getVisibleItems(toReturn, item.getItems()); } } } @Override public void refresh() { if (getTree() == null || getTree().isDisposed()) { return; } super.refresh(); // do not need to updateStatusLabel cause super.refresh will call refresh(element); } public boolean isFiltered() { return getFilters().length > 0; } @Override public void refresh(boolean updateLabels) { super.refresh(updateLabels); // do not need to updateStatusLabel cause super.refresh will call refresh(element, updateLabels); } @Override public void refresh(Object element, boolean updateLabels) { super.refresh(element, updateLabels); updateStatusLabel(); } @Override public void refresh(Object element) { super.refresh(element); updateStatusLabel(); } /** * Override this to add information to the status string. eg. extra filters etc. */ public String getStatusString() { return ""; //$NON-NLS-1$ } public void updateStatusLabel() { if (!xViewerFactory.isLoadedStatusLabelAvailable()) { return; } if (getTree().isDisposed() || statusLabel.isDisposed()) { return; } StringBuffer sb = new StringBuffer(); boolean allItemsFiltered = false; if (loading) { sb.append("Loading..."); } else { // Status Line 1 int loadedNum = 0; int visibleNum = getVisibleItemCount(getTree().getItems()); if (getRoot() != null && ((ITreeContentProvider) getContentProvider()) != null) { loadedNum = ((ITreeContentProvider) getContentProvider()).getChildren(getRoot()).length; } allItemsFiltered = loadedNum > 0 && visibleNum == 0; if (allItemsFiltered) { sb.append(XViewerText.get("status.all_filtered")); //$NON-NLS-1$ } sb.append(MessageFormat.format(XViewerText.get("status"), loadedNum, visibleNum, //$NON-NLS-1$ ((IStructuredSelection) getSelection()).size())); customizeMgr.appendToStatusLabel(sb); if (filterDataUI != null) { filterDataUI.appendToStatusLabel(sb); } columnFilterDataUI.appendToStatusLabel(sb); sb.append(getStatusString()); if (sb.length() > 0) { sb.append("\n"); //$NON-NLS-1$ } // Status Line 2 customizeMgr.getSortingStr(sb); } // Display status lines String str = sb.toString(); statusLabel.setText(str); statusLabel.getParent().getParent().layout(); statusLabel.setToolTipText(str); if (loading) { statusLabel.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_BLUE)); } else if (allItemsFiltered) { statusLabel.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_RED)); } else { statusLabel.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_BLACK)); } } public void setLoading(boolean loading) { this.loading = loading; updateStatusLabel(); } private MouseAdapter getCustomizationMouseListener() { return new MouseAdapter() { @Override public void mouseUp(MouseEvent mouseEvent) { if (mouseEvent.button == 3 && mouseEvent.count == 1) { CustomizeData custData = getCustomizeMgr().getCurrentCustomizeData(); List<XViewerColumn> currentVisibleTableColumns = getCustomizeMgr().getCurrentVisibleTableColumns(); custData.getColumnData().getColumns().clear(); custData.getColumnData().getColumns().addAll(currentVisibleTableColumns); String custStr = custData.toString(); custStr = custStr.replaceAll("XView", "\nXView"); custStr = custStr.replaceFirst("guid", "\nguid"); String html = HtmlUtil.simplePage(HtmlUtil.getPreData(custStr)); String title = String.format("Customization [%s]-[%s]", custData.getName(), custData.getGuid()); new HtmlDialog(title, title, html).open(); } } }; } public String getViewerNamespace() { return getXViewerFactory().getNamespace(); } public IXViewerFactory getXViewerFactory() { return xViewerFactory; } public Label getStatusLabel() { return statusLabel; } public FilterDataUI getFilterDataUI() { return filterDataUI; } public boolean isColumnMultiEditEnabled() { return columnMultiEditEnabled; } public void setColumnMultiEditEnabled(boolean columnMultiEditEnabled) { this.columnMultiEditEnabled = columnMultiEditEnabled; } public void setEnabled(boolean arg) { this.getControl().setEnabled(arg); } public TreeColumn getRightClickSelectedColumn() { return rightClickSelectedColumn; } public TreeItem getRightClickSelectedItem() { return rightClickSelectedItem; } public Integer getRightClickSelectedColumnNum() { return rightClickSelectedColumnNum; } public CustomizeManager getCustomizeMgr() { return customizeMgr; } public boolean isCtrlKeyDown() { return ctrlKeyDown; } public boolean isAltKeyDown() { return altKeyDown; } boolean searchMatch(String text) { if (searchDataUI == null) { return false; } return searchDataUI.match(text); } Color getSearchMatchColor() { return searchColor; } public boolean isSearch() { if (searchDataUI == null) { return false; } return searchDataUI.isSearch(); } public String getColumnText(Object element, int col) { return ((IXViewerLabelProvider) getLabelProvider()).getColumnText(element, col); } /** * Mouse clicks can happen in table via XViewerMouseListener or in menu area via XViewerMenuDetectListener. Both are * processed here to use in UI */ public void processRightClickMouseEvent(Point point) { rightClickSelectedColumn = null; rightClickSelectedColumnNum = null; rightClickSelectedItem = null; rightClickSelectedItem = getItemUnderMouseClick(point); rightClickSelectedColumn = getColumnUnderMouseClick(point); rightClickSelectedColumnNum = getColumnNumberUnderMouseClick(point); } public TreeColumn getColumnUnderMouseClick(Point point) throws ArrayIndexOutOfBoundsException { Integer columnNumber = getColumnNumberUnderMouseClick(point); if (columnNumber == null) { return null; } return getTree().getColumn(columnNumber); } public Integer getColumnNumberUnderMouseClick(Point point) { int[] columnOrder = getTree().getColumnOrder(); int sum = 0; int columnCount = 0; for (int column : columnOrder) { TreeColumn col = getTree().getColumn(column); sum = sum + col.getWidth(); if (sum > point.x) { break; } columnCount++; } if (columnCount > columnOrder.length - 1) { return null; } return columnOrder[columnCount]; } public TreeItem getItemUnderMouseClick(Point point) throws ArrayIndexOutOfBoundsException { TreeItem itemToReturn = getTree().getItem(point); if (itemToReturn == null) { int sum; sum = 0; TreeItem[] allItems = getTree().getItems(); for (TreeItem item : allItems) { sum = sum + getTree().getItemHeight(); if (sum > point.y) { itemToReturn = item; break; } } } return itemToReturn; } /** * Refresh only single column using normal label provider mechanism. This can be called after normal loading and * after columns compute their input in the background. */ public void refreshColumn(XViewerColumn column) { refreshColumn(column.getId()); } /** * Refresh only single column using normal label provider mechanism. This can be called after normal loading and * after columns compute their input in the background. */ public void refreshColumn(String columnId) { Pair<XViewerColumn, Integer> column = getCustomizeMgr().getColumnNumFromXViewerColumn(columnId); IBaseLabelProvider baseLabelProvider = getLabelProvider(); if (baseLabelProvider instanceof XViewerLabelProvider) { XViewerLabelProvider labelProvider = (XViewerLabelProvider) baseLabelProvider; TreeItem[] items = getTree().getItems(); for (TreeItem item : items) { ViewerRow viewerRow = getViewerRowFromItem(item); if (viewerRow != null) { try { ViewerCell cell = viewerRow.getCell(column.getSecond()); String value = null; try { value = labelProvider.getColumnText(item.getData(), column.getSecond()); } catch (Exception ex) { value = String.format("Exception getting value from column [%s][%s]", column.getFirst().getId(), ex.getLocalizedMessage()); } if (value != null) { cell.setText(value); } } catch (NullPointerException ex) { // do nothing } } } } } /** * Override to provide extended filter capabilities */ public XViewerTextFilter getXViewerTextFilter() { return new XViewerTextFilter(this); } public XViewerGradient getxViewerGradient() { return xViewerGradient; } public void setxViewerGradient(XViewerGradient xViewerGradient) { this.xViewerGradient = xViewerGradient; } public void setXViewerEditAdapter(XViewerEditAdapter editAdapter) { this.editAdapter = editAdapter; this.editAdapter.activate(this); } public ColumnFilterDataUI getColumnFilterDataUI() { return columnFilterDataUI; } public XViewerMouseListener getMouseListener() { return mouseListener; } public boolean isForcePend() { return forcePend; } public void setForcePend(boolean forcePend) { this.forcePend = forcePend; } }