com.hydra.project.myplugin_nebula.xviewer.XViewer.java Source code

Java tutorial

Introduction

Here is the source code for com.hydra.project.myplugin_nebula.xviewer.XViewer.java

Source

/*******************************************************************************
 * 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 com.hydra.project.myplugin_nebula.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 com.hydra.project.myplugin_nebula.xviewer.action.TableCustomizationDropDownAction;
import com.hydra.project.myplugin_nebula.xviewer.column.XViewerDaysTillTodayColumn;
import com.hydra.project.myplugin_nebula.xviewer.column.XViewerDiffsBetweenColumnsColumn;
import com.hydra.project.myplugin_nebula.xviewer.customize.ColumnFilterDataUI;
import com.hydra.project.myplugin_nebula.xviewer.customize.CustomizeManager;
import com.hydra.project.myplugin_nebula.xviewer.customize.FilterDataUI;
import com.hydra.project.myplugin_nebula.xviewer.customize.SearchDataUI;
import com.hydra.project.myplugin_nebula.xviewer.edit.XViewerEditAdapter;
import com.hydra.project.myplugin_nebula.xviewer.util.Pair;
import com.hydra.project.myplugin_nebula.xviewer.util.internal.XViewerLib;
import com.hydra.project.myplugin_nebula.xviewer.util.internal.XViewerLog;
import com.hydra.project.myplugin_nebula.xviewer.util.internal.XViewerMenuDetectListener;
import com.hydra.project.myplugin_nebula.xviewer.util.internal.XViewerMouseListener;
import org.eclipse.swt.SWT;
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 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));
            }
        }

        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);
            }
        }
        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 (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) {
        for (XViewerColumn column : getCustomizeMgr().getCurrentVisibleTableColumns()) {
            if (column instanceof IXViewerPreComputedColumn) {
                IXViewerPreComputedColumn preComputedColumn = (IXViewerPreComputedColumn) column;
                if (column.preComputedValueMap == null) {
                    column.preComputedValueMap = new HashMap<Long, String>(inputObjects.size());
                } else {
                    column.preComputedValueMap.clear();
                }
                preComputedColumn.populateCachedValues(inputObjects, column.preComputedValueMap);
            }
        }
    }

    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 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;
    }

}