Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
View | Details | Raw Unified | Return to bug 244653 | Differences between
and this patch

Collapse All | Expand All

(-)src/org/eclipse/mylyn/internal/tasks/ui/wizards/EditRepositoryWizard.java (-2 / +5 lines)
Lines 15-20 Link Here
15
import org.eclipse.jface.viewers.IStructuredSelection;
15
import org.eclipse.jface.viewers.IStructuredSelection;
16
import org.eclipse.jface.wizard.Wizard;
16
import org.eclipse.jface.wizard.Wizard;
17
import org.eclipse.mylyn.commons.core.StatusHandler;
17
import org.eclipse.mylyn.commons.core.StatusHandler;
18
import org.eclipse.mylyn.internal.tasks.core.LocalRepositoryConnector;
18
import org.eclipse.mylyn.internal.tasks.ui.RefactorRepositoryUrlOperation;
19
import org.eclipse.mylyn.internal.tasks.ui.RefactorRepositoryUrlOperation;
19
import org.eclipse.mylyn.internal.tasks.ui.TasksUiPlugin;
20
import org.eclipse.mylyn.internal.tasks.ui.TasksUiPlugin;
20
import org.eclipse.mylyn.tasks.core.TaskRepository;
21
import org.eclipse.mylyn.tasks.core.TaskRepository;
Lines 68-74 Link Here
68
69
69
			repository.flushAuthenticationCredentials();
70
			repository.flushAuthenticationCredentials();
70
71
71
			repository.setRepositoryUrl(newUrl);
72
			if (!repository.getConnectorKind().equals(LocalRepositoryConnector.CONNECTOR_KIND)) {
73
				repository.setRepositoryUrl(newUrl);
74
			}
72
			settingsPage.applyTo(repository);
75
			settingsPage.applyTo(repository);
73
			if (oldUrl != null && newUrl != null && !oldUrl.equals(newUrl)) {
76
			if (oldUrl != null && newUrl != null && !oldUrl.equals(newUrl)) {
74
				TasksUiPlugin.getRepositoryManager().notifyRepositoryUrlChanged(repository, oldUrl);
77
				TasksUiPlugin.getRepositoryManager().notifyRepositoryUrlChanged(repository, oldUrl);
Lines 86-92 Link Here
86
	@Override
89
	@Override
87
	public void addPages() {
90
	public void addPages() {
88
		AbstractRepositoryConnectorUi connectorUi = TasksUiPlugin.getConnectorUi(repository.getConnectorKind());
91
		AbstractRepositoryConnectorUi connectorUi = TasksUiPlugin.getConnectorUi(repository.getConnectorKind());
89
		settingsPage = connectorUi.getSettingsPage(null);
92
		settingsPage = connectorUi.getSettingsPage(repository);
90
		if (settingsPage instanceof AbstractRepositorySettingsPage) {
93
		if (settingsPage instanceof AbstractRepositorySettingsPage) {
91
			((AbstractRepositorySettingsPage) settingsPage).setRepository(repository);
94
			((AbstractRepositorySettingsPage) settingsPage).setRepository(repository);
92
			((AbstractRepositorySettingsPage) settingsPage).setVersion(repository.getVersion());
95
			((AbstractRepositorySettingsPage) settingsPage).setVersion(repository.getVersion());
(-)plugin.xml (+1 lines)
Lines 7-12 Link Here
7
    <extension-point id="projectLinkProviders" name="Linking Provider from Project to the Task Repository" schema="schema/projectLinkProviders.exsd"/>
7
    <extension-point id="projectLinkProviders" name="Linking Provider from Project to the Task Repository" schema="schema/projectLinkProviders.exsd"/>
8
    <extension-point id="duplicateDetectors" name="duplicateDetectors" schema="schema/duplicateDetectors.exsd"/>
8
    <extension-point id="duplicateDetectors" name="duplicateDetectors" schema="schema/duplicateDetectors.exsd"/>
9
    <extension-point id="presentations" name="presentations" schema="schema/presentations.exsd"/>
9
    <extension-point id="presentations" name="presentations" schema="schema/presentations.exsd"/>
10
    <extension-point id="taskRepositoryPageContributor" name="Task Repository Page Contributor" schema="schema/taskRepositoryPageContributor.exsd"/>
10
11
11
    <extension
12
    <extension
12
          point="org.eclipse.mylyn.context.core.bridges">
13
          point="org.eclipse.mylyn.context.core.bridges">
(-)src/org/eclipse/mylyn/internal/tasks/ui/LocalRepositoryConnectorUi.java (-1 / +2 lines)
Lines 11-16 Link Here
11
import org.eclipse.jface.resource.ImageDescriptor;
11
import org.eclipse.jface.resource.ImageDescriptor;
12
import org.eclipse.jface.wizard.IWizard;
12
import org.eclipse.jface.wizard.IWizard;
13
import org.eclipse.mylyn.internal.tasks.core.LocalRepositoryConnector;
13
import org.eclipse.mylyn.internal.tasks.core.LocalRepositoryConnector;
14
import org.eclipse.mylyn.internal.tasks.ui.wizards.LocalRepositorySettingsPage;
14
import org.eclipse.mylyn.internal.tasks.ui.wizards.NewLocalTaskWizard;
15
import org.eclipse.mylyn.internal.tasks.ui.wizards.NewLocalTaskWizard;
15
import org.eclipse.mylyn.tasks.core.IRepositoryQuery;
16
import org.eclipse.mylyn.tasks.core.IRepositoryQuery;
16
import org.eclipse.mylyn.tasks.core.ITask;
17
import org.eclipse.mylyn.tasks.core.ITask;
Lines 47-53 Link Here
47
48
48
	@Override
49
	@Override
49
	public ITaskRepositoryPage getSettingsPage(TaskRepository taskRepository) {
50
	public ITaskRepositoryPage getSettingsPage(TaskRepository taskRepository) {
50
		return null;
51
		return new LocalRepositorySettingsPage(taskRepository);
51
	}
52
	}
52
53
53
	@Override
54
	@Override
(-)src/org/eclipse/mylyn/tasks/ui/wizards/ITaskRepositoryPageContributor.java (+28 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2004, 2008 Mylyn project committers and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *******************************************************************************/
8
9
package org.eclipse.mylyn.tasks.ui.wizards;
10
11
import org.eclipse.mylyn.tasks.core.TaskRepository;
12
13
/**
14
 * Implementors are capable of contributing to the settings page for a task repository.
15
 * 
16
 * @author David Green
17
 */
18
public interface ITaskRepositoryPageContributor {
19
	/**
20
	 * create a contribution to a task repository
21
	 * 
22
	 * @param repository
23
	 *            the repository for which contributions are desired
24
	 * 
25
	 * @return the contribution, or null if the contributor should not contribute to the given repository
26
	 */
27
	ITaskRepositoryPageContribution createContribution(TaskRepository repository);
28
}
(-)src/org/eclipse/mylyn/tasks/ui/wizards/AbstractTaskRepositoryPageContribution.java (+53 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2004, 2007 Mylyn project committers and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *******************************************************************************/
8
9
package org.eclipse.mylyn.tasks.ui.wizards;
10
11
import java.util.List;
12
import java.util.concurrent.CopyOnWriteArrayList;
13
14
import org.eclipse.mylyn.tasks.core.TaskRepository;
15
16
public abstract class AbstractTaskRepositoryPageContribution implements ITaskRepositoryPageContribution {
17
18
	private final List<Listener> listeners = new CopyOnWriteArrayList<Listener>();
19
20
	private final String title;
21
22
	private final String description;
23
24
	protected final TaskRepository repository;
25
26
	protected AbstractTaskRepositoryPageContribution(String title, String description, TaskRepository repository) {
27
		this.title = title;
28
		this.description = description;
29
		this.repository = repository;
30
	}
31
32
	public void addListener(Listener listener) {
33
		listeners.add(listener);
34
	}
35
36
	public String getDescription() {
37
		return description;
38
	}
39
40
	public String getTitle() {
41
		return title;
42
	}
43
44
	public void removeListener(Listener listener) {
45
		listeners.remove(listener);
46
	}
47
48
	protected void fireValidationRequired() {
49
		for (Listener l : listeners) {
50
			l.validationRequired(this);
51
		}
52
	}
53
}
(-)src/org/eclipse/mylyn/tasks/ui/wizards/ITaskRepositoryPageContribution.java (+99 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2004, 2008 Mylyn project committers and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *******************************************************************************/
8
9
package org.eclipse.mylyn.tasks.ui.wizards;
10
11
import org.eclipse.core.runtime.IProgressMonitor;
12
import org.eclipse.core.runtime.IStatus;
13
import org.eclipse.jface.dialogs.IDialogPage;
14
import org.eclipse.jface.wizard.IWizardPage;
15
import org.eclipse.mylyn.tasks.core.TaskRepository;
16
import org.eclipse.swt.widgets.Composite;
17
import org.eclipse.ui.forms.widgets.FormToolkit;
18
19
/**
20
 * A contribution to a {@link ITaskRepositoryPage}
21
 * 
22
 * @see ITaskRepositoryPageContributor
23
 * 
24
 * @author David Green
25
 */
26
public interface ITaskRepositoryPageContribution {
27
	/**
28
	 * a listener interface that should be implemented by classes wishing to be notified of changes that occur within
29
	 * the contribution
30
	 */
31
	public interface Listener {
32
		/**
33
		 * Called when the state of the contribution changes such that validation should be performed
34
		 * 
35
		 * @param contribution
36
		 *            the contribution that changed
37
		 * 
38
		 * @see ITaskRepositoryPageContribution#validate(IProgressMonitor)
39
		 */
40
		public void validationRequired(ITaskRepositoryPageContribution contribution);
41
	}
42
43
	/**
44
	 * add a listener to this contribution. The contribution must notify the listener at the appropriate times
45
	 * 
46
	 * @see #removeListener(Listener)
47
	 */
48
	public void addListener(Listener listener);
49
50
	/**
51
	 * remove a listener from this contribution.
52
	 * 
53
	 * @see #addListener(Listener)
54
	 */
55
	public void removeListener(Listener listener);
56
57
	/**
58
	 * @see IDialogPage#createControl(Composite)
59
	 */
60
	public void createControl(Composite parent, FormToolkit toolkit);
61
62
	/**
63
	 * @see IDialogPage#getTitle()
64
	 */
65
	public String getTitle();
66
67
	/**
68
	 * @see IDialogPage#getDescription()
69
	 */
70
	public String getDescription();
71
72
	/**
73
	 * @see IWizardPage#isPageComplete()
74
	 */
75
	public boolean isPageComplete();
76
77
	/**
78
	 * @see IWizardPage#canFlipToNextPage()
79
	 */
80
	public boolean canFlipToNextPage();
81
82
	/**
83
	 * Validate the settings of the contribution. Contributions should expect this method to be called often and should
84
	 * thus return quickly.
85
	 * 
86
	 * @return a list of errors on the contribution, or null if there are none
87
	 */
88
	public IStatus[] validate(IProgressMonitor monitor);
89
90
	/**
91
	 * Apply the settings in the contribution to the given repository.
92
	 * 
93
	 * @param repository
94
	 *            the repository to which settings should be applied
95
	 * 
96
	 * @see ITaskRepositoryPage#applyTo(TaskRepository)
97
	 */
98
	public void applyTo(TaskRepository repository);
99
}
(-)src/org/eclipse/mylyn/internal/tasks/ui/wizards/LocalRepositorySettingsPage.java (+42 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2004, 2008 Mylyn project committers and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *******************************************************************************/
8
9
package org.eclipse.mylyn.internal.tasks.ui.wizards;
10
11
import org.eclipse.core.runtime.IProgressMonitor;
12
import org.eclipse.core.runtime.IStatus;
13
import org.eclipse.mylyn.tasks.core.TaskRepository;
14
import org.eclipse.swt.widgets.Composite;
15
16
public class LocalRepositorySettingsPage extends AbstractExtensibleRepositorySettingsPage {
17
18
	public LocalRepositorySettingsPage(TaskRepository taskRepository) {
19
		super("Local Repository Settings", "Configure the local repository", taskRepository);
20
	}
21
22
	public String getRepositoryUrl() {
23
		return null;
24
	}
25
26
	@Override
27
	protected void applyPageSettingsTo(TaskRepository repository) {
28
		// nothing to do
29
	}
30
31
	@Override
32
	protected void createSettingControls(Composite parent) {
33
		// nothing to do
34
	}
35
36
	@Override
37
	protected IStatus[] validate(IProgressMonitor monitor) {
38
		// nothing to do
39
		return null;
40
	}
41
42
}
(-)schema/taskRepositoryPageContributor.exsd (+109 lines)
Added Link Here
1
<?xml version='1.0' encoding='UTF-8'?>
2
<!-- Schema file written by PDE -->
3
<schema targetNamespace="org.eclipse.mylyn.tasks.ui" xmlns="http://www.w3.org/2001/XMLSchema">
4
<annotation>
5
      <appinfo>
6
         <meta.schema plugin="org.eclipse.mylyn.tasks.ui" id="taskRepositoryPageContributor" name="Task Repository Page Contributor"/>
7
      </appinfo>
8
      <documentation>
9
         [Enter description of this extension point.]
10
      </documentation>
11
   </annotation>
12
13
   <element name="extension">
14
      <annotation>
15
         <appinfo>
16
            <meta.element />
17
         </appinfo>
18
      </annotation>
19
      <complexType>
20
         <sequence>
21
            <element ref="taskRepositoryPageContributor" minOccurs="1" maxOccurs="unbounded"/>
22
         </sequence>
23
         <attribute name="point" type="string" use="required">
24
            <annotation>
25
               <documentation>
26
                  
27
               </documentation>
28
            </annotation>
29
         </attribute>
30
         <attribute name="id" type="string">
31
            <annotation>
32
               <documentation>
33
                  
34
               </documentation>
35
            </annotation>
36
         </attribute>
37
         <attribute name="name" type="string">
38
            <annotation>
39
               <documentation>
40
                  
41
               </documentation>
42
               <appinfo>
43
                  <meta.attribute translatable="true"/>
44
               </appinfo>
45
            </annotation>
46
         </attribute>
47
      </complexType>
48
   </element>
49
50
   <element name="taskRepositoryPageContributor">
51
      <complexType>
52
         <attribute name="class" type="string" use="required">
53
            <annotation>
54
               <documentation>
55
                  
56
               </documentation>
57
               <appinfo>
58
                  <meta.attribute kind="java" basedOn=":org.eclipse.mylyn.tasks.ui.wizards.ITaskRepositoryPageContributor"/>
59
               </appinfo>
60
            </annotation>
61
         </attribute>
62
         <attribute name="connectorKind" type="string" use="required">
63
            <annotation>
64
               <documentation>
65
                  the kind of repository connector for which this contributor should be used, or &quot;*&quot; if it applies to all connectors
66
               </documentation>
67
            </annotation>
68
         </attribute>
69
      </complexType>
70
   </element>
71
72
   <annotation>
73
      <appinfo>
74
         <meta.section type="since"/>
75
      </appinfo>
76
      <documentation>
77
         [Enter the first release in which this extension point appears.]
78
      </documentation>
79
   </annotation>
80
81
   <annotation>
82
      <appinfo>
83
         <meta.section type="examples"/>
84
      </appinfo>
85
      <documentation>
86
         [Enter extension point usage example here.]
87
      </documentation>
88
   </annotation>
89
90
   <annotation>
91
      <appinfo>
92
         <meta.section type="apiinfo"/>
93
      </appinfo>
94
      <documentation>
95
         [Enter API information here.]
96
      </documentation>
97
   </annotation>
98
99
   <annotation>
100
      <appinfo>
101
         <meta.section type="implementation"/>
102
      </appinfo>
103
      <documentation>
104
         [Enter information about supplied implementation of this extension point.]
105
      </documentation>
106
   </annotation>
107
108
109
</schema>
(-)src/org/eclipse/mylyn/internal/tasks/ui/wizards/AbstractExtensibleRepositorySettingsPage.java (+327 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2004, 2008 Mylyn project committers and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *******************************************************************************/
8
9
package org.eclipse.mylyn.internal.tasks.ui.wizards;
10
11
import java.lang.reflect.InvocationTargetException;
12
import java.util.ArrayList;
13
import java.util.Arrays;
14
import java.util.Collections;
15
import java.util.Comparator;
16
import java.util.List;
17
18
import org.eclipse.core.runtime.IConfigurationElement;
19
import org.eclipse.core.runtime.IExtension;
20
import org.eclipse.core.runtime.IExtensionPoint;
21
import org.eclipse.core.runtime.IExtensionRegistry;
22
import org.eclipse.core.runtime.IProgressMonitor;
23
import org.eclipse.core.runtime.IStatus;
24
import org.eclipse.core.runtime.Platform;
25
import org.eclipse.core.runtime.Status;
26
import org.eclipse.core.runtime.SubProgressMonitor;
27
import org.eclipse.jface.dialogs.IMessageProvider;
28
import org.eclipse.jface.layout.GridDataFactory;
29
import org.eclipse.jface.operation.IRunnableWithProgress;
30
import org.eclipse.jface.wizard.WizardPage;
31
import org.eclipse.mylyn.commons.core.StatusHandler;
32
import org.eclipse.mylyn.internal.tasks.ui.TasksUiPlugin;
33
import org.eclipse.mylyn.tasks.core.TaskRepository;
34
import org.eclipse.mylyn.tasks.ui.wizards.ITaskRepositoryPage;
35
import org.eclipse.mylyn.tasks.ui.wizards.ITaskRepositoryPageContribution;
36
import org.eclipse.mylyn.tasks.ui.wizards.ITaskRepositoryPageContributor;
37
import org.eclipse.mylyn.tasks.ui.wizards.ITaskRepositoryPageContribution.Listener;
38
import org.eclipse.swt.SWT;
39
import org.eclipse.swt.layout.GridLayout;
40
import org.eclipse.swt.widgets.Composite;
41
import org.eclipse.ui.forms.events.ExpansionAdapter;
42
import org.eclipse.ui.forms.events.ExpansionEvent;
43
import org.eclipse.ui.forms.widgets.ExpandableComposite;
44
import org.eclipse.ui.forms.widgets.FormToolkit;
45
46
public abstract class AbstractExtensibleRepositorySettingsPage extends WizardPage implements ITaskRepositoryPage {
47
48
	private static final String KIND = "connectorKind";
49
50
	private static final String TASK_REPOSITORY_PAGE_CONTRIBUTOR = "taskRepositoryPageContributor";
51
52
	private static final String TASK_REPOSITORY_PAGE_CONTRIBUTOR_EXTENSION = "org.eclipse.mylyn.tasks.ui.taskRepositoryPageContributor";
53
54
	private static final Comparator<ITaskRepositoryPageContribution> CONTRIBUTION_COMPARATOR = new ContributionComparator();
55
56
	protected final TaskRepository repository;
57
58
	private final List<ITaskRepositoryPageContribution> contributions = new ArrayList<ITaskRepositoryPageContribution>();
59
60
	protected FormToolkit toolkit;
61
62
	protected Composite compositeContainer;
63
64
	private final Listener contributionListener = new ITaskRepositoryPageContribution.Listener() {
65
		public void validationRequired(ITaskRepositoryPageContribution contribution) {
66
			validateSettings();
67
		}
68
	};
69
70
	public AbstractExtensibleRepositorySettingsPage(String title, String description, TaskRepository repository) {
71
		super(title);
72
		this.repository = repository;
73
		setTitle(title);
74
		setDescription(description);
75
	}
76
77
	public void createControl(Composite parent) {
78
		toolkit = new FormToolkit(TasksUiPlugin.getDefault().getFormColors(parent.getDisplay()));
79
80
		compositeContainer = new Composite(parent, SWT.NULL);
81
		GridLayout layout = new GridLayout(1, true);
82
		compositeContainer.setLayout(layout);
83
84
		createSettingControls(compositeContainer);
85
86
		addContributions(compositeContainer);
87
88
		setControl(compositeContainer);
89
	}
90
91
	/**
92
	 * create the controls of this page
93
	 */
94
	protected abstract void createSettingControls(Composite parent);
95
96
	@Override
97
	public boolean isPageComplete() {
98
		return super.isPageComplete() && conributionsIsPageComplete();
99
	}
100
101
	@Override
102
	public boolean canFlipToNextPage() {
103
		return super.canFlipToNextPage() && contributionsCanFlipToNextPage();
104
	}
105
106
	private boolean contributionsCanFlipToNextPage() {
107
		for (ITaskRepositoryPageContribution contribution : contributions) {
108
			if (!contribution.canFlipToNextPage()) {
109
				return false;
110
			}
111
		}
112
		return true;
113
	}
114
115
	private boolean conributionsIsPageComplete() {
116
		for (ITaskRepositoryPageContribution contribution : contributions) {
117
			if (!contribution.isPageComplete()) {
118
				return false;
119
			}
120
		}
121
		return true;
122
	}
123
124
	protected void addContributions(Composite parentControl) {
125
		List<ITaskRepositoryPageContributor> contributors = findApplicableContributors();
126
		for (ITaskRepositoryPageContributor contributor : contributors) {
127
			ITaskRepositoryPageContribution contribution = contributor.createContribution(repository);
128
			if (contribution != null) {
129
				contributions.add(contribution);
130
				contribution.addListener(contributionListener);
131
			}
132
		}
133
		if (!contributions.isEmpty()) {
134
			Collections.sort(contributions, CONTRIBUTION_COMPARATOR);
135
136
			for (ITaskRepositoryPageContribution contribution : contributions) {
137
138
				ExpandableComposite section = toolkit.createExpandableComposite(compositeContainer,
139
						ExpandableComposite.COMPACT | ExpandableComposite.TWISTIE | ExpandableComposite.TITLE_BAR);
140
				section.clientVerticalSpacing = 0;
141
				section.setBackground(parentControl.getBackground());
142
				section.setFont(parentControl.getFont());
143
				section.addExpansionListener(new ExpansionAdapter() {
144
					@Override
145
					public void expansionStateChanged(ExpansionEvent e) {
146
						getControl().getShell().pack();
147
					}
148
				});
149
				section.setText(contribution.getTitle());
150
				section.setToolTipText(contribution.getDescription());
151
152
				GridDataFactory.fillDefaults().grab(true, false).applyTo(section);
153
154
				Composite sectionContentsContainer = toolkit.createComposite(section);
155
				sectionContentsContainer.setBackground(parentControl.getBackground());
156
				contribution.createControl(sectionContentsContainer, toolkit);
157
158
				section.setClient(sectionContentsContainer);
159
			}
160
		}
161
	}
162
163
	/**
164
	 * Validate the settings of this page, not including contributions. This method should not be called directly by
165
	 * page implementations
166
	 * 
167
	 * @return an array of statuses, or null if there are no messages.
168
	 * 
169
	 * @see #validateSettings()
170
	 */
171
	protected abstract IStatus[] validate(IProgressMonitor monitor);
172
173
	public final void applyTo(TaskRepository repository) {
174
		applyPageSettingsTo(repository);
175
		applyContributionSettingsTo(repository);
176
	}
177
178
	private void applyContributionSettingsTo(TaskRepository repository) {
179
		for (ITaskRepositoryPageContribution contribution : contributions) {
180
			contribution.applyTo(repository);
181
		}
182
	}
183
184
	/**
185
	 * apply the page settings to the repository.
186
	 * 
187
	 * @see ITaskRepositoryPage#applyTo(TaskRepository)
188
	 */
189
	protected abstract void applyPageSettingsTo(TaskRepository repository);
190
191
	private IStatus[] computeValidation(IProgressMonitor monitor) {
192
		int factor = 100;
193
		monitor.beginTask("Validating settings", (contributions.size() + 1) * factor);
194
195
		List<IStatus> statuses = null;
196
197
		// validate the page
198
		{
199
			SubProgressMonitor subMonitor = new SubProgressMonitor(monitor, factor);
200
			IStatus[] result = validate(subMonitor);
201
			if (result != null && result.length > 0) {
202
				if (statuses == null) {
203
					statuses = new ArrayList<IStatus>(result.length);
204
				}
205
				statuses.addAll(Arrays.asList(result));
206
			}
207
			subMonitor.done();
208
		}
209
210
		// validate contributions
211
		for (ITaskRepositoryPageContribution contribution : contributions) {
212
			SubProgressMonitor subMonitor = new SubProgressMonitor(monitor, factor);
213
			IStatus[] result = contribution.validate(subMonitor);
214
			if (result != null && result.length > 0) {
215
				if (statuses == null) {
216
					statuses = new ArrayList<IStatus>(result.length);
217
				}
218
				statuses.addAll(Arrays.asList(result));
219
			}
220
			subMonitor.done();
221
		}
222
		monitor.done();
223
		return statuses == null ? null : statuses.toArray(new IStatus[statuses.size()]);
224
	}
225
226
	/**
227
	 * Validate all settings in the page including contributions. This method should be called whenever a setting is
228
	 * changed on the page.
229
	 * 
230
	 * @see #validate(IProgressMonitor)
231
	 */
232
	protected void validateSettings() {
233
		final Object[] result = new Object[1];
234
		try {
235
			getWizard().getContainer().run(true, true, new IRunnableWithProgress() {
236
				public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
237
					result[0] = computeValidation(monitor);
238
				}
239
			});
240
		} catch (InvocationTargetException e) {
241
			StatusHandler.fail(new Status(IStatus.ERROR, TasksUiPlugin.ID_PLUGIN,
242
					"Internal error validating repository", e.getCause()));
243
			return;
244
		} catch (InterruptedException e) {
245
			// canceled
246
			return;
247
		}
248
		applyValidationResult((IStatus[]) result[0]);
249
		getWizard().getContainer().updateButtons();
250
	}
251
252
	protected void applyValidationResult(IStatus[] statuses) {
253
		if (statuses == null || statuses.length == 0) {
254
			setMessage(null, IMessageProvider.INFORMATION);
255
			setErrorMessage(null);
256
		} else {
257
			// find the most severe status
258
			IStatus status = statuses[0];
259
			for (IStatus s : statuses) {
260
				if (status == null || s.getSeverity() > status.getSeverity()) {
261
					status = s;
262
				}
263
			}
264
			int messageType;
265
			switch (status.getSeverity()) {
266
			case IStatus.OK:
267
			case IStatus.INFO:
268
				messageType = IMessageProvider.INFORMATION;
269
				break;
270
			case IStatus.WARNING:
271
				messageType = IMessageProvider.WARNING;
272
				break;
273
			case IStatus.ERROR:
274
			default:
275
				messageType = IMessageProvider.ERROR;
276
				break;
277
			}
278
			setErrorMessage(null);
279
			setMessage(status.getMessage(), messageType);
280
		}
281
	}
282
283
	private List<ITaskRepositoryPageContributor> findApplicableContributors() {
284
		List<ITaskRepositoryPageContributor> contributors = new ArrayList<ITaskRepositoryPageContributor>();
285
286
		IExtensionRegistry registry = Platform.getExtensionRegistry();
287
288
		IExtensionPoint editorExtensionPoint = registry.getExtensionPoint(TASK_REPOSITORY_PAGE_CONTRIBUTOR_EXTENSION);
289
		IExtension[] editorExtensions = editorExtensionPoint.getExtensions();
290
		for (IExtension extension : editorExtensions) {
291
			IConfigurationElement[] elements = extension.getConfigurationElements();
292
			for (IConfigurationElement element : elements) {
293
				if (element.getName().equals(TASK_REPOSITORY_PAGE_CONTRIBUTOR)) {
294
					String kind = element.getAttribute(KIND);
295
					if ("*".equals(kind) || repository.getConnectorKind().equals(kind)) {
296
						try {
297
							Object contributor = element.createExecutableExtension("class");
298
							contributors.add((ITaskRepositoryPageContributor) contributor);
299
						} catch (Exception e) {
300
							StatusHandler.log(new Status(IStatus.ERROR, TasksUiPlugin.ID_PLUGIN, "Could not load "
301
									+ TASK_REPOSITORY_PAGE_CONTRIBUTOR, e));
302
						}
303
					}
304
				}
305
			}
306
		}
307
308
		return contributors;
309
	}
310
311
	private static class ContributionComparator implements Comparator<ITaskRepositoryPageContribution> {
312
313
		public int compare(ITaskRepositoryPageContribution o1, ITaskRepositoryPageContribution o2) {
314
			if (o1 == o2) {
315
				return 0;
316
			}
317
			String s1 = o1.getTitle();
318
			String s2 = o2.getTitle();
319
			int i = s1.compareTo(s2);
320
			if (i == 0) {
321
				i = new Integer(System.identityHashCode(s1)).compareTo(System.identityHashCode(s2));
322
			}
323
			return i;
324
		}
325
326
	}
327
}
(-)plugin.xml (+7 lines)
Lines 450-455 Link Here
450
                 name="View Source">
450
                 name="View Source">
451
           </command>
451
           </command>
452
        </extension>
452
        </extension>
453
        <extension
454
              point="org.eclipse.mylyn.tasks.ui.taskRepositoryPageContributor">
455
           <taskRepositoryPageContributor
456
                 class="org.eclipse.mylyn.internal.sandbox.ui.wizards.TaskEditorExtensionSettingsContributor"
457
                 connectorKind="*">
458
           </taskRepositoryPageContributor>
459
        </extension>
453
   <!--
460
   <!--
454
   <extension point="org.eclipse.mylyn.tasks.ui.presentations">
461
   <extension point="org.eclipse.mylyn.tasks.ui.presentations">
455
      <presentation 
462
      <presentation 
(-)src/org/eclipse/mylyn/internal/sandbox/ui/wizards/TaskEditorExtensionSettingsContributor.java (+31 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2004, 2008 Mylyn project committers and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *******************************************************************************/
8
9
package org.eclipse.mylyn.internal.sandbox.ui.wizards;
10
11
import org.eclipse.mylyn.tasks.core.TaskRepository;
12
import org.eclipse.mylyn.tasks.ui.wizards.ITaskRepositoryPageContribution;
13
import org.eclipse.mylyn.tasks.ui.wizards.ITaskRepositoryPageContributor;
14
15
/**
16
 * A contributor that adds {@link TaskEditorExtensionSettingsContribution} to all repositories
17
 * 
18
 * @see TaskEditorExtensionSettingsContribution
19
 * 
20
 * @author David Green
21
 */
22
public class TaskEditorExtensionSettingsContributor implements ITaskRepositoryPageContributor {
23
24
	public TaskEditorExtensionSettingsContributor() {
25
	}
26
27
	public ITaskRepositoryPageContribution createContribution(TaskRepository repository) {
28
		return new TaskEditorExtensionSettingsContribution(repository);
29
	}
30
31
}
(-)src/org/eclipse/mylyn/internal/sandbox/ui/wizards/TaskEditorExtensionSettingsContribution.java (+155 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2004, 2007 Mylyn project committers and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *******************************************************************************/
8
9
package org.eclipse.mylyn.internal.sandbox.ui.wizards;
10
11
import java.util.SortedSet;
12
13
import org.eclipse.core.runtime.IProgressMonitor;
14
import org.eclipse.core.runtime.IStatus;
15
import org.eclipse.jface.resource.FontRegistry;
16
import org.eclipse.jface.resource.JFaceResources;
17
import org.eclipse.mylyn.internal.sandbox.ui.editors.TaskEditorExtensions;
18
import org.eclipse.mylyn.internal.sandbox.ui.editors.TaskEditorExtensions.RegisteredTaskEditorExtension;
19
import org.eclipse.mylyn.tasks.core.TaskRepository;
20
import org.eclipse.mylyn.tasks.ui.wizards.AbstractTaskRepositoryPageContribution;
21
import org.eclipse.swt.SWT;
22
import org.eclipse.swt.events.SelectionAdapter;
23
import org.eclipse.swt.events.SelectionEvent;
24
import org.eclipse.swt.events.SelectionListener;
25
import org.eclipse.swt.graphics.Font;
26
import org.eclipse.swt.graphics.FontData;
27
import org.eclipse.swt.layout.GridLayout;
28
import org.eclipse.swt.widgets.Button;
29
import org.eclipse.swt.widgets.Composite;
30
import org.eclipse.swt.widgets.Widget;
31
import org.eclipse.ui.forms.widgets.FormToolkit;
32
33
/**
34
 * A contribution that adds a section for 'Task Editor Extension'.
35
 * 
36
 * @author David Green
37
 */
38
public class TaskEditorExtensionSettingsContribution extends AbstractTaskRepositoryPageContribution {
39
40
	private static final String LABEL_NONE = "None";
41
42
	private static final String LABEL_DEFAULT_SUFFIX = " (default)";
43
44
	private static final String DATA_EDITOR_EXTENSION = "editorExtension";
45
46
	private final SelectionListener listener = new SelectionAdapter() {
47
		@Override
48
		public void widgetSelected(SelectionEvent e) {
49
			selectedExtensionId = (String) ((Widget) e.getSource()).getData(DATA_EDITOR_EXTENSION);
50
			fireValidationRequired();
51
		}
52
	};
53
54
	private String selectedExtensionId = null;
55
56
	public TaskEditorExtensionSettingsContribution(TaskRepository repository) {
57
		super("Task Editor Extension", "Select an extension to the task editor", repository);
58
	}
59
60
	public void applyTo(TaskRepository repository) {
61
		TaskEditorExtensions.setTaskEditorExtensionId(repository, selectedExtensionId == null ? "none"
62
				: selectedExtensionId);
63
	}
64
65
	public boolean canFlipToNextPage() {
66
		return true;
67
	}
68
69
	public boolean isPageComplete() {
70
		return true;
71
	}
72
73
	public void createControl(Composite parent, FormToolkit toolkit) {
74
		parent.setLayout(new GridLayout(1, true));
75
76
		selectedExtensionId = TaskEditorExtensions.getTaskEditorExtensionId(repository);
77
		String defaultExtensionId = TaskEditorExtensions.getDefaultTaskEditorExtensionId(repository);
78
79
		Button noneButton;
80
		{ // configure a 'none' button
81
			String noneTitle = LABEL_NONE;
82
83
			boolean isDefault = defaultExtensionId == null || defaultExtensionId.length() == 0;
84
			if (isDefault) {
85
				noneTitle += LABEL_DEFAULT_SUFFIX;
86
			}
87
			noneButton = toolkit.createButton(parent, noneTitle, SWT.RADIO);
88
			if (isDefault) {
89
				adjustForDefault(noneButton);
90
			}
91
92
			noneButton.addSelectionListener(listener);
93
		}
94
95
		boolean foundSelection = false;
96
97
		// now add selection buttons for all registered extensions
98
		SortedSet<RegisteredTaskEditorExtension> allEditorExtensions = TaskEditorExtensions.getTaskEditorExtensions();
99
		for (RegisteredTaskEditorExtension editorExtension : allEditorExtensions) {
100
			String name = editorExtension.getName();
101
102
			boolean isDefault = editorExtension.getId().equals(defaultExtensionId);
103
			if (isDefault) {
104
				name += LABEL_DEFAULT_SUFFIX;
105
			}
106
			Button button = toolkit.createButton(parent, name, SWT.RADIO);
107
			if (isDefault) {
108
				adjustForDefault(button);
109
			}
110
111
			if (editorExtension.getId().equals(selectedExtensionId)) {
112
				foundSelection = true;
113
				button.setSelection(true);
114
			}
115
			button.setText(name);
116
			button.setData(DATA_EDITOR_EXTENSION, editorExtension.getId());
117
			button.addSelectionListener(listener);
118
		}
119
		if (!foundSelection) {
120
			noneButton.setSelection(true);
121
		}
122
	}
123
124
	private void adjustForDefault(Button button) {
125
		Font font = button.getFont();
126
		button.setFont(getBold(font));
127
	}
128
129
	private Font getBold(Font font) {
130
		FontData[] originalFontData = font.getFontData();
131
		FontData fontData = originalFontData[0];
132
		if ((fontData.getStyle() & SWT.BOLD) != 0) {
133
			return font;
134
		}
135
136
		FontRegistry fontRegistry = JFaceResources.getFontRegistry();
137
		String key = fontData.getName() + '-' + fontData.getHeight() + "-" + fontData.getLocale() + "-"
138
				+ fontData.getStyle() + "-bold";
139
140
		if (!fontRegistry.hasValueFor(key)) {
141
			FontData[] boldFontDatas = new FontData[originalFontData.length];
142
			int index = -1;
143
			for (FontData fd : originalFontData) {
144
				boldFontDatas[++index] = new FontData(fd.getName(), fd.getHeight(), fd.getStyle() | SWT.BOLD);
145
			}
146
			fontRegistry.put(key, boldFontDatas);
147
		}
148
		return fontRegistry.get(key);
149
	}
150
151
	public IStatus[] validate(IProgressMonitor monitor) {
152
		return null;
153
	}
154
155
}

Return to bug 244653