Package it.unibz.instasearch.ui

Source Code of it.unibz.instasearch.ui.SearchViewControl$FilterChangeAction

/*
* Copyright (c) 2009 Andrejs Jermakovics.
*
* 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:
*     Andrejs Jermakovics - initial implementation
*/
package it.unibz.instasearch.ui;

import it.unibz.instasearch.InstaSearchPlugin;
import it.unibz.instasearch.indexing.Field;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;

import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.bindings.keys.KeyStroke;
import org.eclipse.jface.fieldassist.ContentProposalAdapter;
import org.eclipse.jface.fieldassist.IContentProposalProvider;
import org.eclipse.jface.fieldassist.IControlContentAdapter;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.resource.ImageRegistry;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.FocusListener;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.FillLayout;
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.ToolBar;
import org.eclipse.swt.widgets.ToolItem;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorRegistry;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.ide.IDE.SharedImages;

/**
*
*/
public class SearchViewControl implements DisposeListener {

  private static final String PROPOSAL_KEYSTROKE = "Ctrl+Space";
  private static final String SEARCH_TEXT_TIP = "search text " + Field.PROJ + ":MyProject " +  Field.EXT + ":xml,java";
 
  private TreeViewer resultViewer;
  private StyledText searchText;
  private ImageRegistry imageRegistry = new ImageRegistry();
  private ToolBar filterBar;
  private SearchContentProposalProvider proposalProvider;
  private Composite parent;
  private int itemInsertIndex = 0;
  private ModifyListener modifyListener; //TODO: new interface
 
  private Color searchTipColor =  getDisplay().getSystemColor(SWT.COLOR_DARK_GRAY);
  private Color defaultSearchColor =  getDisplay().getSystemColor(SWT.COLOR_BLACK);
  /**
   * @param parent
   */
  public SearchViewControl(Composite parent, ModifyListener modifyListener) {
   
    this.parent = parent;
    this.modifyListener = modifyListener;
   
    createControl(parent);
    parent.addDisposeListener(this);
  }

  /**
   * @return the searchText
   */
  public StyledText getSearchText() {
    return searchText;
  }
 
  /**
   * @return the resultViewer
   */
  public TreeViewer getResultViewer() {
    return resultViewer;
  }
 
  /**
   * @param parent
   */
  private void createControl(Composite parent) {
           
    GridLayout parentLayout = new GridLayout();
    //parentLayout.marginTop = 2;
    parentLayout.marginLeft = 0;
    parentLayout.horizontalSpacing = 0;
    parentLayout.verticalSpacing = 0;
    parentLayout.marginWidth = 0;
    parentLayout.marginHeight = 2;
    parent.setLayout( parentLayout );
   
    Composite textComposite = new Composite(parent, SWT.NONE);
    GridData textCompositeGridData = new GridData(GridData.FILL, GridData.BEGINNING, true, false);
    textComposite.setLayoutData( textCompositeGridData );
   
    GridLayout layout = new GridLayout(2, false);
    layout.marginLeft = 2;
    layout.horizontalSpacing = 0;
    layout.verticalSpacing = 0;
    layout.marginWidth = 0;
    layout.marginHeight = 0;
    textComposite.setLayout( layout );
               
    createSearchTextControl( textComposite );
    createFilterBar(textComposite);
   
    Composite viewComposite = new Composite(parent, SWT.NONE);
    viewComposite.setLayoutData( new GridData(GridData.FILL, GridData.FILL, true, true) );
    FillLayout fillLayout = new FillLayout();
    fillLayout.marginHeight = 0;
    fillLayout.marginWidth = 0;
    fillLayout.spacing = 0;
    viewComposite.setLayout( fillLayout );
   
    resultViewer = new TreeViewer(viewComposite, SWT.FULL_SELECTION);
  }

  private void createFilterBar(Composite parent) {
   
    filterBar = new ToolBar(parent, SWT.FLAT | SWT.RIGHT);
    GridData gridData = new GridData(GridData.END, GridData.CENTER, false, false);
    filterBar.setLayoutData(gridData);
   
    ToolItem clearItem = new ToolItem(filterBar, SWT.NONE);
    clearItem.setImage( getPluginImage("close") );
    clearItem.setToolTipText("Clear search text");
    clearItem.addSelectionListener(new SelectionAdapter() {
      @Override
      public void widgetSelected(SelectionEvent e) {
        searchText.setText("");
        searchText.setFocus();
      }
    });
   
    new ToolItem(filterBar, SWT.SEPARATOR);
    itemInsertIndex = filterBar.getItemCount(); // so we insert after separator
   
    ToolItem filterItem = new ToolItem(filterBar, SWT.DROP_DOWN);
    filterItem.setToolTipText("Filter by...");
    filterItem.setImage( getPluginImage("filter") );
   
    DropdownMenuProvider<FilterChangeAction> dropdown = new DropdownMenuProvider<FilterChangeAction>(filterItem);
    dropdown.add( new ProjFilterAction(PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(SharedImages.IMG_OBJ_PROJECT)) );
    dropdown.add( new ExtensionFilterAction(PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(ISharedImages.IMG_OBJ_FILE)) );
    dropdown.add( new FieldFilterAction(Field.WS, InstaSearchPlugin.getImageDescriptor("workingsets")) );
    dropdown.add( new FieldFilterAction(Field.MODIFIED, InstaSearchPlugin.getImageDescriptor("dates")) );
   
    filterBar.update();
  }
 
  private abstract class FilterChangeAction extends Action
  {
    public FilterChangeAction(String proposal, ImageDescriptor imageDescriptor) {
      super(proposal, imageDescriptor);
    }
 
    public FilterChangeAction(String string) {
      super(string);
    }
 
    @Override
    final public void run() {
      runAction();
      updateSearch();
    }
   
    abstract protected void runAction();
  }

  private class FieldFilterAction extends FilterChangeAction
  {
    private Field field;

    public FieldFilterAction(Field field, ImageDescriptor img) {
      super(field.getTitle(), img);
     
      this.field = field;
    }
   
    protected Image getImage(String proposal)
    {
      String key = field + ":" + proposal;
      Image img = imageRegistry.get(key);
     
      if( img == null ) img = imageRegistry.get(field + ":");
     
      if( img == null )
      {
        imageRegistry.put(key, getImageDescriptor());
        img = imageRegistry.get(key);
      }
     
      return img;
    }
   
    @Override
    public void runAction() {
     
      final ToolItem fieldItem = new ToolItem(filterBar, SWT.DROP_DOWN, itemInsertIndex);
      fieldItem.setToolTipText("Filter by " + field.getTitle());
      fieldItem.setImage( getImage("") );
      fieldItem.setData(field);
     
      DropdownMenuProvider<FilterChangeAction> dropdown = new DropdownMenuProvider<FilterChangeAction>(fieldItem);
      addRemoveAction(fieldItem, dropdown);
      dropdown.addSeparator();
     
      List<String> proposals = proposalProvider.getFieldProposals(field, "");
      FilterChangeAction firstAction = null;
     
      for(String proposal: proposals)
      {
        FilterChangeAction action = addAction(dropdown, proposal);
       
        if( firstAction == null ) firstAction = action;
      }
     
      if( "".equals(fieldItem.getText()) && firstAction != null )
        firstAction.run();
     
      parent.layout(true, true);
    }

    private void addRemoveAction(final ToolItem fieldItem,
        DropdownMenuProvider<FilterChangeAction> dropdown)
    {
      FilterChangeAction removeAction = new FilterChangeAction("Remove") {
        @Override
        public void runAction() {
          fieldItem.dispose();
          parent.layout(true, true);
        }
      };
      removeAction.setImageDescriptor(InstaSearchPlugin.getImageDescriptor("close"));
      dropdown.add(removeAction);
    }
   
    /**
     * @param dropdown
     *
     */
    protected FilterChangeAction addAction(final DropdownMenuProvider<FilterChangeAction> dropdown, final String proposal)
    {
      FilterChangeAction action = new FilterChangeAction(proposal, getImageDescriptor())
      {
        @Override
        public void runAction()
        {
          dropdown.getToolItem().setText(getText());
          dropdown.getToolItem().setImage(getImage(proposal));
          parent.layout(true, true);
        }
      };
     
      dropdown.add(action);
      return action;
    }
  }
 
  private class ProjFilterAction extends FieldFilterAction
  {
    public ProjFilterAction(ImageDescriptor img) {
      super(Field.PROJ, img);
    }
   
    @Override
    protected FilterChangeAction addAction(
        DropdownMenuProvider<FilterChangeAction> dropdown,
        String proposal) {
     
      FilterChangeAction action = super.addAction(dropdown, proposal);
     
      if( proposal.equals(InstaSearchUI.getActiveProject()) ) // active project
        action.run(); // add it
     
      return action;
    }
  }
 
  private class ExtensionFilterAction extends FieldFilterAction
  {
    public ExtensionFilterAction(ImageDescriptor img) {
      super(Field.EXT, img);
    }
   
    @Override
    protected Image getImage(String proposal) {
     
      getExtImageDescriptor(proposal);
     
      return imageRegistry.get(Field.EXT + ":" + proposal);
    }
   
    @Override
    protected FilterChangeAction addAction(DropdownMenuProvider<FilterChangeAction> dropdown, String proposal) {
      FilterChangeAction action = super.addAction(dropdown, proposal);
      ImageDescriptor imgDesc = getExtImageDescriptor(proposal);
 
      if( imgDesc != null )
        action.setImageDescriptor(imgDesc);
     
      IEditorPart editor = InstaSearchUI.getActiveEditor();
     
      if( editor != null )
      {
        IAdaptable adaptable = editor.getEditorInput();
       
        if( adaptable != null )
        {
          // get current edited file
          IResource res = (IResource) adaptable.getAdapter(IResource.class);
         
          if( res != null && proposal.equals(res.getFileExtension()))
            action.run(); // set as active extension
        }
      }
     
      return action;
    }
  }
 
  private void updateSearch()
  {
    modifyListener.modifyText(null); // notify view
  }

  private void createSearchTextControl(Composite textComposite) {
    searchText = new StyledText(textComposite, SWT.SINGLE | SWT.BORDER | SWT.SEARCH | SWT.CANCEL);
   
    textComposite.setTabList(new Control[]{searchText});
   
    GridData searchTextGridData = new GridData(GridData.FILL, GridData.CENTER, true, false);
    searchText.setLayoutData( searchTextGridData );

    FocusListener focusListener = new FocusListener() { // to set search tip
     
      public void focusGained(FocusEvent e)
      {
        if (searchText.isDisposed())
          return;

        if( isShowingSearchTip() )
        {
          searchText.setForeground( defaultSearchColor );
         
          if( SEARCH_TEXT_TIP.equals(searchText.getText()) )
            searchText.setText("");
        }
      }
     
      public void focusLost(FocusEvent e)
      {
        if( searchText.getText().length() == 0 )
        {
          searchText.setForeground( searchTipColor );
          searchText.setText(SEARCH_TEXT_TIP);
        }
      }
    };
   
    searchText.addFocusListener(focusListener);
   
    searchText.setToolTipText(SEARCH_TEXT_TIP + "\n(" + PROPOSAL_KEYSTROKE + " for autocompletion)");
  }
 
  public boolean isShowingSearchTip()
  {
    return searchText.getForeground().equals( searchTipColor );
  }
 
  /**
   * @return display
   *
   */
  private Display getDisplay() {
    return Display.getCurrent();
  }
 
  public void setContentProposalAdapter(SearchContentProposalProvider provider)
  {
    this.proposalProvider = provider;
    KeyStroke keyStroke = null;
   
    try {
      keyStroke = KeyStroke.getInstance(PROPOSAL_KEYSTROKE);
    } catch(Exception e) {
      InstaSearchPlugin.log(e);
    }
   
    char[] autoActivationCharacters = new char[]{':', ','};
   
    ContentProposalAdapter adapter = new SearchContentProposalAdapter(
        searchText, new StyledTextContentAdapter(),
        provider, keyStroke, autoActivationCharacters );
   
    adapter.setPopupSize(new Point(300, 150));
    adapter.setPropagateKeys(true);
    adapter.setProposalAcceptanceStyle(ContentProposalAdapter.PROPOSAL_REPLACE);
  }
 
  private Image getPluginImage(String name)
  {
    Image img = imageRegistry.get(name);
    if( img == null )
    {
      imageRegistry.put(name, InstaSearchPlugin.getImageDescriptor(name));
      img = imageRegistry.get(name);
    }
   
    return img;
  }
 
  private ImageDescriptor getExtImageDescriptor(String ext)
  {
    String key = Field.EXT + ":" + ext;
    ImageDescriptor fileImage = imageRegistry.getDescriptor(key);
   
    if( fileImage == null ) {
      IEditorRegistry registry = PlatformUI.getWorkbench().getEditorRegistry();
      fileImage = registry.getImageDescriptor("*." + ext);
      imageRegistry.put(key, fileImage); // cache created images for extensions
    }
   
    return fileImage;
  }
 
  public void widgetDisposed(DisposeEvent e) {
    imageRegistry.dispose();
  }
 
  private class SearchContentProposalAdapter extends ContentProposalAdapter
  {
    /**
     * @param control
     * @param controlContentAdapter
     * @param proposalProvider
     * @param keyStroke
     * @param autoActivationCharacters
     */
    public SearchContentProposalAdapter(Control control,
        IControlContentAdapter controlContentAdapter,
        IContentProposalProvider proposalProvider, KeyStroke keyStroke,
        char[] autoActivationCharacters)
    {
      super(control, controlContentAdapter, proposalProvider, keyStroke,
          autoActivationCharacters);
    }
   
    @Override
    protected void closeProposalPopup() { // workaround to keep popup open
      String content = getControlContentAdapter().getControlContents(getControl());
      int pos = getControlContentAdapter().getCursorPosition(getControl());
     
      if( content.length() == 0 || pos == 0 ) {
        super.closeProposalPopup();
        return;
      }
     
      String prefix = content.substring(0, pos);
      if( prefix.length() == 0 || prefix.endsWith(" ") ) {
        super.closeProposalPopup();
        return;
      }
     
    }
   
    @Override
    public int getProposalAcceptanceStyle() { // workaround to have the popup at insert positon
      return ContentProposalAdapter.PROPOSAL_INSERT;
    }
  }

  public Map<Field, Set<String>> getFilter()
  {
    HashMap<Field, Set<String>> filters = new HashMap<Field, Set<String>>();
   
    for(ToolItem item: filterBar.getItems())
    {
      Object data = item.getData();
      if( data== null ) continue;
      if( data instanceof Field )
      {
        Field field = (Field) data;
        String value = item.getText();
       
        if( "".equals(value) ) continue;
       
        Set<String> values = filters.get(field);
        if( values == null ) {
          values = new TreeSet<String>();
          filters.put(field, values);
        }
        values.add(value);
      }
    }
   
    return filters;
  }

  /**
   * @param filter
   */
  public void setFilter(Map<Field, Set<String>> filter)
  {
    clearFilter();
   
   
  }
 
  private void clearFilter()
  {
    for(ToolItem item: filterBar.getItems())
    {
      Object data = item.getData();
      if( data== null ) continue;
      if( data instanceof Field )
        item.dispose();
    }
  }
}
TOP

Related Classes of it.unibz.instasearch.ui.SearchViewControl$FilterChangeAction

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.
ga('create', 'UA-20639858-1', 'auto'); ga('send', 'pageview');