| /******************************************************************************* |
| * Copyright (c) 2013 Ericsson, 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 |
| * Sebastien Dubois (Ericsson) - Improvements for bug 400266 |
| *******************************************************************************/ |
| |
| package org.eclipse.mylyn.internal.gerrit.ui.factories; |
| |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Set; |
| |
| import org.eclipse.compare.CompareConfiguration; |
| import org.eclipse.compare.CompareUI; |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.core.runtime.Status; |
| import org.eclipse.jface.layout.GridDataFactory; |
| import org.eclipse.jface.layout.GridLayoutFactory; |
| import org.eclipse.mylyn.internal.gerrit.core.client.PatchSetContent; |
| import org.eclipse.mylyn.internal.gerrit.core.remote.PatchSetContentCompareRemoteFactory; |
| import org.eclipse.mylyn.internal.gerrit.ui.GerritReviewBehavior; |
| import org.eclipse.mylyn.internal.gerrit.ui.GerritUiPlugin; |
| import org.eclipse.mylyn.internal.reviews.ui.compare.ReviewItemSetCompareEditorInput; |
| import org.eclipse.mylyn.reviews.core.model.IFileItem; |
| import org.eclipse.mylyn.reviews.core.model.IReviewItemSet; |
| import org.eclipse.mylyn.reviews.core.model.IReviewsFactory; |
| import org.eclipse.mylyn.reviews.core.spi.remote.emf.RemoteEmfConsumer; |
| import org.eclipse.mylyn.reviews.core.spi.remote.emf.RemoteEmfObserver; |
| import org.eclipse.mylyn.reviews.ui.spi.factories.IUiContext; |
| import org.eclipse.osgi.util.NLS; |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.events.SelectionAdapter; |
| import org.eclipse.swt.events.SelectionEvent; |
| import org.eclipse.swt.graphics.Point; |
| import org.eclipse.swt.widgets.Button; |
| import org.eclipse.swt.widgets.Composite; |
| import org.eclipse.swt.widgets.Control; |
| import org.eclipse.swt.widgets.Menu; |
| import org.eclipse.swt.widgets.MenuItem; |
| import org.eclipse.ui.forms.widgets.FormToolkit; |
| import org.eclipse.ui.internal.IWorkbenchGraphicConstants; |
| import org.eclipse.ui.internal.WorkbenchImages; |
| import org.eclipse.ui.statushandlers.StatusManager; |
| |
| import com.google.common.base.Function; |
| import com.google.common.collect.Collections2; |
| import com.google.common.collect.Sets; |
| import com.google.gerrit.common.data.PatchSetDetail; |
| import com.google.gerrit.reviewdb.PatchSet; |
| |
| /** |
| * @author Steffen Pingel |
| * @author Miles Parker |
| * @author Sebastien Dubois |
| */ |
| public class CompareWithUiFactory extends AbstractPatchSetUiFactory { |
| |
| private final class ItemListClient extends RemoteEmfObserver<IReviewItemSet, List<IFileItem>, String, Long> { |
| private final IReviewItemSet baseSet; |
| |
| private final IReviewItemSet targetSet; |
| |
| private final IReviewItemSet compareSet; |
| |
| public ItemListClient(IReviewItemSet baseSet, IReviewItemSet targetSet, IReviewItemSet compareSet) { |
| this.baseSet = baseSet; |
| this.targetSet = targetSet; |
| this.compareSet = compareSet; |
| } |
| |
| @Override |
| public void updated(boolean modified) { |
| IStatus status = getConsumer().getStatus(); |
| if (status.isOK()) { |
| Set<String> fileNames = Sets.newHashSet(); |
| addItems(baseSet, fileNames); |
| addItems(targetSet, fileNames); |
| if (!fileNames.isEmpty()) { |
| for (Iterator<IFileItem> iter = compareSet.getItems().iterator(); iter.hasNext();) { |
| IFileItem file = iter.next(); |
| if (!fileNames.contains(file.getName())) { |
| iter.remove(); |
| } |
| } |
| } |
| CompareConfiguration configuration = new CompareConfiguration(); |
| CompareUI.openCompareEditor(new ReviewItemSetCompareEditorInput(configuration, compareSet, null, |
| new GerritReviewBehavior(getTask(), resolveGitRepository()))); |
| dispose(); |
| } else { |
| StatusManager.getManager().handle( |
| new Status(IStatus.ERROR, GerritUiPlugin.PLUGIN_ID, "Couldn't load content for compare editor", //$NON-NLS-1$ |
| status.getException()), StatusManager.SHOW | StatusManager.LOG); |
| } |
| } |
| |
| private void addItems(IReviewItemSet itemSet, Set<String> fileNames) { |
| if (itemSet != null) { |
| fileNames.addAll(Collections2.transform(itemSet.getItems(), new Function<IFileItem, String>() { |
| public String apply(IFileItem f) { |
| return f.getName(); |
| } |
| })); |
| } |
| } |
| } |
| |
| private IReviewItemSet baseSet; |
| |
| private IReviewItemSet targetSet; |
| |
| private IReviewItemSet compareSet; |
| |
| public CompareWithUiFactory(IUiContext context, IReviewItemSet set) { |
| super(Messages.CompareWithUiFactory_Compare_With, context, set); |
| } |
| |
| @Override |
| public Control createControl(IUiContext context, Composite parent, FormToolkit toolkit) { |
| if (isExecutable()) { |
| |
| final Composite compareComposite = toolkit.createComposite(parent); |
| GridLayoutFactory.fillDefaults().numColumns(2).spacing(0, 0).applyTo(compareComposite); |
| |
| Button compareButton = toolkit.createButton(compareComposite, |
| Messages.CompareWithUiFactory_Compare_With_Base, SWT.PUSH); |
| compareButton.addSelectionListener(new SelectionAdapter() { |
| @Override |
| public void widgetSelected(SelectionEvent e) { |
| baseSet = null; |
| targetSet = getModelObject(); |
| execute(); |
| } |
| }); |
| |
| if (getModelObject().getReview().getSets().size() > 1) { |
| Button compareWithButton = toolkit.createButton(compareComposite, "", SWT.PUSH); //$NON-NLS-1$ |
| GridDataFactory.fillDefaults().grab(false, true).applyTo(compareWithButton); |
| compareWithButton.setImage(WorkbenchImages.getImage(IWorkbenchGraphicConstants.IMG_LCL_BUTTON_MENU)); |
| compareWithButton.addSelectionListener(new SelectionAdapter() { |
| @Override |
| public void widgetSelected(SelectionEvent e) { |
| showCompareMenu(compareComposite); |
| } |
| |
| private void showCompareMenu(Composite compareComposite) { |
| Menu menu = new Menu(compareComposite); |
| Point p = compareComposite.getLocation(); |
| p.y = p.y + compareComposite.getSize().y; |
| p = compareComposite.getParent().toDisplay(p); |
| for (final IReviewItemSet otherSet : getModelObject().getReview().getSets()) { |
| if (otherSet != getModelObject()) { |
| MenuItem item = new MenuItem(menu, SWT.NONE); |
| item.setText(NLS.bind(Messages.CompareWithUiFactory_Compare_with_X, otherSet.getName())); |
| item.addSelectionListener(new SelectionAdapter() { |
| @Override |
| public void widgetSelected(SelectionEvent e) { |
| baseSet = otherSet; |
| targetSet = getModelObject(); |
| execute(); |
| } |
| }); |
| } |
| } |
| menu.setLocation(p); |
| menu.setVisible(true); |
| } |
| }); |
| } |
| return compareComposite; |
| } |
| return null; |
| } |
| |
| @Override |
| public void execute() { |
| PatchSet basePatch = null; |
| if (baseSet != null) { |
| PatchSetDetail baseSetDetail = getPatchSetDetail(baseSet); |
| if (baseSetDetail == null) { |
| handleExecutionStateError(); |
| return; |
| } |
| basePatch = baseSetDetail.getPatchSet(); |
| } |
| PatchSetDetail targetSetDetail = getPatchSetDetail(targetSet); |
| if (targetSetDetail == null) { |
| handleExecutionStateError(); |
| return; |
| } |
| final PatchSetContent content = new PatchSetContent(basePatch, targetSetDetail.getPatchSet()); |
| compareSet = IReviewsFactory.INSTANCE.createReviewItemSet(); |
| String basePatchSetLabel = content.getBase() != null |
| ? Integer.toString(content.getBase().getPatchSetId()) |
| : Messages.CompareWithUiFactory_Base; |
| compareSet.setName(NLS.bind(Messages.CompareWithUiFactory_Compare_Patch_Set_X_with_Y, content.getTarget() |
| .getPatchSetId(), basePatchSetLabel)); |
| PatchSetContentCompareRemoteFactory remoteFactory = new PatchSetContentCompareRemoteFactory( |
| getGerritFactoryProvider()); |
| final RemoteEmfConsumer<IReviewItemSet, List<IFileItem>, String, PatchSetContent, PatchSetContent, Long> consumer = remoteFactory.getConsumerForRemoteObject( |
| compareSet, content); |
| consumer.setUiJob(true); |
| consumer.addObserver(new ItemListClient(baseSet, targetSet, compareSet)); |
| consumer.retrieve(true); |
| } |
| |
| @Override |
| protected boolean isExecutableStateKnown() { |
| return true; |
| } |
| |
| @Override |
| public boolean isExecutable() { |
| return true; |
| } |
| } |