no.javatime.util.messages.views.MessageView.java Source code

Java tutorial

Introduction

Here is the source code for no.javatime.util.messages.views.MessageView.java

Source

/*******************************************************************************
 * Copyright (c) 2011, 2012 JavaTime project and others
 * 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:
 *    JavaTime project, Eirik Gronsund - initial implementation
 *******************************************************************************/
package no.javatime.util.messages.views;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Collection;
import java.util.ConcurrentModificationException;
import java.util.Iterator;

import no.javatime.util.Activator;
import no.javatime.util.messages.Category;
import no.javatime.util.messages.ExceptionMessage;
import no.javatime.util.messages.MessageContainer;

import org.eclipse.core.runtime.Status;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.IFontDecorator;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.dnd.Clipboard;
import org.eclipse.swt.dnd.TextTransfer;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.FocusListener;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IMemento;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.IViewSite;
import org.eclipse.ui.IWorkbenchActionConstants;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.actions.ActionFactory;
import org.eclipse.ui.part.ViewPart;
import org.eclipse.ui.statushandlers.StatusManager;

/**
 * A message view that displays data obtained from the {@link MessageContainer} model. The view is connected to
 * the model using a minimal content provider and the view part of the model is a simple list of queued messages.
 * <p>
 * The primary purpose of this view is tracing of bundle commands and events and filtering out and displaying
 * log messages from the bind manager due to bug 295662. The view should probably be disabled when the
 * InPlace Activator get mature.
 * <p>
 * Not using properties. UI messages are hard coded.
 */
public class MessageView extends ViewPart {

    public static String ID = "no.javatime.util.messages.views.MessageView"; //$NON-NLS-1$
    final public static ImageDescriptor messageViewImage = Activator.getImageDescriptor("icons/message_view.gif"); //$NON-NLS-1$

    private TableViewer viewer;
    private Action clearAction;
    private Action copyAction;
    private Action doubleClickAction;
    private Action selectAllAction;
    private Action traceOperationsAction;
    private Action traceEventsAction;
    private Action infoMessageAction;
    private ViewContentProvider contentProvider;
    private IMemento memento;

    /*
     * Provides a list of messages to the view.
     */
    class ViewContentProvider implements IStructuredContentProvider {

        public void inputChanged(Viewer v, Object oldInput, Object newInput) {
        }

        public void dispose() {
        }

        public int size() {
            return MessageContainer.getInstance().size();
        }

        public Object[] getElements(Object parent) {

            return MessageContainer.getInstance().getMessages();
        }
    }

    /**
     * Displays messages as a simple list
     * 
     */
    class ViewLabelProvider extends LabelProvider implements ITableLabelProvider, IFontDecorator {

        public String getColumnText(Object obj, int index) {
            return getText(obj);
        }

        public Image getColumnImage(Object obj, int index) {
            return null;
        }

        public Image getImage(Object obj) {
            return null;
        }

        @Override
        public Font decorateFont(Object element) {
            return JFaceResources.getFontRegistry().getBold(JFaceResources.TEXT_FONT);
        }
    }

    public MessageView() {
    }

    public void init(IViewSite site, IMemento memento) throws PartInitException {
        super.init(site, memento);
        this.memento = memento;
    }

    /**
     * Save state of trace tool bar buttons and  checked menu for receiving binding
     * messages. 
     * Overrides settings at bundle level
     * @param memento interface to persist state
     */
    @Override
    public void saveState(IMemento memento) {
        super.saveState(memento);
        if (null != memento) {
            IMemento mem = memento.createChild("ToolbarButtons"); //$NON-NLS-1$
            mem.putBoolean(traceEventsAction.getId(), traceEventsAction.isChecked());
            mem = memento.createChild("ToolbarButtons"); //$NON-NLS-1$
            mem.putBoolean(traceOperationsAction.getId(), traceOperationsAction.isChecked());
            mem = memento.createChild("ToolbarButtons"); //$NON-NLS-1$
            mem.putBoolean(infoMessageAction.getId(), infoMessageAction.isChecked());
        }
    }

    /**
     * Set state of trace tool bar buttons and menu for receiving binding messages from previous session
     * Overrides settings at bundle level if memento exist
     * @param memento interface to access persisted state
     */
    public void restoreState(IMemento memento) {
        if (null != memento) {
            IMemento[] mem = memento.getChildren("ToolbarButtons"); //$NON-NLS-1$
            if (null != mem && mem.length == 3) {
                Boolean traceEventsValue = mem[0].getBoolean(traceEventsAction.getId());
                Boolean traceOperationsValue = mem[1].getBoolean(traceOperationsAction.getId());
                Boolean traceBindingValue = mem[2].getBoolean(infoMessageAction.getId());
                if (null != traceOperationsValue && null != traceEventsValue && null != traceBindingValue) {
                    setTraceState(traceEventsValue, traceOperationsValue, traceBindingValue);
                }
            }
        } else {
            // Use settings at bundle level
            setTraceState(Category.getState(Category.bundleEvents), Category.getState(Category.bundleOperations),
                    Category.getState(Category.infoMessages));
        }
    }

    /**
     * Create and initialize the viewer with selection provider and listener, actions,
     * tool bar, pop-up and pull-down menus.
     */
    public void createPartControl(Composite parent) {
        viewer = new TableViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
        contentProvider = new ViewContentProvider();
        viewer.setContentProvider(contentProvider);
        ViewLabelProvider labelProvider = new ViewLabelProvider();
        viewer.setLabelProvider(labelProvider);
        viewer.getTable().setLinesVisible(true);
        viewer.setInput(MessageContainer.getInstance());
        getSite().setSelectionProvider(viewer);
        viewer.addSelectionChangedListener(new ISelectionChangedListener() {
            public void selectionChanged(SelectionChangedEvent event) {
                toggleClipboardActions((contentProvider.size()) > 0 ? true : false);
            }
        });
        PlatformUI.getWorkbench().getHelpSystem().setHelp(viewer.getControl(), "no.javatime.util.messages.viewer"); //$NON-NLS-1$
        makeActions();
        IActionBars actionBars = getViewSite().getActionBars();
        actionBars.setGlobalActionHandler(ActionFactory.COPY.getId(), copyAction);
        hookContextMenu();
        hookDoubleClickAction();
        contributeToActionBars();
        restoreState(memento);

        viewer.getTable().addFocusListener(new FocusListener() {

            @Override
            public void focusGained(FocusEvent e) {

                toggleClipboardActions((contentProvider.size()) > 0 ? true : false);
                setTraceState(traceEventsAction.isChecked(), traceOperationsAction.isChecked(),
                        infoMessageAction.isChecked());
                try {
                    MessageContainer mc = MessageContainer.getInstance();
                    setInput(mc);
                } catch (ConcurrentModificationException ex) {
                    StatusManager.getManager().handle(
                            new Status(Status.ERROR, Activator.PLUGIN_ID, ex.getLocalizedMessage(), ex),
                            StatusManager.LOG);
                    ExceptionMessage.getInstance().handleMessage(ex, "ConcurrentModificationException"); //$NON-NLS-1$
                }
            }

            @Override
            public void focusLost(FocusEvent e) {
                toggleClipboardActions((contentProvider.size()) > 0 ? true : false);
            }
        });
        toggleClipboardActions((contentProvider.size()) > 0 ? true : false);
    }

    /**
     * Set trace buttons and category trace variables based on the value of trace actions.
     * @param eventState event state to apply to trace event button and category
     * @param operationState operation state to apply to trace operation button and category
     * @param infoMessageState to receive binding messages
     */
    private void setTraceState(Boolean eventState, Boolean operationState, Boolean infoMessageState) {
        traceEventsAction.setChecked(eventState);
        Category.setState(Category.bundleEvents, eventState);
        if (eventState) {
            traceEventsAction.setImageDescriptor(Activator.getImageDescriptor("icons/enable_trace_events.png")); //$NON-NLS-1$
        } else {
            traceEventsAction.setImageDescriptor(Activator.getImageDescriptor("icons/disable_trace_events.png")); //$NON-NLS-1$
        }
        traceOperationsAction.setChecked(operationState);
        Category.setState(Category.bundleOperations, operationState);
        if (operationState) {
            traceOperationsAction.setImageDescriptor(Activator.getImageDescriptor("icons/enable_trace_op.png")); //$NON-NLS-1$
        } else {
            traceOperationsAction.setImageDescriptor(Activator.getImageDescriptor("icons/disable_trace_op.png")); //$NON-NLS-1$
        }
        infoMessageAction.setChecked(infoMessageState);
        Category.setState(Category.infoMessages, infoMessageState);
        if (infoMessageState) {
            infoMessageAction.setImageDescriptor(Activator.getImageDescriptor("icons/process_info.png")); //$NON-NLS-1$
        } else {
            infoMessageAction.setImageDescriptor(Activator.getImageDescriptor("icons/no_process_info.png")); //$NON-NLS-1$
        }
    }

    /**
     * Invoke filling tool bar and pull-down menu
     */
    private void contributeToActionBars() {
        IActionBars bars = getViewSite().getActionBars();
        fillLocalPullDown(bars.getMenuManager());
        fillLocalToolBar(bars.getToolBarManager());
    }

    /**
     * Fill local pull-down menu
     * @param manager the menu manager for the pull-down menu
     */
    private void fillLocalPullDown(IMenuManager manager) {
        manager.add(traceEventsAction);
        manager.add(traceOperationsAction);
        manager.add(infoMessageAction);
        manager.add(new Separator());
        manager.add(clearAction);
        manager.add(selectAllAction);
        manager.add(copyAction);
        manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
    }

    /**
     * Fill local tool bar menu
     * @param manager the menu manager for the tool bar
     */
    private void fillLocalToolBar(IToolBarManager manager) {
        manager.add(clearAction);
        manager.add(selectAllAction);
        manager.add(new Separator());
        manager.add(traceEventsAction);
        manager.add(traceOperationsAction);
        manager.add(infoMessageAction);
        manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
    }

    /**
     * Fill local pop-up menu
     * @param manager the menu manager for the pop-up menu
     */
    private void fillContextMenu(IMenuManager manager) {
        manager.add(traceEventsAction);
        manager.add(traceOperationsAction);
        manager.add(infoMessageAction);
        manager.add(new Separator());
        manager.add(clearAction);
        manager.add(selectAllAction);
        manager.add(copyAction);
        // Other plug-ins can contribute their actions here
        manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
    }

    /**
     * Hook for the context pop-up menu   
     */
    private void hookContextMenu() {
        MenuManager menuMgr = new MenuManager("#PopupMenu"); //$NON-NLS-1$
        menuMgr.setRemoveAllWhenShown(true);
        menuMgr.addMenuListener(new IMenuListener() {
            public void menuAboutToShow(IMenuManager manager) {
                MessageView.this.fillContextMenu(manager);
            }
        });
        Menu menu = menuMgr.createContextMenu(viewer.getControl());
        viewer.getControl().setMenu(menu);
        getSite().registerContextMenu(menuMgr, viewer);
    }

    private void hookDoubleClickAction() {
        viewer.addDoubleClickListener(new IDoubleClickListener() {
            public void doubleClick(DoubleClickEvent event) {
                doubleClickAction.run();
            }
        });
    }

    /**
     * Create all actions and assign text, tool tip and images
     */
    private void makeActions() {

        traceEventsAction = new Action("Trace Bundle Events", Action.AS_CHECK_BOX) { //$NON-NLS-1$

            public void run() {
                Boolean traceEvents = traceEventsAction.isChecked();
                Category.setState(Category.bundleEvents, traceEvents);
                if (traceEvents) {
                    traceEventsAction
                            .setImageDescriptor(Activator.getImageDescriptor("icons/enable_trace_events.png")); //$NON-NLS-1$
                } else {
                    traceEventsAction
                            .setImageDescriptor(Activator.getImageDescriptor("icons/disable_trace_events.png")); //$NON-NLS-1$
                }
            }
        };
        traceEventsAction.setId("traceEventsAction"); //$NON-NLS-1$
        traceEventsAction.setToolTipText("Trace Bundle and Framework Events"); //$NON-NLS-1$

        traceOperationsAction = new Action("Trace Bundle Operations", Action.AS_CHECK_BOX) { //$NON-NLS-1$

            public void run() {
                Boolean traceOp = traceOperationsAction.isChecked();
                Category.setState(Category.bundleOperations, traceOp);
                if (traceOp) {
                    traceOperationsAction
                            .setImageDescriptor(Activator.getImageDescriptor("icons/enable_trace_op.png")); //$NON-NLS-1$
                } else {
                    traceOperationsAction
                            .setImageDescriptor(Activator.getImageDescriptor("icons/disable_trace_op.png")); //$NON-NLS-1$
                }
            }
        };
        traceOperationsAction.setId("traceOperationsAction"); //$NON-NLS-1$
        traceOperationsAction.setToolTipText("Trace Bundle Life Cycle Operations"); //$NON-NLS-1$

        infoMessageAction = new Action("Information Messages", Action.AS_CHECK_BOX) { //$NON-NLS-1$

            public void run() {
                Boolean infoEvents = infoMessageAction.isChecked();
                Category.setState(Category.infoMessages, infoEvents);
                if (infoEvents) {
                    infoMessageAction.setImageDescriptor(Activator.getImageDescriptor("icons/process_info.png")); //$NON-NLS-1$
                } else {
                    infoMessageAction.setImageDescriptor(Activator.getImageDescriptor("icons/no_process_info.png")); //$NON-NLS-1$
                }
            }
        };
        infoMessageAction.setId("infoMessageAction"); //$NON-NLS-1$
        infoMessageAction.setToolTipText("Information Messages"); //$NON-NLS-1$

        clearAction = new Action("C&lear") { //$NON-NLS-1$
            public void run() {
                MessageContainer.getInstance().clearMessages();
                viewer.refresh();
                toggleClipboardActions((contentProvider.size()) > 0 ? true : false);
            }
        };
        clearAction.setToolTipText("Clear the message view"); //$NON-NLS-1$
        clearAction.setImageDescriptor(Activator.getImageDescriptor("icons/clear.gif")); //$NON-NLS-1$
        clearAction.setEnabled(true);

        copyAction = new Action("&Copy \tCtrl+C") { //$NON-NLS-1$
            public void run() {
                IStructuredSelection selection = (IStructuredSelection) viewer.getSelection();
                if (null != selection) {
                    Collection<IStructuredSelection> values = selection.toList();
                    copyValues(values);
                }
            }
        };
        copyAction.setToolTipText("Copy selected message(s)"); //$NON-NLS-1$
        copyAction.setImageDescriptor(
                PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(ISharedImages.IMG_TOOL_COPY));

        selectAllAction = new Action("Select &All \tCtrl+A") { //$NON-NLS-1$
            public void run() {
                viewer.getTable().selectAll();
                toggleClipboardActions(true);
            }
        };
        selectAllAction.setToolTipText("Select all message(s)"); //$NON-NLS-1$
        selectAllAction.setImageDescriptor(Activator.getImageDescriptor("icons/select_all.png")); //$NON-NLS-1$

        doubleClickAction = new Action() {
            public void run() {
                ISelection selection = viewer.getSelection();
                Object obj = ((IStructuredSelection) selection).getFirstElement();
                showMessage(obj.toString());
            }
        };
    }

    /**
     * Toggle clip board actions. If empty disable clear, selection of rows and the copy UI element
     * @param notEmpty if empty disable clip board UI elements, otherwise enable clip board UI elements
     */
    private void toggleClipboardActions(Boolean notEmpty) {
        if (copyAction.isEnabled() != notEmpty) {
            copyAction.setEnabled(notEmpty);
        }
        if (selectAllAction.isEnabled() != notEmpty) {
            selectAllAction.setEnabled(notEmpty);
        }
        if (clearAction.isEnabled() != notEmpty) {
            clearAction.setEnabled(notEmpty);
        }
    }

    private void copyValues(Collection<IStructuredSelection> values) {
        StringWriter buf = new StringWriter();
        PrintWriter writer = new PrintWriter(buf);
        for (Iterator<IStructuredSelection> i = values.iterator(); i.hasNext();) {
            writer.print(i.next());
            if (i.hasNext())
                writer.println();
        }
        writer.close();
        Clipboard clipboard = new Clipboard(Activator.getDisplay());
        Object[] o = new Object[] { buf.toString() };
        Transfer[] t = new Transfer[] { TextTransfer.getInstance() };
        clipboard.setContents(o, t);
        clipboard.dispose();
    }

    private void showMessage(String message) {
        MessageDialog.openInformation(viewer.getControl().getShell(), "Message View", message); //$NON-NLS-1$
    }

    /**
     * Sets the input to the {@link MessageContainer}
     * @param instance the container providing content
     */
    public void setInput(MessageContainer instance) {
        viewer.setInput(instance);
        // Always enabled when there are messages to clear
        // Content provider initialized in create part
        if (null != contentProvider) {
            toggleClipboardActions((contentProvider.size()) > 0 ? true : false);
        }
    }

    /**
     * Passing the focus request to the viewer's control.
     */
    public void setFocus() {
        viewer.getControl().setFocus();
    }

    @Override
    public void dispose() {
        super.dispose();
    }
}