org.rssowl.ui.internal.views.explorer.BookMarkViewer.java Source code

Java tutorial

Introduction

Here is the source code for org.rssowl.ui.internal.views.explorer.BookMarkViewer.java

Source

/*   **********************************************************************  **
 **   Copyright notice                                                       **
 **                                                                          **
 **   (c) 2005-2009 RSSOwl Development Team                                  **
 **   http://www.rssowl.org/                                                 **
 **                                                                          **
 **   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.rssowl.org/legal/epl-v10.html                               **
 **                                                                          **
 **   A copy is found in the file epl-v10.html and important notices to the  **
 **   license from the team is found in the textfile LICENSE.txt distributed **
 **   in this package.                                                       **
 **                                                                          **
 **   This copyright notice MUST APPEAR in all copies of the file!           **
 **                                                                          **
 **   Contributors:                                                          **
 **     RSSOwl Development Team - initial API and implementation             **
 **                                                                          **
 **  **********************************************************************  */

package org.rssowl.ui.internal.views.explorer;

import org.eclipse.core.runtime.ListenerList;
import org.eclipse.jface.util.IOpenEventListener;
import org.eclipse.jface.util.SafeRunnable;
import org.eclipse.jface.viewers.IOpenListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.OpenEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeItem;
import org.eclipse.swt.widgets.Widget;
import org.rssowl.ui.internal.util.TreeItemAdapter;
import org.rssowl.ui.internal.util.ViewerOpenStrategy;

import java.util.List;

/**
 * A Subclass of <code>TreeViewer</code> to display Folders and all kinds of
 * Marks in the "Feeds" view.
 *
 * @author bpasero
 */
public class BookMarkViewer extends TreeViewer {
    private final BookMarkExplorer fExplorer;
    private ListenerList fOpenListeners = new ListenerList();
    private ViewerOpenStrategy fViewerOpenStrategy;

    /**
     * @param explorer
     * @param parent
     * @param style
     */
    public BookMarkViewer(BookMarkExplorer explorer, Composite parent, int style) {
        super(parent, style);
        fExplorer = explorer;
    }

    /*
     * @see org.eclipse.jface.viewers.TreeViewer#createChildren(org.eclipse.swt.widgets.Widget)
     */
    @Override
    public void createChildren(Widget widget) {
        super.createChildren(widget);
    }

    /*
     * @see org.eclipse.jface.viewers.StructuredViewer#refresh(boolean)
     */
    @Override
    public void refresh(boolean updateLabels) {
        getControl().getParent().setRedraw(false);
        try {
            super.refresh(updateLabels);
        } finally {
            getControl().getParent().setRedraw(true);
        }
    }

    /*
     * @see org.eclipse.jface.viewers.ColumnViewer#refresh(java.lang.Object)
     */
    @Override
    public void refresh(Object element) {
        super.refresh(element);

        /* Avoid restoring expanded elements on refresh() */
        if (element == getRoot())
            return;

        /* TODO Revisit later */
        fExplorer.restoreExpandedElements();
    }

    /*
     * @see org.eclipse.jface.viewers.StructuredViewer#refresh(java.lang.Object,
     * boolean)
     */
    @Override
    public void refresh(Object element, boolean updateLabels) {
        super.refresh(element, updateLabels);

        /* TODO Revisit later */
        fExplorer.restoreExpandedElements();
    }

    /*
     * @see org.eclipse.jface.viewers.AbstractTreeViewer#remove(java.lang.Object[])
     */
    @Override
    public void remove(final Object[] elements) {
        updateSelectionAfterDelete(new Runnable() {
            public void run() {
                internalRemove(elements);
            }
        });
    }

    /*
     * @see org.eclipse.jface.viewers.Viewer#setSelection(org.eclipse.jface.viewers.ISelection)
     */
    @Override
    public void setSelection(ISelection selection) {
        super.setSelection(selection);
        if (fViewerOpenStrategy != null)
            fViewerOpenStrategy.clearExpandFlag(); // See Bug 164372
    }

    /*
     * @see org.eclipse.jface.viewers.StructuredViewer#setSelection(org.eclipse.jface.viewers.ISelection,
     * boolean)
     */
    @Override
    public void setSelection(ISelection selection, boolean reveal) {
        super.setSelection(selection, reveal);
        if (fViewerOpenStrategy != null)
            fViewerOpenStrategy.clearExpandFlag(); // See Bug 164372
    }

    /*
     * @see org.eclipse.jface.viewers.TreeViewer#setSelection(java.util.List)
     */
    @SuppressWarnings("unchecked")
    @Override
    protected void setSelection(List items) {
        super.setSelection(items);
        if (fViewerOpenStrategy != null)
            fViewerOpenStrategy.clearExpandFlag(); // See Bug 164372
    }

    /*
     * @see org.eclipse.jface.viewers.AbstractTreeViewer#setSelectionToWidget(org.eclipse.jface.viewers.ISelection, boolean)
     */
    @Override
    protected void setSelectionToWidget(ISelection selection, boolean reveal) {
        super.setSelectionToWidget(selection, reveal);
        if (fViewerOpenStrategy != null)
            fViewerOpenStrategy.clearExpandFlag(); // See Bug 164372
    }

    /*
     * @see org.eclipse.jface.viewers.AbstractTreeViewer#setSelectionToWidget(java.util.List, boolean)
     */
    @SuppressWarnings("unchecked")
    @Override
    protected void setSelectionToWidget(List v, boolean reveal) {
        super.setSelectionToWidget(v, reveal);
        if (fViewerOpenStrategy != null)
            fViewerOpenStrategy.clearExpandFlag(); // See Bug 164372
    }

    /*
     * @see org.eclipse.jface.viewers.TreeViewer#hookControl(org.eclipse.swt.widgets.Control)
     */
    @Override
    protected void hookControl(Control control) {
        super.hookControl(control);

        /* Add a ViewerOpenStrategy */
        fViewerOpenStrategy = new ViewerOpenStrategy(control);
        fViewerOpenStrategy.addOpenListener(new IOpenEventListener() {
            public void handleOpen(SelectionEvent e) {
                internalHandleOpen();
            }
        });
    }

    /*
     * Overrides the open-listener to work with the ViewerOpenStrategy.
     *
     * @see org.eclipse.jface.viewers.StructuredViewer#addOpenListener(org.eclipse.jface.viewers.IOpenListener)
     */
    @Override
    public void addOpenListener(IOpenListener listener) {
        fOpenListeners.add(listener);
    }

    private void internalHandleOpen() {
        Control control = getControl();
        if (control != null && !control.isDisposed()) {
            ISelection selection = getSelection();
            internalFireOpen(new OpenEvent(this, selection));
        }
    }

    private void internalFireOpen(final OpenEvent event) {
        Object[] listeners = fOpenListeners.getListeners();
        for (int i = 0; i < listeners.length; ++i) {
            final IOpenListener listener = (IOpenListener) listeners[i];
            SafeRunnable.run(new SafeRunnable() {
                public void run() {
                    listener.open(event);
                }
            });
        }
    }

    private void updateSelectionAfterDelete(Runnable runnable) {
        Tree tree = (Tree) getControl();
        IStructuredSelection selection = (IStructuredSelection) getSelection();

        /* Nothing to do, since no selection */
        if (selection.isEmpty()) {
            runnable.run();
            return;
        }

        /* Look for the minimal Index of all selected Elements */
        int minSelectedIndex = Integer.MAX_VALUE;
        TreeItemAdapter parentOfMinSelected = new TreeItemAdapter(tree);

        /* For each selected Element */
        Object[] selectedElements = selection.toArray();
        for (Object selectedElement : selectedElements) {
            Widget widget = findItem(selectedElement);
            if (widget instanceof TreeItem) {
                TreeItem item = (TreeItem) widget;
                TreeItemAdapter parent = new TreeItemAdapter(item).getParent();

                int index = parent.indexOf(item);
                minSelectedIndex = Math.min(minSelectedIndex, index);
                if (index == minSelectedIndex)
                    parentOfMinSelected.setItem(parent.getItem());
            }
        }

        /* Perform Deletion */
        runnable.run();

        Object data = null;

        /* Parent itself has been deleted */
        if (parentOfMinSelected.getItem().isDisposed())
            return;

        /* Restore selection to next Element */
        if (parentOfMinSelected.getItemCount() > minSelectedIndex)
            data = parentOfMinSelected.getItem(minSelectedIndex).getData();

        /* Restore selection to last Element */
        else if (parentOfMinSelected.getItemCount() > 0)
            data = parentOfMinSelected.getItem(parentOfMinSelected.getItemCount() - 1).getData();

        /* Restore selection on actual Element */
        else
            data = parentOfMinSelected.getItem().getData();

        /* Apply selection */
        if (data != null) {
            IStructuredSelection newSelection = new StructuredSelection(data);
            setSelection(newSelection);
        }
    }
}