com.bdaum.zoom.ui.internal.dialogs.CodesDialog.java Source code

Java tutorial

Introduction

Here is the source code for com.bdaum.zoom.ui.internal.dialogs.CodesDialog.java

Source

/*
 * This file is part of the ZoRa project: http://www.photozora.org.
 *
 * ZoRa is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * ZoRa 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with ZoRa; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * (c) 2011-2017 Berthold Daum  
 */
package com.bdaum.zoom.ui.internal.dialogs;

import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.ColumnViewer;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.TreeViewerColumn;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.BusyIndicator;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;

import com.bdaum.zoom.core.QueryField;
import com.bdaum.zoom.css.ZColumnLabelProvider;
import com.bdaum.zoom.ui.dialogs.ZTitleAreaDialog;
import com.bdaum.zoom.ui.internal.SortColumnManager;
import com.bdaum.zoom.ui.internal.UiActivator;
import com.bdaum.zoom.ui.internal.UiUtilities;
import com.bdaum.zoom.ui.internal.ZViewerComparator;
import com.bdaum.zoom.ui.internal.codes.CodeParser;
import com.bdaum.zoom.ui.internal.codes.Topic;
import com.bdaum.zoom.ui.internal.views.ZColumnViewerToolTipSupport;
import com.bdaum.zoom.ui.internal.widgets.ExpandCollapseGroup;
import com.bdaum.zoom.ui.internal.widgets.FilterField;

public class CodesDialog extends ZTitleAreaDialog {
    private static final Topic[] EMPTYTOPICS = new Topic[0];

    private final class TopicFilter extends ViewerFilter {
        private final boolean deep;
        private final Set<String> filterExclusions;

        public TopicFilter(boolean deep, Set<String> exclusions) {
            this.deep = deep;
            this.filterExclusions = exclusions;
        }

        @Override
        public boolean select(Viewer viewer, Object parentElement, Object element) {
            if (element instanceof Topic)
                return ((Topic) element).isShown(filterField.getFilter(), deep, filterExclusions);
            return false;
        }
    }

    public class TopicContentProvider implements ITreeContentProvider {

        public void dispose() {
            // do nothing
        }

        public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
            // do nothing
        }

        public Object[] getElements(Object inputElement) {
            if (inputElement instanceof Topic[])
                return (Topic[]) inputElement;
            return EMPTYTOPICS;
        }

        public Object[] getChildren(Object parentElement) {
            if (parentElement instanceof Topic) {
                List<Topic> subTopics = ((Topic) parentElement).getSubTopics();
                if (subTopics != null)
                    return subTopics.toArray();
            }
            return EMPTYTOPICS;
        }

        public Object getParent(Object element) {
            if (element instanceof Topic)
                return ((Topic) element).getParent();
            return null;
        }

        public boolean hasChildren(Object element) {
            if (element instanceof Topic)
                return ((Topic) element).getSubTopics() != null;
            return false;
        }

    }

    public class TopicLabelProvider extends ZColumnLabelProvider {
        private final int column;

        public TopicLabelProvider(int column) {
            this.column = column;
        }

        @Override
        public String getText(Object element) {
            if (element instanceof Topic) {
                switch (column) {
                case 0:
                    return ((Topic) element).getCode();
                case 2:
                    return ((Topic) element).getDescription();
                }
            }
            return element.toString();
        }

    }

    private String result;
    private ColumnViewer topicViewer;
    private final String dflt;
    private TableViewer recentViewer;
    private final CodeParser parser;
    private FilterField filterField;
    protected Topic selectedTopic;
    private final Set<String> exclusions;
    private Combo customField;

    private IDoubleClickListener doubleClickListener = new IDoubleClickListener() {
        public void doubleClick(DoubleClickEvent event) {
            okPressed();
        }
    };

    private ISelectionChangedListener selectionChangedListener = new ISelectionChangedListener() {
        public void selectionChanged(SelectionChangedEvent event) {
            IStructuredSelection selection = (IStructuredSelection) event.getSelection();
            if (!selection.isEmpty())
                selectedTopic = ((Topic) selection.getFirstElement());
            updateFields();
            updateButtons();
        }
    };

    public CodesDialog(Shell parentShell, QueryField qfield, String dflt, String[] exclusions) {
        super(parentShell);
        this.parser = UiActivator.getDefault().getCodeParser((Integer) qfield.getEnumeration());
        this.dflt = dflt;
        this.exclusions = exclusions == null ? null : new HashSet<String>(Arrays.asList(exclusions));
    }

    @Override
    public void create() {
        super.create();
        BusyIndicator.showWhile(getShell().getDisplay(), () -> {
            fillValues();
            updateButtons();
            setTitle(parser.getTitle());
            setMessage(parser.getMessage());
        });
    }

    @Override
    protected Control createDialogArea(Composite parent) {
        Composite area = (Composite) super.createDialogArea(parent);
        Composite composite = new Composite(area, SWT.NONE);
        composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
        composite.setLayout(new GridLayout(2, false));
        filterField = new FilterField(composite);
        filterField.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, false, false, 2, 1));
        filterField.addModifyListener(new ModifyListener() {
            public void modifyText(ModifyEvent e) {
                updateViewers();
            }
        });
        if (parser.hasRecentTopics()) {
            Label recentLabel = new Label(composite, SWT.NONE);
            recentLabel.setText(Messages.CodesDialog_recent_topics);
            recentLabel.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, false, false, 2, 1));
            createRecentViewer(composite);
        }
        new Label(composite, SWT.NONE).setText(Messages.CodesDialog_matching_topics);
        createTopicViewer(composite);
        if (parser.isAllowCustomCode()) {
            Label label = new Label(composite, SWT.NONE);
            label.setText(Messages.CodesDialog_custom_code);
            customField = new Combo(composite, SWT.BORDER);
            customField.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
            customField.setItems(parser.getCustomTopics());
            customField.setText(""); //$NON-NLS-1$
            customField.addModifyListener(new ModifyListener() {
                @Override
                public void modifyText(ModifyEvent e) {
                    updateButtons();
                }
            });
        }
        topicViewer.getControl().setFocus();
        return area;
    }

    protected void updateViewers() {
        if (recentViewer != null) {
            ISelection selection = recentViewer.getSelection();
            recentViewer.setInput(recentViewer.getInput());
            recentViewer.setSelection(selection);
        }
        ISelection selection = topicViewer.getSelection();
        topicViewer.setInput(topicViewer.getInput());
        if (topicViewer instanceof TreeViewer && filterField.getFilter() != null)
            ((TreeViewer) topicViewer).expandAll();
        topicViewer.setSelection(selection);
    }

    @SuppressWarnings("unused")
    private void createRecentViewer(Composite composite) {
        recentViewer = new TableViewer(composite, SWT.SINGLE | SWT.V_SCROLL | SWT.FULL_SELECTION | SWT.BORDER);
        GridData layoutData = new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1);
        layoutData.heightHint = 100;
        recentViewer.getTable().setLayoutData(layoutData);
        recentViewer.getTable().setLinesVisible(true);
        recentViewer.getTable().setHeaderVisible(true);
        if (!parser.isByName())
            createTableColumn(recentViewer, 120, Messages.CodesDialog_code, 0);
        createTableColumn(recentViewer, 150, Messages.CodesDialog_name, 1);
        createTableColumn(recentViewer, 300, Messages.CodesDialog_explanation, 2);
        recentViewer.setContentProvider(ArrayContentProvider.getInstance());
        if (parser.isByName())
            new SortColumnManager(recentViewer, new int[] { SWT.UP, SWT.UP }, 0);
        else
            new SortColumnManager(recentViewer, new int[] { SWT.UP, SWT.UP, SWT.UP }, 1);
        recentViewer.setComparator(ZViewerComparator.INSTANCE);
        recentViewer.setFilters(new ViewerFilter[] { new TopicFilter(false, exclusions) });
        recentViewer.addSelectionChangedListener(selectionChangedListener);
        recentViewer.addDoubleClickListener(doubleClickListener);
        ZColumnViewerToolTipSupport.enableFor(recentViewer);
    }

    @SuppressWarnings("unused")
    private void createTopicViewer(Composite composite) {
        ExpandCollapseGroup expandCollapseGroup = null;
        if (parser.hasSubtopics()) {
            expandCollapseGroup = new ExpandCollapseGroup(composite, SWT.NONE);
            TreeViewer treeViewer = new TreeViewer(composite,
                    SWT.SINGLE | SWT.V_SCROLL | SWT.FULL_SELECTION | SWT.BORDER);
            expandCollapseGroup.setViewer((TreeViewer) topicViewer);
            treeViewer.getTree().setLinesVisible(true);
            treeViewer.getTree().setHeaderVisible(true);
            if (!parser.isByName())
                createTreeColumn(treeViewer, 120, Messages.CodesDialog_code, 0);
            createTreeColumn(treeViewer, 150, Messages.CodesDialog_name, 1);
            createTreeColumn(treeViewer, 300, Messages.CodesDialog_explanation, 2);
            UiUtilities.installDoubleClickExpansion(treeViewer);
            topicViewer = treeViewer;
        } else {
            new Label(composite, SWT.NONE);
            TableViewer tableViewer = new TableViewer(composite,
                    SWT.SINGLE | SWT.V_SCROLL | SWT.FULL_SELECTION | SWT.BORDER);
            tableViewer.getTable().setLinesVisible(true);
            tableViewer.getTable().setHeaderVisible(true);
            if (!parser.isByName())
                createTableColumn(tableViewer, 120, Messages.CodesDialog_code, 0);
            createTableColumn(tableViewer, 150, Messages.CodesDialog_name, 1);
            createTableColumn(tableViewer, 300, Messages.CodesDialog_explanation, 2);
            tableViewer.addDoubleClickListener(doubleClickListener);
            topicViewer = tableViewer;
        }
        GridData layoutData = new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1);
        layoutData.heightHint = 300;
        topicViewer.getControl().setLayoutData(layoutData);
        topicViewer.setContentProvider(new TopicContentProvider());
        if (parser.isByName())
            new SortColumnManager(recentViewer, new int[] { SWT.UP, SWT.UP }, 0);
        else
            new SortColumnManager(recentViewer, new int[] { SWT.UP, SWT.UP, SWT.UP }, 1);
        topicViewer.setComparator(ZViewerComparator.INSTANCE);
        topicViewer.setFilters(new ViewerFilter[] { new TopicFilter(true, exclusions) });
        topicViewer.addSelectionChangedListener(selectionChangedListener);
        ZColumnViewerToolTipSupport.enableFor(topicViewer);
    }

    private void createTreeColumn(TreeViewer treeViewer, int width, String text, int index) {
        TreeViewerColumn col = new TreeViewerColumn(treeViewer, SWT.NONE);
        col.getColumn().setWidth(width);
        col.getColumn().setText(text);
        col.setLabelProvider(new TopicLabelProvider(index));
    }

    private void createTableColumn(TableViewer tableViewer, int width, String text, int index) {
        TableViewerColumn col = new TableViewerColumn(tableViewer, SWT.NONE);
        col.getColumn().setWidth(width);
        col.getColumn().setText(text);
        col.setLabelProvider(new TopicLabelProvider(index));
    }

    private void fillValues() {
        topicViewer.setInput(parser.loadCodes());
        if (dflt != null && !dflt.isEmpty()) {
            selectedTopic = parser.findTopic(dflt);
            if (selectedTopic != null)
                topicViewer.setSelection(new StructuredSelection(selectedTopic), true);
            else
                customField.setText(dflt);
        }
        if (recentViewer != null) {
            recentViewer.setInput(parser.getRecentTopics());
            if (selectedTopic != null)
                recentViewer.setSelection(new StructuredSelection(selectedTopic), true);
        }
    }

    @Override
    protected void okPressed() {
        if (customField != null)
            result = customField.getText();
        if ((result == null || result.isEmpty()) && selectedTopic != null)
            result = selectedTopic.getCode();
        if (result == null)
            result = ""; //$NON-NLS-1$
        if (!result.isEmpty() && parser.findTopic(result) == null)
            parser.addCustomTopic(result);
        super.okPressed();
    }

    private void updateButtons() {
        getButton(OK).setEnabled(selectedTopic != null || customField != null && !customField.getText().isEmpty());
    }

    private void updateFields() {
        if (selectedTopic != null && customField != null)
            customField.setText(selectedTopic.getCode());
    }

    public String getResult() {
        return result;
    }

}