Package org.eclipse.egit.ui.internal.search

Source Code of org.eclipse.egit.ui.internal.search.CommitSearchPage$SearchComposite

/*******************************************************************************
*  Copyright (c) 2011 GitHub 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:
*    Kevin Sawicki (GitHub Inc.) - initial API and implementation
*******************************************************************************/
package org.eclipse.egit.ui.internal.search;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.StringReader;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.regex.PatternSyntaxException;

import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.egit.ui.Activator;
import org.eclipse.egit.ui.UIUtils;
import org.eclipse.egit.ui.internal.UIIcons;
import org.eclipse.egit.ui.internal.UIText;
import org.eclipse.egit.ui.internal.repository.RepositoriesViewContentProvider;
import org.eclipse.egit.ui.internal.repository.RepositoriesViewLabelProvider;
import org.eclipse.egit.ui.internal.repository.tree.RepositoryNode;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.DialogPage;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.fieldassist.ComboContentAdapter;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.layout.GridLayoutFactory;
import org.eclipse.jface.resource.JFaceColors;
import org.eclipse.jface.text.FindReplaceDocumentAdapter;
import org.eclipse.jface.text.FindReplaceDocumentAdapterContentProposalProvider;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.viewers.CheckStateChangedEvent;
import org.eclipse.jface.viewers.CheckboxTableViewer;
import org.eclipse.jface.viewers.DelegatingStyledCellLabelProvider;
import org.eclipse.jface.viewers.ICheckStateListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.search.ui.ISearchPage;
import org.eclipse.search.ui.ISearchPageContainer;
import org.eclipse.search.ui.ISearchQuery;
import org.eclipse.search.ui.NewSearchUI;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CLabel;
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.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.swt.widgets.ToolItem;
import org.eclipse.ui.fieldassist.ContentAssistCommandAdapter;
import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds;

/**
* Commit search dialog page class.
*/
public class CommitSearchPage extends DialogPage implements ISearchPage {

  /**
   * ID
   */
  public static final String ID = "org.eclipse.egit.ui.commitSearchPage"; //$NON-NLS-1$

  private static class SearchComposite extends Composite {

    /**
     * @param parent
     * @param style
     */
    public SearchComposite(Composite parent, int style) {
      super(parent, style);
    }

    public void setLayoutData(Object layoutData) {
      // Prevent search dialog from overriding the locally set data
      if (getLayoutData() == null)
        super.setLayoutData(layoutData);
    }
  }

  private static final int HISTORY_SIZE = 12;

  // Dialog store id constants
  private static final String PAGE_NAME = "GitCommitSearchPage"; //$NON-NLS-1$

  private static final String STORE_HISTORY = "HISTORY"; //$NON-NLS-1$

  private static final String STORE_HISTORY_SIZE = "HISTORY_SIZE"; //$NON-NLS-1$

  private List<CommitSearchSettings> fPreviousSearchPatterns = new ArrayList<CommitSearchSettings>(
      HISTORY_SIZE);

  private boolean firstTime = true;

  private Combo patternCombo;

  private Button isCaseSensitiveButton;

  private Button isRegExButton;

  private Button searchTreeButton;

  private Button searchCommitButton;

  private Button searchParentsButton;

  private Button searchAuthorButton;

  private Button searchCommitterButton;

  private Button searchMessageButton;

  private Button searchAllBranchesButton;

  private CLabel statusLabel;

  private Group repositoryGroup;

  private CheckboxTableViewer repositoryViewer;

  private ISearchPageContainer container;

  private ContentAssistCommandAdapter patternFieldContentAssist;

  private ISearchQuery newQuery() {
    CommitSearchSettings settings = new CommitSearchSettings();
    settings.setTextPattern(patternCombo.getText());
    settings.setRegExSearch(isRegExButton.getSelection());
    settings.setCaseSensitive(isCaseSensitiveButton.getSelection());
    settings.setMatchAuthor(searchAuthorButton.getSelection());
    settings.setMatchCommitter(searchCommitterButton.getSelection());
    settings.setMatchMessage(searchMessageButton.getSelection());
    settings.setMatchCommit(searchCommitButton.getSelection());
    settings.setMatchTree(searchTreeButton.getSelection());
    settings.setMatchParents(searchParentsButton.getSelection());
    settings.setAllBranches(searchAllBranchesButton.getSelection());
    for (Object checked : repositoryViewer.getCheckedElements())
      settings.addRepository(((RepositoryNode) checked).getRepository()
          .getDirectory().getAbsolutePath());
    fPreviousSearchPatterns.add(0, settings);
    return new CommitSearchQuery(settings);
  }

  /**
   * Perform search by running query in background
   *
   * @see org.eclipse.search.ui.ISearchPage#performAction()
   */
  public boolean performAction() {
    NewSearchUI.runQueryInBackground(newQuery());
    return true;
  }

  private String[] getPreviousSearchPatterns() {
    int size = fPreviousSearchPatterns.size();
    String[] patterns = new String[size];
    for (int i = 0; i < size; i++)
      patterns[i] = fPreviousSearchPatterns.get(i).getTextPattern();
    return patterns;
  }

  public void setVisible(boolean visible) {
    if (visible && patternCombo != null) {
      if (firstTime) {
        firstTime = false;
        // Set item and text here to prevent page from resizing
        patternCombo.setItems(getPreviousSearchPatterns());
        if (!initializePatternControl()) {
          patternCombo.select(0);
          handleWidgetSelected();
        }
      }
      patternCombo.setFocus();
    }
    updateOKStatus();
    super.setVisible(visible);
  }

  private void updateOKStatus() {
    boolean status = validateRegex();
    if (status)
      status = validateScope();
    if (status)
      status = validateRepositories();
    getContainer().setPerformActionEnabled(status);
  }

  private boolean validateRepositories() {
    return this.repositoryViewer.getCheckedElements().length > 0;
  }

  private boolean validateScope() {
    return this.searchAuthorButton.getSelection()
        || this.searchCommitterButton.getSelection()
        || this.searchMessageButton.getSelection()
        || this.searchCommitButton.getSelection()
        || this.searchParentsButton.getSelection()
        || this.searchTreeButton.getSelection();
  }

  public void createControl(Composite parent) {
    readConfiguration();

    initializeDialogUnits(parent);
    SearchComposite result = new SearchComposite(parent, SWT.NONE);
    result.setFont(parent.getFont());
    GridDataFactory.fillDefaults().grab(true, true).applyTo(result);
    GridLayoutFactory.swtDefaults().numColumns(2).equalWidth(false)
        .applyTo(result);
    addTextPatternControls(result);
    addScopeControls(result);
    addRepositoryControl(result);
    setControl(result);
    Dialog.applyDialogFont(result);
  }

  private boolean validateRegex() {
    if (isRegExButton.getSelection()) {
      try {
        PatternUtils.createPattern(patternCombo.getText(),
            isCaseSensitiveButton.getSelection(), true);
      } catch (PatternSyntaxException e) {
        String locMessage = e.getLocalizedMessage();
        int i = 0;
        while (i < locMessage.length()
            && "\n\r".indexOf(locMessage.charAt(i)) == -1) //$NON-NLS-1$
          i++;
        statusMessage(true, locMessage.substring(0, i));
        return false;
      }
      statusMessage(false, ""); //$NON-NLS-1$
    } else {
      statusMessage(false, UIText.CommitSearchPage_ContainingTextHint);
    }
    return true;
  }

  private void addScopeControls(Composite parent) {
    SelectionAdapter statusAdapter = new SelectionAdapter() {

      public void widgetSelected(SelectionEvent e) {
        updateOKStatus();
      }

    };

    Group scopeArea = new Group(parent, SWT.NONE);
    scopeArea.setText(UIText.CommitSearchPage_Scope);
    GridDataFactory.fillDefaults().grab(true, false).span(2, 1)
        .applyTo(scopeArea);
    GridLayoutFactory.swtDefaults().numColumns(3).applyTo(scopeArea);

    this.searchMessageButton = new Button(scopeArea, SWT.CHECK);
    this.searchMessageButton.setText(UIText.CommitSearchPage_Message);
    this.searchMessageButton.setSelection(true);
    this.searchMessageButton.addSelectionListener(statusAdapter);

    this.searchAuthorButton = new Button(scopeArea, SWT.CHECK);
    this.searchAuthorButton.setText(UIText.CommitSearchPage_Author);
    this.searchAuthorButton.setSelection(true);
    this.searchAuthorButton.addSelectionListener(statusAdapter);

    this.searchCommitterButton = new Button(scopeArea, SWT.CHECK);
    this.searchCommitterButton.setText(UIText.CommitSearchPage_Committer);
    this.searchCommitterButton.setSelection(true);
    this.searchCommitterButton.addSelectionListener(statusAdapter);

    this.searchCommitButton = new Button(scopeArea, SWT.CHECK);
    this.searchCommitButton.setText(UIText.CommitSearchPage_CommitId);
    this.searchCommitButton.setSelection(true);
    this.searchCommitButton.addSelectionListener(statusAdapter);

    this.searchTreeButton = new Button(scopeArea, SWT.CHECK);
    this.searchTreeButton.setText(UIText.CommitSearchPage_TreeId);
    this.searchTreeButton.setSelection(true);
    this.searchTreeButton.addSelectionListener(statusAdapter);

    this.searchParentsButton = new Button(scopeArea, SWT.CHECK);
    this.searchParentsButton.setText(UIText.CommitSearchPage_ParentIds);
    this.searchParentsButton.setSelection(true);
    this.searchParentsButton.addSelectionListener(statusAdapter);
  }

  private void addRepositoryControl(Composite parent) {
    repositoryGroup = new Group(parent, SWT.NONE);
    repositoryGroup.setBackgroundMode(SWT.INHERIT_DEFAULT);
    GridDataFactory.fillDefaults().grab(true, true).span(2, 1)
        .applyTo(repositoryGroup);
    GridLayoutFactory.swtDefaults().numColumns(2).applyTo(repositoryGroup);

    this.repositoryViewer = CheckboxTableViewer.newCheckList(
        repositoryGroup, SWT.SINGLE | SWT.V_SCROLL | SWT.H_SCROLL
            | SWT.BORDER);
    this.repositoryViewer
        .setLabelProvider(new DelegatingStyledCellLabelProvider(
            new RepositoriesViewLabelProvider()));
    this.repositoryViewer
        .setContentProvider(new RepositoriesViewContentProvider());
    this.repositoryViewer
        .setInput(ResourcesPlugin.getWorkspace().getRoot());
    this.repositoryViewer.addCheckStateListener(new ICheckStateListener() {

      public void checkStateChanged(CheckStateChangedEvent event) {
        updateOKStatus();
        repositoryGroup.setText(getRepositoryText());
      }
    });
    GridDataFactory.fillDefaults().grab(true, true).hint(SWT.DEFAULT, 40)
        .applyTo(this.repositoryViewer.getControl());

    ToolBar checkBar = new ToolBar(repositoryGroup, SWT.FLAT | SWT.VERTICAL);
    GridDataFactory.swtDefaults().align(SWT.BEGINNING, SWT.TOP)
        .grab(false, true).applyTo(checkBar);
    ToolItem checkItem = new ToolItem(checkBar, SWT.PUSH);
    checkItem.setToolTipText(UIText.CommitSearchPage_CheckAll);
    Image checkImage = UIIcons.CHECK_ALL.createImage();
    UIUtils.hookDisposal(checkItem, checkImage);
    checkItem.setImage(checkImage);
    checkItem.addSelectionListener(new SelectionAdapter() {

      public void widgetSelected(SelectionEvent e) {
        repositoryViewer.setAllChecked(true);
        repositoryGroup.setText(getRepositoryText());
        updateOKStatus();
      }

    });
    ToolItem uncheckItem = new ToolItem(checkBar, SWT.PUSH);
    uncheckItem.setToolTipText(UIText.CommitSearchPage_UncheckAll);
    Image uncheckImage = UIIcons.UNCHECK_ALL.createImage();
    UIUtils.hookDisposal(uncheckItem, uncheckImage);
    uncheckItem.setImage(uncheckImage);
    uncheckItem.addSelectionListener(new SelectionAdapter() {

      public void widgetSelected(SelectionEvent e) {
        repositoryViewer.setAllChecked(false);
        repositoryGroup.setText(getRepositoryText());
        updateOKStatus();
      }

    });

    this.searchAllBranchesButton = new Button(repositoryGroup, SWT.CHECK);
    this.searchAllBranchesButton
        .setText(UIText.CommitSearchPage_SearchAllBranches);
    GridDataFactory.swtDefaults().grab(true, false).span(2, 1)
        .applyTo(this.searchAllBranchesButton);

    repositoryGroup.setText(getRepositoryText());
  }

  private String getRepositoryText() {
    return MessageFormat.format(UIText.CommitSearchPage_Repositories,
        Integer.valueOf(repositoryViewer.getCheckedElements().length),
        Integer.valueOf(repositoryViewer.getTable().getItemCount()));
  }

  private void addTextPatternControls(Composite group) {
    // Info text
    Label label = new Label(group, SWT.NONE);
    label.setText(UIText.CommitSearchPage_ContainingText);
    label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 2,
        1));
    label.setFont(group.getFont());

    // Pattern combo
    patternCombo = new Combo(group, SWT.SINGLE | SWT.BORDER);
    patternCombo.addSelectionListener(new SelectionAdapter() {
      public void widgetSelected(SelectionEvent e) {
        handleWidgetSelected();
        updateOKStatus();
      }
    });
    // add some listeners for regex syntax checking
    patternCombo.addModifyListener(new ModifyListener() {
      public void modifyText(ModifyEvent e) {
        updateOKStatus();
      }
    });
    patternCombo.setFont(group.getFont());
    GridData data = new GridData(GridData.FILL, GridData.FILL, true, false,
        1, 1);
    data.widthHint = convertWidthInCharsToPixels(50);
    patternCombo.setLayoutData(data);

    ComboContentAdapter contentAdapter = new ComboContentAdapter();
    FindReplaceDocumentAdapterContentProposalProvider findProposer = new FindReplaceDocumentAdapterContentProposalProvider(
        true);
    patternFieldContentAssist = new ContentAssistCommandAdapter(
        patternCombo, contentAdapter, findProposer,
        ITextEditorActionDefinitionIds.CONTENT_ASSIST_PROPOSALS,
        new char[0], true);
    patternFieldContentAssist.setEnabled(false);

    isCaseSensitiveButton = new Button(group, SWT.CHECK);
    isCaseSensitiveButton.setText(UIText.CommitSearchPage_CaseSensitive);
    isCaseSensitiveButton.setLayoutData(new GridData(SWT.FILL, SWT.CENTER,
        false, false, 1, 1));
    isCaseSensitiveButton.setFont(group.getFont());

    // Text line which explains the special characters
    statusLabel = new CLabel(group, SWT.LEAD);
    statusLabel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true,
        false, 1, 1));
    statusLabel.setFont(group.getFont());
    statusLabel.setAlignment(SWT.LEFT);
    statusLabel.setText(UIText.CommitSearchPage_ContainingTextHint);

    // RegEx checkbox
    isRegExButton = new Button(group, SWT.CHECK);
    isRegExButton.setText(UIText.CommitSearchPage_RegularExpression);
    isRegExButton.addSelectionListener(new SelectionAdapter() {
      public void widgetSelected(SelectionEvent e) {
        updateOKStatus();

        patternFieldContentAssist.setEnabled(isRegExButton
            .getSelection());
      }
    });
    isRegExButton.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false,
        false, 1, 1));
    isRegExButton.setFont(group.getFont());
  }

  private void handleWidgetSelected() {
    int selectionIndex = patternCombo.getSelectionIndex();
    if (selectionIndex < 0
        || selectionIndex >= fPreviousSearchPatterns.size()) {
      repositoryViewer.setAllChecked(true);
      repositoryGroup.setText(getRepositoryText());
      return;
    }

    CommitSearchSettings settings = fPreviousSearchPatterns
        .get(selectionIndex);
    if (!patternCombo.getText().equals(settings.getTextPattern()))
      return;

    isCaseSensitiveButton.setSelection(settings.isCaseSensitive());
    isRegExButton.setSelection(settings.isRegExSearch());
    patternCombo.setText(settings.getTextPattern());
    patternFieldContentAssist.setEnabled(settings.isRegExSearch());

    searchAuthorButton.setSelection(settings.isMatchAuthor());
    searchCommitButton.setSelection(settings.isMatchCommit());
    searchCommitterButton.setSelection(settings.isMatchCommitter());
    searchMessageButton.setSelection(settings.isMatchMessage());
    searchParentsButton.setSelection(settings.isMatchParents());
    searchTreeButton.setSelection(settings.isMatchTree());
    searchAllBranchesButton.setSelection(settings.isAllBranches());

    List<RepositoryNode> repositories = new LinkedList<RepositoryNode>();
    for (String path : settings.getRepositories()) {
      File file = new File(path);
      if (file.exists())
        try {
          RepositoryNode node = new RepositoryNode(null,
              org.eclipse.egit.core.Activator.getDefault()
                  .getRepositoryCache()
                  .lookupRepository(file));
          repositories.add(node);
        } catch (IOException ignore) {
          // Ignore and don't check
        }
    }
    repositoryViewer.setCheckedElements(repositories.toArray());
    repositoryGroup.setText(getRepositoryText());
  }

  private boolean initializePatternControl() {
    ISelection selection = getSelection();
    if (selection instanceof ITextSelection && !selection.isEmpty()) {
      String text = ((ITextSelection) selection).getText();
      if (text != null) {
        if (isRegExButton.getSelection())
          patternCombo.setText(FindReplaceDocumentAdapter
              .escapeForRegExPattern(text));
        else
          patternCombo.setText(insertEscapeChars(text));

        return true;
      }
    }
    return false;
  }

  private String insertEscapeChars(String text) {
    if (text == null || text.length() == 0)
      return ""; //$NON-NLS-1$
    StringBuilder sbIn = new StringBuilder(text);
    BufferedReader reader = new BufferedReader(new StringReader(text));
    int lengthOfFirstLine = 0;
    try {
      String l = reader.readLine();
      if (l != null)
        lengthOfFirstLine = l.length();
    } catch (IOException ex) {
      return ""; //$NON-NLS-1$
    }
    StringBuilder sbOut = new StringBuilder(lengthOfFirstLine + 5);
    int i = 0;
    while (i < lengthOfFirstLine) {
      char ch = sbIn.charAt(i);
      if (ch == '*' || ch == '?' || ch == '\\')
        sbOut.append('\\');
      sbOut.append(ch);
      i++;
    }
    return sbOut.toString();
  }

  /**
   * Sets the search page's container.
   *
   * @param container
   *            the container to set
   */
  public void setContainer(ISearchPageContainer container) {
    this.container = container;
  }

  private ISearchPageContainer getContainer() {
    return this.container;
  }

  private ISelection getSelection() {
    return this.container.getSelection();
  }

  public void dispose() {
    writeConfiguration();
    super.dispose();
  }

  /**
   * Returns the page settings for this Text search page.
   *
   * @return the page settings to be used
   */
  private IDialogSettings getDialogSettings() {
    IDialogSettings dialogSettings = Activator.getDefault()
        .getDialogSettings();
    IDialogSettings section = dialogSettings.getSection(PAGE_NAME);
    if (section == null)
      section = dialogSettings.addNewSection(PAGE_NAME);
    return section;
  }

  /**
   * Initializes itself from the stored page settings.
   */
  private void readConfiguration() {
    IDialogSettings settings = getDialogSettings();
    try {
      int historySize = settings.getInt(STORE_HISTORY_SIZE);
      for (int i = 0; i < historySize; i++) {
        IDialogSettings histSettings = settings
            .getSection(STORE_HISTORY + i);
        if (histSettings != null)
          fPreviousSearchPatterns.add(CommitSearchSettings
              .create(histSettings));
      }
    } catch (NumberFormatException ignored) {
      // Ignored
    }
  }

  /**
   * Stores it current configuration in the dialog store.
   */
  private void writeConfiguration() {
    IDialogSettings s = getDialogSettings();
    int historySize = Math
        .min(fPreviousSearchPatterns.size(), HISTORY_SIZE);
    s.put(STORE_HISTORY_SIZE, historySize);
    for (int i = 0; i < historySize; i++)
      fPreviousSearchPatterns.get(i).store(
          s.addNewSection(STORE_HISTORY + i));
  }

  private void statusMessage(boolean error, String message) {
    statusLabel.setText(message);
    if (error)
      statusLabel.setForeground(JFaceColors.getErrorText(statusLabel
          .getDisplay()));
    else
      statusLabel.setForeground(null);
  }

}
TOP

Related Classes of org.eclipse.egit.ui.internal.search.CommitSearchPage$SearchComposite

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.