Package org.eclipse.egit.ui.internal.rebase

Source Code of org.eclipse.egit.ui.internal.rebase.RebaseResultDialog

/*******************************************************************************
* Copyright (c) 2010, 2013 SAP AG 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
*
* Contributors:
*    Mathias Kinzler (SAP AG) - initial implementation
*******************************************************************************/
package org.eclipse.egit.ui.internal.rebase;

import java.io.IOException;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.eclipse.compare.CompareEditorInput;
import org.eclipse.compare.CompareUI;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.egit.core.internal.FileChecker;
import org.eclipse.egit.core.internal.FileChecker.CheckResult;
import org.eclipse.egit.core.internal.FileChecker.CheckResultEntry;
import org.eclipse.egit.core.project.RepositoryMapping;
import org.eclipse.egit.ui.Activator;
import org.eclipse.egit.ui.UIPreferences;
import org.eclipse.egit.ui.internal.UIText;
import org.eclipse.egit.ui.internal.commands.shared.AbortRebaseCommand;
import org.eclipse.egit.ui.internal.commands.shared.AbstractRebaseCommandHandler;
import org.eclipse.egit.ui.internal.commands.shared.SkipRebaseCommand;
import org.eclipse.egit.ui.internal.dialogs.CheckoutConflictDialog;
import org.eclipse.egit.ui.internal.merge.GitMergeEditorInput;
import org.eclipse.egit.ui.internal.merge.MergeModeDialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.text.TextViewer;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.window.Window;
import org.eclipse.jgit.api.RebaseResult;
import org.eclipse.jgit.api.RebaseResult.Status;
import org.eclipse.jgit.dircache.DirCache;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.merge.ResolveMerger.MergeFailureReason;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.PlatformUI;

/**
* Display the result of a rebase.
*/
public class RebaseResultDialog extends MessageDialog {
  private static final String SPACE = " "; //$NON-NLS-1$

  private static final Image INFO = PlatformUI.getWorkbench()
      .getSharedImages().getImage(ISharedImages.IMG_OBJS_INFO_TSK);

  private final RebaseResult result;

  private final Repository repo;

  private final Set<String> conflictPaths = new HashSet<String>();

  private Button toggleButton;

  private Button startMergeButton;

  private Button skipCommitButton;

  private Button abortRebaseButton;

  private Button doNothingButton;

  private Group nextStepsGroup;

  /**
   * @param result
   *            the result to show
   * @param repository
   */
  public static void show(final RebaseResult result,
      final Repository repository) {
    boolean shouldShow = result.getStatus() == Status.STOPPED
        || result.getStatus() == Status.STASH_APPLY_CONFLICTS
        || Activator.getDefault().getPreferenceStore().getBoolean(
            UIPreferences.SHOW_REBASE_CONFIRM);

    if(result.getStatus() == Status.CONFLICTS) {
      PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
        public void run() {
          Shell shell = PlatformUI.getWorkbench()
              .getActiveWorkbenchWindow().getShell();
          new CheckoutConflictDialog(shell, repository, result.getConflicts()).open();
        }
      });

      return;
    }

    if (!shouldShow) {
      Activator.getDefault().getLog().log(
          new org.eclipse.core.runtime.Status(IStatus.INFO, Activator
              .getPluginId(), NLS.bind(
              UIText.RebaseResultDialog_StatusLabel, result
                  .getStatus().name())));
      return;
    }
    PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
      public void run() {
        Shell shell = PlatformUI.getWorkbench()
            .getActiveWorkbenchWindow().getShell();
        new RebaseResultDialog(shell, repository, result).open();
      }
    });
  }

  private static String getTitle(Status status) {
    switch (status) {
    case OK:
      return UIText.RebaseResultDialog_SuccessfullyFinished;
    case ABORTED:
      return UIText.RebaseResultDialog_Aborted;
    case STOPPED:
      return UIText.RebaseResultDialog_Stopped;
    case EDIT:
      return UIText.RebaseResultDialog_Edit;
    case FAILED:
      return UIText.RebaseResultDialog_Failed;
    case UP_TO_DATE:
      return UIText.RebaseResultDialog_UpToDate;
    case FAST_FORWARD:
      return UIText.RebaseResultDialog_FastForward;
    case NOTHING_TO_COMMIT:
      return UIText.RebaseResultDialog_NothingToCommit;
    case INTERACTIVE_PREPARED:
      return UIText.RebaseResultDialog_InteractivePrepared;
    case UNCOMMITTED_CHANGES:
      return UIText.RebaseResultDialog_UncommittedChanges;
    case STASH_APPLY_CONFLICTS:
      return UIText.RebaseResultDialog_SuccessfullyFinished + ".\n" + //$NON-NLS-1$
          UIText.RebaseResultDialog_stashApplyConflicts;
    default:
      throw new IllegalStateException(status.name());
    }
  }

  /**
   * @param status
   * @return text describing rebase status in short form
   */
  public static String getStatusText(Status status) {
    switch (status) {
    case OK:
      return UIText.RebaseResultDialog_StatusOK;
    case ABORTED:
      return UIText.RebaseResultDialog_StatusAborted;
    case STOPPED:
      return UIText.RebaseResultDialog_StatusStopped;
    case EDIT:
      return UIText.RebaseResultDialog_StatusEdit;
    case FAILED:
      return UIText.RebaseResultDialog_StatusFailed;
    case CONFLICTS:
      return UIText.RebaseResultDialog_StatusConflicts;
    case UP_TO_DATE:
      return UIText.RebaseResultDialog_StatusUpToDate;
    case FAST_FORWARD:
      return UIText.RebaseResultDialog_StatusFastForward;
    case NOTHING_TO_COMMIT:
      return UIText.RebaseResultDialog_StatusNothingToCommit;
    case UNCOMMITTED_CHANGES:
      return UIText.RebaseResultDialog_UncommittedChanges;
    case INTERACTIVE_PREPARED:
      return UIText.RebaseResultDialog_StatusInteractivePrepared;
    case STASH_APPLY_CONFLICTS:
      return UIText.RebaseResultDialog_SuccessfullyFinished + ".\n" + //$NON-NLS-1$
          UIText.RebaseResultDialog_stashApplyConflicts;
    }
    return status.toString();
  }

  /**
   * @param shell
   * @param repository
   * @param result
   */
  private RebaseResultDialog(Shell shell, Repository repository,
      RebaseResult result) {
    super(shell, UIText.RebaseResultDialog_DialogTitle, INFO,
        getTitle(result.getStatus()),
        result.getStatus() == Status.FAILED ? MessageDialog.ERROR
            : MessageDialog.INFORMATION,
        new String[] { IDialogConstants.OK_LABEL }, 0);
    setShellStyle(getShellStyle() | SWT.SHELL_TRIM);
    this.repo = repository;
    this.result = result;
  }

  @Override
  protected Control createCustomArea(Composite parent) {

    if (result.getStatus() == Status.STOPPED)
      return createStoppedDialogArea(parent);
    if (result.getStatus() == Status.FAILED
        || result.getStatus() == Status.CONFLICTS)
      return createFailedOrConflictDialog(parent);
    createToggleButton(parent);
    return null;
  }

  private Control createFailedOrConflictDialog(Composite parent) {
    Composite composite = new Composite(parent, SWT.NONE);
    createFailedOrConflictsParts(composite, result);

    return composite;
  }

  /**
   * Create the items in composite necessary for a rebase result
   *
   * @param composite
   * @param result
   */
  public static void createFailedOrConflictsParts(Composite composite,
      RebaseResult result) {
    GridLayout gridLayout = new GridLayout();
    gridLayout.numColumns = 2;
    composite.setLayout(gridLayout);
    // result
    Label resultLabel = new Label(composite, SWT.NONE);
    resultLabel.setText(UIText.MergeResultDialog_result);
    resultLabel.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false,
        false));
    Text resultText = new Text(composite, SWT.READ_ONLY);
    resultText.setText(getStatusText(result.getStatus()));
    if (!result.getStatus().isSuccessful())
      resultText.setForeground(composite.getParent().getDisplay()
          .getSystemColor(SWT.COLOR_RED));
    resultText.setSelection(resultText.getCaretPosition());
    resultText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));

    if (result.getStatus() == Status.FAILED) {
      StringBuilder paths = new StringBuilder();
      Label pathsLabel = new Label(composite, SWT.NONE);
      pathsLabel.setText(UIText.MergeResultDialog_failed);
      pathsLabel.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, false,
          false));
      Text pathsText = new Text(composite, SWT.READ_ONLY);
      pathsText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false,
          false));
      Set<Entry<String, MergeFailureReason>> failedPaths = result
          .getFailingPaths().entrySet();
      int n = 0;
      for (Map.Entry<String, MergeFailureReason> e : failedPaths) {
        if (n > 0)
          paths.append(Text.DELIMITER);
        paths.append(e.getValue());
        paths.append("\t"); //$NON-NLS-1$
        paths.append(e.getKey());
        n++;
        if (n > 10 && failedPaths.size() > 15)
          break;
      }
      if (n < failedPaths.size()) {
        paths.append(Text.DELIMITER);
        paths.append(MessageFormat.format(
            UIText.MergeResultDialog_nMore,
            Integer.valueOf(n - failedPaths.size())));
      }
      pathsText.setText(paths.toString());
    } else if (result.getStatus() == Status.CONFLICTS) {
      StringBuilder paths = new StringBuilder();
      Label pathsLabel = new Label(composite, SWT.NONE);
      pathsLabel.setText(UIText.MergeResultDialog_conflicts);
      pathsLabel.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, false,
          false));
      Text pathsText = new Text(composite, SWT.READ_ONLY);
      pathsText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false,
          false));
      List<String> conflList = result.getConflicts();
      int n = 0;
      for (String e : conflList) {
        if (n > 0)
          paths.append(Text.DELIMITER);
        paths.append(e);
        n++;
        if (n > 10 && conflList.size() > 15)
          break;
      }
      if (n < conflList.size()) {
        paths.append(Text.DELIMITER);
        paths.append(MessageFormat.format(
            UIText.MergeResultDialog_nMore,
            Integer.valueOf(n - conflList.size())));
      }
      pathsText.setText(paths.toString());
    }
  }

  private Control createStoppedDialogArea(Composite parent) {
    Composite main = new Composite(parent, SWT.NONE);
    main.setLayout(new GridLayout(1, false));
    GridDataFactory.fillDefaults().indent(0, 0).grab(true, true).applyTo(
        main);

    Group commitGroup = new Group(main, SWT.SHADOW_ETCHED_IN);
    GridDataFactory.fillDefaults().grab(true, true).applyTo(commitGroup);
    commitGroup.setText(UIText.RebaseResultDialog_DetailsGroup);
    commitGroup.setLayout(new GridLayout(1, false));

    Label commitIdLabel = new Label(commitGroup, SWT.NONE);
    commitIdLabel.setText(UIText.RebaseResultDialog_CommitIdLabel);
    Text commitId = new Text(commitGroup, SWT.READ_ONLY | SWT.BORDER);
    GridDataFactory.fillDefaults().grab(true, false).applyTo(commitId);

    Label commitMessageLabel = new Label(commitGroup, SWT.NONE);
    commitMessageLabel
        .setText(UIText.RebaseResultDialog_CommitMessageLabel);
    TextViewer commitMessage = new TextViewer(commitGroup, SWT.H_SCROLL
        | SWT.V_SCROLL | SWT.MULTI | SWT.BORDER | SWT.READ_ONLY);
    GridDataFactory.fillDefaults().grab(true, true).hint(SWT.DEFAULT, 60)
        .applyTo(commitMessage.getControl());

    boolean conflictListFailure = false;
    DirCache dc = null;
    RevWalk rw = null;
    try {
      rw = new RevWalk(repo);
      // the commits might not have been fully loaded
      RevCommit commit = rw.parseCommit(result.getCurrentCommit());
      commitMessage.getTextWidget().setText(commit.getFullMessage());
      commitId.setText(commit.name());
      dc = repo.lockDirCache();
      for (int i = 0; i < dc.getEntryCount(); i++)
        if (dc.getEntry(i).getStage() > 0)
          conflictPaths.add(dc.getEntry(i).getPathString());
      if (conflictPaths.size() > 0) {
        message = NLS.bind(UIText.RebaseResultDialog_Conflicting,
            Integer.valueOf(conflictPaths.size()));
        messageLabel.setText(message);
      }
    } catch (IOException e) {
      // the file list will be empty
      conflictListFailure = true;
    } finally {
      if (rw != null)
        rw.release();
      if (dc != null)
        dc.unlock();
    }

    boolean mergeToolAvailable = true;
    final CheckResult checkResult;
    if (!conflictListFailure) {
      checkResult = FileChecker.checkFiles(repo, conflictPaths);
      mergeToolAvailable = checkResult.isOk();
    }
    else {
      checkResult = null;
      mergeToolAvailable = false;
    }

    if (conflictListFailure) {
      Label failureLabel = new Label(main, SWT.NONE);
      failureLabel
          .setText(UIText.RebaseResultDialog_ConflictListFailureMessage);
    } else {
      if (checkResult != null && !checkResult.isOk()) {
        Label failureLabel = new Label(main, SWT.NONE);
        failureLabel
          .setText(getProblemDescription(checkResult));
      }
      Label conflictListLabel = new Label(main, SWT.NONE);
      conflictListLabel
      .setText(UIText.RebaseResultDialog_DiffDetailsLabel);
      TableViewer conflictList = new TableViewer(main, SWT.BORDER);
      GridDataFactory.fillDefaults().span(2, 1).grab(true, true).applyTo(
          conflictList.getTable());
      conflictList.setContentProvider(ArrayContentProvider.getInstance());
      conflictList.setInput(conflictPaths);
      conflictList.setLabelProvider(new LabelProvider() {
        @Override
        public String getText(Object element) {
          String path = (String) element;
          if (checkResult != null && !checkResult.isOk()) {
            CheckResultEntry entry = checkResult.getEntry(path);
            if (entry != null) {
              if (!entry.inWorkspace)
                return UIText.RebaseResultDialog_notInWorkspace + SPACE + path;
              if (!entry.shared)
                return UIText.RebaseResultDialog_notShared + SPACE + path;
            }
          }
          return super.getText(element);
        }

      });
    }

    Group actionGroup = new Group(main, SWT.SHADOW_ETCHED_IN);
    GridDataFactory.fillDefaults().grab(true, false).applyTo(actionGroup);
    actionGroup.setText(UIText.RebaseResultDialog_ActionGroupTitle);
    actionGroup.setLayout(new GridLayout(1, false));

    nextStepsGroup = new Group(main, SWT.SHADOW_ETCHED_IN);
    GridDataFactory.fillDefaults().grab(true, true).applyTo(nextStepsGroup);
    nextStepsGroup.setText(UIText.RebaseResultDialog_NextSteps);
    nextStepsGroup.setLayout(new GridLayout(1, false));
    final TextViewer nextSteps = new TextViewer(nextStepsGroup, SWT.MULTI
        | SWT.BORDER | SWT.READ_ONLY);
    GridDataFactory.fillDefaults().grab(true, true).hint(SWT.DEFAULT, 60)
        .applyTo(nextSteps.getControl());
    nextSteps.getTextWidget().setText(
        UIText.RebaseResultDialog_NextStepsAfterResolveConflicts);

    startMergeButton = new Button(actionGroup, SWT.RADIO);
    startMergeButton.setText(UIText.RebaseResultDialog_StartMergeRadioText);
    startMergeButton.setEnabled(mergeToolAvailable);
    startMergeButton.addSelectionListener(new SelectionListener() {

      public void widgetSelected(SelectionEvent e) {
        if (startMergeButton.getSelection())
          nextSteps
              .getTextWidget()
              .setText(
                  UIText.RebaseResultDialog_NextStepsAfterResolveConflicts);
      }

      public void widgetDefaultSelected(SelectionEvent e) {
        // nothing
      }

    });

    skipCommitButton = new Button(actionGroup, SWT.RADIO);
    skipCommitButton.setText(UIText.RebaseResultDialog_SkipCommitButton);
    skipCommitButton.addSelectionListener(new SelectionListener() {

      public void widgetSelected(SelectionEvent e) {
        if (skipCommitButton.getSelection())
          nextSteps.getTextWidget().setText(""); //$NON-NLS-1$
      }

      public void widgetDefaultSelected(SelectionEvent e) {
        // nothing
      }

    });

    abortRebaseButton = new Button(actionGroup, SWT.RADIO);
    abortRebaseButton
        .setText(UIText.RebaseResultDialog_AbortRebaseRadioText);
    abortRebaseButton.addSelectionListener(new SelectionListener() {

      public void widgetSelected(SelectionEvent e) {
        if (abortRebaseButton.getSelection())
          nextSteps.getTextWidget().setText(""); //$NON-NLS-1$
      }

      public void widgetDefaultSelected(SelectionEvent e) {
        // nothing
      }

    });

    doNothingButton = new Button(actionGroup, SWT.RADIO);
    doNothingButton.setText(UIText.RebaseResultDialog_DoNothingRadioText);
    doNothingButton.addSelectionListener(new SelectionListener() {

      public void widgetSelected(SelectionEvent e) {
        if (doNothingButton.getSelection())
          nextSteps.getTextWidget().setText(
              UIText.RebaseResultDialog_NextStepsDoNothing);
      }

      public void widgetDefaultSelected(SelectionEvent e) {
        // nothing
      }

    });

    if (mergeToolAvailable)
      startMergeButton.setSelection(true);
    else
      doNothingButton.setSelection(true);

    commitGroup.pack();
    applyDialogFont(main);

    return main;
  }

  private static String getProblemDescription(CheckResult checkResult) {
    StringBuffer result = new StringBuffer();
    if (checkResult.containsNonWorkspaceFiles())
      result.append(UIText.RebaseResultDialog_notInWorkspaceMessage);
    if (checkResult.containsNotSharedResources()) {
      if (result.length() > 0)
        result.append('\n');
      result.append(UIText.RebaseResultDialog_notSharedMessage);
    }
    return result.toString();
  }

  @Override
  protected void buttonPressed(int buttonId) {
    // store the preference to hide these dialogs
    if (toggleButton != null)
      Activator.getDefault().getPreferenceStore().setValue(
          UIPreferences.SHOW_REBASE_CONFIRM,
          !toggleButton.getSelection());
    if (buttonId == IDialogConstants.OK_ID) {
      if (result.getStatus() != Status.STOPPED) {
        super.buttonPressed(buttonId);
        return;
      }
      if (startMergeButton.getSelection()) {
        super.buttonPressed(buttonId);
        // open the merge tool
        IProject[] projects = ResourcesPlugin.getWorkspace().getRoot()
            .getProjects();
        for (IProject project : projects) {
          RepositoryMapping mapping = RepositoryMapping
              .getMapping(project);
          if (mapping != null && mapping.getRepository().equals(repo)) {
            try {
              // make sure to refresh before opening the merge
              // tool
              project
                  .refreshLocal(IResource.DEPTH_INFINITE,
                      null);
            } catch (CoreException e) {
              Activator.handleError(e.getMessage(), e, false);
            }
          }
        }
        List<IPath> locationList = new ArrayList<IPath>();
        IPath repoWorkdirPath = new Path(repo.getWorkTree().getPath());
        for (String repoPath : conflictPaths) {
          IPath location = repoWorkdirPath.append(repoPath);
          locationList.add(location);
        }
        IPath[] locations = locationList.toArray(new IPath[locationList
            .size()]);
        int mergeMode = Activator.getDefault().getPreferenceStore()
            .getInt(UIPreferences.MERGE_MODE);
        CompareEditorInput input;
        if (mergeMode == 0) {
          MergeModeDialog dlg = new MergeModeDialog(getParentShell());
          if (dlg.open() != Window.OK)
            return;
          input = new GitMergeEditorInput(dlg.useWorkspace(),
              locations);
        } else {
          boolean useWorkspace = mergeMode == 1;
          input = new GitMergeEditorInput(useWorkspace,
              locations);
        }
        CompareUI.openCompareEditor(input);
        return;
      } else if (skipCommitButton.getSelection()) {
        // skip the rebase
        SkipRebaseCommand skipCommand = new SkipRebaseCommand();
        execute(skipCommand);
      } else if (abortRebaseButton.getSelection()) {
        // abort the rebase
        AbortRebaseCommand abortCommand = new AbortRebaseCommand();
        execute(abortCommand);
      } else if (doNothingButton.getSelection()) {
        // nothing
      }
    }
    super.buttonPressed(buttonId);
  }

  private void execute(AbstractRebaseCommandHandler command) {
    try {
      command.execute(repo);
    } catch (ExecutionException e) {
      Activator.showError(e.getMessage(), e);
    }
  }

  private void createToggleButton(Composite parent) {
    boolean toggleState = !Activator.getDefault().getPreferenceStore()
        .getBoolean(UIPreferences.SHOW_REBASE_CONFIRM);
    toggleButton = new Button(parent, SWT.CHECK | SWT.LEFT);
    toggleButton.setText(UIText.RebaseResultDialog_ToggleShowButton);
    toggleButton.setSelection(toggleState);
  }
}
TOP

Related Classes of org.eclipse.egit.ui.internal.rebase.RebaseResultDialog

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.