org.rssowl.ui.internal.dialogs.preferences.SharingPreferencesPage.java Source code

Java tutorial

Introduction

Here is the source code for org.rssowl.ui.internal.dialogs.preferences.SharingPreferencesPage.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.dialogs.preferences;

import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.preference.PreferencePage;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.resource.LocalResourceManager;
import org.eclipse.jface.util.LocalSelectionTransfer;
import org.eclipse.jface.util.SafeRunnable;
import org.eclipse.jface.viewers.CellLabelProvider;
import org.eclipse.jface.viewers.CheckStateChangedEvent;
import org.eclipse.jface.viewers.CheckboxTableViewer;
import org.eclipse.jface.viewers.ICheckStateListener;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerCell;
import org.eclipse.jface.viewers.ViewerDropAdapter;
import org.eclipse.swt.SWT;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.DragSourceAdapter;
import org.eclipse.swt.dnd.DragSourceEvent;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.dnd.TransferData;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPreferencePage;
import org.rssowl.core.Owl;
import org.rssowl.core.internal.persist.pref.DefaultPreferences;
import org.rssowl.core.persist.pref.IPreferenceScope;
import org.rssowl.core.util.LoggingSafeRunnable;
import org.rssowl.core.util.StringUtils;
import org.rssowl.ui.internal.ApplicationWorkbenchWindowAdvisor;
import org.rssowl.ui.internal.Controller;
import org.rssowl.ui.internal.OwlUI;
import org.rssowl.ui.internal.ShareProvider;
import org.rssowl.ui.internal.util.CColumnLayoutData;
import org.rssowl.ui.internal.util.CColumnLayoutData.Size;
import org.rssowl.ui.internal.util.CTable;
import org.rssowl.ui.internal.util.LayoutUtils;

import java.util.ArrayList;
import java.util.List;

/**
 * A {@link PreferencePage} to configure {@link ShareProvider}.
 *
 * @author bpasero
 */
public class SharingPreferencesPage extends PreferencePage implements IWorkbenchPreferencePage {

    /** ID of the Page */
    public static final String ID = "org.rssowl.ui.SharingPreferencesPage"; //$NON-NLS-1$

    private LocalResourceManager fResources;
    private IPreferenceScope fPreferences;
    private Button fMoveDownButton;
    private Button fMoveUpButton;
    private CheckboxTableViewer fViewer;
    private int[] fInitialShareProviderState;

    /** Leave for reflection */
    public SharingPreferencesPage() {
        setImageDescriptor(OwlUI.getImageDescriptor("icons/elcl16/share.gif")); //$NON-NLS-1$
        fResources = new LocalResourceManager(JFaceResources.getResources());
        fPreferences = Owl.getPreferenceService().getGlobalScope();
    }

    /*
     * @see org.eclipse.ui.IWorkbenchPreferencePage#init(org.eclipse.ui.IWorkbench)
     */
    public void init(IWorkbench workbench) {
        fInitialShareProviderState = fPreferences.getIntegers(DefaultPreferences.SHARE_PROVIDER_STATE);
    }

    /*
     * @see org.eclipse.jface.preference.PreferencePage#createControl(org.eclipse.swt.widgets.Composite)
     */
    @Override
    public void createControl(Composite parent) {
        super.createControl(parent);
        updateApplyEnablement(false);
    }

    /*
     * @see org.eclipse.jface.preference.PreferencePage#createContents(org.eclipse.swt.widgets.Composite)
     */
    @Override
    protected Control createContents(Composite parent) {
        Composite container = createContainer(parent);

        Label infoText = new Label(container, SWT.WRAP);
        infoText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 2, 1));
        ((GridData) infoText.getLayoutData()).widthHint = 200;
        infoText.setText(Messages.SharingPreferencesPage_SELECT_COMMUNITY);

        Composite tableContainer = new Composite(container, SWT.NONE);
        tableContainer.setLayout(LayoutUtils.createGridLayout(1, 0, 0));
        tableContainer.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));

        CTable cTable = new CTable(tableContainer, SWT.CHECK | SWT.BORDER | SWT.MULTI | SWT.FULL_SELECTION);

        fViewer = new CheckboxTableViewer(cTable.getControl());
        fViewer.getTable().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
        fViewer.getTable().setHeaderVisible(true);
        ((GridData) fViewer.getTable().getLayoutData()).heightHint = fViewer.getTable().getItemHeight() * 15;
        fViewer.getTable().setFocus();
        fViewer.getTable().setData(ApplicationWorkbenchWindowAdvisor.FOCUSLESS_SCROLL_HOOK, new Object());

        TableColumn nameCol = new TableColumn(fViewer.getTable(), SWT.NONE);

        CColumnLayoutData data = new CColumnLayoutData(Size.FILL, 100);
        cTable.manageColumn(nameCol, data, Messages.SharingPreferencesPage_AVAILABLE_COMMUNITIES, null, null, false,
                false);

        /* ContentProvider returns all providers */
        fViewer.setContentProvider(new IStructuredContentProvider() {
            public Object[] getElements(Object inputElement) {
                return Controller.getDefault().getShareProviders().toArray();
            }

            public void dispose() {
            }

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

        /* Label Provider */
        fViewer.setLabelProvider(new CellLabelProvider() {
            @Override
            public void update(ViewerCell cell) {
                ShareProvider provider = (ShareProvider) cell.getElement();
                cell.setText(provider.getName());
                if (StringUtils.isSet(provider.getIconPath()))
                    cell.setImage(fResources
                            .createImage(OwlUI.getImageDescriptor(provider.getPluginId(), provider.getIconPath())));
            }
        });

        /* Selection */
        fViewer.addSelectionChangedListener(new ISelectionChangedListener() {
            public void selectionChanged(SelectionChangedEvent event) {
                updateMoveEnablement();
            }
        });

        /* Drag Support */
        fViewer.addDragSupport(DND.DROP_MOVE, new Transfer[] { LocalSelectionTransfer.getTransfer() },
                new DragSourceAdapter() {
                    @Override
                    public void dragStart(final DragSourceEvent event) {
                        SafeRunnable.run(new LoggingSafeRunnable() {
                            public void run() throws Exception {
                                IStructuredSelection selection = (IStructuredSelection) fViewer.getSelection();
                                event.doit = (selection.size() < fViewer.getTable().getItemCount());

                                if (event.doit) {
                                    LocalSelectionTransfer.getTransfer().setSelection(selection);
                                    LocalSelectionTransfer.getTransfer()
                                            .setSelectionSetTime(event.time & 0xFFFFFFFFL);
                                }
                                ;
                            }
                        });
                    }

                    @Override
                    public void dragSetData(final DragSourceEvent event) {
                        SafeRunnable.run(new LoggingSafeRunnable() {
                            public void run() throws Exception {
                                if (LocalSelectionTransfer.getTransfer().isSupportedType(event.dataType))
                                    event.data = LocalSelectionTransfer.getTransfer().getSelection();
                            }
                        });
                    }

                    @Override
                    public void dragFinished(DragSourceEvent event) {
                        SafeRunnable.run(new LoggingSafeRunnable() {
                            public void run() throws Exception {
                                LocalSelectionTransfer.getTransfer().setSelection(null);
                                LocalSelectionTransfer.getTransfer().setSelectionSetTime(0);
                            }
                        });
                    }
                });

        /* Drop Support */
        ViewerDropAdapter dropSupport = new ViewerDropAdapter(fViewer) {

            @Override
            public boolean validateDrop(Object target, int operation, TransferData transferType) {
                return true;
            }

            @Override
            public boolean performDrop(Object data) {
                ShareProvider target = (ShareProvider) getCurrentTarget();
                if (target != null) {
                    onMove((StructuredSelection) data, target, getCurrentLocation());
                    return true;
                }

                return false;
            }
        };
        dropSupport.setFeedbackEnabled(true);
        dropSupport.setScrollEnabled(true);
        dropSupport.setSelectionFeedbackEnabled(true);
        fViewer.addDropSupport(DND.DROP_MOVE, new Transfer[] { LocalSelectionTransfer.getTransfer() }, dropSupport);

        /* Set input (ignored by ContentProvider anyways) */
        fViewer.setInput(this);
        updateCheckedState();

        /* Ensure that the first checked element is visible */
        TableItem[] items = fViewer.getTable().getItems();
        for (TableItem item : items) {
            if (item.getChecked()) {
                fViewer.getTable().showItem(item);
                break;
            }
        }

        /* Listen on Check State Changes */
        fViewer.addCheckStateListener(new ICheckStateListener() {
            public void checkStateChanged(CheckStateChangedEvent event) {
                ShareProvider provider = (ShareProvider) event.getElement();
                provider.setEnabled(event.getChecked());
                save();
                fViewer.update(provider, null);
            }
        });

        /* Container for the Buttons to Manage Providers */
        Composite buttonContainer = new Composite(container, SWT.None);
        buttonContainer.setLayout(LayoutUtils.createGridLayout(1, 0, 0));
        buttonContainer.setLayoutData(new GridData(SWT.BEGINNING, SWT.FILL, false, false));

        /* Move Provider Up */
        fMoveUpButton = new Button(buttonContainer, SWT.PUSH);
        fMoveUpButton.setText(Messages.SharingPreferencesPage_MOVE_UP);
        fMoveUpButton.setEnabled(false);
        Dialog.applyDialogFont(fMoveUpButton);
        setButtonLayoutData(fMoveUpButton);
        fMoveUpButton.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                onMove(true);
            }
        });

        /* Move Provider Down */
        fMoveDownButton = new Button(buttonContainer, SWT.PUSH);
        fMoveDownButton.setText(Messages.SharingPreferencesPage_MOVE_DOWN);
        fMoveDownButton.setEnabled(false);
        Dialog.applyDialogFont(fMoveDownButton);
        setButtonLayoutData(fMoveDownButton);
        fMoveDownButton.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                onMove(false);
            }
        });

        /* Select All */
        Button selectAllButton = new Button(buttonContainer, SWT.PUSH);
        selectAllButton.setText(Messages.SharingPreferencesPage_SELECT_ALL);
        Dialog.applyDialogFont(selectAllButton);
        setButtonLayoutData(selectAllButton);
        ((GridData) selectAllButton.getLayoutData()).verticalIndent = 10;
        selectAllButton.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                onSelectAll(false);
            }
        });

        /* De-Select All */
        Button deSelectAllButton = new Button(buttonContainer, SWT.PUSH);
        deSelectAllButton.setText(Messages.SharingPreferencesPage_DESELECT_ALL);
        Dialog.applyDialogFont(deSelectAllButton);
        setButtonLayoutData(deSelectAllButton);
        deSelectAllButton.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                onSelectAll(true);
            }
        });

        /* Info Container */
        Composite infoContainer = new Composite(container, SWT.None);
        infoContainer.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 2, 1));
        infoContainer.setLayout(LayoutUtils.createGridLayout(2, 0, 0));

        Label infoImg = new Label(infoContainer, SWT.NONE);
        infoImg.setImage(OwlUI.getImage(fResources, "icons/obj16/info.gif")); //$NON-NLS-1$
        infoImg.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));

        Label infoTextLabel = new Label(infoContainer, SWT.WRAP);
        infoTextLabel.setText(Messages.SharingPreferencesPage_COMMUNITY_INFO);
        infoTextLabel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));

        applyDialogFont(container);

        /* Enable Apply Button on Selection Changes */
        OwlUI.runOnSelection(new Runnable() {
            public void run() {
                updateApplyEnablement(true);
            }
        }, container);

        return container;
    }

    private Composite createContainer(Composite parent) {
        Composite composite = new Composite(parent, SWT.NULL);
        GridLayout layout = new GridLayout(2, false);
        layout.marginWidth = 0;
        layout.marginHeight = 0;
        composite.setLayout(layout);
        composite.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_FILL | GridData.HORIZONTAL_ALIGN_FILL));
        composite.setFont(parent.getFont());
        return composite;
    }

    private void onSelectAll(boolean deselect) {
        TableItem[] items = fViewer.getTable().getItems();
        for (int i = 0; i < items.length; i++) {
            TableItem tableItem = items[i];
            ShareProvider provider = (ShareProvider) tableItem.getData();
            provider.setEnabled(!deselect);
            fViewer.setChecked(provider, !deselect);
        }

        save();
        fViewer.refresh();
    }

    private void save() {
        TableItem[] items = fViewer.getTable().getItems();
        int[] newState = new int[items.length];

        for (int i = 0; i < items.length; i++) {
            TableItem tableItem = items[i];
            ShareProvider provider = (ShareProvider) tableItem.getData();

            int index = provider.getIndex();
            index++; //Adjust to non-zero indexing
            if (!provider.isEnabled())
                index = index * -1;

            newState[i] = index;
        }

        fPreferences.putIntegers(DefaultPreferences.SHARE_PROVIDER_STATE, newState);
    }

    private void updateMoveEnablement() {
        boolean enableMoveUp = true;
        boolean enableMoveDown = true;
        int[] selectionIndices = fViewer.getTable().getSelectionIndices();
        if (selectionIndices.length == 1) {
            enableMoveUp = selectionIndices[0] != 0;
            enableMoveDown = selectionIndices[0] != fViewer.getTable().getItemCount() - 1;
        } else {
            enableMoveUp = false;
            enableMoveDown = false;
        }

        fMoveUpButton.setEnabled(enableMoveUp);
        fMoveDownButton.setEnabled(enableMoveDown);
    }

    private void onMove(boolean up) {
        TableItem[] items = fViewer.getTable().getItems();
        List<ShareProvider> sortedProviders = new ArrayList<ShareProvider>(items.length);
        for (TableItem item : items) {
            sortedProviders.add((ShareProvider) item.getData());
        }

        IStructuredSelection selection = (IStructuredSelection) fViewer.getSelection();
        ShareProvider selectedProvider = (ShareProvider) selection.getFirstElement();

        int[] order = fPreferences.getIntegers(DefaultPreferences.SHARE_PROVIDER_STATE);
        int selectedIndex = sortedProviders.indexOf(selectedProvider);

        /* Move Up */
        if (up && selectedIndex > 0) {
            int order1 = order[selectedIndex];
            int order2 = order[selectedIndex - 1];
            order[selectedIndex] = order2;
            order[selectedIndex - 1] = order1;
        }

        /* Move Down */
        else if (!up && selectedIndex < sortedProviders.size() - 1) {
            int order1 = order[selectedIndex];
            int order2 = order[selectedIndex + 1];
            order[selectedIndex] = order2;
            order[selectedIndex + 1] = order1;
        }

        fPreferences.putIntegers(DefaultPreferences.SHARE_PROVIDER_STATE, order);
        fViewer.refresh();
        fViewer.getTable().showSelection();
        updateCheckedState();
        updateMoveEnablement();
    }

    private void onMove(StructuredSelection selection, ShareProvider destination, int location) {

        /* Determine Moved Items */
        List<ShareProvider> movedItems = new ArrayList<ShareProvider>();
        Object[] selectedElements = selection.toArray();
        for (Object element : selectedElements) {
            movedItems.add((ShareProvider) element);
        }

        /* Determine Visible Items */
        List<ShareProvider> visibleItems = new ArrayList<ShareProvider>();
        TableItem[] items = fViewer.getTable().getItems();
        for (TableItem item : items) {
            visibleItems.add((ShareProvider) item.getData());
        }

        /* Return in these unlikely cases */
        if (movedItems.isEmpty() || visibleItems.isEmpty())
            return;

        /* Remove all Moved Items from Visible */
        visibleItems.removeAll(movedItems);

        /* Put Moved Items to Destination Index if possible */
        int destinationIndex = visibleItems.indexOf(destination);
        if (destinationIndex >= 0) {

            /* Adjust Destination */
            if (location == ViewerDropAdapter.LOCATION_ON || location == ViewerDropAdapter.LOCATION_AFTER)
                destinationIndex++;

            /* Add to Visible */
            visibleItems.addAll(destinationIndex, movedItems);

            /* Save Visible */
            int[] newState = new int[items.length];
            for (int i = 0; i < visibleItems.size(); i++) {
                ShareProvider provider = visibleItems.get(i);

                int index = provider.getIndex();
                index++; //Adjust to non-zero indexing
                if (!provider.isEnabled())
                    index = index * -1;

                newState[i] = index;
            }

            fPreferences.putIntegers(DefaultPreferences.SHARE_PROVIDER_STATE, newState);

            /* Show Updates */
            fViewer.refresh();

            /* Restore Selection */
            fViewer.getTable().setSelection(destinationIndex, destinationIndex + movedItems.size() - 1);

            /* Update */
            updateCheckedState();
            updateMoveEnablement();
        }
    }

    private void updateCheckedState() {
        TableItem[] items = fViewer.getTable().getItems();
        for (TableItem item : items) {
            ShareProvider provider = (ShareProvider) item.getData();
            fViewer.setChecked(provider, provider.isEnabled());
        }
    }

    /*
     * @see org.eclipse.jface.preference.PreferencePage#performOk()
     */
    @Override
    public boolean performOk() {
        save();
        return super.performOk();
    }

    /*
     * @see org.eclipse.jface.preference.PreferencePage#performDefaults()
     */
    @Override
    protected void performDefaults() {
        IPreferenceScope defaultScope = Owl.getPreferenceService().getDefaultScope();
        int[] defaultState = defaultScope.getIntegers(DefaultPreferences.SHARE_PROVIDER_STATE);

        Owl.getPreferenceService().getGlobalScope().putIntegers(DefaultPreferences.SHARE_PROVIDER_STATE,
                defaultState);
        fViewer.refresh();
        updateCheckedState();
        updateMoveEnablement();
        updateApplyEnablement(true);
    }

    /*
     * @see org.eclipse.jface.preference.PreferencePage#performApply()
     */
    @Override
    protected void performApply() {
        super.performApply();
        fInitialShareProviderState = fPreferences.getIntegers(DefaultPreferences.SHARE_PROVIDER_STATE);
        updateApplyEnablement(false);
    }

    /*
     * @see org.eclipse.jface.preference.PreferencePage#performCancel()
     */
    @Override
    public boolean performCancel() {
        fPreferences.putIntegers(DefaultPreferences.SHARE_PROVIDER_STATE, fInitialShareProviderState);
        return super.performCancel();
    }

    /*
     * @see org.eclipse.jface.dialogs.DialogPage#dispose()
     */
    @Override
    public void dispose() {
        super.dispose();
        fResources.dispose();
    }

    private void updateApplyEnablement(boolean enable) {
        Button applyButton = getApplyButton();
        if (applyButton != null && !applyButton.isDisposed() && applyButton.isEnabled() != enable)
            applyButton.setEnabled(enable);
    }
}