/*******************************************************************************
* Copyright (C) 2011, Stefan Lay <stefan.lay@sap.com>
* Copyright (C) 2011, 2013, Matthias Sohn <matthias.sohn@sap.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.gerrit;
import java.io.IOException;
import java.net.URISyntaxException;
import java.text.MessageFormat;
import java.util.Collections;
import java.util.Set;
import java.util.TreeSet;
import org.eclipse.egit.core.internal.gerrit.GerritUtil;
import org.eclipse.egit.ui.Activator;
import org.eclipse.egit.ui.UIUtils;
import org.eclipse.egit.ui.internal.SWTUtils;
import org.eclipse.egit.ui.internal.UIText;
import org.eclipse.egit.ui.internal.components.RepositorySelectionPage.Protocol;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.fieldassist.ContentProposal;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.transport.URIish;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.TraverseEvent;
import org.eclipse.swt.events.TraverseListener;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.PlatformUI;
/**
* Wizard page that offers simplified configuration if upstream repository
* is hosted by Gerrit.
*/
class GerritConfigurationPage extends WizardPage {
private final static int GERRIT_DEFAULT_SSH_PORT = 29418;
private String helpContext = null;
private Text branch;
private Group pushConfigurationGroup;
private Group fetchConfigurationGroup;
private Group uriGroup;
private Combo scheme;
private Text uriText;
private URIish pushURI;
private Text user;
private int eventDepth;
private final Repository repository;
private final String remoteName;
/**
* @param repository the respository
* @param remoteName the remote name
*
*/
public GerritConfigurationPage(Repository repository, String remoteName) {
super(GerritConfigurationPage.class.getName());
this.repository = repository;
this.remoteName = remoteName;
setTitle(UIText.GerritConfigurationPage_title);
String repositoryName = Activator.getDefault().getRepositoryUtil().getRepositoryName(repository);
setDescription(MessageFormat.format(
UIText.GerritConfigurationPage_PageDescription, remoteName,
repositoryName));
}
@Override
public void createControl(Composite parent) {
final Composite panel = new Composite(parent, SWT.NULL);
final GridLayout layout = new GridLayout();
layout.numColumns = 1;
panel.setLayout(layout);
createURIGroup(panel);
createPushConfigurationGroup(panel);
createFetchConfigurationGroup(panel);
Dialog.applyDialogFont(panel);
setControl(panel);
uriText.setFocus();
}
private void createURIGroup(Composite panel) {
uriGroup = SWTUtils.createHFillGroup(panel,
UIText.GerritConfigurationPage_pushUri,
SWTUtils.MARGINS_DEFAULT, 2);
scheme = new Combo(uriGroup, SWT.DROP_DOWN | SWT.READ_ONLY);
uriText = SWTUtils.createText(uriGroup);
new Label(uriGroup, SWT.NULL).setText(UIText.GerritConfigurationPage_UserLabel);
user = SWTUtils.createText(uriGroup);
user.addModifyListener(new ModifyListener() {
@Override
public void modifyText(final ModifyEvent e) {
eventDepth++;
try {
if (eventDepth == 1) {
if (pushURI != null) {
pushURI = pushURI.setUser(user.getText());
uriText.setText(pushURI.toString());
checkPage();
}
}
} finally {
eventDepth--;
}
}
});
uriText.addModifyListener(new ModifyListener() {
@Override
public void modifyText(final ModifyEvent e) {
eventDepth++;
try {
if (eventDepth == 1) {
URIish u = new URIish(uriText.getText());
String newUser = u.getUser();
user.setText(newUser != null ? newUser : ""); //$NON-NLS-1$
}
} catch (URISyntaxException e1) {
// empty
} finally {
eventDepth--;
}
checkPage();
}
});
for (Protocol p : Protocol.values()) {
scheme.add(p.getDefaultScheme());
}
scheme.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(final SelectionEvent e) {
final int idx = scheme.getSelectionIndex();
pushURI = pushURI.setScheme(scheme.getItem(idx));
if (Protocol.SSH.handles(pushURI))
pushURI = pushURI.setPort(GERRIT_DEFAULT_SSH_PORT);
else
pushURI = pushURI.setPort(-1);
uriText.setText(pushURI.toString());
scheme.setToolTipText(Protocol.values()[idx].getTooltip());
}
});
}
private void createPushConfigurationGroup(Composite panel) {
pushConfigurationGroup = SWTUtils.createHFillGroup(panel,
UIText.GerritConfigurationPage_groupPush,
SWTUtils.MARGINS_DEFAULT, 3);
Label branchLabel = new Label(pushConfigurationGroup, SWT.NULL);
branchLabel
.setText(UIText.GerritConfigurationPage_labelDestinationBranch);
// we visualize the prefix here
Text prefix = new Text(pushConfigurationGroup, SWT.READ_ONLY);
prefix.setText(GerritUtil.REFS_FOR);
prefix.setEnabled(false);
branch = SWTUtils.createText(pushConfigurationGroup);
branch.addModifyListener(new ModifyListener() {
@Override
public void modifyText(final ModifyEvent e) {
checkPage();
}
});
// give focus to the branch if label is activated using the mnemonic
branchLabel.addTraverseListener(new TraverseListener() {
@Override
public void keyTraversed(TraverseEvent e) {
branch.setFocus();
branch.selectAll();
}
});
addRefContentProposalToText(branch);
}
private void createFetchConfigurationGroup(Composite panel) {
fetchConfigurationGroup = SWTUtils.createHFillGroup(panel,
UIText.GerritConfigurationPage_groupFetch,
SWTUtils.MARGINS_DEFAULT, 2);
new Label(fetchConfigurationGroup, SWT.NULL)
.setText(UIText.GerritConfigurationPage_ConfigureFetchReviewNotes);
}
/**
* @return the push URI for Gerrit code review
*/
public URIish getURI() {
return pushURI;
}
/**
* @return the branch used in the gerrit push refspec: refs/for/branch
*/
public String getBranch() {
return branch.getText();
}
/**
* Set the ID for context sensitive help
*
* @param id
* help context
*/
public void setHelpContext(String id) {
helpContext = id;
}
@Override
public void performHelp() {
PlatformUI.getWorkbench().getHelpSystem().displayHelp(helpContext);
}
/**
* @param uri the URI of the source repository
*/
public void setSelection(URIish uri) {
setSelection(uri, null);
}
/**
* @param uri
* the URI of the source repository
* @param targetBranch
*/
public void setSelection(URIish uri, String targetBranch) {
setDefaults(uri, targetBranch);
checkPage();
}
private void setDefaults(URIish uri, String targetBranch) {
URIish newPushURI = uri;
if (Protocol.SSH.handles(uri) && uri.getPort() < 0) {
newPushURI = newPushURI.setPort(GERRIT_DEFAULT_SSH_PORT);
} else if (Protocol.GIT.handles(uri)) {
newPushURI = newPushURI.setScheme(Protocol.SSH.getDefaultScheme());
newPushURI = newPushURI.setPort(GERRIT_DEFAULT_SSH_PORT);
}
uriText.setText(newPushURI.toString());
final String uriScheme = newPushURI.getScheme();
if (uriScheme != null)
scheme.select(scheme.indexOf(uriScheme));
branch.setText(targetBranch != null ? targetBranch : Constants.MASTER);
}
private void checkPage() {
try {
pushURI = new URIish(uriText.getText());
String uriScheme = pushURI.getScheme();
if (uriScheme != null)
scheme.select(scheme.indexOf(uriScheme));
} catch (URISyntaxException e) {
setErrorMessage(e.getLocalizedMessage());
setPageComplete(false);
return;
}
String branchName = branch.getText();
if (branchName.length() == 0) {
setErrorMessage(UIText.GerritConfigurationPage_errorBranchName);
setPageComplete(false);
return;
}
setErrorMessage(null);
setPageComplete(true);
}
private void addRefContentProposalToText(final Text textField) {
UIUtils.<String> addContentProposalToText(textField,
() -> {
try {
Set<String> sortedSet = new TreeSet<>(
String.CASE_INSENSITIVE_ORDER);
sortedSet.addAll(repository.getRefDatabase()
.getRefs(Constants.R_REMOTES + remoteName + '/')
.keySet());
return sortedSet;
} catch (IOException e) {
return Collections.emptyList();
}
}, (pattern, refName) -> {
if (pattern != null
&& !pattern.matcher(refName).matches()) {
return null;
}
return new ContentProposal(refName);
}, UIText.GerritConfigurationPage_BranchTooltipStartTyping,
UIText.GerritConfigurationPage_BranchTooltipHover);
}
}