/*******************************************************************************
* Copyright (C) 2014, Andreas Hermann <a.v.hermann@gmail.com>
*
* 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.commit;
import static java.util.Arrays.asList;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.egit.ui.UIUtils;
import org.eclipse.egit.ui.internal.UIText;
import org.eclipse.egit.ui.internal.history.CommitFileDiffViewer;
import org.eclipse.egit.ui.internal.history.FileDiff;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.ui.forms.editor.FormEditor;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.ScrolledForm;
import org.eclipse.ui.forms.widgets.Section;
/**
* Stash viewer page class displaying author, committer, parent commits,
* message, and file information in form sections.
*/
public class StashEditorPage extends CommitEditorPage {
/**
* Index of the parent commit which contains staged changes.
*/
public static final int PARENT_COMMIT_STAGED = 1;
/**
* Index of the parent commit which contains untracked changes.
*/
public static final int PARENT_COMMIT_UNTRACKED = 2;
private Section stagedDiffSection;
private CommitFileDiffViewer stagedDiffViewer;
/**
* Create stash viewer page
*
* @param editor
*/
public StashEditorPage(FormEditor editor) {
super(editor, "stashPage", UIText.CommitEditorPage_Title); //$NON-NLS-1$
}
@Override
String getParentCommitLabel(int i) {
switch (i) {
case 0:
return UIText.StashEditorPage_LabelParent0;
case 1:
return UIText.StashEditorPage_LabelParent1;
case 2:
return UIText.StashEditorPage_LabelParent2;
default:
throw new IllegalStateException("Unexpected parent with index" + i); //$NON-NLS-1$
}
}
@Override
void createTagsArea(Composite parent, FormToolkit toolkit,
int span) {
// tags do not apply to stash commits
}
@Override
void createChangesArea(Composite displayArea, FormToolkit toolkit) {
createDiffArea(displayArea, toolkit, 2);
createIndexArea(displayArea, toolkit, 2);
}
private void createIndexArea(Composite parent,
FormToolkit toolkit, int span) {
String sectionTitle = MessageFormat.format(
UIText.StashEditorPage_StagedChanges, Integer.valueOf(0));
stagedDiffSection = createSection(parent, toolkit, sectionTitle, span);
Composite unstagedChangesArea = createSectionClient(
stagedDiffSection, toolkit);
stagedDiffViewer = new CommitFileDiffViewer(unstagedChangesArea,
getSite(), SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL
| SWT.FULL_SELECTION | toolkit.getBorderStyle());
Control control = stagedDiffViewer.getControl();
control.setData(FormToolkit.KEY_DRAW_BORDER, FormToolkit.TREE_BORDER);
GridDataFactory.fillDefaults().grab(true, true).applyTo(control);
addToFocusTracking(control);
stagedDiffViewer.setContentProvider(ArrayContentProvider
.getInstance());
stagedDiffViewer.setTreeWalk(getCommit().getRepository(), null);
updateSectionClient(stagedDiffSection, unstagedChangesArea, toolkit);
}
@Override
void loadSections() {
RepositoryCommit commit = getCommit();
Job refreshJob = new Job(MessageFormat.format(
UIText.CommitEditorPage_JobName, commit.getRevCommit().name())) {
@Override
protected IStatus run(IProgressMonitor monitor) {
final FileDiff[] unstagedDiffs = getUnstagedDiffs();
final FileDiff[] indexDiffs = getStagedDiffs();
final ScrolledForm form = getManagedForm().getForm();
if (UIUtils.isUsable(form))
form.getDisplay().syncExec(new Runnable() {
@Override
public void run() {
if (!UIUtils.isUsable(form))
return;
fillDiffs(unstagedDiffs);
fillStagedDiffs(indexDiffs);
form.reflow(true);
form.layout(true, true);
}
});
return Status.OK_STATUS;
}
};
refreshJob.setRule(this);
refreshJob.schedule();
}
/**
* @return diffs for staged changes
*/
protected FileDiff[] getStagedDiffs() {
List<FileDiff> stagedDiffsResult = new ArrayList<>();
if (getCommit().getRevCommit().getParentCount() > 1) {
RevCommit stagedCommit = getCommit().getRevCommit().getParent(
PARENT_COMMIT_STAGED);
FileDiff[] stagedDiffs = new RepositoryCommit(getCommit()
.getRepository(), stagedCommit).getDiffs();
stagedDiffsResult.addAll(asList(stagedDiffs));
}
return stagedDiffsResult
.toArray(new FileDiff[stagedDiffsResult.size()]);
}
/**
* @return diffs for unstaged and untracked changes
*/
protected FileDiff[] getUnstagedDiffs() {
List<FileDiff> unstagedDiffs = new ArrayList<>();
RevCommit stagedCommit = getCommit().getRevCommit().getParent(
PARENT_COMMIT_STAGED);
List<FileDiff> workingDirDiffs = asList(getCommit().getDiffs(
stagedCommit));
unstagedDiffs.addAll(workingDirDiffs);
if (getCommit().getRevCommit().getParentCount() > 2) {
RevCommit untrackedCommit = getCommit().getRevCommit().getParent(
PARENT_COMMIT_UNTRACKED);
FileDiff[] untrackedDiffs = new RepositoryCommit(getCommit()
.getRepository(), untrackedCommit).getDiffs();
unstagedDiffs.addAll(asList(untrackedDiffs));
}
return unstagedDiffs.toArray(new FileDiff[unstagedDiffs.size()]);
}
private void fillStagedDiffs(FileDiff[] diffs) {
if (diffs == null)
return;
stagedDiffViewer.setInput(diffs);
stagedDiffSection.setText(MessageFormat.format(
UIText.StashEditorPage_StagedChanges,
Integer.valueOf(diffs.length)));
setSectionExpanded(stagedDiffSection, diffs.length != 0);
}
@Override
String getDiffSectionTitle(Integer numChanges) {
return MessageFormat.format(UIText.StashEditorPage_UnstagedChanges,
numChanges);
}
}