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.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 34-40 Link Here
34
      </templates>
34
      </templates>
35
   </extension>
35
   </extension>
36
   <extension
36
   <extension
37
         point="org.eclipse.mylyn.sandbox.ui.taskEditorExtensions">
37
         point="org.eclipse.mylyn.tasks.ui.taskEditorExtensions">
38
      <taskEditorExtension
38
      <taskEditorExtension
39
            class="org.eclipse.mylyn.internal.wikitext.mediawiki.ui.editors.TaskEditorExtension"
39
            class="org.eclipse.mylyn.internal.wikitext.mediawiki.ui.editors.TaskEditorExtension"
40
            id="org.eclipse.mylyn.internal.wikitext.mediawiki.ui.taskEditorExtension"
40
            id="org.eclipse.mylyn.internal.wikitext.mediawiki.ui.taskEditorExtension"
(-)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"
(-)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/wikitext/ui/editor/MarkupTaskEditorExtension.java (-2 / +3 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 37-44 Link Here
37
import org.eclipse.mylyn.internal.wikitext.ui.viewer.AnnotationHyperlinkDetector;
36
import org.eclipse.mylyn.internal.wikitext.ui.viewer.AnnotationHyperlinkDetector;
38
import org.eclipse.mylyn.tasks.core.ITask;
37
import org.eclipse.mylyn.tasks.core.ITask;
39
import org.eclipse.mylyn.tasks.core.TaskRepository;
38
import org.eclipse.mylyn.tasks.core.TaskRepository;
39
import org.eclipse.mylyn.tasks.ui.ITasksUiConstants;
40
import org.eclipse.mylyn.tasks.ui.TaskHyperlink;
40
import org.eclipse.mylyn.tasks.ui.TaskHyperlink;
41
import org.eclipse.mylyn.tasks.ui.TasksUi;
41
import org.eclipse.mylyn.tasks.ui.TasksUi;
42
import org.eclipse.mylyn.tasks.ui.editors.AbstractTaskEditorExtension;
42
import org.eclipse.mylyn.wikitext.core.parser.markup.MarkupLanguage;
43
import org.eclipse.mylyn.wikitext.core.parser.markup.MarkupLanguage;
43
import org.eclipse.mylyn.wikitext.ui.viewer.MarkupViewer;
44
import org.eclipse.mylyn.wikitext.ui.viewer.MarkupViewer;
44
import org.eclipse.mylyn.wikitext.ui.viewer.MarkupViewerConfiguration;
45
import org.eclipse.mylyn.wikitext.ui.viewer.MarkupViewerConfiguration;
Lines 192-198 Link Here
192
	 * @see #configureDefaultInternalLinkPattern(TaskRepository, MarkupLanguage)
193
	 * @see #configureDefaultInternalLinkPattern(TaskRepository, MarkupLanguage)
193
	 */
194
	 */
194
	protected void configureMarkupLanguage(TaskRepository taskRepository, MarkupLanguage markupLanguage) {
195
	protected void configureMarkupLanguage(TaskRepository taskRepository, MarkupLanguage markupLanguage) {
195
		String internalLinkPattern = taskRepository.getProperty(AbstractTaskEditorExtension.INTERNAL_WIKI_LINK_PATTERN);
196
		String internalLinkPattern = taskRepository.getProperty(ITasksUiConstants.INTERNAL_WIKI_LINK_PATTERN);
196
		if (internalLinkPattern != null && internalLinkPattern.trim().length() > 0) {
197
		if (internalLinkPattern != null && internalLinkPattern.trim().length() > 0) {
197
			markupLanguage.setInternalLinkPattern(internalLinkPattern.trim());
198
			markupLanguage.setInternalLinkPattern(internalLinkPattern.trim());
198
		} else {
199
		} else {
(-)src/org/eclipse/mylyn/internal/sandbox/ui/editors/ExtensibleRichTextAttributeEditor.java (-342 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.EditorUtil;
29
import org.eclipse.mylyn.internal.tasks.ui.editors.RepositoryTextViewer;
30
import org.eclipse.mylyn.internal.tasks.ui.editors.RepositoryTextViewerConfiguration;
31
import org.eclipse.mylyn.internal.tasks.ui.editors.RichTextAttributeEditor;
32
import org.eclipse.mylyn.internal.tasks.ui.editors.TaskHyperlinkDetector;
33
import org.eclipse.mylyn.internal.tasks.ui.editors.TaskHyperlinkTextPresentationManager;
34
import org.eclipse.mylyn.internal.tasks.ui.util.TasksUiInternal;
35
import org.eclipse.mylyn.tasks.core.TaskRepository;
36
import org.eclipse.mylyn.tasks.core.data.TaskAttribute;
37
import org.eclipse.mylyn.tasks.core.data.TaskDataModel;
38
import org.eclipse.swt.SWT;
39
import org.eclipse.swt.custom.StackLayout;
40
import org.eclipse.swt.events.DisposeEvent;
41
import org.eclipse.swt.events.DisposeListener;
42
import org.eclipse.swt.events.FocusAdapter;
43
import org.eclipse.swt.events.FocusEvent;
44
import org.eclipse.swt.events.FocusListener;
45
import org.eclipse.swt.graphics.Font;
46
import org.eclipse.swt.graphics.Point;
47
import org.eclipse.swt.widgets.Composite;
48
import org.eclipse.swt.widgets.Control;
49
import org.eclipse.swt.widgets.Menu;
50
import org.eclipse.ui.PlatformUI;
51
import org.eclipse.ui.contexts.IContextActivation;
52
import org.eclipse.ui.contexts.IContextService;
53
import org.eclipse.ui.editors.text.EditorsUI;
54
import org.eclipse.ui.forms.widgets.FormToolkit;
55
import org.eclipse.ui.texteditor.AnnotationPreference;
56
import org.eclipse.ui.texteditor.DefaultMarkerAnnotationAccess;
57
import org.eclipse.ui.texteditor.MarkerAnnotationPreferences;
58
import org.eclipse.ui.texteditor.SourceViewerDecorationSupport;
59
import org.eclipse.ui.themes.IThemeManager;
60
61
/**
62
 * A text attribute that can switch between a source editor and a preview using StackLayout.
63
 * 
64
 * @author Jingwen Ou
65
 * @author Steffen Pingel
66
 */
67
public class ExtensibleRichTextAttributeEditor extends RichTextAttributeEditor {
68
69
	private IContextActivation contextActivation;
70
71
	private final IContextService contextService;
72
73
	private SourceViewer defaultViewer;
74
75
	private Composite editorComposite;
76
77
	private StackLayout editorLayout;
78
79
	private final AbstractTaskEditorExtension extension;
80
81
	private SourceViewer editorViewer;
82
83
	private SourceViewer previewViewer;
84
85
	private int styles;
86
87
	private final TaskRepository taskRepository;
88
89
	private FormToolkit toolkit;
90
91
	public class ViewSourceAction extends Action {
92
93
		public ViewSourceAction() {
94
			super("Viewer Source", SWT.TOGGLE);
95
			setChecked(false);
96
		}
97
98
		@Override
99
		public void run() {
100
			if (isChecked()) {
101
				showDefault();
102
			} else {
103
				showEditor();
104
			}
105
		}
106
107
	}
108
109
	private final IAction viewSourceAction = new ViewSourceAction();
110
111
	public ExtensibleRichTextAttributeEditor(IContextService contextService, TaskDataModel manager,
112
			TaskRepository taskRepository, AbstractTaskEditorExtension extension, TaskAttribute taskAttribute,
113
			int styles) {
114
		super(manager, taskRepository, taskAttribute, styles);
115
		this.contextService = contextService;
116
		this.taskRepository = taskRepository;
117
		this.extension = extension;
118
		this.styles = styles;
119
	}
120
121
	/** Configures annontation model for spell checking. */
122
	private void configureAsTextEditor(SourceViewer viewer, Document document) {
123
		AnnotationModel annotationModel = new AnnotationModel();
124
		viewer.showAnnotations(false);
125
		viewer.showAnnotationsOverview(false);
126
		IAnnotationAccess annotationAccess = new DefaultMarkerAnnotationAccess();
127
		final SourceViewerDecorationSupport support = new SourceViewerDecorationSupport(viewer, null, annotationAccess,
128
				EditorsUI.getSharedTextColors());
129
		Iterator<?> e = new MarkerAnnotationPreferences().getAnnotationPreferences().iterator();
130
		while (e.hasNext()) {
131
			support.setAnnotationPreference((AnnotationPreference) e.next());
132
		}
133
		support.install(EditorsUI.getPreferenceStore());
134
		viewer.getTextWidget().addDisposeListener(new DisposeListener() {
135
			public void widgetDisposed(DisposeEvent e) {
136
				support.uninstall();
137
			}
138
		});
139
		viewer.getTextWidget().setIndent(2);
140
		viewer.setDocument(document, annotationModel);
141
	}
142
143
	private SourceViewer configureEditor(final SourceViewer viewer, boolean readOnly) {
144
		Document document = new Document(getValue());
145
		if (readOnly) {
146
			viewer.setDocument(document);
147
			// setting view source action
148
			viewer.getControl().setData(ViewSourceHandler.VIEW_SOURCE_ACTION, viewSourceAction);
149
			viewer.getControl().addFocusListener(new FocusAdapter() {
150
				@Override
151
				public void focusGained(FocusEvent e) {
152
					ViewSourceHandler.setChecked(getViewer() == defaultViewer);
153
				}
154
			});
155
		} else {
156
			configureAsTextEditor(viewer, document);
157
			viewer.addTextListener(new ITextListener() {
158
				public void textChanged(TextEvent event) {
159
					// filter out events caused by text presentation changes, e.g. annotation drawing
160
					String value = viewer.getTextWidget().getText();
161
					if (!getValue().equals(value)) {
162
						setValue(value);
163
						EditorUtil.ensureVisible(viewer.getTextWidget());
164
					}
165
				}
166
			});
167
168
			viewer.getControl().setData(FormToolkit.KEY_DRAW_BORDER, FormToolkit.TEXT_BORDER);
169
170
			// drop & drag support, under review
171
			TaskEditorDropTarget.addDropTargetSupport(viewer);
172
		}
173
174
		// enable cut/copy/paste
175
		EditorUtil.setTextViewer(viewer.getTextWidget(), viewer);
176
		viewer.setEditable(!readOnly);
177
		viewer.getTextWidget().setFont(getFont());
178
		toolkit.adapt(viewer.getControl(), false, false);
179
180
		TaskHyperlinkTextPresentationManager hyperlinkTextPresentationManager = new TaskHyperlinkTextPresentationManager();
181
		hyperlinkTextPresentationManager.setHyperlinkDetector(new TaskHyperlinkDetector());
182
		hyperlinkTextPresentationManager.install(viewer);
183
184
		return viewer;
185
	}
186
187
	@Override
188
	public void createControl(Composite parent, FormToolkit toolkit) {
189
		this.toolkit = toolkit;
190
191
		editorComposite = new Composite(parent, SWT.NULL);
192
		editorLayout = new StackLayout() {
193
			@Override
194
			protected Point computeSize(Composite composite, int hint, int hint2, boolean flushCache) {
195
				return topControl.computeSize(hint, hint2, flushCache);
196
			}
197
		};
198
		editorComposite.setLayout(editorLayout);
199
		setControl(editorComposite);
200
201
		if (!isReadOnly() && (styles & TasksUiInternal.SWT_NO_SCROLL) == 0) {
202
			styles |= SWT.V_SCROLL;
203
		}
204
205
		if (isReadOnly()) {
206
			editorViewer = extension.createViewer(taskRepository, editorComposite, styles);
207
		} else {
208
			editorViewer = extension.createEditor(taskRepository, editorComposite, styles);
209
			editorViewer.getTextWidget().addFocusListener(new FocusListener() {
210
				public void focusGained(FocusEvent e) {
211
					setContext();
212
				}
213
214
				public void focusLost(FocusEvent e) {
215
					unsetContext();
216
				}
217
			});
218
			editorViewer.getTextWidget().addDisposeListener(new DisposeListener() {
219
				public void widgetDisposed(DisposeEvent e) {
220
					unsetContext();
221
				}
222
			});
223
		}
224
		configureEditor(editorViewer, isReadOnly());
225
226
		show(editorViewer);
227
	}
228
229
	private SourceViewer createDefaultEditor(Composite parent, int styles) {
230
		SourceViewer defaultEditor = new RepositoryTextViewer(taskRepository, parent, styles | SWT.WRAP);
231
232
		RepositoryTextViewerConfiguration viewerConfig = new RepositoryTextViewerConfiguration(taskRepository,
233
				isSpellCheckingEnabled());
234
		viewerConfig.setMode(getMode());
235
		defaultEditor.configure(viewerConfig);
236
237
		return defaultEditor;
238
	}
239
240
	private SourceViewer getDefaultViewer() {
241
		if (defaultViewer == null) {
242
			defaultViewer = createDefaultEditor(editorComposite, styles);
243
			configureEditor(defaultViewer, isReadOnly());
244
245
			// fixed font size
246
			defaultViewer.getTextWidget().setFont(JFaceResources.getFontRegistry().get(JFaceResources.TEXT_FONT));
247
			// adapt maximize action
248
			defaultViewer.getControl().setData(EditorUtil.KEY_TOGGLE_TO_MAXIMIZE_ACTION,
249
					editorViewer.getControl().getData(EditorUtil.KEY_TOGGLE_TO_MAXIMIZE_ACTION));
250
			// adapt menu to the new viewer
251
			installMenu(defaultViewer.getControl(), editorViewer.getControl().getMenu());
252
		}
253
		return defaultViewer;
254
	}
255
256
	private void installMenu(final Control control, Menu menu) {
257
		if (menu != null) {
258
			control.setMenu(menu);
259
			control.addDisposeListener(new DisposeListener() {
260
				public void widgetDisposed(DisposeEvent e) {
261
					control.setMenu(null);
262
				}
263
			});
264
		}
265
	}
266
267
	private Font getFont() {
268
		IThemeManager themeManager = PlatformUI.getWorkbench().getThemeManager();
269
		Font font = themeManager.getCurrentTheme().getFontRegistry().get(CommonThemes.FONT_EDITOR_COMMENT);
270
		return font;
271
	}
272
273
	private SourceViewer getPreviewViewer() {
274
		// construct as needed
275
		if (previewViewer == null) {
276
			previewViewer = extension.createViewer(taskRepository, editorComposite, styles);
277
			configureEditor(previewViewer, true);
278
			// adapt maximize action
279
			previewViewer.getControl().setData(EditorUtil.KEY_TOGGLE_TO_MAXIMIZE_ACTION,
280
					editorViewer.getControl().getData(EditorUtil.KEY_TOGGLE_TO_MAXIMIZE_ACTION));
281
		}
282
		Document document = new Document(editorViewer.getDocument().get());
283
		previewViewer.setDocument(document);
284
		return previewViewer;
285
	}
286
287
	public SourceViewer getEditorViewer() {
288
		return editorViewer;
289
	}
290
291
	@Override
292
	public SourceViewer getViewer() {
293
		if (defaultViewer != null && editorLayout.topControl == defaultViewer.getControl()) {
294
			return defaultViewer;
295
		} else if (previewViewer != null && editorLayout.topControl == previewViewer.getControl()) {
296
			return previewViewer;
297
		} else {
298
			return editorViewer;
299
		}
300
	}
301
302
	private void setContext() {
303
		if (contextActivation != null) {
304
			contextService.deactivateContext(contextActivation);
305
			contextActivation = null;
306
		}
307
		if (contextService != null && extension.getEditorContextId() != null) {
308
			contextActivation = contextService.activateContext(extension.getEditorContextId());
309
		}
310
	}
311
312
	/**
313
	 * Brings <code>viewer</code> to top.
314
	 */
315
	private void show(SourceViewer viewer) {
316
		editorLayout.topControl = viewer.getControl();
317
		editorComposite.layout();
318
		viewer.getControl().setFocus();
319
	}
320
321
	public void showDefault() {
322
		show(getDefaultViewer());
323
	}
324
325
	public void showPreview() {
326
		if (!isReadOnly()) {
327
			show(getPreviewViewer());
328
		}
329
	}
330
331
	public void showEditor() {
332
		show(getEditorViewer());
333
	}
334
335
	private void unsetContext() {
336
		if (contextActivation != null) {
337
			contextService.deactivateContext(contextActivation);
338
			contextActivation = null;
339
		}
340
	}
341
342
}
(-)src/org/eclipse/mylyn/internal/sandbox/ui/editors/ExtensibleTaskEditorNewCommentPart.java (-70 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
 *******************************************************************************/
11
12
package org.eclipse.mylyn.internal.sandbox.ui.editors;
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;
19
import org.eclipse.swt.SWT;
20
import org.eclipse.swt.widgets.Composite;
21
import org.eclipse.swt.widgets.Control;
22
import org.eclipse.ui.forms.widgets.FormToolkit;
23
24
/**
25
 * @author Jingwen Ou
26
 */
27
public class ExtensibleTaskEditorNewCommentPart extends TaskEditorNewCommentPart {
28
29
	@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) {
59
		super.createControl(parent, toolkit);
60
		if (getControl() != null) {
61
			getEditor().getControl().setData(EditorUtil.KEY_TOGGLE_TO_MAXIMIZE_ACTION, getMaximizePartAction());
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
		}
68
	}
69
70
}
(-)src/org/eclipse/mylyn/internal/sandbox/ui/editors/EditorStyleContributionItem.java (-3 / +5 lines)
Lines 22-29 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;
28
import org.eclipse.mylyn.tasks.ui.ITasksUiConstants;
27
import org.eclipse.mylyn.tasks.ui.TasksUiUtil;
29
import org.eclipse.mylyn.tasks.ui.TasksUiUtil;
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;
Lines 119-125 Link Here
119
			String message = "Set the internal link pattern for choosen markup language,\ne.g. http://wiki.eclipse.org/{0}";
121
			String message = "Set the internal link pattern for choosen markup language,\ne.g. http://wiki.eclipse.org/{0}";
120
122
121
			TaskRepository taskRepository = TasksUiUtil.getSelectedRepository();
123
			TaskRepository taskRepository = TasksUiUtil.getSelectedRepository();
122
			String initialValue = taskRepository.getProperty(AbstractTaskEditorExtension.INTERNAL_WIKI_LINK_PATTERN);
124
			String initialValue = taskRepository.getProperty(ITasksUiConstants.INTERNAL_WIKI_LINK_PATTERN);
123
			if (initialValue == null) {
125
			if (initialValue == null) {
124
				initialValue = "";
126
				initialValue = "";
125
			}
127
			}
Lines 139-144 Link Here
139
141
140
	private static void setInternalLink(String internalLink) {
142
	private static void setInternalLink(String internalLink) {
141
		TaskRepository taskRepository = TasksUiUtil.getSelectedRepository();
143
		TaskRepository taskRepository = TasksUiUtil.getSelectedRepository();
142
		taskRepository.setProperty(AbstractTaskEditorExtension.INTERNAL_WIKI_LINK_PATTERN, internalLink);
144
		taskRepository.setProperty(ITasksUiConstants.INTERNAL_WIKI_LINK_PATTERN, internalLink);
143
	}
145
	}
144
}
146
}
(-)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 (+4 lines)
Lines 26-33 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.internal.tasks.ui.editors.ExtensibleRichTextAttributeEditor;
30
import org.eclipse.mylyn.internal.tasks.ui.editors.ExtensibleTaskEditorNewCommentPart;
31
import org.eclipse.mylyn.internal.tasks.ui.editors.TaskEditorExtensions;
29
import org.eclipse.mylyn.tasks.core.data.TaskAttribute;
32
import org.eclipse.mylyn.tasks.core.data.TaskAttribute;
30
import org.eclipse.mylyn.tasks.ui.editors.AbstractAttributeEditor;
33
import org.eclipse.mylyn.tasks.ui.editors.AbstractAttributeEditor;
34
import org.eclipse.mylyn.tasks.ui.editors.AbstractTaskEditorExtension;
31
import org.eclipse.mylyn.tasks.ui.editors.AbstractTaskEditorPage;
35
import org.eclipse.mylyn.tasks.ui.editors.AbstractTaskEditorPage;
32
import org.eclipse.mylyn.tasks.ui.editors.AbstractTaskEditorPart;
36
import org.eclipse.mylyn.tasks.ui.editors.AbstractTaskEditorPart;
33
import org.eclipse.mylyn.tasks.ui.editors.AttributeEditorFactory;
37
import org.eclipse.mylyn.tasks.ui.editors.AttributeEditorFactory;
(-)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 (-24 / +1 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 417-445 Link Here
417
             generatedPrefix="file">
416
             generatedPrefix="file">
418
       </resourceHyperlinkExtension>
417
       </resourceHyperlinkExtension>
419
    </extension>
418
    </extension>
420
        <extension point="org.eclipse.ui.menus">
419
        
421
		<menuContribution
422
			locationURI="popup:org.eclipse.mylyn.tasks.ui.editors.task?after=additions">
423
   <command
424
         commandId="org.eclipse.mylyn.sandbox.ui.viewSource.command"
425
         id="org.eclipse.mylyn.sandbox.ui.viewSource"
426
         label="View Source"
427
         style="toggle">
428
      <visibleWhen
429
            checkEnabled="true">
430
      </visibleWhen>
431
   </command>
432
		</menuContribution>
433
	</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
   <!--
420
   <!--
444
   <extension point="org.eclipse.mylyn.tasks.ui.presentations">
421
   <extension point="org.eclipse.mylyn.tasks.ui.presentations">
445
      <presentation 
422
      <presentation 
(-)src/org/eclipse/mylyn/tasks/ui/ITasksUiConstants.java (+10 lines)
Lines 11-16 Link Here
11
11
12
package org.eclipse.mylyn.tasks.ui;
12
package org.eclipse.mylyn.tasks.ui;
13
13
14
import org.eclipse.mylyn.tasks.core.TaskRepository;
15
14
/**
16
/**
15
 * @author Mik Kersten
17
 * @author Mik Kersten
16
 * @since 3.0
18
 * @since 3.0
Lines 28-31 Link Here
28
30
29
	public static final String ID_PREFERENCES_COLORS_AND_FONTS = "org.eclipse.ui.preferencePages.ColorsAndFonts";
31
	public static final String ID_PREFERENCES_COLORS_AND_FONTS = "org.eclipse.ui.preferencePages.ColorsAndFonts";
30
32
33
	/**
34
	 * The key to access the {@link TaskRepository} property that stores the URL of an associated wiki. The URL
35
	 * typically uses {@link java.text.MessageFormat} with argument 0 being the page name of the desired wiki page.
36
	 * 
37
	 * @since 3.1
38
	 */
39
	public static final String INTERNAL_WIKI_LINK_PATTERN = "wikiLinkPattern";
40
31
}
41
}
(-)plugin.xml (-1 / +18 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 858-863 Link Here
858
      <command id="org.eclipse.mylyn.tasks.ui.command.previousTask"
859
      <command id="org.eclipse.mylyn.tasks.ui.command.previousTask"
859
               defaultHandler="org.eclipse.mylyn.internal.tasks.ui.TaskHistoryHandler"
860
               defaultHandler="org.eclipse.mylyn.internal.tasks.ui.TaskHistoryHandler"
860
               name="Previous Task Command"/>
861
               name="Previous Task Command"/>
862
           
863
       <command
864
             categoryId="org.eclipse.mylyn.tasks.ui.commands"
865
             defaultHandler="org.eclipse.mylyn.internal.tasks.ui.commands.ViewSourceHandler"
866
             id="org.eclipse.mylyn.tasks.ui.viewSource.command"
867
             name="View Source"/>
861
   </extension>
868
   </extension>
862
869
863
  <!-- command-based implementation of the previousTask/history dropdown, 
870
  <!-- command-based implementation of the previousTask/history dropdown, 
Lines 889-895 Link Here
889
    </menuContribution>
896
    </menuContribution>
890
  </extension>
897
  </extension>
891
  -->
898
  -->
892
899
	<extension point="org.eclipse.ui.menus">
900
		<menuContribution
901
			locationURI="popup:org.eclipse.mylyn.tasks.ui.editors.task?after=additions">
902
			<command commandId="org.eclipse.mylyn.tasks.ui.viewSource.command"
903
				id="org.eclipse.mylyn.sandbox.ui.viewSource" label="View Source"
904
				style="toggle">
905
				<visibleWhen checkEnabled="true"/>
906
			</command>
907
		</menuContribution>
908
	</extension>
909
	
893
   <extension point="org.eclipse.ui.actionSets">
910
   <extension point="org.eclipse.ui.actionSets">
894
      <actionSet
911
      <actionSet
895
            id="org.eclipse.mylyn.tasks.ui.navigation.additions"
912
            id="org.eclipse.mylyn.tasks.ui.navigation.additions"
(-)src/org/eclipse/mylyn/internal/tasks/ui/editors/TaskEditorExtensionReader.java (+88 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
 * A utility for initializing {@link TaskEditorExtensions}.
28
 * 
29
 * @author David Green
30
 */
31
class TaskEditorExtensionReader {
32
33
	private static final String CONNECTOR_KIND = "connectorKind";
34
35
	public static final String ATTR_ID = "id";
36
37
	public static final String ATTR_NAME = "name";
38
39
	public static final String EXTENSION_TASK_EDITOR_EXTENSIONS = TasksUiPlugin.ID_PLUGIN + ".taskEditorExtensions";
40
41
	private static final String REPOSITORY_ASSOCIATION = "repositoryAssociation";
42
43
	private static final String TASK_EDITOR_EXTENSION = "taskEditorExtension";
44
45
	public static void initExtensions() {
46
		IExtensionRegistry registry = Platform.getExtensionRegistry();
47
48
		IExtensionPoint editorExtensionPoint = registry.getExtensionPoint(EXTENSION_TASK_EDITOR_EXTENSIONS);
49
		IExtension[] editorExtensions = editorExtensionPoint.getExtensions();
50
		for (IExtension extension : editorExtensions) {
51
			IConfigurationElement[] elements = extension.getConfigurationElements();
52
			for (IConfigurationElement element : elements) {
53
				if (element.getName().equals(TASK_EDITOR_EXTENSION)) {
54
					readEditorExtension(element);
55
				} else if (element.getName().equals(REPOSITORY_ASSOCIATION)) {
56
					readEditorExtensionAssociation(element);
57
				}
58
			}
59
		}
60
	}
61
62
	private static void readEditorExtension(IConfigurationElement element) {
63
		try {
64
			String id = element.getAttribute(ATTR_ID);
65
			String name = element.getAttribute(ATTR_NAME);
66
			AbstractTaskEditorExtension extension = (AbstractTaskEditorExtension) element.createExecutableExtension("class");
67
			TaskEditorExtensions.addTaskEditorExtension(id, name, extension);
68
		} catch (CoreException e) {
69
			StatusHandler.log(new Status(IStatus.ERROR, TasksUiPlugin.ID_PLUGIN, "Could not load taskEditorExtension",
70
					e));
71
		} catch (Exception e) {
72
			StatusHandler.log(new Status(IStatus.ERROR, TasksUiPlugin.ID_PLUGIN, "Could not load taskEditorExtension",
73
					e));
74
		}
75
	}
76
77
	private static void readEditorExtensionAssociation(IConfigurationElement element) {
78
		try {
79
			String repository = element.getAttribute(CONNECTOR_KIND);
80
			String taskEditorExtension = element.getAttribute(TASK_EDITOR_EXTENSION);
81
			TaskEditorExtensions.addRepositoryAssociation(repository, taskEditorExtension);
82
		} catch (Exception e) {
83
			StatusHandler.log(new Status(IStatus.ERROR, TasksUiPlugin.ID_PLUGIN,
84
					"Could not load repositoryAssociation", e));
85
		}
86
	}
87
88
}
(-)src/org/eclipse/mylyn/internal/tasks/ui/editors/ExtensibleTaskEditorNewCommentPart.java (+68 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
 *******************************************************************************/
11
12
package org.eclipse.mylyn.internal.tasks.ui.editors;
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.swt.SWT;
18
import org.eclipse.swt.widgets.Composite;
19
import org.eclipse.swt.widgets.Control;
20
import org.eclipse.ui.forms.widgets.FormToolkit;
21
22
/**
23
 * @author Jingwen Ou
24
 */
25
public class ExtensibleTaskEditorNewCommentPart extends TaskEditorNewCommentPart {
26
27
	@Override
28
	protected void fillToolBar(ToolBarManager barManager) {
29
		Action toggleEditingAction = new Action("", SWT.TOGGLE) {
30
			@Override
31
			public void run() {
32
				toggleEditing(this);
33
			}
34
		};
35
		toggleEditingAction.setImageDescriptor(CommonImages.PREVIEW_WEB);
36
		toggleEditingAction.setToolTipText("Preview");
37
		toggleEditingAction.setChecked(false);
38
39
		barManager.add(toggleEditingAction);
40
		barManager.add(getMaximizePartAction());
41
		super.fillToolBar(barManager);
42
	}
43
44
	private void toggleEditing(Action action) {
45
		if (getEditor() instanceof ExtensibleRichTextAttributeEditor) {
46
			ExtensibleRichTextAttributeEditor editor = (ExtensibleRichTextAttributeEditor) getEditor();
47
			if (action.isChecked()) {
48
				editor.showPreview();
49
			} else {
50
				editor.showEditor();
51
			}
52
		}
53
	}
54
55
	@Override
56
	public void createControl(Composite parent, FormToolkit toolkit) {
57
		super.createControl(parent, toolkit);
58
		if (getControl() != null) {
59
			getEditor().getControl().setData(EditorUtil.KEY_TOGGLE_TO_MAXIMIZE_ACTION, getMaximizePartAction());
60
			if (getEditor().getControl() instanceof Composite) {
61
				for (Control control : ((Composite) getEditor().getControl()).getChildren()) {
62
					control.setData(EditorUtil.KEY_TOGGLE_TO_MAXIMIZE_ACTION, getMaximizePartAction());
63
				}
64
			}
65
		}
66
	}
67
68
}
(-)schema/taskEditorExtensions.exsd (+160 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 have capabilities beyond basic plain-text.
10
For example, WikiText uses this extension to provide editors that are markup-aware.
11
      </documentation>
12
   </annotation>
13
14
   <element name="extension">
15
      <annotation>
16
         <appinfo>
17
            <meta.element internal="true" />
18
         </appinfo>
19
      </annotation>
20
      <complexType>
21
         <sequence>
22
            <element ref="taskEditorExtension" minOccurs="0" maxOccurs="unbounded"/>
23
            <element ref="repositoryAssociation" minOccurs="0" maxOccurs="unbounded"/>
24
         </sequence>
25
         <attribute name="point" type="string" use="required">
26
            <annotation>
27
               <documentation>
28
                  
29
               </documentation>
30
            </annotation>
31
         </attribute>
32
         <attribute name="id" type="string">
33
            <annotation>
34
               <documentation>
35
                  
36
               </documentation>
37
            </annotation>
38
         </attribute>
39
         <attribute name="name" type="string">
40
            <annotation>
41
               <documentation>
42
                  
43
               </documentation>
44
               <appinfo>
45
                  <meta.attribute translatable="true"/>
46
               </appinfo>
47
            </annotation>
48
         </attribute>
49
      </complexType>
50
   </element>
51
52
   <element name="taskEditorExtension">
53
      <annotation>
54
         <documentation>
55
            Declare an extension to the Mylyn task editor.  Extensions are typically capable of providing improved editing capabilities, such as markup-aware.
56
         </documentation>
57
      </annotation>
58
      <complexType>
59
         <attribute name="class" type="string" use="required">
60
            <annotation>
61
               <documentation>
62
                  the fully qualified class name of the class that extends org.eclipse.mylyn.tasks.ui.editors.AbstractTaskEditorExtension
63
               </documentation>
64
               <appinfo>
65
                  <meta.attribute kind="java" basedOn="org.eclipse.mylyn.tasks.ui.editors.AbstractTaskEditorExtension:"/>
66
               </appinfo>
67
            </annotation>
68
         </attribute>
69
         <attribute name="id" type="string" use="required">
70
            <annotation>
71
               <documentation>
72
                  a unique identifier identifying the extension
73
               </documentation>
74
               <appinfo>
75
                  <meta.attribute kind="identifier"/>
76
               </appinfo>
77
            </annotation>
78
         </attribute>
79
         <attribute name="name" type="string" use="required">
80
            <annotation>
81
               <documentation>
82
                  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;.
83
               </documentation>
84
               <appinfo>
85
                  <meta.attribute translatable="true"/>
86
               </appinfo>
87
            </annotation>
88
         </attribute>
89
      </complexType>
90
   </element>
91
92
   <element name="repositoryAssociation">
93
      <annotation>
94
         <documentation>
95
            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.
96
         </documentation>
97
      </annotation>
98
      <complexType>
99
         <attribute name="connectorKind" type="string" use="required">
100
            <annotation>
101
               <documentation>
102
                  the kind of connector for that this task editor extension should be associated with.
103
               </documentation>
104
            </annotation>
105
         </attribute>
106
         <attribute name="taskEditorExtension" type="string" use="required">
107
            <annotation>
108
               <documentation>
109
                  the id of the taskEditorExtension to associate
110
               </documentation>
111
            </annotation>
112
         </attribute>
113
      </complexType>
114
   </element>
115
116
   <annotation>
117
      <appinfo>
118
         <meta.section type="since"/>
119
      </appinfo>
120
      <documentation>
121
         3.1
122
      </documentation>
123
   </annotation>
124
125
   <annotation>
126
      <appinfo>
127
         <meta.section type="examples"/>
128
      </appinfo>
129
      <documentation>
130
            &lt;extension
131
         point=&quot;org.eclipse.mylyn.tasks.ui.taskEditorExtensions&quot;&gt;
132
      &lt;taskEditorExtension
133
            class=&quot;org.eclipse.mylyn.internal.wikitext.textile.ui.editors.TextileTaskEditorExtension&quot;
134
            id=&quot;org.eclipse.mylyn.wikitext.textile.core.ui.taskEditorExtension&quot;
135
            name=&quot;Textile&quot;&gt;
136
      &lt;/taskEditorExtension&gt;
137
   &lt;/extension&gt;
138
      </documentation>
139
   </annotation>
140
141
   <annotation>
142
      <appinfo>
143
         <meta.section type="apiinfo"/>
144
      </appinfo>
145
      <documentation>
146
         [Enter API information here.]
147
      </documentation>
148
   </annotation>
149
150
   <annotation>
151
      <appinfo>
152
         <meta.section type="implementation"/>
153
      </appinfo>
154
      <documentation>
155
         [Enter information about supplied implementation of this extension point.]
156
      </documentation>
157
   </annotation>
158
159
160
</schema>
(-)src/org/eclipse/mylyn/tasks/ui/editors/AbstractTaskEditorExtension.java (+60 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
 * 
25
 * @since 3.1
26
 */
27
public abstract class AbstractTaskEditorExtension {
28
29
	/**
30
	 * Creates a source viewer that can be used to view content in the task editor. The source viewer should be
31
	 * configured with a source viewer configuration prior to returning.
32
	 * 
33
	 * @param taskRepository
34
	 *            the task repository for which the viewer is created
35
	 * @param parent
36
	 *            the control parent of the source viewer
37
	 * @param style
38
	 *            the styles to use
39
	 */
40
	public abstract SourceViewer createViewer(TaskRepository taskRepository, Composite parent, int style);
41
42
	/**
43
	 * Creates a source viewer that can be used to edit content in the task editor. The source viewer should be
44
	 * configured with a source viewer configuration prior to returning.
45
	 * 
46
	 * @param taskRepository
47
	 *            the task repository for which the viewer is created
48
	 * @param parent
49
	 *            the control parent of the source viewer
50
	 * @param style
51
	 *            the styles to use
52
	 */
53
	public abstract SourceViewer createEditor(TaskRepository taskRepository, Composite parent, int style);
54
55
	/**
56
	 * Returns the editor context id, to be passed to the {@link IContextService} when the editor is in focus.
57
	 */
58
	public abstract String getEditorContextId();
59
60
}
(-)src/org/eclipse/mylyn/internal/tasks/ui/editors/ExtensibleRichTextAttributeEditor.java (+337 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.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.tasks.ui.commands.ViewSourceHandler;
28
import org.eclipse.mylyn.internal.tasks.ui.util.TasksUiInternal;
29
import org.eclipse.mylyn.tasks.core.TaskRepository;
30
import org.eclipse.mylyn.tasks.core.data.TaskAttribute;
31
import org.eclipse.mylyn.tasks.core.data.TaskDataModel;
32
import org.eclipse.mylyn.tasks.ui.editors.AbstractTaskEditorExtension;
33
import org.eclipse.swt.SWT;
34
import org.eclipse.swt.custom.StackLayout;
35
import org.eclipse.swt.events.DisposeEvent;
36
import org.eclipse.swt.events.DisposeListener;
37
import org.eclipse.swt.events.FocusAdapter;
38
import org.eclipse.swt.events.FocusEvent;
39
import org.eclipse.swt.events.FocusListener;
40
import org.eclipse.swt.graphics.Font;
41
import org.eclipse.swt.graphics.Point;
42
import org.eclipse.swt.widgets.Composite;
43
import org.eclipse.swt.widgets.Control;
44
import org.eclipse.swt.widgets.Menu;
45
import org.eclipse.ui.PlatformUI;
46
import org.eclipse.ui.contexts.IContextActivation;
47
import org.eclipse.ui.contexts.IContextService;
48
import org.eclipse.ui.editors.text.EditorsUI;
49
import org.eclipse.ui.forms.widgets.FormToolkit;
50
import org.eclipse.ui.texteditor.AnnotationPreference;
51
import org.eclipse.ui.texteditor.DefaultMarkerAnnotationAccess;
52
import org.eclipse.ui.texteditor.MarkerAnnotationPreferences;
53
import org.eclipse.ui.texteditor.SourceViewerDecorationSupport;
54
import org.eclipse.ui.themes.IThemeManager;
55
56
/**
57
 * A text attribute that can switch between a source editor and a preview using StackLayout.
58
 * 
59
 * @author Jingwen Ou
60
 * @author Steffen Pingel
61
 */
62
public class ExtensibleRichTextAttributeEditor extends RichTextAttributeEditor {
63
64
	private IContextActivation contextActivation;
65
66
	private final IContextService contextService;
67
68
	private SourceViewer defaultViewer;
69
70
	private Composite editorComposite;
71
72
	private StackLayout editorLayout;
73
74
	private final AbstractTaskEditorExtension extension;
75
76
	private SourceViewer editorViewer;
77
78
	private SourceViewer previewViewer;
79
80
	private int styles;
81
82
	private final TaskRepository taskRepository;
83
84
	private FormToolkit toolkit;
85
86
	public class ViewSourceAction extends Action {
87
88
		public ViewSourceAction() {
89
			super("Viewer Source", SWT.TOGGLE);
90
			setChecked(false);
91
		}
92
93
		@Override
94
		public void run() {
95
			if (isChecked()) {
96
				showDefault();
97
			} else {
98
				showEditor();
99
			}
100
		}
101
102
	}
103
104
	private final IAction viewSourceAction = new ViewSourceAction();
105
106
	public ExtensibleRichTextAttributeEditor(IContextService contextService, TaskDataModel manager,
107
			TaskRepository taskRepository, AbstractTaskEditorExtension extension, TaskAttribute taskAttribute,
108
			int styles) {
109
		super(manager, taskRepository, taskAttribute, styles);
110
		this.contextService = contextService;
111
		this.taskRepository = taskRepository;
112
		this.extension = extension;
113
		this.styles = styles;
114
	}
115
116
	/** Configures annontation model for spell checking. */
117
	private void configureAsTextEditor(SourceViewer viewer, Document document) {
118
		AnnotationModel annotationModel = new AnnotationModel();
119
		viewer.showAnnotations(false);
120
		viewer.showAnnotationsOverview(false);
121
		IAnnotationAccess annotationAccess = new DefaultMarkerAnnotationAccess();
122
		final SourceViewerDecorationSupport support = new SourceViewerDecorationSupport(viewer, null, annotationAccess,
123
				EditorsUI.getSharedTextColors());
124
		Iterator<?> e = new MarkerAnnotationPreferences().getAnnotationPreferences().iterator();
125
		while (e.hasNext()) {
126
			support.setAnnotationPreference((AnnotationPreference) e.next());
127
		}
128
		support.install(EditorsUI.getPreferenceStore());
129
		viewer.getTextWidget().addDisposeListener(new DisposeListener() {
130
			public void widgetDisposed(DisposeEvent e) {
131
				support.uninstall();
132
			}
133
		});
134
		viewer.getTextWidget().setIndent(2);
135
		viewer.setDocument(document, annotationModel);
136
	}
137
138
	private SourceViewer configureEditor(final SourceViewer viewer, boolean readOnly) {
139
		Document document = new Document(getValue());
140
		if (readOnly) {
141
			viewer.setDocument(document);
142
			// setting view source action
143
			viewer.getControl().setData(ViewSourceHandler.VIEW_SOURCE_ACTION, viewSourceAction);
144
			viewer.getControl().addFocusListener(new FocusAdapter() {
145
				@Override
146
				public void focusGained(FocusEvent e) {
147
					ViewSourceHandler.setChecked(getViewer() == defaultViewer);
148
				}
149
			});
150
		} else {
151
			configureAsTextEditor(viewer, document);
152
			viewer.addTextListener(new ITextListener() {
153
				public void textChanged(TextEvent event) {
154
					// filter out events caused by text presentation changes, e.g. annotation drawing
155
					String value = viewer.getTextWidget().getText();
156
					if (!getValue().equals(value)) {
157
						setValue(value);
158
						EditorUtil.ensureVisible(viewer.getTextWidget());
159
					}
160
				}
161
			});
162
163
			viewer.getControl().setData(FormToolkit.KEY_DRAW_BORDER, FormToolkit.TEXT_BORDER);
164
165
			// drop & drag support, under review
166
			// TODO: reenable D&D support org.eclipse.mylyn.internal.sandbox.ui.editors.TaskEditorDropTarget.addDropTargetSupport(viewer);
167
		}
168
169
		// enable cut/copy/paste
170
		EditorUtil.setTextViewer(viewer.getTextWidget(), viewer);
171
		viewer.setEditable(!readOnly);
172
		viewer.getTextWidget().setFont(getFont());
173
		toolkit.adapt(viewer.getControl(), false, false);
174
175
		TaskHyperlinkTextPresentationManager hyperlinkTextPresentationManager = new TaskHyperlinkTextPresentationManager();
176
		hyperlinkTextPresentationManager.setHyperlinkDetector(new TaskHyperlinkDetector());
177
		hyperlinkTextPresentationManager.install(viewer);
178
179
		return viewer;
180
	}
181
182
	@Override
183
	public void createControl(Composite parent, FormToolkit toolkit) {
184
		this.toolkit = toolkit;
185
186
		editorComposite = new Composite(parent, SWT.NULL);
187
		editorLayout = new StackLayout() {
188
			@Override
189
			protected Point computeSize(Composite composite, int hint, int hint2, boolean flushCache) {
190
				return topControl.computeSize(hint, hint2, flushCache);
191
			}
192
		};
193
		editorComposite.setLayout(editorLayout);
194
		setControl(editorComposite);
195
196
		if (!isReadOnly() && (styles & TasksUiInternal.SWT_NO_SCROLL) == 0) {
197
			styles |= SWT.V_SCROLL;
198
		}
199
200
		if (isReadOnly()) {
201
			editorViewer = extension.createViewer(taskRepository, editorComposite, styles);
202
		} else {
203
			editorViewer = extension.createEditor(taskRepository, editorComposite, styles);
204
			editorViewer.getTextWidget().addFocusListener(new FocusListener() {
205
				public void focusGained(FocusEvent e) {
206
					setContext();
207
				}
208
209
				public void focusLost(FocusEvent e) {
210
					unsetContext();
211
				}
212
			});
213
			editorViewer.getTextWidget().addDisposeListener(new DisposeListener() {
214
				public void widgetDisposed(DisposeEvent e) {
215
					unsetContext();
216
				}
217
			});
218
		}
219
		configureEditor(editorViewer, isReadOnly());
220
221
		show(editorViewer);
222
	}
223
224
	private SourceViewer createDefaultEditor(Composite parent, int styles) {
225
		SourceViewer defaultEditor = new RepositoryTextViewer(taskRepository, parent, styles | SWT.WRAP);
226
227
		RepositoryTextViewerConfiguration viewerConfig = new RepositoryTextViewerConfiguration(taskRepository,
228
				isSpellCheckingEnabled());
229
		viewerConfig.setMode(getMode());
230
		defaultEditor.configure(viewerConfig);
231
232
		return defaultEditor;
233
	}
234
235
	private SourceViewer getDefaultViewer() {
236
		if (defaultViewer == null) {
237
			defaultViewer = createDefaultEditor(editorComposite, styles);
238
			configureEditor(defaultViewer, isReadOnly());
239
240
			// fixed font size
241
			defaultViewer.getTextWidget().setFont(JFaceResources.getFontRegistry().get(JFaceResources.TEXT_FONT));
242
			// adapt maximize action
243
			defaultViewer.getControl().setData(EditorUtil.KEY_TOGGLE_TO_MAXIMIZE_ACTION,
244
					editorViewer.getControl().getData(EditorUtil.KEY_TOGGLE_TO_MAXIMIZE_ACTION));
245
			// adapt menu to the new viewer
246
			installMenu(defaultViewer.getControl(), editorViewer.getControl().getMenu());
247
		}
248
		return defaultViewer;
249
	}
250
251
	private void installMenu(final Control control, Menu menu) {
252
		if (menu != null) {
253
			control.setMenu(menu);
254
			control.addDisposeListener(new DisposeListener() {
255
				public void widgetDisposed(DisposeEvent e) {
256
					control.setMenu(null);
257
				}
258
			});
259
		}
260
	}
261
262
	private Font getFont() {
263
		IThemeManager themeManager = PlatformUI.getWorkbench().getThemeManager();
264
		Font font = themeManager.getCurrentTheme().getFontRegistry().get(CommonThemes.FONT_EDITOR_COMMENT);
265
		return font;
266
	}
267
268
	private SourceViewer getPreviewViewer() {
269
		// construct as needed
270
		if (previewViewer == null) {
271
			previewViewer = extension.createViewer(taskRepository, editorComposite, styles);
272
			configureEditor(previewViewer, true);
273
			// adapt maximize action
274
			previewViewer.getControl().setData(EditorUtil.KEY_TOGGLE_TO_MAXIMIZE_ACTION,
275
					editorViewer.getControl().getData(EditorUtil.KEY_TOGGLE_TO_MAXIMIZE_ACTION));
276
		}
277
		Document document = new Document(editorViewer.getDocument().get());
278
		previewViewer.setDocument(document);
279
		return previewViewer;
280
	}
281
282
	public SourceViewer getEditorViewer() {
283
		return editorViewer;
284
	}
285
286
	@Override
287
	public SourceViewer getViewer() {
288
		if (defaultViewer != null && editorLayout.topControl == defaultViewer.getControl()) {
289
			return defaultViewer;
290
		} else if (previewViewer != null && editorLayout.topControl == previewViewer.getControl()) {
291
			return previewViewer;
292
		} else {
293
			return editorViewer;
294
		}
295
	}
296
297
	private void setContext() {
298
		if (contextActivation != null) {
299
			contextService.deactivateContext(contextActivation);
300
			contextActivation = null;
301
		}
302
		if (contextService != null && extension.getEditorContextId() != null) {
303
			contextActivation = contextService.activateContext(extension.getEditorContextId());
304
		}
305
	}
306
307
	/**
308
	 * Brings <code>viewer</code> to top.
309
	 */
310
	private void show(SourceViewer viewer) {
311
		editorLayout.topControl = viewer.getControl();
312
		editorComposite.layout();
313
		viewer.getControl().setFocus();
314
	}
315
316
	public void showDefault() {
317
		show(getDefaultViewer());
318
	}
319
320
	public void showPreview() {
321
		if (!isReadOnly()) {
322
			show(getPreviewViewer());
323
		}
324
	}
325
326
	public void showEditor() {
327
		show(getEditorViewer());
328
	}
329
330
	private void unsetContext() {
331
		if (contextActivation != null) {
332
			contextService.deactivateContext(contextActivation);
333
			contextActivation = null;
334
		}
335
	}
336
337
}
(-)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 (+166 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
			id = getDefaultTaskEditorExtensionId(taskRepository);
90
		}
91
		return id;
92
	}
93
94
	public static void setTaskEditorExtensionId(TaskRepository repository, String editorExtensionId) {
95
		repository.setProperty(REPOSITORY_PROPERTY_EDITOR_EXTENSION, editorExtensionId);
96
	}
97
98
	public static String getDefaultTaskEditorExtensionId(TaskRepository taskRepository) {
99
		init();
100
		return associationByConnectorKind.get(taskRepository.getConnectorKind());
101
	}
102
103
	/**
104
	 * get a default task editor extension for a specific repository
105
	 * 
106
	 * @param taskRepository
107
	 * @return the extension, or null if there is none
108
	 * 
109
	 * @see #getTaskEditorExtension(TaskRepository)
110
	 */
111
	public static AbstractTaskEditorExtension getDefaultTaskEditorExtension(TaskRepository taskRepository) {
112
		init();
113
		String extensionId = getDefaultTaskEditorExtensionId(taskRepository);
114
		if (extensionId != null) {
115
			RegisteredTaskEditorExtension taskEditorExtension = extensionsById.get(extensionId);
116
			return taskEditorExtension == null ? null : taskEditorExtension.getExtension();
117
		}
118
		return null;
119
	}
120
121
	private static void init() {
122
		if (!initialized) {
123
			initialized = true;
124
			TaskEditorExtensionReader.initExtensions();
125
		}
126
	}
127
128
	public static class RegisteredTaskEditorExtension implements Comparable<RegisteredTaskEditorExtension> {
129
130
		private final String id;
131
132
		private final String name;
133
134
		private final AbstractTaskEditorExtension extension;
135
136
		private RegisteredTaskEditorExtension(AbstractTaskEditorExtension extension, String id, String name) {
137
			this.extension = extension;
138
			this.id = id;
139
			this.name = name;
140
		}
141
142
		public String getId() {
143
			return id;
144
		}
145
146
		public String getName() {
147
			return name;
148
		}
149
150
		public AbstractTaskEditorExtension getExtension() {
151
			return extension;
152
		}
153
154
		public int compareTo(RegisteredTaskEditorExtension o) {
155
			if (o == this) {
156
				return 0;
157
			}
158
			int i = name.compareTo(o.name);
159
			if (i == 0) {
160
				i = id.compareTo(o.id);
161
			}
162
			return i;
163
		}
164
	}
165
166
}
(-)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"

Return to bug 244579