de.itemis.tooling.terminology.ui.search.TerminologyEObjectSearchDialog.java Source code

Java tutorial

Introduction

Here is the source code for de.itemis.tooling.terminology.ui.search.TerminologyEObjectSearchDialog.java

Source

/*******************************************************************************
 * Copyright (c) 2013 itemis AG (http://www.itemis.eu).
 * 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
 ******************************************************************************/
package de.itemis.tooling.terminology.ui.search;

import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.Map;

import org.eclipse.emf.common.util.URI;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.internal.text.TableOwnerDrawSupport;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.viewers.CheckStateChangedEvent;
import org.eclipse.jface.viewers.DelegatingStyledCellLabelProvider.IStyledLabelProvider;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.ICheckStateListener;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.ILabelProvider;
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.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.StyledString;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyleRange;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
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.Display;
import org.eclipse.swt.widgets.Event;
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 org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.dialogs.ListDialog;
import org.eclipse.ui.forms.events.ExpansionAdapter;
import org.eclipse.ui.forms.events.ExpansionEvent;
import org.eclipse.ui.forms.widgets.ExpandableComposite;
import org.eclipse.xtext.resource.IEObjectDescription;
import org.eclipse.xtext.resource.IResourceDescriptions;
import org.eclipse.xtext.ui.editor.IURIEditorOpener;
import org.eclipse.xtext.ui.label.AbstractLabelProvider;
import org.eclipse.xtext.ui.search.EObjectDescriptionContentProvider;

import de.itemis.tooling.terminology.terminology.TermStatus;
import de.itemis.tooling.terminology.terminology.TerminologyPackage;
import de.itemis.tooling.terminology.ui.internal.TerminologyActivator;
import de.itemis.tooling.terminology.ui.search.TerminologyEObjectSearch.TerminologySearchPattern;

/**
 * adapted from {@Link org.eclipse.xtext.ui.search.XtextEObjectSearchDialog}
 */
@SuppressWarnings("restriction")
public class TerminologyEObjectSearchDialog extends ListDialog {

    private static final String SETTINGS_SECTION = "Terminology_Search";

    protected Text searchControl;

    private String initialPatternText;

    private Label messageLabel;

    private Label searchStatusLabel;

    private TerminologyIteratorJob sizeCalculationJob;

    private Label matchingElementsLabel;

    private TerminologyEObjectSearch searchEngine;

    private final ILabelProvider labelProvider;

    private boolean enableStyledLabels;

    private IURIEditorOpener uriOpener;

    private Button definitionControl;
    private Button usageControl;
    private Button useCustomerProductsControl;

    private Map<TermStatus, Button> statusControls;
    private EObjectDescriptionCheckboxTableViewer productViewer;
    private EObjectDescriptionCheckboxTableViewer customerViewer;

    private Iterable<IEObjectDescription> possibleProducs;
    private Iterable<IEObjectDescription> possibleCustomers;

    public TerminologyEObjectSearchDialog(Shell parent, TerminologyEObjectSearch searchEngine,
            ILabelProvider labelProvider, IURIEditorOpener uriOpener, IResourceDescriptions index) {
        super(parent);
        this.searchEngine = searchEngine;
        this.labelProvider = new AbstractLabelProvider(labelProvider) {
            @Override
            protected Object doGetText(Object element) {
                if (element instanceof IEObjectDescription) {
                    return ((IEObjectDescription) element).getQualifiedName().getLastSegment();
                }
                return super.doGetText(element);
            }
        };
        this.uriOpener = uriOpener;
        this.possibleProducs = index.getExportedObjectsByType(TerminologyPackage.Literals.PRODUCT);
        this.possibleCustomers = index.getExportedObjectsByType(TerminologyPackage.Literals.CUSTOMER);
        setTitle("Terminology Search");
        setMessage("Search for terms");
        setAddCancelButton(true);
        // super class needs an IStructuredContentProvider so we register this dummy and 
        // register the lazy one later
        setContentProvider(new IStructuredContentProvider() {
            public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
            }

            public void dispose() {
            }

            public Object[] getElements(Object inputElement) {
                return null;
            }
        });
        setLabelProvider(this.labelProvider);
        setHelpAvailable(false);
        setDialogBoundsSettings(getDialogSettings(), DIALOG_PERSISTLOCATION | DIALOG_PERSISTSIZE);
    }

    public TerminologyEObjectSearchDialog(Shell parent, TerminologyEObjectSearch searchEngine,
            ILabelProvider labelProvider, boolean enableStyledLabels, IURIEditorOpener uriOpener,
            IResourceDescriptions index) {
        this(parent, searchEngine, labelProvider, uriOpener, index);
        setShellStyle(SWT.DIALOG_TRIM | SWT.MAX | SWT.RESIZE | getDefaultOrientation());
        this.enableStyledLabels = enableStyledLabels;
    }

    /**
     * @since 2.0
     */
    protected TerminologyEObjectSearch getSearchEngine() {
        return searchEngine;
    }

    /**
     * @since 2.0
     */
    public void setInitialPattern(String text) {
        this.initialPatternText = text;
    }

    /**
     * @since 2.0
     */
    protected String getInitialPattern() {
        return initialPatternText;
    }

    @Override
    public int open() {
        if (getInitialPattern() == null) {
            IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
            if (window != null) {
                ISelection selection = window.getSelectionService().getSelection();
                if (selection instanceof ITextSelection) {
                    String text = ((ITextSelection) selection).getText();
                    if (text != null) {
                        text = text.trim();
                        if (text.length() > 0) {
                            setInitialPattern(text);
                        }
                    }
                }
            }
        }
        return super.open();
    }

    @Override
    protected int getTableStyle() {
        return super.getTableStyle() | SWT.VIRTUAL;
    }

    @Override
    protected Control createDialogArea(Composite container) {
        Composite parent = (Composite) super.createDialogArea(container);
        if (enableStyledLabels && labelProvider instanceof IStyledLabelProvider) {
            final Table table = getTableViewer().getTable();
            final IStyledLabelProvider styledLabelProvider = (IStyledLabelProvider) labelProvider;
            TableOwnerDrawSupport.install(table);
            Listener listener = new Listener() {
                public void handleEvent(Event event) {
                    handleSetData(event);
                }

                protected void handleSetData(Event event) {
                    TableItem item = (TableItem) event.item;
                    IEObjectDescription description = (IEObjectDescription) item.getData();
                    if (description != null) {
                        StyledString styledString = styledLabelProvider.getStyledText(description);
                        String displayString = styledString.toString();
                        StyleRange[] styleRanges = styledString.getStyleRanges();
                        item.setText(displayString);
                        TableOwnerDrawSupport.storeStyleRanges(item, 0, styleRanges);
                    }
                }
            };
            table.addListener(SWT.SetData, listener);
        }
        messageLabel = new Label(parent, SWT.NONE);
        setDefaultGridData(messageLabel);
        EObjectDescriptionContentProvider contentProvider = new EObjectDescriptionContentProvider();
        getTableViewer().setContentProvider(contentProvider);
        getTableViewer().addSelectionChangedListener(new ISelectionChangedListener() {
            public void selectionChanged(SelectionChangedEvent event) {
                ISelection selection = event.getSelection();
                if (selection instanceof IStructuredSelection) {
                    IStructuredSelection structuredSelection = (IStructuredSelection) selection;
                    if (!structuredSelection.isEmpty()) {
                        Object firstElement = structuredSelection.getFirstElement();
                        if (firstElement instanceof IEObjectDescription) {
                            IEObjectDescription eObjectDescription = (IEObjectDescription) firstElement;
                            URI resourceURI = eObjectDescription.getEObjectURI().trimFragment();
                            if (resourceURI.isPlatform()) {
                                messageLabel.setText(resourceURI.toPlatformString(true));
                            } else if (resourceURI.isFile()) {
                                messageLabel.setText(resourceURI.toFileString());
                            } else {
                                messageLabel.setText(resourceURI.toString());
                            }
                            return;
                        }
                    }
                }
                messageLabel.setText(""); //$NON-NLS-1$
            }
        });
        getTableViewer().addDoubleClickListener(new IDoubleClickListener() {
            public void doubleClick(DoubleClickEvent event) {
                try {
                    ISelection selection = event.getSelection();
                    if (selection instanceof StructuredSelection) {
                        Object o = ((StructuredSelection) selection).getFirstElement();
                        if (o instanceof IEObjectDescription) {
                            IEObjectDescription selectedObjectDescription = (IEObjectDescription) o;
                            uriOpener.open(selectedObjectDescription.getEObjectURI(), true);
                        }
                    }
                } catch (Exception e) {
                    //               LOG.error("Error opening editor", e);
                    //               throw new ExecutionException("Error opening editor", e);
                }

            }
        });

        applyFilter();

        return parent;
    }

    @Override
    protected void okPressed() {
        try {
            //disable tableViewer's doubleClickListener, so that the dialog stays open
            StackTraceElement traceElement = Thread.currentThread().getStackTrace()[2];
            if (traceElement.getMethodName().contains("Click")) {
                return;
            }
        } catch (Exception e) {
        }
        storeSettings();
        super.okPressed();
    }

    private void storeSettings() {
        IDialogSettings settings = getDialogSettings();
        settings.put("definition", definitionControl.getSelection());
        settings.put("usage", usageControl.getSelection());
        settings.put("enableCPsettings", useCustomerProductsControl.getSelection());
        for (TermStatus status : TermStatus.values()) {
            settings.put(status.toString(), statusControls.get(status).getSelection());
        }
        settings.put("products", productViewer.getCheckedNames());
        settings.put("customers", customerViewer.getCheckedNames());
    }

    @Override
    protected Label createMessageArea(Composite parent2) {
        Label label = super.createMessageArea(parent2);
        searchControl = new Text(parent2, SWT.BORDER | SWT.SEARCH | SWT.ICON_CANCEL);
        setDefaultGridData(searchControl);

        SelectionAdapter selectionListener = new SelectionAdapter() {
            public void widgetSelected(SelectionEvent e) {
                applyFilter();
            }
        };

        initSearchScopeSettings(parent2, selectionListener);
        initCustomersProductsSettings(parent2, selectionListener);

        Composite labelComposite = new Composite(parent2, SWT.NONE);
        setDefaultGridData(labelComposite);
        GridLayout labelCompositeLayout = new GridLayout(2, true);
        labelCompositeLayout.marginWidth = 0;
        labelComposite.setLayout(labelCompositeLayout);
        matchingElementsLabel = new Label(labelComposite, SWT.NONE);
        matchingElementsLabel.setText("Searching...");
        matchingElementsLabel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false, 1, 1));
        searchStatusLabel = new Label(labelComposite, SWT.RIGHT);
        searchStatusLabel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 1, 1));

        ModifyListener textModifyListener = new ModifyListener() {
            public void modifyText(ModifyEvent e) {
                applyFilter();
            }
        };
        searchControl.addModifyListener(textModifyListener);

        searchControl.addKeyListener(new KeyAdapter() {
            @Override
            public void keyPressed(KeyEvent e) {
                if (e.keyCode == SWT.ARROW_DOWN) {
                    definitionControl.setFocus();
                }
            }
        });

        definitionControl.addKeyListener(new KeyAdapter() {
            @Override
            public void keyPressed(KeyEvent e) {
                if (e.keyCode == SWT.ARROW_DOWN) {
                    TableViewer tableViewer = getTableViewer();
                    tableViewer.getTable().setFocus();
                    if (tableViewer.getSelection().isEmpty()) {
                        Object firstElement = tableViewer.getElementAt(0);
                        if (firstElement != null) {
                            tableViewer.setSelection(new StructuredSelection(firstElement));
                        }
                    }
                }
            }
        });

        if (initialPatternText != null) {
            searchControl.setText(initialPatternText);
            searchControl.selectAll();
        }
        readSettings();
        return label;
    }

    private void initCustomersProductsSettings(Composite parent, SelectionAdapter selectionListener) {
        ExpandableComposite exComposite = createStyleSection(parent, "product/customer settings", 2);
        Composite composite = new Composite(exComposite, SWT.NONE);
        exComposite.setClient(composite);
        GridLayout leftRight = new GridLayout(2, true);
        leftRight.marginWidth = 0;
        composite.setLayout(leftRight);

        productViewer = getViewer(composite, "Terms for products", possibleProducs);
        customerViewer = getViewer(composite, "Terms for customers", possibleCustomers);
    }

    private EObjectDescriptionCheckboxTableViewer getViewer(Composite parent, String label,
            Iterable<IEObjectDescription> values) {
        ICheckStateListener listener = new ICheckStateListener() {
            public void checkStateChanged(CheckStateChangedEvent event) {
                applyFilter();
            }
        };
        Composite pc = new Composite(parent, SWT.NONE);
        pc.setLayout(new GridLayout());
        GridData layoutData = new GridData(GridData.VERTICAL_ALIGN_BEGINNING | GridData.FILL_HORIZONTAL);
        pc.setLayoutData(layoutData);

        Label l = new Label(pc, SWT.NONE);
        l.setText(label);
        EObjectDescriptionCheckboxTableViewer result = EObjectDescriptionCheckboxTableViewer.newCheckList(pc,
                SWT.BORDER);
        result.addCheckStateListener(listener);
        result.setDescriptions(values);

        Table table = result.getTable();
        GridData gd = new GridData(GridData.FILL_BOTH | GridData.GRAB_HORIZONTAL);
        if (table.getItems().length > 6) {
            gd.heightHint = convertHeightInCharsToPixels(6);
        }
        table.setLayoutData(gd);
        return result;
    }

    private void makeCompact(GridLayout layout) {
        layout.marginWidth = 0;
        layout.verticalSpacing = 0;
    }

    private void initSearchScopeSettings(Composite parent, SelectionAdapter selectionListener) {
        ExpandableComposite exComposite = createStyleSection(parent, "general settings", 3);
        Composite composite = new Composite(exComposite, SWT.NONE);
        exComposite.setClient(composite);
        GridLayout compositeLayout = new GridLayout();
        makeCompact(compositeLayout);
        composite.setLayout(compositeLayout);

        Composite leftRight = new Composite(composite, SWT.NONE);
        GridLayout leftRightLayout = new GridLayout(2, false);
        makeCompact(leftRightLayout);
        leftRight.setLayout(leftRightLayout);

        //left
        Label searchIn = new Label(leftRight, SWT.NONE);
        searchIn.setText("Also search in:");

        //right
        Label useCustomerProductSettings = new Label(leftRight, SWT.NONE);
        useCustomerProductSettings.setText("Customer/product settings:");

        //left
        Composite checkboxComposite = new Composite(leftRight, SWT.NONE);
        setDefaultGridData(checkboxComposite);
        GridLayout checkboxCompositeLayout = new GridLayout(2, true);
        makeCompact(checkboxCompositeLayout);
        checkboxComposite.setLayout(checkboxCompositeLayout);

        definitionControl = new Button(checkboxComposite, SWT.CHECK);
        definitionControl.setText("Definition");
        definitionControl.addSelectionListener(selectionListener);
        usageControl = new Button(checkboxComposite, SWT.CHECK);
        usageControl.setText("Usage");
        usageControl.addSelectionListener(selectionListener);

        //right
        useCustomerProductsControl = new Button(leftRight, SWT.CHECK);
        useCustomerProductsControl.setText("enabled");
        useCustomerProductsControl.addSelectionListener(selectionListener);

        Label searchStatus = new Label(composite, SWT.NONE);
        searchStatus.setText("Terms with status:");

        Composite checkboxComposite2 = new Composite(composite, SWT.NONE);
        setDefaultGridData(checkboxComposite2);
        GridLayout checkboxComposite2Layout = new GridLayout(5, true);
        makeCompact(checkboxComposite2Layout);
        checkboxComposite2.setLayout(checkboxComposite2Layout);

        statusControls = new LinkedHashMap<TermStatus, Button>();
        for (TermStatus status : TermStatus.values()) {
            Button statusButton = new Button(checkboxComposite2, SWT.CHECK);
            statusButton.setText(status.toString());
            statusButton.addSelectionListener(selectionListener);
            statusControls.put(status, statusButton);
        }
    }

    protected ExpandableComposite createStyleSection(Composite parent, String label, int nColumns) {
        ExpandableComposite excomposite = new ExpandableComposite(parent,
                ExpandableComposite.TWISTIE | ExpandableComposite.CLIENT_INDENT);
        excomposite.setText(label);
        excomposite.setExpanded(false);
        excomposite.setFont(JFaceResources.getFontRegistry().getBold(JFaceResources.DIALOG_FONT));
        excomposite.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, false, nColumns, 1));
        excomposite.addExpansionListener(new ExpansionAdapter() {
            @Override
            public void expansionStateChanged(ExpansionEvent e) {
                getShell().layout(true, true);
            }
        });
        return excomposite;
    }

    @Override
    protected void createButtonsForButtonBar(Composite parent) {
        super.createButtonsForButtonBar(parent);
        getOkButton().setText("Save Settings and Close");
        setButtonLayoutData(getOkButton());
        getButton(IDialogConstants.CANCEL_ID).setText("Close");
    }

    private void readSettings() {
        definitionControl.setSelection(getDialogSettings().getBoolean("definition"));
        usageControl.setSelection(getDialogSettings().getBoolean("usage"));
        useCustomerProductsControl.setSelection(getDialogSettings().getBoolean("enableCPsettings"));
        for (TermStatus status : TermStatus.values()) {
            statusControls.get(status).setSelection(getDialogSettings().getBoolean(status.toString()));
        }
        readEObjectSettings("products", productViewer);
        readEObjectSettings("customers", customerViewer);
    }

    private void readEObjectSettings(String key, EObjectDescriptionCheckboxTableViewer viewer) {
        if (getDialogSettings().getArray(key) != null) {
            viewer.setCheckedNames(getDialogSettings().getArray(key));
        }
    }

    private IDialogSettings getDialogSettings() {
        IDialogSettings settings = TerminologyActivator.getInstance().getDialogSettings();
        if (settings.getSection(SETTINGS_SECTION) == null) {
            initDefaultSettings(settings);
        }
        return settings.getSection(SETTINGS_SECTION);
    }

    private void initDefaultSettings(IDialogSettings settings) {
        IDialogSettings newSetting = settings.addNewSection(SETTINGS_SECTION);
        for (TermStatus status : TermStatus.values()) {
            newSetting.put(status.toString(), true);
        }
    }

    private void setDefaultGridData(Control control) {
        control.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL));
    }

    protected void applyFilter() {
        boolean useCustomerProductSettings = useCustomerProductsControl.getSelection();
        setProductCustomerSettingsEnabled(useCustomerProductSettings);
        TerminologySearchPattern pattern = new TerminologySearchPattern();
        pattern.setTextPattern(searchControl.getText());
        pattern.setInDefinition(definitionControl.getSelection());
        pattern.setUseCustomerProducts(useCustomerProductSettings);
        pattern.setInUsage(usageControl.getSelection());
        pattern.setStatus(statusControls);
        pattern.setProducts(productViewer.getChecked());
        pattern.setCustomers(customerViewer.getChecked());

        //      if (pattern.textPattern != null) {
        Iterable<IEObjectDescription> matches = getSearchEngine().findMatches(pattern);
        startSizeCalculation(matches);
        //      }
    }

    private void setProductCustomerSettingsEnabled(boolean enabled) {
        productViewer.getControl().setEnabled(enabled);
        customerViewer.getControl().setEnabled(enabled);
    }

    public void updateMatches(final Collection<IEObjectDescription> matches, final boolean isFinished) {
        Display.getDefault().asyncExec(new Runnable() {
            public void run() {
                if (getShell() != null) {
                    if (getTableViewer() != null) {
                        getTableViewer().setItemCount(matches.size());
                        getTableViewer().setInput(matches);
                        if (getTableViewer().getSelection().isEmpty() && matches.size() > 0)
                            getTableViewer().getTable().select(0);
                    }
                    searchStatusLabel.setText((isFinished) ? "" : "Search"); //$NON-NLS-1$
                    matchingElementsLabel.setText(matches.size() + " hits"); //$NON-NLS-1$
                }
            }
        });
    }

    /**
     * Called by {@link #applyFilter()} and is responsible for calling {@link #updateMatches(Collection, boolean)} with
     * an appropriately sorted list of matches.
     * 
     * @since 2.0
     */
    protected void startSizeCalculation(Iterable<IEObjectDescription> matches) {
        if (getTableViewer() != null) {
            if (sizeCalculationJob != null) {
                sizeCalculationJob.cancel();
                try {
                    sizeCalculationJob.join();
                } catch (InterruptedException e) {
                    sizeCalculationJob = new TerminologyIteratorJob(this);
                }
            } else {
                sizeCalculationJob = new TerminologyIteratorJob(this);
            }
            sizeCalculationJob.init(matches);
            sizeCalculationJob.schedule();
        }
    }

}