Package com.puppetlabs.geppetto.pp.dsl.ui.search

Source Code of com.puppetlabs.geppetto.pp.dsl.ui.search.PPObjectSearchDialog

/**
* Copyright (c) 2013 Puppet Labs, Inc. and other contributors, as listed below.
* 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
*
* Contributors:
*   Initial implementation - itemis AG (http://www.itemis.eu
*   Puppet Labs - specialized for puppet
*
*/
package com.puppetlabs.geppetto.pp.dsl.ui.search;

import java.util.Collection;

import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.jface.internal.text.TableOwnerDrawSupport;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.viewers.DelegatingStyledCellLabelProvider.IStyledLabelProvider;
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.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
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.xtext.resource.IEObjectDescription;
import org.eclipse.xtext.ui.search.EObjectDescriptionContentProvider;

/**
* @author Jan Koehnlein - Initial contribution and API
* @author Knut Wannheden
* @author Henrik Lindberg - Puppet Labs, adapted to Puppet
*/
public class PPObjectSearchDialog extends ListDialog {

  protected Text searchControl;

  private String initialPatternText;

  private Label messageLabel;

  private Label searchStatusLabel;

  private IteratorJob sizeCalculationJob;

  private Label matchingElementsLabel;

  /** @since 2.0 */
  // protected Text typeSearchControl;

  private IPPEObjectSearch searchEngine;

  private final ILabelProvider labelProvider;

  private boolean enableStyledLabels;

  public PPObjectSearchDialog(Shell parent, IPPEObjectSearch searchEngine, ILabelProvider labelProvider) {
    super(parent);
    this.searchEngine = searchEngine;
    this.labelProvider = labelProvider;
    setTitle("Open Puppet Element");
    setMessage("Enter element name prefix or pattern (*, ?, or camel case):");
    setAddCancelButton(true);
    // super class needs an IStructuredContentProvider so we register this dummy and
    // register the lazy one later
    setContentProvider(new IStructuredContentProvider() {
      public void dispose() {
      }

      public Object[] getElements(Object inputElement) {
        return null;
      }

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

  public PPObjectSearchDialog(Shell parent, IPPEObjectSearch searchEngine, ILabelProvider labelProvider,
      boolean enableStyledLabels) {
    this(parent, searchEngine, labelProvider);
    this.enableStyledLabels = enableStyledLabels;
  }

  /**
   * Called when the dialog is initially opened and whenever the input text changes. Applies the search filter as
   * specified by {@link #searchControl} and {@link #typeSearchControl} using {@link #getSearchEngine()} and updates
   * the result using {@link #startSizeCalculation(Iterable)}.
   *
   * @since 2.0
   */
  protected void applyFilter() {
    String searchPattern = searchControl.getText();

    // TODO: get a set of accepted classes - null or empty collection means all/any
    // String typeSearchPattern = typeSearchControl.getText();
    Collection<EClass> acceptedClasses = null;
    if(searchPattern != null) {
      Iterable<IEObjectDescription> matches = getSearchEngine().findMatches(searchPattern, acceptedClasses);
      startSizeCalculation(matches);
    }
  }

  @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 == null
                ? description.toString()
                : 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$
      }
    });

    applyFilter();

    return parent;
  }

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

    // TODO: NOT MEANINGFUL TO SEARCH FOR ANY ECLASS - OFFER A SELECTION INSTEAD
    // TODO: HANDLE (FUTURE) SEARCH FOR RESOURCE WHERE USER DOES NOT KNOW THE ENCODING OF THE FQN
    //
    // Label typePatternLabel = new Label(composite, SWT.NONE);
    // typePatternLabel.setText("EClass name prefix or pattern");
    // setDefaultGridData(typePatternLabel);
    // typeSearchControl = new Text(composite, SWT.BORDER | SWT.SEARCH | SWT.ICON_CANCEL);
    // setDefaultGridData(typeSearchControl);

    Composite labelComposite = new Composite(composite, SWT.NONE);
    setDefaultGridData(labelComposite);
    GridLayout labelCompositeLayout = new GridLayout(2, true);
    labelCompositeLayout.marginWidth = 0;
    labelComposite.setLayout(labelCompositeLayout);
    matchingElementsLabel = new Label(labelComposite, SWT.NONE);
    matchingElementsLabel.setText("Matching items:");
    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);
    // typeSearchControl.addModifyListener(textModifyListener);

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

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

    // typeSearchControl.addKeyListener(new KeyAdapter() {
    searchControl.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));
            }
          }
        }
      }
    });

    return label;
  }

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

  protected IPPEObjectSearch getSearchEngine() {
    return searchEngine;
  }

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

  @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();
            // skip interpolation start
            if(text.startsWith("${"))
              text = text.substring(2);
            // skip interpolation end
            while(text.endsWith("}"))
              text = text.substring(0, text.length() - 1);
            // Skip a leading $ for variable
            if(text.startsWith("$"))
              text = text.substring(1);
            if(text.length() > 0) {
              setInitialPattern(text);
            }
          }
        }
      }
    }
    return super.open();
  }

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

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

  /**
   * 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 IteratorJob(this);
        }
      }
      else {
        sizeCalculationJob = new IteratorJob(this);
      }
      sizeCalculationJob.init(matches);
      sizeCalculationJob.schedule();
    }
  }

  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);
          }
          searchStatusLabel.setText((isFinished)
              ? "" : "Searching..."); //$NON-NLS-1$
          matchingElementsLabel.setText("Matching items:" + " (" + matches.size() + " matches)"); //$NON-NLS-1$
        }
      }
    });
  }

}
TOP

Related Classes of com.puppetlabs.geppetto.pp.dsl.ui.search.PPObjectSearchDialog

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.