### Eclipse Workspace Patch 1.0 #P org.eclipse.mylyn.tasks.ui Index: src/org/eclipse/mylyn/tasks/ui/wizards/TaskAttachmentPage.java =================================================================== RCS file: /cvsroot/tools/org.eclipse.mylyn/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/tasks/ui/wizards/TaskAttachmentPage.java,v retrieving revision 1.15 diff -u -r1.15 TaskAttachmentPage.java --- src/org/eclipse/mylyn/tasks/ui/wizards/TaskAttachmentPage.java 13 Sep 2008 03:28:17 -0000 1.15 +++ src/org/eclipse/mylyn/tasks/ui/wizards/TaskAttachmentPage.java 20 Oct 2008 15:59:22 -0000 @@ -16,14 +16,32 @@ import java.util.LinkedList; import java.util.List; +import org.eclipse.jface.text.Document; +import org.eclipse.jface.text.ITextListener; +import org.eclipse.jface.text.TextEvent; +import org.eclipse.jface.text.source.AnnotationModel; +import org.eclipse.jface.text.source.IAnnotationAccess; +import org.eclipse.jface.text.source.SourceViewer; import org.eclipse.jface.wizard.WizardPage; import org.eclipse.mylyn.context.core.ContextCore; import org.eclipse.mylyn.internal.provisional.commons.ui.CommonImages; import org.eclipse.mylyn.internal.tasks.core.data.FileTaskAttachmentSource; +import org.eclipse.mylyn.internal.tasks.ui.editors.AbstractHyperlinkTextPresentationManager; +import org.eclipse.mylyn.internal.tasks.ui.editors.EditorUtil; +import org.eclipse.mylyn.internal.tasks.ui.editors.HighlightingHyperlinkTextPresentationManager; +import org.eclipse.mylyn.internal.tasks.ui.editors.RepositoryTextViewer; +import org.eclipse.mylyn.internal.tasks.ui.editors.RepositoryTextViewerConfiguration; +import org.eclipse.mylyn.internal.tasks.ui.editors.TaskEditorExtensions; +import org.eclipse.mylyn.internal.tasks.ui.editors.TaskHyperlinkTextPresentationManager; +import org.eclipse.mylyn.internal.tasks.ui.editors.RepositoryTextViewerConfiguration.Mode; +import org.eclipse.mylyn.tasks.core.TaskRepository; import org.eclipse.mylyn.tasks.core.data.TaskAttachmentMapper; import org.eclipse.mylyn.tasks.core.data.TaskAttachmentModel; import org.eclipse.mylyn.tasks.ui.TasksUiImages; +import org.eclipse.mylyn.tasks.ui.editors.AbstractTaskEditorExtension; import org.eclipse.swt.SWT; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; import org.eclipse.swt.events.ModifyEvent; import org.eclipse.swt.events.ModifyListener; import org.eclipse.swt.events.SelectionAdapter; @@ -36,6 +54,14 @@ import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Text; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.contexts.IContextActivation; +import org.eclipse.ui.contexts.IContextService; +import org.eclipse.ui.editors.text.EditorsUI; +import org.eclipse.ui.texteditor.AnnotationPreference; +import org.eclipse.ui.texteditor.DefaultMarkerAnnotationAccess; +import org.eclipse.ui.texteditor.MarkerAnnotationPreferences; +import org.eclipse.ui.texteditor.SourceViewerDecorationSupport; /** * A wizard page to enter details of a new attachment. @@ -43,6 +69,7 @@ * @author Jeff Pound * @author Mik Kersten * @author Steffen Pingel + * @author David Green task editor extension integration * @since 3.0 */ public class TaskAttachmentPage extends WizardPage { @@ -62,7 +89,7 @@ private Button attachContextButton; - private Text commentText; + private SourceViewer comment; private Text descriptionText; @@ -80,6 +107,10 @@ private boolean first = true; + private IContextActivation commentContext; + + private IContextService contextService; + public TaskAttachmentPage(TaskAttachmentModel model) { super("AttachmentDetails"); this.model = model; @@ -118,14 +149,31 @@ Label label = new Label(composite, SWT.NONE); label.setLayoutData(new GridData(SWT.LEFT, SWT.FILL, false, false)); label.setText("Comment"); - commentText = new Text(composite, SWT.V_SCROLL | SWT.BORDER | SWT.WRAP); - commentText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1)); - commentText.addModifyListener(new ModifyListener() { - public void modifyText(ModifyEvent e) { + + AbstractTaskEditorExtension extension = TaskEditorExtensions.getTaskEditorExtension(model.getTaskRepository()); + if (extension != null) { + // TODO: stack layout with preview + comment = extension.createEditor(model.getTaskRepository(), composite, SWT.V_SCROLL | SWT.MULTI + | SWT.BORDER); + String contextId = extension.getEditorContextId(); + if (contextId != null) { + // FIXME: keybindings don't work. How do we use commands with a dialog/wizard? + // related: http://dev.eclipse.org/newslists/news.eclipse.platform.rcp/msg14539.html + contextService = (IContextService) PlatformUI.getWorkbench().getService(IContextService.class); + if (contextService != null) { + commentContext = contextService.activateContext(contextId); + } + } + } else { + comment = createDefaultEditor(composite, SWT.V_SCROLL | SWT.MULTI | SWT.BORDER); + } + configure(comment); + comment.addTextListener(new ITextListener() { + public void textChanged(TextEvent event) { apply(); } - }); + comment.getControl().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1)); new Label(composite, SWT.NONE).setText("Content Type");// .setBackground(parent.getBackground()); @@ -219,10 +267,75 @@ if (descriptionText != null) { descriptionText.setFocus(); } else { - commentText.setFocus(); + comment.getTextWidget().setFocus(); } } + private RepositoryTextViewerConfiguration installHyperlinkPresenter(SourceViewer viewer) { + RepositoryTextViewerConfiguration configuration = new RepositoryTextViewerConfiguration( + model.getTaskRepository(), false); + configuration.setMode(Mode.DEFAULT); + + // do not configure viewer, this has already been done in extension + + AbstractHyperlinkTextPresentationManager manager; + + manager = new HighlightingHyperlinkTextPresentationManager(); + manager.setHyperlinkDetectors(configuration.getDefaultHyperlinkDetectors(viewer, null)); + manager.install(viewer); + + manager = new TaskHyperlinkTextPresentationManager(); + manager.setHyperlinkDetectors(configuration.getDefaultHyperlinkDetectors(viewer, Mode.TASK)); + manager.install(viewer); + + return configuration; + } + + private SourceViewer configure(final SourceViewer viewer) { + // do this before setting the document to not require invalidating the presentation + installHyperlinkPresenter(viewer); + + configureAsEditor(viewer, new Document()); + + // enable cut/copy/paste + EditorUtil.setTextViewer(viewer.getTextWidget(), viewer); + viewer.setEditable(true); + + return viewer; + } + + private void configureAsEditor(SourceViewer viewer, Document document) { + AnnotationModel annotationModel = new AnnotationModel(); + viewer.showAnnotations(false); + viewer.showAnnotationsOverview(false); + IAnnotationAccess annotationAccess = new DefaultMarkerAnnotationAccess(); + final SourceViewerDecorationSupport support = new SourceViewerDecorationSupport(viewer, null, annotationAccess, + EditorsUI.getSharedTextColors()); + Iterator e = new MarkerAnnotationPreferences().getAnnotationPreferences().iterator(); + while (e.hasNext()) { + support.setAnnotationPreference((AnnotationPreference) e.next()); + } + support.install(EditorsUI.getPreferenceStore()); + viewer.getTextWidget().addDisposeListener(new DisposeListener() { + public void widgetDisposed(DisposeEvent e) { + support.uninstall(); + } + }); + //viewer.getTextWidget().setIndent(2); + viewer.setDocument(document, annotationModel); + } + + private SourceViewer createDefaultEditor(Composite parent, int styles) { + TaskRepository taskRepository = model.getTaskRepository(); + SourceViewer defaultEditor = new RepositoryTextViewer(taskRepository, parent, styles | SWT.WRAP); + + RepositoryTextViewerConfiguration viewerConfig = new RepositoryTextViewerConfiguration(taskRepository, true); + viewerConfig.setMode(Mode.DEFAULT); + defaultEditor.configure(viewerConfig); + + return defaultEditor; + } + private void validate() { apply(); if (fileNameText != null && "".equals(fileNameText.getText().trim())) { @@ -243,7 +356,7 @@ private void apply() { taskAttachment.applyTo(model.getAttribute()); - model.setComment(commentText.getText()); + model.setComment(comment.getDocument().get()); model.setAttachContext(attachContextButton.getSelection()); model.setContentType(taskAttachment.getContentType()); } @@ -298,10 +411,22 @@ if (descriptionText != null) { descriptionText.setFocus(); } else { - commentText.setFocus(); + comment.getTextWidget().setFocus(); } first = false; } } + @Override + public void dispose() { + deactivateCommentContext(); + super.dispose(); + } + + private void deactivateCommentContext() { + if (contextService != null && commentContext != null) { + contextService.deactivateContext(commentContext); + commentContext = null; + } + } }