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

Collapse All | Expand All

(-)src/org/eclipse/mylyn/tasks/ui/editors/AbstractTaskEditorPage.java (-3 / +13 lines)
Lines 50-55 Link Here
50
import org.eclipse.jface.window.Window;
50
import org.eclipse.jface.window.Window;
51
import org.eclipse.mylyn.commons.core.StatusHandler;
51
import org.eclipse.mylyn.commons.core.StatusHandler;
52
import org.eclipse.mylyn.context.core.ContextCore;
52
import org.eclipse.mylyn.context.core.ContextCore;
53
import org.eclipse.mylyn.internal.commons.ui.CommonTextSupport;
53
import org.eclipse.mylyn.internal.context.core.ContextCorePlugin;
54
import org.eclipse.mylyn.internal.context.core.ContextCorePlugin;
54
import org.eclipse.mylyn.internal.provisional.commons.ui.CommonImages;
55
import org.eclipse.mylyn.internal.provisional.commons.ui.CommonImages;
55
import org.eclipse.mylyn.internal.tasks.core.AbstractTask;
56
import org.eclipse.mylyn.internal.tasks.core.AbstractTask;
Lines 449-454 Link Here
449
450
450
	private TaskAttachmentDropListener defaultDropListener;
451
	private TaskAttachmentDropListener defaultDropListener;
451
452
453
	private CommonTextSupport textSupport;
454
452
	// TODO 3.1 define constructor for setting id and label
455
	// TODO 3.1 define constructor for setting id and label
453
	public AbstractTaskEditorPage(TaskEditor editor, String connectorKind) {
456
	public AbstractTaskEditorPage(TaskEditor editor, String connectorKind) {
454
		super(editor, "id", "label"); //$NON-NLS-1$ //$NON-NLS-2$
457
		super(editor, "id", "label"); //$NON-NLS-1$ //$NON-NLS-2$
Lines 520-527 Link Here
520
	}
523
	}
521
524
522
	AttributeEditorToolkit createAttributeEditorToolkit() {
525
	AttributeEditorToolkit createAttributeEditorToolkit() {
523
		IHandlerService handlerService = (IHandlerService) getSite().getService(IHandlerService.class);
526
		return new AttributeEditorToolkit(textSupport);
524
		return new AttributeEditorToolkit(handlerService);
525
	}
527
	}
526
528
527
	@Override
529
	@Override
Lines 620-626 Link Here
620
		attributeEditorToolkit = createAttributeEditorToolkit();
622
		attributeEditorToolkit = createAttributeEditorToolkit();
621
		Assert.isNotNull(attributeEditorToolkit);
623
		Assert.isNotNull(attributeEditorToolkit);
622
		attributeEditorToolkit.setMenu(editorComposite.getMenu());
624
		attributeEditorToolkit.setMenu(editorComposite.getMenu());
623
		attributeEditorToolkit.setSelectionChangedListener(this);
624
		attributeEditorFactory.setEditorToolkit(attributeEditorToolkit);
625
		attributeEditorFactory.setEditorToolkit(attributeEditorToolkit);
625
626
626
		createParts();
627
		createParts();
Lines 1113-1118 Link Here
1113
		this.task = taskEditorInput.getTask();
1114
		this.task = taskEditorInput.getTask();
1114
		this.defaultSelection = new StructuredSelection(task);
1115
		this.defaultSelection = new StructuredSelection(task);
1115
		this.lastSelection = defaultSelection;
1116
		this.lastSelection = defaultSelection;
1117
		IHandlerService handlerService = (IHandlerService) getSite().getService(IHandlerService.class);
1118
		this.textSupport = new CommonTextSupport(handlerService);
1116
1119
1117
		initModel(taskEditorInput);
1120
		initModel(taskEditorInput);
1118
1121
Lines 1424-1427 Link Here
1424
		}
1427
		}
1425
	}
1428
	}
1426
1429
1430
	/**
1431
	 * @since 3.1
1432
	 */
1433
	public CommonTextSupport getTextSupport() {
1434
		return textSupport;
1435
	}
1436
1427
}
1437
}
(-)src/org/eclipse/mylyn/tasks/ui/editors/AttributeEditorToolkit.java (-128 / +10 lines)
Lines 11-19 Link Here
11
11
12
package org.eclipse.mylyn.tasks.ui.editors;
12
package org.eclipse.mylyn.tasks.ui.editors;
13
13
14
import org.eclipse.core.commands.IHandler;
15
import org.eclipse.jface.action.Action;
16
import org.eclipse.jface.commands.ActionHandler;
17
import org.eclipse.jface.fieldassist.ComboContentAdapter;
14
import org.eclipse.jface.fieldassist.ComboContentAdapter;
18
import org.eclipse.jface.fieldassist.ContentProposalAdapter;
15
import org.eclipse.jface.fieldassist.ContentProposalAdapter;
19
import org.eclipse.jface.fieldassist.ControlDecoration;
16
import org.eclipse.jface.fieldassist.ControlDecoration;
Lines 22-36 Link Here
22
import org.eclipse.jface.fieldassist.IContentProposalProvider;
19
import org.eclipse.jface.fieldassist.IContentProposalProvider;
23
import org.eclipse.jface.fieldassist.IControlContentAdapter;
20
import org.eclipse.jface.fieldassist.IControlContentAdapter;
24
import org.eclipse.jface.fieldassist.TextContentAdapter;
21
import org.eclipse.jface.fieldassist.TextContentAdapter;
25
import org.eclipse.jface.text.ITextListener;
26
import org.eclipse.jface.text.TextEvent;
27
import org.eclipse.jface.text.TextViewer;
22
import org.eclipse.jface.text.TextViewer;
28
import org.eclipse.jface.text.source.ISourceViewer;
29
import org.eclipse.jface.text.source.SourceViewer;
23
import org.eclipse.jface.text.source.SourceViewer;
30
import org.eclipse.jface.viewers.ILabelProvider;
24
import org.eclipse.jface.viewers.ILabelProvider;
31
import org.eclipse.jface.viewers.ISelectionChangedListener;
25
import org.eclipse.mylyn.internal.commons.ui.CommonTextSupport;
32
import org.eclipse.jface.viewers.SelectionChangedEvent;
33
import org.eclipse.jface.viewers.StructuredSelection;
34
import org.eclipse.mylyn.internal.provisional.commons.ui.CommonThemes;
26
import org.eclipse.mylyn.internal.provisional.commons.ui.CommonThemes;
35
import org.eclipse.mylyn.internal.tasks.ui.PersonProposalLabelProvider;
27
import org.eclipse.mylyn.internal.tasks.ui.PersonProposalLabelProvider;
36
import org.eclipse.mylyn.internal.tasks.ui.PersonProposalProvider;
28
import org.eclipse.mylyn.internal.tasks.ui.PersonProposalProvider;
Lines 42-62 Link Here
42
import org.eclipse.osgi.util.NLS;
34
import org.eclipse.osgi.util.NLS;
43
import org.eclipse.swt.SWT;
35
import org.eclipse.swt.SWT;
44
import org.eclipse.swt.custom.CCombo;
36
import org.eclipse.swt.custom.CCombo;
45
import org.eclipse.swt.custom.StyledText;
46
import org.eclipse.swt.events.DisposeEvent;
37
import org.eclipse.swt.events.DisposeEvent;
47
import org.eclipse.swt.events.DisposeListener;
38
import org.eclipse.swt.events.DisposeListener;
48
import org.eclipse.swt.events.FocusEvent;
49
import org.eclipse.swt.events.FocusListener;
50
import org.eclipse.swt.graphics.Color;
39
import org.eclipse.swt.graphics.Color;
51
import org.eclipse.swt.widgets.Combo;
40
import org.eclipse.swt.widgets.Combo;
52
import org.eclipse.swt.widgets.Control;
41
import org.eclipse.swt.widgets.Control;
53
import org.eclipse.swt.widgets.Menu;
42
import org.eclipse.swt.widgets.Menu;
54
import org.eclipse.swt.widgets.Text;
43
import org.eclipse.swt.widgets.Text;
55
import org.eclipse.ui.ActiveShellExpression;
56
import org.eclipse.ui.PlatformUI;
44
import org.eclipse.ui.PlatformUI;
57
import org.eclipse.ui.fieldassist.ContentAssistCommandAdapter;
45
import org.eclipse.ui.fieldassist.ContentAssistCommandAdapter;
58
import org.eclipse.ui.handlers.IHandlerActivation;
46
import org.eclipse.ui.handlers.IHandlerActivation;
59
import org.eclipse.ui.handlers.IHandlerService;
60
import org.eclipse.ui.keys.IBindingService;
47
import org.eclipse.ui.keys.IBindingService;
61
import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds;
48
import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds;
62
import org.eclipse.ui.themes.IThemeManager;
49
import org.eclipse.ui.themes.IThemeManager;
Lines 68-141 Link Here
68
// TODO EDITOR rename to AttributeUiToolkit?
55
// TODO EDITOR rename to AttributeUiToolkit?
69
public class AttributeEditorToolkit {
56
public class AttributeEditorToolkit {
70
57
71
	private class StyledTextFocusListener implements FocusListener {
72
73
		private final boolean spellCheck;
74
75
		private final SourceViewer viewer;
76
77
		public StyledTextFocusListener(SourceViewer viewer, boolean spellCheck) {
78
			this.viewer = viewer;
79
			this.spellCheck = spellCheck;
80
		}
81
82
		public void focusGained(FocusEvent e) {
83
			if (selectionChangedListener != null) {
84
				selectionChangedListener.selectionChanged(new SelectionChangedEvent(viewer, viewer.getSelection()));
85
			}
86
			activateHandlers(viewer, spellCheck);
87
		}
88
89
		public void focusLost(FocusEvent e) {
90
			deactivateHandlers();
91
			if (selectionChangedListener != null) {
92
				// make sure selection no text is selected when control looses focus
93
				StyledText st = (StyledText) e.widget;
94
				st.setSelectionRange(st.getCaretOffset(), 0);
95
				// update action enablement
96
				selectionChangedListener.selectionChanged(new SelectionChangedEvent(viewer, StructuredSelection.EMPTY));
97
			}
98
		}
99
100
	}
101
102
	private final Color colorIncoming;
58
	private final Color colorIncoming;
103
59
104
	public IHandlerActivation contentAssistHandlerActivation;
105
106
	private final IHandlerService handlerService;
107
108
	private Menu menu;
60
	private Menu menu;
109
61
110
	private IHandlerActivation quickAssistHandlerActivation;
62
	private AbstractRenderingEngine renderingEngine;
111
63
112
	private ISelectionChangedListener selectionChangedListener;
64
	private final CommonTextSupport textSupport;
113
65
114
	private AbstractRenderingEngine renderingEngine;
66
	@Deprecated
67
	public IHandlerActivation contentAssistHandlerActivation;
115
68
116
	AttributeEditorToolkit(IHandlerService handlerService) {
69
	AttributeEditorToolkit(CommonTextSupport textSupport) {
117
		this.handlerService = handlerService;
70
		this.textSupport = textSupport;
118
		IThemeManager themeManager = PlatformUI.getWorkbench().getThemeManager();
71
		IThemeManager themeManager = PlatformUI.getWorkbench().getThemeManager();
119
		colorIncoming = themeManager.getCurrentTheme().getColorRegistry().get(CommonThemes.COLOR_INCOMING_BACKGROUND);
72
		colorIncoming = themeManager.getCurrentTheme().getColorRegistry().get(CommonThemes.COLOR_INCOMING_BACKGROUND);
120
	}
73
	}
121
74
122
	private IHandlerActivation activateHandler(SourceViewer viewer, int operation, String actionDefinitionId) {
123
		IHandler handler = createActionHandler(viewer, operation, actionDefinitionId);
124
		return handlerService.activateHandler(actionDefinitionId, handler, //
125
				new ActiveShellExpression(viewer.getTextWidget().getShell()));
126
	}
127
128
	private void activateHandlers(SourceViewer viewer, boolean spellCheck) {
129
		deactivateHandlers();
130
		if (spellCheck) {
131
			quickAssistHandlerActivation = activateHandler(viewer, ISourceViewer.QUICK_ASSIST,
132
					ITextEditorActionDefinitionIds.QUICK_ASSIST);
133
		}
134
		contentAssistHandlerActivation = activateHandler(viewer, ISourceViewer.CONTENTASSIST_PROPOSALS,
135
				ITextEditorActionDefinitionIds.CONTENT_ASSIST_PROPOSALS);
136
137
	}
138
139
	public void adapt(AbstractAttributeEditor editor) {
75
	public void adapt(AbstractAttributeEditor editor) {
140
		if (editor.getControl() instanceof Text || editor.getControl() instanceof CCombo) {
76
		if (editor.getControl() instanceof Text || editor.getControl() instanceof CCombo) {
141
			Control control = editor.getControl();
77
			Control control = editor.getControl();
Lines 154-190 Link Here
154
			RichTextAttributeEditor richTextEditor = (RichTextAttributeEditor) editor;
90
			RichTextAttributeEditor richTextEditor = (RichTextAttributeEditor) editor;
155
			boolean spellCheck = hasSpellChecking(editor.getTaskAttribute());
91
			boolean spellCheck = hasSpellChecking(editor.getTaskAttribute());
156
			final SourceViewer viewer = richTextEditor.getViewer();
92
			final SourceViewer viewer = richTextEditor.getViewer();
157
			viewer.getControl().addFocusListener(new StyledTextFocusListener(viewer, spellCheck));
93
			textSupport.install(viewer, spellCheck);
158
			if (selectionChangedListener != null) {
159
				viewer.addSelectionChangedListener(selectionChangedListener);
160
				viewer.addTextListener(new ITextListener() {
161
					public void textChanged(TextEvent event) {
162
						if (selectionChangedListener != null) {
163
							selectionChangedListener.selectionChanged(new SelectionChangedEvent(viewer,
164
									viewer.getSelection()));
165
						}
166
					}
167
				});
168
			}
169
			if (!editor.isReadOnly() && richTextEditor.getMode() == Mode.TASK_RELATION) {
94
			if (!editor.isReadOnly() && richTextEditor.getMode() == Mode.TASK_RELATION) {
170
				installContentAssistControlDecoration(viewer.getControl());
95
				installContentAssistControlDecoration(viewer.getControl());
171
			}
96
			}
172
			installMenu(viewer.getControl());
97
			installMenu(viewer.getControl());
173
			EditorUtil.setTextViewer(editor.getControl(), viewer);
174
		} else {
98
		} else {
175
			final TextViewer viewer = EditorUtil.getTextViewer(editor.getControl());
99
			final TextViewer viewer = EditorUtil.getTextViewer(editor.getControl());
176
			if (viewer != null) {
100
			if (viewer != null) {
177
				if (selectionChangedListener != null) {
101
				textSupport.install(viewer, false);
178
					viewer.addSelectionChangedListener(selectionChangedListener);
179
					viewer.addTextListener(new ITextListener() {
180
						public void textChanged(TextEvent event) {
181
							if (selectionChangedListener != null) {
182
								selectionChangedListener.selectionChanged(new SelectionChangedEvent(viewer,
183
										viewer.getSelection()));
184
							}
185
						}
186
					});
187
				}
188
				installMenu(viewer.getControl());
102
				installMenu(viewer.getControl());
189
			}
103
			}
190
		}
104
		}
Lines 236-254 Link Here
236
		return controlDecoration;
150
		return controlDecoration;
237
	}
151
	}
238
152
239
	private IHandler createActionHandler(final SourceViewer viewer, final int operation, String actionDefinitionId) {
240
		Action quickFixAction = new Action() {
241
			@Override
242
			public void run() {
243
				if (viewer.canDoOperation(operation)) {
244
					viewer.doOperation(operation);
245
				}
246
			}
247
		};
248
		quickFixAction.setActionDefinitionId(actionDefinitionId);
249
		return new ActionHandler(quickFixAction);
250
	}
251
252
	/**
153
	/**
253
	 * Creates an IContentProposalProvider to provide content assist proposals for the given attribute.
154
	 * Creates an IContentProposalProvider to provide content assist proposals for the given attribute.
254
	 * 
155
	 * 
Lines 264-282 Link Here
264
		return new PersonProposalLabelProvider();
165
		return new PersonProposalLabelProvider();
265
	}
166
	}
266
167
267
	private void deactivateHandlers() {
268
		if (quickAssistHandlerActivation != null) {
269
			handlerService.deactivateHandler(quickAssistHandlerActivation);
270
			quickAssistHandlerActivation = null;
271
		}
272
		if (contentAssistHandlerActivation != null) {
273
			handlerService.deactivateHandler(contentAssistHandlerActivation);
274
			contentAssistHandlerActivation = null;
275
		}
276
	}
277
278
	void dispose() {
168
	void dispose() {
279
		deactivateHandlers();
169
		// FIXME textSupport.deactivateHandlers();
280
	}
170
	}
281
171
282
	public Color getColorIncoming() {
172
	public Color getColorIncoming() {
Lines 298-307 Link Here
298
		return renderingEngine;
188
		return renderingEngine;
299
	}
189
	}
300
190
301
	ISelectionChangedListener getSelectionChangedListener() {
302
		return selectionChangedListener;
303
	}
304
305
	/**
191
	/**
306
	 * Called to check if there's content assist available for the given attribute.
192
	 * Called to check if there's content assist available for the given attribute.
307
	 * 
193
	 * 
Lines 331-340 Link Here
331
		this.menu = menu;
217
		this.menu = menu;
332
	}
218
	}
333
219
334
	void setSelectionChangedListener(ISelectionChangedListener selectionListener) {
335
		this.selectionChangedListener = selectionListener;
336
	}
337
338
	public void setRenderingEngine(AbstractRenderingEngine renderingEngine) {
220
	public void setRenderingEngine(AbstractRenderingEngine renderingEngine) {
339
		this.renderingEngine = renderingEngine;
221
		this.renderingEngine = renderingEngine;
340
	}
222
	}
(-)src/org/eclipse/mylyn/internal/tasks/ui/editors/TaskEditorActionContributor.java (-134 / +50 lines)
Lines 29-35 Link Here
29
import org.eclipse.jface.viewers.IStructuredSelection;
29
import org.eclipse.jface.viewers.IStructuredSelection;
30
import org.eclipse.jface.viewers.SelectionChangedEvent;
30
import org.eclipse.jface.viewers.SelectionChangedEvent;
31
import org.eclipse.jface.viewers.StructuredSelection;
31
import org.eclipse.jface.viewers.StructuredSelection;
32
import org.eclipse.mylyn.internal.provisional.commons.ui.CommonImages;
32
import org.eclipse.mylyn.internal.commons.ui.WorkbenchActionSupport;
33
import org.eclipse.mylyn.internal.commons.ui.WorkbenchActionSupport.WorkbenchActionCallback;
33
import org.eclipse.mylyn.internal.tasks.core.AbstractTaskCategory;
34
import org.eclipse.mylyn.internal.tasks.core.AbstractTaskCategory;
34
import org.eclipse.mylyn.internal.tasks.core.LocalTask;
35
import org.eclipse.mylyn.internal.tasks.core.LocalTask;
35
import org.eclipse.mylyn.internal.tasks.core.UnmatchedTaskContainer;
36
import org.eclipse.mylyn.internal.tasks.core.UnmatchedTaskContainer;
Lines 51-70 Link Here
51
import org.eclipse.mylyn.tasks.ui.editors.AbstractTaskEditorPage;
52
import org.eclipse.mylyn.tasks.ui.editors.AbstractTaskEditorPage;
52
import org.eclipse.mylyn.tasks.ui.editors.TaskEditor;
53
import org.eclipse.mylyn.tasks.ui.editors.TaskEditor;
53
import org.eclipse.mylyn.tasks.ui.editors.TaskEditorInput;
54
import org.eclipse.mylyn.tasks.ui.editors.TaskEditorInput;
55
import org.eclipse.swt.widgets.Control;
54
import org.eclipse.ui.IActionBars;
56
import org.eclipse.ui.IActionBars;
55
import org.eclipse.ui.IEditorInput;
57
import org.eclipse.ui.IEditorInput;
56
import org.eclipse.ui.IEditorPart;
58
import org.eclipse.ui.IEditorPart;
57
import org.eclipse.ui.ISharedImages;
58
import org.eclipse.ui.IWorkbenchActionConstants;
59
import org.eclipse.ui.IWorkbenchActionConstants;
59
import org.eclipse.ui.IWorkbenchPage;
60
import org.eclipse.ui.IWorkbenchPage;
60
import org.eclipse.ui.PlatformUI;
61
import org.eclipse.ui.PlatformUI;
61
import org.eclipse.ui.actions.ActionFactory;
62
import org.eclipse.ui.forms.editor.IFormPage;
62
import org.eclipse.ui.forms.editor.IFormPage;
63
import org.eclipse.ui.internal.WorkbenchImages;
64
import org.eclipse.ui.internal.WorkbenchMessages;
65
import org.eclipse.ui.part.MultiPageEditorActionBarContributor;
63
import org.eclipse.ui.part.MultiPageEditorActionBarContributor;
66
import org.eclipse.ui.progress.IProgressService;
64
import org.eclipse.ui.progress.IProgressService;
67
import org.eclipse.ui.texteditor.IWorkbenchActionDefinitionIds;
68
65
69
/**
66
/**
70
 * @author Mik Kersten
67
 * @author Mik Kersten
Lines 86-163 Link Here
86
83
87
	private final NewTaskFromSelectionAction newTaskFromSelectionAction = new NewTaskFromSelectionAction();
84
	private final NewTaskFromSelectionAction newTaskFromSelectionAction = new NewTaskFromSelectionAction();
88
85
89
	private final GlobalAction cutAction;
86
	private final WorkbenchActionSupport actionSupport;
90
91
	private final GlobalAction undoAction;
92
93
	private final GlobalAction redoAction;
94
95
	private final GlobalAction copyAction;
96
97
	private final GlobalAction pasteAction;
98
99
	private final GlobalAction selectAllAction;
100
101
	private final GlobalAction findAction;
102
87
103
	public TaskEditorActionContributor() {
88
	public TaskEditorActionContributor() {
104
		cutAction = new GlobalAction(ActionFactory.CUT.getId());
89
		actionSupport = new WorkbenchActionSupport();
105
		cutAction.setText(WorkbenchMessages.Workbench_cut);
90
		actionSupport.setCallback(new EditorPageCallback());
106
		cutAction.setToolTipText(WorkbenchMessages.Workbench_cutToolTip);
107
		cutAction.setImageDescriptor(WorkbenchImages.getImageDescriptor(ISharedImages.IMG_TOOL_CUT));
108
		cutAction.setHoverImageDescriptor(WorkbenchImages.getImageDescriptor(ISharedImages.IMG_TOOL_CUT));
109
		cutAction.setDisabledImageDescriptor(WorkbenchImages.getImageDescriptor(ISharedImages.IMG_TOOL_CUT_DISABLED));
110
		cutAction.setActionDefinitionId(IWorkbenchActionDefinitionIds.CUT);
111
112
		pasteAction = new GlobalAction(ActionFactory.PASTE.getId());
113
		pasteAction.setText(WorkbenchMessages.Workbench_paste);
114
		pasteAction.setToolTipText(WorkbenchMessages.Workbench_pasteToolTip);
115
		pasteAction.setImageDescriptor(WorkbenchImages.getImageDescriptor(ISharedImages.IMG_TOOL_PASTE));
116
		pasteAction.setHoverImageDescriptor(WorkbenchImages.getImageDescriptor(ISharedImages.IMG_TOOL_PASTE));
117
		pasteAction.setDisabledImageDescriptor(WorkbenchImages.getImageDescriptor(ISharedImages.IMG_TOOL_PASTE_DISABLED));
118
		pasteAction.setActionDefinitionId(IWorkbenchActionDefinitionIds.PASTE);
119
120
		copyAction = new GlobalAction(ActionFactory.COPY.getId());
121
		copyAction.setText(WorkbenchMessages.Workbench_copy);
122
		copyAction.setImageDescriptor(WorkbenchImages.getImageDescriptor(ISharedImages.IMG_TOOL_COPY));
123
		copyAction.setHoverImageDescriptor(WorkbenchImages.getImageDescriptor(ISharedImages.IMG_TOOL_COPY));
124
		copyAction.setDisabledImageDescriptor(WorkbenchImages.getImageDescriptor(ISharedImages.IMG_TOOL_COPY_DISABLED));
125
		copyAction.setActionDefinitionId(IWorkbenchActionDefinitionIds.COPY);
126
127
		undoAction = new GlobalAction(ActionFactory.UNDO.getId());
128
		undoAction.setText(WorkbenchMessages.Workbench_undo);
129
		undoAction.setImageDescriptor(WorkbenchImages.getImageDescriptor(ISharedImages.IMG_TOOL_UNDO));
130
		undoAction.setHoverImageDescriptor(WorkbenchImages.getImageDescriptor(ISharedImages.IMG_TOOL_UNDO));
131
		undoAction.setDisabledImageDescriptor(WorkbenchImages.getImageDescriptor(ISharedImages.IMG_TOOL_UNDO_DISABLED));
132
		undoAction.setActionDefinitionId(IWorkbenchActionDefinitionIds.UNDO);
133
134
		redoAction = new GlobalAction(ActionFactory.REDO.getId());
135
		redoAction.setText(WorkbenchMessages.Workbench_redo);
136
		redoAction.setImageDescriptor(WorkbenchImages.getImageDescriptor(ISharedImages.IMG_TOOL_REDO));
137
		redoAction.setHoverImageDescriptor(WorkbenchImages.getImageDescriptor(ISharedImages.IMG_TOOL_REDO));
138
		redoAction.setDisabledImageDescriptor(WorkbenchImages.getImageDescriptor(ISharedImages.IMG_TOOL_REDO_DISABLED));
139
		redoAction.setActionDefinitionId(IWorkbenchActionDefinitionIds.REDO);
140
141
		selectAllAction = new GlobalAction(ActionFactory.SELECT_ALL.getId());
142
		selectAllAction.setText(WorkbenchMessages.Workbench_selectAll);
143
		selectAllAction.setActionDefinitionId(IWorkbenchActionDefinitionIds.SELECT_ALL);
144
		selectAllAction.setEnabled(true);
145
146
		findAction = new GlobalAction(ActionFactory.FIND.getId());
147
		findAction.setText(Messages.TaskEditorActionContributor_Find);
148
		findAction.setActionDefinitionId(IWorkbenchActionDefinitionIds.FIND_REPLACE);
149
		findAction.setImageDescriptor(CommonImages.FIND);
150
	}
91
	}
151
92
152
	public void addClipboardActions(IMenuManager manager) {
93
	public void addClipboardActions(IMenuManager manager) {
153
		manager.add(undoAction);
94
		manager.add(actionSupport.getUndoAction());
154
		manager.add(redoAction);
95
		manager.add(actionSupport.getRedoAction());
155
		manager.add(new Separator());
96
		manager.add(new Separator());
156
		manager.add(cutAction);
97
		manager.add(actionSupport.getCutAction());
157
		manager.add(copyAction);
98
		manager.add(actionSupport.getCopyAction());
158
		manager.add(copyTaskDetailsAction);
99
		manager.add(copyTaskDetailsAction);
159
		manager.add(pasteAction);
100
		manager.add(actionSupport.getPasteAction());
160
		manager.add(selectAllAction);
101
		manager.add(actionSupport.getSelectAllAction());
161
		manager.add(newTaskFromSelectionAction);
102
		manager.add(newTaskFromSelectionAction);
162
		manager.add(new Separator());
103
		manager.add(new Separator());
163
	}
104
	}
Lines 275-288 Link Here
275
216
276
	public void updateSelectableActions(ISelection selection) {
217
	public void updateSelectableActions(ISelection selection) {
277
		if (editor != null) {
218
		if (editor != null) {
278
			cutAction.selectionChanged(selection);
219
			actionSupport.updateActions(selection);
279
			copyAction.selectionChanged(selection);
280
			pasteAction.selectionChanged(selection);
281
			undoAction.selectionChanged(selection);
282
			redoAction.selectionChanged(selection);
283
			selectAllAction.selectionChanged(selection);
284
			newTaskFromSelectionAction.selectionChanged(selection);
220
			newTaskFromSelectionAction.selectionChanged(selection);
285
			findAction.selectionChanged(selection);
286
		}
221
		}
287
	}
222
	}
288
223
Lines 305-312 Link Here
305
	@Override
240
	@Override
306
	public void init(IActionBars bars, IWorkbenchPage page) {
241
	public void init(IActionBars bars, IWorkbenchPage page) {
307
		super.init(bars, page);
242
		super.init(bars, page);
308
		registerGlobalHandlers(bars);
243
		actionSupport.install(bars);
309
		findAction.selectionChanged(StructuredSelection.EMPTY);
310
	}
244
	}
311
245
312
	public TaskEditor getEditor() {
246
	public TaskEditor getEditor() {
Lines 332-411 Link Here
332
		updateSelectableActions(event.getSelection());
266
		updateSelectableActions(event.getSelection());
333
	}
267
	}
334
268
335
	private class GlobalAction extends Action {
269
	private class EditorPageCallback extends WorkbenchActionCallback {
336
337
		private final String actionId;
338
339
		public GlobalAction(String actionId) {
340
			this.actionId = actionId;
341
		}
342
270
343
		@Override
271
		@Override
344
		public void run() {
272
		public void doAction(String actionId, Control control) {
345
			IFormPage page = getActivePage();
273
			IFormPage page = getActivePage();
346
			if (page instanceof TaskFormPage) {
274
			if (page instanceof AbstractTaskEditorPage) {
347
				TaskFormPage editor = (TaskFormPage) page;
348
				editor.doAction(actionId);
349
			} else if (page instanceof AbstractTaskEditorPage) {
350
				AbstractTaskEditorPage editor = (AbstractTaskEditorPage) page;
275
				AbstractTaskEditorPage editor = (AbstractTaskEditorPage) page;
351
				editor.doAction(actionId);
276
				editor.doAction(actionId);
352
			} else {
277
			} else {
353
				EditorUtil.doAction(actionId, EditorUtil.getFocusControl(getActivePage()));
278
				WorkbenchActionCallback textSupport = (WorkbenchActionCallback) page.getAdapter(WorkbenchActionCallback.class);
279
				if (textSupport != null) {
280
					textSupport.doAction(actionId, control);
281
				} else {
282
					super.doAction(actionId, control);
283
				}
354
			}
284
			}
355
			updateSelectableActions(getSelection());
356
		}
285
		}
357
286
358
		public void selectionChanged(ISelection selection) {
287
		@Override
288
		public boolean canPerformAction(String actionId, Control control) {
359
			IFormPage page = getActivePage();
289
			IFormPage page = getActivePage();
360
			if (page instanceof TaskFormPage) {
290
			if (page instanceof TaskFormPage) {
361
				TaskFormPage editor = (TaskFormPage) page;
291
				TaskFormPage editor = (TaskFormPage) page;
362
				setEnabled(editor.canPerformAction(actionId));
292
				return editor.canPerformAction(actionId);
363
			} else if (page instanceof AbstractTaskEditorPage) {
364
				AbstractTaskEditorPage editor = (AbstractTaskEditorPage) page;
365
				setEnabled(editor.canPerformAction(actionId));
366
			} else {
293
			} else {
367
				setEnabled(EditorUtil.canPerformAction(actionId, EditorUtil.getFocusControl(getActivePage())));
294
				WorkbenchActionCallback textSupport = (WorkbenchActionCallback) page.getAdapter(WorkbenchActionCallback.class);
295
				if (textSupport != null) {
296
					return textSupport.canPerformAction(actionId, control);
297
				} else {
298
					return super.canPerformAction(actionId, control);
299
				}
368
			}
300
			}
369
		}
301
		}
370
	}
371
302
372
	private void registerGlobalHandlers(IActionBars bars) {
303
		@Override
373
		bars.setGlobalActionHandler(ActionFactory.CUT.getId(), cutAction);
304
		public ISelection getSelection() {
374
		bars.setGlobalActionHandler(ActionFactory.PASTE.getId(), pasteAction);
305
			return TaskEditorActionContributor.this.getSelection();
375
		bars.setGlobalActionHandler(ActionFactory.COPY.getId(), copyAction);
306
		}
376
		bars.setGlobalActionHandler(ActionFactory.UNDO.getId(), undoAction);
377
		bars.setGlobalActionHandler(ActionFactory.REDO.getId(), redoAction);
378
		bars.setGlobalActionHandler(ActionFactory.SELECT_ALL.getId(), selectAllAction);
379
		bars.setGlobalActionHandler(ActionFactory.FIND.getId(), findAction);
380
		bars.updateActionBars();
381
	}
382
383
	@SuppressWarnings("unused")
384
	private void unregisterGlobalHandlers(IActionBars bars) {
385
		bars.setGlobalActionHandler(ActionFactory.CUT.getId(), null);
386
		bars.setGlobalActionHandler(ActionFactory.PASTE.getId(), null);
387
		bars.setGlobalActionHandler(ActionFactory.COPY.getId(), null);
388
		bars.setGlobalActionHandler(ActionFactory.UNDO.getId(), null);
389
		bars.setGlobalActionHandler(ActionFactory.REDO.getId(), null);
390
		bars.setGlobalActionHandler(ActionFactory.SELECT_ALL.getId(), null);
391
		bars.setGlobalActionHandler(ActionFactory.FIND.getId(), null);
392
		bars.updateActionBars();
393
	}
394
307
395
	public void forceActionsEnabled() {
308
		@Override
396
		cutAction.setEnabled(true);
309
		public Control getFocusControl() {
397
		copyAction.setEnabled(true);
310
			IFormPage page = getActivePage();
398
		pasteAction.setEnabled(true);
311
			return EditorUtil.getFocusControl(page);
399
		selectAllAction.setEnabled(true);
312
		}
400
		undoAction.setEnabled(false);
401
		redoAction.setEnabled(false);
402
	}
403
313
404
	private IFormPage getActivePage() {
405
		return (editor != null) ? editor.getActivePageInstance() : null;
406
	}
314
	}
407
315
408
	private ISelection getSelection() {
316
	public ISelection getSelection() {
409
		if (editor != null && editor.getSite().getSelectionProvider() != null) {
317
		if (editor != null && editor.getSite().getSelectionProvider() != null) {
410
			return editor.getSite().getSelectionProvider().getSelection();
318
			return editor.getSite().getSelectionProvider().getSelection();
411
		} else {
319
		} else {
Lines 413-416 Link Here
413
		}
321
		}
414
	}
322
	}
415
323
324
	public void forceActionsEnabled() {
325
		actionSupport.forceActionsEnabled();
326
	}
327
328
	private IFormPage getActivePage() {
329
		return (editor != null) ? editor.getActivePageInstance() : null;
330
	}
331
416
}
332
}
(-)src/org/eclipse/mylyn/internal/tasks/ui/editors/TaskPlanningEditor.java (-1 / +40 lines)
Lines 24-34 Link Here
24
import org.eclipse.jface.action.IToolBarManager;
24
import org.eclipse.jface.action.IToolBarManager;
25
import org.eclipse.jface.dialogs.MessageDialog;
25
import org.eclipse.jface.dialogs.MessageDialog;
26
import org.eclipse.jface.layout.GridDataFactory;
26
import org.eclipse.jface.layout.GridDataFactory;
27
import org.eclipse.jface.text.Document;
27
import org.eclipse.jface.text.ITextListener;
28
import org.eclipse.jface.text.ITextListener;
28
import org.eclipse.jface.text.TextEvent;
29
import org.eclipse.jface.text.TextEvent;
29
import org.eclipse.jface.text.TextViewer;
30
import org.eclipse.jface.text.TextViewer;
31
import org.eclipse.jface.text.source.SourceViewer;
30
import org.eclipse.jface.viewers.StructuredSelection;
32
import org.eclipse.jface.viewers.StructuredSelection;
31
import org.eclipse.mylyn.commons.core.StatusHandler;
33
import org.eclipse.mylyn.commons.core.StatusHandler;
34
import org.eclipse.mylyn.internal.commons.ui.CommonTextSupport;
32
import org.eclipse.mylyn.internal.provisional.commons.ui.CommonImages;
35
import org.eclipse.mylyn.internal.provisional.commons.ui.CommonImages;
33
import org.eclipse.mylyn.internal.provisional.commons.ui.DatePicker;
36
import org.eclipse.mylyn.internal.provisional.commons.ui.DatePicker;
34
import org.eclipse.mylyn.internal.tasks.core.AbstractTask;
37
import org.eclipse.mylyn.internal.tasks.core.AbstractTask;
Lines 77-85 Link Here
77
import org.eclipse.swt.widgets.Label;
80
import org.eclipse.swt.widgets.Label;
78
import org.eclipse.swt.widgets.Spinner;
81
import org.eclipse.swt.widgets.Spinner;
79
import org.eclipse.swt.widgets.Text;
82
import org.eclipse.swt.widgets.Text;
83
import org.eclipse.ui.IEditorInput;
84
import org.eclipse.ui.IEditorSite;
80
import org.eclipse.ui.PlatformUI;
85
import org.eclipse.ui.PlatformUI;
81
import org.eclipse.ui.forms.IFormColors;
86
import org.eclipse.ui.forms.IFormColors;
82
import org.eclipse.ui.forms.IManagedForm;
87
import org.eclipse.ui.forms.IManagedForm;
88
import org.eclipse.ui.forms.editor.FormPage;
83
import org.eclipse.ui.forms.events.ExpansionEvent;
89
import org.eclipse.ui.forms.events.ExpansionEvent;
84
import org.eclipse.ui.forms.events.HyperlinkAdapter;
90
import org.eclipse.ui.forms.events.HyperlinkAdapter;
85
import org.eclipse.ui.forms.events.HyperlinkEvent;
91
import org.eclipse.ui.forms.events.HyperlinkEvent;
Lines 90-101 Link Here
90
import org.eclipse.ui.forms.widgets.ImageHyperlink;
96
import org.eclipse.ui.forms.widgets.ImageHyperlink;
91
import org.eclipse.ui.forms.widgets.ScrolledForm;
97
import org.eclipse.ui.forms.widgets.ScrolledForm;
92
import org.eclipse.ui.forms.widgets.Section;
98
import org.eclipse.ui.forms.widgets.Section;
99
import org.eclipse.ui.handlers.IHandlerService;
93
100
94
/**
101
/**
95
 * @author Mik Kersten
102
 * @author Mik Kersten
96
 * @author Rob Elves
103
 * @author Rob Elves
97
 */
104
 */
98
public class TaskPlanningEditor extends TaskFormPage {
105
public class TaskPlanningEditor extends FormPage {
99
106
100
	private static final String RESET = Messages.TaskPlanningEditor_Reset;
107
	private static final String RESET = Messages.TaskPlanningEditor_Reset;
101
108
Lines 182-193 Link Here
182
189
183
	private ITaskActivityListener timingListener;
190
	private ITaskActivityListener timingListener;
184
191
192
	private boolean isDirty;
193
194
	private CommonTextSupport textSupport;
195
185
	public TaskPlanningEditor(TaskEditor editor) {
196
	public TaskPlanningEditor(TaskEditor editor) {
186
		super(editor, ITasksUiConstants.ID_PAGE_PLANNING, Messages.TaskPlanningEditor_Planning);
197
		super(editor, ITasksUiConstants.ID_PAGE_PLANNING, Messages.TaskPlanningEditor_Planning);
187
		this.parentEditor = editor;
198
		this.parentEditor = editor;
188
		TasksUiInternal.getTaskList().addChangeListener(TASK_LIST_LISTENER);
199
		TasksUiInternal.getTaskList().addChangeListener(TASK_LIST_LISTENER);
189
	}
200
	}
190
201
202
	@Override
203
	public void init(IEditorSite site, IEditorInput input) {
204
		super.init(site, input);
205
		this.textSupport = new CommonTextSupport((IHandlerService) getSite().getService(IHandlerService.class));
206
		this.textSupport.setSelectionChangedListener((TaskEditorActionContributor) getEditorSite().getActionBarContributor());
207
	}
208
209
	@Override
210
	public Object getAdapter(Class adapter) {
211
		if (adapter == CommonTextSupport.class) {
212
			return textSupport;
213
		}
214
		return super.getAdapter(adapter);
215
	}
216
191
	/**
217
	/**
192
	 * Override for customizing the tool bar.
218
	 * Override for customizing the tool bar.
193
	 */
219
	 */
Lines 564-569 Link Here
564
		toolkit.paintBordersFor(statusComposite);
590
		toolkit.paintBordersFor(statusComposite);
565
	}
591
	}
566
592
593
	private TextViewer addTextEditor(TaskRepository repository, Composite parent, String text, boolean spellCheck,
594
			int style) {
595
		SourceViewer viewer = new SourceViewer(parent, null, style);
596
		viewer.configure(new RepositoryTextViewerConfiguration(repository, spellCheck));
597
		textSupport.configure(viewer, new Document(text), spellCheck);
598
		return viewer;
599
	}
600
601
	private void markDirty(boolean dirty) {
602
		isDirty = dirty;
603
		getManagedForm().dirtyStateChanged();
604
	}
605
567
	/**
606
	/**
568
	 * Attempts to set the task pageTitle to the title from the specified url
607
	 * Attempts to set the task pageTitle to the title from the specified url
569
	 */
608
	 */
(-)src/org/eclipse/mylyn/internal/tasks/ui/editors/TaskEditorNotesPart.java (+130 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2004, 2008 Tasktop Technologies and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     Tasktop Technologies - initial API and implementation
10
 *******************************************************************************/
11
12
package org.eclipse.mylyn.internal.tasks.ui.editors;
13
14
import org.eclipse.core.runtime.Assert;
15
import org.eclipse.jface.text.Document;
16
import org.eclipse.jface.text.ITextListener;
17
import org.eclipse.jface.text.TextEvent;
18
import org.eclipse.jface.text.source.SourceViewer;
19
import org.eclipse.mylyn.internal.tasks.core.AbstractTask;
20
import org.eclipse.mylyn.tasks.ui.editors.AbstractTaskEditorPage;
21
import org.eclipse.mylyn.tasks.ui.editors.AbstractTaskEditorPart;
22
import org.eclipse.swt.SWT;
23
import org.eclipse.swt.layout.GridData;
24
import org.eclipse.swt.layout.GridLayout;
25
import org.eclipse.swt.widgets.Composite;
26
import org.eclipse.ui.forms.widgets.FormToolkit;
27
import org.eclipse.ui.forms.widgets.Section;
28
import org.eclipse.ui.internal.EditorAreaHelper;
29
import org.eclipse.ui.internal.WorkbenchPage;
30
31
/**
32
 * @author Steffen Pingel
33
 */
34
public class TaskEditorNotesPart extends AbstractTaskEditorPart {
35
36
	private String value;
37
38
	private AbstractTask task;
39
40
	private SourceViewer noteEditor;
41
42
	public TaskEditorNotesPart() {
43
		setPartName(Messages.TaskPlanningEditor_Notes);
44
	}
45
46
	@Override
47
	public void initialize(AbstractTaskEditorPage taskEditorPage) {
48
		super.initialize(taskEditorPage);
49
		task = (AbstractTask) taskEditorPage.getTask();
50
	}
51
52
	private boolean notesEqual() {
53
		if (task.getNotes() == null && value == null) {
54
			return true;
55
		}
56
57
		if (task.getNotes() != null && value != null) {
58
			return task.getNotes().equals(value);
59
		}
60
		return false;
61
	}
62
63
	@Override
64
	public void commit(boolean onSave) {
65
		Assert.isNotNull(task);
66
67
		if (!notesEqual()) {
68
			task.setNotes(value);
69
			// XXX REFRESH THE TASLKIST
70
		}
71
72
		super.commit(onSave);
73
	}
74
75
	@Override
76
	public void createControl(Composite parent, FormToolkit toolkit) {
77
		this.value = task.getNotes();
78
		if (this.value == null) {
79
			this.value = "";
80
		}
81
82
		Section section = createSection(parent, toolkit, this.value != null && this.value.length() > 0);
83
84
		Composite composite = toolkit.createComposite(section);
85
		GridLayout layout = new GridLayout();
86
		layout.numColumns = 1;
87
		composite.setLayout(layout);
88
89
		noteEditor = new SourceViewer(parent, null, SWT.FLAT | SWT.MULTI | SWT.WRAP | SWT.V_SCROLL);
90
		noteEditor.configure(new RepositoryTextViewerConfiguration(getModel().getTaskRepository(), true));
91
		getTaskEditorPage().getTextSupport().configure(noteEditor, new Document(this.value), true);
92
		noteEditor.addTextListener(new ITextListener() {
93
			public void textChanged(TextEvent event) {
94
				TaskEditorNotesPart.this.value = noteEditor.getTextWidget().getText();
95
				markDirty();
96
			}
97
		});
98
99
		final GridData gd = new GridData(GridData.FILL_BOTH);
100
		int widthHint = 0;
101
102
		if (getManagedForm() != null && getManagedForm().getForm() != null) {
103
			widthHint = getManagedForm().getForm().getClientArea().width - 90;
104
		}
105
		if (widthHint <= 0 && getTaskEditorPage().getEditor().getEditorSite() != null
106
				&& getTaskEditorPage().getEditor().getEditorSite().getPage() != null) {
107
			EditorAreaHelper editorManager = ((WorkbenchPage) getTaskEditorPage().getEditor().getEditorSite().getPage()).getEditorPresentation();
108
			if (editorManager != null && editorManager.getLayoutPart() != null) {
109
				widthHint = editorManager.getLayoutPart().getControl().getBounds().width - 90;
110
			}
111
		}
112
113
		if (widthHint <= 0) {
114
			widthHint = 100;
115
		}
116
117
		gd.widthHint = widthHint;
118
		gd.minimumHeight = 100;
119
		gd.grabExcessHorizontalSpace = true;
120
121
		noteEditor.getControl().setLayoutData(gd);
122
		noteEditor.getControl().setData(FormToolkit.KEY_DRAW_BORDER, FormToolkit.TEXT_BORDER);
123
		noteEditor.setEditable(true);
124
125
		toolkit.paintBordersFor(composite);
126
		section.setClient(composite);
127
		setSection(toolkit, section);
128
	}
129
130
}
(-)META-INF/MANIFEST.MF (+3 lines)
Lines 4-10 Link Here
4
Bundle-SymbolicName: org.eclipse.mylyn.commons.ui;singleton:=true
4
Bundle-SymbolicName: org.eclipse.mylyn.commons.ui;singleton:=true
5
Bundle-Version: 3.1.0.qualifier
5
Bundle-Version: 3.1.0.qualifier
6
Require-Bundle: org.eclipse.core.runtime,
6
Require-Bundle: org.eclipse.core.runtime,
7
 org.eclipse.core.expressions,
8
 org.eclipse.jface.text,
7
 org.eclipse.ui,
9
 org.eclipse.ui,
10
 org.eclipse.ui.editors;resolution:=optional,
8
 org.eclipse.ui.forms;resolution:=optional
11
 org.eclipse.ui.forms;resolution:=optional
9
Bundle-ActivationPolicy: lazy
12
Bundle-ActivationPolicy: lazy
10
Bundle-RequiredExecutionEnvironment: J2SE-1.5
13
Bundle-RequiredExecutionEnvironment: J2SE-1.5
(-)src/org/eclipse/mylyn/internal/commons/ui/WorkbenchActionSupport.java (+267 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2004, 2008 Tasktop Technologies and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     Tasktop Technologies - initial API and implementation
10
 *******************************************************************************/
11
12
package org.eclipse.mylyn.internal.commons.ui;
13
14
import org.eclipse.jface.action.Action;
15
import org.eclipse.jface.action.IMenuManager;
16
import org.eclipse.jface.action.Separator;
17
import org.eclipse.jface.text.TextSelection;
18
import org.eclipse.jface.viewers.ISelection;
19
import org.eclipse.jface.viewers.ISelectionChangedListener;
20
import org.eclipse.jface.viewers.SelectionChangedEvent;
21
import org.eclipse.mylyn.internal.provisional.commons.ui.CommonImages;
22
import org.eclipse.swt.widgets.Control;
23
import org.eclipse.swt.widgets.Display;
24
import org.eclipse.ui.IActionBars;
25
import org.eclipse.ui.ISharedImages;
26
import org.eclipse.ui.IWorkbenchWindow;
27
import org.eclipse.ui.PlatformUI;
28
import org.eclipse.ui.actions.ActionFactory;
29
import org.eclipse.ui.internal.WorkbenchImages;
30
import org.eclipse.ui.internal.WorkbenchMessages;
31
32
/**
33
 * @author Mik Kersten
34
 * @author Rob Elves
35
 * @author Steffen Pingel
36
 */
37
@SuppressWarnings("restriction")
38
public class WorkbenchActionSupport implements ISelectionChangedListener {
39
40
	private class GlobalAction extends Action {
41
42
		private final String actionId;
43
44
		public GlobalAction(String actionId) {
45
			this.actionId = actionId;
46
		}
47
48
		@Override
49
		public void run() {
50
			if (callback != null) {
51
				callback.doAction(actionId, callback.getFocusControl());
52
				updateActions(callback.getSelection());
53
			}
54
		}
55
56
		public void selectionChanged(ISelection selection) {
57
			if (callback != null) {
58
				setEnabled(callback.canPerformAction(actionId, callback.getFocusControl()));
59
			} else {
60
				setEnabled(false);
61
			}
62
		}
63
	}
64
65
	public static class WorkbenchActionCallback {
66
67
		public boolean canPerformAction(String actionId, Control control) {
68
			return CommonTextSupport.canPerformAction(actionId, control);
69
		}
70
71
		public void doAction(String actionId, Control control) {
72
			CommonTextSupport.doAction(actionId, control);
73
		}
74
75
		public Control getFocusControl() {
76
			return Display.getDefault().getFocusControl();
77
		}
78
79
		public ISelection getSelection() {
80
			IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
81
			if (window != null && window.getSelectionService() != null) {
82
				return window.getSelectionService().getSelection();
83
			}
84
			return null;
85
		}
86
87
	}
88
89
	public static final String COPY = "org.eclipse.ui.edit.copy"; //$NON-NLS-1$
90
91
	public static final String CUT = "org.eclipse.ui.edit.cut"; //$NON-NLS-1$
92
93
	public static final String FIND_REPLACE = "org.eclipse.ui.edit.findReplace"; //$NON-NLS-1$
94
95
	public static final String PASTE = "org.eclipse.ui.edit.paste"; //$NON-NLS-1$
96
97
	public static final String REDO = "org.eclipse.ui.edit.redo"; //$NON-NLS-1$
98
99
	public static final String SELECT_ALL = "org.eclipse.ui.edit.selectAll"; //$NON-NLS-1$
100
101
	public static final String UNDO = "org.eclipse.ui.edit.undo"; //$NON-NLS-1$
102
103
	public WorkbenchActionCallback callback;
104
105
	private final GlobalAction copyAction;
106
107
	private final GlobalAction cutAction;
108
109
	private final GlobalAction findAction;
110
111
	private final GlobalAction pasteAction;
112
113
	private final GlobalAction redoAction;
114
115
	private final GlobalAction selectAllAction;
116
117
	private final GlobalAction undoAction;
118
119
	public WorkbenchActionSupport() {
120
		cutAction = new GlobalAction(ActionFactory.CUT.getId());
121
		cutAction.setText(WorkbenchMessages.Workbench_cut);
122
		cutAction.setToolTipText(WorkbenchMessages.Workbench_cutToolTip);
123
		cutAction.setImageDescriptor(WorkbenchImages.getImageDescriptor(ISharedImages.IMG_TOOL_CUT));
124
		cutAction.setHoverImageDescriptor(WorkbenchImages.getImageDescriptor(ISharedImages.IMG_TOOL_CUT));
125
		cutAction.setDisabledImageDescriptor(WorkbenchImages.getImageDescriptor(ISharedImages.IMG_TOOL_CUT_DISABLED));
126
		cutAction.setActionDefinitionId(CUT);
127
128
		pasteAction = new GlobalAction(ActionFactory.PASTE.getId());
129
		pasteAction.setText(WorkbenchMessages.Workbench_paste);
130
		pasteAction.setToolTipText(WorkbenchMessages.Workbench_pasteToolTip);
131
		pasteAction.setImageDescriptor(WorkbenchImages.getImageDescriptor(ISharedImages.IMG_TOOL_PASTE));
132
		pasteAction.setHoverImageDescriptor(WorkbenchImages.getImageDescriptor(ISharedImages.IMG_TOOL_PASTE));
133
		pasteAction.setDisabledImageDescriptor(WorkbenchImages.getImageDescriptor(ISharedImages.IMG_TOOL_PASTE_DISABLED));
134
		pasteAction.setActionDefinitionId(PASTE);
135
136
		copyAction = new GlobalAction(ActionFactory.COPY.getId());
137
		copyAction.setText(WorkbenchMessages.Workbench_copy);
138
		copyAction.setImageDescriptor(WorkbenchImages.getImageDescriptor(ISharedImages.IMG_TOOL_COPY));
139
		copyAction.setHoverImageDescriptor(WorkbenchImages.getImageDescriptor(ISharedImages.IMG_TOOL_COPY));
140
		copyAction.setDisabledImageDescriptor(WorkbenchImages.getImageDescriptor(ISharedImages.IMG_TOOL_COPY_DISABLED));
141
		copyAction.setActionDefinitionId(COPY);
142
143
		undoAction = new GlobalAction(ActionFactory.UNDO.getId());
144
		undoAction.setText(WorkbenchMessages.Workbench_undo);
145
		undoAction.setImageDescriptor(WorkbenchImages.getImageDescriptor(ISharedImages.IMG_TOOL_UNDO));
146
		undoAction.setHoverImageDescriptor(WorkbenchImages.getImageDescriptor(ISharedImages.IMG_TOOL_UNDO));
147
		undoAction.setDisabledImageDescriptor(WorkbenchImages.getImageDescriptor(ISharedImages.IMG_TOOL_UNDO_DISABLED));
148
		undoAction.setActionDefinitionId(UNDO);
149
150
		redoAction = new GlobalAction(ActionFactory.REDO.getId());
151
		redoAction.setText(WorkbenchMessages.Workbench_redo);
152
		redoAction.setImageDescriptor(WorkbenchImages.getImageDescriptor(ISharedImages.IMG_TOOL_REDO));
153
		redoAction.setHoverImageDescriptor(WorkbenchImages.getImageDescriptor(ISharedImages.IMG_TOOL_REDO));
154
		redoAction.setDisabledImageDescriptor(WorkbenchImages.getImageDescriptor(ISharedImages.IMG_TOOL_REDO_DISABLED));
155
		redoAction.setActionDefinitionId(REDO);
156
157
		selectAllAction = new GlobalAction(ActionFactory.SELECT_ALL.getId());
158
		selectAllAction.setText(WorkbenchMessages.Workbench_selectAll);
159
		selectAllAction.setActionDefinitionId(SELECT_ALL);
160
		selectAllAction.setEnabled(true);
161
162
		findAction = new GlobalAction(ActionFactory.FIND.getId());
163
		findAction.setText(WorkbenchMessages.Workbench_findReplace);
164
		findAction.setImageDescriptor(CommonImages.FIND);
165
		findAction.setActionDefinitionId(FIND_REPLACE);
166
	}
167
168
	public void contributeActions(IMenuManager manager) {
169
		manager.add(undoAction);
170
		manager.add(redoAction);
171
		manager.add(new Separator());
172
		manager.add(cutAction);
173
		manager.add(copyAction);
174
		manager.add(pasteAction);
175
		manager.add(selectAllAction);
176
		manager.add(new Separator());
177
	}
178
179
	public void forceActionsEnabled() {
180
		cutAction.setEnabled(true);
181
		copyAction.setEnabled(true);
182
		pasteAction.setEnabled(true);
183
		selectAllAction.setEnabled(true);
184
		undoAction.setEnabled(false);
185
		redoAction.setEnabled(false);
186
	}
187
188
	public Action getCopyAction() {
189
		return copyAction;
190
	}
191
192
	public Action getCutAction() {
193
		return cutAction;
194
	}
195
196
	public Action getFindAction() {
197
		return findAction;
198
	}
199
200
	public Action getPasteAction() {
201
		return pasteAction;
202
	}
203
204
	public Action getRedoAction() {
205
		return redoAction;
206
	}
207
208
	public Action getSelectAllAction() {
209
		return selectAllAction;
210
	}
211
212
	public Action getUndoAction() {
213
		return undoAction;
214
	}
215
216
	public void install(IActionBars bars) {
217
		bars.setGlobalActionHandler(ActionFactory.CUT.getId(), cutAction);
218
		bars.setGlobalActionHandler(ActionFactory.PASTE.getId(), pasteAction);
219
		bars.setGlobalActionHandler(ActionFactory.COPY.getId(), copyAction);
220
		bars.setGlobalActionHandler(ActionFactory.UNDO.getId(), undoAction);
221
		bars.setGlobalActionHandler(ActionFactory.REDO.getId(), redoAction);
222
		bars.setGlobalActionHandler(ActionFactory.SELECT_ALL.getId(), selectAllAction);
223
		bars.setGlobalActionHandler(ActionFactory.FIND.getId(), findAction);
224
		bars.updateActionBars();
225
	}
226
227
	public void selectionChanged(SelectionChangedEvent event) {
228
		ISelection selection = event.getSelection();
229
		if (selection instanceof TextSelection) {
230
			// only update global actions
231
			updateActions(event.getSelection());
232
		} else if (selection.isEmpty()) {
233
			// XXX a styled text widget has lost focus, re-enable all edit actions
234
			forceActionsEnabled();
235
		}
236
	}
237
238
	public void uninstall(IActionBars bars) {
239
		bars.setGlobalActionHandler(ActionFactory.CUT.getId(), null);
240
		bars.setGlobalActionHandler(ActionFactory.PASTE.getId(), null);
241
		bars.setGlobalActionHandler(ActionFactory.COPY.getId(), null);
242
		bars.setGlobalActionHandler(ActionFactory.UNDO.getId(), null);
243
		bars.setGlobalActionHandler(ActionFactory.REDO.getId(), null);
244
		bars.setGlobalActionHandler(ActionFactory.SELECT_ALL.getId(), null);
245
		bars.setGlobalActionHandler(ActionFactory.FIND.getId(), null);
246
		bars.updateActionBars();
247
	}
248
249
	public void updateActions(ISelection selection) {
250
		cutAction.selectionChanged(selection);
251
		copyAction.selectionChanged(selection);
252
		pasteAction.selectionChanged(selection);
253
		undoAction.selectionChanged(selection);
254
		redoAction.selectionChanged(selection);
255
		selectAllAction.selectionChanged(selection);
256
		findAction.selectionChanged(selection);
257
	}
258
259
	public void setCallback(WorkbenchActionCallback callback) {
260
		this.callback = callback;
261
	}
262
263
	public WorkbenchActionCallback getCallback() {
264
		return callback;
265
	}
266
267
}
(-)src/org/eclipse/mylyn/internal/commons/ui/CommonTextSupport.java (+307 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2004, 2008 Tasktop Technologies and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     Tasktop Technologies - initial API and implementation
10
 *******************************************************************************/
11
12
package org.eclipse.mylyn.internal.commons.ui;
13
14
import java.util.Iterator;
15
16
import org.eclipse.core.commands.IHandler;
17
import org.eclipse.jface.action.Action;
18
import org.eclipse.jface.commands.ActionHandler;
19
import org.eclipse.jface.text.Document;
20
import org.eclipse.jface.text.ITextListener;
21
import org.eclipse.jface.text.ITextOperationTarget;
22
import org.eclipse.jface.text.TextEvent;
23
import org.eclipse.jface.text.TextViewer;
24
import org.eclipse.jface.text.source.AnnotationModel;
25
import org.eclipse.jface.text.source.IAnnotationAccess;
26
import org.eclipse.jface.text.source.ISourceViewer;
27
import org.eclipse.jface.viewers.ISelectionChangedListener;
28
import org.eclipse.jface.viewers.SelectionChangedEvent;
29
import org.eclipse.jface.viewers.StructuredSelection;
30
import org.eclipse.swt.custom.StyledText;
31
import org.eclipse.swt.events.DisposeEvent;
32
import org.eclipse.swt.events.DisposeListener;
33
import org.eclipse.swt.events.FocusEvent;
34
import org.eclipse.swt.events.FocusListener;
35
import org.eclipse.swt.widgets.Control;
36
import org.eclipse.swt.widgets.Text;
37
import org.eclipse.swt.widgets.Widget;
38
import org.eclipse.ui.ActiveShellExpression;
39
import org.eclipse.ui.actions.ActionFactory;
40
import org.eclipse.ui.editors.text.EditorsUI;
41
import org.eclipse.ui.handlers.IHandlerActivation;
42
import org.eclipse.ui.handlers.IHandlerService;
43
import org.eclipse.ui.texteditor.AnnotationPreference;
44
import org.eclipse.ui.texteditor.DefaultMarkerAnnotationAccess;
45
import org.eclipse.ui.texteditor.MarkerAnnotationPreferences;
46
import org.eclipse.ui.texteditor.SourceViewerDecorationSupport;
47
48
/**
49
 * @author Steffen Pingel
50
 */
51
public class CommonTextSupport {
52
53
	private class TextViewerFocusListener implements FocusListener {
54
55
		private final boolean spellCheck;
56
57
		private final TextViewer viewer;
58
59
		public TextViewerFocusListener(TextViewer viewer, boolean spellCheck) {
60
			this.viewer = viewer;
61
			this.spellCheck = spellCheck;
62
		}
63
64
		public void focusGained(FocusEvent e) {
65
			if (selectionChangedListener != null) {
66
				selectionChangedListener.selectionChanged(new SelectionChangedEvent(viewer, viewer.getSelection()));
67
			}
68
			activateHandlers(viewer, spellCheck);
69
		}
70
71
		public void focusLost(FocusEvent e) {
72
			deactivateHandlers();
73
			if (selectionChangedListener != null) {
74
				// make sure selection no text is selected when control looses focus
75
				StyledText st = (StyledText) e.widget;
76
				st.setSelectionRange(st.getCaretOffset(), 0);
77
				// update action enablement
78
				selectionChangedListener.selectionChanged(new SelectionChangedEvent(viewer, StructuredSelection.EMPTY));
79
			}
80
		}
81
82
	}
83
84
	private static String CONTENT_ASSIST_PROPOSALS = "org.eclipse.ui.edit.text.contentAssist.proposals"; //$NON-NLS-1$
85
86
	private static final String KEY_TEXT_VIEWER = "textViewer"; //$NON-NLS-1$
87
88
	private static final String QUICK_ASSIST = "org.eclipse.jdt.ui.edit.text.java.correction.assist.proposals"; //$NON-NLS-1$
89
90
	static boolean canDoGlobalAction(String actionId, TextViewer textViewer) {
91
		if (actionId.equals(ActionFactory.CUT.getId())) {
92
			return textViewer.canDoOperation(ITextOperationTarget.CUT);
93
		} else if (actionId.equals(ActionFactory.COPY.getId())) {
94
			return textViewer.canDoOperation(ITextOperationTarget.COPY);
95
		} else if (actionId.equals(ActionFactory.PASTE.getId())) {
96
			return textViewer.canDoOperation(ITextOperationTarget.PASTE);
97
		} else if (actionId.equals(ActionFactory.DELETE.getId())) {
98
			return textViewer.canDoOperation(ITextOperationTarget.DELETE);
99
		} else if (actionId.equals(ActionFactory.UNDO.getId())) {
100
			return textViewer.canDoOperation(ITextOperationTarget.UNDO);
101
		} else if (actionId.equals(ActionFactory.REDO.getId())) {
102
			return textViewer.canDoOperation(ITextOperationTarget.REDO);
103
		} else if (actionId.equals(ActionFactory.SELECT_ALL.getId())) {
104
			return textViewer.canDoOperation(ITextOperationTarget.SELECT_ALL);
105
		}
106
		return false;
107
	}
108
109
	public static boolean canPerformAction(String actionId, Control focusControl) {
110
		TextViewer viewer = getTextViewer(focusControl);
111
		if (viewer != null) {
112
			return canDoGlobalAction(actionId, viewer);
113
		}
114
		if (actionId.equals(ActionFactory.UNDO.getId()) || actionId.equals(ActionFactory.REDO.getId())) {
115
			return false;
116
		}
117
		return true;
118
	}
119
120
	private static boolean canPerformDirectly(String id, Control control) {
121
		if (control instanceof Text) {
122
			Text text = (Text) control;
123
			if (id.equals(ActionFactory.CUT.getId())) {
124
				text.cut();
125
				return true;
126
			}
127
			if (id.equals(ActionFactory.COPY.getId())) {
128
				text.copy();
129
				return true;
130
			}
131
			if (id.equals(ActionFactory.PASTE.getId())) {
132
				text.paste();
133
				return true;
134
			}
135
			if (id.equals(ActionFactory.SELECT_ALL.getId())) {
136
				text.selectAll();
137
				return true;
138
			}
139
			if (id.equals(ActionFactory.DELETE.getId())) {
140
				int count = text.getSelectionCount();
141
				if (count == 0) {
142
					int caretPos = text.getCaretPosition();
143
					text.setSelection(caretPos, caretPos + 1);
144
				}
145
				text.insert(""); //$NON-NLS-1$
146
				return true;
147
			}
148
		}
149
		return false;
150
	}
151
152
	public static void doAction(String actionId, Control focusControl) {
153
		if (canPerformDirectly(actionId, focusControl)) {
154
			return;
155
		}
156
		TextViewer viewer = getTextViewer(focusControl);
157
		if (viewer != null) {
158
			doGlobalAction(actionId, viewer);
159
		}
160
	}
161
162
	private static boolean doGlobalAction(String actionId, TextViewer textViewer) {
163
		if (actionId.equals(ActionFactory.CUT.getId())) {
164
			textViewer.doOperation(ITextOperationTarget.CUT);
165
			return true;
166
		} else if (actionId.equals(ActionFactory.COPY.getId())) {
167
			textViewer.doOperation(ITextOperationTarget.COPY);
168
			return true;
169
		} else if (actionId.equals(ActionFactory.PASTE.getId())) {
170
			textViewer.doOperation(ITextOperationTarget.PASTE);
171
			return true;
172
		} else if (actionId.equals(ActionFactory.DELETE.getId())) {
173
			textViewer.doOperation(ITextOperationTarget.DELETE);
174
			return true;
175
		} else if (actionId.equals(ActionFactory.UNDO.getId())) {
176
			textViewer.doOperation(ITextOperationTarget.UNDO);
177
			return true;
178
		} else if (actionId.equals(ActionFactory.REDO.getId())) {
179
			textViewer.doOperation(ITextOperationTarget.REDO);
180
			return true;
181
		} else if (actionId.equals(ActionFactory.SELECT_ALL.getId())) {
182
			textViewer.doOperation(ITextOperationTarget.SELECT_ALL);
183
			return true;
184
		}
185
		return false;
186
	}
187
188
	public static TextViewer getTextViewer(Widget widget) {
189
		if (widget instanceof StyledText) {
190
			Object data = widget.getData(KEY_TEXT_VIEWER);
191
			if (data instanceof TextViewer) {
192
				return (TextViewer) data;
193
			}
194
		}
195
		return null;
196
	}
197
198
	public static void setTextViewer(Widget widget, TextViewer textViewer) {
199
		widget.setData(KEY_TEXT_VIEWER, textViewer);
200
	}
201
202
	public IHandlerActivation contentAssistHandlerActivation;
203
204
	private final IHandlerService handlerService;
205
206
	private IHandlerActivation quickAssistHandlerActivation;
207
208
	private ISelectionChangedListener selectionChangedListener;
209
210
	public CommonTextSupport(IHandlerService handlerService) {
211
		this.handlerService = handlerService;
212
	}
213
214
	private IHandlerActivation activateHandler(TextViewer viewer, int operation, String actionDefinitionId) {
215
		IHandler handler = createActionHandler(viewer, operation, actionDefinitionId);
216
		return handlerService.activateHandler(actionDefinitionId, handler, //
217
				new ActiveShellExpression(viewer.getTextWidget().getShell()));
218
	}
219
220
	private void activateHandlers(TextViewer viewer, boolean spellCheck) {
221
		deactivateHandlers();
222
		if (spellCheck) {
223
			quickAssistHandlerActivation = activateHandler(viewer, ISourceViewer.QUICK_ASSIST, QUICK_ASSIST);
224
		}
225
		contentAssistHandlerActivation = activateHandler(viewer, ISourceViewer.CONTENTASSIST_PROPOSALS,
226
				CONTENT_ASSIST_PROPOSALS);
227
228
	}
229
230
	private IHandler createActionHandler(final ITextOperationTarget viewer, final int operation,
231
			String actionDefinitionId) {
232
		Action action = new Action() {
233
			@Override
234
			public void run() {
235
				if (viewer.canDoOperation(operation)) {
236
					viewer.doOperation(operation);
237
				}
238
			}
239
		};
240
		action.setActionDefinitionId(actionDefinitionId);
241
		return new ActionHandler(action);
242
	}
243
244
	private void deactivateHandlers() {
245
		if (quickAssistHandlerActivation != null) {
246
			handlerService.deactivateHandler(quickAssistHandlerActivation);
247
			quickAssistHandlerActivation = null;
248
		}
249
		if (contentAssistHandlerActivation != null) {
250
			handlerService.deactivateHandler(contentAssistHandlerActivation);
251
			contentAssistHandlerActivation = null;
252
		}
253
	}
254
255
	/** Configures annotation model for spell checking. */
256
	private void configureAsEditor(ISourceViewer viewer, Document document) {
257
		IAnnotationAccess annotationAccess = new DefaultMarkerAnnotationAccess();
258
		final SourceViewerDecorationSupport support = new SourceViewerDecorationSupport(viewer, null, annotationAccess,
259
				EditorsUI.getSharedTextColors());
260
		Iterator<?> e = new MarkerAnnotationPreferences().getAnnotationPreferences().iterator();
261
		while (e.hasNext()) {
262
			support.setAnnotationPreference((AnnotationPreference) e.next());
263
		}
264
		support.install(EditorsUI.getPreferenceStore());
265
		viewer.getTextWidget().addDisposeListener(new DisposeListener() {
266
			public void widgetDisposed(DisposeEvent e) {
267
				support.uninstall();
268
			}
269
		});
270
		AnnotationModel annotationModel = new AnnotationModel();
271
		viewer.setDocument(document, annotationModel);
272
	}
273
274
	public void configure(final TextViewer viewer, Document document, boolean spellCheck) {
275
		if (spellCheck && viewer instanceof ISourceViewer) {
276
			configureAsEditor((ISourceViewer) viewer, document);
277
		} else {
278
			viewer.setDocument(document);
279
		}
280
		install(viewer, spellCheck);
281
	}
282
283
	public void install(final TextViewer viewer, boolean spellCheck) {
284
		viewer.getControl().addFocusListener(new TextViewerFocusListener(viewer, spellCheck));
285
		if (selectionChangedListener != null) {
286
			viewer.addSelectionChangedListener(selectionChangedListener);
287
			viewer.addTextListener(new ITextListener() {
288
				public void textChanged(TextEvent event) {
289
					if (selectionChangedListener != null) {
290
						selectionChangedListener.selectionChanged(new SelectionChangedEvent(viewer,
291
								viewer.getSelection()));
292
					}
293
				}
294
			});
295
		}
296
		setTextViewer(viewer.getControl(), viewer);
297
	}
298
299
	public void setSelectionChangedListener(ISelectionChangedListener selectionChangedListener) {
300
		this.selectionChangedListener = selectionChangedListener;
301
	}
302
303
	public ISelectionChangedListener getSelectionChangedListener() {
304
		return selectionChangedListener;
305
	}
306
307
}

Return to bug 234044