28126: Patch: Standard public cvs repositories
diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/messages.properties b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/messages.properties
index cde9e01..a19e5a5 100644
--- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/messages.properties
+++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/messages.properties
@@ -303,6 +303,8 @@
 RepositorySelectionPage.useExisting=&Use existing repository location:
 RepositorySelectionPage.useNew=&Create a new repository location
 
+ConfigurationWizardMainPage.anonymous=&Anonymous
+ConfigurationWizardMainPage.user=U&ser
 ConfigurationWizardMainPage.connection=&Connection type:
 ConfigurationWizardMainPage.userName=&User:
 ConfigurationWizardMainPage.password=&Password:
@@ -310,6 +312,9 @@
 ConfigurationWizardMainPage.useDefaultPort=Use &Default Port
 ConfigurationWizardMainPage.usePort=Use Por&t:
 ConfigurationWizardMainPage.repositoryPath=&Repository path:
+ConfigurationWizardMainPage.repositorySpec=Resulting Repository Location
+ConfigurationWizardMainPage.project=&Project:
+ConfigurationWizardMainPage.invalidProjectName=Invalid Project Name
 ConfigurationWizardMainPage.invalidUserName=Invalid User Name
 ConfigurationWizardMainPage.invalidHostName=Invalid Host Name
 ConfigurationWizardMainPage.invalidPort=Invalid Port
@@ -481,7 +486,7 @@
 RepositoriesView.refreshTooltip=Refresh View
 RepositoriesView.new=&Repository Location...
 RepositoriesView.newSubmenu=&New
-RepositoriesView.newAnonCVS=&Anonymous Repository Location to dev.eclipse.org...
+RepositoriesView.newStd=&Standard Public Repository Location...
 RepositoriesView.newWorkingSet=Select Working Set...
 RepositoriesView.deselectWorkingSet=Deselect Working Set
 RepositoriesView.editWorkingSet=Edit Active Working Set...
diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/repo/RepositoriesView.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/repo/RepositoriesView.java
index 6ab0637..d1ab536 100644
--- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/repo/RepositoriesView.java
+++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/repo/RepositoriesView.java
@@ -11,8 +11,6 @@
 package org.eclipse.team.internal.ccvs.ui.repo;
 
 
-import java.util.Properties;
-
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.jface.action.Action;
 import org.eclipse.jface.action.IMenuManager;
@@ -67,7 +65,7 @@
 	
 	// Actions
 	private Action newAction;
-	private Action newAnonAction;
+	private Action newStdAction;
 	private PropertyDialogAction propertiesAction;
 	private RemoveRootAction removeRootAction;
 	
@@ -95,7 +93,7 @@
 			});
 		}
 	};
-	
+
 	/**
 	 * Constructor for RepositoriesView.
 	 * @param partName
@@ -123,22 +121,16 @@
 		};
 		WorkbenchHelp.setHelp(newAction, IHelpContextIds.NEW_REPOSITORY_LOCATION_ACTION);
 		
-		if (includeAnonConnection()) {
-			newAnonAction = new Action(Policy.bind("RepositoriesView.newAnonCVS"), CVSUIPlugin.getPlugin().getImageDescriptor(ICVSUIConstants.IMG_NEWLOCATION)) { //$NON-NLS-1$
-				public void run() {
-					Properties p = new Properties();
-					p.setProperty("connection", "pserver"); //$NON-NLS-1$ //$NON-NLS-2$
-					p.setProperty("user", "anonymous"); //$NON-NLS-1$ //$NON-NLS-2$
-					p.setProperty("host", "dev.eclipse.org"); //$NON-NLS-1$ //$NON-NLS-2$
-					p.setProperty("root", "/home/eclipse"); //$NON-NLS-1$ //$NON-NLS-2$
-					NewLocationWizard wizard = new NewLocationWizard(p);
-					WizardDialog dialog = new WizardDialog(shell, wizard);
-					dialog.open();
-				}
-			};
-			WorkbenchHelp.setHelp(newAnonAction, IHelpContextIds.NEW_DEV_ECLIPSE_REPOSITORY_LOCATION_ACTION);
-		}
-		
+		// New Standard Repository (popup)
+		newStdAction = new Action(Policy.bind("RepositoriesView.newStd"), CVSUIPlugin.getPlugin().getImageDescriptor(ICVSUIConstants.IMG_NEWLOCATION)) { //$NON-NLS-1$
+			public void run() {
+				NewLocationWizard wizard = new NewLocationWizard(NewLocationWizard.STANDARD);
+				WizardDialog dialog = new WizardDialog(shell, wizard);
+				dialog.open();
+			}
+		};
+		WorkbenchHelp.setHelp(newStdAction, IHelpContextIds.NEW_REPOSITORY_LOCATION_ACTION);
+
 		// Properties
 		propertiesAction = new PropertyDialogAction(shell, getViewer());
 		getViewSite().getActionBars().setGlobalActionHandler(IWorkbenchActionConstants.PROPERTIES, propertiesAction);		
@@ -164,14 +156,6 @@
 	}
 	
 	/**
-	 * Method includeEclipseConnection.
-	 * @return boolean
-	 */
-	private boolean includeAnonConnection() {
-		return System.getProperty("eclipse.cvs.anon") != null; //$NON-NLS-1$
-	}
-
-	/**
 	 * @see org.eclipse.team.internal.ccvs.ui.repo.RemoteViewPart#addWorkbenchActions(org.eclipse.jface.action.IMenuManager)
 	 */
 	protected void addWorkbenchActions(IMenuManager manager) {
@@ -192,8 +176,7 @@
 			manager.add(propertiesAction);
 		}
 		sub.add(newAction);
-		if (newAnonAction != null)
-			sub.add(newAnonAction);		
+		sub.add(newStdAction);
 	}
 	
 	/*
diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/wizards/ConfigurationWizardMainPage.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/wizards/ConfigurationWizardMainPage.java
index e2ddae1..d15bc72 100644
--- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/wizards/ConfigurationWizardMainPage.java
+++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/wizards/ConfigurationWizardMainPage.java
@@ -44,44 +44,46 @@
  * Wizard page for entering information about a CVS repository location.
  */
 public class ConfigurationWizardMainPage extends CVSWizardPage {
-	private boolean showValidate;
-	private boolean validate;
+	protected boolean showValidate;
+	protected boolean validate;
 	
 	// Widgets
 	
 	// Connection Method
-	private Combo connectionMethodCombo;
+	protected Combo connectionMethodCombo;
 	// User
-	private Combo userCombo;
+	protected Combo userCombo;
 	// Password
-	private Text passwordText;
+	protected Text passwordText;
 	// Port
-	private Text portText;
-	private Button useDefaultPort;
-	private Button useCustomPort;
+	protected Text portText;
+	protected Button useDefaultPort;
+	protected Button useCustomPort;
 	// Host
-	private Combo hostCombo;
+	protected Combo hostCombo;
 	// Repository Path
-	private Combo repositoryPathCombo;
+	protected Combo repositoryPathCombo;
 	// Validation
-	private Button validateButton;
+	protected Button validateButton;
 	
-	private static final int COMBO_HISTORY_LENGTH = 5;
+	protected static final int COMBO_HISTORY_LENGTH = 5;
 	
-	private Properties properties = null;
+	protected Properties properties = null;
 	
 	// Dialog store id constants
-	private static final String STORE_USERNAME_ID =
+	protected static final String STORE_USERNAME_ID =
 		"ConfigurationWizardMainPage.STORE_USERNAME_ID";//$NON-NLS-1$
-	private static final String STORE_HOSTNAME_ID =
+	protected static final String STORE_HOSTNAME_ID =
 		"ConfigurationWizardMainPage.STORE_HOSTNAME_ID";//$NON-NLS-1$
-	private static final String STORE_PATH_ID =
+	protected static final String STORE_PATH_ID =
 		"ConfigurationWizardMainPage.STORE_PATH_ID";//$NON-NLS-1$
-	private static final String STORE_DONT_VALIDATE_ID =
+	protected static final String STORE_PROJECT_ID =
+		"ConfigurationWizardMainPage.STORE_PROJECT_ID";//$NON-NLS-1$
+	protected static final String STORE_DONT_VALIDATE_ID =
 		"ConfigurationWizardMainPage.STORE_DONT_VALIDATE_ID";//$NON-NLS-1$
 	
 	// In case the page was launched from a different wizard	
-	private IDialogSettings settings;
+	protected IDialogSettings settings;
 	
 	/**
 	 * ConfigurationWizardMainPage constructor.
@@ -102,7 +104,7 @@
 	 * @param newEntry the entry to add to the history
 	 * @return the history with the new entry appended
 	 */
-	private String[] addToHistory(String[] history, String newEntry) {
+	protected String[] addToHistory(String[] history, String newEntry) {
 		ArrayList l = new ArrayList(Arrays.asList(history));
 		addToHistory(l, newEntry);
 		String[] r = new String[l.size()];
@@ -123,7 +125,7 @@
 	 * @param history the current history
 	 * @param newEntry the entry to add to the history
 	 */
-	private void addToHistory(List history, String newEntry) {
+	protected void addToHistory(List history, String newEntry) {
 		history.remove(newEntry);
 		history.add(0,newEntry);
 	
@@ -280,7 +282,7 @@
 	/**
 	 * Initializes states of the controls.
 	 */
-	private void initializeValues() {
+	protected void initializeValues() {
 		// Set remembered values
 		IDialogSettings settings = getDialogSettings();
 		if (settings != null) {
@@ -297,6 +299,12 @@
 				}
 			}
 			String[] userNames = settings.getArray(STORE_USERNAME_ID);
+			if (userNames == null) {
+				userNames = new String[] {
+					System.getProperty("user.name"),
+				};
+				settings.put(STORE_USERNAME_ID, userNames);
+			}
 			if (userNames != null) {
 				for (int i = 0; i < userNames.length; i++) {
 					userCombo.add(userNames[i]);
@@ -355,7 +363,7 @@
 	/**
 	 * Saves the widget values
 	 */
-	private void saveWidgetValues() {
+	protected void saveWidgetValues() {
 		// Update history
 		IDialogSettings settings = getDialogSettings();
 		if (settings != null) {
@@ -409,7 +417,7 @@
 	 * Validates the contents of the editable fields and set page completion 
 	 * and error messages appropriately.
 	 */
-	private void validateFields() {
+	protected void validateFields() {
 		String user = userCombo.getText();
 		if (user.length() == 0) {
 			setErrorMessage(null);
diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/wizards/NewLocationWizard.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/wizards/NewLocationWizard.java
index 325d3b6..1b32e14 100644
--- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/wizards/NewLocationWizard.java
+++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/wizards/NewLocationWizard.java
@@ -34,7 +34,22 @@
 
 	private Properties properties = null;
 	
+	// Type of wizard, whether GENERIC or STANDARD.
+	private int type;
+
+	/** Type used when creating a dialog that can find an arbitrary
+		cvs repository.  */
+	public static final int GENERIC = 0;
+	/** Type used when creating a dialog that knows about the standard
+		public repositories.  */
+	public static final int STANDARD = 1;
+
 	public NewLocationWizard() {
+		this(GENERIC);
+	}
+
+	public NewLocationWizard(int type) {
+		this.type = type;
 		IDialogSettings workbenchSettings = CVSUIPlugin.getPlugin().getDialogSettings();
 		IDialogSettings section = workbenchSettings.getSection("NewLocationWizard");//$NON-NLS-1$
 		if (section == null) {
@@ -53,7 +68,11 @@
 	 * Creates the wizard pages
 	 */
 	public void addPages() {
-		mainPage = new ConfigurationWizardMainPage("repositoryPage1", Policy.bind("NewLocationWizard.heading"), CVSUIPlugin.getPlugin().getImageDescriptor(ICVSUIConstants.IMG_WIZBAN_NEW_LOCATION)); //$NON-NLS-1$ //$NON-NLS-2$
+		if (type == GENERIC) {
+			mainPage = new ConfigurationWizardMainPage("repositoryPage1", Policy.bind("NewLocationWizard.heading"), CVSUIPlugin.getPlugin().getImageDescriptor(ICVSUIConstants.IMG_WIZBAN_NEW_LOCATION)); //$NON-NLS-1$ //$NON-NLS-2$
+		} else {
+			mainPage = new StandardWizardMainPage("repositoryPage1", Policy.bind("NewLocationWizard.heading"), CVSUIPlugin.getPlugin().getImageDescriptor(ICVSUIConstants.IMG_WIZBAN_NEW_LOCATION)); //$NON-NLS-1$ //$NON-NLS-2$
+		}
 		if (properties != null) {
 			mainPage.setProperties(properties);
 		}
diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/wizards/StandardWizardMainPage.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/wizards/StandardWizardMainPage.java
new file mode 100644
index 0000000..c539036
--- /dev/null
+++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/wizards/StandardWizardMainPage.java
@@ -0,0 +1,442 @@
+/*******************************************************************************
+ * Copyright (c) 2003 Red Hat, Inc.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     Red Hat, Inc.   - initial implementation
+ *******************************************************************************/
+package org.eclipse.team.internal.ccvs.ui.wizards;
+
+import java.text.MessageFormat;
+import java.util.Properties;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jface.dialogs.IDialogSettings;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.team.internal.ccvs.core.IConnectionMethod;
+import org.eclipse.team.internal.ccvs.core.connection.CVSRepositoryLocation;
+import org.eclipse.team.internal.ccvs.ui.IHelpContextIds;
+import org.eclipse.team.internal.ccvs.ui.Policy;
+import org.eclipse.ui.help.WorkbenchHelp;
+
+/**
+ * Wizard page for entering information about a standard CVS
+ * repository location.
+ */
+public class StandardWizardMainPage extends ConfigurationWizardMainPage {
+	// The standard repositories we know about.
+	protected StandardRepository[] standardRepositories;
+
+	private Button anonButton;
+	private Button userButton;
+	private Label repoLabel;
+
+	/**
+	 * ConfigurationWizardMainPage constructor.
+	 * 
+	 * @param pageName  the name of the page
+	 * @param title  the title of the page
+	 * @param titleImage  the image for the page
+	 */
+	public StandardWizardMainPage(String pageName, String title, ImageDescriptor titleImage) {
+		super(pageName, title, titleImage);
+	}
+
+	/**
+	 * Creates the UI part of the page.
+	 * 
+	 * @param parent  the parent of the created widgets
+	 */
+	public void createControl(Composite parent) {
+		Composite composite = createComposite(parent, 2);
+		// set F1 help
+		WorkbenchHelp.setHelp(composite, IHelpContextIds.SHARING_NEW_REPOSITORY_PAGE);
+
+		Listener listener = new Listener() {
+			public void handleEvent(Event event) {
+				updateWidgetEnablements();
+			}
+		};
+		
+		Group g = createGroup(composite, Policy.bind("ConfigurationWizardMainPage.Location_1")); //$NON-NLS-1$
+		
+		// Standard cvs repository.
+		createLabel(g, Policy.bind("ConfigurationWizardMainPage.host")); //$NON-NLS-1$
+		hostCombo = createCombo(g);
+		hostCombo.addListener(SWT.Selection, listener);
+		// FIXME
+		// hostCombo.setEditable(false);
+
+		createLabel(g, Policy.bind("ConfigurationWizardMainPage.project")); //$NON-NLS-1$
+		repositoryPathCombo = createEditableCombo(g);
+		repositoryPathCombo.addListener(SWT.Selection, listener);
+		repositoryPathCombo.addListener(SWT.Modify, listener);
+
+		g = createGroup(composite, Policy.bind("ConfigurationWizardMainPage.Authentication_2")); //$NON-NLS-1$
+		
+		anonButton = new Button(g, SWT.RADIO);
+		anonButton.setText(Policy.bind("ConfigurationWizardMainPage.anonymous")); //$NON-NLS-1$
+		anonButton.addListener(SWT.Selection, listener);
+
+		userButton = new Button(g, SWT.RADIO);
+		userButton.setText(Policy.bind("ConfigurationWizardMainPage.user")); //$NON-NLS-1$
+		userButton.addListener(SWT.Selection, listener);
+
+		// User name
+		createLabel(g, Policy.bind("ConfigurationWizardMainPage.userName")); //$NON-NLS-1$
+		userCombo = createEditableCombo(g);
+		userCombo.addListener(SWT.Selection, listener);
+		userCombo.addListener(SWT.Modify, listener);
+		
+		// Password
+		createLabel(g, Policy.bind("ConfigurationWizardMainPage.password")); //$NON-NLS-1$
+		passwordText = createTextField(g);
+		passwordText.setEchoChar('*');
+
+		// Connection type
+		createLabel(g, Policy.bind("ConfigurationWizardMainPage.connection")); //$NON-NLS-1$
+		connectionMethodCombo = createCombo(g);
+
+		Composite repo = createGroup(composite, Policy.bind("ConfigurationWizardMainPage.repositorySpec")); //$NON-NLS-1$
+		repoLabel = createWrappingLabel(repo, "", 0 /* indent */, 1 /* columns */); //$NON-NLS-1$
+		
+		// create a composite to ensure the validate button is in its own tab group
+		if (showValidate) {
+			Composite validateButtonTabGroup = new Composite(composite, SWT.NONE);
+			GridData data = new GridData();
+			data.horizontalSpan = 2;
+			validateButtonTabGroup.setLayoutData(data);
+			validateButtonTabGroup.setLayout(new FillLayout());
+
+			validateButton = new Button(validateButtonTabGroup, SWT.CHECK);
+			validateButton.setText(Policy.bind("ConfigurationWizardAutoconnectPage.validate")); //$NON-NLS-1$
+			validateButton.addListener(SWT.Selection, new Listener() {
+				public void handleEvent(Event e) {
+					validate = validateButton.getSelection();
+				}
+			});
+		}
+
+		initializeValues();
+		updateWidgetEnablements();
+		hostCombo.setFocus();
+		
+		setControl(composite);
+	}
+
+	/**
+	 * @see CVSWizardPage#finish
+	 */
+	public boolean finish(IProgressMonitor monitor) {
+		// Set the result to be the current values
+		Properties result = new Properties();
+
+		StandardRepository repo = getCurrentRepository(hostCombo.getText());
+
+		String user;
+		boolean anon = anonButton.getSelection();
+
+		if (anon) {
+			result.setProperty("connection", repo.getConnectionMethod()); //$NON-NLS-1$ //$NON-NLS-2
+			user = repo.anonymousUserName;
+			result.setProperty("password", repo.anonymousPassword); //$NON-NLS-1$
+		} else {
+			result.setProperty("connection", connectionMethodCombo.getText()); //$NON-NLS-1$
+			user = userCombo.getText();
+			result.setProperty("password", passwordText.getText()); //$NON-NLS-1$
+		}
+		result.setProperty("user", user);
+
+		String hostPlusPath = repo.computeCvsroot(repositoryPathCombo.getText(), user);
+		int index = hostPlusPath.indexOf(':');
+
+		result.setProperty("host", hostPlusPath.substring(0, index)); //$NON-NLS-1$
+		result.setProperty("root", hostPlusPath.substring(index + 1)); //$NON-NLS-1$
+		this.properties = result;
+		
+		saveWidgetValues();
+		
+		return true;
+	}
+
+	/**
+	 * Initializes states of the controls.
+	 */
+	protected void initializeValues() {
+		// Set remembered values
+		IDialogSettings settings = getDialogSettings();
+
+		standardRepositories = getStandardRepositories();
+		for (int i = 0; i < standardRepositories.length; i++) {
+			hostCombo.add(standardRepositories[i].repositoryName);
+		}
+
+		if (settings != null) {
+			String[] paths = settings.getArray(STORE_PROJECT_ID);
+			if (paths != null) {
+				for (int i = 0; i < paths.length; i++) {
+					repositoryPathCombo.add(paths[i]);
+				}
+			}
+			String[] userNames = settings.getArray(STORE_USERNAME_ID);
+			if (userNames == null) {
+				userNames = new String[] {
+					System.getProperty("user.name"),
+				};
+				settings.put(STORE_USERNAME_ID, userNames);
+			}
+			if (userNames != null) {
+				for (int i = 0; i < userNames.length; i++) {
+					userCombo.add(userNames[i]);
+				}
+			}
+			if (showValidate) {
+				validate = !settings.getBoolean(STORE_DONT_VALIDATE_ID);
+				validateButton.setSelection(validate);
+			}
+		}
+		
+		// Initialize other values and widget states
+		IConnectionMethod[] methods = CVSRepositoryLocation.getPluggedInConnectionMethods();
+		for (int i = 0; i < methods.length; i++) {
+			connectionMethodCombo.add(methods[i].getName());
+		}
+		
+		connectionMethodCombo.select(0);
+		
+		// FIXME.
+		userButton.setSelection(true);
+
+		if(properties != null) {
+			String method = (String)properties.getProperty("connection"); //$NON-NLS-1$
+			if (method == null) {
+				connectionMethodCombo.select(0);
+			} else {
+				connectionMethodCombo.select(connectionMethodCombo.indexOf(method));
+			}
+	
+			String user = (String)properties.getProperty("user"); //$NON-NLS-1$
+			if (user != null) {
+				userCombo.setText(user);
+			}
+	
+			String password = (String)properties.getProperty("password"); //$NON-NLS-1$
+			if (password != null) {
+				passwordText.setText(password);
+			}
+		}
+	}
+
+	/**
+	 * Saves the widget values
+	 */
+	protected void saveWidgetValues() {
+		// Update history
+		IDialogSettings settings = getDialogSettings();
+		if (settings != null) {
+			String[] userNames = settings.getArray(STORE_USERNAME_ID);
+			if (userNames == null) userNames = new String[0];
+			userNames = addToHistory(userNames, userCombo.getText());
+			settings.put(STORE_USERNAME_ID, userNames);
+
+			String[] paths = settings.getArray(STORE_PROJECT_ID);
+			if (paths == null) paths = new String[0];
+			paths = addToHistory(paths, repositoryPathCombo.getText());
+			settings.put(STORE_PATH_ID, paths);
+
+			if (showValidate) {
+				settings.put(STORE_DONT_VALIDATE_ID, !validate);
+			}
+		}
+	}
+
+	/**
+	 * Find the current standard repository object, given the host
+	 * name.
+	 */
+	protected StandardRepository getCurrentRepository(String name) {
+		for (int i = 0; i < standardRepositories.length; i++) {
+			if (name.equals(standardRepositories[i].repositoryName))
+				return standardRepositories[i];
+		}
+		return null;
+	}
+
+	/**
+	 * Updates widget enablements and sets error message if appropriate.
+	 */
+	protected void updateWidgetEnablements() {
+		StandardRepository repo = getCurrentRepository(hostCombo.getText());
+		if (repo == null || repo.soleProjectName != null)
+			repositoryPathCombo.setEnabled(false);
+		else
+			repositoryPathCombo.setEnabled(true);
+
+		boolean isanon = anonButton.getSelection();
+		userCombo.setEnabled(!isanon);
+		passwordText.setEnabled(!isanon);
+		connectionMethodCombo.setEnabled(!isanon);
+
+		validateFields();
+
+		String host = hostCombo.getText();
+		String repospec;
+		if (repo == null) {
+			repospec = "";
+		} else {
+			String user;
+			if (isanon)
+				user = repo.anonymousUserName;
+			else
+				user = userCombo.getText();
+			if (user.length() == 0)
+				user = "???";
+			String project;
+			if (repositoryPathCombo.isEnabled()) {
+				project = repositoryPathCombo.getText();
+				if (project.length() == 0)
+					project = "???";
+			} else {
+				project = "";	// doesn't matter
+			}
+			String hostPlusPath = repo.computeCvsroot(project, user);
+			repospec = (":" + connectionMethodCombo.getText() + ":"
+						+ user + "@" + hostPlusPath);
+		}
+		repoLabel.setText(repospec);
+	}
+
+	/**
+	 * Validates the contents of the editable fields and set page completion 
+	 * and error messages appropriately.
+	 */
+	protected void validateFields() {
+		// First ensure that there is a host.
+		String host = hostCombo.getText();
+		if (getCurrentRepository(host) == null) {
+			setErrorMessage(null);
+			setPageComplete(false);
+			return;
+		}
+		if (host.indexOf(':') != -1) {
+			setErrorMessage(Policy.bind("ConfigurationWizardMainPage.invalidHostName")); //$NON-NLS-1$
+			setPageComplete(false);
+			return;
+		}
+		
+		// Validate the user name
+		String user = userCombo.getText();
+		boolean isanon = anonButton.getSelection();
+		if (!isanon && user.length() == 0) {
+			setErrorMessage("A user name is required for user athentication.");
+			setPageComplete(false);
+			return;
+		}
+		if ((user.indexOf('@') != -1) || (user.indexOf(':') != -1)) {
+			setErrorMessage(Policy.bind("ConfigurationWizardMainPage.invalidUserName")); //$NON-NLS-1$
+			setPageComplete(false);
+			return;
+		}
+
+		// Validate the project
+		if (!repositoryPathCombo.isEnabled()) {
+			// Nothing.
+		} else if (repositoryPathCombo.getText().length() == 0) {
+			setErrorMessage("A project is required for this host.");
+			setPageComplete(false);
+			return;
+		} else {
+			// The standard repositories use a single word specifying
+			// the project name.  So disallow `/'.
+			String pathString = repositoryPathCombo.getText();
+			if (pathString.indexOf("/") != -1) { //$NON-NLS-1$
+				setErrorMessage(Policy.bind("ConfigurationWizardMainPage.invalidProjectName"));
+				setPageComplete(false);
+				return;
+			}
+		}
+		setErrorMessage(null);
+		setPageComplete(true);
+	}
+
+	// This holds information about a given standard repository.
+	public static final class StandardRepository {
+		// Name of repository as presented to user.
+		public String repositoryName;
+
+		// Name of the anonymous user.
+		public String anonymousUserName;
+
+		// The name of the only project available at that repository.
+		// If null, then the user must enter a project name.
+		public String soleProjectName;
+
+		// Used to construct the CVSROOT for anonymous access.
+		// The name of the project is passed as argument {0}.
+		public MessageFormat anonymousCvsrootFormat;
+
+		// Used to construct the CVSROOT for non-anonymous access.
+		// The name of the project is passed as argument {0}.
+		public MessageFormat userCvsrootFormat;
+
+		// Password for anonymous user.
+		public String anonymousPassword;
+
+		public StandardRepository(String repositoryName, String anonymousUserName, String anonymousCvsroot, String userCvsroot) {
+			this(repositoryName, anonymousUserName, null, anonymousCvsroot, userCvsroot, "");
+		}
+
+		public StandardRepository(String repositoryName, String anonymousUserName, String soleProjectName, String anonymousCvsroot, String userCvsroot) {
+			this(repositoryName, anonymousUserName, soleProjectName, anonymousCvsroot, userCvsroot, "");
+		}
+
+		public StandardRepository(String repositoryName, String anonymousUserName, String soleProjectName, String anonymousCvsroot, String userCvsroot, String anonymousPassword) {
+			this.repositoryName = repositoryName;
+			this.anonymousUserName = anonymousUserName;
+			this.soleProjectName = soleProjectName;
+			this.anonymousCvsrootFormat = new MessageFormat(anonymousCvsroot);
+			this.userCvsrootFormat = new MessageFormat(userCvsroot);
+			this.anonymousPassword = anonymousPassword;
+		}
+
+		public String computeCvsroot(String project, String userName) {
+			MessageFormat format;
+			if (soleProjectName != null) {
+				project = soleProjectName;
+			}
+			if (userName.equals(anonymousUserName)) {
+				format = anonymousCvsrootFormat;
+			} else {
+				format = userCvsrootFormat;
+			}
+			return format.format(new String[] { project });
+		}
+		public String getConnectionMethod() {
+			return "pserver"; //$NON-NLS-1$
+		}
+	}
+
+	public static StandardRepository[] getStandardRepositories () {
+		return new StandardRepository[] {
+			new StandardRepository("sourceforge.net", "anonymous", "cvs.{0}.sourceforge.net:/cvsroot/{0}", "cvs.{0}.sourceforge.net:/cvsroot/{0}"),
+			new StandardRepository("sources.redhat.com", "anoncvs", null, "sources.redhat.com:/cvs/{0}", "sources.redhat.com:/cvs/{0}", "anoncvs"),
+			new StandardRepository("gcc.gnu.org", "anoncvs", "gcc", "anoncvs.gnu.org:/cvsroot/{0}", "gcc.gnu.org:/cvs/{0}"),
+			new StandardRepository("subversions.gnu.org", "anoncvs", "anoncvs.gnu.org:/cvsroot/{0}", "subversions.gnu.org:/cvsroot/{0}"),
+			new StandardRepository("cvs.gnome.org", "anonymous", "gnome", "anoncvs.gnome.org:/cvs/{0}", "cvs.gnome.org:/cvs/{0}"),
+			new StandardRepository("cvs.kde.org", "anonymous", "kde", "anoncvs.kde.org:/home/{0}", "cvs.kde.org:/home/{0}"),
+			new StandardRepository("dev.eclipse.org", "anonymous", "dev.eclipse.org:/home/{0}", "dev.eclipse.org:/home/{0}"),
+		};
+	}
+}