net.rim.ejde.internal.ui.views.VarContentDebugView.java Source code

Java tutorial

Introduction

Here is the source code for net.rim.ejde.internal.ui.views.VarContentDebugView.java

Source

/*
* Copyright (c) 2010-2012 Research In Motion Limited. All rights reserved.
*
* This program and the accompanying materials are made available
* under the terms of the Eclipse Public License, Version 1.0,
* which accompanies this distribution and is available at
*
* http://www.eclipse.org/legal/epl-v10.html
*
*/
package net.rim.ejde.internal.ui.views;

import java.io.File;
import java.util.Iterator;
import java.util.Vector;

import net.rim.ejde.internal.core.ContextManager;
import net.rim.ejde.internal.core.RimIDEUtil;
import net.rim.ejde.internal.ui.preferences.PreferenceConstants;
import net.rim.ejde.internal.util.Messages;
import net.rim.ide.RIA;
import net.rim.ide.core.IDEError;
import net.rim.ide.core.VarContentsHelper;
import net.rim.ide.core.VarContentsHelper.Callback;
import net.rim.ide.core.VarContentsHelper.Line;
import net.rim.ide.core.VarContentsHelper.MenuItem;

import org.apache.log4j.Logger;
import org.eclipse.core.filesystem.EFS;
import org.eclipse.core.filesystem.IFileStore;
import org.eclipse.core.filesystem.IFileSystem;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.viewers.ILazyContentProvider;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.ui.IWorkbenchActionConstants;

/**
 * This view is the parent of views which display data from a {@link VarContentsHelper}, e.g. process view, locals view, locks
 * view,threads view and statics view.
 *
 */
public abstract class VarContentDebugView extends BasicDebugView {

    private static final Logger _log = Logger.getLogger(VarContentDebugView.class);

    private TableViewer _tableViewer;

    private int _selectedColumns = -1;

    private int _selectedRow = -1;

    private VarLabelProvider _labelProvider;

    private int _moveCursorTo;

    private IProgressMonitor _progressMonitor;

    DebuggerLiveUpdateJob _liveUpdateJob;

    /**
     * Get the instance of the contents helper used by this view.
     *
     * @return
     */
    abstract protected VarContentsHelper getContentsHelper();

    /**
     * Constructs an instance of VarContentDebugView.
     */
    public VarContentDebugView(int style) {
        super(style);
        if (_log.isDebugEnabled()) {
            _log.debug(String.format("Instance [%s] created.", hashCode())); //$NON-NLS-1$
        }
    }

    synchronized protected void setProgressMonitor(IProgressMonitor monitor) {
        _progressMonitor = monitor;
    }

    synchronized protected IProgressMonitor getProgressMonitor() {
        return _progressMonitor;
    }

    protected void startLiveupdate() {
        IPreferenceStore ps = ContextManager.PLUGIN.getPreferenceStore();
        boolean startLiveUpdate = ps.getBoolean(PreferenceConstants.NET_RIM_EJDE_UI_VIEWS_LIVE_UPDATE);
        if (!startLiveUpdate) {
            // if live update is disabled, we cancel the update job if it is available
            if (_liveUpdateJob != null) {
                _liveUpdateJob.cancelUpdate();
            }
            return;
        }
        if (_liveUpdateJob == null) {
            _liveUpdateJob = new DebuggerLiveUpdateJob("", this);
            _liveUpdateJob.schedule();
        } else {
            if (_liveUpdateJob.getState() == Job.NONE || _liveUpdateJob.isUpdateCanceled()) {
                _liveUpdateJob.schedule();
            }
        }
    }

    /**
     * Disposes created image instances.
     */
    public void dispose() {
        super.dispose();
        if (_liveUpdateJob != null) {
            _liveUpdateJob.cancelUpdate();
        }
    }

    /*
     * (non-Javadoc) Sub-clsses may override this method.
     *
     * @see BasicDebugView#refresh()
     */
    public void refresh() throws CoreException {
        _log.trace("Refreshing DebugView");
        RIA ria = RIA.getCurrentDebugger();
        if (ria != null) {
            VarContentsHelper contentHelper = getContentsHelper();
            if (contentHelper == null) {
                return;
            }
            try {
                contentHelper.updateContents();
                Table table = getTableView().getTable();
                table.setRedraw(false);
                getTableView().setInput(contentHelper);
                table.setItemCount(getContentsHelper().getRowCount());
                table.setRedraw(true);

                if (_selectedRow >= 0) {
                    table.setSelection(_selectedRow);
                    table.showSelection();
                }
            } catch (IDEError e) {
                _log.error(e);
            }
        }
    }

    /**
     * Gets the TableViewer component used in this view.
     *
     * @return
     */
    protected TableViewer getTableView() {
        if (_tableViewer == null) {
            _log.error("The TableViewer component has not been created.");
        }
        return _tableViewer;
    }

    /**
     * Sets the TableViewer component used in this view. <b>This must be called after the TableViewer component is created in the
     * sub-classes</b>.
     *
     * @param view
     */
    protected void setTableView(TableViewer view) {
        _tableViewer = view;
    }

    /**
     * Gets the LabelProvider of the TableViewer component used in this view.
     *
     * @return
     */
    protected VarLabelProvider getLabelProvider() {
        return _labelProvider;
    }

    /**
     * Sets the LabelProvider of the TableViewer component used in this view. <b>This must be called after the TableViewer
     * component is created in the sub-classes</b>.
     *
     * @param view
     */
    protected void setLabelProvider(VarLabelProvider labelProvider) {
        _labelProvider = labelProvider;
    }

    /***************************************************************************
     * @link java.lang.Object#finalize()
     */
    @Override
    protected void finalize() {
        if (_log.isDebugEnabled()) {
            _log.debug(String.format("Instance [%s] finalized.", hashCode())); //$NON-NLS-1$
        }
    }

    protected void createContextMenu() {
        MenuManager menuManager = new MenuManager("PopupMenu"); //$NON-NLS-1$
        menuManager.setRemoveAllWhenShown(true);

        menuManager.addMenuListener(new IMenuListener() {
            public void menuAboutToShow(IMenuManager m) {
                fillContextMenu(m);
            }
        });

        Menu menu = menuManager.createContextMenu(_tableViewer.getControl());

        _tableViewer.getControl().setMenu(menu);

        getSite().registerContextMenu(menuManager, _tableViewer);
    }

    protected void fillContextMenu(IMenuManager menuMgr) {
        RIA ria = RIA.getCurrentDebugger();
        if (ria == null || !ria.isDebuggerSuspended()) {
            return;
        }
        Vector<MenuItem> menuVector = null;
        VarContentsHelper helper = getContentsHelper();
        if (helper == null) {
            return;
        }
        try {
            menuVector = helper.getMenu();
        } catch (IDEError e) {
            _log.error(e.getMessage(), e);
        }

        if (menuVector == null) {
            return;
        }

        MenuItem menuItem;
        for (Iterator<MenuItem> iterator = menuVector.iterator(); iterator.hasNext();) {
            menuItem = iterator.next();

            if (menuItem.isSeparator) {
                menuMgr.add(new Separator());
            } else {
                menuMgr.add(new MenuAction(this, menuItem));
            }
        }

        menuMgr.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
        fillExtraContextMenu(menuMgr);
    }

    /**
     * Sub-classes need to override this method if they want to add extra context menus.
     *
     * @param menuMgr
     */
    protected void fillExtraContextMenu(IMenuManager menuMgr) {
        // do nothing here
    }

    /**
     * Gets the index of <code>column</code>.
     *
     * @param column
     * @return index of <code>column</code> or <em>-1</em> if <code>column</code> is not in the table
     */
    private int getColumnIndex(TableColumn column) {
        Table table = _tableViewer.getTable();
        for (int i = 0; i < table.getColumnCount(); i++) {
            if (table.getColumn(i).equals(column)) {
                return i;
            }
        }
        return -1;
    }

    /**
     * Display the objects information.
     */
    void displayData() {
        // clear all items from the table
        Table table = _tableViewer.getTable();

        table.removeAll();

        VarContentsHelper contentsHelper = getContentsHelper();

        if (null == contentsHelper) {
            return;
        }

        // update contents (set data to lines)
        try {
            contentsHelper.updateContents();
        } catch (IDEError e) {
            _log.error(e.getMessage(), e);
            return;
        }
        //

        table.setRedraw(false);
        _tableViewer.setInput(contentsHelper);
        table.setItemCount(contentsHelper.getRowCount());
        table.setRedraw(true);

        if (_selectedRow >= 0) {
            table.setSelection(_selectedRow);
            table.showSelection();
        }
    }

    /**
     * Gets the index of selected column in the table.
     *
     * @return
     */
    protected int getSelectedColumnIndex() {
        return _selectedColumns;
    }

    /**
     * Sets the index of selected column in the table.
     *
     * @param index
     */
    protected void setSelectedColumnIndex(int index) {
        _selectedColumns = index;
    }

    /**
     * Gets the index of selected row in the table.
     *
     * @return
     */
    protected int getSelectedRowIndex() {
        return _selectedRow;
    }

    /**
     * Sets the index of selected row in the table.
     *
     * @return
     */
    protected void setSelectedRowIndex(int index) {
        _selectedRow = index;
    }

    /**
     * Gets the index of row where the cursor should be moved to.
     *
     * @return
     */
    protected int getMoveCursorToIndex() {
        return _moveCursorTo;
    }

    /**
     * Sets the index of row where the cursor should be moved to.
     *
     * @return
     */
    protected void setMoveCursorToIndex(int index) {
        _moveCursorTo = index;
    }

    // ------ Inner Classes ------
    /**
     * Content provider of objects tree view.
     */
    protected class VarContentProvider implements ILazyContentProvider {
        private TableViewer _myViewer;
        private Object[] _models;

        public VarContentProvider(TableViewer viewer) {
            _myViewer = viewer;
        }

        public void updateElement(int index) {
            _myViewer.replace(_models[index], index);
        }

        public void dispose() {
            // TODO Auto-generated method stub

        }

        public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
            if ((newInput == null) || !(newInput instanceof VarContentsHelper)) {
                _models = new Object[0];
            } else {
                VarContentsHelper helper = (VarContentsHelper) newInput;
                int rowCount = helper.getRowCount();
                _models = new Object[rowCount];
                for (int i = 0; i < rowCount; i++) {
                    _models[i] = helper.getLine(i);
                }
            }
        }

    }

    /**
     * (no java doc)
     *
     * @see IBasicActions#clear()
     */
    @Override
    public void clear() {
        TableViewer tableviewer = getTableView();
        if (tableviewer != null) {
            tableviewer.getTable().removeAll();
        }
        setHasData(false);
        updateToolbar();
    }

    /**
     * Label provider of objects tree view.
     */
    protected class VarLabelProvider extends AbstractTreeOwnerDrawLabelProvider {

        public VarLabelProvider(TableViewer viewer) {
            super(viewer);
        }

        @Override
        public boolean findRowAtSameIndent(Object obj, int indent) {
            int row = getIndex(obj) + 1;

            VarContentsHelper contentsHelper = getContentsHelper();

            if (null == contentsHelper) {
                return false;
            }

            for (int i = row; i < contentsHelper.getRowCount(); i++) {
                Line line = contentsHelper.getLine(i);

                if (line == null) {
                    return false;
                }

                int indentOfChild = getIndent(line);

                if (indentOfChild < indent) {
                    return false;
                }

                if (indentOfChild == indent) {
                    return true;
                }
            }

            return false;
        }

        @Override
        public int getIndent(Object obj) {
            Line line = (Line) obj;
            return line.getIndent();
        }

        @Override
        public int getIndex(Object obj) {
            return _tableViewer.getTable().indexOf((TableItem) obj);
        }

        @Override
        public boolean hasChildren(Object obj) {
            Line line = (Line) obj;
            return line.getIcon() != Line.ICON_NONE;
        }

        @Override
        public boolean isExpanded(Object obj) {
            Line line = (Line) obj;
            return line.getIcon() == Line.ICON_MINUS;
        }

        /*
         * (non-Javadoc)
         *
         * @see org.eclipse.jface.viewers.OwnerDrawLabelProvider#measure(Event, Object)
         */
        @Override
        protected void measure(Event event, Object element) {
            if (_tableViewer.getTable().getColumnCount() != 0) {
                event.width = _tableViewer.getTable().getColumn(event.index).getWidth();
            }
        }

        /*
         * (non-Javadoc)
         *
         * @see org.eclipse.jface.viewers.OwnerDrawLabelProvider#paint(org.eclipse .swt.widgets.Event, java.lang.Object)
         */
        @Override
        protected void paint(Event event, Object element) {
            // call super method to initiate variables
            super.paint(event, element);
            String text;

            VarContentsHelper contentsHelper = getContentsHelper();
            if (contentsHelper == null) {
                return;
            }

            Line line = (Line) element;

            text = (contentsHelper.getValue(line, event.index)).toString();

            if (event.index == 0) {
                drawFirstColumn(event, element, text, line.getHilight());
            } else {
                drawText(event, text, event.x, event.y, line.getHilight());
            }
        }

        @Override
        public int calculateDisplayLevel(Object obj) {
            // nothing to do
            return 0;
        }
    }

    protected class VarMouseAdapter extends MouseAdapter {
        public VarMouseAdapter() {
            // TODO Auto-generated constructor stub
        }

        @Override
        public void mouseDown(MouseEvent e) {
            int selectionIndex = _tableViewer.getTable().getSelectionIndex();
            if (selectionIndex < 0) {
                return;
            }
            TableItem selectedItem = _tableViewer.getTable().getItem(selectionIndex);
            if (selectedItem == null) {
                return;
            }
            // If user clicked on the [+] or [-], expand or collapse the item
            Line line = (Line) selectedItem.getData();
            Rectangle rect = _labelProvider.getImageBounds(line, selectedItem.getBounds(0));
            if (rect.contains(e.x, e.y)) {
                switch (line.getIcon()) {
                case Line.ICON_PLUS:
                case Line.ICON_MINUS: {
                    _moveCursorTo = -1;
                    _selectedRow = selectionIndex;
                    VarContentsHelper contentsHelper = getContentsHelper();
                    if (contentsHelper == null) {
                        return;
                    }
                    contentsHelper.toggleExpansion(line);
                    displayData();
                    break;
                }
                }
            }
        }
    }

    protected class VarTableColumnSelectionListener implements SelectionListener {

        public VarTableColumnSelectionListener() {
            // TODO Auto-generated constructor stub
        }

        public void widgetDefaultSelected(SelectionEvent e) {
            // nothing to do

        }

        /**
         * Sort the content when a column is selected.
         */
        public void widgetSelected(SelectionEvent e) {
            TableColumn column = (TableColumn) e.widget;
            _selectedColumns = getColumnIndex(column);
            _moveCursorTo = -1;
            try {
                VarContentsHelper contentsHelper = getContentsHelper();
                if (contentsHelper == null) {
                    return;
                }
                contentsHelper.sortRows(_selectedColumns);
            } catch (IDEError e1) {
                _log.error(e1.getStackTrace(), e1);
                return;
            }
        }
    }

    protected class VarTableRowSelectionListener implements SelectionListener {

        public VarTableRowSelectionListener() {
            // TODO Auto-generated constructor stub
        }

        public void widgetDefaultSelected(SelectionEvent e) {
            // nothing to do

        }

        /**
         * Sort the content when a column is selected.
         */
        public void widgetSelected(SelectionEvent e) {
            _selectedRow = _tableViewer.getTable().getSelectionIndex();
        }
    }

    protected class VarCallbackAdaptor implements Callback {
        @Override
        public int getSelectedRow() {
            return getSelectedRowIndex();
        }

        @Override
        public int getSelectedColumn() {
            return getSelectedColumnIndex();
        }

        @Override
        public void beep() {
            // TODO Auto-generated method stub

        }

        @Override
        public void showSource(String fileName, int line) {
            IFileSystem fileSystem = EFS.getLocalFileSystem();
            IFileStore fileStore = fileSystem.getStore(new Path(fileName));
            RimIDEUtil.openSourceFile(fileStore, line);

        }

        @Override
        public void updateAllDebugWindows() {
            // TODO Auto-generated method stub

        }

        @Override
        public void addWatchExpression(String expr) throws IDEError {
            // TODO Auto-generated method stub

        }

        @Override
        public void columnHeadersChanged() {
            // TODO Auto-generated method stub

        }

        @Override
        public void moveCursorTo(int row, int column) {
            setMoveCursorToIndex(row);
        }

        @Override
        public void reload() {
            // TODO Auto-generated method stub
        }

        @Override
        public File promptAndCreateFile(String wildCard, String title) {
            return RimIDEUtil.openFileForSave(getSite().getShell(), wildCard, new String[] {});
        }

        @Override
        public void displayLineAttribute(String toStringValue) {
            MessageDialog.openInformation(getSite().getShell(), Messages.ObjectsView_LINE_ATTRIBUTE_DIALOG_TITLE,
                    toStringValue);
        }
    }
}