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

Collapse All | Expand All

(-)plugin.xml (-1 / +1 lines)
Lines 2-8 Link Here
2
<?eclipse version="3.2"?>
2
<?eclipse version="3.2"?>
3
<plugin>
3
<plugin>
4
   <extension
4
   <extension
5
         point="org.eclipse.mylyn.sandbox.ui.taskEditorExtensions">
5
         point="org.eclipse.mylyn.tasks.ui.taskEditorExtensions">
6
      <taskEditorExtension
6
      <taskEditorExtension
7
            class="org.eclipse.mylyn.internal.wikitext.confluence.ui.editors.TaskEditorExtension"
7
            class="org.eclipse.mylyn.internal.wikitext.confluence.ui.editors.TaskEditorExtension"
8
            id="org.eclipse.mylyn.wikitext.confluence.ui.taskEditorExtension"
8
            id="org.eclipse.mylyn.wikitext.confluence.ui.taskEditorExtension"
(-)src/org/eclipse/mylyn/internal/jira/ui/editor/JiraTaskEditorPage.java (-2 / +2 lines)
Lines 1-5 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
* Copyright (c) 2004, 2008 Tasktop Technologies and others.
2
 * Copyright (c) 2004, 2008 Tasktop Technologies and others.
3
 * All rights reserved. This program and the accompanying materials
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
Lines 33-39 Link Here
33
33
34
	@Override
34
	@Override
35
	protected AttributeEditorFactory createAttributeEditorFactory() {
35
	protected AttributeEditorFactory createAttributeEditorFactory() {
36
		AttributeEditorFactory factory = new AttributeEditorFactory(getModel(), getTaskRepository()) {
36
		AttributeEditorFactory factory = new AttributeEditorFactory(getModel(), getTaskRepository(), getEditorSite()) {
37
			@Override
37
			@Override
38
			public AbstractAttributeEditor createEditor(String type, TaskAttribute taskAttribute) {
38
			public AbstractAttributeEditor createEditor(String type, TaskAttribute taskAttribute) {
39
				if (JiraTaskDataHandler.isTimeSpanAttribute(taskAttribute)) {
39
				if (JiraTaskDataHandler.isTimeSpanAttribute(taskAttribute)) {
(-)plugin.xml (-1 / +1 lines)
Lines 2-8 Link Here
2
<?eclipse version="3.2"?>
2
<?eclipse version="3.2"?>
3
<plugin>
3
<plugin>
4
   <extension
4
   <extension
5
         point="org.eclipse.mylyn.sandbox.ui.taskEditorExtensions">
5
         point="org.eclipse.mylyn.tasks.ui.taskEditorExtensions">
6
      <taskEditorExtension
6
      <taskEditorExtension
7
            class="org.eclipse.mylyn.internal.wikitext.twiki.ui.TaskEditorExtension"
7
            class="org.eclipse.mylyn.internal.wikitext.twiki.ui.TaskEditorExtension"
8
            id="org.eclipse.mylyn.wikitext.twiki.ui.taskEditorExtension1"
8
            id="org.eclipse.mylyn.wikitext.twiki.ui.taskEditorExtension1"
(-)src/org/eclipse/mylyn/internal/bugzilla/ui/editor/BugzillaTaskEditorPage.java (-1 / +1 lines)
Lines 94-100 Link Here
94
94
95
	@Override
95
	@Override
96
	protected AttributeEditorFactory createAttributeEditorFactory() {
96
	protected AttributeEditorFactory createAttributeEditorFactory() {
97
		AttributeEditorFactory factory = new AttributeEditorFactory(getModel(), getTaskRepository()) {
97
		AttributeEditorFactory factory = new AttributeEditorFactory(getModel(), getTaskRepository(), getEditorSite()) {
98
			@Override
98
			@Override
99
			public AbstractAttributeEditor createEditor(String type, TaskAttribute taskAttribute) {
99
			public AbstractAttributeEditor createEditor(String type, TaskAttribute taskAttribute) {
100
				AbstractAttributeEditor editor;
100
				AbstractAttributeEditor editor;
(-)plugin.xml (-1 / +1 lines)
Lines 2-8 Link Here
2
<?eclipse version="3.2"?>
2
<?eclipse version="3.2"?>
3
<plugin>
3
<plugin>
4
   <extension
4
   <extension
5
         point="org.eclipse.mylyn.sandbox.ui.taskEditorExtensions">
5
         point="org.eclipse.mylyn.tasks.ui.taskEditorExtensions">
6
      <taskEditorExtension
6
      <taskEditorExtension
7
            class="org.eclipse.mylyn.internal.wikitext.tracwiki.ui.editors.TracWikiTaskEditorExtension"
7
            class="org.eclipse.mylyn.internal.wikitext.tracwiki.ui.editors.TracWikiTaskEditorExtension"
8
            id="org.eclipse.mylyn.wikitext.tracwiki.ui.taskEditorExtension"
8
            id="org.eclipse.mylyn.wikitext.tracwiki.ui.taskEditorExtension"
(-)plugin.xml (-1 / +1 lines)
Lines 35-41 Link Here
35
      </templates>
35
      </templates>
36
   </extension>
36
   </extension>
37
   <extension
37
   <extension
38
         point="org.eclipse.mylyn.sandbox.ui.taskEditorExtensions">
38
         point="org.eclipse.mylyn.tasks.ui.taskEditorExtensions">
39
      <taskEditorExtension
39
      <taskEditorExtension
40
            class="org.eclipse.mylyn.internal.wikitext.mediawiki.ui.editors.TaskEditorExtension"
40
            class="org.eclipse.mylyn.internal.wikitext.mediawiki.ui.editors.TaskEditorExtension"
41
            id="org.eclipse.mylyn.internal.wikitext.mediawiki.ui.taskEditorExtension"
41
            id="org.eclipse.mylyn.internal.wikitext.mediawiki.ui.taskEditorExtension"
(-)src/org/eclipse/mylyn/internal/trac/ui/editor/TracTaskEditorPage.java (-2 / +2 lines)
Lines 1-5 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
* Copyright (c) 2006, 2008 Steffen Pingel and others.
2
 * Copyright (c) 2006, 2008 Steffen Pingel and others.
3
 * All rights reserved. This program and the accompanying materials
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
Lines 65-71 Link Here
65
65
66
	@Override
66
	@Override
67
	protected AttributeEditorFactory createAttributeEditorFactory() {
67
	protected AttributeEditorFactory createAttributeEditorFactory() {
68
		AttributeEditorFactory factory = new AttributeEditorFactory(getModel(), getTaskRepository()) {
68
		AttributeEditorFactory factory = new AttributeEditorFactory(getModel(), getTaskRepository(), getEditorSite()) {
69
			@Override
69
			@Override
70
			public AbstractAttributeEditor createEditor(String type, TaskAttribute taskAttribute) {
70
			public AbstractAttributeEditor createEditor(String type, TaskAttribute taskAttribute) {
71
				if (TracAttribute.CC.getTracKey().equals(taskAttribute.getId())) {
71
				if (TracAttribute.CC.getTracKey().equals(taskAttribute.getId())) {
(-)src/org/eclipse/mylyn/wikitext/ui/editor/MarkupTaskEditorExtension.java (-1 / +1 lines)
Lines 28-34 Link Here
28
import org.eclipse.jface.text.source.IAnnotationModel;
28
import org.eclipse.jface.text.source.IAnnotationModel;
29
import org.eclipse.jface.text.source.ISourceViewer;
29
import org.eclipse.jface.text.source.ISourceViewer;
30
import org.eclipse.jface.text.source.SourceViewer;
30
import org.eclipse.jface.text.source.SourceViewer;
31
import org.eclipse.mylyn.internal.sandbox.ui.editors.AbstractTaskEditorExtension;
32
import org.eclipse.mylyn.internal.tasks.ui.editors.RepositoryCompletionProcessor;
31
import org.eclipse.mylyn.internal.tasks.ui.editors.RepositoryCompletionProcessor;
33
import org.eclipse.mylyn.internal.wikitext.ui.editor.MarkupEditor;
32
import org.eclipse.mylyn.internal.wikitext.ui.editor.MarkupEditor;
34
import org.eclipse.mylyn.internal.wikitext.ui.editor.MarkupSourceViewerConfiguration;
33
import org.eclipse.mylyn.internal.wikitext.ui.editor.MarkupSourceViewerConfiguration;
Lines 39-44 Link Here
39
import org.eclipse.mylyn.tasks.core.TaskRepository;
38
import org.eclipse.mylyn.tasks.core.TaskRepository;
40
import org.eclipse.mylyn.tasks.ui.TaskHyperlink;
39
import org.eclipse.mylyn.tasks.ui.TaskHyperlink;
41
import org.eclipse.mylyn.tasks.ui.TasksUi;
40
import org.eclipse.mylyn.tasks.ui.TasksUi;
41
import org.eclipse.mylyn.tasks.ui.editors.AbstractTaskEditorExtension;
42
import org.eclipse.mylyn.wikitext.core.parser.markup.MarkupLanguage;
42
import org.eclipse.mylyn.wikitext.core.parser.markup.MarkupLanguage;
43
import org.eclipse.mylyn.wikitext.ui.viewer.MarkupViewer;
43
import org.eclipse.mylyn.wikitext.ui.viewer.MarkupViewer;
44
import org.eclipse.mylyn.wikitext.ui.viewer.MarkupViewerConfiguration;
44
import org.eclipse.mylyn.wikitext.ui.viewer.MarkupViewerConfiguration;
(-)src/org/eclipse/mylyn/internal/sandbox/ui/editors/ExtensibleRichTextAttributeEditor.java (-378 lines)
Removed Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2004, 2008 Jingwen Ou 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
 *     Jingwen Ou - initial API and implementation
10
 *     Tasktop Technologies - improvements
11
 *******************************************************************************/
12
13
package org.eclipse.mylyn.internal.sandbox.ui.editors;
14
15
import java.util.Iterator;
16
17
import org.eclipse.jface.action.Action;
18
import org.eclipse.jface.action.IAction;
19
import org.eclipse.jface.resource.JFaceResources;
20
import org.eclipse.jface.text.Document;
21
import org.eclipse.jface.text.ITextListener;
22
import org.eclipse.jface.text.TextEvent;
23
import org.eclipse.jface.text.source.AnnotationModel;
24
import org.eclipse.jface.text.source.IAnnotationAccess;
25
import org.eclipse.jface.text.source.SourceViewer;
26
import org.eclipse.mylyn.internal.provisional.commons.ui.CommonThemes;
27
import org.eclipse.mylyn.internal.sandbox.ui.commands.ViewSourceHandler;
28
import org.eclipse.mylyn.internal.tasks.ui.editors.AbstractHyperlinkTextPresentationManager;
29
import org.eclipse.mylyn.internal.tasks.ui.editors.EditorUtil;
30
import org.eclipse.mylyn.internal.tasks.ui.editors.HighlightingHyperlinkTextPresentationManager;
31
import org.eclipse.mylyn.internal.tasks.ui.editors.RepositoryTextViewer;
32
import org.eclipse.mylyn.internal.tasks.ui.editors.RepositoryTextViewerConfiguration;
33
import org.eclipse.mylyn.internal.tasks.ui.editors.RichTextAttributeEditor;
34
import org.eclipse.mylyn.internal.tasks.ui.editors.TaskHyperlinkTextPresentationManager;
35
import org.eclipse.mylyn.internal.tasks.ui.editors.RepositoryTextViewerConfiguration.Mode;
36
import org.eclipse.mylyn.internal.tasks.ui.util.TasksUiInternal;
37
import org.eclipse.mylyn.tasks.core.TaskRepository;
38
import org.eclipse.mylyn.tasks.core.data.TaskAttribute;
39
import org.eclipse.mylyn.tasks.core.data.TaskDataModel;
40
import org.eclipse.swt.SWT;
41
import org.eclipse.swt.custom.StackLayout;
42
import org.eclipse.swt.events.DisposeEvent;
43
import org.eclipse.swt.events.DisposeListener;
44
import org.eclipse.swt.events.FocusAdapter;
45
import org.eclipse.swt.events.FocusEvent;
46
import org.eclipse.swt.events.FocusListener;
47
import org.eclipse.swt.graphics.Font;
48
import org.eclipse.swt.graphics.Point;
49
import org.eclipse.swt.widgets.Composite;
50
import org.eclipse.swt.widgets.Control;
51
import org.eclipse.swt.widgets.Menu;
52
import org.eclipse.ui.PlatformUI;
53
import org.eclipse.ui.contexts.IContextActivation;
54
import org.eclipse.ui.contexts.IContextService;
55
import org.eclipse.ui.editors.text.EditorsUI;
56
import org.eclipse.ui.forms.widgets.FormToolkit;
57
import org.eclipse.ui.texteditor.AnnotationPreference;
58
import org.eclipse.ui.texteditor.DefaultMarkerAnnotationAccess;
59
import org.eclipse.ui.texteditor.MarkerAnnotationPreferences;
60
import org.eclipse.ui.texteditor.SourceViewerDecorationSupport;
61
import org.eclipse.ui.themes.IThemeManager;
62
63
/**
64
 * A text attribute that can switch between a source editor and a preview using StackLayout.
65
 * 
66
 * @author Jingwen Ou
67
 * @author Steffen Pingel
68
 */
69
public class ExtensibleRichTextAttributeEditor extends RichTextAttributeEditor {
70
71
	private IContextActivation contextActivation;
72
73
	private final IContextService contextService;
74
75
	private SourceViewer defaultViewer;
76
77
	private Composite editorComposite;
78
79
	private StackLayout editorLayout;
80
81
	private final AbstractTaskEditorExtension extension;
82
83
	private SourceViewer editorViewer;
84
85
	private SourceViewer previewViewer;
86
87
	private int styles;
88
89
	private final TaskRepository taskRepository;
90
91
	private FormToolkit toolkit;
92
93
	public class ViewSourceAction extends Action {
94
95
		public ViewSourceAction() {
96
			super("Viewer Source", SWT.TOGGLE);
97
			setChecked(false);
98
		}
99
100
		@Override
101
		public void run() {
102
			if (isChecked()) {
103
				showDefault();
104
			} else {
105
				showEditor();
106
			}
107
		}
108
109
	}
110
111
	private final IAction viewSourceAction = new ViewSourceAction();
112
113
	public ExtensibleRichTextAttributeEditor(IContextService contextService, TaskDataModel manager,
114
			TaskRepository taskRepository, AbstractTaskEditorExtension extension, TaskAttribute taskAttribute,
115
			int styles) {
116
		super(manager, taskRepository, taskAttribute, styles);
117
		this.contextService = contextService;
118
		this.taskRepository = taskRepository;
119
		this.extension = extension;
120
		this.styles = styles;
121
	}
122
123
	/** Configures annontation model for spell checking. */
124
	private void configureAsTextEditor(SourceViewer viewer, Document document) {
125
		AnnotationModel annotationModel = new AnnotationModel();
126
		viewer.showAnnotations(false);
127
		viewer.showAnnotationsOverview(false);
128
		IAnnotationAccess annotationAccess = new DefaultMarkerAnnotationAccess();
129
		final SourceViewerDecorationSupport support = new SourceViewerDecorationSupport(viewer, null, annotationAccess,
130
				EditorsUI.getSharedTextColors());
131
		Iterator<?> e = new MarkerAnnotationPreferences().getAnnotationPreferences().iterator();
132
		while (e.hasNext()) {
133
			support.setAnnotationPreference((AnnotationPreference) e.next());
134
		}
135
		support.install(EditorsUI.getPreferenceStore());
136
		viewer.getTextWidget().addDisposeListener(new DisposeListener() {
137
			public void widgetDisposed(DisposeEvent e) {
138
				support.uninstall();
139
			}
140
		});
141
		viewer.getTextWidget().setIndent(2);
142
		viewer.setDocument(document, annotationModel);
143
	}
144
145
	private RepositoryTextViewerConfiguration configure(SourceViewer viewer) {
146
		RepositoryTextViewerConfiguration configuration = new RepositoryTextViewerConfiguration(taskRepository, false);
147
		configuration.setMode(getMode());
148
149
		// do not configure viewer, this has already been done in extension
150
151
		AbstractHyperlinkTextPresentationManager manager;
152
		if (getMode() == Mode.DEFAULT) {
153
			manager = new HighlightingHyperlinkTextPresentationManager();
154
			manager.setHyperlinkDetectors(configuration.getDefaultHyperlinkDetectors(viewer, null));
155
			manager.install(viewer);
156
157
			manager = new TaskHyperlinkTextPresentationManager();
158
			manager.setHyperlinkDetectors(configuration.getDefaultHyperlinkDetectors(viewer, Mode.TASK));
159
			manager.install(viewer);
160
		} else if (getMode() == Mode.TASK_RELATION) {
161
			manager = new TaskHyperlinkTextPresentationManager();
162
			manager.setHyperlinkDetectors(configuration.getDefaultHyperlinkDetectors(viewer, Mode.TASK_RELATION));
163
			manager.install(viewer);
164
		}
165
166
		return configuration;
167
	}
168
169
	private SourceViewer configureEditor(final SourceViewer viewer, boolean readOnly) {
170
		configure(viewer);
171
172
		Document document = new Document(getValue());
173
		if (readOnly) {
174
			viewer.setDocument(document);
175
			// setting view source action
176
			viewer.getControl().setData(ViewSourceHandler.VIEW_SOURCE_ACTION, viewSourceAction);
177
			viewer.getControl().addFocusListener(new FocusAdapter() {
178
				@Override
179
				public void focusGained(FocusEvent e) {
180
					ViewSourceHandler.setChecked(getViewer() == defaultViewer);
181
				}
182
			});
183
		} else {
184
			configureAsTextEditor(viewer, document);
185
			viewer.addTextListener(new ITextListener() {
186
				public void textChanged(TextEvent event) {
187
					// filter out events caused by text presentation changes, e.g. annotation drawing
188
					String value = viewer.getTextWidget().getText();
189
					if (!getValue().equals(value)) {
190
						setValue(value);
191
						EditorUtil.ensureVisible(viewer.getTextWidget());
192
					}
193
				}
194
			});
195
196
			viewer.getControl().setData(FormToolkit.KEY_DRAW_BORDER, FormToolkit.TEXT_BORDER);
197
198
			// drop & drag support, under review
199
			TaskEditorDropTarget.addDropTargetSupport(viewer);
200
		}
201
202
		// enable cut/copy/paste
203
		EditorUtil.setTextViewer(viewer.getTextWidget(), viewer);
204
		viewer.setEditable(!readOnly);
205
		viewer.getTextWidget().setFont(getFont());
206
		toolkit.adapt(viewer.getControl(), false, false);
207
208
		RepositoryTextViewerConfiguration configuration = new RepositoryTextViewerConfiguration(
209
				getModel().getTaskRepository(), false);
210
211
		TaskHyperlinkTextPresentationManager hyperlinkTextPresentationManager = new TaskHyperlinkTextPresentationManager();
212
		hyperlinkTextPresentationManager.setHyperlinkDetectors(configuration.getDefaultHyperlinkDetectors(viewer,
213
				Mode.TASK));
214
		hyperlinkTextPresentationManager.install(viewer);
215
216
		HighlightingHyperlinkTextPresentationManager manager = new HighlightingHyperlinkTextPresentationManager();
217
		manager.setHyperlinkDetectors(configuration.getDefaultHyperlinkDetectors(viewer, null));
218
		manager.install(viewer);
219
220
		return viewer;
221
	}
222
223
	@Override
224
	public void createControl(Composite parent, FormToolkit toolkit) {
225
		this.toolkit = toolkit;
226
227
		editorComposite = new Composite(parent, SWT.NULL);
228
		editorLayout = new StackLayout() {
229
			@Override
230
			protected Point computeSize(Composite composite, int hint, int hint2, boolean flushCache) {
231
				return topControl.computeSize(hint, hint2, flushCache);
232
			}
233
		};
234
		editorComposite.setLayout(editorLayout);
235
		setControl(editorComposite);
236
237
		if (!isReadOnly() && (styles & TasksUiInternal.SWT_NO_SCROLL) == 0) {
238
			styles |= SWT.V_SCROLL;
239
		}
240
241
		if (isReadOnly()) {
242
			editorViewer = extension.createViewer(taskRepository, editorComposite, styles);
243
		} else {
244
			editorViewer = extension.createEditor(taskRepository, editorComposite, styles);
245
			editorViewer.getTextWidget().addFocusListener(new FocusListener() {
246
				public void focusGained(FocusEvent e) {
247
					setContext();
248
				}
249
250
				public void focusLost(FocusEvent e) {
251
					unsetContext();
252
				}
253
			});
254
			editorViewer.getTextWidget().addDisposeListener(new DisposeListener() {
255
				public void widgetDisposed(DisposeEvent e) {
256
					unsetContext();
257
				}
258
			});
259
		}
260
		configureEditor(editorViewer, isReadOnly());
261
262
		show(editorViewer);
263
	}
264
265
	private SourceViewer createDefaultEditor(Composite parent, int styles) {
266
		SourceViewer defaultEditor = new RepositoryTextViewer(taskRepository, parent, styles | SWT.WRAP);
267
268
		RepositoryTextViewerConfiguration viewerConfig = new RepositoryTextViewerConfiguration(taskRepository,
269
				isSpellCheckingEnabled());
270
		viewerConfig.setMode(getMode());
271
		defaultEditor.configure(viewerConfig);
272
273
		return defaultEditor;
274
	}
275
276
	private SourceViewer getDefaultViewer() {
277
		if (defaultViewer == null) {
278
			defaultViewer = createDefaultEditor(editorComposite, styles);
279
			configureEditor(defaultViewer, isReadOnly());
280
281
			// fixed font size
282
			defaultViewer.getTextWidget().setFont(JFaceResources.getFontRegistry().get(JFaceResources.TEXT_FONT));
283
			// adapt maximize action
284
			defaultViewer.getControl().setData(EditorUtil.KEY_TOGGLE_TO_MAXIMIZE_ACTION,
285
					editorViewer.getControl().getData(EditorUtil.KEY_TOGGLE_TO_MAXIMIZE_ACTION));
286
			// adapt menu to the new viewer
287
			installMenu(defaultViewer.getControl(), editorViewer.getControl().getMenu());
288
		}
289
		return defaultViewer;
290
	}
291
292
	private void installMenu(final Control control, Menu menu) {
293
		if (menu != null) {
294
			control.setMenu(menu);
295
			control.addDisposeListener(new DisposeListener() {
296
				public void widgetDisposed(DisposeEvent e) {
297
					control.setMenu(null);
298
				}
299
			});
300
		}
301
	}
302
303
	private Font getFont() {
304
		IThemeManager themeManager = PlatformUI.getWorkbench().getThemeManager();
305
		Font font = themeManager.getCurrentTheme().getFontRegistry().get(CommonThemes.FONT_EDITOR_COMMENT);
306
		return font;
307
	}
308
309
	private SourceViewer getPreviewViewer() {
310
		// construct as needed
311
		if (previewViewer == null) {
312
			previewViewer = extension.createViewer(taskRepository, editorComposite, styles);
313
			configureEditor(previewViewer, true);
314
			// adapt maximize action
315
			previewViewer.getControl().setData(EditorUtil.KEY_TOGGLE_TO_MAXIMIZE_ACTION,
316
					editorViewer.getControl().getData(EditorUtil.KEY_TOGGLE_TO_MAXIMIZE_ACTION));
317
		}
318
		Document document = new Document(editorViewer.getDocument().get());
319
		previewViewer.setDocument(document);
320
		return previewViewer;
321
	}
322
323
	public SourceViewer getEditorViewer() {
324
		return editorViewer;
325
	}
326
327
	@Override
328
	public SourceViewer getViewer() {
329
		if (defaultViewer != null && editorLayout.topControl == defaultViewer.getControl()) {
330
			return defaultViewer;
331
		} else if (previewViewer != null && editorLayout.topControl == previewViewer.getControl()) {
332
			return previewViewer;
333
		} else {
334
			return editorViewer;
335
		}
336
	}
337
338
	private void setContext() {
339
		if (contextActivation != null) {
340
			contextService.deactivateContext(contextActivation);
341
			contextActivation = null;
342
		}
343
		if (contextService != null && extension.getEditorContextId() != null) {
344
			contextActivation = contextService.activateContext(extension.getEditorContextId());
345
		}
346
	}
347
348
	/**
349
	 * Brings <code>viewer</code> to top.
350
	 */
351
	private void show(SourceViewer viewer) {
352
		editorLayout.topControl = viewer.getControl();
353
		editorComposite.layout();
354
		viewer.getControl().setFocus();
355
	}
356
357
	public void showDefault() {
358
		show(getDefaultViewer());
359
	}
360
361
	public void showPreview() {
362
		if (!isReadOnly()) {
363
			show(getPreviewViewer());
364
		}
365
	}
366
367
	public void showEditor() {
368
		show(getEditorViewer());
369
	}
370
371
	private void unsetContext() {
372
		if (contextActivation != null) {
373
			contextService.deactivateContext(contextActivation);
374
			contextActivation = null;
375
		}
376
	}
377
378
}
(-)src/org/eclipse/mylyn/internal/sandbox/ui/editors/ExtensibleTaskEditorNewCommentPart.java (-41 / +2 lines)
Lines 11-24 Link Here
11
11
12
package org.eclipse.mylyn.internal.sandbox.ui.editors;
12
package org.eclipse.mylyn.internal.sandbox.ui.editors;
13
13
14
import org.eclipse.jface.action.Action;
15
import org.eclipse.jface.action.ToolBarManager;
16
import org.eclipse.mylyn.internal.provisional.commons.ui.CommonImages;
17
import org.eclipse.mylyn.internal.tasks.ui.editors.EditorUtil;
18
import org.eclipse.mylyn.internal.tasks.ui.editors.TaskEditorNewCommentPart;
14
import org.eclipse.mylyn.internal.tasks.ui.editors.TaskEditorNewCommentPart;
19
import org.eclipse.swt.SWT;
20
import org.eclipse.swt.widgets.Composite;
15
import org.eclipse.swt.widgets.Composite;
21
import org.eclipse.swt.widgets.Control;
22
import org.eclipse.ui.forms.widgets.FormToolkit;
16
import org.eclipse.ui.forms.widgets.FormToolkit;
23
17
24
/**
18
/**
Lines 27-69 Link Here
27
public class ExtensibleTaskEditorNewCommentPart extends TaskEditorNewCommentPart {
21
public class ExtensibleTaskEditorNewCommentPart extends TaskEditorNewCommentPart {
28
22
29
	@Override
23
	@Override
30
	protected void fillToolBar(ToolBarManager barManager) {
31
		Action toggleEditingAction = new Action("", SWT.TOGGLE) {
32
			@Override
33
			public void run() {
34
				toggleEditing(this);
35
			}
36
		};
37
		toggleEditingAction.setImageDescriptor(CommonImages.PREVIEW_WEB);
38
		toggleEditingAction.setToolTipText("Preview");
39
		toggleEditingAction.setChecked(false);
40
41
		barManager.add(toggleEditingAction);
42
		barManager.add(getMaximizePartAction());
43
		super.fillToolBar(barManager);
44
	}
45
46
	private void toggleEditing(Action action) {
47
		if (getEditor() instanceof ExtensibleRichTextAttributeEditor) {
48
			ExtensibleRichTextAttributeEditor editor = (ExtensibleRichTextAttributeEditor) getEditor();
49
			if (action.isChecked()) {
50
				editor.showPreview();
51
			} else {
52
				editor.showEditor();
53
			}
54
		}
55
	}
56
57
	@Override
58
	public void createControl(Composite parent, FormToolkit toolkit) {
24
	public void createControl(Composite parent, FormToolkit toolkit) {
59
		super.createControl(parent, toolkit);
25
		super.createControl(parent, toolkit);
60
		if (getControl() != null) {
26
		if (getEditor() != null && !getEditor().isReadOnly() && getEditor().getViewer() != null) {
61
			getEditor().getControl().setData(EditorUtil.KEY_TOGGLE_TO_MAXIMIZE_ACTION, getMaximizePartAction());
27
			TaskEditorDropTarget.addDropTargetSupport(getEditor().getViewer());
62
			if (getEditor().getControl() instanceof Composite) {
63
				for (Control control : ((Composite) getEditor().getControl()).getChildren()) {
64
					control.setData(EditorUtil.KEY_TOGGLE_TO_MAXIMIZE_ACTION, getMaximizePartAction());
65
				}
66
			}
67
		}
28
		}
68
	}
29
	}
69
30
(-)src/org/eclipse/mylyn/internal/sandbox/ui/editors/EditorStyleContributionItem.java (-1 / +3 lines)
Lines 22-30 Link Here
22
import org.eclipse.jface.dialogs.IInputValidator;
22
import org.eclipse.jface.dialogs.IInputValidator;
23
import org.eclipse.jface.dialogs.InputDialog;
23
import org.eclipse.jface.dialogs.InputDialog;
24
import org.eclipse.jface.window.Window;
24
import org.eclipse.jface.window.Window;
25
import org.eclipse.mylyn.internal.sandbox.ui.editors.TaskEditorExtensions.RegisteredTaskEditorExtension;
25
import org.eclipse.mylyn.internal.tasks.ui.editors.TaskEditorExtensions;
26
import org.eclipse.mylyn.internal.tasks.ui.editors.TaskEditorExtensions.RegisteredTaskEditorExtension;
26
import org.eclipse.mylyn.tasks.core.TaskRepository;
27
import org.eclipse.mylyn.tasks.core.TaskRepository;
27
import org.eclipse.mylyn.tasks.ui.TasksUiUtil;
28
import org.eclipse.mylyn.tasks.ui.TasksUiUtil;
29
import org.eclipse.mylyn.tasks.ui.editors.AbstractTaskEditorExtension;
28
import org.eclipse.ui.PlatformUI;
30
import org.eclipse.ui.PlatformUI;
29
import org.eclipse.ui.actions.CompoundContributionItem;
31
import org.eclipse.ui.actions.CompoundContributionItem;
30
32
(-)src/org/eclipse/mylyn/internal/sandbox/ui/editors/TaskEditorExtensionReader.java (-85 lines)
Removed Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2004, 2008 David Green 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
 *     David Green - initial API and implementation
10
 *******************************************************************************/
11
12
package org.eclipse.mylyn.internal.sandbox.ui.editors;
13
14
import org.eclipse.core.runtime.CoreException;
15
import org.eclipse.core.runtime.IConfigurationElement;
16
import org.eclipse.core.runtime.IExtension;
17
import org.eclipse.core.runtime.IExtensionPoint;
18
import org.eclipse.core.runtime.IExtensionRegistry;
19
import org.eclipse.core.runtime.IStatus;
20
import org.eclipse.core.runtime.Platform;
21
import org.eclipse.core.runtime.Status;
22
import org.eclipse.mylyn.commons.core.StatusHandler;
23
import org.eclipse.mylyn.internal.tasks.ui.TasksUiPlugin;
24
25
/**
26
 * @author David Green
27
 */
28
public class TaskEditorExtensionReader {
29
30
	private static final String CONNECTOR_KIND = "connectorKind";
31
32
	public static final String ATTR_ID = "id";
33
34
	public static final String ATTR_NAME = "name";
35
36
	public static final String EXTENSION_TASK_EDITOR_EXTENSIONS = "org.eclipse.mylyn.sandbox.ui.taskEditorExtensions";
37
38
	private static final String REPOSITORY_ASSOCIATION = "repositoryAssociation";
39
40
	private static final String TASK_EDITOR_EXTENSION = "taskEditorExtension";
41
42
	public static void initExtensions() {
43
		IExtensionRegistry registry = Platform.getExtensionRegistry();
44
45
		IExtensionPoint editorExtensionPoint = registry.getExtensionPoint(EXTENSION_TASK_EDITOR_EXTENSIONS);
46
		IExtension[] editorExtensions = editorExtensionPoint.getExtensions();
47
		for (IExtension extension : editorExtensions) {
48
			IConfigurationElement[] elements = extension.getConfigurationElements();
49
			for (IConfigurationElement element : elements) {
50
				if (element.getName().equals(TASK_EDITOR_EXTENSION)) {
51
					readEditorExtension(element);
52
				} else if (element.getName().equals(REPOSITORY_ASSOCIATION)) {
53
					readEditorExtensionAssociation(element);
54
				}
55
			}
56
		}
57
	}
58
59
	private static void readEditorExtension(IConfigurationElement element) {
60
		try {
61
			String id = element.getAttribute(ATTR_ID);
62
			String name = element.getAttribute(ATTR_NAME);
63
			AbstractTaskEditorExtension extension = (AbstractTaskEditorExtension) element.createExecutableExtension("class");
64
			TaskEditorExtensions.addTaskEditorExtension(id, name, extension);
65
		} catch (CoreException e) {
66
			StatusHandler.log(new Status(IStatus.ERROR, TasksUiPlugin.ID_PLUGIN, "Could not load taskEditorExtension",
67
					e));
68
		} catch (Exception e) {
69
			StatusHandler.log(new Status(IStatus.ERROR, TasksUiPlugin.ID_PLUGIN, "Could not load taskEditorExtension",
70
					e));
71
		}
72
	}
73
74
	private static void readEditorExtensionAssociation(IConfigurationElement element) {
75
		try {
76
			String repository = element.getAttribute(CONNECTOR_KIND);
77
			String taskEditorExtension = element.getAttribute(TASK_EDITOR_EXTENSION);
78
			TaskEditorExtensions.addRepositoryAssociation(repository, taskEditorExtension);
79
		} catch (Exception e) {
80
			StatusHandler.log(new Status(IStatus.ERROR, TasksUiPlugin.ID_PLUGIN,
81
					"Could not load repositoryAssociation", e));
82
		}
83
	}
84
85
}
(-)src/org/eclipse/mylyn/internal/sandbox/ui/editors/AbstractTaskEditorExtension.java (-63 lines)
Removed Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2004, 2008 David Green 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
 *     David Green - initial API and implementation
10
 *******************************************************************************/
11
12
package org.eclipse.mylyn.internal.sandbox.ui.editors;
13
14
import org.eclipse.jface.text.source.SourceViewer;
15
import org.eclipse.mylyn.tasks.core.TaskRepository;
16
import org.eclipse.swt.widgets.Composite;
17
import org.eclipse.ui.contexts.IContextService;
18
19
/**
20
 * An extension that provides task editor capabilities beyond the default, oriented towards providing markup-aware
21
 * editing and viewing
22
 * 
23
 * @author David Green
24
 */
25
public abstract class AbstractTaskEditorExtension {
26
27
	/**
28
	 * The key to access the {@link TaskRepository} property that stores the URL of an associated wiki.
29
	 */
30
	public static final String INTERNAL_WIKI_LINK_PATTERN = "wikiLinkPattern";
31
32
	/**
33
	 * Creates a source viewer that can be used to view content in the task editor. The source viewer should be
34
	 * configured with a source viewer configuration prior to returning.
35
	 * 
36
	 * @param taskRepository
37
	 *            the task repository for which the viewer is created
38
	 * @param parent
39
	 *            the control parent of the source viewer
40
	 * @param style
41
	 *            the styles to use
42
	 */
43
	public abstract SourceViewer createViewer(TaskRepository taskRepository, Composite parent, int style);
44
45
	/**
46
	 * Creates a source viewer that can be used to edit content in the task editor. The source viewer should be
47
	 * configured with a source viewer configuration prior to returning.
48
	 * 
49
	 * @param taskRepository
50
	 *            the task repository for which the viewer is created
51
	 * @param parent
52
	 *            the control parent of the source viewer
53
	 * @param style
54
	 *            the styles to use
55
	 */
56
	public abstract SourceViewer createEditor(TaskRepository taskRepository, Composite parent, int style);
57
58
	/**
59
	 * Returns the editor context id, to be passed to the {@link IContextService} when the editor is in focus.
60
	 */
61
	public abstract String getEditorContextId();
62
63
}
(-)src/org/eclipse/mylyn/internal/sandbox/ui/editors/ExtensibleBugzillaTaskEditorPage.java (-25 lines)
Lines 26-36 Link Here
26
import org.eclipse.mylyn.internal.bugzilla.ui.editor.BugzillaTaskEditorPage;
26
import org.eclipse.mylyn.internal.bugzilla.ui.editor.BugzillaTaskEditorPage;
27
import org.eclipse.mylyn.internal.provisional.commons.ui.CommonImages;
27
import org.eclipse.mylyn.internal.provisional.commons.ui.CommonImages;
28
import org.eclipse.mylyn.internal.tasks.ui.editors.EditorUtil;
28
import org.eclipse.mylyn.internal.tasks.ui.editors.EditorUtil;
29
import org.eclipse.mylyn.tasks.core.data.TaskAttribute;
30
import org.eclipse.mylyn.tasks.ui.editors.AbstractAttributeEditor;
31
import org.eclipse.mylyn.tasks.ui.editors.AbstractTaskEditorPage;
29
import org.eclipse.mylyn.tasks.ui.editors.AbstractTaskEditorPage;
32
import org.eclipse.mylyn.tasks.ui.editors.AbstractTaskEditorPart;
30
import org.eclipse.mylyn.tasks.ui.editors.AbstractTaskEditorPart;
33
import org.eclipse.mylyn.tasks.ui.editors.AttributeEditorFactory;
34
import org.eclipse.mylyn.tasks.ui.editors.TaskEditor;
31
import org.eclipse.mylyn.tasks.ui.editors.TaskEditor;
35
import org.eclipse.mylyn.tasks.ui.editors.TaskEditorPartDescriptor;
32
import org.eclipse.mylyn.tasks.ui.editors.TaskEditorPartDescriptor;
36
import org.eclipse.swt.SWT;
33
import org.eclipse.swt.SWT;
Lines 45-51 Link Here
45
import org.eclipse.swt.widgets.Display;
42
import org.eclipse.swt.widgets.Display;
46
import org.eclipse.swt.widgets.Text;
43
import org.eclipse.swt.widgets.Text;
47
import org.eclipse.ui.actions.ActionFactory;
44
import org.eclipse.ui.actions.ActionFactory;
48
import org.eclipse.ui.contexts.IContextService;
49
import org.eclipse.ui.forms.IManagedForm;
45
import org.eclipse.ui.forms.IManagedForm;
50
import org.eclipse.ui.forms.editor.IFormPage;
46
import org.eclipse.ui.forms.editor.IFormPage;
51
import org.eclipse.ui.forms.widgets.ExpandableComposite;
47
import org.eclipse.ui.forms.widgets.ExpandableComposite;
Lines 137-163 Link Here
137
	}
133
	}
138
134
139
	@Override
135
	@Override
140
	protected AttributeEditorFactory createAttributeEditorFactory() {
141
		final AttributeEditorFactory bugzillaFactory = super.createAttributeEditorFactory();
142
		AttributeEditorFactory factory = new AttributeEditorFactory(getModel(), getTaskRepository()) {
143
			@Override
144
			public AbstractAttributeEditor createEditor(String type, TaskAttribute taskAttribute) {
145
				// replace description part and the comment part
146
				AbstractTaskEditorExtension extension = TaskEditorExtensions.getTaskEditorExtension(getTaskRepository());
147
				if (extension != null) {
148
					if (TaskAttribute.TYPE_LONG_RICH_TEXT.equals(type)) {
149
						return new ExtensibleRichTextAttributeEditor((IContextService) getEditor().getEditorSite()
150
								.getService(IContextService.class), getModel(), getTaskRepository(), extension,
151
								taskAttribute, SWT.MULTI);
152
					}
153
				}
154
				return bugzillaFactory.createEditor(type, taskAttribute);
155
			}
156
		};
157
		return factory;
158
	}
159
160
	@Override
161
	protected Set<TaskEditorPartDescriptor> createPartDescriptors() {
136
	protected Set<TaskEditorPartDescriptor> createPartDescriptors() {
162
		Set<TaskEditorPartDescriptor> descriptors = super.createPartDescriptors();
137
		Set<TaskEditorPartDescriptor> descriptors = super.createPartDescriptors();
163
138
(-)src/org/eclipse/mylyn/internal/sandbox/ui/editors/TaskEditorExtensions.java (-165 lines)
Removed Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2004, 2008 David Green 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
 *     David Green - initial API and implementation
10
 *******************************************************************************/
11
12
package org.eclipse.mylyn.internal.sandbox.ui.editors;
13
14
import java.util.HashMap;
15
import java.util.Map;
16
import java.util.SortedSet;
17
import java.util.TreeSet;
18
19
import org.eclipse.core.runtime.Assert;
20
import org.eclipse.core.runtime.IStatus;
21
import org.eclipse.core.runtime.Status;
22
import org.eclipse.mylyn.commons.core.StatusHandler;
23
import org.eclipse.mylyn.internal.tasks.ui.TasksUiPlugin;
24
import org.eclipse.mylyn.tasks.core.TaskRepository;
25
26
/**
27
 * @author David Green
28
 */
29
public class TaskEditorExtensions {
30
31
	public static final String REPOSITORY_PROPERTY_EDITOR_EXTENSION = "editorExtension";
32
33
	private static Map<String, RegisteredTaskEditorExtension> extensionsById = new HashMap<String, RegisteredTaskEditorExtension>();
34
35
	private static Map<String, String> associationByConnectorKind = new HashMap<String, String>();
36
37
	private static boolean initialized;
38
39
	public static SortedSet<RegisteredTaskEditorExtension> getTaskEditorExtensions() {
40
		init();
41
		return new TreeSet<RegisteredTaskEditorExtension>(extensionsById.values());
42
	}
43
44
	public static void addTaskEditorExtension(String id, String name, AbstractTaskEditorExtension extension) {
45
		Assert.isNotNull(id);
46
		RegisteredTaskEditorExtension previous = extensionsById.put(id, new RegisteredTaskEditorExtension(extension,
47
				id, name));
48
		if (previous != null) {
49
			StatusHandler.log(new Status(IStatus.ERROR, TasksUiPlugin.ID_PLUGIN, "Duplicate taskEditorExtension id="
50
					+ id, null));
51
		}
52
	}
53
54
	public static void addRepositoryAssociation(String connectorKind, String extensionId) {
55
		if (connectorKind == null || extensionId == null) {
56
			throw new IllegalArgumentException();
57
		}
58
		String previous = associationByConnectorKind.put(connectorKind, extensionId);
59
		if (previous != null) {
60
			StatusHandler.log(new Status(IStatus.ERROR, TasksUiPlugin.ID_PLUGIN, String.format(
61
					"Duplicate association for repository %s: %s replaces %s", connectorKind, extensionId, previous),
62
					null));
63
		}
64
	}
65
66
	/**
67
	 * get a task editor extension for a specific repository
68
	 * 
69
	 * @param taskRepository
70
	 * @return the extension, or null if there is none
71
	 * 
72
	 * @see #getDefaultTaskEditorExtension(TaskRepository)
73
	 */
74
	public static AbstractTaskEditorExtension getTaskEditorExtension(TaskRepository taskRepository) {
75
		init();
76
		String extensionId = getTaskEditorExtensionId(taskRepository);
77
		if (extensionId != null) {
78
			RegisteredTaskEditorExtension taskEditorExtension = extensionsById.get(extensionId);
79
			return taskEditorExtension == null ? null : taskEditorExtension.getExtension();
80
		}
81
		return null;
82
	}
83
84
	public static String getTaskEditorExtensionId(TaskRepository taskRepository) {
85
		init();
86
		String id = taskRepository.getProperty(REPOSITORY_PROPERTY_EDITOR_EXTENSION);
87
		if (id == null) {
88
			id = getDefaultTaskEditorExtensionId(taskRepository);
89
		}
90
		return id;
91
	}
92
93
	public static void setTaskEditorExtensionId(TaskRepository repository, String editorExtensionId) {
94
		repository.setProperty(REPOSITORY_PROPERTY_EDITOR_EXTENSION, editorExtensionId);
95
	}
96
97
	public static String getDefaultTaskEditorExtensionId(TaskRepository taskRepository) {
98
		init();
99
		return associationByConnectorKind.get(taskRepository.getConnectorKind());
100
	}
101
102
	/**
103
	 * get a default task editor extension for a specific repository
104
	 * 
105
	 * @param taskRepository
106
	 * @return the extension, or null if there is none
107
	 * 
108
	 * @see #getTaskEditorExtension(TaskRepository)
109
	 */
110
	public static AbstractTaskEditorExtension getDefaultTaskEditorExtension(TaskRepository taskRepository) {
111
		init();
112
		String extensionId = getDefaultTaskEditorExtensionId(taskRepository);
113
		if (extensionId != null) {
114
			RegisteredTaskEditorExtension taskEditorExtension = extensionsById.get(extensionId);
115
			return taskEditorExtension == null ? null : taskEditorExtension.getExtension();
116
		}
117
		return null;
118
	}
119
120
	private static void init() {
121
		if (!initialized) {
122
			initialized = true;
123
			TaskEditorExtensionReader.initExtensions();
124
		}
125
	}
126
127
	public static class RegisteredTaskEditorExtension implements Comparable<RegisteredTaskEditorExtension> {
128
129
		private final String id;
130
131
		private final String name;
132
133
		private final AbstractTaskEditorExtension extension;
134
135
		private RegisteredTaskEditorExtension(AbstractTaskEditorExtension extension, String id, String name) {
136
			this.extension = extension;
137
			this.id = id;
138
			this.name = name;
139
		}
140
141
		public String getId() {
142
			return id;
143
		}
144
145
		public String getName() {
146
			return name;
147
		}
148
149
		public AbstractTaskEditorExtension getExtension() {
150
			return extension;
151
		}
152
153
		public int compareTo(RegisteredTaskEditorExtension o) {
154
			if (o == this) {
155
				return 0;
156
			}
157
			int i = name.compareTo(o.name);
158
			if (i == 0) {
159
				i = id.compareTo(o.id);
160
			}
161
			return i;
162
		}
163
	}
164
165
}
(-)src/org/eclipse/mylyn/internal/sandbox/ui/editors/ExtensibleBugzillaTaskEditorPageFactory.java (+1 lines)
Lines 13-18 Link Here
13
package org.eclipse.mylyn.internal.sandbox.ui.editors;
13
package org.eclipse.mylyn.internal.sandbox.ui.editors;
14
14
15
import org.eclipse.mylyn.internal.bugzilla.ui.editor.BugzillaTaskEditorPageFactory;
15
import org.eclipse.mylyn.internal.bugzilla.ui.editor.BugzillaTaskEditorPageFactory;
16
import org.eclipse.mylyn.internal.tasks.ui.editors.TaskEditorExtensions;
16
import org.eclipse.mylyn.tasks.ui.editors.TaskEditor;
17
import org.eclipse.mylyn.tasks.ui.editors.TaskEditor;
17
import org.eclipse.mylyn.tasks.ui.editors.TaskEditorInput;
18
import org.eclipse.mylyn.tasks.ui.editors.TaskEditorInput;
18
import org.eclipse.ui.forms.editor.FormPage;
19
import org.eclipse.ui.forms.editor.FormPage;
(-)schema/taskEditorExtensions.exsd (-152 lines)
Removed Link Here
1
<?xml version='1.0' encoding='UTF-8'?>
2
<!-- Schema file written by PDE -->
3
<schema targetNamespace="org.eclipse.mylyn.sandbox.ui" xmlns="http://www.w3.org/2001/XMLSchema">
4
<annotation>
5
      <appInfo>
6
         <meta.schema plugin="org.eclipse.mylyn.sandbox.ui" id="taskEditorExtensions" name="Task Editor Extensions"/>
7
      </appInfo>
8
      <documentation>
9
         An extension to the Mylyn task editor that can provide viewing and editing controls that are markup-aware.
10
      </documentation>
11
   </annotation>
12
13
   <element name="extension">
14
      <annotation>
15
         <appInfo>
16
            <meta.element internal="true" />
17
         </appInfo>
18
      </annotation>
19
      <complexType>
20
         <sequence>
21
            <element ref="taskEditorExtension" minOccurs="0" maxOccurs="unbounded"/>
22
            <element ref="repositoryAssociation" minOccurs="0" maxOccurs="unbounded"/>
23
         </sequence>
24
         <attribute name="point" type="string" use="required">
25
            <annotation>
26
               <documentation>
27
                  
28
               </documentation>
29
            </annotation>
30
         </attribute>
31
         <attribute name="id" type="string">
32
            <annotation>
33
               <documentation>
34
                  
35
               </documentation>
36
            </annotation>
37
         </attribute>
38
         <attribute name="name" type="string">
39
            <annotation>
40
               <documentation>
41
                  
42
               </documentation>
43
               <appInfo>
44
                  <meta.attribute translatable="true"/>
45
               </appInfo>
46
            </annotation>
47
         </attribute>
48
      </complexType>
49
   </element>
50
51
   <element name="taskEditorExtension">
52
      <annotation>
53
         <documentation>
54
            Declare an extension to the Mylyn task editor.  Extensions are typically capable of providing improved editing capabilities, such as markup-aware.
55
         </documentation>
56
      </annotation>
57
      <complexType>
58
         <attribute name="class" type="string" use="required">
59
            <annotation>
60
               <documentation>
61
                  the fully qualified class name of the class that extends org.eclipse.mylyn.internal.sandbox.ui.editors.AbstractTaskEditorExtension
62
               </documentation>
63
               <appInfo>
64
                  <meta.attribute kind="java" basedOn="org.eclipse.mylyn.internal.sandbox.ui.editors.AbstractTaskEditorExtension:"/>
65
               </appInfo>
66
            </annotation>
67
         </attribute>
68
         <attribute name="id" type="string" use="required">
69
            <annotation>
70
               <documentation>
71
                  a unique identifier identifying the extension
72
               </documentation>
73
               <appInfo>
74
                  <meta.attribute kind="identifier"/>
75
               </appInfo>
76
            </annotation>
77
         </attribute>
78
         <attribute name="name" type="string" use="required">
79
            <annotation>
80
               <documentation>
81
                  A human-readable name for the extension that is presented to the Eclipse user in the UI.    Should be translated.  Used in the UI to identify the type of extension, so the name should indicate what the extension is for, and it should be short so that it can be displayed on one line (for example as an option in a combo box.)  Example: &quot;TracWiki&quot;, or &quot;Textile&quot;.
82
               </documentation>
83
               <appInfo>
84
                  <meta.attribute translatable="true"/>
85
               </appInfo>
86
            </annotation>
87
         </attribute>
88
      </complexType>
89
   </element>
90
91
   <element name="repositoryAssociation">
92
      <annotation>
93
         <documentation>
94
            Associate the task editor extension with a kind of repository.  Making such an association causes the taskEditorExtension to become the default or preferred setting for a kind of repository.
95
         </documentation>
96
      </annotation>
97
      <complexType>
98
         <attribute name="connectorKind" type="string" use="required">
99
            <annotation>
100
               <documentation>
101
                  the kind of connector for that this task editor extension should be associated with.
102
               </documentation>
103
            </annotation>
104
         </attribute>
105
         <attribute name="taskEditorExtension" type="string" use="required">
106
            <annotation>
107
               <documentation>
108
                  the id of the taskEditorExtension to associate
109
               </documentation>
110
            </annotation>
111
         </attribute>
112
      </complexType>
113
   </element>
114
115
   <annotation>
116
      <appInfo>
117
         <meta.section type="since"/>
118
      </appInfo>
119
      <documentation>
120
         3.0
121
      </documentation>
122
   </annotation>
123
124
   <annotation>
125
      <appInfo>
126
         <meta.section type="examples"/>
127
      </appInfo>
128
      <documentation>
129
         [Enter extension point usage example here.]
130
      </documentation>
131
   </annotation>
132
133
   <annotation>
134
      <appInfo>
135
         <meta.section type="apiinfo"/>
136
      </appInfo>
137
      <documentation>
138
         [Enter API information here.]
139
      </documentation>
140
   </annotation>
141
142
   <annotation>
143
      <appInfo>
144
         <meta.section type="implementation"/>
145
      </appInfo>
146
      <documentation>
147
         [Enter information about supplied implementation of this extension point.]
148
      </documentation>
149
   </annotation>
150
151
152
</schema>
(-)src/org/eclipse/mylyn/internal/sandbox/ui/commands/ViewSourceHandler.java (-103 lines)
Removed Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2004, 2008 Jingwen Ou 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
 *     Jingwen Ou - initial API and implementation
10
 *     Tasktop Technologies - improvements
11
 *******************************************************************************/
12
13
package org.eclipse.mylyn.internal.sandbox.ui.commands;
14
15
import java.util.Map;
16
17
import org.eclipse.core.commands.AbstractHandler;
18
import org.eclipse.core.commands.ExecutionEvent;
19
import org.eclipse.core.commands.ExecutionException;
20
import org.eclipse.core.commands.HandlerEvent;
21
import org.eclipse.jface.action.IAction;
22
import org.eclipse.mylyn.internal.tasks.ui.editors.EditorUtil;
23
import org.eclipse.swt.custom.StyledText;
24
import org.eclipse.swt.widgets.Control;
25
import org.eclipse.ui.IEditorSite;
26
import org.eclipse.ui.IWorkbenchPart;
27
import org.eclipse.ui.IWorkbenchSite;
28
import org.eclipse.ui.PlatformUI;
29
import org.eclipse.ui.commands.IElementUpdater;
30
import org.eclipse.ui.forms.editor.FormEditor;
31
import org.eclipse.ui.forms.editor.IFormPage;
32
import org.eclipse.ui.handlers.HandlerUtil;
33
import org.eclipse.ui.menus.UIElement;
34
35
/**
36
 * @author Jingwen Ou
37
 * @author Steffen Pingel
38
 */
39
public class ViewSourceHandler extends AbstractHandler implements IElementUpdater {
40
41
	private static boolean checked;
42
43
	private static ViewSourceHandler instance;
44
45
	public ViewSourceHandler() {
46
		instance = this;
47
	}
48
49
	public boolean isChecked() {
50
		return checked;
51
	}
52
53
	public static void setChecked(boolean checked) {
54
		ViewSourceHandler.checked = checked;
55
		if (instance != null) {
56
			instance.fireHandlerChanged(new HandlerEvent(instance, true, false));
57
		}
58
	}
59
60
	private Control getFocusControl() {
61
		return PlatformUI.getWorkbench().getDisplay().getFocusControl();
62
	}
63
64
	@Override
65
	public boolean isEnabled() {
66
		Control focusControl = getFocusControl();
67
		if (focusControl instanceof StyledText && focusControl.getData(VIEW_SOURCE_ACTION) instanceof IAction) {
68
			return true;
69
		}
70
71
		return false;
72
	}
73
74
	public static final String VIEW_SOURCE_ACTION = "viewSourceAction";
75
76
	public Object execute(ExecutionEvent event) throws ExecutionException {
77
		IWorkbenchSite site = HandlerUtil.getActiveSite(event);
78
		if (site instanceof IEditorSite) {
79
			IWorkbenchPart part = ((IEditorSite) site).getPart();
80
			if (part instanceof FormEditor) {
81
				IFormPage page = ((FormEditor) part).getActivePageInstance();
82
				Control focusedControl = EditorUtil.getFocusControl(page);
83
				if (focusedControl != null) {
84
					Object data = focusedControl.getData(VIEW_SOURCE_ACTION);
85
					if (data instanceof IAction) {
86
						IAction action = (IAction) data;
87
						action.setChecked(!action.isChecked());
88
						action.run();
89
						setChecked(action.isChecked());
90
						EditorUtil.reflow(focusedControl);
91
					}
92
				}
93
			}
94
		}
95
		return null;
96
	}
97
98
	@SuppressWarnings("unchecked")
99
	public void updateElement(UIElement element, Map parameters) {
100
		element.setChecked(checked);
101
	}
102
103
}
(-)plugin.xml (-17 lines)
Lines 1-7 Link Here
1
<?xml version="1.0" encoding="UTF-8"?>
1
<?xml version="1.0" encoding="UTF-8"?>
2
<?eclipse version="3.0"?>
2
<?eclipse version="3.0"?>
3
<plugin>
3
<plugin>
4
    <extension-point id="taskEditorExtensions" name="Task Editor Extension" schema="schema/taskEditorExtensions.exsd"/>
5
    <extension-point id="resourceHyperlinkExtensions" name="Resource Hyperlink Extension" schema="schema/resourceHyperlinkExtensions.exsd"/>
4
    <extension-point id="resourceHyperlinkExtensions" name="Resource Hyperlink Extension" schema="schema/resourceHyperlinkExtensions.exsd"/>
6
    
5
    
7
	<extension point="org.eclipse.ui.views">
6
	<extension point="org.eclipse.ui.views">
Lines 382-394 Link Here
382
                  <count
381
                  <count
383
                        value="1">
382
                        value="1">
384
                  </count>
383
                  </count>
385
                  <iterate>
386
                     <test
387
                           forcePluginActivation="false"
388
                           property="org.eclipse.mylyn.taskRepository.connectorKind"
389
                           value="bugzilla">
390
                     </test>
391
                  </iterate>
392
               </and>
384
               </and>
393
            </visibleWhen>
385
            </visibleWhen>
394
         </menu>
386
         </menu>
Lines 431-445 Link Here
431
   </command>
423
   </command>
432
		</menuContribution>
424
		</menuContribution>
433
	</extension>
425
	</extension>
434
        <extension
435
              point="org.eclipse.ui.commands">
436
           <command
437
                 categoryId="org.eclipse.mylyn.tasks.ui.commands"
438
                 defaultHandler="org.eclipse.mylyn.internal.sandbox.ui.commands.ViewSourceHandler"
439
                 id="org.eclipse.mylyn.sandbox.ui.viewSource.command"
440
                 name="View Source">
441
           </command>
442
        </extension>
443
   <!--
426
   <!--
444
   <extension point="org.eclipse.mylyn.tasks.ui.presentations">
427
   <extension point="org.eclipse.mylyn.tasks.ui.presentations">
445
      <presentation 
428
      <presentation 
(-).refactorings/2008/10/42/refactorings.history (+3 lines)
Added Link Here
1
<?xml version="1.0" encoding="UTF-8"?>
2
<session version="1.0">&#x0A;<refactoring comment="Move 2 elements(s) to &apos;org.eclipse.mylyn.tasks.ui/src/org.eclipse.mylyn.internal.tasks.ui.editors&apos;&#x0A;- Original project: &apos;org.eclipse.mylyn.sandbox.ui&apos;&#x0A;- Destination element: &apos;org.eclipse.mylyn.tasks.ui/src/org.eclipse.mylyn.internal.tasks.ui.editors&apos;&#x0A;- Original elements:&#x0A;     org.eclipse.mylyn.internal.sandbox.ui.editors.TaskEditorExtensionReader.java&#x0A;     org.eclipse.mylyn.internal.sandbox.ui.editors.TaskEditorExtensions.java&#x0A;- Update references to refactored element" description="Move compilation units" destination="=org.eclipse.mylyn.tasks.ui/src&lt;org.eclipse.mylyn.internal.tasks.ui.editors" element1="/src&lt;org.eclipse.mylyn.internal.sandbox.ui.editors{TaskEditorExtensionReader.java" element2="/src&lt;org.eclipse.mylyn.internal.sandbox.ui.editors{TaskEditorExtensions.java" files="0" flags="589830" folders="0" id="org.eclipse.jdt.ui.move" patterns="*" policy="org.eclipse.jdt.ui.moveResources" qualified="false" references="true" stamp="1224204730606" units="2" version="1.0"/>&#x0A;<refactoring comment="Move 1 elements(s) to &apos;org.eclipse.mylyn.tasks.ui/src/org.eclipse.mylyn.tasks.ui.editors&apos;&#x0A;- Original project: &apos;org.eclipse.mylyn.sandbox.ui&apos;&#x0A;- Destination element: &apos;org.eclipse.mylyn.tasks.ui/src/org.eclipse.mylyn.tasks.ui.editors&apos;&#x0A;- Original element: &apos;org.eclipse.mylyn.internal.sandbox.ui.editors.AbstractTaskEditorExtension.java&apos;&#x0A;- Update references to refactored element" description="Move compilation unit" destination="=org.eclipse.mylyn.tasks.ui/src&lt;org.eclipse.mylyn.tasks.ui.editors" element1="/src&lt;org.eclipse.mylyn.internal.sandbox.ui.editors{AbstractTaskEditorExtension.java" files="0" flags="589830" folders="0" id="org.eclipse.jdt.ui.move" patterns="*" policy="org.eclipse.jdt.ui.moveResources" qualified="false" references="true" stamp="1224204780085" units="1" version="1.0"/>&#x0A;<refactoring comment="Move 1 elements(s) to &apos;org.eclipse.mylyn.tasks.ui/src/org.eclipse.mylyn.internal.tasks.ui.commands&apos;&#x0A;- Original project: &apos;org.eclipse.mylyn.sandbox.ui&apos;&#x0A;- Destination element: &apos;org.eclipse.mylyn.tasks.ui/src/org.eclipse.mylyn.internal.tasks.ui.commands&apos;&#x0A;- Original element: &apos;org.eclipse.mylyn.internal.sandbox.ui.commands.ViewSourceHandler.java&apos;&#x0A;- Update references to refactored element" description="Move compilation unit" destination="=org.eclipse.mylyn.tasks.ui/src&lt;org.eclipse.mylyn.internal.tasks.ui.commands" element1="/src&lt;org.eclipse.mylyn.internal.sandbox.ui.commands{ViewSourceHandler.java" files="0" flags="589830" folders="0" id="org.eclipse.jdt.ui.move" patterns="*" policy="org.eclipse.jdt.ui.moveResources" qualified="false" references="true" stamp="1224205970323" units="1" version="1.0"/>&#x0A;<refactoring comment="Move 1 elements(s) to &apos;schema&apos;&#x0A;- Original project: &apos;org.eclipse.mylyn.sandbox.ui&apos;&#x0A;- Destination element: &apos;schema&apos;&#x0A;- Original element: &apos;taskEditorExtensions.exsd&apos;" description="Move file" element1="schema/taskEditorExtensions.exsd" files="1" flags="589830" folders="0" id="org.eclipse.jdt.ui.move" policy="org.eclipse.jdt.ui.moveResources" qualified="false" references="true" stamp="1224206083822" target="/org.eclipse.mylyn.tasks.ui/schema" units="0" version="1.0"/>&#x0A;<refactoring accessors="true" comment="Delete 1 element(s) from project &apos;org.eclipse.mylyn.sandbox.ui&apos;&#x0A;- Original project: &apos;org.eclipse.mylyn.sandbox.ui&apos;&#x0A;- Original element: &apos;org.eclipse.mylyn.internal.sandbox.ui.editors.ExtensibleRichTextAttributeEditor.java&apos;" description="Delete element" element1="/src&lt;org.eclipse.mylyn.internal.sandbox.ui.editors{ExtensibleRichTextAttributeEditor.java" elements="1" flags="589830" id="org.eclipse.jdt.ui.delete" resources="0" stamp="1224210228104" subPackages="false" version="1.0"/>
3
</session>
(-).refactorings/2008/10/42/refactorings.index (+5 lines)
Added Link Here
1
1224204730606	Move compilation units
2
1224204780085	Move compilation unit
3
1224205970323	Move compilation unit
4
1224206083822	Move file
5
1224210228104	Delete element
(-)plugin.xml (-1 / +1 lines)
Lines 61-67 Link Here
61
      </templates>
61
      </templates>
62
   </extension>
62
   </extension>
63
   <extension
63
   <extension
64
         point="org.eclipse.mylyn.sandbox.ui.taskEditorExtensions">
64
         point="org.eclipse.mylyn.tasks.ui.taskEditorExtensions">
65
      <taskEditorExtension
65
      <taskEditorExtension
66
            class="org.eclipse.mylyn.internal.wikitext.textile.ui.editors.TextileTaskEditorExtension"
66
            class="org.eclipse.mylyn.internal.wikitext.textile.ui.editors.TextileTaskEditorExtension"
67
            id="org.eclipse.mylyn.wikitext.textile.core.ui.taskEditorExtension"
67
            id="org.eclipse.mylyn.wikitext.textile.core.ui.taskEditorExtension"
(-)src/org/eclipse/mylyn/internal/tasks/ui/editors/RichTextAttributeEditor.java (-81 / +313 lines)
Lines 6-13 Link Here
6
 * http://www.eclipse.org/legal/epl-v10.html
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
7
 *
8
 * Contributors:
8
 * Contributors:
9
 *     Raphael Ackermann - initial API and implementation
9
 *     Tasktop Technologies - initial API and implementation
10
 *     Tasktop Technologies - improvements
10
 *     Raphael Ackermann - spell checking support on bug 195514
11
 *     Jingwen Ou - extensibility improvements
11
 *******************************************************************************/
12
 *******************************************************************************/
12
13
13
package org.eclipse.mylyn.internal.tasks.ui.editors;
14
package org.eclipse.mylyn.internal.tasks.ui.editors;
Lines 15-20 Link Here
15
import java.util.Iterator;
16
import java.util.Iterator;
16
17
17
import org.eclipse.core.runtime.Assert;
18
import org.eclipse.core.runtime.Assert;
19
import org.eclipse.jface.action.Action;
20
import org.eclipse.jface.action.IAction;
21
import org.eclipse.jface.resource.JFaceResources;
18
import org.eclipse.jface.text.Document;
22
import org.eclipse.jface.text.Document;
19
import org.eclipse.jface.text.ITextListener;
23
import org.eclipse.jface.text.ITextListener;
20
import org.eclipse.jface.text.TextEvent;
24
import org.eclipse.jface.text.TextEvent;
Lines 22-44 Link Here
22
import org.eclipse.jface.text.source.IAnnotationAccess;
26
import org.eclipse.jface.text.source.IAnnotationAccess;
23
import org.eclipse.jface.text.source.SourceViewer;
27
import org.eclipse.jface.text.source.SourceViewer;
24
import org.eclipse.mylyn.internal.provisional.commons.ui.CommonThemes;
28
import org.eclipse.mylyn.internal.provisional.commons.ui.CommonThemes;
29
import org.eclipse.mylyn.internal.tasks.ui.commands.ViewSourceHandler;
25
import org.eclipse.mylyn.internal.tasks.ui.editors.RepositoryTextViewerConfiguration.Mode;
30
import org.eclipse.mylyn.internal.tasks.ui.editors.RepositoryTextViewerConfiguration.Mode;
26
import org.eclipse.mylyn.internal.tasks.ui.util.TasksUiInternal;
31
import org.eclipse.mylyn.internal.tasks.ui.util.TasksUiInternal;
27
import org.eclipse.mylyn.tasks.core.TaskRepository;
32
import org.eclipse.mylyn.tasks.core.TaskRepository;
28
import org.eclipse.mylyn.tasks.core.data.TaskAttribute;
33
import org.eclipse.mylyn.tasks.core.data.TaskAttribute;
29
import org.eclipse.mylyn.tasks.core.data.TaskDataModel;
34
import org.eclipse.mylyn.tasks.core.data.TaskDataModel;
30
import org.eclipse.mylyn.tasks.ui.editors.AbstractAttributeEditor;
35
import org.eclipse.mylyn.tasks.ui.editors.AbstractAttributeEditor;
36
import org.eclipse.mylyn.tasks.ui.editors.AbstractTaskEditorExtension;
31
import org.eclipse.mylyn.tasks.ui.editors.LayoutHint;
37
import org.eclipse.mylyn.tasks.ui.editors.LayoutHint;
32
import org.eclipse.mylyn.tasks.ui.editors.LayoutHint.ColumnSpan;
38
import org.eclipse.mylyn.tasks.ui.editors.LayoutHint.ColumnSpan;
33
import org.eclipse.mylyn.tasks.ui.editors.LayoutHint.RowSpan;
39
import org.eclipse.mylyn.tasks.ui.editors.LayoutHint.RowSpan;
34
import org.eclipse.swt.SWT;
40
import org.eclipse.swt.SWT;
41
import org.eclipse.swt.custom.StackLayout;
35
import org.eclipse.swt.events.DisposeEvent;
42
import org.eclipse.swt.events.DisposeEvent;
36
import org.eclipse.swt.events.DisposeListener;
43
import org.eclipse.swt.events.DisposeListener;
44
import org.eclipse.swt.events.FocusAdapter;
45
import org.eclipse.swt.events.FocusEvent;
46
import org.eclipse.swt.events.FocusListener;
37
import org.eclipse.swt.graphics.Font;
47
import org.eclipse.swt.graphics.Font;
48
import org.eclipse.swt.graphics.Point;
38
import org.eclipse.swt.widgets.Composite;
49
import org.eclipse.swt.widgets.Composite;
50
import org.eclipse.swt.widgets.Control;
39
import org.eclipse.swt.widgets.Event;
51
import org.eclipse.swt.widgets.Event;
40
import org.eclipse.swt.widgets.Listener;
52
import org.eclipse.swt.widgets.Listener;
53
import org.eclipse.swt.widgets.Menu;
41
import org.eclipse.ui.PlatformUI;
54
import org.eclipse.ui.PlatformUI;
55
import org.eclipse.ui.contexts.IContextActivation;
56
import org.eclipse.ui.contexts.IContextService;
42
import org.eclipse.ui.editors.text.EditorsUI;
57
import org.eclipse.ui.editors.text.EditorsUI;
43
import org.eclipse.ui.forms.widgets.FormToolkit;
58
import org.eclipse.ui.forms.widgets.FormToolkit;
44
import org.eclipse.ui.texteditor.AnnotationPreference;
59
import org.eclipse.ui.texteditor.AnnotationPreference;
Lines 48-74 Link Here
48
import org.eclipse.ui.themes.IThemeManager;
63
import org.eclipse.ui.themes.IThemeManager;
49
64
50
/**
65
/**
51
 * FIXME comment is out dated
66
 * A text attribute editor that can switch between a editor, preview and source view.
52
 * 
67
 * 
53
 * Text viewer generally used for displaying non-editable text. No annotation model or spell checking support. Supports
68
 * @author Raphael Ackermann
54
 * cut/copy/paste/etc..
55
 * 
56
 * For viewing and editing text. Spell checking w/ annotations supported One or two max per editor, any more and the
57
 * spell checker will bring the editor to a grinding halt.
58
 * 
59
 * @author Raphael Ackermann (bug 195514)
60
 * @author Steffen Pingel
69
 * @author Steffen Pingel
70
 * @author Jingwen Ou
61
 */
71
 */
62
public class RichTextAttributeEditor extends AbstractAttributeEditor {
72
public class RichTextAttributeEditor extends AbstractAttributeEditor {
63
73
64
	private RepositoryTextViewer viewer;
74
	private IContextActivation contextActivation;
65
75
66
	private boolean spellCheckingEnabled;
76
	private final IContextService contextService;
67
77
68
	private final int style;
78
	private SourceViewer defaultViewer;
79
80
	private Composite editorComposite;
81
82
	private StackLayout editorLayout;
83
84
	private final AbstractTaskEditorExtension extension;
85
86
	private SourceViewer editorViewer;
87
88
	private SourceViewer previewViewer;
69
89
70
	private final TaskRepository taskRepository;
90
	private final TaskRepository taskRepository;
71
91
92
	private FormToolkit toolkit;
93
94
	public class ViewSourceAction extends Action {
95
96
		public ViewSourceAction() {
97
			super("Viewer Source", SWT.TOGGLE);
98
			setChecked(false);
99
		}
100
101
		@Override
102
		public void run() {
103
			if (isChecked()) {
104
				showDefault();
105
			} else {
106
				showEditor();
107
			}
108
		}
109
110
	}
111
112
	private final IAction viewSourceAction = new ViewSourceAction();
113
114
	private boolean spellCheckingEnabled;
115
116
	private final int style;
117
72
	private Mode mode;
118
	private Mode mode;
73
119
74
	public RichTextAttributeEditor(TaskDataModel manager, TaskRepository taskRepository, TaskAttribute taskAttribute) {
120
	public RichTextAttributeEditor(TaskDataModel manager, TaskRepository taskRepository, TaskAttribute taskAttribute) {
Lines 77-85 Link Here
77
123
78
	public RichTextAttributeEditor(TaskDataModel manager, TaskRepository taskRepository, TaskAttribute taskAttribute,
124
	public RichTextAttributeEditor(TaskDataModel manager, TaskRepository taskRepository, TaskAttribute taskAttribute,
79
			int style) {
125
			int style) {
126
		this(manager, taskRepository, taskAttribute, style, null, null);
127
	}
128
129
	public RichTextAttributeEditor(TaskDataModel manager, TaskRepository taskRepository, TaskAttribute taskAttribute,
130
			int style, IContextService contextService, AbstractTaskEditorExtension extension) {
80
		super(manager, taskAttribute);
131
		super(manager, taskAttribute);
81
		this.taskRepository = taskRepository;
132
		this.taskRepository = taskRepository;
82
		this.style = style;
133
		this.style = style;
134
		this.contextService = contextService;
135
		this.extension = extension;
83
		if ((style & SWT.MULTI) != 0) {
136
		if ((style & SWT.MULTI) != 0) {
84
			setLayoutHint(new LayoutHint(RowSpan.MULTIPLE, ColumnSpan.MULTIPLE));
137
			setLayoutHint(new LayoutHint(RowSpan.MULTIPLE, ColumnSpan.MULTIPLE));
85
		} else {
138
		} else {
Lines 97-111 Link Here
97
		this.mode = mode;
150
		this.mode = mode;
98
	}
151
	}
99
152
100
	private void configureAsTextEditor(Document document) {
153
	private void installListeners(final SourceViewer viewer) {
154
		viewer.addTextListener(new ITextListener() {
155
			public void textChanged(TextEvent event) {
156
				// filter out events caused by text presentation changes, e.g. annotation drawing
157
				String value = viewer.getTextWidget().getText();
158
				if (!getValue().equals(value)) {
159
					setValue(value);
160
					EditorUtil.ensureVisible(viewer.getTextWidget());
161
				}
162
			}
163
		});
164
		// ensure that tab traverses to next control instead of inserting a tab character unless editing multi-line text
165
		if ((style & SWT.MULTI) != 0 && mode != Mode.DEFAULT) {
166
			viewer.getTextWidget().addListener(SWT.Traverse, new Listener() {
167
				public void handleEvent(Event event) {
168
					switch (event.detail) {
169
					case SWT.TRAVERSE_TAB_NEXT:
170
					case SWT.TRAVERSE_TAB_PREVIOUS:
171
						event.doit = true;
172
						break;
173
					}
174
				}
175
			});
176
		}
177
	}
178
179
	public String getValue() {
180
		return getAttributeMapper().getValue(getTaskAttribute());
181
	}
182
183
	public boolean isSpellCheckingEnabled() {
184
		return spellCheckingEnabled;
185
	}
186
187
	public void setSpellCheckingEnabled(boolean spellCheckingEnabled) {
188
		this.spellCheckingEnabled = spellCheckingEnabled;
189
	}
190
191
	public void setValue(String value) {
192
		getAttributeMapper().setValue(getTaskAttribute(), value);
193
		attributeChanged();
194
	}
195
196
	/** Configures annotation model for spell checking. */
197
	private void configureAsEditor(SourceViewer viewer, Document document) {
101
		AnnotationModel annotationModel = new AnnotationModel();
198
		AnnotationModel annotationModel = new AnnotationModel();
102
		viewer.showAnnotations(false);
199
		viewer.showAnnotations(false);
103
		viewer.showAnnotationsOverview(false);
200
		viewer.showAnnotationsOverview(false);
104
		IAnnotationAccess annotationAccess = new DefaultMarkerAnnotationAccess();
201
		IAnnotationAccess annotationAccess = new DefaultMarkerAnnotationAccess();
105
		final SourceViewerDecorationSupport support = new SourceViewerDecorationSupport(viewer, null, annotationAccess,
202
		final SourceViewerDecorationSupport support = new SourceViewerDecorationSupport(viewer, null, annotationAccess,
106
				EditorsUI.getSharedTextColors());
203
				EditorsUI.getSharedTextColors());
107
		@SuppressWarnings("unchecked")
204
		Iterator<?> e = new MarkerAnnotationPreferences().getAnnotationPreferences().iterator();
108
		Iterator e = new MarkerAnnotationPreferences().getAnnotationPreferences().iterator();
109
		while (e.hasNext()) {
205
		while (e.hasNext()) {
110
			support.setAnnotationPreference((AnnotationPreference) e.next());
206
			support.setAnnotationPreference((AnnotationPreference) e.next());
111
		}
207
		}
Lines 115-160 Link Here
115
				support.uninstall();
211
				support.uninstall();
116
			}
212
			}
117
		});
213
		});
118
		viewer.getTextWidget().setIndent(2);
214
		//viewer.getTextWidget().setIndent(2);
119
		viewer.setDocument(document, annotationModel);
215
		viewer.setDocument(document, annotationModel);
120
	}
216
	}
121
217
122
	@Override
218
	private RepositoryTextViewerConfiguration installHyperlinkPresenter(SourceViewer viewer) {
123
	public void createControl(Composite parent, FormToolkit toolkit) {
219
		RepositoryTextViewerConfiguration configuration = new RepositoryTextViewerConfiguration(taskRepository, false);
124
		int style = this.style;
125
		if (!isReadOnly() && (style & TasksUiInternal.SWT_NO_SCROLL) == 0) {
126
			style |= SWT.V_SCROLL;
127
		}
128
		viewer = new RepositoryTextViewer(taskRepository, parent, SWT.FLAT | SWT.WRAP | style);
129
130
		// NOTE: configuration must be applied before the document is set in order for
131
		// hyper link coloring to work, the Presenter requires the document object up front
132
		configure();
133
134
		Document document = new Document(getValue());
135
		if (isReadOnly()) {
136
			viewer.setEditable(false);
137
			viewer.setDocument(document);
138
		} else {
139
			viewer.setEditable(true);
140
			configureAsTextEditor(document);
141
			installListeners(viewer);
142
			viewer.getControl().setData(FormToolkit.KEY_DRAW_BORDER, FormToolkit.TEXT_BORDER);
143
		}
144
145
		IThemeManager themeManager = PlatformUI.getWorkbench().getThemeManager();
146
		Font font = themeManager.getCurrentTheme().getFontRegistry().get(CommonThemes.FONT_EDITOR_COMMENT);
147
		viewer.getTextWidget().setFont(font);
148
		toolkit.adapt(viewer.getTextWidget(), false, false);
149
150
		setControl(viewer.getTextWidget());
151
	}
152
153
	private RepositoryTextViewerConfiguration configure() {
154
		RepositoryTextViewerConfiguration configuration = new RepositoryTextViewerConfiguration(taskRepository,
155
				spellCheckingEnabled);
156
		configuration.setMode(getMode());
220
		configuration.setMode(getMode());
157
		viewer.configure(configuration);
221
222
		// do not configure viewer, this has already been done in extension
158
223
159
		AbstractHyperlinkTextPresentationManager manager;
224
		AbstractHyperlinkTextPresentationManager manager;
160
		if (getMode() == Mode.DEFAULT) {
225
		if (getMode() == Mode.DEFAULT) {
Lines 174-224 Link Here
174
		return configuration;
239
		return configuration;
175
	}
240
	}
176
241
177
	private void installListeners(RepositoryTextViewer viewer2) {
242
	private SourceViewer configure(final SourceViewer viewer, boolean readOnly) {
178
		viewer.addTextListener(new ITextListener() {
243
		// do this before setting the document to not require invalidating the presentation
179
			public void textChanged(TextEvent event) {
244
		installHyperlinkPresenter(viewer);
180
				// filter out events caused by text presentation changes, e.g. annotation drawing
245
181
				String value = viewer.getTextWidget().getText();
246
		Document document = new Document(getValue());
182
				if (!getValue().equals(value)) {
247
		if (readOnly) {
183
					setValue(value);
248
			viewer.setDocument(document);
184
					EditorUtil.ensureVisible(viewer.getTextWidget());
249
			if (extension != null) {
185
				}
250
				// setting view source action
251
				viewer.getControl().setData(ViewSourceHandler.VIEW_SOURCE_ACTION, viewSourceAction);
252
				viewer.getControl().addFocusListener(new FocusAdapter() {
253
					@Override
254
					public void focusGained(FocusEvent e) {
255
						ViewSourceHandler.setChecked(getViewer() == defaultViewer);
256
					}
257
				});
186
			}
258
			}
187
		});
259
		} else {
188
		// ensure that tab traverses to next control instead of inserting a tab character unless editing multi-line text
260
			configureAsEditor(viewer, document);
189
		if ((style & SWT.MULTI) != 0 && mode != Mode.DEFAULT) {
261
			installListeners(viewer);
190
			viewer.getTextWidget().addListener(SWT.Traverse, new Listener() {
262
			viewer.getControl().setData(FormToolkit.KEY_DRAW_BORDER, FormToolkit.TEXT_BORDER);
191
				public void handleEvent(Event event) {
263
		}
192
					switch (event.detail) {
264
193
					case SWT.TRAVERSE_TAB_NEXT:
265
		// enable cut/copy/paste
194
					case SWT.TRAVERSE_TAB_PREVIOUS:
266
		EditorUtil.setTextViewer(viewer.getTextWidget(), viewer);
195
						event.doit = true;
267
		viewer.setEditable(!readOnly);
196
						break;
268
		viewer.getTextWidget().setFont(getFont());
269
		toolkit.adapt(viewer.getControl(), false, false);
270
271
		return viewer;
272
	}
273
274
	@Override
275
	public void createControl(Composite parent, FormToolkit toolkit) {
276
		this.toolkit = toolkit;
277
278
		int style = this.style;
279
		if (!isReadOnly() && (style & TasksUiInternal.SWT_NO_SCROLL) == 0) {
280
			style |= SWT.V_SCROLL;
281
		}
282
283
		if (extension != null) {
284
			editorComposite = new Composite(parent, SWT.NULL);
285
			editorLayout = new StackLayout() {
286
				@Override
287
				protected Point computeSize(Composite composite, int hint, int hint2, boolean flushCache) {
288
					return topControl.computeSize(hint, hint2, flushCache);
289
				}
290
			};
291
			editorComposite.setLayout(editorLayout);
292
			setControl(editorComposite);
293
294
			if (isReadOnly()) {
295
				editorViewer = extension.createViewer(taskRepository, editorComposite, style);
296
			} else {
297
				editorViewer = extension.createEditor(taskRepository, editorComposite, style);
298
				editorViewer.getTextWidget().addFocusListener(new FocusListener() {
299
					public void focusGained(FocusEvent e) {
300
						setContext();
197
					}
301
					}
302
303
					public void focusLost(FocusEvent e) {
304
						unsetContext();
305
					}
306
				});
307
				editorViewer.getTextWidget().addDisposeListener(new DisposeListener() {
308
					public void widgetDisposed(DisposeEvent e) {
309
						unsetContext();
310
					}
311
				});
312
			}
313
			configure(editorViewer, isReadOnly());
314
			show(editorViewer);
315
		} else {
316
			defaultViewer = createDefaultEditor(parent, style);
317
			configure(defaultViewer, isReadOnly());
318
			setControl(defaultViewer.getControl());
319
		}
320
	}
321
322
	private SourceViewer createDefaultEditor(Composite parent, int styles) {
323
		SourceViewer defaultEditor = new RepositoryTextViewer(taskRepository, parent, styles | SWT.WRAP);
324
325
		RepositoryTextViewerConfiguration viewerConfig = new RepositoryTextViewerConfiguration(taskRepository,
326
				isSpellCheckingEnabled());
327
		viewerConfig.setMode(getMode());
328
		defaultEditor.configure(viewerConfig);
329
330
		return defaultEditor;
331
	}
332
333
	public SourceViewer getDefaultViewer() {
334
		if (defaultViewer == null) {
335
			defaultViewer = createDefaultEditor(editorComposite, style);
336
			configure(defaultViewer, isReadOnly());
337
338
			// fixed font size
339
			defaultViewer.getTextWidget().setFont(JFaceResources.getFontRegistry().get(JFaceResources.TEXT_FONT));
340
			// adapt maximize action
341
			defaultViewer.getControl().setData(EditorUtil.KEY_TOGGLE_TO_MAXIMIZE_ACTION,
342
					editorViewer.getControl().getData(EditorUtil.KEY_TOGGLE_TO_MAXIMIZE_ACTION));
343
			// adapt menu to the new viewer
344
			installMenu(defaultViewer.getControl(), editorViewer.getControl().getMenu());
345
		}
346
		return defaultViewer;
347
	}
348
349
	private void installMenu(final Control control, Menu menu) {
350
		if (menu != null) {
351
			control.setMenu(menu);
352
			control.addDisposeListener(new DisposeListener() {
353
				public void widgetDisposed(DisposeEvent e) {
354
					control.setMenu(null);
198
				}
355
				}
199
			});
356
			});
200
		}
357
		}
201
	}
358
	}
202
359
203
	public String getValue() {
360
	private Font getFont() {
204
		return getAttributeMapper().getValue(getTaskAttribute());
361
		IThemeManager themeManager = PlatformUI.getWorkbench().getThemeManager();
362
		Font font = themeManager.getCurrentTheme().getFontRegistry().get(CommonThemes.FONT_EDITOR_COMMENT);
363
		return font;
364
	}
365
366
	private SourceViewer getPreviewViewer() {
367
		if (extension == null) {
368
			return null;
369
		}
370
371
		// construct as needed
372
		if (previewViewer == null) {
373
			previewViewer = extension.createViewer(taskRepository, editorComposite, style);
374
			configure(previewViewer, true);
375
			// adapt maximize action
376
			previewViewer.getControl().setData(EditorUtil.KEY_TOGGLE_TO_MAXIMIZE_ACTION,
377
					editorViewer.getControl().getData(EditorUtil.KEY_TOGGLE_TO_MAXIMIZE_ACTION));
378
		}
379
		Document document = new Document(editorViewer.getDocument().get());
380
		previewViewer.setDocument(document);
381
		return previewViewer;
382
	}
383
384
	public SourceViewer getEditorViewer() {
385
		return editorViewer;
205
	}
386
	}
206
387
207
	public SourceViewer getViewer() {
388
	public SourceViewer getViewer() {
208
		return viewer;
389
		if (editorLayout == null) {
390
			return defaultViewer;
391
		}
392
		if (defaultViewer != null && editorLayout.topControl == defaultViewer.getControl()) {
393
			return defaultViewer;
394
		} else if (previewViewer != null && editorLayout.topControl == previewViewer.getControl()) {
395
			return previewViewer;
396
		} else {
397
			return editorViewer;
398
		}
209
	}
399
	}
210
400
211
	public boolean isSpellCheckingEnabled() {
401
	private void setContext() {
212
		return spellCheckingEnabled;
402
		if (contextService == null) {
403
			return;
404
		}
405
		if (contextActivation != null) {
406
			contextService.deactivateContext(contextActivation);
407
			contextActivation = null;
408
		}
409
		if (contextService != null && extension.getEditorContextId() != null) {
410
			contextActivation = contextService.activateContext(extension.getEditorContextId());
411
		}
213
	}
412
	}
214
413
215
	public void setSpellCheckingEnabled(boolean spellCheckingEnabled) {
414
	/**
216
		this.spellCheckingEnabled = spellCheckingEnabled;
415
	 * Brings <code>viewer</code> to top.
416
	 */
417
	private void show(SourceViewer viewer) {
418
		// no extension is available
419
		if (editorComposite == null) {
420
			return;
421
		}
422
423
		editorLayout.topControl = viewer.getControl();
424
		editorComposite.layout();
425
		viewer.getControl().setFocus();
217
	}
426
	}
218
427
219
	public void setValue(String value) {
428
	public void showDefault() {
220
		getAttributeMapper().setValue(getTaskAttribute(), value);
429
		show(getDefaultViewer());
221
		attributeChanged();
430
	}
431
432
	public void showPreview() {
433
		if (!isReadOnly()) {
434
			show(getPreviewViewer());
435
		}
436
	}
437
438
	public void showEditor() {
439
		show(getEditorViewer());
440
	}
441
442
	private void unsetContext() {
443
		if (contextService == null) {
444
			return;
445
		}
446
		if (contextActivation != null) {
447
			contextService.deactivateContext(contextActivation);
448
			contextActivation = null;
449
		}
450
	}
451
452
	public boolean hasPreview() {
453
		return extension != null && !isReadOnly();
222
	}
454
	}
223
455
224
}
456
}
(-)src/org/eclipse/mylyn/internal/tasks/ui/editors/TaskEditorRichTextPart.java (-4 / +34 lines)
Lines 14-19 Link Here
14
import org.eclipse.core.runtime.IStatus;
14
import org.eclipse.core.runtime.IStatus;
15
import org.eclipse.core.runtime.Status;
15
import org.eclipse.core.runtime.Status;
16
import org.eclipse.jface.action.Action;
16
import org.eclipse.jface.action.Action;
17
import org.eclipse.jface.action.ToolBarManager;
17
import org.eclipse.jface.layout.GridDataFactory;
18
import org.eclipse.jface.layout.GridDataFactory;
18
import org.eclipse.mylyn.commons.core.StatusHandler;
19
import org.eclipse.mylyn.commons.core.StatusHandler;
19
import org.eclipse.mylyn.internal.provisional.commons.ui.CommonImages;
20
import org.eclipse.mylyn.internal.provisional.commons.ui.CommonImages;
Lines 27-32 Link Here
27
import org.eclipse.swt.layout.GridData;
28
import org.eclipse.swt.layout.GridData;
28
import org.eclipse.swt.layout.GridLayout;
29
import org.eclipse.swt.layout.GridLayout;
29
import org.eclipse.swt.widgets.Composite;
30
import org.eclipse.swt.widgets.Composite;
31
import org.eclipse.swt.widgets.Control;
30
import org.eclipse.ui.forms.widgets.ExpandableComposite;
32
import org.eclipse.ui.forms.widgets.ExpandableComposite;
31
import org.eclipse.ui.forms.widgets.FormToolkit;
33
import org.eclipse.ui.forms.widgets.FormToolkit;
32
import org.eclipse.ui.forms.widgets.Section;
34
import org.eclipse.ui.forms.widgets.Section;
Lines 158-163 Link Here
158
			}
160
			}
159
		}
161
		}
160
162
163
		getEditor().getControl().setData(EditorUtil.KEY_TOGGLE_TO_MAXIMIZE_ACTION, getMaximizePartAction());
164
		if (getEditor().getControl() instanceof Composite) {
165
			for (Control control : ((Composite) getEditor().getControl()).getChildren()) {
166
				control.setData(EditorUtil.KEY_TOGGLE_TO_MAXIMIZE_ACTION, getMaximizePartAction());
167
			}
168
		}
161
		getTaskEditorPage().getAttributeEditorToolkit().adapt(editor);
169
		getTaskEditorPage().getAttributeEditorToolkit().adapt(editor);
162
170
163
		toolkit.paintBordersFor(composite);
171
		toolkit.paintBordersFor(composite);
Lines 234-243 Link Here
234
242
235
		@Override
243
		@Override
236
		public void run() {
244
		public void run() {
237
			toogleToMaximizePart();
238
		}
239
240
		private void toogleToMaximizePart() {
241
			if (!(getEditor().getControl().getLayoutData() instanceof GridData)) {
245
			if (!(getEditor().getControl().getLayoutData() instanceof GridData)) {
242
				return;
246
				return;
243
			}
247
			}
Lines 273-276 Link Here
273
		}
277
		}
274
	}
278
	}
275
279
280
	@Override
281
	protected void fillToolBar(ToolBarManager manager) {
282
		if (getEditor().hasPreview()) {
283
			Action toggleEditingAction = new Action("", SWT.TOGGLE) {
284
				@Override
285
				public void run() {
286
					toggleEditing(this);
287
				}
288
			};
289
			toggleEditingAction.setImageDescriptor(CommonImages.PREVIEW_WEB);
290
			toggleEditingAction.setToolTipText("Preview");
291
			toggleEditingAction.setChecked(false);
292
			manager.add(toggleEditingAction);
293
		}
294
		manager.add(getMaximizePartAction());
295
		super.fillToolBar(manager);
296
	}
297
298
	private void toggleEditing(Action action) {
299
		if (action.isChecked()) {
300
			editor.showPreview();
301
		} else {
302
			editor.showEditor();
303
		}
304
	}
305
276
}
306
}
(-)src/org/eclipse/mylyn/tasks/ui/editors/AbstractTaskEditorPage.java (-1 / +1 lines)
Lines 487-493 Link Here
487
	}
487
	}
488
488
489
	protected AttributeEditorFactory createAttributeEditorFactory() {
489
	protected AttributeEditorFactory createAttributeEditorFactory() {
490
		return new AttributeEditorFactory(getModel(), getTaskRepository());
490
		return new AttributeEditorFactory(getModel(), getTaskRepository(), getEditorSite());
491
	}
491
	}
492
492
493
	AttributeEditorToolkit createAttributeEditorToolkit() {
493
	AttributeEditorToolkit createAttributeEditorToolkit() {
(-)src/org/eclipse/mylyn/tasks/ui/editors/AttributeEditorFactory.java (-1 / +26 lines)
Lines 1-5 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
* Copyright (c) 2004, 2008 Tasktop Technologies and others.
2
 * Copyright (c) 2004, 2008 Tasktop Technologies and others.
3
 * All rights reserved. This program and the accompanying materials
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
Lines 19-24 Link Here
19
import org.eclipse.mylyn.internal.tasks.ui.editors.PersonAttributeEditor;
19
import org.eclipse.mylyn.internal.tasks.ui.editors.PersonAttributeEditor;
20
import org.eclipse.mylyn.internal.tasks.ui.editors.RichTextAttributeEditor;
20
import org.eclipse.mylyn.internal.tasks.ui.editors.RichTextAttributeEditor;
21
import org.eclipse.mylyn.internal.tasks.ui.editors.SingleSelectionAttributeEditor;
21
import org.eclipse.mylyn.internal.tasks.ui.editors.SingleSelectionAttributeEditor;
22
import org.eclipse.mylyn.internal.tasks.ui.editors.TaskEditorExtensions;
22
import org.eclipse.mylyn.internal.tasks.ui.editors.TextAttributeEditor;
23
import org.eclipse.mylyn.internal.tasks.ui.editors.TextAttributeEditor;
23
import org.eclipse.mylyn.internal.tasks.ui.editors.RepositoryTextViewerConfiguration.Mode;
24
import org.eclipse.mylyn.internal.tasks.ui.editors.RepositoryTextViewerConfiguration.Mode;
24
import org.eclipse.mylyn.internal.tasks.ui.util.TasksUiInternal;
25
import org.eclipse.mylyn.internal.tasks.ui.util.TasksUiInternal;
Lines 28-33 Link Here
28
import org.eclipse.mylyn.tasks.ui.editors.LayoutHint.ColumnSpan;
29
import org.eclipse.mylyn.tasks.ui.editors.LayoutHint.ColumnSpan;
29
import org.eclipse.mylyn.tasks.ui.editors.LayoutHint.RowSpan;
30
import org.eclipse.mylyn.tasks.ui.editors.LayoutHint.RowSpan;
30
import org.eclipse.swt.SWT;
31
import org.eclipse.swt.SWT;
32
import org.eclipse.ui.contexts.IContextService;
33
import org.eclipse.ui.services.IServiceLocator;
31
34
32
/**
35
/**
33
 * @since 3.0
36
 * @since 3.0
Lines 39-47 Link Here
39
42
40
	private final TaskRepository taskRepository;
43
	private final TaskRepository taskRepository;
41
44
45
	private final IServiceLocator serviceLocator;
46
42
	public AttributeEditorFactory(TaskDataModel model, TaskRepository taskRepository) {
47
	public AttributeEditorFactory(TaskDataModel model, TaskRepository taskRepository) {
48
		this(model, taskRepository, null);
49
	}
50
51
	/**
52
	 * @since 3.1
53
	 */
54
	public AttributeEditorFactory(TaskDataModel model, TaskRepository taskRepository, IServiceLocator serviceLocator) {
55
		Assert.isNotNull(model);
56
		Assert.isNotNull(taskRepository);
43
		this.model = model;
57
		this.model = model;
44
		this.taskRepository = taskRepository;
58
		this.taskRepository = taskRepository;
59
		this.serviceLocator = serviceLocator;
45
	}
60
	}
46
61
47
	public AbstractAttributeEditor createEditor(String type, TaskAttribute taskAttribute) {
62
	public AbstractAttributeEditor createEditor(String type, TaskAttribute taskAttribute) {
Lines 54-59 Link Here
54
		} else if (TaskAttribute.TYPE_PERSON.equals(type)) {
69
		} else if (TaskAttribute.TYPE_PERSON.equals(type)) {
55
			return new PersonAttributeEditor(model, taskAttribute);
70
			return new PersonAttributeEditor(model, taskAttribute);
56
		} else if (TaskAttribute.TYPE_LONG_RICH_TEXT.equals(type)) {
71
		} else if (TaskAttribute.TYPE_LONG_RICH_TEXT.equals(type)) {
72
			if (serviceLocator != null) {
73
				IContextService contextService = (IContextService) serviceLocator.getService(IContextService.class);
74
				if (contextService != null) {
75
					AbstractTaskEditorExtension extension = TaskEditorExtensions.getTaskEditorExtension(model.getTaskRepository());
76
					if (extension != null) {
77
						return new RichTextAttributeEditor(model, taskRepository, taskAttribute, SWT.MULTI,
78
								contextService, extension);
79
					}
80
				}
81
			}
57
			return new RichTextAttributeEditor(model, taskRepository, taskAttribute);
82
			return new RichTextAttributeEditor(model, taskRepository, taskAttribute);
58
		} else if (TaskAttribute.TYPE_LONG_TEXT.equals(type)) {
83
		} else if (TaskAttribute.TYPE_LONG_TEXT.equals(type)) {
59
			return new LongTextAttributeEditor(model, taskAttribute);
84
			return new LongTextAttributeEditor(model, taskAttribute);
(-)plugin.xml (+7 lines)
Lines 7-12 Link Here
7
    <extension-point id="projectLinkProviders" name="Linking Provider from Project to the Task Repository" schema="schema/projectLinkProviders.exsd"/>
7
    <extension-point id="projectLinkProviders" name="Linking Provider from Project to the Task Repository" schema="schema/projectLinkProviders.exsd"/>
8
    <extension-point id="duplicateDetectors" name="duplicateDetectors" schema="schema/duplicateDetectors.exsd"/>
8
    <extension-point id="duplicateDetectors" name="duplicateDetectors" schema="schema/duplicateDetectors.exsd"/>
9
    <extension-point id="presentations" name="presentations" schema="schema/presentations.exsd"/>
9
    <extension-point id="presentations" name="presentations" schema="schema/presentations.exsd"/>
10
    <extension-point id="taskEditorExtensions" name="Task Editor Extension" schema="schema/taskEditorExtensions.exsd"/>
10
11
11
    <extension
12
    <extension
12
          point="org.eclipse.mylyn.context.core.bridges">
13
          point="org.eclipse.mylyn.context.core.bridges">
Lines 1745-1750 Link Here
1745
            id="org.eclipse.mylyn.tasks.ui.command.maximizePart"
1746
            id="org.eclipse.mylyn.tasks.ui.command.maximizePart"
1746
            name="Maximize Part">
1747
            name="Maximize Part">
1747
      </command>
1748
      </command>
1749
      <command
1750
            categoryId="org.eclipse.mylyn.tasks.ui.commands"
1751
            defaultHandler="org.eclipse.mylyn.internal.tasks.ui.commands.ViewSourceHandler"
1752
            id="org.eclipse.mylyn.sandbox.ui.viewSource.command"
1753
            name="View Source">
1754
      </command>
1748
   </extension>
1755
   </extension>
1749
   <extension
1756
   <extension
1750
         point="org.eclipse.ui.bindings">
1757
         point="org.eclipse.ui.bindings">
(-)src/org/eclipse/mylyn/internal/tasks/ui/editors/TaskEditorExtensionReader.java (+86 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2004, 2008 David Green 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
 *     David Green - initial API and implementation
10
 *******************************************************************************/
11
12
package org.eclipse.mylyn.internal.tasks.ui.editors;
13
14
import org.eclipse.core.runtime.CoreException;
15
import org.eclipse.core.runtime.IConfigurationElement;
16
import org.eclipse.core.runtime.IExtension;
17
import org.eclipse.core.runtime.IExtensionPoint;
18
import org.eclipse.core.runtime.IExtensionRegistry;
19
import org.eclipse.core.runtime.IStatus;
20
import org.eclipse.core.runtime.Platform;
21
import org.eclipse.core.runtime.Status;
22
import org.eclipse.mylyn.commons.core.StatusHandler;
23
import org.eclipse.mylyn.internal.tasks.ui.TasksUiPlugin;
24
import org.eclipse.mylyn.tasks.ui.editors.AbstractTaskEditorExtension;
25
26
/**
27
 * @author David Green
28
 */
29
public class TaskEditorExtensionReader {
30
31
	private static final String CONNECTOR_KIND = "connectorKind";
32
33
	public static final String ATTR_ID = "id";
34
35
	public static final String ATTR_NAME = "name";
36
37
	public static final String EXTENSION_TASK_EDITOR_EXTENSIONS = "org.eclipse.mylyn.tasks.ui.taskEditorExtensions";
38
39
	private static final String REPOSITORY_ASSOCIATION = "repositoryAssociation";
40
41
	private static final String TASK_EDITOR_EXTENSION = "taskEditorExtension";
42
43
	public static void initExtensions() {
44
		IExtensionRegistry registry = Platform.getExtensionRegistry();
45
46
		IExtensionPoint editorExtensionPoint = registry.getExtensionPoint(EXTENSION_TASK_EDITOR_EXTENSIONS);
47
		IExtension[] editorExtensions = editorExtensionPoint.getExtensions();
48
		for (IExtension extension : editorExtensions) {
49
			IConfigurationElement[] elements = extension.getConfigurationElements();
50
			for (IConfigurationElement element : elements) {
51
				if (element.getName().equals(TASK_EDITOR_EXTENSION)) {
52
					readEditorExtension(element);
53
				} else if (element.getName().equals(REPOSITORY_ASSOCIATION)) {
54
					readEditorExtensionAssociation(element);
55
				}
56
			}
57
		}
58
	}
59
60
	private static void readEditorExtension(IConfigurationElement element) {
61
		try {
62
			String id = element.getAttribute(ATTR_ID);
63
			String name = element.getAttribute(ATTR_NAME);
64
			AbstractTaskEditorExtension extension = (AbstractTaskEditorExtension) element.createExecutableExtension("class");
65
			TaskEditorExtensions.addTaskEditorExtension(id, name, extension);
66
		} catch (CoreException e) {
67
			StatusHandler.log(new Status(IStatus.ERROR, TasksUiPlugin.ID_PLUGIN, "Could not load taskEditorExtension",
68
					e));
69
		} catch (Exception e) {
70
			StatusHandler.log(new Status(IStatus.ERROR, TasksUiPlugin.ID_PLUGIN, "Could not load taskEditorExtension",
71
					e));
72
		}
73
	}
74
75
	private static void readEditorExtensionAssociation(IConfigurationElement element) {
76
		try {
77
			String repository = element.getAttribute(CONNECTOR_KIND);
78
			String taskEditorExtension = element.getAttribute(TASK_EDITOR_EXTENSION);
79
			TaskEditorExtensions.addRepositoryAssociation(repository, taskEditorExtension);
80
		} catch (Exception e) {
81
			StatusHandler.log(new Status(IStatus.ERROR, TasksUiPlugin.ID_PLUGIN,
82
					"Could not load repositoryAssociation", e));
83
		}
84
	}
85
86
}
(-)schema/taskEditorExtensions.exsd (+152 lines)
Added Link Here
1
<?xml version='1.0' encoding='UTF-8'?>
2
<!-- Schema file written by PDE -->
3
<schema targetNamespace="org.eclipse.mylyn.tasks.ui" xmlns="http://www.w3.org/2001/XMLSchema">
4
<annotation>
5
      <appinfo>
6
         <meta.schema plugin="org.eclipse.mylyn.tasks.ui" id="taskEditorExtensions" name="Task Editor Extensions"/>
7
      </appinfo>
8
      <documentation>
9
         An extension to the Mylyn task editor that can provide viewing and editing controls that are markup-aware.
10
      </documentation>
11
   </annotation>
12
13
   <element name="extension">
14
      <annotation>
15
         <appinfo>
16
            <meta.element />
17
         </appinfo>
18
      </annotation>
19
      <complexType>
20
         <sequence>
21
            <element ref="taskEditorExtension" minOccurs="0" maxOccurs="unbounded"/>
22
            <element ref="repositoryAssociation" minOccurs="0" maxOccurs="unbounded"/>
23
         </sequence>
24
         <attribute name="point" type="string" use="required">
25
            <annotation>
26
               <documentation>
27
                  
28
               </documentation>
29
            </annotation>
30
         </attribute>
31
         <attribute name="id" type="string">
32
            <annotation>
33
               <documentation>
34
                  
35
               </documentation>
36
            </annotation>
37
         </attribute>
38
         <attribute name="name" type="string">
39
            <annotation>
40
               <documentation>
41
                  
42
               </documentation>
43
               <appinfo>
44
                  <meta.attribute translatable="true"/>
45
               </appinfo>
46
            </annotation>
47
         </attribute>
48
      </complexType>
49
   </element>
50
51
   <element name="taskEditorExtension">
52
      <annotation>
53
         <documentation>
54
            Declare an extension to the Mylyn task editor.  Extensions are typically capable of providing improved editing capabilities, such as markup-aware.
55
         </documentation>
56
      </annotation>
57
      <complexType>
58
         <attribute name="class" type="string" use="required">
59
            <annotation>
60
               <documentation>
61
                  the fully qualified class name of the class that extends org.eclipse.mylyn.internal.sandbox.ui.editors.AbstractTaskEditorExtension
62
               </documentation>
63
               <appinfo>
64
                  <meta.attribute kind="java" basedOn="org.eclipse.mylyn.internal.sandbox.ui.editors.AbstractTaskEditorExtension:"/>
65
               </appinfo>
66
            </annotation>
67
         </attribute>
68
         <attribute name="id" type="string" use="required">
69
            <annotation>
70
               <documentation>
71
                  a unique identifier identifying the extension
72
               </documentation>
73
               <appinfo>
74
                  <meta.attribute kind="identifier"/>
75
               </appinfo>
76
            </annotation>
77
         </attribute>
78
         <attribute name="name" type="string" use="required">
79
            <annotation>
80
               <documentation>
81
                  A human-readable name for the extension that is presented to the Eclipse user in the UI.    Should be translated.  Used in the UI to identify the type of extension, so the name should indicate what the extension is for, and it should be short so that it can be displayed on one line (for example as an option in a combo box.)  Example: &quot;TracWiki&quot;, or &quot;Textile&quot;.
82
               </documentation>
83
               <appinfo>
84
                  <meta.attribute translatable="true"/>
85
               </appinfo>
86
            </annotation>
87
         </attribute>
88
      </complexType>
89
   </element>
90
91
   <element name="repositoryAssociation">
92
      <annotation>
93
         <documentation>
94
            Associate the task editor extension with a kind of repository.  Making such an association causes the taskEditorExtension to become the default or preferred setting for a kind of repository.
95
         </documentation>
96
      </annotation>
97
      <complexType>
98
         <attribute name="connectorKind" type="string" use="required">
99
            <annotation>
100
               <documentation>
101
                  the kind of connector for that this task editor extension should be associated with.
102
               </documentation>
103
            </annotation>
104
         </attribute>
105
         <attribute name="taskEditorExtension" type="string" use="required">
106
            <annotation>
107
               <documentation>
108
                  the id of the taskEditorExtension to associate
109
               </documentation>
110
            </annotation>
111
         </attribute>
112
      </complexType>
113
   </element>
114
115
   <annotation>
116
      <appinfo>
117
         <meta.section type="since"/>
118
      </appinfo>
119
      <documentation>
120
         3.0
121
      </documentation>
122
   </annotation>
123
124
   <annotation>
125
      <appinfo>
126
         <meta.section type="examples"/>
127
      </appinfo>
128
      <documentation>
129
         [Enter extension point usage example here.]
130
      </documentation>
131
   </annotation>
132
133
   <annotation>
134
      <appinfo>
135
         <meta.section type="apiinfo"/>
136
      </appinfo>
137
      <documentation>
138
         [Enter API information here.]
139
      </documentation>
140
   </annotation>
141
142
   <annotation>
143
      <appinfo>
144
         <meta.section type="implementation"/>
145
      </appinfo>
146
      <documentation>
147
         [Enter information about supplied implementation of this extension point.]
148
      </documentation>
149
   </annotation>
150
151
152
</schema>
(-)src/org/eclipse/mylyn/tasks/ui/editors/AbstractTaskEditorExtension.java (+64 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2004, 2008 David Green 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
 *     David Green - initial API and implementation
10
 *******************************************************************************/
11
12
package org.eclipse.mylyn.tasks.ui.editors;
13
14
import org.eclipse.jface.text.source.SourceViewer;
15
import org.eclipse.mylyn.tasks.core.TaskRepository;
16
import org.eclipse.swt.widgets.Composite;
17
import org.eclipse.ui.contexts.IContextService;
18
19
/**
20
 * An extension that provides task editor capabilities beyond the default, oriented towards providing markup-aware
21
 * editing and viewing
22
 * 
23
 * @author David Green
24
 * @since 3.1
25
 */
26
public abstract class AbstractTaskEditorExtension {
27
28
	/**
29
	 * The key to access the {@link TaskRepository} property that stores the URL of an associated wiki.
30
	 */
31
	public static final String INTERNAL_WIKI_LINK_PATTERN = "wikiLinkPattern";
32
33
	/**
34
	 * Creates a source viewer that can be used to view content in the task editor. The source viewer should be
35
	 * configured with a source viewer configuration prior to returning.
36
	 * 
37
	 * @param taskRepository
38
	 *            the task repository for which the viewer is created
39
	 * @param parent
40
	 *            the control parent of the source viewer
41
	 * @param style
42
	 *            the styles to use
43
	 */
44
	public abstract SourceViewer createViewer(TaskRepository taskRepository, Composite parent, int style);
45
46
	/**
47
	 * Creates a source viewer that can be used to edit content in the task editor. The source viewer should be
48
	 * configured with a source viewer configuration prior to returning.
49
	 * 
50
	 * @param taskRepository
51
	 *            the task repository for which the viewer is created
52
	 * @param parent
53
	 *            the control parent of the source viewer
54
	 * @param style
55
	 *            the styles to use
56
	 */
57
	public abstract SourceViewer createEditor(TaskRepository taskRepository, Composite parent, int style);
58
59
	/**
60
	 * Returns the editor context id, to be passed to the {@link IContextService} when the editor is in focus.
61
	 */
62
	public abstract String getEditorContextId();
63
64
}
(-)src/org/eclipse/mylyn/internal/tasks/ui/commands/ViewSourceHandler.java (+103 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2004, 2008 Jingwen Ou 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
 *     Jingwen Ou - initial API and implementation
10
 *     Tasktop Technologies - improvements
11
 *******************************************************************************/
12
13
package org.eclipse.mylyn.internal.tasks.ui.commands;
14
15
import java.util.Map;
16
17
import org.eclipse.core.commands.AbstractHandler;
18
import org.eclipse.core.commands.ExecutionEvent;
19
import org.eclipse.core.commands.ExecutionException;
20
import org.eclipse.core.commands.HandlerEvent;
21
import org.eclipse.jface.action.IAction;
22
import org.eclipse.mylyn.internal.tasks.ui.editors.EditorUtil;
23
import org.eclipse.swt.custom.StyledText;
24
import org.eclipse.swt.widgets.Control;
25
import org.eclipse.ui.IEditorSite;
26
import org.eclipse.ui.IWorkbenchPart;
27
import org.eclipse.ui.IWorkbenchSite;
28
import org.eclipse.ui.PlatformUI;
29
import org.eclipse.ui.commands.IElementUpdater;
30
import org.eclipse.ui.forms.editor.FormEditor;
31
import org.eclipse.ui.forms.editor.IFormPage;
32
import org.eclipse.ui.handlers.HandlerUtil;
33
import org.eclipse.ui.menus.UIElement;
34
35
/**
36
 * @author Jingwen Ou
37
 * @author Steffen Pingel
38
 */
39
public class ViewSourceHandler extends AbstractHandler implements IElementUpdater {
40
41
	private static boolean checked;
42
43
	private static ViewSourceHandler instance;
44
45
	public ViewSourceHandler() {
46
		instance = this;
47
	}
48
49
	public boolean isChecked() {
50
		return checked;
51
	}
52
53
	public static void setChecked(boolean checked) {
54
		ViewSourceHandler.checked = checked;
55
		if (instance != null) {
56
			instance.fireHandlerChanged(new HandlerEvent(instance, true, false));
57
		}
58
	}
59
60
	private Control getFocusControl() {
61
		return PlatformUI.getWorkbench().getDisplay().getFocusControl();
62
	}
63
64
	@Override
65
	public boolean isEnabled() {
66
		Control focusControl = getFocusControl();
67
		if (focusControl instanceof StyledText && focusControl.getData(VIEW_SOURCE_ACTION) instanceof IAction) {
68
			return true;
69
		}
70
71
		return false;
72
	}
73
74
	public static final String VIEW_SOURCE_ACTION = "viewSourceAction";
75
76
	public Object execute(ExecutionEvent event) throws ExecutionException {
77
		IWorkbenchSite site = HandlerUtil.getActiveSite(event);
78
		if (site instanceof IEditorSite) {
79
			IWorkbenchPart part = ((IEditorSite) site).getPart();
80
			if (part instanceof FormEditor) {
81
				IFormPage page = ((FormEditor) part).getActivePageInstance();
82
				Control focusedControl = EditorUtil.getFocusControl(page);
83
				if (focusedControl != null) {
84
					Object data = focusedControl.getData(VIEW_SOURCE_ACTION);
85
					if (data instanceof IAction) {
86
						IAction action = (IAction) data;
87
						action.setChecked(!action.isChecked());
88
						action.run();
89
						setChecked(action.isChecked());
90
						EditorUtil.reflow(focusedControl);
91
					}
92
				}
93
			}
94
		}
95
		return null;
96
	}
97
98
	@SuppressWarnings("unchecked")
99
	public void updateElement(UIElement element, Map parameters) {
100
		element.setChecked(checked);
101
	}
102
103
}
(-)src/org/eclipse/mylyn/internal/tasks/ui/editors/TaskEditorExtensions.java (+167 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2004, 2008 David Green 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
 *     David Green - initial API and implementation
10
 *******************************************************************************/
11
12
package org.eclipse.mylyn.internal.tasks.ui.editors;
13
14
import java.util.HashMap;
15
import java.util.Map;
16
import java.util.SortedSet;
17
import java.util.TreeSet;
18
19
import org.eclipse.core.runtime.Assert;
20
import org.eclipse.core.runtime.IStatus;
21
import org.eclipse.core.runtime.Status;
22
import org.eclipse.mylyn.commons.core.StatusHandler;
23
import org.eclipse.mylyn.internal.tasks.ui.TasksUiPlugin;
24
import org.eclipse.mylyn.tasks.core.TaskRepository;
25
import org.eclipse.mylyn.tasks.ui.editors.AbstractTaskEditorExtension;
26
27
/**
28
 * @author David Green
29
 */
30
public class TaskEditorExtensions {
31
32
	public static final String REPOSITORY_PROPERTY_EDITOR_EXTENSION = "editorExtension";
33
34
	private static Map<String, RegisteredTaskEditorExtension> extensionsById = new HashMap<String, RegisteredTaskEditorExtension>();
35
36
	private static Map<String, String> associationByConnectorKind = new HashMap<String, String>();
37
38
	private static boolean initialized;
39
40
	public static SortedSet<RegisteredTaskEditorExtension> getTaskEditorExtensions() {
41
		init();
42
		return new TreeSet<RegisteredTaskEditorExtension>(extensionsById.values());
43
	}
44
45
	public static void addTaskEditorExtension(String id, String name, AbstractTaskEditorExtension extension) {
46
		Assert.isNotNull(id);
47
		RegisteredTaskEditorExtension previous = extensionsById.put(id, new RegisteredTaskEditorExtension(extension,
48
				id, name));
49
		if (previous != null) {
50
			StatusHandler.log(new Status(IStatus.ERROR, TasksUiPlugin.ID_PLUGIN, "Duplicate taskEditorExtension id="
51
					+ id, null));
52
		}
53
	}
54
55
	public static void addRepositoryAssociation(String connectorKind, String extensionId) {
56
		if (connectorKind == null || extensionId == null) {
57
			throw new IllegalArgumentException();
58
		}
59
		String previous = associationByConnectorKind.put(connectorKind, extensionId);
60
		if (previous != null) {
61
			StatusHandler.log(new Status(IStatus.ERROR, TasksUiPlugin.ID_PLUGIN, String.format(
62
					"Duplicate association for repository %s: %s replaces %s", connectorKind, extensionId, previous),
63
					null));
64
		}
65
	}
66
67
	/**
68
	 * get a task editor extension for a specific repository
69
	 * 
70
	 * @param taskRepository
71
	 * @return the extension, or null if there is none
72
	 * 
73
	 * @see #getDefaultTaskEditorExtension(TaskRepository)
74
	 */
75
	public static AbstractTaskEditorExtension getTaskEditorExtension(TaskRepository taskRepository) {
76
		init();
77
		String extensionId = getTaskEditorExtensionId(taskRepository);
78
		if (extensionId != null) {
79
			RegisteredTaskEditorExtension taskEditorExtension = extensionsById.get(extensionId);
80
			return taskEditorExtension == null ? null : taskEditorExtension.getExtension();
81
		}
82
		return null;
83
	}
84
85
	public static String getTaskEditorExtensionId(TaskRepository taskRepository) {
86
		init();
87
		String id = taskRepository.getProperty(REPOSITORY_PROPERTY_EDITOR_EXTENSION);
88
		if (id == null) {
89
			// TODO 3.1 disabled until bug 244653 is resolved
90
			//id = getDefaultTaskEditorExtensionId(taskRepository);
91
		}
92
		return id;
93
	}
94
95
	public static void setTaskEditorExtensionId(TaskRepository repository, String editorExtensionId) {
96
		repository.setProperty(REPOSITORY_PROPERTY_EDITOR_EXTENSION, editorExtensionId);
97
	}
98
99
	public static String getDefaultTaskEditorExtensionId(TaskRepository taskRepository) {
100
		init();
101
		return associationByConnectorKind.get(taskRepository.getConnectorKind());
102
	}
103
104
	/**
105
	 * get a default task editor extension for a specific repository
106
	 * 
107
	 * @param taskRepository
108
	 * @return the extension, or null if there is none
109
	 * 
110
	 * @see #getTaskEditorExtension(TaskRepository)
111
	 */
112
	public static AbstractTaskEditorExtension getDefaultTaskEditorExtension(TaskRepository taskRepository) {
113
		init();
114
		String extensionId = getDefaultTaskEditorExtensionId(taskRepository);
115
		if (extensionId != null) {
116
			RegisteredTaskEditorExtension taskEditorExtension = extensionsById.get(extensionId);
117
			return taskEditorExtension == null ? null : taskEditorExtension.getExtension();
118
		}
119
		return null;
120
	}
121
122
	private static void init() {
123
		if (!initialized) {
124
			initialized = true;
125
			TaskEditorExtensionReader.initExtensions();
126
		}
127
	}
128
129
	public static class RegisteredTaskEditorExtension implements Comparable<RegisteredTaskEditorExtension> {
130
131
		private final String id;
132
133
		private final String name;
134
135
		private final AbstractTaskEditorExtension extension;
136
137
		private RegisteredTaskEditorExtension(AbstractTaskEditorExtension extension, String id, String name) {
138
			this.extension = extension;
139
			this.id = id;
140
			this.name = name;
141
		}
142
143
		public String getId() {
144
			return id;
145
		}
146
147
		public String getName() {
148
			return name;
149
		}
150
151
		public AbstractTaskEditorExtension getExtension() {
152
			return extension;
153
		}
154
155
		public int compareTo(RegisteredTaskEditorExtension o) {
156
			if (o == this) {
157
				return 0;
158
			}
159
			int i = name.compareTo(o.name);
160
			if (i == 0) {
161
				i = id.compareTo(o.id);
162
			}
163
			return i;
164
		}
165
	}
166
167
}

Return to bug 244579