sernet.verinice.rcp.IconSelectDialog.java Source code

Java tutorial

Introduction

Here is the source code for sernet.verinice.rcp.IconSelectDialog.java

Source

/*******************************************************************************
 * Copyright (c) 2012 Daniel Murygin.
 *
 * This program is free software: you can redistribute it and/or 
 * modify it under the terms of the GNU Lesser General Public License 
 * as published by the Free Software Foundation, either version 3 
 * of the License, or (at your option) any later version.
 * This program is distributed in the hope that it will be useful,    
 * but WITHOUT ANY WARRANTY; without even the implied warranty 
 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
 * See the GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program. 
 * If not, see <http://www.gnu.org/licenses/>.
 * 
 * Contributors:
 *     Daniel Murygin <dm[at]sernet[dot]de> - initial API and implementation
 ******************************************************************************/
package sernet.verinice.rcp;

import java.io.File;
import java.io.FileFilter;
import java.net.URI;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.apache.commons.io.filefilter.DirectoryFileFilter;
import org.apache.log4j.Logger;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.ColumnViewerEditor;
import org.eclipse.jface.viewers.ColumnViewerEditorActivationEvent;
import org.eclipse.jface.viewers.ColumnViewerEditorActivationStrategy;
import org.eclipse.jface.viewers.FocusCellOwnerDrawHighlighter;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.jface.viewers.TableViewerEditor;
import org.eclipse.jface.viewers.TableViewerFocusCellManager;
import org.eclipse.jface.viewers.ViewerCell;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;

import sernet.gs.ui.rcp.main.Activator;
import sernet.verinice.iso27k.rcp.ComboModel;
import sernet.verinice.iso27k.rcp.IComboModelLabelProvider;

/**
 * 
 * 
 * @author Daniel Murygin <dm[at]sernet[dot]de>
 */
public class IconSelectDialog extends Dialog {

    private static final Logger LOG = Logger.getLogger(IconSelectDialog.class);

    public static final String ICON_DIRECTORY = "tree-icons"; //$NON-NLS-1$

    private static final FileFilter ICON_FILE_FILTER = new IconFileFilter();

    private static final int SIZE_Y = 370;
    private static final int SIZE_X = 485;
    private static final int NUMBER_OF_COLUMNS = 10;
    private static final int ICON_SPACING = 10;
    private static final int THUMBNAIL_SIZE = 20;

    private Combo dirCombo;
    private ComboModel<IconPathDescriptor> dirComboModel;

    private TableViewer viewer;

    private IconPathDescriptor directory;

    private String selectedPath;

    private boolean defaultIcon = false;

    /**
     * @param parentShell
     */
    protected IconSelectDialog(Shell parentShell) {
        super(parentShell);
        initComboValues();
    }

    private void initComboValues() {
        dirComboModel = new ComboModel<IconPathDescriptor>(new IComboModelLabelProvider<IconPathDescriptor>() {
            @Override
            public String getLabel(IconPathDescriptor descriptor) {
                return descriptor.getName();
            }
        });
        URL[] inconUrlArray = FileLocator.findEntries(Platform.getBundle(Activator.PLUGIN_ID),
                new Path(ICON_DIRECTORY), null);

        try {
            for (URL inconUrl : inconUrlArray) {
                if (LOG.isDebugEnabled()) {
                    LOG.debug("Icon dir: " + inconUrl); //$NON-NLS-1$
                }

                URL realFileUrl = FileLocator.toFileURL(inconUrl);
                String urlString = realFileUrl.toExternalForm();
                urlString = urlString.replaceAll(" ", "%20");
                File baseDir = new File(URI.create(urlString));
                if (LOG.isDebugEnabled()) {
                    LOG.debug("Icon dir (file system): " + baseDir.getPath()); //$NON-NLS-1$
                }
                String[] directories = baseDir.list(DirectoryFileFilter.INSTANCE);
                for (String dir : directories) {
                    if (!dir.startsWith(".")) { //$NON-NLS-1$
                        dirComboModel.add(new IconPathDescriptor(dir, baseDir.getPath() + File.separator + dir));
                    }
                }
            }
        } catch (Exception e) {
            LOG.error("Error while reading icon directory: " + ICON_DIRECTORY, e); //$NON-NLS-1$
            return;
        }

        if (!dirComboModel.isEmpty()) {
            dirComboModel.sort();
        }
    }

    public void showComboValues() {
        dirCombo.setItems(dirComboModel.getLabelArray());
        if (dirComboModel.isEmpty()) {
            dirCombo.setEnabled(false);
        }
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * org.eclipse.jface.dialogs.Dialog#createDialogArea(org.eclipse.swt.widgets
     * .Composite)
     */
    @Override
    protected Control createDialogArea(Composite parent) {

        final int gridDataSizeSubtrahend = 20;

        Composite comp = (Composite) super.createDialogArea(parent);

        Label dirLabel = new Label(comp, SWT.NONE);
        dirLabel.setText(Messages.IconSelectDialog_5);
        dirCombo = new Combo(comp, SWT.VERTICAL | SWT.DROP_DOWN | SWT.BORDER | SWT.READ_ONLY);
        GridData gd = new GridData(SWT.FILL, SWT.TOP, true, false);
        dirCombo.setLayoutData(gd);
        dirCombo.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                dirComboModel.setSelectedIndex(dirCombo.getSelectionIndex());
                directory = dirComboModel.getSelectedObject();
                loadIcons(directory.getPath());
            }
        });
        showComboValues();

        Group group = new Group(comp, SWT.NONE);
        group.setText(Messages.IconSelectDialog_6);
        GridLayout groupOrganizationLayout = new GridLayout(1, true);
        group.setLayout(groupOrganizationLayout);
        gd = new GridData(SWT.FILL, SWT.FILL, true, true);
        gd.minimumWidth = SIZE_Y - gridDataSizeSubtrahend;
        gd.heightHint = SIZE_X - gridDataSizeSubtrahend;
        group.setLayoutData(gd);

        createTable(group);

        group.layout();

        final Button defaultCheckbox = new Button(comp, SWT.CHECK);
        defaultCheckbox.setText(Messages.IconSelectDialog_7);
        defaultCheckbox.setSelection(false);
        defaultCheckbox.addSelectionListener(new SelectionListener() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                defaultIcon = defaultCheckbox.isEnabled();
            }

            @Override
            public void widgetDefaultSelected(SelectionEvent e) {
            }
        });

        comp.pack();
        return comp;
    }

    private void loadIcons(String path) {
        final int maxRowCount = 10;
        File internalDirectory = new File(path);
        File[] files = internalDirectory.listFiles(ICON_FILE_FILTER);
        Arrays.sort(files);

        List<IconDescriptor[]> iconDescriptorList = new ArrayList<IconDescriptor[]>();
        IconDescriptor[] iconRow = new IconDescriptor[NUMBER_OF_COLUMNS];
        int i = 0;
        for (File file : files) {
            iconRow[i] = new IconDescriptor(file);
            i++;
            if (i == maxRowCount) {
                iconDescriptorList.add(iconRow);
                iconRow = new IconDescriptor[NUMBER_OF_COLUMNS];
                i = 0;
            }
        }
        if (i != 0) {
            iconDescriptorList.add(iconRow);
        }
        IconDescriptor[][] iconDescriptorArray = null;
        iconDescriptorArray = iconDescriptorList
                .toArray(new IconDescriptor[iconDescriptorList.size()][NUMBER_OF_COLUMNS]);
        viewer.setInput(iconDescriptorArray);
    }

    private void createTable(Composite parent) {

        final int gdHeightSubtrahend = 100;
        final int iconRowSize = 10;

        int style = SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER;
        style = style | SWT.SINGLE | SWT.FULL_SELECTION;
        viewer = new TableViewer(parent, style);
        viewer.setContentProvider(new ArrayContentProvider());

        TableViewerFocusCellManager focusCellManager = new TableViewerFocusCellManager(viewer,
                new FocusCellOwnerDrawHighlighter(viewer));
        ColumnViewerEditorActivationStrategy actSupport = new ColumnViewerEditorActivationStrategy(viewer) {
            @Override
            protected boolean isEditorActivationEvent(ColumnViewerEditorActivationEvent event) {
                boolean retVal = event.eventType == ColumnViewerEditorActivationEvent.TRAVERSAL
                        || event.eventType == ColumnViewerEditorActivationEvent.MOUSE_DOUBLE_CLICK_SELECTION;
                retVal = retVal || (event.eventType == ColumnViewerEditorActivationEvent.KEY_PRESSED
                        && event.keyCode == SWT.CR);
                return retVal || event.eventType == ColumnViewerEditorActivationEvent.PROGRAMMATIC;
            }
        };

        TableViewerEditor.create(viewer, focusCellManager, actSupport,
                ColumnViewerEditor.TABBING_HORIZONTAL | ColumnViewerEditor.TABBING_MOVE_TO_ROW_NEIGHBOR
                        | ColumnViewerEditor.TABBING_VERTICAL | ColumnViewerEditor.KEYBOARD_ACTIVATION);

        Table table = viewer.getTable();
        GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true);
        gd.heightHint = SIZE_X - gdHeightSubtrahend;
        table.setLayoutData(gd);

        table.addListener(SWT.MeasureItem, new Listener() {
            @Override
            public void handleEvent(Event event) {
                // height cannot be per row so simply set
                event.height = getThumbnailSize() + ICON_SPACING;
            }
        });

        table.addMouseListener(new MouseListener() {

            @Override
            public void mouseUp(MouseEvent e) {
            }

            @Override
            public void mouseDown(MouseEvent e) {
                ViewerCell cell = viewer.getCell(new Point(e.x, e.y));
                if (cell != null) {
                    selectedPath = getRelativePath(
                            ((IconDescriptor[]) cell.getElement())[cell.getColumnIndex()].getPath());
                    if (LOG.isDebugEnabled()) {
                        LOG.debug("Icon: " + selectedPath); //$NON-NLS-1$
                    }
                }

            }

            @Override
            public void mouseDoubleClick(MouseEvent e) {
            }
        });

        for (int i = 0; i < iconRowSize; i++) {
            TableViewerColumn imageColumn = new TableViewerColumn(viewer, SWT.LEFT);
            imageColumn.setLabelProvider(new IconCellProvider(i));
            imageColumn.getColumn().setWidth(getThumbnailSize() + ICON_SPACING);
        }

        if (!dirComboModel.isEmpty()) {
            dirComboModel.setSelectedIndex(2);
            dirCombo.select(2);
            directory = dirComboModel.getSelectedObject();
            loadIcons(directory.getPath());
        } else {
            loadIcons(ICON_DIRECTORY + "silk"); //$NON-NLS-1$
        }
    }

    /**
     * @param path
     * @return
     */
    protected String getRelativePath(String path) {
        String relative = path;
        if (path.contains(ICON_DIRECTORY)) {
            relative = path.substring(path.indexOf(ICON_DIRECTORY));
        }
        if (relative.contains("\\")) { //$NON-NLS-1$
            relative = relative.replace('\\', '/');
        }
        return relative;
    }

    /**
     * @return
     */
    protected int getThumbnailSize() {
        return THUMBNAIL_SIZE;
    }

    public String getSelectedPath() {
        return selectedPath;
    }

    public boolean isDefaultIcon() {
        return defaultIcon;
    }

    public boolean isSomethingSelected() {
        return defaultIcon || getSelectedPath() != null;
    }

    @Override
    protected void configureShell(Shell newShell) {
        super.configureShell(newShell);
        newShell.setText(Messages.IconSelectDialog_11);
        newShell.setSize(SIZE_Y, SIZE_X);

        // open the window right under the mouse pointer:
        Point cursorLocation = Display.getCurrent().getCursorLocation();
        newShell.setLocation(new Point(cursorLocation.x - SIZE_X / 2, cursorLocation.y - SIZE_Y / 2));

    }
}

class IconFileFilter implements FileFilter {

    @Override
    public boolean accept(File file) {
        boolean accept = false;
        if (file != null && file.getName() != null) {
            String filename = file.getName().toLowerCase();
            accept = filename.endsWith("gif") || filename.endsWith("png"); //$NON-NLS-1$ //$NON-NLS-2$
        }
        return accept;
    }
}