Package org.springframework.ide.eclipse.wizard.gettingstarted.guides

Source Code of org.springframework.ide.eclipse.wizard.gettingstarted.guides.ChooseTypedContentSection$ChoicesFilter

/*******************************************************************************
*  Copyright (c) 2013 GoPivotal, Inc.
*  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:
*      GoPivotal, Inc. - initial API and implementation
*******************************************************************************/
package org.springframework.ide.eclipse.wizard.gettingstarted.guides;

import java.util.HashMap;

import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.layout.GridLayoutFactory;
import org.eclipse.jface.resource.JFaceResources;
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.LabelProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.internal.misc.StringMatcher;
import org.eclipse.ui.internal.misc.StringMatcher.Position;
import org.springframework.ide.eclipse.wizard.WizardPlugin;
import org.springframework.ide.eclipse.wizard.gettingstarted.content.ContentManager;
import org.springframework.ide.eclipse.wizard.gettingstarted.content.ContentType;
import org.springframework.ide.eclipse.wizard.gettingstarted.content.Describable;
import org.springframework.ide.eclipse.wizard.gettingstarted.content.DisplayNameable;
import org.springframework.ide.eclipse.wizard.gettingstarted.content.GSContent;
import org.springsource.ide.eclipse.commons.frameworks.core.ExceptionUtil;
import org.springsource.ide.eclipse.commons.livexp.core.LiveExpression;
import org.springsource.ide.eclipse.commons.livexp.core.LiveVariable;
import org.springsource.ide.eclipse.commons.livexp.core.ValidationResult;
import org.springsource.ide.eclipse.commons.livexp.ui.IPageWithSections;
import org.springsource.ide.eclipse.commons.livexp.ui.WizardPageSection;

/**
* Allow choosing a guide in pull-down style combo box or table viewer.
*
* TODO: this was copied from the GuidesWizard but it should be changed
* into or replaced by something that allows picking content from
* a tree where the first level are the types of content available
* and the second level are elements of that content type.
*
* @author Kris De Volder
*/
@SuppressWarnings("restriction")
public class ChooseTypedContentSection extends WizardPageSection {

  private static class ContentProvider implements ITreeContentProvider {

    private final ContentManager content;

    public ContentProvider(ContentManager content) {
      this.content = content;
    }

    //@Override
    public void dispose() {
    }

    //@Override
    public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
    }

    //@Override
    public Object[] getElements(Object e) {
      if (e==content) {
        ContentType<?>[] types = content.getTypes();
        if (types!=null) {
          if (types.length==1) {
            //If there's only one type of content. Then it looks better
            //to just show those elements uncategorized.
            return getChildren(types[0]);
          } else {
            return types;
          }
        }
      }
      return null;
    }

    //@Override
    public Object[] getChildren(Object e) {
      try {
        if (e instanceof ContentType<?>) {
          return content.get((ContentType<?>)e);
        }
        return null;
      } catch (Throwable error) {
        WizardPlugin.log(error);
        return new Object[] {error};
      }
    }

    //@Override
    public Object getParent(Object e) {
      if (e instanceof GSContent) {
        return e.getClass();
      } else if (e instanceof Class<?>) {
        return content;
      }
      return null;
    }

    //@Override
    public boolean hasChildren(Object e) {
      Object[] c = getChildren(e);
      return c!=null && c.length>0;
    }
  }

  private static final LabelProvider labelProvider = new LabelProvider() {
    @Override
    public String getText(Object element) {
      if (element instanceof DisplayNameable) {
        DisplayNameable item = (DisplayNameable) element;
        return item.getDisplayName();
      } else if (element instanceof Throwable) {
        return ExceptionUtil.getMessage((Throwable) element);
      }
      return super.getText(element);
    }

    @Override
    public Image getImage(Object element) {
      if (element instanceof Throwable) {
        return JFaceResources.getImage(Dialog.DLG_IMG_MESSAGE_ERROR);
      }
      return null;
    }
  };

  private class ChoicesFilter extends ViewerFilter {

    private StringMatcher matcher = null;
    private final HashMap<Object, Boolean> cache = new HashMap<Object, Boolean>();

    public ChoicesFilter() {
      if (searchBox!=null) {
        setSearchTerm(searchBox.getText());
      }
    }

    public void setSearchTerm(String text) {
      matcher = new StringMatcher(text, true, false);
      cache.clear();
    }

    @Override
    public boolean select(Viewer viewer, Object parentElement, Object element) {
      if (matcher==null) {
        return true;
      }
      Boolean v = cache.get(element);
      if (v==null) {
        v = compute(viewer, parentElement, element);
        cache.put(element, v);
      }
      return v;
    }

    public boolean compute(Viewer viewer, Object parentElement, Object e) {
      String label = labelProvider.getText(e);
      if (e instanceof ContentType<?>) {
        //Only search in the content (leaves). The contenttypes are selected if
        // any of their children (content) is selected.
        return matchChildren(viewer, e);
      } else if (match(label)) {
        return true;
      } else if (e instanceof Describable && match(((Describable) e).getDescription())) {
        return true;
      }
      return false;
    }

    private boolean matchChildren(Viewer viewer, Object e) {
      Object[] children=contentProvider.getChildren(e);
      if (children!=null) {
        for (Object c : children) {
          if (select(viewer, e, c)) {
            return true;
          }
        }
      }
      return false;
    }

    private boolean match(String text) {
      if (matcher==null) {
        return true; // Search term not set... anything is acceptable.
      } else if (text==null) {
        return false;
      } else {
        Position x = matcher.find(text, 0, text.length());
        return x!=null;
      }
    }

  }


  private String sectionLabel;
  private final SelectionModel<GSContent> selection;
  private Text searchBox;
  private ChoicesFilter filter;
  private final ContentManager content;
  private final ContentProvider contentProvider;
  private final LiveVariable<Object> rawSelection;
  private TreeViewer treeviewer;
  private String initialFilterText;
  private String category;

  public ChooseTypedContentSection(IPageWithSections owner, SelectionModel<GSContent> selection,
      LiveVariable<Object> rawSelection, ContentManager content) {
    super(owner);
    this.selection = selection;
    this.rawSelection = rawSelection;
    this.content = content;
    this.contentProvider = new ContentProvider(content);
  }


  @Override
  public LiveExpression<ValidationResult> getValidator() {
    return selection.validator;
  }

  @Override
  public void createContents(Composite page) {
    Composite field = new Composite(page, SWT.NONE);
    int cols = sectionLabel==null ? 1 : 2;
    GridLayout layout = GridLayoutFactory.fillDefaults().numColumns(cols).create();
    field.setLayout(layout);

    searchBox = new Text(field, SWT.SINGLE | SWT.BORDER | SWT.SEARCH | SWT.ICON_CANCEL);
    searchBox.setMessage("Type pattern to match");

    GridDataFactory.fillDefaults().grab(true, false).applyTo(searchBox);

    Label fieldNameLabel = null;
    if (sectionLabel!=null) {
      fieldNameLabel = new Label(field, SWT.NONE);
      fieldNameLabel.setText(sectionLabel);
    }

    treeviewer = new TreeViewer(field, SWT.SINGLE|SWT.BORDER|SWT.V_SCROLL);
    treeviewer.addFilter(filter = new ChoicesFilter());
    treeviewer.setLabelProvider(labelProvider);
    treeviewer.setContentProvider(contentProvider);
    treeviewer.setInput(content);
    treeviewer.expandAll();

    if (fieldNameLabel!=null) {
      GridDataFactory.fillDefaults().align(SWT.BEGINNING, SWT.BEGINNING).applyTo(fieldNameLabel);
    }
    GridDataFactory grab = GridDataFactory.fillDefaults().grab(true, true).hint(SWT.DEFAULT, 150);
    grab.applyTo(field);
    grab.applyTo(treeviewer.getControl());

    whenVisible(treeviewer.getControl(), new Runnable() {
      public void run() {
        GSContent preSelect = selection.selection.getValue();
        if (preSelect!=null) {
          treeviewer.setSelection(new StructuredSelection(preSelect), true);
        } else {
          treeviewer.setSelection(StructuredSelection.EMPTY, true);
        }
        if (initialFilterText!=null) {
          searchBox.setText(initialFilterText);
          updateFilter();
        }
        if (category!=null) {
          //System.out.println(category);
          ContentType<?> expand = null;
          ContentType<?>[] contentTypes = content.getTypes();
          for (ContentType<?> contentType : contentTypes) {
            //TODO: Miles(?) Searching by display name seems like a bad idea
            if (contentType.getDisplayName().equals(category)) {
              expand = contentType;
              break;
            }
          }
          if (expand!=null) {
            treeviewer.setExpandedElements(new Object[] { expand });
          }
        }
      }
    });

    treeviewer.addSelectionChangedListener(new ISelectionChangedListener() {
      public void selectionChanged(SelectionChangedEvent event) {
        ISelection sel = treeviewer.getSelection();
        if (sel.isEmpty()) {
          setSelection(null);
        } else if (sel instanceof IStructuredSelection){
          IStructuredSelection ss = (IStructuredSelection) sel;
          setSelection(ss.getFirstElement());
        } else {
          //Not expecting anything else. So ignore.
        }
      }

      private void setSelection(Object e) {
        if (e == null) {
          selection.selection.setValue(null);
          rawSelection.setValue(null);
        } else {
          rawSelection.setValue(e);
          if (e instanceof GSContent) {
            selection.selection.setValue((GSContent) e);
          }
        }
      }
    });

    searchBox.addModifyListener(new ModifyListener() {
      public void modifyText(ModifyEvent e) {
        updateFilter();
      }
    });
  }

  private void whenVisible(final Control control, final Runnable runnable) {
    PaintListener l = new PaintListener() {
      public void paintControl(PaintEvent e) {
        runnable.run();
        control.removePaintListener(this);
      }
    };
    control.addPaintListener(l);
  }

  public void setFilterText(String text) {
    if (searchBox!=null) {
      searchBox.setText(text);
      updateFilter();
    } else {
      //UI isn't there yet so remember the text as intial filter text to be set when
      // ui is created later.
      this.initialFilterText = text;
    }
  }

  public void setCategory(String category) {
    this.category = category;
  }

  private void updateFilter() {
    filter.setSearchTerm(searchBox.getText());
    treeviewer.refresh();
    treeviewer.expandAll();
  }

//  private String[] getLabels() {
//    String[] labels = new String[options.length];
//    for (int i = 0; i < labels.length; i++) {
//      labels[i] = labelProvider.getText(options[i]);
//    }
//    return labels;
//  }

}
TOP

Related Classes of org.springframework.ide.eclipse.wizard.gettingstarted.guides.ChooseTypedContentSection$ChoicesFilter

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.