Package org.eclipse.egit.ui.internal.history

Source Code of org.eclipse.egit.ui.internal.history.CommitSelectionDialog

/*******************************************************************************
* Copyright (C) 2011, 2013 Mathias Kinzler <mathias.kinzler@sap.com> and others.
*
* 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 org.eclipse.egit.ui.internal.history;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map.Entry;

import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.egit.core.project.RepositoryMapping;
import org.eclipse.egit.ui.Activator;
import org.eclipse.egit.ui.UIPreferences;
import org.eclipse.egit.ui.UIUtils;
import org.eclipse.egit.ui.internal.UIText;
import org.eclipse.jface.dialogs.IMessageProvider;
import org.eclipse.jface.dialogs.TitleAreaDialog;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.resource.LocalResourceManager;
import org.eclipse.jface.resource.ResourceManager;
import org.eclipse.jface.viewers.IOpenListener;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.OpenEvent;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jgit.diff.DiffConfig;
import org.eclipse.jgit.errors.IncorrectObjectTypeException;
import org.eclipse.jgit.errors.MissingObjectException;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.FollowFilter;
import org.eclipse.jgit.revwalk.RevFlag;
import org.eclipse.jgit.revwalk.RevSort;
import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.jgit.treewalk.filter.AndTreeFilter;
import org.eclipse.jgit.treewalk.filter.OrTreeFilter;
import org.eclipse.jgit.treewalk.filter.PathFilter;
import org.eclipse.jgit.treewalk.filter.TreeFilter;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.PlatformUI;

/**
* Allows to select a single commit
*/
public class CommitSelectionDialog extends TitleAreaDialog {
  private static final int BATCH_SIZE = 256;

  private final Repository repository;

  private final IResource[] filterResources;

  private CommitGraphTable table;

  private SWTCommitList allCommits;

  private RevFlag highlightFlag;

  private ObjectId commitId;

  /**
   * @param parentShell
   * @param repository
   */
  public CommitSelectionDialog(Shell parentShell, Repository repository) {
    this(parentShell, repository, null);
  }

  /**
   * Create a commit selection dialog which shows only commits which changed
   * the given resources.
   *
   * @param parentShell
   * @param repository
   * @param filterResources
   *            the resources to use to filter commits, null for no filter
   */
  public CommitSelectionDialog(Shell parentShell, Repository repository,
      IResource[] filterResources) {
    super(parentShell);
    setShellStyle(getShellStyle() | SWT.SHELL_TRIM);
    this.repository = repository;
    this.filterResources = filterResources;
  }

  @Override
  protected Control createDialogArea(Composite parent) {
    Composite main = new Composite(parent, SWT.NONE);
    main.setLayout(new GridLayout(1, false));
    GridDataFactory.fillDefaults().grab(true, true).applyTo(main);
    final ResourceManager resources = new LocalResourceManager(
        JFaceResources.getResources());
    UIUtils.hookDisposal(main, resources);
    table = new CommitGraphTable(main, null, resources);
    table.setRelativeDate(GitHistoryPage.isShowingRelativeDates());
    table.getTableView().addSelectionChangedListener(
        new ISelectionChangedListener() {
          public void selectionChanged(SelectionChangedEvent event) {
            commitId = null;
            IStructuredSelection sel = (IStructuredSelection) event
                .getSelection();
            if (sel.size() == 1)
              commitId = ((SWTCommit) sel.getFirstElement())
                  .getId();
            getButton(OK).setEnabled(commitId != null);
          }
        });
    table.getTableView().addOpenListener(new IOpenListener() {
      public void open(OpenEvent event) {
        if (getButton(OK).isEnabled())
          buttonPressed(OK);
      }
    });
    // allow for some room here
    GridDataFactory.fillDefaults().grab(true, true).minSize(SWT.DEFAULT,
        400).applyTo(table.getControl());
    allCommits = new SWTCommitList(table.getControl(), resources);
    return main;
  }

  @Override
  protected void configureShell(Shell newShell) {
    super.configureShell(newShell);
    newShell.setText(UIText.CommitSelectionDialog_WindowTitle);
  }

  @Override
  public void create() {
    super.create();
    getButton(OK).setEnabled(false);
    try {
      PlatformUI.getWorkbench().getProgressService().run(true, true,
          new IRunnableWithProgress() {
            public void run(IProgressMonitor monitor)
                throws InvocationTargetException,
                InterruptedException {
              try {
                monitor
                    .beginTask(
                        UIText.CommitSelectionDialog_BuildingCommitListMessage,
                        IProgressMonitor.UNKNOWN);
                SWTWalk currentWalk = new SWTWalk(repository);
                currentWalk.setTreeFilter(createTreeFilter());
                currentWalk
                    .sort(RevSort.COMMIT_TIME_DESC, true);
                currentWalk.sort(RevSort.BOUNDARY, true);
                highlightFlag = currentWalk
                    .newFlag("highlight"); //$NON-NLS-1$
                allCommits.source(currentWalk);

                try {

                  if (Activator
                      .getDefault()
                      .getPreferenceStore()
                      .getBoolean(
                          UIPreferences.RESOURCEHISTORY_SHOW_ALL_BRANCHES)) {
                    markStartAllRefs(currentWalk,
                        Constants.R_HEADS);
                    markStartAllRefs(currentWalk,
                        Constants.R_REMOTES);
                  } else
                    currentWalk
                        .markStart(currentWalk
                            .parseCommit(repository
                                .resolve(Constants.HEAD)));
                  for (;;) {
                    final int oldsz = allCommits.size();
                    allCommits.fillTo(oldsz + BATCH_SIZE
                        - 1);

                    if (monitor.isCanceled()
                        || oldsz == allCommits.size())
                      break;
                    String taskName = NLS
                        .bind(
                            UIText.CommitSelectionDialog_FoundCommitsMessage,
                            Integer
                                .valueOf(allCommits
                                    .size()));
                    monitor.setTaskName(taskName);

                  }
                } catch (IOException e) {
                  throw new InvocationTargetException(e);
                }
                getShell().getDisplay().asyncExec(
                    new Runnable() {
                      public void run() {
                        updateUi();
                      }
                    });
                if (monitor.isCanceled())
                  throw new InterruptedException();
              } finally {
                monitor.done();
              }
            }
          });
    } catch (InvocationTargetException e) {
      setErrorMessage(e.getCause().getMessage());
    } catch (InterruptedException e) {
      setMessage(UIText.CommitSelectionDialog_IncompleteListMessage,
          IMessageProvider.WARNING);
    }
  }

  /**
   * @return the commit id
   */
  public ObjectId getCommitId() {
    return commitId;
  }

  private void updateUi() {
    setTitle(NLS.bind(UIText.CommitSelectionDialog_DialogTitle, Integer
        .valueOf(allCommits.size()), repository.getDirectory()
        .toString()));
    setMessage(UIText.CommitSelectionDialog_DialogMessage);
    table.setInput(highlightFlag, allCommits, allCommits
        .toArray(new SWTCommit[allCommits.size()]), null, true);
  }

  private void markStartAllRefs(RevWalk currentWalk, String prefix)
      throws IOException, MissingObjectException,
      IncorrectObjectTypeException {
    for (Entry<String, Ref> refEntry : repository.getRefDatabase().getRefs(
        prefix).entrySet()) {
      Ref ref = refEntry.getValue();
      if (ref.isSymbolic())
        continue;
      currentWalk.markStart(currentWalk.parseCommit(ref.getObjectId()));
    }
  }

  private TreeFilter createTreeFilter() {
    if (filterResources == null)
      return TreeFilter.ALL;

    List<TreeFilter> filters = new ArrayList<TreeFilter>();
    for (IResource resource : filterResources) {
      RepositoryMapping mapping = RepositoryMapping.getMapping(resource);
      if (mapping != null) {
        DiffConfig diffConfig = mapping.getRepository().getConfig().get(DiffConfig.KEY);
        String path = mapping.getRepoRelativePath(resource);
        if (path != null && !"".equals(path)) { //$NON-NLS-1$
          if (resource.getType() == IResource.FILE)
            filters.add(FollowFilter.create(path, diffConfig));
          else
            filters.add(AndTreeFilter.create(
                PathFilter.create(path), TreeFilter.ANY_DIFF));
        }
      }
    }

    if (filters.isEmpty())
      return TreeFilter.ALL;
    else if (filters.size() == 1)
      return filters.get(0);
    else
      return OrTreeFilter.create(filters);
  }
}
TOP

Related Classes of org.eclipse.egit.ui.internal.history.CommitSelectionDialog

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.