blob: 414bcc577fda7b46bdd87552521b0a03a613338c [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2015 Ericsson AB.
* 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:
* Jacques Bouthillier - initial API and implementation
*******************************************************************************/
package org.eclipse.egerrit.ui.internal.tabs;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Observable;
import org.eclipse.core.databinding.observable.list.IObservableList;
import org.eclipse.core.databinding.observable.map.IObservableMap;
import org.eclipse.core.databinding.property.Properties;
import org.eclipse.core.databinding.property.value.IValueProperty;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.preferences.ConfigurationScope;
import org.eclipse.egerrit.core.EGerritCorePlugin;
import org.eclipse.egerrit.core.GerritClient;
import org.eclipse.egerrit.core.command.DeleteDraftRevisionCommand;
import org.eclipse.egerrit.core.command.DeleteReviewedCommand;
import org.eclipse.egerrit.core.command.GetReviewedFilesCommand;
import org.eclipse.egerrit.core.command.ListCommentsCommand;
import org.eclipse.egerrit.core.command.ListDraftsCommand;
import org.eclipse.egerrit.core.command.SetReviewedCommand;
import org.eclipse.egerrit.core.exception.EGerritException;
import org.eclipse.egerrit.internal.model.ChangeInfo;
import org.eclipse.egerrit.internal.model.CommentInfo;
import org.eclipse.egerrit.internal.model.FetchInfo;
import org.eclipse.egerrit.internal.model.FileInfo;
import org.eclipse.egerrit.internal.model.ModelPackage;
import org.eclipse.egerrit.internal.model.RevisionInfo;
import org.eclipse.egerrit.internal.model.impl.StringToFileInfoImpl;
import org.eclipse.egerrit.internal.model.impl.StringToRevisionInfoImpl;
import org.eclipse.egerrit.ui.EGerritUIPlugin;
import org.eclipse.egerrit.ui.editors.OpenCompareEditor;
import org.eclipse.egerrit.ui.internal.table.UIFilesTable;
import org.eclipse.egerrit.ui.internal.table.provider.ComboPatchSetLabelProvider;
import org.eclipse.egerrit.ui.internal.table.provider.FileTableLabelProvider;
import org.eclipse.egerrit.ui.internal.utils.LinkDashboard;
import org.eclipse.emf.common.util.EMap;
import org.eclipse.emf.databinding.EMFProperties;
import org.eclipse.emf.databinding.FeaturePath;
import org.eclipse.emf.databinding.IEMFListProperty;
import org.eclipse.jface.databinding.viewers.ObservableListContentProvider;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.dialogs.MessageDialogWithToggle;
import org.eclipse.jface.resource.ImageRegistry;
import org.eclipse.jface.viewers.ComboViewer;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerCell;
import org.eclipse.jface.viewers.ViewerComparator;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.FocusListener;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.TabFolder;
import org.eclipse.swt.widgets.TabItem;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.PlatformUI;
import org.osgi.service.prefs.BackingStoreException;
import org.osgi.service.prefs.Preferences;
/**
* This class is used in the editor to handle the Gerrit history view
*
* @since 1.0
*/
public class FilesTabView extends Observable implements PropertyChangeListener {
// used to fire events of registered properties
private transient PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(this);
private static final String BASE = "Base"; //$NON-NLS-1$
private static final String WORKSPACE = "Workspace"; //$NON-NLS-1$
private static final String PATCHSET = "Patch Sets ";
private static final String SEPARATOR = "/"; //$NON-NLS-1$
private final String TITLE = "Gerrit Server ";
private RevisionInfo fSelectedRevision = null;
private GerritClient gerritClient;
private ChangeInfo fChangeInfo;
private TableViewer tableFilesViewer;
private Label lblTotal;
private Combo comboDiffAgainst;
private Label lblPatchSet;
private ComboViewer comboPatchsetViewer;
private IDoubleClickListener fdoubleClickListener;
private Button fDeleteDraftRevisionButton;
// For the images
private static ImageRegistry fImageRegistry = new ImageRegistry();
private static final String ARROW_DOWN = "arrowDown.png"; //$NON-NLS-1$
/**
* Note: An image registry owns all of the image objects registered with it, and automatically disposes of them the
* SWT Display is disposed.
*/
static {
String iconPath = "icons/"; //$NON-NLS-1$
fImageRegistry.put(ARROW_DOWN, EGerritUIPlugin.getImageDescriptor(iconPath + ARROW_DOWN));
}
// ------------------------------------------------------------------------
// Constructor and life cycle
// ------------------------------------------------------------------------
/**
* @param tabFolder
* @param ChangeInfo
* changeInfo
*/
public void create(GerritClient gerritClient, TabFolder tabFolder, ChangeInfo changeInfo) {
this.gerritClient = gerritClient;
fChangeInfo = changeInfo;
createControls(tabFolder);
}
private void createControls(final TabFolder tabFolder) {
final TabItem tbtmFiles = new TabItem(tabFolder, SWT.NONE);
tbtmFiles.setText("Files");
Composite composite = new Composite(tabFolder, SWT.NONE);
tbtmFiles.setControl(composite);
composite.setLayout(new GridLayout(10, false));
lblPatchSet = new Label(composite, SWT.NONE);
GridData gd_lblPatchSet = new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1);
lblPatchSet.setLayoutData(gd_lblPatchSet);
lblPatchSet.setText("Patch Sets ( / )");
comboPatchsetViewer = new ComboViewer(composite, SWT.DROP_DOWN | SWT.READ_ONLY);
GridData gd_comboPatchSet = new GridData(SWT.FILL, SWT.CENTER, true, false, 4, 1);
comboPatchsetViewer.getCombo().setLayoutData(gd_comboPatchSet);
comboPatchsetViewer.addSelectionChangedListener(new ISelectionChangedListener() {
@Override
public void selectionChanged(SelectionChangedEvent event) {
ISelection selection = event.getSelection();
if (selection instanceof StructuredSelection) {
IStructuredSelection structSel = (IStructuredSelection) selection;
if (structSel.getFirstElement() instanceof StringToRevisionInfoImpl) {
setPatchSetLabelCombo();
setDiffAgainstCombo();
StringToRevisionInfoImpl revInfo = (StringToRevisionInfoImpl) structSel.getFirstElement();
setCurrentRevision(revInfo.getValue());
//Adjust the reviewed files and the comments associated to the current patchset
setFileTabFields();
setChanged();
notifyObservers();
}
}
}
});
comboPatchsetViewer.setComparator(new ViewerComparator() {
@Override
public int compare(Viewer viewer, Object e1, Object e2) {
StringToRevisionInfoImpl rev1 = (StringToRevisionInfoImpl) e1;
StringToRevisionInfoImpl rev2 = (StringToRevisionInfoImpl) e2;
return rev2.getValue().get_number() - rev1.getValue().get_number();
};
});
comboPatchsetViewer.getControl().addFocusListener(new FocusListener() {
@Override
public void focusLost(FocusEvent e) {
// ignore
}
@Override
public void focusGained(FocusEvent e) {
// To allow to display the whole list in the pull-down menu
comboPatchsetViewer.getCombo().setItems(comboPatchsetViewer.getCombo().getItems());
}
});
Label lblDiffAgainst = new Label(composite, SWT.NONE);
GridData gd_DiffAgainst = new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1);
lblDiffAgainst.setLayoutData(gd_DiffAgainst);
lblDiffAgainst.setText("Diff against:");
comboDiffAgainst = new Combo(composite, SWT.NONE);
GridData gd_combo = new GridData(SWT.FILL, SWT.CENTER, true, false, 4, 1);
comboDiffAgainst.setLayoutData(gd_combo);
lblTotal = new Label(composite, SWT.NONE);
GridData gd_lblTotal = new GridData(SWT.FILL, SWT.CENTER, true, false, 6, 1);
lblTotal.setLayoutData(gd_lblTotal);
lblTotal.setText("Total");
fDeleteDraftRevisionButton = new Button(composite, SWT.BORDER);
fDeleteDraftRevisionButton.setText("Delete Revision");
GridData gd_deleteDraft = new GridData(SWT.FILL, SWT.TOP, true, false, 3, 1);
fDeleteDraftRevisionButton.setLayoutData(gd_deleteDraft);
fDeleteDraftRevisionButton.setToolTipText("Delete Draft Revision");
fDeleteDraftRevisionButton.addSelectionListener(new SelectionListener() {
@Override
public void widgetSelected(SelectionEvent e) {
if (!MessageDialog.openConfirm(fDeleteDraftRevisionButton.getParent().getShell(),
"Delete draft revision", "Continue ?")) {
return;
}
DeleteDraftRevisionCommand deleteDraftChangeCmd = gerritClient.deleteDraftRevision(fChangeInfo.getId(),
fSelectedRevision.getId());
try {
deleteDraftChangeCmd.call();
if (fChangeInfo.getRevisions().size() == 1) {
IWorkbench workbench = PlatformUI.getWorkbench();
final IWorkbenchPage activePage = workbench.getActiveWorkbenchWindow().getActivePage();
IEditorPart editor = activePage.getActiveEditor();
activePage.closeEditor(editor, false);
}
LinkDashboard linkDash = new LinkDashboard(gerritClient);
linkDash.invokeRefreshDashboardCommand("", ""); //$NON-NLS-1$ //$NON-NLS-2$
} catch (EGerritException e1) {
EGerritCorePlugin.logError(gerritClient.getRepository().formatGerritVersion() + e1.getMessage());
}
}
@Override
public void widgetDefaultSelected(SelectionEvent e) {
// ignore
}
});
final Button fileViewPulldown = new Button(composite, SWT.BORDER);
fileViewPulldown.setImage(fImageRegistry.get(ARROW_DOWN));
GridData gd_FileView = new GridData(SWT.RIGHT, SWT.TOP, true, false, 1, 1);
fileViewPulldown.setLayoutData(gd_FileView);
fileViewPulldown.setToolTipText("File path layout");
fileViewPulldown.addSelectionListener(new SelectionListener() {
@Override
public void widgetSelected(SelectionEvent e) {
org.eclipse.swt.widgets.Menu menu = new org.eclipse.swt.widgets.Menu(fileViewPulldown.getShell(),
SWT.POP_UP);
final MenuItem nameFirst = new MenuItem(menu, SWT.CHECK);
nameFirst.setText("Show File Names first");
final FileTableLabelProvider labelProvider = (FileTableLabelProvider) tableFilesViewer
.getLabelProvider();
nameFirst.setSelection(labelProvider.getFileOrder());
nameFirst.addSelectionListener(new SelectionListener() {
@Override
public void widgetSelected(SelectionEvent e) {
MenuItem menuItem = (MenuItem) e.getSource();
labelProvider.setFileNameFirst(menuItem.getSelection());
tableFilesViewer.refresh();
}
@Override
public void widgetDefaultSelected(SelectionEvent e) {
// ignore
}
});
Point loc = fileViewPulldown.getLocation();
Rectangle rect = fileViewPulldown.getBounds();
Point mLoc = new Point(loc.x - 1, loc.y + rect.height);
menu.setLocation(fileViewPulldown.getDisplay().map(fileViewPulldown.getParent(), null, mLoc));
menu.setVisible(true);
};
@Override
public void widgetDefaultSelected(SelectionEvent e) {
// ignore
}
});
UIFilesTable tableUIFiles = new UIFilesTable();
tableUIFiles.createTableViewerSection(composite);
tableFilesViewer = tableUIFiles.getViewer();
tableFilesViewer.getTable().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 10, 1));
fdoubleClickListener = new IDoubleClickListener() {
public void doubleClick(DoubleClickEvent event) {
IStructuredSelection sel = (IStructuredSelection) event.getSelection();
Object element = sel.getFirstElement();
if (element instanceof StringToFileInfoImpl) {
FileInfo selectedFile = ((StringToFileInfoImpl) element).getValue();
OpenCompareEditor compareEditor;
if (!gerritClient.getRepository().getServerInfo().isAnonymous()) {
showEditorTip();
}
compareEditor = new OpenCompareEditor(gerritClient, fChangeInfo);
String diffSource = comboDiffAgainst.getText();
if (diffSource.equals(WORKSPACE)) {
compareEditor.compareAgainstWorkspace(selectedFile,
getParticipant(selectedFile.getContainedIn().getId()));
} else if (diffSource.equals(BASE)) {
compareEditor.compareAgainstBase(fChangeInfo.getProject(), selectedFile,
getParticipant(selectedFile.getContainedIn().getId()));
} else {
RevisionInfo rev = getRevisionInfoByNumber(diffSource);
if (rev != null) {
compareEditor.compareTwoRevisions(rev.getFiles().get(selectedFile.getOld_path()),
selectedFile, getParticipant(selectedFile.getContainedIn().getId()));
return;
}
MessageDialog.openError(null, "Can not open compare editor",
"The compare editor can not yet show difference with " + diffSource);
}
setReviewedFlag(element);
}
}
};
tableFilesViewer.addDoubleClickListener(fdoubleClickListener);
if (!gerritClient.getRepository().getServerInfo().isAnonymous()) {
tableFilesViewer.getTable().addMouseListener(toggleReviewedStateListener());
}
//Set the binding for this section
filesTabDataBindings(tableFilesViewer);
}
/**
* This method is for the command double click on a row
*
* @return none
*/
public void selectRow() {
if (tableFilesViewer.getElementAt(0) != null) {
tableFilesViewer.setSelection(new StructuredSelection(tableFilesViewer.getElementAt(0)), true);
IStructuredSelection selection = (IStructuredSelection) tableFilesViewer.getSelection();
final DoubleClickEvent event = new DoubleClickEvent(tableFilesViewer, selection);
fdoubleClickListener.doubleClick(event);
}
}
private void showEditorTip() {
Preferences prefs = ConfigurationScope.INSTANCE.getNode("org.eclipse.egerrit.prefs");
Preferences editorPrefs = prefs.node("editor");
boolean choice = editorPrefs.getBoolean("editortip", false);
if (choice) {
return;
}
MessageDialogWithToggle dialog = MessageDialogWithToggle.openInformation(
tableFilesViewer.getControl().getShell(), Messages.FileTabView_EGerriTip,
Messages.FileTabView_EGerriTipValue, Messages.FileTabView_EGerriTipShowAgain, false, null, null);
if (dialog.getToggleState()) {
editorPrefs.putBoolean("editortip", true);
try {
editorPrefs.flush();
} catch (BackingStoreException e) {
//There is not much we can do
}
}
return;
}
private Runnable getParticipant(final String revisionId) {
return new Runnable() {
@Override
public void run() {
update();
}
};
}
private void computeTotals() {
int lineInserted = 0;
int lineDeleted = 0;
int numDrafts = 0;
int numComment = 0;
RevisionInfo revInfo = fSelectedRevision;
EMap<String, FileInfo> mapFiles = revInfo.getFiles();
Collection<FileInfo> filesInfo = mapFiles.values();
if (!filesInfo.isEmpty()) {
Iterator<FileInfo> itr1 = filesInfo.iterator();
while (itr1.hasNext()) {
FileInfo fileInfo = itr1.next();
lineInserted += fileInfo.getLines_inserted();
lineDeleted += fileInfo.getLines_deleted();
if (fileInfo.getDraftComments() != null) {
numDrafts += fileInfo.getDraftComments().size();
}
if (fileInfo.getNewComments() != null) {
numComment += fileInfo.getNewComments().size();
}
}
StringBuilder sb = new StringBuilder();
sb.append("Summary:\tTotal changes: ");
sb.append("+"); //$NON-NLS-1$
sb.append(Integer.toString(lineInserted));
sb.append("/"); //$NON-NLS-1$
sb.append("-"); //$NON-NLS-1$
sb.append(Integer.toString(lineDeleted));
if (numDrafts != 0) {
sb.append("\t\t");
sb.append("Drafts: ");
sb.append(numDrafts);
}
if (numComment != 0) {
sb.append("\t\t");
sb.append("Comments: ");
sb.append(numComment);
}
lblTotal.setText(sb.toString());
}
}
private void setReviewedFlag(Object element) {
if (!gerritClient.getRepository().getServerInfo().isAnonymous()) {
FileInfo fileInfo = ((StringToFileInfoImpl) element).getValue();
if (!fileInfo.isReviewed()) {
SetReviewedCommand command = gerritClient.setReviewed(fChangeInfo.getId(),
fSelectedRevision.getCommit().getCommit(), fileInfo.getOld_path());
try {
command.call();
} catch (EGerritException ex) {
EGerritCorePlugin.logError(gerritClient.getRepository().formatGerritVersion() + ex.getMessage());
}
fileInfo.setReviewed(true);
tableFilesViewer.refresh();
}
}
}
/**
* This method is the listener to toggle a file's reviewed state
*
* @return MouseAdapter
*/
private MouseAdapter toggleReviewedStateListener() {
return new MouseAdapter() {
@Override
public void mouseDown(MouseEvent e) {
ViewerCell viewerCell = tableFilesViewer.getCell(new Point(e.x, e.y));
if (viewerCell != null && viewerCell.getColumnIndex() == 0) {
//Selected the first column, so we can send the delete option
//Otherwise, do not delete
ISelection selection = tableFilesViewer.getSelection();
if (selection instanceof IStructuredSelection) {
IStructuredSelection structuredSelection = (IStructuredSelection) selection;
Object element = structuredSelection.getFirstElement();
FileInfo fileInfo = ((StringToFileInfoImpl) element).getValue();
toggleReviewed(fileInfo);
}
}
}
};
}
private void toggleReviewed(FileInfo fileInfo) {
if (fileInfo.isReviewed()) {
DeleteReviewedCommand command = gerritClient.deleteReviewed(fChangeInfo.getId(),
fSelectedRevision.getCommit().getCommit(), fileInfo.getOld_path());
try {
command.call();
fileInfo.setReviewed(false);
} catch (EGerritException ex) {
EGerritCorePlugin.logError(gerritClient.getRepository().formatGerritVersion() + ex.getMessage());
}
} else {
SetReviewedCommand command = gerritClient.setReviewed(fChangeInfo.getId(),
fSelectedRevision.getCommit().getCommit(), fileInfo.getOld_path());
try {
command.call();
} catch (EGerritException ex) {
EGerritCorePlugin.logError(gerritClient.getRepository().formatGerritVersion() + ex.getMessage());
}
fileInfo.setReviewed(true);
}
tableFilesViewer.refresh();
}
protected void filesTabDataBindings(TableViewer tableFilesViewer) {
//Set the PatchSet Combo viewer
if (comboPatchsetViewer != null) {
ObservableListContentProvider contentPatchSetProvider = new ObservableListContentProvider();
comboPatchsetViewer.setContentProvider(contentPatchSetProvider);
IEMFListProperty revisionsProperty = EMFProperties.list(ModelPackage.Literals.CHANGE_INFO__REVISIONS);
IObservableMap[] observePatchSetMaps = Properties.observeEach(contentPatchSetProvider.getKnownElements(),
EMFProperties.value(ModelPackage.Literals.REVISION_INFO__NUMBER));
comboPatchsetViewer.setLabelProvider(new ComboPatchSetLabelProvider(observePatchSetMaps));
comboPatchsetViewer.setInput(revisionsProperty.observe(fChangeInfo));
}
//Set the FilesViewer
if (tableFilesViewer != null) {
FeaturePath changerev = FeaturePath.fromList(ModelPackage.Literals.CHANGE_INFO__REVISION,
ModelPackage.Literals.REVISION_INFO__FILES);
IObservableList revisionsChanges = EMFProperties.list(changerev).observe(fChangeInfo);
final FeaturePath reviewed = FeaturePath.fromList(ModelPackage.Literals.STRING_TO_FILE_INFO__VALUE,
ModelPackage.Literals.FILE_INFO__REVIEWED);
final FeaturePath status = FeaturePath.fromList(ModelPackage.Literals.STRING_TO_FILE_INFO__VALUE,
ModelPackage.Literals.FILE_INFO__STATUS);
final FeaturePath filePath = FeaturePath.fromList(ModelPackage.Literals.STRING_TO_FILE_INFO__VALUE,
ModelPackage.Literals.FILE_INFO__OLD_PATH);
final FeaturePath comment = FeaturePath.fromList(ModelPackage.Literals.STRING_TO_FILE_INFO__VALUE,
ModelPackage.Literals.FILE_INFO__NEW_COMMENTS);
final FeaturePath size = FeaturePath.fromList(ModelPackage.Literals.STRING_TO_FILE_INFO__VALUE,
ModelPackage.Literals.FILE_INFO__LINES_INSERTED);
ObservableListContentProvider contentProvider = new ObservableListContentProvider();
tableFilesViewer.setContentProvider(contentProvider);
final IObservableMap[] watchedProperties = Properties
.observeEach(contentProvider.getKnownElements(),
new IValueProperty[] { EMFProperties.value(reviewed), EMFProperties.value(status),
EMFProperties.value(filePath), EMFProperties.value(comment),
EMFProperties.value(size) });
tableFilesViewer.setLabelProvider(new FileTableLabelProvider(watchedProperties));
tableFilesViewer.setInput(revisionsChanges);
}
}
/**
* Fill the combo box with all patch set to compare with except the selected one. Also, add the Base and the
* Workspace which is the default one
*/
private void setDiffAgainstCombo() {
List<String> listPatch = new ArrayList<String>();
//Always start the list with the following items
listPatch.add(BASE);
listPatch.add(WORKSPACE);
//Find the current Patchset selection
ISelection selected = comboPatchsetViewer.getSelection();
if (!selected.isEmpty()) {
int psSelected = -1;
if (selected instanceof StructuredSelection) {
Object element = ((IStructuredSelection) selected).getFirstElement();
if (element instanceof StringToRevisionInfoImpl) {
RevisionInfo selectInfo = ((StringToRevisionInfoImpl) element).getValue();
psSelected = selectInfo.get_number();
}
}
//Display the list of patchset without the current one
List<RevisionInfo> listRevision = new ArrayList<RevisionInfo>(fChangeInfo.getRevisions().values());
Collections.sort(listRevision, new Comparator<RevisionInfo>() {
@Override
public int compare(RevisionInfo rev1, RevisionInfo rev2) {
return rev2.get_number() - rev1.get_number();
}
});
Iterator<RevisionInfo> it = listRevision.iterator();
while (it.hasNext()) {
RevisionInfo rev = it.next();
if (rev.get_number() != psSelected) {
listPatch.add(Integer.toString(rev.get_number()));
}
}
comboDiffAgainst.setItems(listPatch.toArray(new String[0]));
comboDiffAgainst.select(0);//Select the Base to compare with by default
}
}
/**
* - Fill the label showing which patch set is selected from the total list of patchset
*/
private void setPatchSetLabelCombo() {
//Find the current PatchSet selection
ISelection selected = comboPatchsetViewer.getSelection();
if (!selected.isEmpty()) {
int psSelected = -1;
if (selected instanceof StructuredSelection) {
Object element = ((IStructuredSelection) selected).getFirstElement();
if (element instanceof StringToRevisionInfoImpl) {
RevisionInfo selectInfo = ((StringToRevisionInfoImpl) element).getValue();
psSelected = selectInfo.get_number();
}
}
StringBuilder sb = new StringBuilder();
sb.append(PATCHSET);
sb.append(psSelected);
sb.append(SEPARATOR);
sb.append(fChangeInfo.getRevisions().size());
//Display the selected patchSet
lblPatchSet.setText(sb.toString());
}
}
private void fillReviewedRevisionFileInfo() {
RevisionInfo revInfo = fSelectedRevision;
// enable reviewed file status
if (!gerritClient.getRepository().getServerInfo().isAnonymous()) {
String[] reviewedFiles = queryVerified(gerritClient, fChangeInfo.getId(), revInfo.getId(),
new NullProgressMonitor());
if (reviewedFiles != null) {//List can be null if there was a conflict from the query
List<String> reviewedFilesList = Arrays.asList(reviewedFiles);
EMap<String, FileInfo> mapFiles = revInfo.getFiles();
Iterator<FileInfo> file = mapFiles.values().iterator();
while (file.hasNext()) {
FileInfo fi = file.next();
for (String e : reviewedFilesList) {
if (e.compareTo(fi.getOld_path()) == 0) {
fi.setReviewed(true);
}
}
}
}
}
}
private void fillCommentsRevisionFileInfo() {
RevisionInfo revInfo = fSelectedRevision;
Map<String, ArrayList<CommentInfo>> mapCommentInfo = queryComments(gerritClient, fChangeInfo.getId(),
revInfo.getId(), new NullProgressMonitor());
//Fill the Files table with comments
EMap<String, FileInfo> mapFiles = revInfo.getFiles();
Iterator<FileInfo> file = mapFiles.values().iterator();
while (file.hasNext()) {
FileInfo fi = file.next();
Iterator<Map.Entry<String, ArrayList<CommentInfo>>> commentIter = mapCommentInfo.entrySet().iterator();
while (commentIter.hasNext()) {
Entry<String, ArrayList<CommentInfo>> entryComment = commentIter.next();
//Add comments associated to the file
if (fi.getOld_path().equals(entryComment.getKey())) {
fi.getNewComments().clear();
fi.getNewComments().addAll(entryComment.getValue());
break;
}
}
}
//Query for the DRAFTS comments
Map<String, ArrayList<CommentInfo>> mapDraftCommentInfo = queryDraftComments(gerritClient, fChangeInfo.getId(),
revInfo.getId(), new NullProgressMonitor());
//Fill the Files table
Iterator<FileInfo> fileIt = mapFiles.values().iterator();
while (fileIt.hasNext() && mapDraftCommentInfo != null) {
FileInfo displayFileInfo = fileIt.next();
Iterator<Map.Entry<String, ArrayList<CommentInfo>>> commentIter = mapDraftCommentInfo.entrySet().iterator();
while (commentIter.hasNext()) {
Entry<String, ArrayList<CommentInfo>> entryComment = commentIter.next();
//Add comments associated to the file
if (displayFileInfo.getOld_path().equals(entryComment.getKey())) {
displayFileInfo.getDraftComments().clear();
displayFileInfo.getDraftComments().addAll(entryComment.getValue());
break;
}
}
}
}
/**
* Fill the data fields included in the Files Tab
*/
private void setFileTabFields() {
if (tableFilesViewer != null && !tableFilesViewer.getTable().isDisposed()) {
fillReviewedRevisionFileInfo();
fillCommentsRevisionFileInfo();
tableFilesViewer.refresh();
computeTotals();
}
}
/***************************************************************/
/* */
/* Section to QUERY the data structure */
/* */
/************************************************************* */
private Map<String, ArrayList<CommentInfo>> queryComments(GerritClient gerrit, String change_id, String revision_id,
IProgressMonitor monitor) {
try {
monitor.beginTask("Executing query", IProgressMonitor.UNKNOWN);
ListCommentsCommand command = gerrit.getListComments(change_id, revision_id);
Map<String, ArrayList<CommentInfo>> res = null;
try {
res = command.call();
return res;
} catch (EGerritException e) {
EGerritCorePlugin.logError(gerrit.getRepository().formatGerritVersion() + e.getMessage());
}
} finally {
monitor.done();
}
return null;
}
/***************************************************************/
/* */
/* Section to QUERY the files that were reviewed */
/* */
/************************************************************* */
private String[] queryVerified(GerritClient gerrit, String change_id, String revision_id,
IProgressMonitor monitor) {
try {
monitor.beginTask("Executing query", IProgressMonitor.UNKNOWN);
GetReviewedFilesCommand command = gerrit.getReviewed(change_id, revision_id);
String[] res = null;
try {
res = command.call();
return res;
} catch (EGerritException e) {
EGerritCorePlugin.logError(gerrit.getRepository().formatGerritVersion() + e.getMessage());
}
} finally {
monitor.done();
}
return null;
}
private Map<String, ArrayList<CommentInfo>> queryDraftComments(GerritClient gerrit, String change_id,
String revision_id, IProgressMonitor monitor) {
try {
if (gerrit.getRepository().getServerInfo().isAnonymous()) {
return null;
}
monitor.beginTask("Executing query", IProgressMonitor.UNKNOWN);
ListDraftsCommand command = gerrit.listDraftsComments(change_id, revision_id);
Map<String, ArrayList<CommentInfo>> res = null;
try {
res = command.call();
return res;
} catch (EGerritException e) {
EGerritCorePlugin.logError(gerrit.getRepository().formatGerritVersion() + e.getMessage());
}
} finally {
monitor.done();
}
return null;
}
/**
* @return the tableFilesViewer
*/
public TableViewer getTableFilesViewer() {
return tableFilesViewer;
}
private void setCurrentRevision(RevisionInfo revisionInfo) {
fChangeInfo.setCurrent_revision(revisionInfo.getId());
fSelectedRevision = revisionInfo;
fDeleteDraftRevisionButton.setEnabled(
fChangeInfo.getStatus().compareTo("DRAFT") == 0 && fSelectedRevision.isActionAllowed("publish")); //$NON-NLS-1$
}
/**
* Notify the registered observer
*/
@Override
public void notifyObservers() {
super.notifyObservers();
}
@Override
public void propertyChange(PropertyChangeEvent arg0) {
// ignore
}
public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) {
propertyChangeSupport.addPropertyChangeListener(propertyName, listener);
}
public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) {
propertyChangeSupport.removePropertyChangeListener(propertyName, listener);
}
protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) {
propertyChangeSupport.firePropertyChange(propertyName, oldValue, newValue);
}
/**
* @return the patchset selection as a string
*/
public String getSelectedPatchSet() {
String psSelected = null;
ISelection selected = comboPatchsetViewer.getSelection();
if (!selected.isEmpty()) {
psSelected = findSelectedPatchsetRef(selected, psSelected);
}
return psSelected;
}
/**
* @return the patchset selection ID as a string
*/
public String getSelectedPatchSetID() {
RevisionInfo psSelectedRev = null;
ISelection selected = comboPatchsetViewer.getSelection();
if (!selected.isEmpty()) {
psSelectedRev = findSelectedPatchsetRevision(selected);
return psSelectedRev.getId();
}
return null;
}
/**
* @return the patchset selection number as an int
*/
public int getSelectedPatchSetNumber() {
RevisionInfo psSelectedRev = null;
ISelection selected = comboPatchsetViewer.getSelection();
if (!selected.isEmpty()) {
psSelectedRev = findSelectedPatchsetRevision(selected);
return psSelectedRev.get_number();
}
return -1;
}
/**
* Initialize the combo patch set viewer with the latest patch set
*/
public void setInitPatchSet() {
ISelection selection = comboPatchsetViewer.getSelection();
if (selection.isEmpty()) {
//Select the latest patch-set and trigger the selection change
//The latest patch set is the first one in the list since we sort the data
//in this order
comboPatchsetViewer.getCombo().select(0);
comboPatchsetViewer.setSelection(comboPatchsetViewer.getSelection(), true);
}
}
/**
* @param selected
* @param psSelected
* @return String The patch set reference when a patch set is selected
*/
private String findSelectedPatchsetRef(ISelection selected, String psSelected) {
RevisionInfo selectInfo = findSelectedPatchsetRevision(selected);
EMap<String, FetchInfo> fetchInfoMap = selectInfo.getFetch();
FetchInfo fetchInfo = fetchInfoMap.get("git"); //$NON-NLS-1$
if (fetchInfo != null) {
psSelected = fetchInfo.getRef().toString();
} else {
fetchInfo = fetchInfoMap.get("ssh"); //$NON-NLS-1$
if (fetchInfo != null) {
psSelected = fetchInfo.getRef().toString();
} else {
fetchInfo = fetchInfoMap.get("http"); //$NON-NLS-1$
if (fetchInfo != null) {
psSelected = fetchInfo.getRef().toString();
}
}
}
return psSelected;
}
/**
* @param selected
* @return RevisionInfo The patch set reference when a patch set is selected
*/
private RevisionInfo findSelectedPatchsetRevision(ISelection selected) {
RevisionInfo selectInfo = null;
if (selected instanceof StructuredSelection) {
Object element = ((IStructuredSelection) selected).getFirstElement();
if (element instanceof StringToRevisionInfoImpl) {
selectInfo = ((StringToRevisionInfoImpl) element).getValue();
}
}
return selectInfo;
}
private RevisionInfo getRevisionInfoByNumber(String number) {
return fChangeInfo.getRevisionByNumber(Integer.valueOf(number));
}
public void update() {
RevisionInfo revInfo = fSelectedRevision;
setCurrentRevision(revInfo);
setFileTabFields();
setChanged();
notifyObservers();
}
/**
* allows to receive an updated version of changeinfo which in turn is used to determine enablement of buttons
*
* @param changeInfo
* @return none
*/
public void setChangeInfo(ChangeInfo changeInfo) {
fChangeInfo = changeInfo;
}
}