diff options
Diffstat (limited to 'stubs/org.eclipse.mylyn.commons.team/src/org/eclipse')
23 files changed, 2711 insertions, 0 deletions
diff --git a/stubs/org.eclipse.mylyn.commons.team/src/org/eclipse/mylyn/commons/ui/team/IPartContainer.java b/stubs/org.eclipse.mylyn.commons.team/src/org/eclipse/mylyn/commons/ui/team/IPartContainer.java new file mode 100644 index 00000000..9f2f7e4e --- /dev/null +++ b/stubs/org.eclipse.mylyn.commons.team/src/org/eclipse/mylyn/commons/ui/team/IPartContainer.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright (c) 2010 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 + *******************************************************************************/ + +package org.eclipse.mylyn.commons.ui.team; + +import org.eclipse.jface.operation.IRunnableContext; + +/** + * @author Steffen Pingel + * @noimplement This interface is not intended to be implemented by clients. + * @noextend This interface is not intended to be extended by clients. + */ +public interface IPartContainer extends IRunnableContext { + + public void setMessage(String message, int messageType); + + public void updateButtons(); + +} diff --git a/stubs/org.eclipse.mylyn.commons.team/src/org/eclipse/mylyn/commons/ui/team/Messages.java b/stubs/org.eclipse.mylyn.commons.team/src/org/eclipse/mylyn/commons/ui/team/Messages.java new file mode 100644 index 00000000..c71361ea --- /dev/null +++ b/stubs/org.eclipse.mylyn.commons.team/src/org/eclipse/mylyn/commons/ui/team/Messages.java @@ -0,0 +1,66 @@ +/******************************************************************************* + * Copyright (c) 2011 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 + *******************************************************************************/ + +package org.eclipse.mylyn.commons.ui.team; + +import org.eclipse.osgi.util.NLS; + +class Messages extends NLS { + + private static final String BUNDLE_NAME = "org.eclipse.mylyn.commons.ui.team.messages"; //$NON-NLS-1$ + + public static String RepositoryLocationPart_Anonymous; + + public static String RepositoryLocationPart_Change_Settings; + + public static String RepositoryLocationPart_Disconnected; + + public static String RepositoryLocationPart_Enable_HTTP_Authentication; + + public static String RepositoryLocationPart_Enable_Proxy_Authentication; + + public static String RepositoryLocationPart_Enter_a_valid_server_url; + + public static String RepositoryLocationPart_HTTP_Authentication; + + public static String RepositoryLocationPart_Label; + + public static String RepositoryLocationPart_Password; + + public static String RepositoryLocationPart_Proxy_Host; + + public static String RepositoryLocationPart_Proxy_Port; + + public static String RepositoryLocationPart_Proxy_Server_Configuration; + + public static String RepositoryLocationPart_Repository_is_valid; + + public static String RepositoryLocationPart_Save_Password; + + public static String RepositoryLocationPart_Server; + + public static String RepositoryLocationPart_Unexpected_error_during_repository_validation; + + public static String RepositoryLocationPart_Use_global_Network_Connections_preferences; + + public static String RepositoryLocationPart_User; + + public static String RepositoryLocationPart_Validating_repository; + + static { + // initialize resource bundle + NLS.initializeMessages(BUNDLE_NAME, Messages.class); + } + + private Messages() { + } + +} diff --git a/stubs/org.eclipse.mylyn.commons.team/src/org/eclipse/mylyn/commons/ui/team/RepositoryLocationPart.java b/stubs/org.eclipse.mylyn.commons.team/src/org/eclipse/mylyn/commons/ui/team/RepositoryLocationPart.java new file mode 100644 index 00000000..ae2e89f3 --- /dev/null +++ b/stubs/org.eclipse.mylyn.commons.team/src/org/eclipse/mylyn/commons/ui/team/RepositoryLocationPart.java @@ -0,0 +1,613 @@ +/******************************************************************************* + * Copyright (c) 2010 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 + *******************************************************************************/ + +package org.eclipse.mylyn.commons.ui.team; + +import java.lang.reflect.InvocationTargetException; +import java.net.URI; +import java.util.concurrent.atomic.AtomicReference; + +import org.eclipse.core.databinding.DataBindingContext; +import org.eclipse.core.databinding.UpdateValueStrategy; +import org.eclipse.core.databinding.observable.value.IObservableValue; +import org.eclipse.core.databinding.validation.IValidator; +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.OperationCanceledException; +import org.eclipse.core.runtime.Status; +import org.eclipse.jface.databinding.dialog.DialogPageSupport; +import org.eclipse.jface.databinding.swt.ISWTObservableValue; +import org.eclipse.jface.databinding.swt.SWTObservables; +import org.eclipse.jface.databinding.wizard.WizardPageSupport; +import org.eclipse.jface.dialogs.DialogPage; +import org.eclipse.jface.dialogs.IMessageProvider; +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.jface.operation.IRunnableWithProgress; +import org.eclipse.jface.preference.PreferenceDialog; +import org.eclipse.jface.wizard.IWizardContainer; +import org.eclipse.jface.wizard.WizardPage; +import org.eclipse.mylyn.commons.repositories.RepositoryLocation; +import org.eclipse.mylyn.commons.repositories.RepositoryValidator; +import org.eclipse.mylyn.commons.repositories.auth.AuthenticationType; +import org.eclipse.mylyn.commons.repositories.auth.UsernamePasswordCredentials; +import org.eclipse.mylyn.internal.commons.ui.SectionComposite; +import org.eclipse.mylyn.internal.commons.ui.team.RepositoryLocationValueProperty; +import org.eclipse.mylyn.internal.commons.ui.team.TeamUiPlugin; +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.SelectionListener; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Link; +import org.eclipse.swt.widgets.Text; +import org.eclipse.ui.dialogs.PreferencesUtil; +import org.eclipse.ui.forms.widgets.ExpandableComposite; +import org.eclipse.ui.statushandlers.StatusManager; + +/** + * @author Steffen Pingel + * @since 3.5 + */ +public class RepositoryLocationPart { + + public class UrlValidator implements IValidator { + + public IStatus validate(Object value) { + if (!isValidUrl(value.toString())) { + return new Status(IStatus.ERROR, TeamUiPlugin.ID_PLUGIN, + Messages.RepositoryLocationPart_Enter_a_valid_server_url); + } + return Status.OK_STATUS; + } + + } + + private class UsernamePasswordListener implements ModifyListener, SelectionListener { + + private final AuthenticationType authenticationType; + + private final Button enabledButton; + + private boolean enablementReversed; + + private final Text passwordText; + + private final Button savePasswordButton; + + private boolean updating; + + private final Text userText; + + public UsernamePasswordListener(AuthenticationType authenticationType, Button enabledButton, Text userText, + Text passwordText, Button savePasswordButton) { + this.authenticationType = authenticationType; + this.enabledButton = enabledButton; + this.userText = userText; + this.passwordText = passwordText; + this.savePasswordButton = savePasswordButton; + init(); + } + + private void apply() { + if (updating) { + return; + } + if (isEnabled()) { + UsernamePasswordCredentials credentials = new UsernamePasswordCredentials(userText.getText(), + passwordText.getText()); + getWorkingCopy().setCredentials(authenticationType, credentials); + } else { + getWorkingCopy().setCredentials(authenticationType, null); + } + } + + protected void init() { + enabledButton.addSelectionListener(this); + userText.addModifyListener(this); + passwordText.addModifyListener(this); + savePasswordButton.addSelectionListener(this); + } + + protected boolean isEnabled() { + return enabledButton.getSelection() != isEnablementReversed(); + } + + public boolean isEnablementReversed() { + return enablementReversed; + } + + public void modifyText(ModifyEvent event) { + apply(); + } + + private void restore() { + try { + updating = true; + UsernamePasswordCredentials credentials = getWorkingCopy().getCredentials(authenticationType, + UsernamePasswordCredentials.class); + if (credentials != null) { + enabledButton.setSelection(!isEnablementReversed()); + userText.setText(credentials.getUserName()); + passwordText.setText(credentials.getUserName()); + savePasswordButton.setSelection(true); + } else { + enabledButton.setSelection(isEnablementReversed()); + userText.setText(""); //$NON-NLS-1$ + passwordText.setText(""); //$NON-NLS-1$ + savePasswordButton.setSelection(true); + } + } finally { + updating = false; + } + updateWidgetEnablement(); + } + + public void setEnablementReversed(boolean enablementReversed) { + this.enablementReversed = enablementReversed; + } + + private void updateWidgetEnablement() { + boolean enabled = isEnabled(); + userText.setEnabled(enabled); + passwordText.setEnabled(enabled); + savePasswordButton.setEnabled(enabled); + } + + public void widgetDefaultSelected(SelectionEvent event) { + apply(); + + } + + public void widgetSelected(SelectionEvent event) { + apply(); + if (event.widget == enabledButton) { + updateWidgetEnablement(); + } + } + + } + + protected static final String PREFS_PAGE_ID_NET_PROXY = "org.eclipse.ui.net.NetPreferences"; //$NON-NLS-1$ + + private DataBindingContext bindingContext; + + private boolean needsAdditionalSections; + + private boolean needsAnonymousLogin; + + private boolean needsHttpAuth; + + private boolean needsProxy; + + private boolean needsValidation; + + private IAdaptable serviceLocator; + + private final RepositoryLocation workingCopy; + + public RepositoryLocationPart(RepositoryLocation workingCopy) { + this.workingCopy = workingCopy; + setNeedsProxy(false); + setNeedsHttpAuth(false); + setNeedsValidation(true); + } + + protected void applyValidatorResult(RepositoryValidator validator) { + IStatus status = validator.getResult(); + String message = status.getMessage(); + if (message == null || message.length() == 0) { + message = null; + } + switch (status.getSeverity()) { + case IStatus.OK: + if (status == Status.OK_STATUS) { +// if (getUserName().length() > 0) { +// message = "Credentials are valid."; +// } else { + message = Messages.RepositoryLocationPart_Repository_is_valid; +// } + } + getPartContainer().setMessage(message, IMessageProvider.INFORMATION); + break; + case IStatus.INFO: + getPartContainer().setMessage(message, IMessageProvider.INFORMATION); + break; + case IStatus.WARNING: + getPartContainer().setMessage(message, IMessageProvider.WARNING); + break; + default: + getPartContainer().setMessage(message, IMessageProvider.ERROR); + break; + } + } + + private void bind(AuthenticationType authType, Button anonymousButton, Text userText, Text passwordText, + Button savePasswordButton, boolean reverseEnablement) { + UsernamePasswordListener listener = new UsernamePasswordListener(authType, anonymousButton, userText, + passwordText, savePasswordButton); + listener.setEnablementReversed(reverseEnablement); + listener.restore(); + } + + protected void bind(Button button, String property) { + ISWTObservableValue uiElement = SWTObservables.observeSelection(button); + IObservableValue modelElement = new RepositoryLocationValueProperty(property, Boolean.FALSE.toString()).observe(workingCopy); + bindingContext.bindValue(uiElement, modelElement, null, null); + } + + protected void bind(Text text, String property) { + bind(text, property, null, null); + } + + protected void bind(Text text, String property, UpdateValueStrategy targetObservableValue, + UpdateValueStrategy modelObservableValue) { + ISWTObservableValue uiElement = SWTObservables.observeText(text, SWT.Modify); + IObservableValue modelElement = new RepositoryLocationValueProperty(property, null).observe(workingCopy); + bindingContext.bindValue(uiElement, modelElement, targetObservableValue, modelObservableValue); + } + + /** + * Returns whether this page can be validated or not. + * <p> + * This information is typically used by the wizard to set the enablement of the validation UI affordance. + * </p> + * + * @return <code>true</code> if this page can be validated, and <code>false</code> otherwise + * @see #needsValidation() + * @see IWizardContainer#updateButtons() + */ + public boolean canValidate() { + return getValidator() != null; + } + + protected Control createAdditionalContents(Composite composite) { + return null; + } + + public Control createContents(Composite parent) { + bindingContext = new DataBindingContext(); + WizardPage wizardPage = getContainer(WizardPage.class); + if (wizardPage != null) { + WizardPageSupport.create(wizardPage, bindingContext); + } else { + DialogPage page = getContainer(DialogPage.class); + if (page != null) { + DialogPageSupport.create(page, bindingContext); + } + } + Composite composite = new Composite(parent, SWT.NONE); + GridLayoutFactory.swtDefaults().numColumns(3).applyTo(composite); + +// Composite this = new Composite(parent, SWT.NULL); +// Layout layout = new FillLayout(); +// this.setLayout(layout); + + createServerSection(composite); + createUserSection(composite); + + Control control = createAdditionalContents(composite); + if (control != null) { + GridDataFactory.fillDefaults().grab(true, true).span(3, 1).applyTo(control); + } + + if (needsHttpAuth() || needsProxy() || needsAdditionalSections()) { + SectionComposite sectionComposite = new SectionComposite(composite, SWT.NONE); + GridDataFactory.fillDefaults().grab(true, true).span(3, 1).applyTo(sectionComposite); + + if (needsHttpAuth()) { + createHttpAuthSection(sectionComposite); + } + if (needsProxy()) { + createProxySection(sectionComposite); + } + createSections(sectionComposite); + } + +// Button validateButton = new Button(composite, SWT.PUSH); +// validateButton.setText("Validate"); +// validateButton.addSelectionListener(new SelectionAdapter() { +// @Override +// public void widgetSelected(SelectionEvent e) { +// validate(); +// } +// }); + + return composite; + } + + private void createHttpAuthSection(SectionComposite parent) { + int style = SWT.NONE; + if (getWorkingCopy().getCredentials(AuthenticationType.HTTP, UsernamePasswordCredentials.class) != null) { + style |= ExpandableComposite.EXPANDED; + } + ExpandableComposite section = parent.createSection(Messages.RepositoryLocationPart_HTTP_Authentication, style); + section.clientVerticalSpacing = 5; + + Composite composite = new Composite(section, SWT.NONE); + section.setClient(composite); + GridLayoutFactory.fillDefaults().numColumns(3).applyTo(composite); + + Label label; + + Button enableButton = new Button(composite, SWT.CHECK); + GridDataFactory.fillDefaults().grab(true, false).span(3, 1).applyTo(enableButton); + enableButton.setText(Messages.RepositoryLocationPart_Enable_HTTP_Authentication); + + label = new Label(composite, SWT.NONE); + label.setText(Messages.RepositoryLocationPart_User); + + Text userText = new Text(composite, SWT.BORDER); + GridDataFactory.fillDefaults().grab(true, false).span(2, 1).applyTo(userText); + + label = new Label(composite, SWT.NONE); + label.setText(Messages.RepositoryLocationPart_Password); + + Text passwordText = new Text(composite, SWT.BORDER | SWT.PASSWORD); + GridDataFactory.fillDefaults().grab(true, false).applyTo(passwordText); + + Button savePasswordButton = new Button(composite, SWT.CHECK); + savePasswordButton.setText(Messages.RepositoryLocationPart_Save_Password); + + bind(AuthenticationType.HTTP, enableButton, userText, passwordText, savePasswordButton, false); + } + + private void createProxySection(final SectionComposite parent) { + ExpandableComposite section = parent.createSection(Messages.RepositoryLocationPart_Proxy_Server_Configuration); + + Composite composite = new Composite(section, SWT.NONE); + section.setClient(composite); + GridLayoutFactory.fillDefaults().numColumns(3).applyTo(composite); + + Label label; + + Button systemProxyButton = new Button(composite, SWT.CHECK); + GridDataFactory.fillDefaults().span(2, SWT.DEFAULT).applyTo(systemProxyButton); + systemProxyButton.setText(Messages.RepositoryLocationPart_Use_global_Network_Connections_preferences); +// systemProxyButton.addSelectionListener(new SelectionAdapter() { +// @Override +// public void widgetSelected(SelectionEvent e) { +// updateProxyEnablement(systemProxyButton.getSelection()); +// } +// }); + bind(systemProxyButton, RepositoryLocation.PROPERTY_PROXY_USEDEFAULT); + + Link changeProxySettingsLink = new Link(composite, SWT.NONE); + changeProxySettingsLink.setText(Messages.RepositoryLocationPart_Change_Settings); + changeProxySettingsLink.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + PreferenceDialog dlg = PreferencesUtil.createPreferenceDialogOn(parent.getShell(), + PREFS_PAGE_ID_NET_PROXY, new String[] { PREFS_PAGE_ID_NET_PROXY }, null); + dlg.open(); + } + }); + + label = new Label(composite, SWT.NONE); + label.setText(Messages.RepositoryLocationPart_Proxy_Host); + + Text proxyHostText = new Text(composite, SWT.BORDER); + GridDataFactory.fillDefaults().grab(true, false).span(2, 1).applyTo(proxyHostText); + bind(proxyHostText, RepositoryLocation.PROPERTY_PROXY_HOST); + + label = new Label(composite, SWT.NONE); + label.setText(Messages.RepositoryLocationPart_Proxy_Port); + + Text proxyPortText = new Text(composite, SWT.BORDER | SWT.PASSWORD); + GridDataFactory.fillDefaults().grab(true, false).span(2, 1).applyTo(proxyPortText); + bind(proxyPortText, RepositoryLocation.PROPERTY_PROXY_PORT); + + // authentication + + Button enableButton = new Button(composite, SWT.CHECK); + GridDataFactory.fillDefaults().grab(true, false).span(3, 1).applyTo(enableButton); + enableButton.setText(Messages.RepositoryLocationPart_Enable_Proxy_Authentication); + + label = new Label(composite, SWT.NONE); + label.setText(Messages.RepositoryLocationPart_User); + + Text userText = new Text(composite, SWT.BORDER); + GridDataFactory.fillDefaults().grab(true, false).span(2, 1).applyTo(userText); + + label = new Label(composite, SWT.NONE); + label.setText(Messages.RepositoryLocationPart_Password); + + Text passwordText = new Text(composite, SWT.BORDER | SWT.PASSWORD); + GridDataFactory.fillDefaults().grab(true, false).applyTo(passwordText); + + Button savePasswordButton = new Button(composite, SWT.CHECK); + savePasswordButton.setText(Messages.RepositoryLocationPart_Save_Password); + + bind(AuthenticationType.PROXY, enableButton, userText, passwordText, savePasswordButton, false); + } + + protected void createSections(SectionComposite sectionComposite) { + } + + private void createServerSection(Composite parent) { + Label label; + + label = new Label(parent, SWT.NONE); + label.setText(Messages.RepositoryLocationPart_Server); + + Text urlText = new Text(parent, SWT.BORDER); + GridDataFactory.fillDefaults().span(2, 1).grab(true, false).applyTo(urlText); + bind(urlText, RepositoryLocation.PROPERTY_URL, getUrlUpdateValueStrategy(), null); + + label = new Label(parent, SWT.NONE); + label.setText(Messages.RepositoryLocationPart_Label); + + Text labelText = new Text(parent, SWT.BORDER); + GridDataFactory.fillDefaults().grab(true, false).applyTo(labelText); + bind(labelText, RepositoryLocation.PROPERTY_LABEL); + + Button disconnectedButton = new Button(parent, SWT.CHECK); + disconnectedButton.setText(Messages.RepositoryLocationPart_Disconnected); + bind(disconnectedButton, RepositoryLocation.PROPERTY_OFFLINE); + } + + protected UpdateValueStrategy getUrlUpdateValueStrategy() { + return new UpdateValueStrategy().setAfterConvertValidator(new UrlValidator()); + } + + private void createUserSection(Composite parent) { + Label label; + + label = new Label(parent, SWT.NONE); + label.setText(Messages.RepositoryLocationPart_User); + + Text userText = new Text(parent, SWT.BORDER); + GridDataFactory.fillDefaults().grab(true, false).applyTo(userText); + bind(userText, RepositoryLocation.PROPERTY_USERNAME); + + Button anonymousButton = new Button(parent, SWT.CHECK); + anonymousButton.setText(Messages.RepositoryLocationPart_Anonymous); + + label = new Label(parent, SWT.NONE); + label.setText(Messages.RepositoryLocationPart_Password); + + Text passwordText = new Text(parent, SWT.BORDER | SWT.PASSWORD); + GridDataFactory.fillDefaults().grab(true, false).applyTo(passwordText); + + Button savePasswordButton = new Button(parent, SWT.CHECK); + savePasswordButton.setText(Messages.RepositoryLocationPart_Save_Password); + + bind(AuthenticationType.REPOSITORY, anonymousButton, userText, passwordText, savePasswordButton, true); + } + + public <T> T getContainer(Class<T> clazz) { + return (T) getServiceLocator().getAdapter(clazz); + } + + public IPartContainer getPartContainer() { + return getContainer(IPartContainer.class); + } + + private IAdaptable getServiceLocator() { + return serviceLocator; + } + + protected RepositoryValidator getValidator() { + return null; + } + + protected RepositoryLocation getWorkingCopy() { + return workingCopy; + } + + public boolean isValidUrl(String url) { + if (url.startsWith("https://") || url.startsWith("http://")) { //$NON-NLS-1$//$NON-NLS-2$ + try { + new URI(url); + return true; + } catch (Exception e) { + // fall through + } + } + return false; + } + + public boolean needsAdditionalSections() { + return needsAdditionalSections; + } + + public boolean needsAnonymousLogin() { + return needsAnonymousLogin; + } + + public boolean needsHttpAuth() { + return this.needsHttpAuth; + } + + public boolean needsProxy() { + return this.needsProxy; + } + + public boolean needsValidation() { + return needsValidation; + } + + public void setNeedsAdditionalSections(boolean needsAdditionalSections) { + this.needsAdditionalSections = needsAdditionalSections; + } + + public void setNeedsAnonymousLogin(boolean needsAnonymousLogin) { + this.needsAnonymousLogin = needsAnonymousLogin; + } + + public void setNeedsHttpAuth(boolean needsHttpAuth) { + this.needsHttpAuth = needsHttpAuth; + } + + public void setNeedsProxy(boolean needsProxy) { + this.needsProxy = needsProxy; + } + + public void setNeedsValidation(boolean needsValidation) { + this.needsValidation = needsValidation; + } + + public void setServiceLocator(IAdaptable container) { + this.serviceLocator = container; + } + + /** + * Validate settings provided by the {@link #getValidator() validator}, typically the server settings. + */ + public void validate() { + final RepositoryValidator validator = getValidator(); + if (validator == null) { + return; + } + + final AtomicReference<IStatus> result = new AtomicReference<IStatus>(); + try { + getContainer(IPartContainer.class).run(true, true, new IRunnableWithProgress() { + public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { + monitor.beginTask(Messages.RepositoryLocationPart_Validating_repository, IProgressMonitor.UNKNOWN); + try { + result.set(validator.run(monitor)); + } catch (OperationCanceledException e) { + result.set(Status.CANCEL_STATUS); + throw new InterruptedException(); + } catch (Exception e) { + throw new InvocationTargetException(e); + } finally { + monitor.done(); + } + } + }); + } catch (InvocationTargetException e) { + StatusManager.getManager().handle( + new Status(IStatus.ERROR, TeamUiPlugin.ID_PLUGIN, + Messages.RepositoryLocationPart_Unexpected_error_during_repository_validation, e), + StatusManager.SHOW | StatusManager.BLOCK | StatusManager.LOG); + return; + } catch (InterruptedException e) { + // canceled + return; + } + if (result.get() == null) { + validator.setResult(Status.OK_STATUS); + } else { + validator.setResult(result.get()); + } + getPartContainer().updateButtons(); + applyValidatorResult(validator); + } + +} diff --git a/stubs/org.eclipse.mylyn.commons.team/src/org/eclipse/mylyn/commons/ui/team/RepositoryPropertyPage.java b/stubs/org.eclipse.mylyn.commons.team/src/org/eclipse/mylyn/commons/ui/team/RepositoryPropertyPage.java new file mode 100644 index 00000000..36e1e878 --- /dev/null +++ b/stubs/org.eclipse.mylyn.commons.team/src/org/eclipse/mylyn/commons/ui/team/RepositoryPropertyPage.java @@ -0,0 +1,70 @@ +/******************************************************************************* + * Copyright (c) 2010 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 + *******************************************************************************/ + +package org.eclipse.mylyn.commons.ui.team; + +import java.util.UUID; + +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.dialogs.DialogPage; +import org.eclipse.mylyn.commons.repositories.RepositoryLocation; +import org.eclipse.mylyn.internal.commons.repositories.InMemoryCredentialsStore; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.ui.dialogs.PropertyPage; + +/** + * @author Steffen Pingel + */ +public class RepositoryPropertyPage extends PropertyPage implements IAdaptable { + + private RepositoryLocationPart part; + + private RepositoryLocation workingCopy; + + public RepositoryPropertyPage() { + } + + @Override + protected Control createContents(Composite parent) { + initializeDialogUnits(parent); + + part = new RepositoryLocationPart(getWorkingCopy()); + part.setServiceLocator(this); + setControl(part.createContents(parent)); + Dialog.applyDialogFont(parent); + return getControl(); + } + + RepositoryLocation getWorkingCopy() { + if (workingCopy == null) { + RepositoryLocation element = (RepositoryLocation) getElement().getAdapter(RepositoryLocation.class); + workingCopy = new RepositoryLocation(element); + if (workingCopy.getId() == null) { + workingCopy.setProperty(RepositoryLocation.PROPERTY_ID, UUID.randomUUID().toString()); + } + workingCopy.setCredentialsStore(new InMemoryCredentialsStore(workingCopy.getCredentialsStore())); + } + return workingCopy; + } + + public Object getAdapter(Class adapter) { + if (adapter == DialogPage.class) { + return this; + } + if (adapter == IPartContainer.class) { + return this; + } + return null; + } + +} diff --git a/stubs/org.eclipse.mylyn.commons.team/src/org/eclipse/mylyn/commons/ui/team/RepositoryUi.java b/stubs/org.eclipse.mylyn.commons.team/src/org/eclipse/mylyn/commons/ui/team/RepositoryUi.java new file mode 100644 index 00000000..572cdb91 --- /dev/null +++ b/stubs/org.eclipse.mylyn.commons.team/src/org/eclipse/mylyn/commons/ui/team/RepositoryUi.java @@ -0,0 +1,93 @@ +/******************************************************************************* + * Copyright (c) 2010 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 + *******************************************************************************/ + +package org.eclipse.mylyn.commons.ui.team; + +import org.eclipse.jface.dialogs.IDialogSettings; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.mylyn.internal.commons.ui.team.Messages; +import org.eclipse.mylyn.internal.commons.ui.team.TeamUiPlugin; +import org.eclipse.mylyn.internal.commons.ui.team.wizards.NewRepositoryWizard; +import org.eclipse.mylyn.internal.provisional.commons.ui.dialogs.ValidatableWizardDialog; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.internal.LegacyResourceSupport; +import org.eclipse.ui.internal.util.Util; + +/** + * @author Steffen Pingel + */ +public final class RepositoryUi { + + /** + * The wizard dialog width. + */ + private static final int SIZING_WIZARD_WIDTH = 500; + + /** + * The wizard dialog height. + */ + private static final int SIZING_WIZARD_HEIGHT = 500; + + public static final String ID_VIEW_REPOSITORIES = "org.eclipse.mylyn.commons.team.navigator.Repositories"; //$NON-NLS-1$ + + private RepositoryUi() { + } + + public static int openNewRepositoryDialog(IWorkbenchWindow workbenchWindow, String categoryId) { + NewRepositoryWizard wizard = new NewRepositoryWizard(); + wizard.setCategoryId(categoryId); + wizard.setWindowTitle(Messages.NewRepositoryHandler_New_Repository); + + ISelection selection = workbenchWindow.getSelectionService().getSelection(); + IStructuredSelection selectionToPass = StructuredSelection.EMPTY; + if (selection instanceof IStructuredSelection) { + selectionToPass = (IStructuredSelection) selection; + } else { + // @issue the following is resource-specific legacy code + // Build the selection from the IFile of the editor + Class resourceClass = LegacyResourceSupport.getResourceClass(); + if (resourceClass != null) { + IWorkbenchPart part = workbenchWindow.getPartService().getActivePart(); + if (part instanceof IEditorPart) { + IEditorInput input = ((IEditorPart) part).getEditorInput(); + Object resource = Util.getAdapter(input, resourceClass); + if (resource != null) { + selectionToPass = new StructuredSelection(resource); + } + } + } + } + + wizard.init(workbenchWindow.getWorkbench(), selectionToPass); + + IDialogSettings workbenchSettings = TeamUiPlugin.getDefault().getDialogSettings(); + IDialogSettings wizardSettings = workbenchSettings.getSection("NewWizardAction"); //$NON-NLS-1$ + if (wizardSettings == null) { + wizardSettings = workbenchSettings.addNewSection("NewWizardAction"); //$NON-NLS-1$ + } + wizard.setDialogSettings(wizardSettings); + wizard.setForcePreviousAndNextButtons(true); + + Shell parent = workbenchWindow.getShell(); + ValidatableWizardDialog dialog = new ValidatableWizardDialog(parent, wizard); + dialog.create(); + dialog.getShell().setSize(Math.max(SIZING_WIZARD_WIDTH, dialog.getShell().getSize().x), SIZING_WIZARD_HEIGHT); + //PlatformUI.getWorkbench().getHelpSystem().setHelp(dialog.getShell(), IWorkbenchHelpContextIds.NEW_WIZARD); + return dialog.open(); + } + +} diff --git a/stubs/org.eclipse.mylyn.commons.team/src/org/eclipse/mylyn/commons/ui/team/RepositoryWizardPage.java b/stubs/org.eclipse.mylyn.commons.team/src/org/eclipse/mylyn/commons/ui/team/RepositoryWizardPage.java new file mode 100644 index 00000000..f2845ae4 --- /dev/null +++ b/stubs/org.eclipse.mylyn.commons.team/src/org/eclipse/mylyn/commons/ui/team/RepositoryWizardPage.java @@ -0,0 +1,117 @@ +/******************************************************************************* + * Copyright (c) 2010 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 + *******************************************************************************/ + +package org.eclipse.mylyn.commons.ui.team; + +import java.lang.reflect.InvocationTargetException; + +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.dialogs.DialogPage; +import org.eclipse.jface.operation.IRunnableWithProgress; +import org.eclipse.jface.wizard.WizardPage; +import org.eclipse.mylyn.commons.repositories.RepositoryLocation; +import org.eclipse.mylyn.internal.provisional.commons.ui.dialogs.IValidatable; +import org.eclipse.swt.widgets.Composite; + +/** + * @author Steffen Pingel + */ +public class RepositoryWizardPage extends WizardPage implements IPartContainer, IAdaptable, IValidatable { + + private IAdaptable element; + + private RepositoryLocationPart part; + + private RepositoryLocation workingCopy; + + public RepositoryWizardPage(String pageName) { + super(pageName); + setPageComplete(false); + } + + public boolean canValidate() { + return part.canValidate(); + } + + public void createControl(Composite parent) { + initializeDialogUnits(parent); + + String message = getMessage(); + + part = doCreateRepositoryPart(); + part.setServiceLocator(this); + setControl(part.createContents(parent)); + Dialog.applyDialogFont(parent); + + setMessage(message); + } + + protected RepositoryLocationPart doCreateRepositoryPart() { + return new RepositoryLocationPart(getWorkingCopy()); + } + + public Object getAdapter(Class adapter) { + if (adapter == WizardPage.class) { + return this; + } + if (adapter == DialogPage.class) { + return this; + } + if (adapter == IPartContainer.class) { + return this; + } + return null; + } + + public IAdaptable getElement() { + return element; + } + + public RepositoryLocationPart getPart() { + return part; + } + + protected RepositoryLocation getWorkingCopy() { + if (workingCopy == null) { + workingCopy = (RepositoryLocation) getElement().getAdapter(RepositoryLocation.class); + } + return workingCopy; + } + + public boolean needsValidation() { + return part.needsValidation(); + } + + public void run(boolean fork, boolean cancelable, IRunnableWithProgress runnable) throws InvocationTargetException, + InterruptedException { + getContainer().run(fork, cancelable, runnable); + } + + /** + * Sets the element that owns properties shown on this page. + * + * @param element + * the element + */ + public void setElement(IAdaptable element) { + this.element = element; + } + + public void updateButtons() { + getContainer().updateButtons(); + } + + public void validate() { + part.validate(); + } + +} diff --git a/stubs/org.eclipse.mylyn.commons.team/src/org/eclipse/mylyn/commons/ui/team/messages.properties b/stubs/org.eclipse.mylyn.commons.team/src/org/eclipse/mylyn/commons/ui/team/messages.properties new file mode 100644 index 00000000..f5362b53 --- /dev/null +++ b/stubs/org.eclipse.mylyn.commons.team/src/org/eclipse/mylyn/commons/ui/team/messages.properties @@ -0,0 +1,19 @@ +RepositoryLocationPart_Anonymous=Anonymous +RepositoryLocationPart_Change_Settings=<a>Change Settings</a> +RepositoryLocationPart_Disconnected=Disconnected +RepositoryLocationPart_Enable_HTTP_Authentication=Enable HTTP Authentication +RepositoryLocationPart_Enable_Proxy_Authentication=Enable Proxy Authentication +RepositoryLocationPart_Enter_a_valid_server_url=Enter a valid server url. +RepositoryLocationPart_HTTP_Authentication=HTTP Authentication +RepositoryLocationPart_Label=&Label: +RepositoryLocationPart_Password=&Password: +RepositoryLocationPart_Proxy_Host=Proxy &Host: +RepositoryLocationPart_Proxy_Port=Proxy &Port: +RepositoryLocationPart_Proxy_Server_Configuration=Proxy Server Configuration +RepositoryLocationPart_Repository_is_valid=Repository is valid. +RepositoryLocationPart_Save_Password=Save Password +RepositoryLocationPart_Server=&Server: +RepositoryLocationPart_Unexpected_error_during_repository_validation=Unexpected error during repository validation. +RepositoryLocationPart_Use_global_Network_Connections_preferences=Use global Network Connections preferences +RepositoryLocationPart_User=&User: +RepositoryLocationPart_Validating_repository=Validating repository diff --git a/stubs/org.eclipse.mylyn.commons.team/src/org/eclipse/mylyn/internal/commons/ui/team/EmptyRepositoryCategoriesFilter.java b/stubs/org.eclipse.mylyn.commons.team/src/org/eclipse/mylyn/internal/commons/ui/team/EmptyRepositoryCategoriesFilter.java new file mode 100644 index 00000000..4000856f --- /dev/null +++ b/stubs/org.eclipse.mylyn.commons.team/src/org/eclipse/mylyn/internal/commons/ui/team/EmptyRepositoryCategoriesFilter.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright (c) 2010 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 + *******************************************************************************/ + +package org.eclipse.mylyn.internal.commons.ui.team; + +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.StructuredViewer; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.viewers.ViewerFilter; +import org.eclipse.mylyn.commons.repositories.RepositoryCategory; + +/** + * @author Robert Elves + * @author Steffen Pingel + */ +public class EmptyRepositoryCategoriesFilter extends ViewerFilter { + + public EmptyRepositoryCategoriesFilter() { + } + + @Override + public boolean select(Viewer viewer, Object parentElement, Object element) { + if (element instanceof RepositoryCategory) { + return ((ITreeContentProvider) ((StructuredViewer) viewer).getContentProvider()).getChildren(element).length > 0; + } + return true; + } +} diff --git a/stubs/org.eclipse.mylyn.commons.team/src/org/eclipse/mylyn/internal/commons/ui/team/Messages.java b/stubs/org.eclipse.mylyn.commons.team/src/org/eclipse/mylyn/internal/commons/ui/team/Messages.java new file mode 100644 index 00000000..4a5c3855 --- /dev/null +++ b/stubs/org.eclipse.mylyn.commons.team/src/org/eclipse/mylyn/internal/commons/ui/team/Messages.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright (c) 2011 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 + *******************************************************************************/ + +package org.eclipse.mylyn.internal.commons.ui.team; + +import org.eclipse.osgi.util.NLS; + +public class Messages extends NLS { + private static final String BUNDLE_NAME = "org.eclipse.mylyn.internal.commons.ui.team.messages"; //$NON-NLS-1$ + + public static String NewRepositoryHandler_New_Repository; + + public static String RepositoriesView_Root; + static { + // initialize resource bundle + NLS.initializeMessages(BUNDLE_NAME, Messages.class); + } + + private Messages() { + } +} diff --git a/stubs/org.eclipse.mylyn.commons.team/src/org/eclipse/mylyn/internal/commons/ui/team/NewRepositoryHandler.java b/stubs/org.eclipse.mylyn.commons.team/src/org/eclipse/mylyn/internal/commons/ui/team/NewRepositoryHandler.java new file mode 100644 index 00000000..507eca39 --- /dev/null +++ b/stubs/org.eclipse.mylyn.commons.team/src/org/eclipse/mylyn/internal/commons/ui/team/NewRepositoryHandler.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright (c) 2010 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 + *******************************************************************************/ + +package org.eclipse.mylyn.internal.commons.ui.team; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.commands.IHandler; +import org.eclipse.mylyn.commons.ui.team.RepositoryUi; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.handlers.HandlerUtil; + +/** + * @author Steffen Pingel + */ +public class NewRepositoryHandler extends AbstractHandler implements IHandler { + + public Object execute(ExecutionEvent event) throws ExecutionException { + IWorkbenchWindow workbenchWindow = HandlerUtil.getActiveWorkbenchWindowChecked(event); + return RepositoryUi.openNewRepositoryDialog(workbenchWindow, null); + } + +} diff --git a/stubs/org.eclipse.mylyn.commons.team/src/org/eclipse/mylyn/internal/commons/ui/team/RepositoriesView.java b/stubs/org.eclipse.mylyn.commons.team/src/org/eclipse/mylyn/internal/commons/ui/team/RepositoriesView.java new file mode 100644 index 00000000..94152ad7 --- /dev/null +++ b/stubs/org.eclipse.mylyn.commons.team/src/org/eclipse/mylyn/internal/commons/ui/team/RepositoriesView.java @@ -0,0 +1,72 @@ +/******************************************************************************* + * Copyright (c) 2010 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 + *******************************************************************************/ + +package org.eclipse.mylyn.internal.commons.ui.team; + +import org.eclipse.mylyn.commons.repositories.RepositoryCategory; +import org.eclipse.mylyn.internal.provisional.commons.ui.GradientDrawer; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.navigator.CommonNavigator; +import org.eclipse.ui.navigator.CommonViewer; +import org.eclipse.ui.part.IShowInTargetList; +import org.eclipse.ui.themes.IThemeManager; + +/** + * @author Steffen Pingel + */ +public class RepositoriesView extends CommonNavigator { + + private final RepositoryCategory rootCategory; + + public RepositoriesView() { + rootCategory = new RepositoryCategory(RepositoryCategory.ID_CATEGORY_ROOT, Messages.RepositoriesView_Root, 0); + } + + @Override + protected Object getInitialInput() { + return rootCategory; + } + + @Override + public void createPartControl(Composite aParent) { + super.createPartControl(aParent); + getCommonViewer().expandAll(); + } + + @Override + protected CommonViewer createCommonViewer(Composite aParent) { + CommonViewer viewer = super.createCommonViewer(aParent); + IThemeManager themeManager = getSite().getWorkbenchWindow().getWorkbench().getThemeManager(); + new GradientDrawer(themeManager, viewer) { + @Override + protected boolean shouldApplyGradient(org.eclipse.swt.widgets.Event event) { + return event.item.getData() instanceof RepositoryCategory; + } + }; + return viewer; + } + + @Override + public Object getAdapter(@SuppressWarnings("rawtypes") + Class adapter) { + // FIXME read targets from extension point? + if (adapter == IShowInTargetList.class) { + return new IShowInTargetList() { + public String[] getShowInTargetIds() { + return new String[] { "org.eclipse.mylyn.builds.navigator.builds" }; //$NON-NLS-1$ + } + + }; + } + return super.getAdapter(adapter); + } + +} diff --git a/stubs/org.eclipse.mylyn.commons.team/src/org/eclipse/mylyn/internal/commons/ui/team/RepositoryCategoryContentProvider.java b/stubs/org.eclipse.mylyn.commons.team/src/org/eclipse/mylyn/internal/commons/ui/team/RepositoryCategoryContentProvider.java new file mode 100644 index 00000000..4200a620 --- /dev/null +++ b/stubs/org.eclipse.mylyn.commons.team/src/org/eclipse/mylyn/internal/commons/ui/team/RepositoryCategoryContentProvider.java @@ -0,0 +1,67 @@ +/******************************************************************************* + * Copyright (c) 2010 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 + *******************************************************************************/ + +package org.eclipse.mylyn.internal.commons.ui.team; + +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.mylyn.commons.repositories.RepositoryCategory; + +public class RepositoryCategoryContentProvider implements ITreeContentProvider { + + private static final Map<String, RepositoryCategory> repositoryCategories = new HashMap<String, RepositoryCategory>(); + + public RepositoryCategoryContentProvider() { + RepositoryCategory catTasks = new RepositoryCategory(RepositoryCategory.ID_CATEGORY_TASKS, "Tasks", 0); //$NON-NLS-1$ + repositoryCategories.put(catTasks.getId(), catTasks); + RepositoryCategory catBugs = new RepositoryCategory(RepositoryCategory.ID_CATEGORY_BUGS, "Bugs", 100); //$NON-NLS-1$ + repositoryCategories.put(catBugs.getId(), catBugs); + RepositoryCategory catBuild = new RepositoryCategory(RepositoryCategory.ID_CATEGORY_BUILDS, "Builds", 200); //$NON-NLS-1$ + repositoryCategories.put(catBuild.getId(), catBuild); + RepositoryCategory catReview = new RepositoryCategory(RepositoryCategory.ID_CATEGORY_REVIEWS, "Reviews", 300); //$NON-NLS-1$ + repositoryCategories.put(catReview.getId(), catReview); + RepositoryCategory catOther = new RepositoryCategory(RepositoryCategory.ID_CATEGORY_OTHER, "Other", 400); //$NON-NLS-1$ + repositoryCategories.put(catOther.getId(), catOther); + } + + public void dispose() { + // ignore + + } + + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + // ignore + + } + + public Object[] getElements(Object inputElement) { + return repositoryCategories.values().toArray(); + } + + public Object[] getChildren(Object parentElement) { + // ignore + return null; + } + + public Object getParent(Object element) { + // ignore + return null; + } + + public boolean hasChildren(Object element) { + // ignore + return false; + } + +} diff --git a/stubs/org.eclipse.mylyn.commons.team/src/org/eclipse/mylyn/internal/commons/ui/team/RepositoryCategorySorter.java b/stubs/org.eclipse.mylyn.commons.team/src/org/eclipse/mylyn/internal/commons/ui/team/RepositoryCategorySorter.java new file mode 100644 index 00000000..fb69a24e --- /dev/null +++ b/stubs/org.eclipse.mylyn.commons.team/src/org/eclipse/mylyn/internal/commons/ui/team/RepositoryCategorySorter.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright (c) 2010 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 + *******************************************************************************/ + +package org.eclipse.mylyn.internal.commons.ui.team; + +import java.text.Collator; + +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.viewers.ViewerSorter; +import org.eclipse.mylyn.commons.repositories.RepositoryCategory; + +public class RepositoryCategorySorter extends ViewerSorter { + + public RepositoryCategorySorter() { + } + + public RepositoryCategorySorter(Collator collator) { + super(collator); + } + + @Override + public int compare(Viewer viewer, Object e1, Object e2) { + if (e1 instanceof RepositoryCategory && e2 instanceof RepositoryCategory) { + RepositoryCategory category1 = (RepositoryCategory) e1; + RepositoryCategory category2 = (RepositoryCategory) e2; + int result = category1.getRank() - category2.getRank(); + if (result != 0) { + return result; + } + } + // fall back to comparing by label + return super.compare(viewer, e1, e2); + } + +} diff --git a/stubs/org.eclipse.mylyn.commons.team/src/org/eclipse/mylyn/internal/commons/ui/team/RepositoryLabelProvider.java b/stubs/org.eclipse.mylyn.commons.team/src/org/eclipse/mylyn/internal/commons/ui/team/RepositoryLabelProvider.java new file mode 100644 index 00000000..e384c669 --- /dev/null +++ b/stubs/org.eclipse.mylyn.commons.team/src/org/eclipse/mylyn/internal/commons/ui/team/RepositoryLabelProvider.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright (c) 2010 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 + *******************************************************************************/ + +package org.eclipse.mylyn.internal.commons.ui.team; + +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.mylyn.commons.repositories.RepositoryCategory; +import org.eclipse.swt.graphics.Image; +import org.eclipse.ui.ISharedImages; +import org.eclipse.ui.internal.WorkbenchImages; + +/** + * @author Steffen Pingel + */ +public class RepositoryLabelProvider extends LabelProvider { + + @Override + public Image getImage(Object object) { + if (object instanceof RepositoryCategory) { + return WorkbenchImages.getImage(ISharedImages.IMG_OBJ_FOLDER); + } + return null; + } + + @Override + public String getText(Object object) { + if (object instanceof RepositoryCategory) { + return ((RepositoryCategory) object).getLabel(); + } + return null; + } + +} diff --git a/stubs/org.eclipse.mylyn.commons.team/src/org/eclipse/mylyn/internal/commons/ui/team/RepositoryLocationValueProperty.java b/stubs/org.eclipse.mylyn.commons.team/src/org/eclipse/mylyn/internal/commons/ui/team/RepositoryLocationValueProperty.java new file mode 100644 index 00000000..1c36dd8d --- /dev/null +++ b/stubs/org.eclipse.mylyn.commons.team/src/org/eclipse/mylyn/internal/commons/ui/team/RepositoryLocationValueProperty.java @@ -0,0 +1,104 @@ +/******************************************************************************* + * Copyright (c) 2010 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 + *******************************************************************************/ + +package org.eclipse.mylyn.internal.commons.ui.team; + +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; + +import org.eclipse.core.databinding.observable.Diffs; +import org.eclipse.core.databinding.observable.IDiff; +import org.eclipse.core.databinding.property.INativePropertyListener; +import org.eclipse.core.databinding.property.IProperty; +import org.eclipse.core.databinding.property.ISimplePropertyListener; +import org.eclipse.core.databinding.property.NativePropertyListener; +import org.eclipse.core.databinding.property.value.SimpleValueProperty; +import org.eclipse.mylyn.commons.repositories.RepositoryLocation; + +/** + * @author Steffen Pingel + */ +public class RepositoryLocationValueProperty extends SimpleValueProperty { + + private class PrivatePropertyChangeListener extends NativePropertyListener implements PropertyChangeListener { + + public PrivatePropertyChangeListener(IProperty property, ISimplePropertyListener listener) { + super(property, listener); + } + + @Override + protected void doAddTo(Object source) { + ((RepositoryLocation) source).addChangeListener(this); + } + + @Override + protected void doRemoveFrom(Object source) { + ((RepositoryLocation) source).removeChangeListener(this); + } + + public void propertyChange(PropertyChangeEvent evt) { + if (evt.getPropertyName() == null || key.equals(evt.getPropertyName())) { + Object oldValue = evt.getOldValue(); + Object newValue = evt.getNewValue(); + IDiff diff; + if (evt.getPropertyName() == null || oldValue == null || newValue == null) { + diff = null; + } else { + diff = Diffs.createValueDiff(oldValue, newValue); + } + fireChange(evt.getSource(), diff); + } + } + + } + + private final String key; + + private final String defaultValue; + + public RepositoryLocationValueProperty(String key, String defaultValue) { + this.key = key; + this.defaultValue = defaultValue; + } + + public Object getValueType() { + return String.class; + } + + @Override + protected Object doGetValue(Object source) { +// if ("uri".equals(key)) { +// URI uri = ((RepositoryLocation) source).getUri(); +// return (uri != null) ? uri.toString() : uri; +// } + String value = ((RepositoryLocation) source).getProperty(key); + return (value != null) ? value : defaultValue; + } + + @Override + protected void doSetValue(Object source, Object value) { +// if ("uri".equals(key)) { +// try { +// ((RepositoryLocation) source).setUri(new URI((String) value)); +// } catch (URISyntaxException e) { +// // ignore +// } +// } else { + ((RepositoryLocation) source).setProperty(key, (value != null) ? value.toString() : null); +// } + } + + @Override + public INativePropertyListener adaptListener(final ISimplePropertyListener listener) { + return new PrivatePropertyChangeListener(this, listener); + } + +} diff --git a/stubs/org.eclipse.mylyn.commons.team/src/org/eclipse/mylyn/internal/commons/ui/team/ShowInMenuContribution.java b/stubs/org.eclipse.mylyn.commons.team/src/org/eclipse/mylyn/internal/commons/ui/team/ShowInMenuContribution.java new file mode 100644 index 00000000..a4e42ed7 --- /dev/null +++ b/stubs/org.eclipse.mylyn.commons.team/src/org/eclipse/mylyn/internal/commons/ui/team/ShowInMenuContribution.java @@ -0,0 +1,56 @@ +/******************************************************************************* + * Copyright (c) 2010 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 + *******************************************************************************/ + +package org.eclipse.mylyn.internal.commons.ui.team; + +import org.eclipse.jface.action.ContributionItem; +import org.eclipse.jface.action.IContributionItem; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.actions.ContributionItemFactory; + +/** + * @author Steffen Pingel + */ +public class ShowInMenuContribution extends ContributionItem { + + private IContributionItem item; + + public ShowInMenuContribution() { + } + + public ShowInMenuContribution(String id) { + super(id); + } + + @Override + public void fill(Menu menu, int index) { + IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); + if (window != null) { + if (item != null) { + item.dispose(); + } + item = ContributionItemFactory.VIEWS_SHOW_IN.create(window); + item.fill(menu, index); + } + } + + @Override + public void dispose() { + if (item != null) { + item.dispose(); + item = null; + } + super.dispose(); + } + +} diff --git a/stubs/org.eclipse.mylyn.commons.team/src/org/eclipse/mylyn/internal/commons/ui/team/TeamUiPlugin.java b/stubs/org.eclipse.mylyn.commons.team/src/org/eclipse/mylyn/internal/commons/ui/team/TeamUiPlugin.java new file mode 100644 index 00000000..007d8651 --- /dev/null +++ b/stubs/org.eclipse.mylyn.commons.team/src/org/eclipse/mylyn/internal/commons/ui/team/TeamUiPlugin.java @@ -0,0 +1,52 @@ +/******************************************************************************* + * Copyright (c) 2010 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 + *******************************************************************************/ +package org.eclipse.mylyn.internal.commons.ui.team; + +import org.eclipse.ui.plugin.AbstractUIPlugin; +import org.osgi.framework.BundleContext; + +/** + * @author Steffen Pingel + */ +public class TeamUiPlugin extends AbstractUIPlugin { + + public static final String ID_PLUGIN = "org.eclipse.mylyn.commons.team"; //$NON-NLS-1$ + + private static TeamUiPlugin plugin; + + /** + * The constructor + */ + public TeamUiPlugin() { + } + + @Override + public void start(BundleContext context) throws Exception { + super.start(context); + plugin = this; + } + + @Override + public void stop(BundleContext context) throws Exception { + plugin = null; + super.stop(context); + } + + /** + * Returns the shared instance + * + * @return the shared instance + */ + public static TeamUiPlugin getDefault() { + return plugin; + } + +} diff --git a/stubs/org.eclipse.mylyn.commons.team/src/org/eclipse/mylyn/internal/commons/ui/team/messages.properties b/stubs/org.eclipse.mylyn.commons.team/src/org/eclipse/mylyn/internal/commons/ui/team/messages.properties new file mode 100644 index 00000000..43958721 --- /dev/null +++ b/stubs/org.eclipse.mylyn.commons.team/src/org/eclipse/mylyn/internal/commons/ui/team/messages.properties @@ -0,0 +1,2 @@ +NewRepositoryHandler_New_Repository=New Repository +RepositoriesView_Root=Root diff --git a/stubs/org.eclipse.mylyn.commons.team/src/org/eclipse/mylyn/internal/commons/ui/team/wizards/NewRepositoryWizard.java b/stubs/org.eclipse.mylyn.commons.team/src/org/eclipse/mylyn/internal/commons/ui/team/wizards/NewRepositoryWizard.java new file mode 100644 index 00000000..557b65bb --- /dev/null +++ b/stubs/org.eclipse.mylyn.commons.team/src/org/eclipse/mylyn/internal/commons/ui/team/wizards/NewRepositoryWizard.java @@ -0,0 +1,172 @@ +/******************************************************************************* + * Copyright (c) 2000, 2010 IBM Corporation 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.mylyn.internal.commons.ui.team.wizards; + +import java.util.StringTokenizer; + +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.wizard.IWizard; +import org.eclipse.jface.wizard.Wizard; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.internal.IWorkbenchGraphicConstants; +import org.eclipse.ui.internal.WorkbenchImages; +import org.eclipse.ui.internal.WorkbenchMessages; +import org.eclipse.ui.wizards.IWizardCategory; +import org.eclipse.ui.wizards.IWizardDescriptor; + +/** + * The new wizard is responsible for allowing the user to choose which new (nested) wizard to run. The set of available + * new wizards comes from the new extension point. + */ +public class NewRepositoryWizard extends Wizard { + + private static final String CATEGORY_SEPARATOR = "/"; //$NON-NLS-1$ + + private String categoryId = null; + + private NewRepositoryWizardSelectionPage mainPage; + + private boolean projectsOnly = false; + + private IStructuredSelection selection; + + private IWorkbench workbench; + + /** + * Create the wizard pages + */ + @Override + public void addPages() { + IWizardCategory root = NewRepositoryWizardRegistry.getInstance().getRootCategory(); + IWizardDescriptor[] primary = NewRepositoryWizardRegistry.getInstance().getPrimaryWizards(); + + if (categoryId != null) { + IWizardCategory categories = root; + StringTokenizer familyTokenizer = new StringTokenizer(categoryId, CATEGORY_SEPARATOR); + while (familyTokenizer.hasMoreElements()) { + categories = getChildWithID(categories, familyTokenizer.nextToken()); + if (categories == null) { + break; + } + } + if (categories != null) { + root = categories; + } + } + + mainPage = new NewRepositoryWizardSelectionPage(workbench, selection, root, primary, projectsOnly); + addPage(mainPage); + } + + /** + * Returns the id of the category of wizards to show or <code>null</code> to show all categories. If no entries can + * be found with this id then all categories are shown. + * + * @return String or <code>null</code>. + */ + public String getCategoryId() { + return categoryId; + } + + /** + * Returns the child collection element for the given id + */ + private IWizardCategory getChildWithID(IWizardCategory parent, String id) { + IWizardCategory[] children = parent.getCategories(); + for (int i = 0; i < children.length; ++i) { + IWizardCategory currentChild = children[i]; + if (currentChild.getId().equals(id)) { + return currentChild; + } + } + return null; + } + + /** + * Lazily create the wizards pages + * + * @param aWorkbench + * the workbench + * @param currentSelection + * the current selection + */ + public void init(IWorkbench aWorkbench, IStructuredSelection currentSelection) { + this.workbench = aWorkbench; + this.selection = currentSelection; + + if (getWindowTitle() == null) { + // No title supplied. Set the default title + if (projectsOnly) { + setWindowTitle(WorkbenchMessages.NewProject_title); + } else { + setWindowTitle(WorkbenchMessages.NewWizard_title); + } + } + setDefaultPageImageDescriptor(WorkbenchImages.getImageDescriptor(IWorkbenchGraphicConstants.IMG_WIZBAN_NEW_WIZ)); + setNeedsProgressMonitor(true); + } + + /** + * The user has pressed Finish. Instruct self's pages to finish, and answer a boolean indicating success. + * + * @return boolean + */ + @Override + public boolean performFinish() { + //save our selection state + mainPage.saveWidgetValues(); + // if we're finishing from the main page then perform finish on the selected wizard. + if (getContainer().getCurrentPage() == mainPage) { + if (mainPage.canFinishEarly()) { + IWizard wizard = mainPage.getSelectedNode().getWizard(); + wizard.setContainer(getContainer()); + return wizard.performFinish(); + } + } + return true; + } + + /** + * Sets the id of the category of wizards to show or <code>null</code> to show all categories. If no entries can be + * found with this id then all categories are shown. + * + * @param id + * may be <code>null</code>. + */ + public void setCategoryId(String id) { + categoryId = id; + } + + /** + * Sets the projects only flag. If <code>true</code> only projects will be shown in this wizard. + * + * @param b + * if only projects should be shown + */ + public void setProjectsOnly(boolean b) { + projectsOnly = b; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.wizard.IWizard#canFinish() + */ + @Override + public boolean canFinish() { + // we can finish if the first page is current and the the page can finish early. + if (getContainer().getCurrentPage() == mainPage) { + if (mainPage.canFinishEarly()) { + return true; + } + } + return super.canFinish(); + } + +} diff --git a/stubs/org.eclipse.mylyn.commons.team/src/org/eclipse/mylyn/internal/commons/ui/team/wizards/NewRepositoryWizardCollectionComparator.java b/stubs/org.eclipse.mylyn.commons.team/src/org/eclipse/mylyn/internal/commons/ui/team/wizards/NewRepositoryWizardCollectionComparator.java new file mode 100644 index 00000000..82bbfb03 --- /dev/null +++ b/stubs/org.eclipse.mylyn.commons.team/src/org/eclipse/mylyn/internal/commons/ui/team/wizards/NewRepositoryWizardCollectionComparator.java @@ -0,0 +1,71 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 IBM Corporation 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ + +package org.eclipse.mylyn.internal.commons.ui.team.wizards; + +import org.eclipse.jface.viewers.IBasicPropertyConstants; +import org.eclipse.jface.viewers.ViewerComparator; +import org.eclipse.ui.internal.dialogs.WizardCollectionElement; +import org.eclipse.ui.internal.dialogs.WorkbenchWizardElement; +import org.eclipse.ui.internal.registry.WizardsRegistryReader; + +/** + * A Viewer element sorter that sorts Elements by their name attribute. Note that capitalization differences are not + * considered by this sorter, so a < B < c. NOTE one exception to the above: an element with the system's reserved name + * for base Wizards will always be sorted such that it will ultimately be placed at the beginning of the sorted result. + */ +class NewWizardCollectionComparator extends ViewerComparator { + /** + * Static instance of this class. + */ + public final static NewWizardCollectionComparator INSTANCE = new NewWizardCollectionComparator(); + + /** + * Creates an instance of <code>NewWizardCollectionSorter</code>. Since this is a stateless sorter, it is only + * accessible as a singleton; the private visibility of this constructor ensures this. + */ + private NewWizardCollectionComparator() { + super(); + } + + /* + * (non-Javadoc) + * @see org.eclipse.jface.viewers.ViewerSorter#category(java.lang.Object) + */ + @Override + public int category(Object element) { + if (element instanceof WorkbenchWizardElement) { + return -1; + } + if (element instanceof WizardCollectionElement) { + String id = ((WizardCollectionElement) element).getId(); + if (WizardsRegistryReader.GENERAL_WIZARD_CATEGORY.equals(id)) { + return 1; + } + if (WizardsRegistryReader.UNCATEGORIZED_WIZARD_CATEGORY.equals(id)) { + return 3; + } + if (WizardsRegistryReader.FULL_EXAMPLES_WIZARD_CATEGORY.equals(id)) { + return 4; + } + return 2; + } + return super.category(element); + } + + /** + * Return true if this sorter is affected by a property change of propertyName on the specified element. + */ + @Override + public boolean isSorterProperty(Object object, String propertyId) { + return propertyId.equals(IBasicPropertyConstants.P_TEXT); + } +} diff --git a/stubs/org.eclipse.mylyn.commons.team/src/org/eclipse/mylyn/internal/commons/ui/team/wizards/NewRepositoryWizardNewPage.java b/stubs/org.eclipse.mylyn.commons.team/src/org/eclipse/mylyn/internal/commons/ui/team/wizards/NewRepositoryWizardNewPage.java new file mode 100644 index 00000000..e93ff360 --- /dev/null +++ b/stubs/org.eclipse.mylyn.commons.team/src/org/eclipse/mylyn/internal/commons/ui/team/wizards/NewRepositoryWizardNewPage.java @@ -0,0 +1,727 @@ +/******************************************************************************* + * Copyright (c) 2000, 2010 IBM Corporation 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.mylyn.internal.commons.ui.team.wizards; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Hashtable; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.Path; +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.dialogs.IDialogSettings; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.viewers.DoubleClickEvent; +import org.eclipse.jface.viewers.IDoubleClickListener; +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.TreeViewer; +import org.eclipse.jface.viewers.ViewerFilter; +import org.eclipse.jface.wizard.IWizardContainer; +import org.eclipse.jface.wizard.IWizardContainer2; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.CLabel; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; +import org.eclipse.ui.IWorkbenchWizard; +import org.eclipse.ui.activities.WorkbenchActivityHelper; +import org.eclipse.ui.dialogs.FilteredTree; +import org.eclipse.ui.internal.WorkbenchMessages; +import org.eclipse.ui.internal.dialogs.DialogUtil; +import org.eclipse.ui.internal.dialogs.WizardActivityFilter; +import org.eclipse.ui.internal.dialogs.WizardContentProvider; +import org.eclipse.ui.internal.dialogs.WizardPatternFilter; +import org.eclipse.ui.internal.dialogs.WizardTagFilter; +import org.eclipse.ui.internal.dialogs.WorkbenchWizardElement; +import org.eclipse.ui.internal.dialogs.WorkbenchWizardNode; +import org.eclipse.ui.model.AdaptableList; +import org.eclipse.ui.model.WorkbenchLabelProvider; +import org.eclipse.ui.wizards.IWizardCategory; +import org.eclipse.ui.wizards.IWizardDescriptor; + +/** + * New wizard selection tab that allows the user to select a registered 'New' wizard to be launched. + */ +class NewRepositoryWizardNewPage implements ISelectionChangedListener { + + // id constants + private static final String DIALOG_SETTING_SECTION_NAME = "NewWizardSelectionPage."; //$NON-NLS-1$ + + private final static int SIZING_LISTS_HEIGHT = 200; + + private final static int SIZING_VIEWER_WIDTH = 300; + + private final static String STORE_EXPANDED_CATEGORIES_ID = DIALOG_SETTING_SECTION_NAME + + "STORE_EXPANDED_CATEGORIES_ID"; //$NON-NLS-1$ + + private final static String STORE_SELECTED_ID = DIALOG_SETTING_SECTION_NAME + "STORE_SELECTED_ID"; //$NON-NLS-1$ + + private final NewRepositoryWizardSelectionPage page; + + private FilteredTree filteredTree; + + private WizardPatternFilter filteredTreeFilter; + + //Keep track of the wizards we have previously selected + private final Hashtable selectedWizards = new Hashtable(); + + private IDialogSettings settings; + + private Button showAllCheck; + + private IWizardCategory wizardCategories; + + private IWizardDescriptor[] primaryWizards; + + private CLabel descImageCanvas; + + private final Map imageTable = new HashMap(); + + private IWizardDescriptor selectedElement; + + private final WizardActivityFilter filter = new WizardActivityFilter(); + + private boolean needShowAll; + + private final boolean projectsOnly; + + private final ViewerFilter projectFilter = new WizardTagFilter(new String[] { WorkbenchWizardElement.TAG_PROJECT }); + + /** + * Create an instance of this class + * + * @param mainPage + * @param wizardCategories + * @param primaryWizards + * @param projectsOnly + */ + public NewRepositoryWizardNewPage(NewRepositoryWizardSelectionPage mainPage, IWizardCategory wizardCategories, + IWizardDescriptor[] primaryWizards, boolean projectsOnly) { + this.page = mainPage; + this.wizardCategories = wizardCategories; + this.primaryWizards = primaryWizards; + this.projectsOnly = projectsOnly; + + trimPrimaryWizards(); + + if (this.primaryWizards.length > 0) { + if (allPrimary(wizardCategories)) { + this.wizardCategories = null; // dont bother considering the categories as all wizards are primary + needShowAll = false; + } else { + needShowAll = !allActivityEnabled(wizardCategories); + } + } else { + needShowAll = !allActivityEnabled(wizardCategories); + } + } + + /** + * @param category + * the wizard category + * @return whether all of the wizards in the category are enabled via activity filtering + */ + private boolean allActivityEnabled(IWizardCategory category) { + IWizardDescriptor[] wizards = category.getWizards(); + for (IWizardDescriptor wizard : wizards) { + if (WorkbenchActivityHelper.filterItem(wizard)) { + return false; + } + } + + IWizardCategory[] children = category.getCategories(); + for (int i = 0; i < children.length; i++) { + if (!allActivityEnabled(children[i])) { + return false; + } + } + + return true; + } + + /** + * Remove all primary wizards that are not in the wizard collection + */ + private void trimPrimaryWizards() { + ArrayList newPrimaryWizards = new ArrayList(primaryWizards.length); + + if (wizardCategories == null) { + return;//No categories so nothing to trim + } + + for (IWizardDescriptor primaryWizard : primaryWizards) { + if (wizardCategories.findWizard(primaryWizard.getId()) != null) { + newPrimaryWizards.add(primaryWizard); + } + } + + primaryWizards = (WorkbenchWizardElement[]) newPrimaryWizards.toArray(new WorkbenchWizardElement[newPrimaryWizards.size()]); + } + + /** + * @param category + * the wizard category + * @return whether all wizards in the category are considered primary + */ + private boolean allPrimary(IWizardCategory category) { + IWizardDescriptor[] wizards = category.getWizards(); + for (IWizardDescriptor wizard2 : wizards) { + IWizardDescriptor wizard = wizard2; + if (!isPrimary(wizard)) { + return false; + } + } + + IWizardCategory[] children = category.getCategories(); + for (int i = 0; i < children.length; i++) { + if (!allPrimary(children[i])) { + return false; + } + } + + return true; + } + + /** + * @param wizard + * @return whether the given wizard is primary + */ + private boolean isPrimary(IWizardDescriptor wizard) { + for (IWizardDescriptor primaryWizard : primaryWizards) { + if (primaryWizard.equals(wizard)) { + return true; + } + } + + return false; + } + + /** + * @since 3.0 + */ + public void activate() { + page.setDescription(WorkbenchMessages.NewWizardNewPage_description); + } + + /** + * Create this tab's visual components + * + * @param parent + * Composite + * @return Control + */ + protected Control createControl(Composite parent) { + + Font wizardFont = parent.getFont(); + // top level group + Composite outerContainer = new Composite(parent, SWT.NONE); + GridLayout layout = new GridLayout(); + outerContainer.setLayout(layout); + + Label wizardLabel = new Label(outerContainer, SWT.NONE); + GridData data = new GridData(SWT.BEGINNING, SWT.FILL, false, true); + outerContainer.setLayoutData(data); + wizardLabel.setFont(wizardFont); + wizardLabel.setText(WorkbenchMessages.NewWizardNewPage_wizardsLabel); + + Composite innerContainer = new Composite(outerContainer, SWT.NONE); + layout = new GridLayout(2, false); + layout.marginHeight = 0; + layout.marginWidth = 0; + innerContainer.setLayout(layout); + innerContainer.setFont(wizardFont); + data = new GridData(SWT.FILL, SWT.FILL, true, true); + innerContainer.setLayoutData(data); + + filteredTree = createFilteredTree(innerContainer); + createOptionsButtons(innerContainer); + + createImage(innerContainer); + + updateDescription(null); + + // wizard actions pane...create SWT table directly to + // get single selection mode instead of multi selection. + restoreWidgetValues(); + + return outerContainer; + } + + /** + * Create a new FilteredTree in the parent. + * + * @param parent + * the parent <code>Composite</code>. + * @since 3.0 + */ + protected FilteredTree createFilteredTree(Composite parent) { + Composite composite = new Composite(parent, SWT.NONE); + GridLayout layout = new GridLayout(); + layout.marginHeight = 0; + layout.marginWidth = 0; + composite.setLayout(layout); + + GridData data = new GridData(SWT.FILL, SWT.FILL, true, true); + data.widthHint = SIZING_VIEWER_WIDTH; + data.horizontalSpan = 2; + data.grabExcessHorizontalSpace = true; + data.grabExcessVerticalSpace = true; + + boolean needsHint = DialogUtil.inRegularFontMode(parent); + + //Only give a height hint if the dialog is going to be too small + if (needsHint) { + data.heightHint = SIZING_LISTS_HEIGHT; + } + composite.setLayoutData(data); + + filteredTreeFilter = new WizardPatternFilter(); + FilteredTree filterTree = new FilteredTree(composite, SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER, + filteredTreeFilter, true); + + final TreeViewer treeViewer = filterTree.getViewer(); + treeViewer.setContentProvider(new WizardContentProvider()); + treeViewer.setLabelProvider(new WorkbenchLabelProvider()); + treeViewer.setComparator(NewWizardCollectionComparator.INSTANCE); + treeViewer.addSelectionChangedListener(this); + + ArrayList inputArray = new ArrayList(); + + for (IWizardDescriptor primaryWizard : primaryWizards) { + inputArray.add(primaryWizard); + } + + boolean expandTop = false; + + if (wizardCategories != null) { + if (wizardCategories.getParent() == null) { + IWizardCategory[] children = wizardCategories.getCategories(); + for (IWizardCategory element : children) { + inputArray.add(element); + } + } else { + expandTop = true; + inputArray.add(wizardCategories); + } + } + + // ensure the category is expanded. If there is a remembered expansion it will be set later. + if (expandTop) { + treeViewer.setAutoExpandLevel(2); + } + + AdaptableList input = new AdaptableList(inputArray); + + treeViewer.setInput(input); + + filterTree.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND)); + + treeViewer.getTree().setFont(parent.getFont()); + + treeViewer.addDoubleClickListener(new IDoubleClickListener() { + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.viewers.IDoubleClickListener#doubleClick(org.eclipse.jface.viewers.DoubleClickEvent) + */ + public void doubleClick(DoubleClickEvent event) { + IStructuredSelection s = (IStructuredSelection) event.getSelection(); + selectionChanged(new SelectionChangedEvent(event.getViewer(), s)); + + Object element = s.getFirstElement(); + if (treeViewer.isExpandable(element)) { + treeViewer.setExpandedState(element, !treeViewer.getExpandedState(element)); + } else if (element instanceof WorkbenchWizardElement) { + page.advanceToNextPageOrFinish(); + } + } + }); + + treeViewer.addFilter(filter); + + if (projectsOnly) { + treeViewer.addFilter(projectFilter); + } + + Dialog.applyDialogFont(filterTree); + return filterTree; + } + + /** + * Create the Show All and help buttons at the bottom of the page. + * + * @param parent + * the parent composite on which to create the widgets + */ + private void createOptionsButtons(Composite parent) { + if (needShowAll) { + showAllCheck = new Button(parent, SWT.CHECK); + GridData data = new GridData(); + showAllCheck.setLayoutData(data); + showAllCheck.setFont(parent.getFont()); + showAllCheck.setText(WorkbenchMessages.NewWizardNewPage_showAll); + showAllCheck.setSelection(false); + + // flipping tabs updates the selected node + showAllCheck.addSelectionListener(new SelectionAdapter() { + + // the delta of expanded elements between the last 'show all' + // and the current 'no show all' + private Object[] delta = new Object[0]; + + @Override + public void widgetSelected(SelectionEvent e) { + boolean showAll = showAllCheck.getSelection(); + + if (showAll) { + filteredTree.getViewer().getControl().setRedraw(false); + } else { + // get the inital expanded elements when going from show + // all-> no show all. + // this isnt really the delta yet, we're just reusing + // the variable. + delta = filteredTree.getViewer().getExpandedElements(); + } + + try { + if (showAll) { + filteredTree.getViewer().resetFilters(); + filteredTree.getViewer().addFilter(filteredTreeFilter); + if (projectsOnly) { + filteredTree.getViewer().addFilter(projectFilter); + } + + // restore the expanded elements that were present + // in the last show all state but not in the 'no + // show all' state. + Object[] currentExpanded = filteredTree.getViewer().getExpandedElements(); + Object[] expanded = new Object[delta.length + currentExpanded.length]; + System.arraycopy(currentExpanded, 0, expanded, 0, currentExpanded.length); + System.arraycopy(delta, 0, expanded, currentExpanded.length, delta.length); + filteredTree.getViewer().setExpandedElements(expanded); + } else { + filteredTree.getViewer().addFilter(filter); + if (projectsOnly) { + filteredTree.getViewer().addFilter(projectFilter); + } + } + filteredTree.getViewer().refresh(false); + + if (!showAll) { + // if we're going from show all -> no show all + // record the elements that were expanded in the + // 'show all' state but not the 'no show all' state + // (because they didnt exist). + Object[] newExpanded = filteredTree.getViewer().getExpandedElements(); + List deltaList = new ArrayList(Arrays.asList(delta)); + deltaList.removeAll(Arrays.asList(newExpanded)); + } + } finally { + if (showAll) { + filteredTree.getViewer().getControl().setRedraw(true); + } + } + } + }); + } + } + + /** + * Create the image controls. + * + * @param parent + * the parent <code>Composite</code>. + * @since 3.0 + */ + private void createImage(Composite parent) { + descImageCanvas = new CLabel(parent, SWT.NONE); + GridData data = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING | GridData.VERTICAL_ALIGN_BEGINNING); + data.widthHint = 0; + data.heightHint = 0; + descImageCanvas.setLayoutData(data); + + // hook a listener to get rid of cached images. + descImageCanvas.addDisposeListener(new DisposeListener() { + + /* (non-Javadoc) + * @see org.eclipse.swt.events.DisposeListener#widgetDisposed(org.eclipse.swt.events.DisposeEvent) + */ + public void widgetDisposed(DisposeEvent e) { + for (Iterator i = imageTable.values().iterator(); i.hasNext();) { + ((Image) i.next()).dispose(); + } + imageTable.clear(); + } + }); + } + + /** + * Expands the wizard categories in this page's category viewer that were expanded last time this page was used. If + * a category that was previously expanded no longer exists then it is ignored. + */ + protected void expandPreviouslyExpandedCategories() { + String[] expandedCategoryPaths = settings.getArray(STORE_EXPANDED_CATEGORIES_ID); + if (expandedCategoryPaths == null || expandedCategoryPaths.length == 0) { + return; + } + + List categoriesToExpand = new ArrayList(expandedCategoryPaths.length); + + if (wizardCategories != null) { + for (String expandedCategoryPath : expandedCategoryPaths) { + IWizardCategory category = wizardCategories.findCategory(new Path(expandedCategoryPath)); + if (category != null) { + categoriesToExpand.add(category); + } + } + } + + if (!categoriesToExpand.isEmpty()) { + filteredTree.getViewer().setExpandedElements(categoriesToExpand.toArray()); + } + + } + + /** + * Returns the single selected object contained in the passed selectionEvent, or <code>null</code> if the + * selectionEvent contains either 0 or 2+ selected objects. + */ + protected Object getSingleSelection(IStructuredSelection selection) { + return selection.size() == 1 ? selection.getFirstElement() : null; + } + + /** + * Set self's widgets to the values that they held last time this page was open + */ + protected void restoreWidgetValues() { + expandPreviouslyExpandedCategories(); + selectPreviouslySelected(); + } + + /** + * Store the current values of self's widgets so that they can be restored in the next instance of self + */ + public void saveWidgetValues() { + storeExpandedCategories(); + storeSelectedCategoryAndWizard(); + } + + /** + * The user selected either new wizard category(s) or wizard element(s). Proceed accordingly. + * + * @param selectionEvent + * ISelection + */ + public void selectionChanged(SelectionChangedEvent selectionEvent) { + page.setErrorMessage(null); + page.setMessage(null); + + Object selectedObject = getSingleSelection((IStructuredSelection) selectionEvent.getSelection()); + + if (selectedObject instanceof IWizardDescriptor) { + if (selectedObject == selectedElement) { + return; + } + updateWizardSelection((IWizardDescriptor) selectedObject); + } else { + selectedElement = null; + page.setHasPages(false); + page.setCanFinishEarly(false); + page.selectWizardNode(null); + updateDescription(null); + } + } + + /** + * Selects the wizard category and wizard in this page that were selected last time this page was used. If a + * category or wizard that was previously selected no longer exists then it is ignored. + */ + protected void selectPreviouslySelected() { + String selectedId = settings.get(STORE_SELECTED_ID); + if (selectedId == null) { + return; + } + + if (wizardCategories == null) { + return; + } + + Object selected = wizardCategories.findCategory(new Path(selectedId)); + + if (selected == null) { + selected = wizardCategories.findWizard(selectedId); + + if (selected == null) { + // if we cant find either a category or a wizard, abort. + return; + } + } + + //work around for 62039 + final StructuredSelection selection = new StructuredSelection(selected); + filteredTree.getViewer().getControl().getDisplay().asyncExec(new Runnable() { + public void run() { + filteredTree.getViewer().setSelection(selection, true); + } + }); + } + + /** + * Set the dialog store to use for widget value storage and retrieval + * + * @param settings + * IDialogSettings + */ + public void setDialogSettings(IDialogSettings settings) { + this.settings = settings; + } + + /** + * Stores the collection of currently-expanded categories in this page's dialog store, in order to recreate this + * page's state in the next instance of this page. + */ + protected void storeExpandedCategories() { + Object[] expandedElements = filteredTree.getViewer().getExpandedElements(); + List expandedElementPaths = new ArrayList(expandedElements.length); + for (int i = 0; i < expandedElements.length; ++i) { + if (expandedElements[i] instanceof IWizardCategory) { + expandedElementPaths.add(((IWizardCategory) expandedElements[i]).getPath().toString()); + } + } + settings.put(STORE_EXPANDED_CATEGORIES_ID, + (String[]) expandedElementPaths.toArray(new String[expandedElementPaths.size()])); + } + + /** + * Stores the currently-selected element in this page's dialog store, in order to recreate this page's state in the + * next instance of this page. + */ + protected void storeSelectedCategoryAndWizard() { + Object selected = getSingleSelection((IStructuredSelection) filteredTree.getViewer().getSelection()); + + if (selected != null) { + if (selected instanceof IWizardCategory) { + settings.put(STORE_SELECTED_ID, ((IWizardCategory) selected).getPath().toString()); + } else { + // else its a wizard + settings.put(STORE_SELECTED_ID, ((IWizardDescriptor) selected).getId()); + } + } + } + + /** + * Update the current description controls. + * + * @param selectedObject + * the new wizard + * @since 3.0 + */ + private void updateDescription(IWizardDescriptor selectedObject) { + String string = ""; //$NON-NLS-1$ + if (selectedObject != null) { + string = selectedObject.getDescription(); + } + + page.setDescription(string); + + if (hasImage(selectedObject)) { + ImageDescriptor descriptor = null; + if (selectedObject != null) { + descriptor = selectedObject.getDescriptionImage(); + } + + if (descriptor != null) { + GridData data = (GridData) descImageCanvas.getLayoutData(); + data.widthHint = SWT.DEFAULT; + data.heightHint = SWT.DEFAULT; + Image image = (Image) imageTable.get(descriptor); + if (image == null) { + image = descriptor.createImage(false); + imageTable.put(descriptor, image); + } + descImageCanvas.setImage(image); + } + } else { + GridData data = (GridData) descImageCanvas.getLayoutData(); + data.widthHint = 0; + data.heightHint = 0; + descImageCanvas.setImage(null); + } + + descImageCanvas.getParent().layout(true); + filteredTree.getViewer().getTree().showSelection(); + + IWizardContainer container = page.getWizard().getContainer(); + if (container instanceof IWizardContainer2) { + ((IWizardContainer2) container).updateSize(); + } + } + + /** + * Tests whether the given wizard has an associated image. + * + * @param selectedObject + * the wizard to test + * @return whether the given wizard has an associated image + */ + private boolean hasImage(IWizardDescriptor selectedObject) { + if (selectedObject == null) { + return false; + } + + if (selectedObject.getDescriptionImage() != null) { + return true; + } + + return false; + } + + /** + * @param selectedObject + */ + private void updateWizardSelection(IWizardDescriptor selectedObject) { + selectedElement = selectedObject; + WorkbenchWizardNode selectedNode; + if (selectedWizards.containsKey(selectedObject)) { + selectedNode = (WorkbenchWizardNode) selectedWizards.get(selectedObject); + } else { + selectedNode = new WorkbenchWizardNode(page, selectedObject) { + @Override + public IWorkbenchWizard createWizard() throws CoreException { + return wizardElement.createWizard(); + } + }; + selectedWizards.put(selectedObject, selectedNode); + } + + page.setCanFinishEarly(selectedObject.canFinishEarly()); + page.setHasPages(selectedObject.hasPages()); + page.selectWizardNode(selectedNode); + + updateDescription(selectedObject); + } +} diff --git a/stubs/org.eclipse.mylyn.commons.team/src/org/eclipse/mylyn/internal/commons/ui/team/wizards/NewRepositoryWizardRegistry.java b/stubs/org.eclipse.mylyn.commons.team/src/org/eclipse/mylyn/internal/commons/ui/team/wizards/NewRepositoryWizardRegistry.java new file mode 100644 index 00000000..2f8be744 --- /dev/null +++ b/stubs/org.eclipse.mylyn.commons.team/src/org/eclipse/mylyn/internal/commons/ui/team/wizards/NewRepositoryWizardRegistry.java @@ -0,0 +1,56 @@ +/******************************************************************************* + * Copyright (c) 2004, 2006 IBM Corporation 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: + * IBM Corporation - initial API and implementation + * Tasktop Technologies - improvements for Mylyn + *******************************************************************************/ + +package org.eclipse.mylyn.internal.commons.ui.team.wizards; + +import org.eclipse.mylyn.internal.commons.ui.team.TeamUiPlugin; +import org.eclipse.ui.internal.wizards.AbstractExtensionWizardRegistry; +import org.eclipse.ui.internal.wizards.NewWizardRegistry; + +/** + * Based on {@link NewWizardRegistry}. + * + * @author Steffen Pingel + */ +public final class NewRepositoryWizardRegistry extends AbstractExtensionWizardRegistry { + + private static NewRepositoryWizardRegistry singleton; + + /** + * Return the singleton instance of this class. + * + * @return the singleton instance of this class + */ + public static synchronized NewRepositoryWizardRegistry getInstance() { + if (singleton == null) { + singleton = new NewRepositoryWizardRegistry(); + } + return singleton; + } + + /** + * Private constructor. + */ + private NewRepositoryWizardRegistry() { + } + + @Override + protected String getExtensionPoint() { + return "newWizards"; //$NON-NLS-1$ + } + + @Override + protected String getPlugin() { + return TeamUiPlugin.ID_PLUGIN; + } + +} diff --git a/stubs/org.eclipse.mylyn.commons.team/src/org/eclipse/mylyn/internal/commons/ui/team/wizards/NewRepositoryWizardSelectionPage.java b/stubs/org.eclipse.mylyn.commons.team/src/org/eclipse/mylyn/internal/commons/ui/team/wizards/NewRepositoryWizardSelectionPage.java new file mode 100644 index 00000000..93833545 --- /dev/null +++ b/stubs/org.eclipse.mylyn.commons.team/src/org/eclipse/mylyn/internal/commons/ui/team/wizards/NewRepositoryWizardSelectionPage.java @@ -0,0 +1,146 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 IBM Corporation 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.mylyn.internal.commons.ui.team.wizards; + +import org.eclipse.jface.dialogs.IDialogSettings; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.wizard.WizardDialog; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.internal.IWorkbenchHelpContextIds; +import org.eclipse.ui.internal.WorkbenchMessages; +import org.eclipse.ui.internal.activities.ws.WorkbenchTriggerPoints; +import org.eclipse.ui.internal.dialogs.WorkbenchWizardSelectionPage; +import org.eclipse.ui.wizards.IWizardCategory; +import org.eclipse.ui.wizards.IWizardDescriptor; + +/** + * New wizard selection tab that allows the user to either select a registered 'New' wizard to be launched, or to select + * a solution or projects to be retrieved from an available server. This page contains two visual tabs that allow the + * user to perform these tasks. Temporarily has two inner pages. The new format page is used if the system is currently + * aware of activity categories. + */ +class NewRepositoryWizardSelectionPage extends WorkbenchWizardSelectionPage { + + private final IWizardCategory wizardCategories; + + // widgets + private NewRepositoryWizardNewPage newResourcePage; + + private final IWizardDescriptor[] primaryWizards; + + private final boolean projectsOnly; + + private boolean canFinishEarly = false, hasPages = true; + + /** + * Create an instance of this class. + * + * @param workbench + * the workbench + * @param selection + * the current selection + * @param root + * the wizard root element + * @param primary + * the primary wizard elements + * @param projectsOnly + * if only projects should be shown + */ + public NewRepositoryWizardSelectionPage(IWorkbench workbench, IStructuredSelection selection, IWizardCategory root, + IWizardDescriptor[] primary, boolean projectsOnly) { + super("newWizardSelectionPage", workbench, selection, null, WorkbenchTriggerPoints.NEW_WIZARDS);//$NON-NLS-1$ + + setTitle(WorkbenchMessages.NewWizardSelectionPage_description); + wizardCategories = root; + primaryWizards = primary; + this.projectsOnly = projectsOnly; + } + + /** + * Makes the next page visible. + */ + public void advanceToNextPageOrFinish() { + if (canFlipToNextPage()) { + getContainer().showPage(getNextPage()); + } else if (canFinishEarly()) { + if (getWizard().performFinish()) { + ((WizardDialog) getContainer()).close(); + } + } + } + + /** + * (non-Javadoc) Method declared on IDialogPage. + */ + public void createControl(Composite parent) { + IDialogSettings settings = getDialogSettings(); + newResourcePage = new NewRepositoryWizardNewPage(this, wizardCategories, primaryWizards, projectsOnly); + newResourcePage.setDialogSettings(settings); + + Control control = newResourcePage.createControl(parent); + getWorkbench().getHelpSystem().setHelp(control, IWorkbenchHelpContextIds.NEW_WIZARD_SELECTION_WIZARD_PAGE); + setControl(control); + } + + /** + * Since Finish was pressed, write widget values to the dialog store so that they will persist into the next + * invocation of this wizard page + */ + protected void saveWidgetValues() { + newResourcePage.saveWidgetValues(); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.wizard.IWizardPage#canFlipToNextPage() + */ + @Override + public boolean canFlipToNextPage() { + // if the current page advertises that it does have pages then ask it via the super call + if (hasPages) { + return super.canFlipToNextPage(); + } + return false; + } + + /** + * Sets whether the selected wizard advertises that it does provide pages. + * + * @param newValue + * whether the selected wizard has pages + * @since 3.1 + */ + public void setHasPages(boolean newValue) { + hasPages = newValue; + } + + /** + * Sets whether the selected wizard advertises that it can finish early. + * + * @param newValue + * whether the selected wizard can finish early + * @since 3.1 + */ + public void setCanFinishEarly(boolean newValue) { + canFinishEarly = newValue; + } + + /** + * Answers whether the currently selected page, if any, advertises that it may finish early. + * + * @return whether the page can finish early + * @since 3.1 + */ + public boolean canFinishEarly() { + return canFinishEarly; + } +} |