blob: ab632e896744def1fcf7f8169a4c3459f1f60d98 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2010, 2014 Tasktop Technologies 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:
* Tasktop Technologies - initial API and implementation
* Jan Lohre (SAP) - improvements
* Sascha Scholz (SAP) - improvements
*******************************************************************************/
package org.eclipse.mylyn.reviews.ui.spi.editor;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap;
import org.apache.commons.lang.StringUtils;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.layout.GridLayoutFactory;
import org.eclipse.mylyn.commons.ui.CommonImages;
import org.eclipse.mylyn.internal.reviews.ui.ReviewsImages;
import org.eclipse.mylyn.reviews.core.model.IApprovalType;
import org.eclipse.mylyn.reviews.core.model.IChange;
import org.eclipse.mylyn.reviews.core.model.IRequirementEntry;
import org.eclipse.mylyn.reviews.core.model.IReview;
import org.eclipse.mylyn.reviews.core.model.IReviewerEntry;
import org.eclipse.mylyn.reviews.core.model.IUser;
import org.eclipse.mylyn.reviews.core.model.RequirementStatus;
import org.eclipse.mylyn.reviews.ui.spi.factories.AbstractUiFactoryProvider;
import org.eclipse.mylyn.tasks.ui.TasksUiUtil;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CLabel;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Link;
import org.eclipse.ui.forms.IFormColors;
import org.eclipse.ui.forms.widgets.ExpandableComposite;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.Section;
/**
* Displays basic information about a given review corresponding to top sections of Gerrit web interface.
*
* @author Steffen Pingel
* @author Miles Parker
*/
public abstract class ReviewDetailSection extends AbstractReviewSection {
public ReviewDetailSection() {
setPartName(Messages.ReviewDetailSection_Review);
}
@Override
protected Control createContent(FormToolkit toolkit, Composite parent) {
Control content = super.createContent(toolkit, parent);
createReviewersSubSection(composite);
createDependenciesSubSection(toolkit, composite, Messages.ReviewDetailSection_Depends_On,
getReview().getParents());
createDependenciesSubSection(toolkit, composite, Messages.ReviewDetailSection_Needed_By,
getReview().getChildren());
return content;
}
protected void createReviewersSubSection(Composite parent) {
if (getReview().getReviewerApprovals().isEmpty() && !canAddReviewers()) {
return;
}
int style = ExpandableComposite.TWISTIE | ExpandableComposite.CLIENT_INDENT
| ExpandableComposite.LEFT_TEXT_CLIENT_ALIGNMENT | ExpandableComposite.EXPANDED;
final Section subSection = toolkit.createSection(parent, style);
GridDataFactory.fillDefaults().grab(true, false).applyTo(subSection);
subSection.setTitleBarForeground(toolkit.getColors().getColor(IFormColors.TITLE));
subSection.setText(Messages.ReviewDetailSection_Reviewers);
Composite composite = toolkit.createComposite(subSection);
List<IApprovalType> approvalTypes = getModelRepository().getApprovalTypes();
List<IApprovalType> approvalTypesWithLabel = new ArrayList<IApprovalType>(approvalTypes.size());
for (IApprovalType approvalType : approvalTypes) {
if (!approvalType.getName().equals(approvalType.getKey())) {
approvalTypesWithLabel.add(approvalType);
}
}
int numColumns = approvalTypesWithLabel.size() + 1;
GridLayoutFactory.fillDefaults()
.numColumns(numColumns)
.extendedMargins(0, 0, 0, 5)
.equalWidth(true)
.spacing(4, 5)
.applyTo(composite);
subSection.setClient(composite);
if (!approvalTypesWithLabel.isEmpty()) {
StringBuilder names = new StringBuilder();
Label headerLabel = new Label(composite, SWT.NONE);
headerLabel.setText(" "); //$NON-NLS-1$
StringBuilder needs = new StringBuilder();
for (IApprovalType approvalType : approvalTypesWithLabel) {
IRequirementEntry requirementEntry = getReview().getRequirements().get(approvalType);
Composite headerContainer = new Composite(composite, SWT.NONE);
headerContainer.setForeground(toolkit.getColors().getColor(IFormColors.TB_BG));
GridLayoutFactory.fillDefaults().numColumns(2).applyTo(headerContainer);
GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.FILL).applyTo(headerContainer);
CLabel approvalHeaderLabel = new CLabel(headerContainer, SWT.NONE);
approvalHeaderLabel.setForeground(toolkit.getColors().getColor(IFormColors.TITLE));
approvalHeaderLabel.setText(approvalType.getName());
GridDataFactory.fillDefaults().align(SWT.RIGHT, SWT.CENTER).applyTo(approvalHeaderLabel);
RequirementStatus status = null;
if (requirementEntry != null) {
status = requirementEntry.getStatus();
switch (status) {
case SATISFIED:
approvalHeaderLabel.setImage(CommonImages.getImage(ReviewsImages.APPROVED));
break;
case NOT_SATISFIED:
approvalHeaderLabel.setImage(CommonImages.getImage(ReviewsImages.UNKNOWN));
break;
case REJECTED:
approvalHeaderLabel.setImage(CommonImages.getImage(ReviewsImages.REJECTED));
break;
default:
//To ensure that label is aligned properly
approvalHeaderLabel.setImage(CommonImages.getImage(ReviewsImages.BLANK));
break;
}
}
if (status != null && (status == RequirementStatus.UNKNOWN || status == RequirementStatus.REJECTED)) {
if (needs.length() > 0) {
needs.append(", "); //$NON-NLS-1$
}
needs.append(approvalType.getName());
}
}
AbstractUiFactoryProvider<IUser> reviewerUiFactoryProvider = getReviewerUiFactoryProvider();
Map<IUser, IReviewerEntry> sortedReviewerApprovals = new TreeMap<>(
(u1, u2) -> u1.getDisplayName().compareTo(u2.getDisplayName()));
sortedReviewerApprovals.putAll(getReview().getReviewerApprovals());
for (Entry<IUser, IReviewerEntry> approval : sortedReviewerApprovals.entrySet()) {
IUser currentUser = approval.getKey();
createReviewerLabelAndControls(composite, reviewerUiFactoryProvider, currentUser);
for (IApprovalType approvalType : approvalTypesWithLabel) {
Integer value = approval.getValue().getApprovals().get(approvalType);
Label approvalValueLabel = new Label(composite, SWT.NONE);
GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.FILL).applyTo(approvalValueLabel);
String rankingText = " "; //$NON-NLS-1$
if (value != null && value != 0) {
if (value > 0) {
rankingText += "+"; //$NON-NLS-1$
approvalValueLabel.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_DARK_GREEN));
} else if (value < 0) {
approvalValueLabel.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_RED));
}
rankingText += value;
approvalValueLabel.setToolTipText(value + " " + approvalType.getName()); //$NON-NLS-1$
}
approvalValueLabel.setText(rankingText);
}
if (names.length() > 0) {
names.append(", "); //$NON-NLS-1$
}
names.append(currentUser.getDisplayName());
}
String headerText = names.toString();
if (needs.length() > 0) {
headerText += NLS.bind(Messages.ReviewDetailSection_Needs_X, needs);
}
if (headerText.length() > 0) {
addTextClient(toolkit, subSection, headerText);
}
}
if (getUiFactoryProvider() != null) {
Composite actionComposite = getUiFactoryProvider().createControls(this, composite, getToolkit(),
getReview());
GridDataFactory.fillDefaults().span(2, 1).applyTo(actionComposite);
}
}
private void createReviewerLabelAndControls(Composite parent,
AbstractUiFactoryProvider<IUser> reviewerUiFactoryProvider, IUser user) {
Composite reviewerComp = toolkit.createComposite(parent, SWT.NONE);
GridLayoutFactory.fillDefaults().numColumns(2).equalWidth(false).applyTo(reviewerComp);
if (reviewerUiFactoryProvider != null) {
createReviewerControls(reviewerComp, user, reviewerUiFactoryProvider);
}
createReviewerLabel(reviewerComp, user);
}
private void createReviewerLabel(Composite reviewerComposite, IUser user) {
Label reviewerRowLabel = new Label(reviewerComposite, SWT.NONE);
reviewerRowLabel.setForeground(toolkit.getColors().getColor(IFormColors.TITLE));
reviewerRowLabel.setText(user.getDisplayName());
}
private void createReviewerControls(Composite reviewerComposite, IUser user,
AbstractUiFactoryProvider<IUser> reviewerUiFactoryProvider) {
Composite controlComposite = reviewerUiFactoryProvider.createControls(this, reviewerComposite, getToolkit(),
user);
GridDataFactory.fillDefaults().applyTo(controlComposite);
}
protected boolean canAddReviewers() {
return true;
}
protected void createDependenciesSubSection(final FormToolkit toolkit, final Composite parent, String title,
List<IChange> changes) {
if (changes.isEmpty()) {
return;
}
int style = ExpandableComposite.TWISTIE | ExpandableComposite.CLIENT_INDENT;
final Section subSection = toolkit.createSection(parent, style);
GridDataFactory.fillDefaults().grab(true, false).applyTo(subSection);
subSection.setTitleBarForeground(toolkit.getColors().getColor(IFormColors.TITLE));
subSection.setText(title);
Composite composite = toolkit.createComposite(subSection);
GridLayoutFactory.fillDefaults().extendedMargins(0, 0, 0, 5).applyTo(composite);
subSection.setClient(composite);
for (final IChange change : changes) {
Link link = new Link(composite, SWT.NONE);
String changeStatus = change.getState() != null
? NLS.bind(Messages.ReviewDetailSection_Bracket_X_bracket,
String.valueOf(change.getState().getName()))
: " "; //$NON-NLS-1$
String ownerName = change.getOwner().getDisplayName();
link.setText(NLS.bind(Messages.ReviewDetailSection_Link_W_X_Y_by_Z, new String[] {
StringUtils.left(change.getKey(), 9), change.getSubject(), ownerName, changeStatus }));
link.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
TasksUiUtil.openTask(getTaskEditorPage().getTaskRepository(), change.getId());
}
});
}
}
protected abstract AbstractUiFactoryProvider<IReview> getUiFactoryProvider();
protected AbstractUiFactoryProvider<IUser> getReviewerUiFactoryProvider() {
return null;
};
@Override
protected boolean shouldExpandOnCreate() {
return true;
}
}