View | Details | Raw Unified | Return to bug 263528 | Differences between
and this patch

Collapse All | Expand All

(-)plugin.xml (+3 lines)
Lines 30-35 Link Here
30
              
30
              
31
	  <taskListMigrator 
31
	  <taskListMigrator 
32
            class="org.eclipse.mylyn.internal.bugzilla.ui.tasklist.BugzillaTaskListMigrator"/>
32
            class="org.eclipse.mylyn.internal.bugzilla.ui.tasklist.BugzillaTaskListMigrator"/>
33
   <repositoryMigrator
34
         class="org.eclipse.mylyn.internal.bugzilla.ui.tasklist.BugzillaRepositoryMigrator">
35
   </repositoryMigrator>
33
   </extension> 
36
   </extension> 
34
    <extension 
37
    <extension 
35
         point="org.eclipse.mylyn.bugzilla.core.languages"> 
38
         point="org.eclipse.mylyn.bugzilla.core.languages"> 
(-)src/org/eclipse/mylyn/internal/bugzilla/ui/tasklist/BugzillaRepositoryMigrator.java (+54 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2004, 2008 Tasktop Technologies 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
 * Contributors:
9
 *     Tasktop Technologies - initial API and implementation
10
 *******************************************************************************/
11
12
package org.eclipse.mylyn.internal.bugzilla.ui.tasklist;
13
14
import org.eclipse.mylyn.internal.bugzilla.core.BugzillaCorePlugin;
15
import org.eclipse.mylyn.internal.tasks.core.IRepositoryConstants;
16
import org.eclipse.mylyn.tasks.core.AbstractRepositoryMigrator;
17
import org.eclipse.mylyn.tasks.core.TaskRepository;
18
19
/**
20
 * @author Robert Elves
21
 * @since 3.4
22
 */
23
public class BugzillaRepositoryMigrator extends AbstractRepositoryMigrator {
24
25
	@Override
26
	public String getConnectorKind() {
27
		return BugzillaCorePlugin.CONNECTOR_KIND;
28
	}
29
30
	@Override
31
	public boolean migrateRepository(TaskRepository repository) {
32
		if (repository.getProperty(IRepositoryConstants.PROPERTY_CATEGORY) == null) {
33
			repository.setProperty(IRepositoryConstants.PROPERTY_CATEGORY, IRepositoryConstants.CATEGORY_BUGS);
34
			return true;
35
		}
36
		return false;
37
38
//		repository.setProperty(IRepositoryConstants.PROPERTY_CATEGORY, IRepositoryConstants.CATEGORY_BUGS);
39
//		
40
//		if (repository.getConnectorKind().equals("bugzilla") || repository.getConnectorKind().equals("local")) {
41
//			if (repository.getRepositoryUrl().contains("bugs.eclipse.org")) {
42
//				repository.setProperty(IRepositoryConstants.PROPERTY_CATEGORY, IRepositoryConstants.CATEGORY_BUGS);
43
//			} else {
44
//				repository.setProperty(IRepositoryConstants.PROPERTY_CATEGORY, IRepositoryConstants.CATEGORY_TASKS);
45
//			}
46
//		} else {
47
//			String category = repository.getProperty(IRepositoryConstants.PROPERTY_CATEGORY);
48
//			if (category == null) {
49
//				repository.setProperty(IRepositoryConstants.PROPERTY_CATEGORY, IRepositoryConstants.CATEGORY_OTHER);
50
//			}
51
//		}
52
	}
53
54
}
(-)META-INF/MANIFEST.MF (+1 lines)
Lines 14-19 Link Here
14
 org.eclipse.mylyn.internal.tasks.core;x-friends:="org.eclipse.mylyn.tasks.ui,org.eclipse.mylyn.tasks.bugs",
14
 org.eclipse.mylyn.internal.tasks.core;x-friends:="org.eclipse.mylyn.tasks.ui,org.eclipse.mylyn.tasks.bugs",
15
 org.eclipse.mylyn.internal.tasks.core.data;x-friends:="org.eclipse.mylyn.tasks.ui,org.eclipse.mylyn.tasks.bugs",
15
 org.eclipse.mylyn.internal.tasks.core.data;x-friends:="org.eclipse.mylyn.tasks.ui,org.eclipse.mylyn.tasks.bugs",
16
 org.eclipse.mylyn.internal.tasks.core.externalization;x-friends:="org.eclipse.mylyn.tasks.ui,org.eclipse.mylyn.tasks.bugs",
16
 org.eclipse.mylyn.internal.tasks.core.externalization;x-friends:="org.eclipse.mylyn.tasks.ui,org.eclipse.mylyn.tasks.bugs",
17
 org.eclipse.mylyn.internal.tasks.core.notifications;x-friends:="org.eclipse.mylyn.tasks.ui,org.eclipse.mylyn.tasks.bugs",
17
 org.eclipse.mylyn.internal.tasks.core.sync;x-friends:="org.eclipse.mylyn.tasks.ui,org.eclipse.mylyn.tasks.bugs",
18
 org.eclipse.mylyn.internal.tasks.core.sync;x-friends:="org.eclipse.mylyn.tasks.ui,org.eclipse.mylyn.tasks.bugs",
18
 org.eclipse.mylyn.tasks.core,
19
 org.eclipse.mylyn.tasks.core,
19
 org.eclipse.mylyn.tasks.core.data,
20
 org.eclipse.mylyn.tasks.core.data,
(-)src/org/eclipse/mylyn/internal/tasks/core/TaskRepositoryManager.java (-3 / +67 lines)
Lines 33-38 Link Here
33
import org.eclipse.mylyn.commons.core.StatusHandler;
33
import org.eclipse.mylyn.commons.core.StatusHandler;
34
import org.eclipse.mylyn.internal.tasks.core.TaskRepositoryDelta.Type;
34
import org.eclipse.mylyn.internal.tasks.core.TaskRepositoryDelta.Type;
35
import org.eclipse.mylyn.tasks.core.AbstractRepositoryConnector;
35
import org.eclipse.mylyn.tasks.core.AbstractRepositoryConnector;
36
import org.eclipse.mylyn.tasks.core.AbstractRepositoryMigrator;
36
import org.eclipse.mylyn.tasks.core.IRepositoryListener;
37
import org.eclipse.mylyn.tasks.core.IRepositoryListener;
37
import org.eclipse.mylyn.tasks.core.IRepositoryManager;
38
import org.eclipse.mylyn.tasks.core.IRepositoryManager;
38
import org.eclipse.mylyn.tasks.core.ITask;
39
import org.eclipse.mylyn.tasks.core.ITask;
Lines 57-62 Link Here
57
58
58
	private final Map<String, AbstractRepositoryConnector> repositoryConnectors = new HashMap<String, AbstractRepositoryConnector>();
59
	private final Map<String, AbstractRepositoryConnector> repositoryConnectors = new HashMap<String, AbstractRepositoryConnector>();
59
60
61
	// connector kinds to corresponding repositories
60
	private final Map<String, Set<TaskRepository>> repositoryMap = new HashMap<String, Set<TaskRepository>>();
62
	private final Map<String, Set<TaskRepository>> repositoryMap = new HashMap<String, Set<TaskRepository>>();
61
63
62
	private final Set<IRepositoryListener> listeners = new CopyOnWriteArraySet<IRepositoryListener>();
64
	private final Set<IRepositoryListener> listeners = new CopyOnWriteArraySet<IRepositoryListener>();
Lines 67-72 Link Here
67
69
68
	public static final String PREFIX_LOCAL = "local-"; //$NON-NLS-1$
70
	public static final String PREFIX_LOCAL = "local-"; //$NON-NLS-1$
69
71
72
	private static final Map<String, Category> repositoryCategories = new HashMap<String, Category>();
73
70
	private final PropertyChangeListener PROPERTY_CHANGE_LISTENER = new PropertyChangeListener() {
74
	private final PropertyChangeListener PROPERTY_CHANGE_LISTENER = new PropertyChangeListener() {
71
		public void propertyChange(PropertyChangeEvent evt) {
75
		public void propertyChange(PropertyChangeEvent evt) {
72
			TaskRepositoryManager.this.notifyRepositorySettingsChanged((TaskRepository) evt.getSource(),
76
			TaskRepositoryManager.this.notifyRepositorySettingsChanged((TaskRepository) evt.getSource(),
Lines 76-82 Link Here
76
80
77
	private final TaskRepositoriesExternalizer externalizer = new TaskRepositoriesExternalizer();
81
	private final TaskRepositoriesExternalizer externalizer = new TaskRepositoriesExternalizer();
78
82
83
	private List<AbstractRepositoryMigrator> migrators;
84
79
	public TaskRepositoryManager() {
85
	public TaskRepositoryManager() {
86
		this.migrators = Collections.emptyList();
87
		Category catTasks = new Category(IRepositoryConstants.CATEGORY_TASKS, "Tasks", 0); //$NON-NLS-1$
88
		repositoryCategories.put(catTasks.getId(), catTasks);
89
		Category catBugs = new Category(IRepositoryConstants.CATEGORY_BUGS, "Bugs", 100); //$NON-NLS-1$
90
		repositoryCategories.put(catBugs.getId(), catBugs);
91
		Category catOther = new Category(IRepositoryConstants.CATEGORY_OTHER, "Other", 200); //$NON-NLS-1$
92
		repositoryCategories.put(catOther.getId(), catOther);
80
	}
93
	}
81
94
82
	public synchronized Collection<AbstractRepositoryConnector> getRepositoryConnectors() {
95
	public synchronized Collection<AbstractRepositoryConnector> getRepositoryConnectors() {
Lines 118-123 Link Here
118
				// TODO 4.0 return false to indicate that remove was unsuccessful
131
				// TODO 4.0 return false to indicate that remove was unsuccessful
119
				return;
132
				return;
120
			}
133
			}
134
121
			repository.addChangeListener(PROPERTY_CHANGE_LISTENER);
135
			repository.addChangeListener(PROPERTY_CHANGE_LISTENER);
122
		}
136
		}
123
137
Lines 182-187 Link Here
182
		return sb.toString();
196
		return sb.toString();
183
	}
197
	}
184
198
199
	public Category getCategory(String id) {
200
		Category category = repositoryCategories.get(IRepositoryConstants.CATEGORY_OTHER);
201
		Category cat = repositoryCategories.get(id);
202
		if (cat != null) {
203
			category = cat;
204
		}
205
		return category;
206
	}
207
185
	public TaskRepository getRepository(String kind, String urlString) {
208
	public TaskRepository getRepository(String kind, String urlString) {
186
		Assert.isNotNull(kind);
209
		Assert.isNotNull(kind);
187
		Assert.isNotNull(urlString);
210
		Assert.isNotNull(urlString);
Lines 233-243 Link Here
233
		return null;
256
		return null;
234
	}
257
	}
235
258
236
	public Set<TaskRepository> getRepositories(String kind) {
259
	public Set<TaskRepository> getRepositories(String connectorKind) {
237
		Assert.isNotNull(kind);
260
		Assert.isNotNull(connectorKind);
238
		Set<TaskRepository> result;
261
		Set<TaskRepository> result;
239
		synchronized (this) {
262
		synchronized (this) {
240
			result = repositoryMap.get(kind);
263
			result = repositoryMap.get(connectorKind);
241
		}
264
		}
242
		if (result == null) {
265
		if (result == null) {
243
			return Collections.emptySet();
266
			return Collections.emptySet();
Lines 309-317 Link Here
309
					if (removeHttpAuthMigration(repository)) {
332
					if (removeHttpAuthMigration(repository)) {
310
						migration = true;
333
						migration = true;
311
					}
334
					}
335
					if (applyMigrators(repository)) {
336
						migration = true;
337
					}
312
					if (repositoryMap.containsKey(repository.getConnectorKind())) {
338
					if (repositoryMap.containsKey(repository.getConnectorKind())) {
313
						repositoryMap.get(repository.getConnectorKind()).add(repository);
339
						repositoryMap.get(repository.getConnectorKind()).add(repository);
340
314
						repository.addChangeListener(PROPERTY_CHANGE_LISTENER);
341
						repository.addChangeListener(PROPERTY_CHANGE_LISTENER);
342
315
					} else {
343
					} else {
316
						orphanedRepositories.add(repository);
344
						orphanedRepositories.add(repository);
317
					}
345
					}
Lines 323-328 Link Here
323
		}
351
		}
324
	}
352
	}
325
353
354
	private boolean applyMigrators(final TaskRepository repository) {
355
		final boolean[] result = new boolean[1];
356
		for (AbstractRepositoryMigrator migrator : migrators) {
357
			if (migrator.getConnectorKind().equals(repository.getConnectorKind())) {
358
359
				final AbstractRepositoryMigrator finalRepositoryMigrator = migrator;
360
				result[0] = false;
361
				SafeRunner.run(new ISafeRunnable() {
362
363
					public void handleException(Throwable e) {
364
						StatusHandler.log(new Status(IStatus.WARNING, ITasksCoreConstants.ID_PLUGIN,
365
								"Repository migration failed for repository \"" + repository.getUrl() + "\"", e)); //$NON-NLS-1$ //$NON-NLS-2$
366
					}
367
368
					public void run() throws Exception {
369
						if (finalRepositoryMigrator.migrateRepository(repository)) {
370
							result[0] = true;
371
						}
372
					}
373
374
				});
375
				break;
376
			}
377
		}
378
		return result[0];
379
	}
380
326
	@SuppressWarnings("deprecation")
381
	@SuppressWarnings("deprecation")
327
	private boolean removeHttpAuthMigration(TaskRepository repository) {
382
	private boolean removeHttpAuthMigration(TaskRepository repository) {
328
		String httpusername = repository.getProperty(TaskRepository.AUTH_HTTP_USERNAME);
383
		String httpusername = repository.getProperty(TaskRepository.AUTH_HTTP_USERNAME);
Lines 447-450 Link Here
447
		}
502
		}
448
	}
503
	}
449
504
505
	public Category getCategory(TaskRepository repository) {
506
		String categoryId = repository.getProperty(IRepositoryConstants.PROPERTY_CATEGORY);
507
		return getCategory(categoryId);
508
	}
509
510
	public void initialize(List<AbstractRepositoryMigrator> repositoryMigrators) {
511
		this.migrators = repositoryMigrators;
512
513
	}
450
}
514
}
(-)src/org/eclipse/mylyn/internal/tasks/core/notifications/IServiceMessageListener.java (+21 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2010 Tasktop Technologies 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
 * Contributors:
9
 *     Tasktop Technologies - initial API and implementation
10
 *******************************************************************************/
11
12
package org.eclipse.mylyn.internal.tasks.core.notifications;
13
14
/**
15
 * @author Robert Elves
16
 */
17
public interface IServiceMessageListener {
18
19
	public void handleEvent(ServiceMessageEvent event);
20
21
}
(-)src/org/eclipse/mylyn/tasks/core/AbstractRepositoryMigrator.java (+26 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2004, 2008 Tasktop Technologies 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
 * Contributors:
9
 *     Tasktop Technologies - initial API and implementation
10
 *******************************************************************************/
11
12
package org.eclipse.mylyn.tasks.core;
13
14
/**
15
 * @author Robert Elves
16
 * @since 3.4
17
 */
18
public abstract class AbstractRepositoryMigrator {
19
20
	public abstract String getConnectorKind();
21
22
	public boolean migrateRepository(TaskRepository repository) {
23
		return false;
24
	}
25
26
}
(-)src/org/eclipse/mylyn/internal/tasks/core/notifications/ServiceMessageXmlHandler.java (+92 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2010 Tasktop Technologies 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
 * Contributors:
9
 *     Tasktop Technologies - initial API and implementation
10
 *******************************************************************************/
11
12
package org.eclipse.mylyn.internal.tasks.core.notifications;
13
14
import java.util.ArrayList;
15
import java.util.List;
16
17
import org.xml.sax.Attributes;
18
import org.xml.sax.SAXException;
19
import org.xml.sax.helpers.DefaultHandler;
20
21
/**
22
 * @author Robert Elves
23
 * @author Steffen Pingel
24
 */
25
public class ServiceMessageXmlHandler extends DefaultHandler {
26
27
	private static final String TAG_MESSAGE = "ServiceMessage"; //$NON-NLS-1$
28
29
	private StringBuilder characters;
30
31
	private final List<ServiceMessage> messages = new ArrayList<ServiceMessage>();
32
33
	private ServiceMessage message;
34
35
	@Override
36
	public void characters(char[] ch, int start, int length) throws SAXException {
37
		characters.append(ch, start, length);
38
	}
39
40
	@Override
41
	public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
42
		if (TAG_MESSAGE.equals(qName.trim())) {
43
			message = new ServiceMessage();
44
		}
45
		characters = new StringBuilder();
46
	}
47
48
	@Override
49
	public void endElement(String uri, String localName, String qName) throws SAXException {
50
		if (message == null) {
51
			return;
52
		}
53
		if (TAG_MESSAGE.equals(qName.trim())) {
54
			if (message.isValid()) {
55
				messages.add(message);
56
			}
57
		} else {
58
			String parsedText = characters.toString();
59
			ServiceMessage.Element element;
60
			try {
61
				element = ServiceMessage.Element.valueOf(qName.trim().toUpperCase());
62
				switch (element) {
63
				case ID:
64
					message.setId(parsedText);
65
					break;
66
				case DESCRIPTION:
67
					message.setDescription(parsedText);
68
					break;
69
				case TITLE:
70
					message.setTitle(parsedText);
71
					break;
72
				case URL:
73
					message.setUrl(parsedText);
74
					break;
75
				case IMAGE:
76
					message.setImage(parsedText);
77
					break;
78
				case VERSION:
79
					message.setVersion(parsedText);
80
					break;
81
				}
82
			} catch (IllegalArgumentException e) {
83
				// ignore unrecognized elements
84
			}
85
		}
86
	}
87
88
	public List<ServiceMessage> getMessages() {
89
		return new ArrayList<ServiceMessage>(messages);
90
	}
91
92
}
(-)src/org/eclipse/mylyn/internal/tasks/core/notifications/ServiceMessageManager.java (+225 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2004, 2008 Tasktop Technologies.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Tasktop EULA
5
 * which accompanies this distribution, and is available at
6
 * http://tasktop.com/legal
7
 *******************************************************************************/
8
9
package org.eclipse.mylyn.internal.tasks.core.notifications;
10
11
import java.io.InputStream;
12
import java.util.ArrayList;
13
import java.util.Collections;
14
import java.util.List;
15
import java.util.concurrent.CopyOnWriteArrayList;
16
17
import javax.xml.parsers.SAXParser;
18
import javax.xml.parsers.SAXParserFactory;
19
20
import org.apache.commons.httpclient.Header;
21
import org.apache.commons.httpclient.HostConfiguration;
22
import org.apache.commons.httpclient.HttpClient;
23
import org.apache.commons.httpclient.HttpStatus;
24
import org.apache.commons.httpclient.methods.GetMethod;
25
import org.eclipse.core.runtime.IProgressMonitor;
26
import org.eclipse.core.runtime.ISafeRunnable;
27
import org.eclipse.core.runtime.IStatus;
28
import org.eclipse.core.runtime.SafeRunner;
29
import org.eclipse.core.runtime.Status;
30
import org.eclipse.core.runtime.SubProgressMonitor;
31
import org.eclipse.core.runtime.jobs.IJobChangeEvent;
32
import org.eclipse.core.runtime.jobs.Job;
33
import org.eclipse.core.runtime.jobs.JobChangeAdapter;
34
import org.eclipse.mylyn.commons.core.StatusHandler;
35
import org.eclipse.mylyn.commons.net.WebLocation;
36
import org.eclipse.mylyn.commons.net.WebUtil;
37
import org.eclipse.mylyn.internal.tasks.core.ITasksCoreConstants;
38
39
/**
40
 * @author Robert Elves
41
 * @author Steffen Pingel
42
 */
43
public class ServiceMessageManager {
44
45
	protected static final long START_DELAY = 30 * 1000;
46
47
	protected static final long RECHECK_DELAY = 2 * 60 * 60 * 1000;
48
49
	private String serviceMessageUrl;
50
51
	private volatile List<ServiceMessage> messages = Collections.emptyList();
52
53
	private Job messageCheckJob;
54
55
	private final List<IServiceMessageListener> listeners = new CopyOnWriteArrayList<IServiceMessageListener>();
56
57
	private String lastModified;
58
59
	private String eTag;
60
61
	private boolean statusLogged;
62
63
	public ServiceMessageManager(String serviceMessageUrl, String lastModified, String eTag) {
64
		this.serviceMessageUrl = serviceMessageUrl;
65
		this.lastModified = lastModified;
66
		this.eTag = eTag;
67
	}
68
69
	public void start() {
70
		if (messageCheckJob == null) {
71
			messageCheckJob = new Job("Checking for new service message") { //$NON-NLS-1$
72
				@Override
73
				protected IStatus run(IProgressMonitor monitor) {
74
					updateServiceMessage(monitor);
75
					return Status.OK_STATUS;
76
				}
77
78
			};
79
			messageCheckJob.setSystem(true);
80
			messageCheckJob.setPriority(Job.DECORATE);
81
			messageCheckJob.addJobChangeListener(new JobChangeAdapter() {
82
				@Override
83
				public void done(IJobChangeEvent event) {
84
					if (messageCheckJob != null) {
85
						messageCheckJob.schedule(RECHECK_DELAY);
86
					}
87
				}
88
			});
89
		}
90
		messageCheckJob.schedule(START_DELAY);
91
	}
92
93
	public void stop() {
94
		if (messageCheckJob != null) {
95
			messageCheckJob.cancel();
96
			messageCheckJob = null;
97
		}
98
99
		final ServiceMessageEvent event = new ServiceMessageEvent(this, ServiceMessageEvent.EVENT_KIND.STOP);
100
101
		for (final IServiceMessageListener listener : listeners) {
102
			SafeRunner.run(new ISafeRunnable() {
103
				public void run() throws Exception {
104
					listener.handleEvent(event);
105
				}
106
107
				public void handleException(Throwable e) {
108
					StatusHandler.log(new Status(IStatus.WARNING, ITasksCoreConstants.ID_PLUGIN, "Listener failed: " //$NON-NLS-1$
109
							+ listener.getClass(), e));
110
				}
111
			});
112
		}
113
	}
114
115
	public void setServiceMessageUrl(String url) {
116
		this.serviceMessageUrl = url;
117
	}
118
119
	public void addServiceMessageListener(IServiceMessageListener listener) {
120
		listeners.add(listener);
121
	}
122
123
	public void removeServiceMessageListener(IServiceMessageListener listener) {
124
		listeners.remove(listener);
125
	}
126
127
	private void notifyListeners(List<ServiceMessage> messages) {
128
		this.messages = messages;
129
		for (final ServiceMessage message : messages) {
130
			message.setETag(eTag);
131
			message.setLastModified(lastModified);
132
		}
133
134
		final ServiceMessageEvent event = new ServiceMessageEvent(this, ServiceMessageEvent.EVENT_KIND.MESSAGE_UPDATE,
135
				messages);
136
137
		for (final IServiceMessageListener listener : listeners) {
138
			SafeRunner.run(new ISafeRunnable() {
139
				public void run() throws Exception {
140
					listener.handleEvent(event);
141
				}
142
143
				public void handleException(Throwable e) {
144
					StatusHandler.log(new Status(IStatus.WARNING, ITasksCoreConstants.ID_PLUGIN, "Listener failed: " //$NON-NLS-1$
145
							+ listener.getClass(), e));
146
				}
147
			});
148
		}
149
	}
150
151
	public List<ServiceMessage> getServiceMessages() {
152
		return new ArrayList<ServiceMessage>(this.messages);
153
	}
154
155
	/**
156
	 * Public for testing
157
	 */
158
	public int updateServiceMessage(IProgressMonitor monitor) {
159
		int status = -1;
160
		List<ServiceMessage> messages = null;
161
		try {
162
			HttpClient httpClient = new HttpClient(WebUtil.getConnectionManager());
163
			WebUtil.configureHttpClient(httpClient, null);
164
165
			WebLocation location = new WebLocation(serviceMessageUrl);
166
			HostConfiguration hostConfiguration = WebUtil.createHostConfiguration(httpClient, location,
167
					new SubProgressMonitor(monitor, 1));
168
169
			GetMethod method = new GetMethod(serviceMessageUrl);
170
			method.setRequestHeader("If-Modified-Since", lastModified); //$NON-NLS-1$
171
			method.setRequestHeader("If-None-Match", eTag); //$NON-NLS-1$
172
173
			try {
174
				status = WebUtil.execute(httpClient, hostConfiguration, method, monitor);
175
				if (status == HttpStatus.SC_OK && messageCheckJob != null) {
176
					Header lastModifiedHeader = method.getResponseHeader("Last-Modified"); //$NON-NLS-1$
177
					if (lastModifiedHeader != null) {
178
						lastModified = lastModifiedHeader.getValue();
179
					}
180
					Header eTagHeader = method.getResponseHeader("ETag"); //$NON-NLS-1$
181
					if (eTagHeader != null) {
182
						eTag = eTagHeader.getValue();
183
					}
184
185
					InputStream in = WebUtil.getResponseBodyAsStream(method, monitor);
186
					try {
187
						SAXParserFactory factory = SAXParserFactory.newInstance();
188
						factory.setValidating(false);
189
						SAXParser parser = factory.newSAXParser();
190
191
						ServiceMessageXmlHandler handler = new ServiceMessageXmlHandler();
192
						parser.parse(in, handler);
193
						messages = handler.getMessages();
194
					} finally {
195
						in.close();
196
					}
197
				} else if (status == HttpStatus.SC_NOT_FOUND) {
198
					// no messages
199
				} else if (status == HttpStatus.SC_NOT_MODIFIED) {
200
					// no new messages
201
				} else {
202
					if (!statusLogged) {
203
						statusLogged = true;
204
						StatusHandler.log(new Status(IStatus.WARNING, ITasksCoreConstants.ID_PLUGIN,
205
								"Http error retrieving service message: " + HttpStatus.getStatusText(status))); //$NON-NLS-1$
206
					}
207
				}
208
			} finally {
209
				WebUtil.releaseConnection(method, monitor);
210
			}
211
		} catch (Exception e) {
212
			if (!statusLogged) {
213
				statusLogged = true;
214
				StatusHandler.log(new Status(IStatus.WARNING, ITasksCoreConstants.ID_PLUGIN,
215
						"Http error retrieving service message.", e)); //$NON-NLS-1$
216
			}
217
		}
218
219
		if (messages != null && messages.size() > 0) {
220
			notifyListeners(messages);
221
		}
222
		return status;
223
	}
224
225
}
(-)src/org/eclipse/mylyn/internal/tasks/core/notifications/ServiceMessage.java (+107 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2010 Tasktop Technologies 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
 * Contributors:
9
 *     Tasktop Technologies - initial API and implementation
10
 *******************************************************************************/
11
12
package org.eclipse.mylyn.internal.tasks.core.notifications;
13
14
/**
15
 * @author Robert Elves
16
 */
17
public class ServiceMessage {
18
19
	public enum Element {
20
		ID, TITLE, DESCRIPTION, URL, IMAGE, VERSION
21
	};
22
23
	private String id;
24
25
	private String title;
26
27
	private String description;
28
29
	private String url;
30
31
	private String image;
32
33
	private String version;
34
35
	private String eTag;
36
37
	private String lastModified;
38
39
	public String getId() {
40
		return id;
41
	}
42
43
	public String getTitle() {
44
		return title;
45
	}
46
47
	public String getDescription() {
48
		return description;
49
	}
50
51
	public String getUrl() {
52
		return url;
53
	}
54
55
	public String getImage() {
56
		return image;
57
	}
58
59
	public void setETag(String eTag) {
60
		this.eTag = eTag;
61
	}
62
63
	public void setLastModified(String lastModified) {
64
		this.lastModified = lastModified;
65
	}
66
67
	public String getETag() {
68
		return eTag;
69
	}
70
71
	public String getLastModified() {
72
		return lastModified;
73
	}
74
75
	public String getVersion() {
76
		return version;
77
	}
78
79
	public void setId(String id) {
80
		this.id = id;
81
	}
82
83
	public void setTitle(String title) {
84
		this.title = title;
85
	}
86
87
	public void setDescription(String description) {
88
		this.description = description;
89
	}
90
91
	public void setUrl(String url) {
92
		this.url = url;
93
	}
94
95
	public void setImage(String image) {
96
		this.image = image;
97
	}
98
99
	public void setVersion(String version) {
100
		this.version = version;
101
	}
102
103
	public boolean isValid() {
104
		return id != null && title != null && description != null && image != null;
105
	}
106
107
}
(-)src/org/eclipse/mylyn/internal/tasks/core/notifications/ServiceMessageEvent.java (+52 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2010 Tasktop Technologies 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
 * Contributors:
9
 *     Tasktop Technologies - initial API and implementation
10
 *******************************************************************************/
11
12
package org.eclipse.mylyn.internal.tasks.core.notifications;
13
14
import java.util.ArrayList;
15
import java.util.Collections;
16
import java.util.EventObject;
17
import java.util.List;
18
19
/**
20
 * @author Steffen Pingel
21
 */
22
public class ServiceMessageEvent extends EventObject {
23
24
	public enum EVENT_KIND {
25
		MESSAGE_UPDATE, STOP
26
	};
27
28
	private static final long serialVersionUID = 1L;
29
30
	private final List<ServiceMessage> messages;
31
32
	private final EVENT_KIND eventKind;
33
34
	public ServiceMessageEvent(ServiceMessageManager manager, EVENT_KIND kind) {
35
		this(manager, kind, new ArrayList<ServiceMessage>());
36
	}
37
38
	public ServiceMessageEvent(ServiceMessageManager manager, EVENT_KIND eventKind, List<ServiceMessage> messages) {
39
		super(manager);
40
		this.eventKind = eventKind;
41
		this.messages = Collections.unmodifiableList(new ArrayList<ServiceMessage>(messages));
42
	}
43
44
	public List<ServiceMessage> getMessages() {
45
		return messages;
46
	}
47
48
	public EVENT_KIND getEventKind() {
49
		return eventKind;
50
	}
51
52
}
(-)src/org/eclipse/mylyn/tasks/tests/AllTasksTests.java (+2 lines)
Lines 30-35 Link Here
30
import org.eclipse.mylyn.tasks.tests.ui.editor.RepositoryCompletionProcessorTest;
30
import org.eclipse.mylyn.tasks.tests.ui.editor.RepositoryCompletionProcessorTest;
31
import org.eclipse.mylyn.tasks.tests.ui.editor.TaskEditorPartDescriptorTest;
31
import org.eclipse.mylyn.tasks.tests.ui.editor.TaskEditorPartDescriptorTest;
32
import org.eclipse.mylyn.tasks.tests.ui.editor.TaskUrlHyperlinkDetectorTest;
32
import org.eclipse.mylyn.tasks.tests.ui.editor.TaskUrlHyperlinkDetectorTest;
33
import org.eclipse.mylyn.tasks.tests.util.ServiceMessageManagerTest;
33
34
34
/**
35
/**
35
 * @author Mik Kersten
36
 * @author Mik Kersten
Lines 102-107 Link Here
102
		suite.addTestSuite(PlanningPartTest.class);
103
		suite.addTestSuite(PlanningPartTest.class);
103
		suite.addTestSuite(RepositoryCompletionProcessorTest.class);
104
		suite.addTestSuite(RepositoryCompletionProcessorTest.class);
104
		suite.addTestSuite(TaskAttributeDiffTest.class);
105
		suite.addTestSuite(TaskAttributeDiffTest.class);
106
		suite.addTestSuite(ServiceMessageManagerTest.class);
105
		// XXX long running tests, put back?
107
		// XXX long running tests, put back?
106
		//suite.addTestSuite(QueryExportImportTest.class);
108
		//suite.addTestSuite(QueryExportImportTest.class);
107
		//suite.addTestSuite(BackgroundSaveTest.class);
109
		//suite.addTestSuite(BackgroundSaveTest.class);
(-)src/org/eclipse/mylyn/tasks/tests/util/ServiceMessageManagerTest.java (+81 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2010 Tasktop Technologies 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
 * Contributors:
9
 *     Tasktop Technologies - initial API and implementation
10
 *******************************************************************************/
11
12
package org.eclipse.mylyn.tasks.tests.util;
13
14
import java.io.ByteArrayInputStream;
15
import java.io.InputStream;
16
17
import javax.xml.parsers.SAXParser;
18
import javax.xml.parsers.SAXParserFactory;
19
20
import junit.framework.TestCase;
21
22
import org.apache.commons.httpclient.HttpStatus;
23
import org.eclipse.core.runtime.NullProgressMonitor;
24
import org.eclipse.mylyn.internal.tasks.core.notifications.ServiceMessage;
25
import org.eclipse.mylyn.internal.tasks.core.notifications.ServiceMessageManager;
26
import org.eclipse.mylyn.internal.tasks.core.notifications.ServiceMessageXmlHandler;
27
28
/**
29
 * @author Robert Elves
30
 */
31
public class ServiceMessageManagerTest extends TestCase {
32
33
	private static final String MESSAGE_XML_URL = "http://eclipse.org/mylyn/messageTest.xml";
34
35
	public void testRetrievingMessage() throws Exception {
36
		ServiceMessageManager manager = new ServiceMessageManager(MESSAGE_XML_URL, "", "");
37
		int status = manager.updateServiceMessage(new NullProgressMonitor());
38
		assertEquals(HttpStatus.SC_OK, status);
39
		ServiceMessage message = manager.getServiceMessages().get(0);
40
41
		assertEquals("1", message.getId());
42
		assertEquals("140 character description here....", message.getDescription());
43
		assertEquals("Mylyn 3.4 now available!", message.getTitle());
44
		assertEquals("http://eclipse.org/mylyn/downloads", message.getUrl());
45
		assertEquals("Mylyn 3.4 now available!", message.getTitle());
46
		assertEquals("dialog_messasge_info_image", message.getImage());
47
	}
48
49
	public void testETag() throws Exception {
50
51
		ServiceMessageManager manager = new ServiceMessageManager(MESSAGE_XML_URL, "", "");
52
		int status = manager.updateServiceMessage(new NullProgressMonitor());
53
		assertEquals(HttpStatus.SC_OK, status);
54
		ServiceMessage message = manager.getServiceMessages().get(0);
55
56
		assertNotNull(message.getLastModified());
57
		assertNotNull(message.getETag());
58
59
		status = manager.updateServiceMessage(new NullProgressMonitor());
60
		assertEquals(HttpStatus.SC_NOT_MODIFIED, status);
61
	}
62
63
	public void testParsingMessageXml() throws Exception {
64
		String messageXml = "<ServiceMessage> <id>1</id><description>140 character description here....</description><title>Mylyn 3.4 now available!</title><url>http://eclipse.org/mylyn/downloads</url><image>dialog_messasge_info_image</image></ServiceMessage>";
65
		InputStream is = new ByteArrayInputStream(messageXml.getBytes("UTF-8"));
66
		SAXParserFactory factory = SAXParserFactory.newInstance();
67
		factory.setValidating(false);
68
		SAXParser parser = factory.newSAXParser();
69
		ServiceMessageXmlHandler handler = new ServiceMessageXmlHandler();
70
		parser.parse(is, handler);
71
		ServiceMessage message = handler.getMessages().get(0);
72
73
		assertEquals("1", message.getId());
74
		assertEquals("140 character description here....", message.getDescription());
75
		assertEquals("Mylyn 3.4 now available!", message.getTitle());
76
		assertEquals("http://eclipse.org/mylyn/downloads", message.getUrl());
77
		assertEquals("Mylyn 3.4 now available!", message.getTitle());
78
		assertEquals("dialog_messasge_info_image", message.getImage());
79
	}
80
81
}
(-)src/org/eclipse/mylyn/internal/tasks/ui/views/TaskRepositoriesView.java (-52 / +17 lines)
Lines 22-31 Link Here
22
import org.eclipse.jface.viewers.DecoratingLabelProvider;
22
import org.eclipse.jface.viewers.DecoratingLabelProvider;
23
import org.eclipse.jface.viewers.DoubleClickEvent;
23
import org.eclipse.jface.viewers.DoubleClickEvent;
24
import org.eclipse.jface.viewers.IDoubleClickListener;
24
import org.eclipse.jface.viewers.IDoubleClickListener;
25
import org.eclipse.jface.viewers.IStructuredContentProvider;
25
import org.eclipse.jface.viewers.TreeViewer;
26
import org.eclipse.jface.viewers.TableViewer;
27
import org.eclipse.jface.viewers.Viewer;
28
import org.eclipse.mylyn.commons.core.StatusHandler;
26
import org.eclipse.mylyn.commons.core.StatusHandler;
27
import org.eclipse.mylyn.internal.tasks.core.Category;
29
import org.eclipse.mylyn.internal.tasks.core.IRepositoryModelListener;
28
import org.eclipse.mylyn.internal.tasks.core.IRepositoryModelListener;
30
import org.eclipse.mylyn.internal.tasks.core.TaskRepositoryAdapter;
29
import org.eclipse.mylyn.internal.tasks.core.TaskRepositoryAdapter;
31
import org.eclipse.mylyn.internal.tasks.ui.TasksUiPlugin;
30
import org.eclipse.mylyn.internal.tasks.ui.TasksUiPlugin;
Lines 50-55 Link Here
50
import org.eclipse.ui.handlers.IHandlerService;
49
import org.eclipse.ui.handlers.IHandlerService;
51
import org.eclipse.ui.part.ViewPart;
50
import org.eclipse.ui.part.ViewPart;
52
import org.eclipse.ui.texteditor.IWorkbenchActionDefinitionIds;
51
import org.eclipse.ui.texteditor.IWorkbenchActionDefinitionIds;
52
import org.eclipse.ui.themes.IThemeManager;
53
53
54
/**
54
/**
55
 * @author Mik Kersten
55
 * @author Mik Kersten
Lines 62-68 Link Here
62
	@Deprecated
62
	@Deprecated
63
	public static final String ID = ITasksUiConstants.ID_VIEW_REPOSITORIES;
63
	public static final String ID = ITasksUiConstants.ID_VIEW_REPOSITORIES;
64
64
65
	private TableViewer viewer;
65
	private TreeViewer viewer;
66
66
67
	private final Action addRepositoryAction = new AddRepositoryAction();
67
	private final Action addRepositoryAction = new AddRepositoryAction();
68
68
Lines 121-138 Link Here
121
		}
121
		}
122
	};
122
	};
123
123
124
	static class ViewContentProvider implements IStructuredContentProvider {
125
		public void inputChanged(Viewer v, Object oldInput, Object newInput) {
126
		}
127
128
		public void dispose() {
129
		}
130
131
		public Object[] getElements(Object parent) {
132
			return TasksUi.getRepositoryManager().getAllRepositories().toArray();
133
		}
134
	}
135
136
	public TaskRepositoriesView() {
124
	public TaskRepositoriesView() {
137
		TasksUi.getRepositoryManager().addListener(REPOSITORY_LISTENER);
125
		TasksUi.getRepositoryManager().addListener(REPOSITORY_LISTENER);
138
		TasksUiPlugin.getDefault().addModelListener(MODEL_LISTENER);
126
		TasksUiPlugin.getDefault().addModelListener(MODEL_LISTENER);
Lines 172-198 Link Here
172
160
173
	@Override
161
	@Override
174
	public void createPartControl(Composite parent) {
162
	public void createPartControl(Composite parent) {
175
		viewer = new TableViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION);
163
		viewer = new TreeViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION);
176
		viewer.setContentProvider(new ViewContentProvider());
164
		viewer.setContentProvider(new TeamRepositoriesContentProvider());
177
		viewer.setUseHashlookup(true);
165
		viewer.setUseHashlookup(true);
178
		viewer.setLabelProvider(new DecoratingLabelProvider(new TaskRepositoryLabelProvider(),
166
		viewer.setLabelProvider(new DecoratingLabelProvider(new TaskRepositoryLabelProvider(),
179
				PlatformUI.getWorkbench().getDecoratorManager().getLabelDecorator()));
167
				PlatformUI.getWorkbench().getDecoratorManager().getLabelDecorator()));
180
168
181
		viewer.setSorter(new TaskRepositoriesSorter());
169
		viewer.setSorter(new TaskRepositoriesViewSorter());
182
170
183
//				new ViewerSorter() {
184
//
185
//			@Override
186
//			public int compare(Viewer viewer, Object e1, Object e2) {
187
//				if (e1 instanceof TaskRepository && e2 instanceof TaskRepository) {
188
//					TaskRepository t1 = (TaskRepository) e1;
189
//					TaskRepository t2 = (TaskRepository) e2;
190
//					return (t1.getKind() + t1.getUrl()).compareTo(t2.getKind() + t2.getUrl());
191
//				} else {
192
//					return super.compare(viewer, e1, e2);
193
//				}
194
//			}
195
//		});
196
		viewer.setInput(getViewSite());
171
		viewer.setInput(getViewSite());
197
		viewer.addDoubleClickListener(new IDoubleClickListener() {
172
		viewer.addDoubleClickListener(new IDoubleClickListener() {
198
			public void doubleClick(DoubleClickEvent event) {
173
			public void doubleClick(DoubleClickEvent event) {
Lines 208-220 Link Here
208
			}
183
			}
209
		});
184
		});
210
185
211
		// FIXME remove listener when view is disposed
186
		final IThemeManager themeManager = getSite().getWorkbenchWindow().getWorkbench().getThemeManager();
212
		TasksUi.getRepositoryManager().addListener(new TaskRepositoryListener());
187
		new GradientDrawer(themeManager, getViewer()) {
188
			@Override
189
			protected boolean shouldApplyGradient(org.eclipse.swt.widgets.Event event) {
190
				return event.item.getData() instanceof Category;
191
			}
192
		};
213
193
214
		makeActions();
194
		makeActions();
215
		hookContextMenu();
195
		hookContextMenu();
216
		hookGlobalActions();
196
		hookGlobalActions();
217
		contributeToActionBars();
197
		contributeToActionBars();
198
		getViewer().expandAll();
218
		getSite().setSelectionProvider(getViewer());
199
		getSite().setSelectionProvider(getViewer());
219
	}
200
	}
220
201
Lines 288-315 Link Here
288
	public void refresh() {
269
	public void refresh() {
289
		if (viewer != null && !viewer.getControl().isDisposed()) {
270
		if (viewer != null && !viewer.getControl().isDisposed()) {
290
			viewer.refresh();
271
			viewer.refresh();
272
			viewer.expandAll();
291
		}
273
		}
292
	}
274
	}
293
275
294
	public TableViewer getViewer() {
276
	public TreeViewer getViewer() {
295
		return viewer;
277
		return viewer;
296
	}
278
	}
297
279
298
	public class TaskRepositoryListener extends TaskRepositoryAdapter {
299
300
		@Override
301
		public void repositorySettingsChanged(TaskRepository repository) {
302
			if (PlatformUI.isWorkbenchRunning() && !PlatformUI.getWorkbench().getDisplay().isDisposed()) {
303
				PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
304
					public void run() {
305
						if (!getViewer().getControl().isDisposed()) {
306
							getViewer().refresh(true);
307
						}
308
					}
309
				});
310
			}
311
		}
312
313
	}
314
315
}
280
}
(-)src/org/eclipse/mylyn/internal/tasks/ui/views/TaskListView.java (-1 / +24 lines)
Lines 64-69 Link Here
64
import org.eclipse.mylyn.internal.tasks.core.ITaskListChangeListener;
64
import org.eclipse.mylyn.internal.tasks.core.ITaskListChangeListener;
65
import org.eclipse.mylyn.internal.tasks.core.ITasksCoreConstants;
65
import org.eclipse.mylyn.internal.tasks.core.ITasksCoreConstants;
66
import org.eclipse.mylyn.internal.tasks.core.TaskContainerDelta;
66
import org.eclipse.mylyn.internal.tasks.core.TaskContainerDelta;
67
import org.eclipse.mylyn.internal.tasks.core.notifications.ServiceMessageEvent;
68
import org.eclipse.mylyn.internal.tasks.core.notifications.ServiceMessageManager;
69
import org.eclipse.mylyn.internal.tasks.core.notifications.ServiceMessageEvent.EVENT_KIND;
67
import org.eclipse.mylyn.internal.tasks.ui.AbstractTaskListFilter;
70
import org.eclipse.mylyn.internal.tasks.ui.AbstractTaskListFilter;
68
import org.eclipse.mylyn.internal.tasks.ui.CategorizedPresentation;
71
import org.eclipse.mylyn.internal.tasks.ui.CategorizedPresentation;
69
import org.eclipse.mylyn.internal.tasks.ui.ITasksUiPreferenceConstants;
72
import org.eclipse.mylyn.internal.tasks.ui.ITasksUiPreferenceConstants;
Lines 86-91 Link Here
86
import org.eclipse.mylyn.internal.tasks.ui.actions.TaskListSortAction;
89
import org.eclipse.mylyn.internal.tasks.ui.actions.TaskListSortAction;
87
import org.eclipse.mylyn.internal.tasks.ui.actions.TaskListViewActionGroup;
90
import org.eclipse.mylyn.internal.tasks.ui.actions.TaskListViewActionGroup;
88
import org.eclipse.mylyn.internal.tasks.ui.editors.TaskListChangeAdapter;
91
import org.eclipse.mylyn.internal.tasks.ui.editors.TaskListChangeAdapter;
92
import org.eclipse.mylyn.internal.tasks.ui.notifications.TaskListServiceMessageControl;
89
import org.eclipse.mylyn.internal.tasks.ui.util.PlatformUtil;
93
import org.eclipse.mylyn.internal.tasks.ui.util.PlatformUtil;
90
import org.eclipse.mylyn.internal.tasks.ui.util.SortCriterion;
94
import org.eclipse.mylyn.internal.tasks.ui.util.SortCriterion;
91
import org.eclipse.mylyn.internal.tasks.ui.util.TaskDragSourceListener;
95
import org.eclipse.mylyn.internal.tasks.ui.util.TaskDragSourceListener;
Lines 131-136 Link Here
131
import org.eclipse.swt.graphics.Image;
135
import org.eclipse.swt.graphics.Image;
132
import org.eclipse.swt.graphics.Point;
136
import org.eclipse.swt.graphics.Point;
133
import org.eclipse.swt.graphics.Rectangle;
137
import org.eclipse.swt.graphics.Rectangle;
138
import org.eclipse.swt.layout.GridLayout;
134
import org.eclipse.swt.widgets.Composite;
139
import org.eclipse.swt.widgets.Composite;
135
import org.eclipse.swt.widgets.Menu;
140
import org.eclipse.swt.widgets.Menu;
136
import org.eclipse.swt.widgets.Text;
141
import org.eclipse.swt.widgets.Text;
Lines 390-395 Link Here
390
395
391
	private CustomTaskListDecorationDrawer customDrawer;
396
	private CustomTaskListDecorationDrawer customDrawer;
392
397
398
	private TaskListServiceMessageControl serviceMessageControl;
399
393
	private final IPageListener PAGE_LISTENER = new IPageListener() {
400
	private final IPageListener PAGE_LISTENER = new IPageListener() {
394
		public void pageActivated(IWorkbenchPage page) {
401
		public void pageActivated(IWorkbenchPage page) {
395
			filteredTree.indicateActiveTaskWorkingSet();
402
			filteredTree.indicateActiveTaskWorkingSet();
Lines 554-559 Link Here
554
	@Override
561
	@Override
555
	public void dispose() {
562
	public void dispose() {
556
		super.dispose();
563
		super.dispose();
564
		TasksUiPlugin.getDefault().getServiceMessageManager().removeServiceMessageListener(serviceMessageControl);
557
		TasksUiPlugin.getDefault().getPreferenceStore().removePropertyChangeListener(tasksUiPreferenceListener);
565
		TasksUiPlugin.getDefault().getPreferenceStore().removePropertyChangeListener(tasksUiPreferenceListener);
558
		TasksUiInternal.getTaskList().removeChangeListener(TASKLIST_CHANGE_LISTENER);
566
		TasksUiInternal.getTaskList().removeChangeListener(TASKLIST_CHANGE_LISTENER);
559
		TasksUiPlugin.getTaskActivityManager().removeActivityListener(TASK_ACTIVITY_LISTENER);
567
		TasksUiPlugin.getTaskActivityManager().removeActivityListener(TASK_ACTIVITY_LISTENER);
Lines 730-735 Link Here
730
738
731
	@Override
739
	@Override
732
	public void createPartControl(Composite parent) {
740
	public void createPartControl(Composite parent) {
741
		Composite body = new Composite(parent, SWT.NONE);
742
		GridLayout layout = new GridLayout(1, false);
743
		layout.marginHeight = 0;
744
		layout.marginWidth = 0;
745
		layout.horizontalSpacing = 0;
746
		layout.verticalSpacing = 0;
747
		layout.numColumns = 1;
748
		body.setLayout(layout);
749
733
		IWorkbenchSiteProgressService progress = (IWorkbenchSiteProgressService) getSite().getAdapter(
750
		IWorkbenchSiteProgressService progress = (IWorkbenchSiteProgressService) getSite().getAdapter(
734
				IWorkbenchSiteProgressService.class);
751
				IWorkbenchSiteProgressService.class);
735
		if (progress != null) {
752
		if (progress != null) {
Lines 743-749 Link Here
743
		themeManager = getSite().getWorkbenchWindow().getWorkbench().getThemeManager();
760
		themeManager = getSite().getWorkbenchWindow().getWorkbench().getThemeManager();
744
		themeManager.addPropertyChangeListener(THEME_CHANGE_LISTENER);
761
		themeManager.addPropertyChangeListener(THEME_CHANGE_LISTENER);
745
762
746
		filteredTree = new TaskListFilteredTree(parent, SWT.MULTI | SWT.VERTICAL | /* SWT.H_SCROLL | */SWT.V_SCROLL
763
		filteredTree = new TaskListFilteredTree(body, SWT.MULTI | SWT.VERTICAL | /* SWT.H_SCROLL | */SWT.V_SCROLL
747
				| SWT.NO_SCROLL | SWT.FULL_SELECTION, new SubstringPatternFilter(), getViewSite().getWorkbenchWindow());
764
				| SWT.NO_SCROLL | SWT.FULL_SELECTION, new SubstringPatternFilter(), getViewSite().getWorkbenchWindow());
748
765
749
		// need to do initialize tooltip early for native tooltip disablement to take effect
766
		// need to do initialize tooltip early for native tooltip disablement to take effect
Lines 923-928 Link Here
923
940
924
		TasksUiPlugin.getDefault().getPreferenceStore().addPropertyChangeListener(tasksUiPreferenceListener);
941
		TasksUiPlugin.getDefault().getPreferenceStore().addPropertyChangeListener(tasksUiPreferenceListener);
925
942
943
		serviceMessageControl = new TaskListServiceMessageControl(body);
944
		ServiceMessageManager manager = TasksUiPlugin.getDefault().getServiceMessageManager();
945
		serviceMessageControl.handleEvent(new ServiceMessageEvent(manager, EVENT_KIND.MESSAGE_UPDATE,
946
				manager.getServiceMessages()));
947
		TasksUiPlugin.getDefault().getServiceMessageManager().addServiceMessageListener(serviceMessageControl);
948
926
		// Need to do this because the page, which holds the active working set is not around on creation, see bug 203179
949
		// Need to do this because the page, which holds the active working set is not around on creation, see bug 203179
927
		PlatformUI.getWorkbench().getActiveWorkbenchWindow().addPageListener(PAGE_LISTENER);
950
		PlatformUI.getWorkbench().getActiveWorkbenchWindow().addPageListener(PAGE_LISTENER);
928
	}
951
	}
(-)src/org/eclipse/mylyn/internal/tasks/ui/preferences/Messages.java (+2 lines)
Lines 63-68 Link Here
63
63
64
	public static String TasksUiPreferencePage_See_X_for_configuring_Task_List_colors;
64
	public static String TasksUiPreferencePage_See_X_for_configuring_Task_List_colors;
65
65
66
	public static String TasksUiPreferencePage_show_service_messages;
67
66
	public static String TasksUiPreferencePage_Show_tooltip_on_hover_Label;
68
	public static String TasksUiPreferencePage_Show_tooltip_on_hover_Label;
67
69
68
	public static String TasksUiPreferencePage_Specify_the_folder_for_tasks;
70
	public static String TasksUiPreferencePage_Specify_the_folder_for_tasks;
(-)src/org/eclipse/mylyn/internal/tasks/ui/preferences/TasksUiPreferencePage.java (-26 / +53 lines)
Lines 109-114 Link Here
109
109
110
	private Button taskListTooltipEnabledButton;
110
	private Button taskListTooltipEnabledButton;
111
111
112
	private Button taskListServiceMessageEnabledButton;
113
112
	public TasksUiPreferencePage() {
114
	public TasksUiPreferencePage() {
113
		super();
115
		super();
114
		setPreferenceStore(TasksUiPlugin.getDefault().getPreferenceStore());
116
		setPreferenceStore(TasksUiPlugin.getDefault().getPreferenceStore());
Lines 208-223 Link Here
208
		getPreferenceStore().setValue(ITasksUiPreferenceConstants.TASK_LIST_TOOL_TIPS_ENABLED,
210
		getPreferenceStore().setValue(ITasksUiPreferenceConstants.TASK_LIST_TOOL_TIPS_ENABLED,
209
				taskListTooltipEnabledButton.getSelection());
211
				taskListTooltipEnabledButton.getSelection());
210
212
213
		getPreferenceStore().setValue(ITasksUiPreferenceConstants.SERVICE_MESSAGES_ENABLED,
214
				taskListServiceMessageEnabledButton.getSelection());
215
211
		getPreferenceStore().setValue(ITasksUiPreferenceConstants.WEEK_START_DAY, getWeekStartValue());
216
		getPreferenceStore().setValue(ITasksUiPreferenceConstants.WEEK_START_DAY, getWeekStartValue());
212
		//getPreferenceStore().setValue(TasksUiPreferenceConstants.PLANNING_STARTHOUR, hourDayStart.getSelection());
217
		//getPreferenceStore().setValue(TasksUiPreferenceConstants.PLANNING_STARTHOUR, hourDayStart.getSelection());
213
//		getPreferenceStore().setValue(TasksUiPreferenceConstants.PLANNING_ENDHOUR, hourDayEnd.getSelection());
218
//		getPreferenceStore().setValue(TasksUiPreferenceConstants.PLANNING_ENDHOUR, hourDayEnd.getSelection());
214
		MonitorUiPlugin.getDefault().getPreferenceStore().setValue(ActivityContextManager.ACTIVITY_TIMEOUT_ENABLED,
219
		MonitorUiPlugin.getDefault()
215
				timeoutEnabledButton.getSelection());
220
				.getPreferenceStore()
216
		MonitorUiPlugin.getDefault().getPreferenceStore().setValue(ActivityContextManager.ACTIVITY_TIMEOUT,
221
				.setValue(ActivityContextManager.ACTIVITY_TIMEOUT_ENABLED, timeoutEnabledButton.getSelection());
217
				timeoutMinutes.getSelection() * (60 * 1000));
222
		MonitorUiPlugin.getDefault()
218
223
				.getPreferenceStore()
219
		MonitorUiPlugin.getDefault().getPreferenceStore().setValue(MonitorUiPlugin.ACTIVITY_TRACKING_ENABLED,
224
				.setValue(ActivityContextManager.ACTIVITY_TIMEOUT, timeoutMinutes.getSelection() * (60 * 1000));
220
				activityTrackingEnabledButton.getSelection());
225
226
		MonitorUiPlugin.getDefault()
227
				.getPreferenceStore()
228
				.setValue(MonitorUiPlugin.ACTIVITY_TRACKING_ENABLED, activityTrackingEnabledButton.getSelection());
221
229
222
		String taskDirectory = taskDirectoryText.getText();
230
		String taskDirectory = taskDirectoryText.getText();
223
		taskDirectory = taskDirectory.replaceAll(BACKSLASH_MULTI, FORWARDSLASH);
231
		taskDirectory = taskDirectory.replaceAll(BACKSLASH_MULTI, FORWARDSLASH);
Lines 276-281 Link Here
276
		taskListTooltipEnabledButton.setSelection(getPreferenceStore().getBoolean(
284
		taskListTooltipEnabledButton.setSelection(getPreferenceStore().getBoolean(
277
				ITasksUiPreferenceConstants.TASK_LIST_TOOL_TIPS_ENABLED));
285
				ITasksUiPreferenceConstants.TASK_LIST_TOOL_TIPS_ENABLED));
278
286
287
		taskListServiceMessageEnabledButton.setSelection(getPreferenceStore().getBoolean(
288
				ITasksUiPreferenceConstants.SERVICE_MESSAGES_ENABLED));
289
279
		weekStartCombo.select(getPreferenceStore().getInt(ITasksUiPreferenceConstants.WEEK_START_DAY) - 1);
290
		weekStartCombo.select(getPreferenceStore().getInt(ITasksUiPreferenceConstants.WEEK_START_DAY) - 1);
280
		//hourDayStart.setSelection(getPreferenceStore().getInt(TasksUiPreferenceConstants.PLANNING_STARTHOUR));
291
		//hourDayStart.setSelection(getPreferenceStore().getInt(TasksUiPreferenceConstants.PLANNING_STARTHOUR));
281
//		hourDayEnd.setSelection(getPreferenceStore().getInt(TasksUiPreferenceConstants.PLANNING_ENDHOUR));
292
//		hourDayEnd.setSelection(getPreferenceStore().getInt(TasksUiPreferenceConstants.PLANNING_ENDHOUR));
Lines 283-293 Link Here
283
		int minutes = MonitorUiPlugin.getDefault().getPreferenceStore().getInt(ActivityContextManager.ACTIVITY_TIMEOUT)
294
		int minutes = MonitorUiPlugin.getDefault().getPreferenceStore().getInt(ActivityContextManager.ACTIVITY_TIMEOUT)
284
				/ MS_MINUTES;
295
				/ MS_MINUTES;
285
		timeoutMinutes.setSelection(minutes);
296
		timeoutMinutes.setSelection(minutes);
286
		timeoutEnabledButton.setSelection(MonitorUiPlugin.getDefault().getPreferenceStore().getBoolean(
297
		timeoutEnabledButton.setSelection(MonitorUiPlugin.getDefault()
287
				ActivityContextManager.ACTIVITY_TIMEOUT_ENABLED));
298
				.getPreferenceStore()
288
299
				.getBoolean(ActivityContextManager.ACTIVITY_TIMEOUT_ENABLED));
289
		activityTrackingEnabledButton.setSelection(MonitorUiPlugin.getDefault().getPreferenceStore().getBoolean(
300
290
				MonitorUiPlugin.ACTIVITY_TRACKING_ENABLED));
301
		activityTrackingEnabledButton.setSelection(MonitorUiPlugin.getDefault()
302
				.getPreferenceStore()
303
				.getBoolean(MonitorUiPlugin.ACTIVITY_TRACKING_ENABLED));
291
304
292
		return true;
305
		return true;
293
	}
306
	}
Lines 310-315 Link Here
310
		taskListTooltipEnabledButton.setSelection(getPreferenceStore().getDefaultBoolean(
323
		taskListTooltipEnabledButton.setSelection(getPreferenceStore().getDefaultBoolean(
311
				ITasksUiPreferenceConstants.TASK_LIST_TOOL_TIPS_ENABLED));
324
				ITasksUiPreferenceConstants.TASK_LIST_TOOL_TIPS_ENABLED));
312
325
326
		taskListServiceMessageEnabledButton.setSelection(getPreferenceStore().getDefaultBoolean(
327
				ITasksUiPreferenceConstants.SERVICE_MESSAGES_ENABLED));
328
313
		// synchQueries.setSelection(getPreferenceStore().getDefaultBoolean(
329
		// synchQueries.setSelection(getPreferenceStore().getDefaultBoolean(
314
		// TaskListPreferenceConstants.REPOSITORY_SYNCH_ON_STARTUP));
330
		// TaskListPreferenceConstants.REPOSITORY_SYNCH_ON_STARTUP));
315
		enableBackgroundSynch.setSelection(getPreferenceStore().getDefaultBoolean(
331
		enableBackgroundSynch.setSelection(getPreferenceStore().getDefaultBoolean(
Lines 322-336 Link Here
322
		weekStartCombo.select(getPreferenceStore().getDefaultInt(ITasksUiPreferenceConstants.WEEK_START_DAY) - 1);
338
		weekStartCombo.select(getPreferenceStore().getDefaultInt(ITasksUiPreferenceConstants.WEEK_START_DAY) - 1);
323
		//	hourDayStart.setSelection(getPreferenceStore().getDefaultInt(TasksUiPreferenceConstants.PLANNING_STARTHOUR));
339
		//	hourDayStart.setSelection(getPreferenceStore().getDefaultInt(TasksUiPreferenceConstants.PLANNING_STARTHOUR));
324
//		hourDayEnd.setSelection(getPreferenceStore().getDefaultInt(TasksUiPreferenceConstants.PLANNING_ENDHOUR));
340
//		hourDayEnd.setSelection(getPreferenceStore().getDefaultInt(TasksUiPreferenceConstants.PLANNING_ENDHOUR));
325
		int activityTimeoutMinutes = MonitorUiPlugin.getDefault().getPreferenceStore().getDefaultInt(
341
		int activityTimeoutMinutes = MonitorUiPlugin.getDefault()
326
				ActivityContextManager.ACTIVITY_TIMEOUT)
342
				.getPreferenceStore()
343
				.getDefaultInt(ActivityContextManager.ACTIVITY_TIMEOUT)
327
				/ MS_MINUTES;
344
				/ MS_MINUTES;
328
		timeoutMinutes.setSelection(activityTimeoutMinutes);
345
		timeoutMinutes.setSelection(activityTimeoutMinutes);
329
		timeoutEnabledButton.setSelection(MonitorUiPlugin.getDefault().getPreferenceStore().getDefaultBoolean(
346
		timeoutEnabledButton.setSelection(MonitorUiPlugin.getDefault()
330
				ActivityContextManager.ACTIVITY_TIMEOUT_ENABLED));
347
				.getPreferenceStore()
331
348
				.getDefaultBoolean(ActivityContextManager.ACTIVITY_TIMEOUT_ENABLED));
332
		activityTrackingEnabledButton.setSelection(MonitorUiPlugin.getDefault().getPreferenceStore().getDefaultBoolean(
349
333
				MonitorUiPlugin.ACTIVITY_TRACKING_ENABLED));
350
		activityTrackingEnabledButton.setSelection(MonitorUiPlugin.getDefault()
351
				.getPreferenceStore()
352
				.getDefaultBoolean(MonitorUiPlugin.ACTIVITY_TRACKING_ENABLED));
334
353
335
		updateRefreshGroupEnablements();
354
		updateRefreshGroupEnablements();
336
	}
355
	}
Lines 480-485 Link Here
480
		taskListTooltipEnabledButton.setText(Messages.TasksUiPreferencePage_Show_tooltip_on_hover_Label);
499
		taskListTooltipEnabledButton.setText(Messages.TasksUiPreferencePage_Show_tooltip_on_hover_Label);
481
		taskListTooltipEnabledButton.setSelection(getPreferenceStore().getBoolean(
500
		taskListTooltipEnabledButton.setSelection(getPreferenceStore().getBoolean(
482
				ITasksUiPreferenceConstants.TASK_LIST_TOOL_TIPS_ENABLED));
501
				ITasksUiPreferenceConstants.TASK_LIST_TOOL_TIPS_ENABLED));
502
503
		taskListServiceMessageEnabledButton = new Button(group, SWT.CHECK);
504
		taskListServiceMessageEnabledButton.setText(Messages.TasksUiPreferencePage_show_service_messages);
505
		taskListServiceMessageEnabledButton.setSelection(getPreferenceStore().getBoolean(
506
				ITasksUiPreferenceConstants.SERVICE_MESSAGES_ENABLED));
483
	}
507
	}
484
508
485
	private void createTaskActivityGroup(Composite container) {
509
	private void createTaskActivityGroup(Composite container) {
Lines 488-498 Link Here
488
		group.setLayout(new GridLayout(3, false));
512
		group.setLayout(new GridLayout(3, false));
489
		group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
513
		group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
490
514
491
		boolean activityTrackingEnabled = MonitorUiPlugin.getDefault().getPreferenceStore().getBoolean(
515
		boolean activityTrackingEnabled = MonitorUiPlugin.getDefault()
492
				MonitorUiPlugin.ACTIVITY_TRACKING_ENABLED);
516
				.getPreferenceStore()
493
517
				.getBoolean(MonitorUiPlugin.ACTIVITY_TRACKING_ENABLED);
494
		boolean timeoutEnabled = MonitorUiPlugin.getDefault().getPreferenceStore().getBoolean(
518
495
				ActivityContextManager.ACTIVITY_TIMEOUT_ENABLED);
519
		boolean timeoutEnabled = MonitorUiPlugin.getDefault()
520
				.getPreferenceStore()
521
				.getBoolean(ActivityContextManager.ACTIVITY_TIMEOUT_ENABLED);
496
522
497
		activityTrackingEnabledButton = new Button(group, SWT.CHECK);
523
		activityTrackingEnabledButton = new Button(group, SWT.CHECK);
498
		activityTrackingEnabledButton.setText(Messages.TasksUiPreferencePage_Enable_Time_Tracking);
524
		activityTrackingEnabledButton.setText(Messages.TasksUiPreferencePage_Enable_Time_Tracking);
Lines 525-532 Link Here
525
		timeoutMinutes.setIncrement(5);
551
		timeoutMinutes.setIncrement(5);
526
		timeoutMinutes.setMaximum(60);
552
		timeoutMinutes.setMaximum(60);
527
		timeoutMinutes.setMinimum(1);
553
		timeoutMinutes.setMinimum(1);
528
		long minutes = MonitorUiPlugin.getDefault().getPreferenceStore().getLong(
554
		long minutes = MonitorUiPlugin.getDefault()
529
				ActivityContextManager.ACTIVITY_TIMEOUT)
555
				.getPreferenceStore()
556
				.getLong(ActivityContextManager.ACTIVITY_TIMEOUT)
530
				/ MS_MINUTES;
557
				/ MS_MINUTES;
531
		timeoutMinutes.setSelection((int) minutes);
558
		timeoutMinutes.setSelection((int) minutes);
532
		timeoutMinutes.addSelectionListener(new SelectionAdapter() {
559
		timeoutMinutes.addSelectionListener(new SelectionAdapter() {
(-)src/org/eclipse/mylyn/internal/tasks/ui/preferences/messages.properties (+1 lines)
Lines 27-32 Link Here
27
TasksUiPreferencePage_Rich_Editor__Recommended_=Rich Editor (Recommended)
27
TasksUiPreferencePage_Rich_Editor__Recommended_=Rich Editor (Recommended)
28
TasksUiPreferencePage_Scheduling=Scheduling
28
TasksUiPreferencePage_Scheduling=Scheduling
29
TasksUiPreferencePage_See_X_for_configuring_Task_List_colors=See <a>''{0}''</a> for configuring Task List colors.
29
TasksUiPreferencePage_See_X_for_configuring_Task_List_colors=See <a>''{0}''</a> for configuring Task List colors.
30
TasksUiPreferencePage_show_service_messages=Show service messages
30
TasksUiPreferencePage_Show_tooltip_on_hover_Label=Show task overview popups on hover
31
TasksUiPreferencePage_Show_tooltip_on_hover_Label=Show task overview popups on hover
31
TasksUiPreferencePage_Specify_the_folder_for_tasks=Specify the folder for tasks
32
TasksUiPreferencePage_Specify_the_folder_for_tasks=Specify the folder for tasks
32
TasksUiPreferencePage_Stop_time_accumulation_after=Stop time accumulation after
33
TasksUiPreferencePage_Stop_time_accumulation_after=Stop time accumulation after
(-)src/org/eclipse/mylyn/internal/tasks/ui/ITasksUiPreferenceConstants.java (+10 lines)
Lines 52-57 Link Here
52
52
53
	public static final String NOTIFICATIONS_ENABLED = "org.eclipse.mylyn.tasks.ui.notifications.enabled"; //$NON-NLS-1$
53
	public static final String NOTIFICATIONS_ENABLED = "org.eclipse.mylyn.tasks.ui.notifications.enabled"; //$NON-NLS-1$
54
54
55
	public static final String SERVICE_MESSAGES_ENABLED = "org.eclipse.mylyn.tasks.ui.messages.enabled"; //$NON-NLS-1$
56
55
	public static final String WEEK_START_DAY = "org.eclipse.mylyn.tasks.ui.planning.week.start.day"; //$NON-NLS-1$
57
	public static final String WEEK_START_DAY = "org.eclipse.mylyn.tasks.ui.planning.week.start.day"; //$NON-NLS-1$
56
58
57
	public static final String PLANNING_ENDHOUR = "org.eclipse.mylyn.tasks.ui.planning.end.hour"; //$NON-NLS-1$
59
	public static final String PLANNING_ENDHOUR = "org.eclipse.mylyn.tasks.ui.planning.end.hour"; //$NON-NLS-1$
Lines 87-90 Link Here
87
	public static final String PREF_DATA_DIR = "org.eclipse.mylyn.data.dir"; //$NON-NLS-1$
89
	public static final String PREF_DATA_DIR = "org.eclipse.mylyn.data.dir"; //$NON-NLS-1$
88
90
89
	public static final String DEFAULT_ATTACHMENTS_DIRECTORY = "org.eclipse.mylyn.tasks.ui.attachments.defaultDirectory"; //$NON-NLS-1$
91
	public static final String DEFAULT_ATTACHMENTS_DIRECTORY = "org.eclipse.mylyn.tasks.ui.attachments.defaultDirectory"; //$NON-NLS-1$
92
93
	public static final String SERVICE_MESSAGE_URL = "org.eclipse.mylyn.tasks.ui.servicemessage.url"; //$NON-NLS-1$;
94
95
	public static final String LAST_SERVICE_MESSAGE_ID = "org.eclipse.mylyn.tasks.ui.servicemessage.id"; //$NON-NLS-1$
96
97
	public static final String LAST_SERVICE_MESSAGE_ETAG = "org.eclipse.mylyn.tasks.ui.servicemessage.etag"; //$NON-NLS-1$
98
99
	public static final String LAST_SERVICE_MESSAGE_LAST_MODIFIED = "org.eclipse.mylyn.tasks.ui.servicemessage.lastmodified"; //$NON-NLS-1$
90
}
100
}
(-)src/org/eclipse/mylyn/internal/tasks/ui/TasksUiPlugin.java (-1 / +31 lines)
Lines 77-82 Link Here
77
import org.eclipse.mylyn.internal.tasks.core.externalization.IExternalizationParticipant;
77
import org.eclipse.mylyn.internal.tasks.core.externalization.IExternalizationParticipant;
78
import org.eclipse.mylyn.internal.tasks.core.externalization.TaskListExternalizationParticipant;
78
import org.eclipse.mylyn.internal.tasks.core.externalization.TaskListExternalizationParticipant;
79
import org.eclipse.mylyn.internal.tasks.core.externalization.TaskListExternalizer;
79
import org.eclipse.mylyn.internal.tasks.core.externalization.TaskListExternalizer;
80
import org.eclipse.mylyn.internal.tasks.core.notifications.ServiceMessageManager;
80
import org.eclipse.mylyn.internal.tasks.ui.notifications.TaskListNotificationReminder;
81
import org.eclipse.mylyn.internal.tasks.ui.notifications.TaskListNotificationReminder;
81
import org.eclipse.mylyn.internal.tasks.ui.notifications.TaskListNotifier;
82
import org.eclipse.mylyn.internal.tasks.ui.notifications.TaskListNotifier;
82
import org.eclipse.mylyn.internal.tasks.ui.util.TasksUiExtensionReader;
83
import org.eclipse.mylyn.internal.tasks.ui.util.TasksUiExtensionReader;
Lines 149-154 Link Here
149
150
150
	private RepositoryTemplateManager repositoryTemplateManager;
151
	private RepositoryTemplateManager repositoryTemplateManager;
151
152
153
	private ServiceMessageManager serviceMessageManager;
154
152
	private final Set<AbstractTaskEditorPageFactory> taskEditorPageFactories = new HashSet<AbstractTaskEditorPageFactory>();
155
	private final Set<AbstractTaskEditorPageFactory> taskEditorPageFactories = new HashSet<AbstractTaskEditorPageFactory>();
153
156
154
	private final TreeSet<AbstractTaskRepositoryLinkProvider> repositoryLinkProviders = new TreeSet<AbstractTaskRepositoryLinkProvider>(
157
	private final TreeSet<AbstractTaskRepositoryLinkProvider> repositoryLinkProviders = new TreeSet<AbstractTaskRepositoryLinkProvider>(
Lines 343-348 Link Here
343
					|| event.getProperty().equals(ITasksUiPreferenceConstants.REPOSITORY_SYNCH_SCHEDULE_MILISECONDS)) {
346
					|| event.getProperty().equals(ITasksUiPreferenceConstants.REPOSITORY_SYNCH_SCHEDULE_MILISECONDS)) {
344
				updateSynchronizationScheduler(false);
347
				updateSynchronizationScheduler(false);
345
			}
348
			}
349
350
			if (event.getProperty().equals(ITasksUiPreferenceConstants.SERVICE_MESSAGES_ENABLED)) {
351
				if (getPreferenceStore().getBoolean(ITasksUiPreferenceConstants.SERVICE_MESSAGES_ENABLED)) {
352
					serviceMessageManager.start();
353
				} else {
354
					serviceMessageManager.stop();
355
				}
356
			}
346
		}
357
		}
347
	};
358
	};
348
359
Lines 552-558 Link Here
552
563
553
			// NOTE: initializing extensions in start(..) has caused race
564
			// NOTE: initializing extensions in start(..) has caused race
554
			// conditions previously
565
			// conditions previously
555
			TasksUiExtensionReader.initStartupExtensions(taskListExternalizer);
566
			TasksUiExtensionReader.initStartupExtensions(taskListExternalizer, repositoryManager);
556
567
557
			// instantiate taskDataManager
568
			// instantiate taskDataManager
558
			TaskDataStore taskDataStore = new TaskDataStore(repositoryManager);
569
			TaskDataStore taskDataStore = new TaskDataStore(repositoryManager);
Lines 605-610 Link Here
605
			// make this available early for clients that are not initialized through tasks ui but need access 
616
			// make this available early for clients that are not initialized through tasks ui but need access 
606
			taskListNotificationManager = new TaskListNotificationManager();
617
			taskListNotificationManager = new TaskListNotificationManager();
607
618
619
			String lastMod = getPreferenceStore().getString(
620
					ITasksUiPreferenceConstants.LAST_SERVICE_MESSAGE_LAST_MODIFIED);
621
			String etag = getPreferenceStore().getString(ITasksUiPreferenceConstants.LAST_SERVICE_MESSAGE_ETAG);
622
623
			serviceMessageManager = new ServiceMessageManager(getPreferenceStore().getString(
624
					ITasksUiPreferenceConstants.SERVICE_MESSAGE_URL), lastMod, etag);
625
626
			if (getPreferenceStore().getBoolean(ITasksUiPreferenceConstants.SERVICE_MESSAGES_ENABLED)) {
627
				serviceMessageManager.start();
628
			}
629
608
			// trigger lazy initialization
630
			// trigger lazy initialization
609
			new TasksUiInitializationJob().schedule();
631
			new TasksUiInitializationJob().schedule();
610
		} catch (Exception e) {
632
		} catch (Exception e) {
Lines 727-732 Link Here
727
//					ContextCorePlugin.getDefault().getPluginPreferences().removePropertyChangeListener(
749
//					ContextCorePlugin.getDefault().getPluginPreferences().removePropertyChangeListener(
728
//							PREFERENCE_LISTENER);
750
//							PREFERENCE_LISTENER);
729
//				}
751
//				}
752
				serviceMessageManager.stop();
730
				taskEditorBloatManager.dispose(PlatformUI.getWorkbench());
753
				taskEditorBloatManager.dispose(PlatformUI.getWorkbench());
731
				INSTANCE = null;
754
				INSTANCE = null;
732
			}
755
			}
Lines 868-873 Link Here
868
		store.setDefault(ITasksUiPreferenceConstants.PREF_DATA_DIR, getDefaultDataDirectory());
891
		store.setDefault(ITasksUiPreferenceConstants.PREF_DATA_DIR, getDefaultDataDirectory());
869
		store.setDefault(ITasksUiPreferenceConstants.GROUP_SUBTASKS, true);
892
		store.setDefault(ITasksUiPreferenceConstants.GROUP_SUBTASKS, true);
870
		store.setDefault(ITasksUiPreferenceConstants.NOTIFICATIONS_ENABLED, true);
893
		store.setDefault(ITasksUiPreferenceConstants.NOTIFICATIONS_ENABLED, true);
894
		store.setDefault(ITasksUiPreferenceConstants.SERVICE_MESSAGES_ENABLED, true);
871
		store.setDefault(ITasksUiPreferenceConstants.FILTER_PRIORITY, PriorityLevel.P5.toString());
895
		store.setDefault(ITasksUiPreferenceConstants.FILTER_PRIORITY, PriorityLevel.P5.toString());
872
		store.setDefault(ITasksUiPreferenceConstants.EDITOR_TASKS_RICH, true);
896
		store.setDefault(ITasksUiPreferenceConstants.EDITOR_TASKS_RICH, true);
873
		store.setDefault(ITasksUiPreferenceConstants.EDITOR_CURRENT_LINE_HIGHLIGHT, false);
897
		store.setDefault(ITasksUiPreferenceConstants.EDITOR_CURRENT_LINE_HIGHLIGHT, false);
Lines 894-899 Link Here
894
918
895
		store.setDefault(ITasksUiPreferenceConstants.AUTO_EXPAND_TASK_LIST, true);
919
		store.setDefault(ITasksUiPreferenceConstants.AUTO_EXPAND_TASK_LIST, true);
896
		store.setDefault(ITasksUiPreferenceConstants.TASK_LIST_TOOL_TIPS_ENABLED, true);
920
		store.setDefault(ITasksUiPreferenceConstants.TASK_LIST_TOOL_TIPS_ENABLED, true);
921
922
		store.setDefault(ITasksUiPreferenceConstants.SERVICE_MESSAGE_URL, "http://eclipse.org/mylyn/message.xml"); //$NON-NLS-1$
897
	}
923
	}
898
924
899
	public static TaskActivityManager getTaskActivityManager() {
925
	public static TaskActivityManager getTaskActivityManager() {
Lines 1306-1309 Link Here
1306
		}
1332
		}
1307
	}
1333
	}
1308
1334
1335
	public ServiceMessageManager getServiceMessageManager() {
1336
		return serviceMessageManager;
1337
	}
1338
1309
}
1339
}
(-)schema/repositories.exsd (+21 lines)
Lines 24-29 Link Here
24
            <element ref="connectorCore"/>
24
            <element ref="connectorCore"/>
25
            <element ref="connectorUi" minOccurs="0" maxOccurs="1"/>
25
            <element ref="connectorUi" minOccurs="0" maxOccurs="1"/>
26
            <element ref="taskListMigrator" minOccurs="0" maxOccurs="1"/>
26
            <element ref="taskListMigrator" minOccurs="0" maxOccurs="1"/>
27
            <element ref="repositoryMigrator" minOccurs="0" maxOccurs="1"/>
27
         </sequence>
28
         </sequence>
28
         <attribute name="point" type="string" use="required">
29
         <attribute name="point" type="string" use="required">
29
            <annotation>
30
            <annotation>
Lines 169-174 Link Here
169
      </complexType>
170
      </complexType>
170
   </element>
171
   </element>
171
172
173
   <element name="repositoryMigrator">
174
      <annotation>
175
         <documentation>
176
            (no description available)
177
         </documentation>
178
      </annotation>
179
      <complexType>
180
         <attribute name="class" type="string" use="required">
181
            <annotation>
182
               <documentation>
183
                  
184
               </documentation>
185
               <appInfo>
186
                  <meta.attribute kind="java" basedOn="org.eclipse.mylyn.tasks.core.AbstractRepositoryMigrator:"/>
187
               </appInfo>
188
            </annotation>
189
         </attribute>
190
      </complexType>
191
   </element>
192
172
   <annotation>
193
   <annotation>
173
      <appInfo>
194
      <appInfo>
174
         <meta.section type="since"/>
195
         <meta.section type="since"/>
(-)src/org/eclipse/mylyn/internal/tasks/ui/util/TasksUiExtensionReader.java (-23 / +63 lines)
Lines 30-35 Link Here
30
import org.eclipse.jface.resource.ImageDescriptor;
30
import org.eclipse.jface.resource.ImageDescriptor;
31
import org.eclipse.mylyn.commons.core.StatusHandler;
31
import org.eclipse.mylyn.commons.core.StatusHandler;
32
import org.eclipse.mylyn.internal.provisional.commons.ui.CommonImages;
32
import org.eclipse.mylyn.internal.provisional.commons.ui.CommonImages;
33
import org.eclipse.mylyn.internal.tasks.core.TaskRepositoryManager;
33
import org.eclipse.mylyn.internal.tasks.core.externalization.TaskListExternalizer;
34
import org.eclipse.mylyn.internal.tasks.core.externalization.TaskListExternalizer;
34
import org.eclipse.mylyn.internal.tasks.ui.IDynamicSubMenuContributor;
35
import org.eclipse.mylyn.internal.tasks.ui.IDynamicSubMenuContributor;
35
import org.eclipse.mylyn.internal.tasks.ui.TasksUiPlugin;
36
import org.eclipse.mylyn.internal.tasks.ui.TasksUiPlugin;
Lines 37-42 Link Here
37
import org.eclipse.mylyn.internal.tasks.ui.views.TaskListView;
38
import org.eclipse.mylyn.internal.tasks.ui.views.TaskListView;
38
import org.eclipse.mylyn.tasks.core.AbstractDuplicateDetector;
39
import org.eclipse.mylyn.tasks.core.AbstractDuplicateDetector;
39
import org.eclipse.mylyn.tasks.core.AbstractRepositoryConnector;
40
import org.eclipse.mylyn.tasks.core.AbstractRepositoryConnector;
41
import org.eclipse.mylyn.tasks.core.AbstractRepositoryMigrator;
40
import org.eclipse.mylyn.tasks.core.AbstractTaskListMigrator;
42
import org.eclipse.mylyn.tasks.core.AbstractTaskListMigrator;
41
import org.eclipse.mylyn.tasks.core.RepositoryTemplate;
43
import org.eclipse.mylyn.tasks.core.RepositoryTemplate;
42
import org.eclipse.mylyn.tasks.ui.AbstractRepositoryConnectorUi;
44
import org.eclipse.mylyn.tasks.ui.AbstractRepositoryConnectorUi;
Lines 57-67 Link Here
57
59
58
		IConfigurationElement element;
60
		IConfigurationElement element;
59
61
60
		IConfigurationElement migratorElement;
62
		IConfigurationElement taskListMigratorElement;
63
64
		IConfigurationElement repositoryMigratorElement;
61
65
62
		AbstractRepositoryConnector repositoryConnector;
66
		AbstractRepositoryConnector repositoryConnector;
63
67
64
		AbstractTaskListMigrator migrator;
68
		AbstractTaskListMigrator taskListMigrator;
69
70
		AbstractRepositoryMigrator repositoryMigrator;
65
71
66
		private final String id;
72
		private final String id;
67
73
Lines 94-111 Link Here
94
			}
100
			}
95
		}
101
		}
96
102
97
		public IStatus createMigrator() {
103
		public IStatus createTaskListMigrator() {
98
			Assert.isTrue(migrator == null);
104
			Assert.isTrue(taskListMigrator == null);
99
			try {
105
			try {
100
				Object migratorObject = migratorElement.createExecutableExtension(ATTR_CLASS);
106
				Object migratorObject = taskListMigratorElement.createExecutableExtension(ATTR_CLASS);
101
				if (migratorObject instanceof AbstractTaskListMigrator) {
107
				if (migratorObject instanceof AbstractTaskListMigrator) {
102
					migrator = (AbstractTaskListMigrator) migratorObject;
108
					taskListMigrator = (AbstractTaskListMigrator) migratorObject;
103
					return Status.OK_STATUS;
109
					return Status.OK_STATUS;
104
				} else {
110
				} else {
105
					return new Status(
111
					return new Status(IStatus.ERROR, TasksUiPlugin.ID_PLUGIN,
106
							IStatus.ERROR,
112
							"Could not load task list migrator: " + migratorObject.getClass().getCanonicalName() //$NON-NLS-1$
107
							TasksUiPlugin.ID_PLUGIN,
108
							"Could not load task list migrator migrator: " + migratorObject.getClass().getCanonicalName() //$NON-NLS-1$
109
									+ " must implement " + AbstractTaskListMigrator.class.getCanonicalName()); //$NON-NLS-1$
113
									+ " must implement " + AbstractTaskListMigrator.class.getCanonicalName()); //$NON-NLS-1$
110
				}
114
				}
111
			} catch (Throwable e) {
115
			} catch (Throwable e) {
Lines 114-119 Link Here
114
			}
118
			}
115
		}
119
		}
116
120
121
		public IStatus createRepositoryMigrator() {
122
			Assert.isTrue(repositoryMigrator == null);
123
			try {
124
				Object migratorObject = repositoryMigratorElement.createExecutableExtension(ATTR_CLASS);
125
				if (migratorObject instanceof AbstractRepositoryMigrator) {
126
					repositoryMigrator = (AbstractRepositoryMigrator) migratorObject;
127
					return Status.OK_STATUS;
128
				} else {
129
					return new Status(IStatus.ERROR, TasksUiPlugin.ID_PLUGIN,
130
							"Could not load repository migrator: " + migratorObject.getClass().getCanonicalName() //$NON-NLS-1$
131
									+ " must implement " + AbstractRepositoryMigrator.class.getCanonicalName()); //$NON-NLS-1$
132
				}
133
			} catch (Throwable e) {
134
				return new Status(IStatus.ERROR, TasksUiPlugin.ID_PLUGIN,
135
						"Could not load repository migrator extension", e); //$NON-NLS-1$
136
			}
137
		}
138
117
		public String getPluginId() {
139
		public String getPluginId() {
118
			return element.getContributor().getName();
140
			return element.getContributor().getName();
119
		}
141
		}
Lines 158-163 Link Here
158
180
159
	public static final String ELMNT_MIGRATOR = "taskListMigrator"; //$NON-NLS-1$
181
	public static final String ELMNT_MIGRATOR = "taskListMigrator"; //$NON-NLS-1$
160
182
183
	public static final String ELMNT_REPOSITORY_MIGRATOR = "repositoryMigrator"; //$NON-NLS-1$
184
161
	public static final String ATTR_BRANDING_ICON = "brandingIcon"; //$NON-NLS-1$
185
	public static final String ATTR_BRANDING_ICON = "brandingIcon"; //$NON-NLS-1$
162
186
163
	public static final String ATTR_OVERLAY_ICON = "overlayIcon"; //$NON-NLS-1$
187
	public static final String ATTR_OVERLAY_ICON = "overlayIcon"; //$NON-NLS-1$
Lines 207-218 Link Here
207
	 */
231
	 */
208
	private static Set<String> disabledContributors = new HashSet<String>();
232
	private static Set<String> disabledContributors = new HashSet<String>();
209
233
210
	public static void initStartupExtensions(TaskListExternalizer taskListExternalizer) {
234
	public static void initStartupExtensions(TaskListExternalizer taskListExternalizer,
235
			TaskRepositoryManager repositoryManager) {
211
		if (!coreExtensionsRead) {
236
		if (!coreExtensionsRead) {
212
			IExtensionRegistry registry = Platform.getExtensionRegistry();
237
			IExtensionRegistry registry = Platform.getExtensionRegistry();
213
238
214
			// NOTE: has to be read first, consider improving
239
			// NOTE: has to be read first, consider improving
215
			initConnectorCores(taskListExternalizer, registry);
240
			initConnectorCores(taskListExternalizer, repositoryManager, registry);
216
241
217
			IExtensionPoint templatesExtensionPoint = registry.getExtensionPoint(EXTENSION_TEMPLATES);
242
			IExtensionPoint templatesExtensionPoint = registry.getExtensionPoint(EXTENSION_TEMPLATES);
218
			IExtension[] templateExtensions = templatesExtensionPoint.getExtensions();
243
			IExtension[] templateExtensions = templatesExtensionPoint.getExtensions();
Lines 256-262 Link Here
256
		}
281
		}
257
	}
282
	}
258
283
259
	private static void initConnectorCores(TaskListExternalizer taskListExternalizer, IExtensionRegistry registry) {
284
	private static void initConnectorCores(TaskListExternalizer taskListExternalizer,
285
			TaskRepositoryManager repositoryManager, IExtensionRegistry registry) {
260
		List<ConnectorDescriptor> descriptors = new ArrayList<ConnectorDescriptor>();
286
		List<ConnectorDescriptor> descriptors = new ArrayList<ConnectorDescriptor>();
261
		MultiStatus result = new MultiStatus(TasksUiPlugin.ID_PLUGIN, 0, "Repository connectors failed to load.", null); //$NON-NLS-1$
287
		MultiStatus result = new MultiStatus(TasksUiPlugin.ID_PLUGIN, 0, "Repository connectors failed to load.", null); //$NON-NLS-1$
262
288
Lines 267-282 Link Here
267
		for (IExtension repositoryExtension : repositoryExtensions) {
293
		for (IExtension repositoryExtension : repositoryExtensions) {
268
			IConfigurationElement[] elements = repositoryExtension.getConfigurationElements();
294
			IConfigurationElement[] elements = repositoryExtension.getConfigurationElements();
269
			ConnectorDescriptor descriptor = null;
295
			ConnectorDescriptor descriptor = null;
270
			IConfigurationElement migratorElement = null;
296
			IConfigurationElement tasklistMigratorElement = null;
297
			IConfigurationElement repositoryMigratorElement = null;
271
			for (IConfigurationElement element : elements) {
298
			for (IConfigurationElement element : elements) {
272
				if (element.getName().equals(ELMNT_REPOSITORY_CONNECTOR)) {
299
				if (element.getName().equals(ELMNT_REPOSITORY_CONNECTOR)) {
273
					descriptor = new ConnectorDescriptor(element);
300
					descriptor = new ConnectorDescriptor(element);
274
				} else if (element.getName().equals(ELMNT_MIGRATOR)) {
301
				} else if (element.getName().equals(ELMNT_MIGRATOR)) {
275
					migratorElement = element;
302
					tasklistMigratorElement = element;
303
				} else if (element.getName().equals(ELMNT_REPOSITORY_MIGRATOR)) {
304
					repositoryMigratorElement = element;
276
				}
305
				}
277
			}
306
			}
278
			if (descriptor != null) {
307
			if (descriptor != null) {
279
				descriptor.migratorElement = migratorElement;
308
				descriptor.taskListMigratorElement = tasklistMigratorElement;
309
				descriptor.repositoryMigratorElement = repositoryMigratorElement;
280
				descriptors.add(descriptor);
310
				descriptors.add(descriptor);
281
				if (descriptor.getId() != null) {
311
				if (descriptor.getId() != null) {
282
					add(descriptorById, descriptor.getId(), descriptor);
312
					add(descriptorById, descriptor.getId(), descriptor);
Lines 300-313 Link Here
300
		checkForConflicts(descriptors, result, descriptorByConnectorKind);
330
		checkForConflicts(descriptors, result, descriptorByConnectorKind);
301
331
302
		// register connectors
332
		// register connectors
303
		List<AbstractTaskListMigrator> migrators = new ArrayList<AbstractTaskListMigrator>();
333
		List<AbstractTaskListMigrator> taskListmigrators = new ArrayList<AbstractTaskListMigrator>();
334
		List<AbstractRepositoryMigrator> repositoryMigrators = new ArrayList<AbstractRepositoryMigrator>();
304
		for (ConnectorDescriptor descriptor : descriptors) {
335
		for (ConnectorDescriptor descriptor : descriptors) {
305
			if (descriptor.repositoryConnector != null) {
336
			if (descriptor.repositoryConnector != null) {
306
				TasksUiPlugin.getRepositoryManager().addRepositoryConnector(descriptor.repositoryConnector);
337
				repositoryManager.addRepositoryConnector(descriptor.repositoryConnector);
307
				if (descriptor.migratorElement != null) {
338
				if (descriptor.taskListMigratorElement != null) {
308
					IStatus status = descriptor.createMigrator();
339
					IStatus status = descriptor.createTaskListMigrator();
309
					if (status.isOK() && descriptor.migrator != null) {
340
					if (status.isOK() && descriptor.taskListMigrator != null) {
310
						migrators.add(descriptor.migrator);
341
						taskListmigrators.add(descriptor.taskListMigrator);
342
					} else {
343
						result.add(status);
344
					}
345
				}
346
				if (descriptor.repositoryMigratorElement != null) {
347
					IStatus status = descriptor.createRepositoryMigrator();
348
					if (status.isOK() && descriptor.repositoryMigrator != null) {
349
						repositoryMigrators.add(descriptor.repositoryMigrator);
311
					} else {
350
					} else {
312
						result.add(status);
351
						result.add(status);
313
					}
352
					}
Lines 319-325 Link Here
319
			StatusHandler.log(result);
358
			StatusHandler.log(result);
320
		}
359
		}
321
360
322
		taskListExternalizer.initialize(migrators);
361
		repositoryManager.initialize(repositoryMigrators);
362
		taskListExternalizer.initialize(taskListmigrators);
323
	}
363
	}
324
364
325
	private static boolean isDisabled(IConfigurationElement element) {
365
	private static boolean isDisabled(IConfigurationElement element) {
(-)plugin.xml (+3 lines)
Lines 1115-1120 Link Here
1115
            class="org.eclipse.mylyn.internal.tasks.ui.LocalRepositoryConnectorUi"
1115
            class="org.eclipse.mylyn.internal.tasks.ui.LocalRepositoryConnectorUi"
1116
            name="%LocalRepositoryConnectorUi.name"
1116
            name="%LocalRepositoryConnectorUi.name"
1117
            overlayIcon="icons/ovr16/overlay-local.gif"/>
1117
            overlayIcon="icons/ovr16/overlay-local.gif"/>
1118
      <repositoryMigrator
1119
            class="org.eclipse.mylyn.internal.tasks.ui.LocalRepositoryMigrator">
1120
      </repositoryMigrator>
1118
   </extension>
1121
   </extension>
1119
         
1122
         
1120
   <extension point="org.eclipse.ui.workbench.texteditor.hyperlinkDetectorTargets">
1123
   <extension point="org.eclipse.ui.workbench.texteditor.hyperlinkDetectorTargets">
(-)src/org/eclipse/mylyn/internal/tasks/ui/notifications/TaskListServiceMessageControl.java (+270 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2010 Tasktop Technologies 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
 * Contributors:
9
 *     Tasktop Technologies - initial API and implementation
10
 *******************************************************************************/
11
12
package org.eclipse.mylyn.internal.tasks.ui.notifications;
13
14
import org.eclipse.jface.dialogs.Dialog;
15
import org.eclipse.jface.preference.IPreferenceStore;
16
import org.eclipse.mylyn.internal.provisional.commons.ui.CommonImages;
17
import org.eclipse.mylyn.internal.provisional.commons.ui.CommonThemes;
18
import org.eclipse.mylyn.internal.provisional.commons.ui.GradientCanvas;
19
import org.eclipse.mylyn.internal.tasks.core.notifications.IServiceMessageListener;
20
import org.eclipse.mylyn.internal.tasks.core.notifications.ServiceMessage;
21
import org.eclipse.mylyn.internal.tasks.core.notifications.ServiceMessageEvent;
22
import org.eclipse.mylyn.internal.tasks.ui.ITasksUiPreferenceConstants;
23
import org.eclipse.mylyn.internal.tasks.ui.TasksUiPlugin;
24
import org.eclipse.mylyn.tasks.ui.TasksUiUtil;
25
import org.eclipse.osgi.service.resolver.VersionRange;
26
import org.eclipse.swt.SWT;
27
import org.eclipse.swt.events.DisposeEvent;
28
import org.eclipse.swt.events.DisposeListener;
29
import org.eclipse.swt.graphics.Color;
30
import org.eclipse.swt.graphics.Font;
31
import org.eclipse.swt.graphics.FontData;
32
import org.eclipse.swt.graphics.Image;
33
import org.eclipse.swt.layout.GridData;
34
import org.eclipse.swt.layout.GridLayout;
35
import org.eclipse.swt.widgets.Composite;
36
import org.eclipse.swt.widgets.Control;
37
import org.eclipse.swt.widgets.Display;
38
import org.eclipse.swt.widgets.Label;
39
import org.eclipse.ui.PlatformUI;
40
import org.eclipse.ui.forms.FormColors;
41
import org.eclipse.ui.forms.IFormColors;
42
import org.eclipse.ui.forms.events.HyperlinkAdapter;
43
import org.eclipse.ui.forms.events.HyperlinkEvent;
44
import org.eclipse.ui.forms.events.IHyperlinkListener;
45
import org.eclipse.ui.forms.widgets.Hyperlink;
46
import org.eclipse.ui.forms.widgets.ImageHyperlink;
47
import org.eclipse.ui.forms.widgets.TableWrapData;
48
import org.eclipse.ui.forms.widgets.TableWrapLayout;
49
import org.osgi.framework.Version;
50
51
/**
52
 * @author Robert Elves
53
 * @author Steffen Pingel
54
 */
55
public class TaskListServiceMessageControl implements IServiceMessageListener {
56
57
	private ImageHyperlink imageHyperlink;
58
59
	private Hyperlink titleHyperlink;
60
61
	private Label descriptionLabel;
62
63
	private GridData headData;
64
65
	private final Composite parent;
66
67
	private GradientCanvas head;
68
69
	private ImageHyperlink closeLink;
70
71
	private ServiceMessage currentMessage;
72
73
	private String messageUrl;
74
75
	public TaskListServiceMessageControl(Composite parent) {
76
		this.parent = parent;
77
	}
78
79
	private void setTitleImage(Image image) {
80
		imageHyperlink.setImage(image);
81
	}
82
83
	private void setTitle(String title) {
84
		titleHyperlink.setText(title);
85
	}
86
87
	private void setDescription(String description) {
88
		descriptionLabel.setText(description);
89
	}
90
91
	private void addHyperlinkListener(IHyperlinkListener listener) {
92
		titleHyperlink.addHyperlinkListener(listener);
93
		imageHyperlink.addHyperlinkListener(listener);
94
	}
95
96
	protected void setMessageUrl(String url) {
97
		messageUrl = url;
98
	}
99
100
	public Control createControl(Composite parent) {
101
		FormColors colors = TasksUiPlugin.getDefault().getFormColors(parent.getDisplay());
102
		head = new GradientCanvas(parent, SWT.NONE);
103
		GridLayout headLayout = new GridLayout();
104
		headLayout.marginHeight = 0;
105
		headLayout.marginWidth = 0;
106
		headLayout.horizontalSpacing = 0;
107
		headLayout.verticalSpacing = 0;
108
		headLayout.numColumns = 1;
109
		head.setLayout(headLayout);
110
		headData = new GridData(SWT.FILL, SWT.TOP, true, false);
111
		head.setLayoutData(headData);
112
113
		Color top = colors.getColor(IFormColors.H_GRADIENT_END);
114
		Color bot = colors.getColor(IFormColors.H_GRADIENT_START);
115
		head.setBackgroundGradient(new Color[] { bot, top }, new int[] { 100 }, true);
116
		head.setSeparatorVisible(true);
117
		head.setSeparatorAlignment(SWT.TOP);
118
119
		head.putColor(IFormColors.H_BOTTOM_KEYLINE1, colors.getColor(IFormColors.H_BOTTOM_KEYLINE1));
120
		head.putColor(IFormColors.H_BOTTOM_KEYLINE2, colors.getColor(IFormColors.H_BOTTOM_KEYLINE2));
121
		head.putColor(IFormColors.H_HOVER_LIGHT, colors.getColor(IFormColors.H_HOVER_LIGHT));
122
		head.putColor(IFormColors.H_HOVER_FULL, colors.getColor(IFormColors.H_HOVER_FULL));
123
		head.putColor(IFormColors.TB_TOGGLE, colors.getColor(IFormColors.TB_TOGGLE));
124
		head.putColor(IFormColors.TB_TOGGLE_HOVER, colors.getColor(IFormColors.TB_TOGGLE_HOVER));
125
126
		TableWrapLayout layout = new TableWrapLayout();
127
		layout.numColumns = 3;
128
		head.setLayout(layout);
129
130
		imageHyperlink = new ImageHyperlink(head, SWT.NONE);
131
132
		titleHyperlink = new Hyperlink(head, SWT.NONE);
133
134
		setHeaderFontSizeAndStyle(titleHyperlink);
135
136
		addHyperlinkListener(new HyperlinkAdapter() {
137
			@Override
138
			public void linkActivated(HyperlinkEvent e) {
139
				if (messageUrl != null) {
140
					TasksUiUtil.openUrl(messageUrl);
141
				}
142
143
			}
144
		});
145
146
		closeLink = new ImageHyperlink(head, SWT.NONE);
147
		closeLink.setImage(CommonImages.getImage(CommonImages.NOTIFICATION_CLOSE));
148
		TableWrapData data = new TableWrapData();
149
		data.align = TableWrapData.RIGHT;
150
		closeLink.setLayoutData(data);
151
		closeLink.addHyperlinkListener(new HyperlinkAdapter() {
152
			@Override
153
			public void linkActivated(HyperlinkEvent e) {
154
				closeMessage();
155
			}
156
157
			@Override
158
			public void linkEntered(HyperlinkEvent e) {
159
				closeLink.setImage(CommonImages.getImage(CommonImages.NOTIFICATION_CLOSE_HOVER));
160
			}
161
162
			@Override
163
			public void linkExited(HyperlinkEvent e) {
164
				closeLink.setImage(CommonImages.getImage(CommonImages.NOTIFICATION_CLOSE));
165
			}
166
		});
167
168
		// spacer
169
		new Label(head, SWT.NONE).setText(" "); //$NON-NLS-1$
170
171
		descriptionLabel = new Label(head, SWT.WRAP);
172
		data = new TableWrapData();
173
		data.colspan = 2;
174
		descriptionLabel.setLayoutData(data);
175
		return head;
176
	}
177
178
	private void closeMessage() {
179
		if (currentMessage != null) {
180
			TasksUiPlugin.getDefault().getPreferenceStore().setValue(
181
					ITasksUiPreferenceConstants.LAST_SERVICE_MESSAGE_ID, currentMessage.getId());
182
		}
183
		head.dispose();
184
		parent.layout(true);
185
	}
186
187
	// From EditorUtil
188
	private static Font setHeaderFontSizeAndStyle(Control text) {
189
		float sizeFactor = 1.2f;
190
		Font initialFont = text.getFont();
191
		FontData[] fontData = initialFont.getFontData();
192
		for (FontData element : fontData) {
193
			element.setHeight((int) (element.getHeight() * sizeFactor));
194
			element.setStyle(element.getStyle() | SWT.BOLD);
195
		}
196
		final Font textFont = new Font(text.getDisplay(), fontData);
197
		text.setFont(textFont);
198
		text.addDisposeListener(new DisposeListener() {
199
			public void widgetDisposed(DisposeEvent e) {
200
				textFont.dispose();
201
			}
202
		});
203
		Color color = PlatformUI.getWorkbench().getThemeManager().getCurrentTheme().getColorRegistry().get(
204
				CommonThemes.COLOR_COMPLETED);
205
		text.setForeground(color);
206
		return textFont;
207
	}
208
209
	public void handleEvent(final ServiceMessageEvent event) {
210
		switch (event.getEventKind()) {
211
		case MESSAGE_UPDATE:
212
			IPreferenceStore preferenceStore = TasksUiPlugin.getDefault().getPreferenceStore();
213
			String lastMessageId = preferenceStore.getString(ITasksUiPreferenceConstants.LAST_SERVICE_MESSAGE_ID);
214
			for (final ServiceMessage message : event.getMessages()) {
215
				if (!message.isValid() || message.getId().equals("-1")) { //$NON-NLS-1$
216
					continue;
217
				}
218
219
				if (!lastMessageId.equals(message.getId()) && isForCurrentVersion(message)) {
220
					Display.getDefault().asyncExec(new Runnable() {
221
						public void run() {
222
							setMessage(message);
223
						}
224
					});
225
				}
226
			}
227
			break;
228
		case STOP:
229
			head.dispose();
230
			parent.layout(true);
231
			break;
232
		}
233
	}
234
235
	private boolean isForCurrentVersion(ServiceMessage message) {
236
		if (message.getVersion() == null) {
237
			return true;
238
		}
239
240
		try {
241
			VersionRange version = new VersionRange(message.getVersion());
242
			String versionString = (String) TasksUiPlugin.getDefault().getBundle().getHeaders().get("Bundle-Version"); //$NON-NLS-1$
243
			return version.isIncluded(new Version(versionString));
244
		} catch (IllegalArgumentException e) {
245
			// invalid version range
246
			return false;
247
		}
248
	}
249
250
	protected void setMessage(ServiceMessage message) {
251
		if (message != null) {
252
			createControl(parent);
253
			IPreferenceStore preferenceStore = TasksUiPlugin.getDefault().getPreferenceStore();
254
			preferenceStore.setValue(ITasksUiPreferenceConstants.LAST_SERVICE_MESSAGE_ETAG, message.getETag());
255
			preferenceStore.setValue(ITasksUiPreferenceConstants.LAST_SERVICE_MESSAGE_LAST_MODIFIED,
256
					message.getLastModified());
257
258
			this.currentMessage = message;
259
260
			setTitle(message.getTitle());
261
			setDescription(message.getDescription());
262
			setTitleImage(Dialog.getImage(message.getImage()));
263
			if (message.getUrl() != null) {
264
				setMessageUrl(message.getUrl());
265
			}
266
			parent.layout(true);
267
		}
268
	}
269
270
}
(-)src/org/eclipse/mylyn/internal/tasks/ui/views/TeamRepositoriesContentProvider.java (+79 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2010 Tasktop Technologies 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
 * Contributors:
9
 *     Tasktop Technologies - initial API and implementation
10
 *******************************************************************************/
11
12
package org.eclipse.mylyn.internal.tasks.ui.views;
13
14
import java.util.HashSet;
15
import java.util.Set;
16
17
import org.eclipse.jface.viewers.ITreeContentProvider;
18
import org.eclipse.jface.viewers.Viewer;
19
import org.eclipse.mylyn.internal.tasks.core.Category;
20
import org.eclipse.mylyn.internal.tasks.core.IRepositoryConstants;
21
import org.eclipse.mylyn.internal.tasks.core.TaskRepositoryManager;
22
import org.eclipse.mylyn.tasks.core.TaskRepository;
23
import org.eclipse.mylyn.tasks.ui.TasksUi;
24
25
/**
26
 * @author Robert Elves
27
 */
28
public class TeamRepositoriesContentProvider implements ITreeContentProvider {
29
30
	private final TaskRepositoryManager manager;
31
32
	public TeamRepositoriesContentProvider() {
33
		manager = ((TaskRepositoryManager) TasksUi.getRepositoryManager());
34
	}
35
36
	public void inputChanged(Viewer v, Object oldInput, Object newInput) {
37
	}
38
39
	public void dispose() {
40
	}
41
42
	public Object[] getElements(Object parent) {
43
44
		Set<Object> objects = new HashSet<Object>();
45
		//objects.addAll(TasksUi.getRepositoryManager().getAllRepositories());
46
47
		objects.add(manager.getCategory(IRepositoryConstants.CATEGORY_TASKS));
48
		objects.add(manager.getCategory(IRepositoryConstants.CATEGORY_BUGS));
49
		objects.add(manager.getCategory(IRepositoryConstants.CATEGORY_OTHER));
50
51
		return objects.toArray();
52
	}
53
54
	public Object[] getChildren(Object parentElement) {
55
		if (parentElement instanceof Category) {
56
			Set<Object> objects = new HashSet<Object>();
57
			for (TaskRepository repository : TasksUi.getRepositoryManager().getAllRepositories()) {
58
				Category cat = manager.getCategory(repository);
59
				if (cat.equals(parentElement)) {
60
					objects.add(repository);
61
				}
62
//				String categoryId = repository.getProperty(IRepositoryConstants.PROPERTY_CATEGORY);
63
//				if (categoryId != null && ((Category) parentElement).getId().equals(categoryId)) {
64
//					objects.add(repository);
65
//				}
66
			}
67
			return objects.toArray();
68
		}
69
		return new Object[0];
70
	}
71
72
	public Object getParent(Object element) {
73
		return null;
74
	}
75
76
	public boolean hasChildren(Object element) {
77
		return element instanceof Category;
78
	}
79
}
(-)src/org/eclipse/mylyn/internal/tasks/ui/LocalRepositoryMigrator.java (+39 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2010 Tasktop Technologies 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
 * Contributors:
9
 *     Tasktop Technologies - initial API and implementation
10
 *******************************************************************************/
11
12
package org.eclipse.mylyn.internal.tasks.ui;
13
14
import org.eclipse.mylyn.internal.tasks.core.IRepositoryConstants;
15
import org.eclipse.mylyn.internal.tasks.core.LocalRepositoryConnector;
16
import org.eclipse.mylyn.tasks.core.AbstractRepositoryMigrator;
17
import org.eclipse.mylyn.tasks.core.TaskRepository;
18
19
/**
20
 * @author Robert Elves
21
 * @since 3.4
22
 */
23
public class LocalRepositoryMigrator extends AbstractRepositoryMigrator {
24
25
	@Override
26
	public String getConnectorKind() {
27
		return LocalRepositoryConnector.CONNECTOR_KIND;
28
	}
29
30
	@Override
31
	public boolean migrateRepository(TaskRepository repository) {
32
		if (repository.getProperty(IRepositoryConstants.PROPERTY_CATEGORY) == null) {
33
			repository.setProperty(IRepositoryConstants.PROPERTY_CATEGORY, IRepositoryConstants.CATEGORY_TASKS);
34
			return true;
35
		}
36
		return false;
37
	}
38
39
}

Return to bug 263528