### Eclipse Workspace Patch 1.0 #P org.eclipse.ui.editors Index: src/org/eclipse/ui/editors/text/TextSourceViewerConfiguration.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.ui.editors/src/org/eclipse/ui/editors/text/TextSourceViewerConfiguration.java,v retrieving revision 1.40 diff -u -r1.40 TextSourceViewerConfiguration.java --- src/org/eclipse/ui/editors/text/TextSourceViewerConfiguration.java 18 Dec 2007 10:20:07 -0000 1.40 +++ src/org/eclipse/ui/editors/text/TextSourceViewerConfiguration.java 18 Feb 2008 16:43:05 -0000 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2007 IBM Corporation and others. + * Copyright (c) 2000, 2008 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -16,16 +16,11 @@ import java.util.StringTokenizer; import java.util.Map.Entry; -import org.eclipse.swt.SWT; -import org.eclipse.swt.widgets.Shell; - import org.eclipse.core.runtime.Assert; import org.eclipse.core.runtime.IAdaptable; - import org.eclipse.jface.action.Action; import org.eclipse.jface.internal.text.html.HTMLTextPresenter; import org.eclipse.jface.preference.IPreferenceStore; - import org.eclipse.jface.text.DefaultInformationControl; import org.eclipse.jface.text.DefaultTextHover; import org.eclipse.jface.text.IInformationControl; @@ -35,9 +30,9 @@ import org.eclipse.jface.text.ITextViewerExtension2; import org.eclipse.jface.text.IUndoManager; import org.eclipse.jface.text.TextViewerUndoManager; -import org.eclipse.jface.text.hyperlink.DefaultHyperlinkPresenter; import org.eclipse.jface.text.hyperlink.IHyperlinkDetector; import org.eclipse.jface.text.hyperlink.IHyperlinkPresenter; +import org.eclipse.jface.text.hyperlink.MultipleHyperlinkPresenter; import org.eclipse.jface.text.quickassist.IQuickAssistAssistant; import org.eclipse.jface.text.quickassist.QuickAssistAssistant; import org.eclipse.jface.text.reconciler.IReconciler; @@ -48,7 +43,9 @@ import org.eclipse.jface.text.source.IAnnotationHover; import org.eclipse.jface.text.source.ISourceViewer; import org.eclipse.jface.text.source.SourceViewerConfiguration; - +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.RGB; +import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.texteditor.AbstractDecoratedTextEditorPreferenceConstants; import org.eclipse.ui.texteditor.AnnotationPreference; import org.eclipse.ui.texteditor.HyperlinkDetectorRegistry; @@ -300,9 +297,9 @@ */ public IHyperlinkPresenter getHyperlinkPresenter(ISourceViewer sourceViewer) { if (fPreferenceStore == null) - return super.getHyperlinkPresenter(sourceViewer); + return new MultipleHyperlinkPresenter(new RGB(0, 0, 255), sourceViewer); - return new DefaultHyperlinkPresenter(fPreferenceStore); + return new MultipleHyperlinkPresenter(fPreferenceStore, sourceViewer); } /** #P org.eclipse.jface.text Index: src/org/eclipse/jface/text/TextViewer.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jface.text/src/org/eclipse/jface/text/TextViewer.java,v retrieving revision 1.191 diff -u -r1.191 TextViewer.java --- src/org/eclipse/jface/text/TextViewer.java 4 Feb 2008 11:24:10 -0000 1.191 +++ src/org/eclipse/jface/text/TextViewer.java 18 Feb 2008 16:43:07 -0000 @@ -20,8 +20,6 @@ import java.util.Set; import java.util.regex.PatternSyntaxException; -import org.eclipse.core.runtime.Assert; - import org.eclipse.swt.SWT; import org.eclipse.swt.custom.LineBackgroundEvent; import org.eclipse.swt.custom.LineBackgroundListener; @@ -61,13 +59,9 @@ import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.ScrollBar; +import org.eclipse.core.runtime.Assert; + import org.eclipse.jface.internal.text.NonDeletingPositionUpdater; -import org.eclipse.jface.text.hyperlink.HyperlinkManager; -import org.eclipse.jface.text.hyperlink.IHyperlinkDetector; -import org.eclipse.jface.text.hyperlink.IHyperlinkDetectorExtension; -import org.eclipse.jface.text.hyperlink.IHyperlinkPresenter; -import org.eclipse.jface.text.projection.ChildDocument; -import org.eclipse.jface.text.projection.ChildDocumentManager; import org.eclipse.jface.viewers.IPostSelectionProvider; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.ISelectionChangedListener; @@ -75,6 +69,14 @@ import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.text.hyperlink.HyperlinkManager; +import org.eclipse.jface.text.hyperlink.IHyperlinkDetector; +import org.eclipse.jface.text.hyperlink.IHyperlinkDetectorExtension; +import org.eclipse.jface.text.hyperlink.IHyperlinkPresenter; +import org.eclipse.jface.text.hyperlink.HyperlinkManager.DETECTION_STRATEGY; +import org.eclipse.jface.text.projection.ChildDocument; +import org.eclipse.jface.text.projection.ChildDocumentManager; + /** * SWT based implementation of {@link ITextViewer} and its extension interfaces. @@ -5366,7 +5368,8 @@ */ private void ensureHyperlinkManagerInstalled() { if (fHyperlinkDetectors != null && fHyperlinkDetectors.length > 0 && fHyperlinkPresenter != null && fHyperlinkManager == null) { - fHyperlinkManager= new HyperlinkManager(HyperlinkManager.FIRST); + DETECTION_STRATEGY strategy= fHyperlinkPresenter.canShowMultipleHyperlinks() ? HyperlinkManager.ALL : HyperlinkManager.FIRST; + fHyperlinkManager= new HyperlinkManager(strategy); fHyperlinkManager.install(this, fHyperlinkPresenter, fHyperlinkDetectors, fHyperlinkStateMask); } } Index: src/org/eclipse/jface/text/hyperlink/MultipleHyperlinkPresenter.java =================================================================== RCS file: src/org/eclipse/jface/text/hyperlink/MultipleHyperlinkPresenter.java diff -N src/org/eclipse/jface/text/hyperlink/MultipleHyperlinkPresenter.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/org/eclipse/jface/text/hyperlink/MultipleHyperlinkPresenter.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,269 @@ +/******************************************************************************* + * Copyright (c) 2007, 2008 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jface.text.hyperlink; + +import com.ibm.icu.text.MessageFormat; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.RGB; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Link; +import org.eclipse.swt.widgets.Shell; + +import org.eclipse.jface.preference.IPreferenceStore; + +import org.eclipse.jface.text.AbstractInformationControl; +import org.eclipse.jface.text.IInformationControl; +import org.eclipse.jface.text.IInformationControlCreator; +import org.eclipse.jface.text.IInformationControlExtension2; +import org.eclipse.jface.text.IRegion; +import org.eclipse.jface.text.ITextViewer; +import org.eclipse.jface.text.Region; +import org.eclipse.jface.text.information.IInformationProvider; +import org.eclipse.jface.text.information.IInformationProviderExtension; +import org.eclipse.jface.text.information.IInformationProviderExtension2; +import org.eclipse.jface.text.information.InformationPresenter; + + +/** + * A hyperlink presenter capable of showing multiple hyperlinks in a information pop up. + * + * @since 3.4 + */ +public class MultipleHyperlinkPresenter extends DefaultHyperlinkPresenter { + + /** + * An information control capable of showing a list of links. The links can be opened. + */ + private static class LinkListInformationControl extends AbstractInformationControl implements IInformationControlExtension2 { + + private IHyperlink[] fInput; + private Composite fParent; + + /** + * Creates a link list information control with the given shell as parent. + * + * @param parentShell the parent shell + * @param shellStyle the additional styles for the shell + * @param statusFieldText the text to be used in the optional status field + * or null if the status field should be hidden + */ + public LinkListInformationControl(Shell parentShell, int shellStyle, String statusFieldText) { + super(parentShell, shellStyle, statusFieldText); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.text.IInformationControlExtension2#setInput(java.lang.Object) + */ + public void setInput(Object input) { + fInput= (IHyperlink[])input; + deferredCreateContent(fParent); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.text.AbstractInformationControl#createContent(org.eclipse.swt.widgets.Composite) + */ + protected void createContent(Composite parent) { + fParent= parent; + } + + private void deferredCreateContent(Composite parent) { + for (int i= 0; i < fInput.length; i++) { + final IHyperlink link= fInput[i]; + + Link linkControl= new Link(parent, SWT.NONE); + linkControl.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, false, false)); + + String text= link.getHyperlinkText(); + if (text == null) + text= HyperlinkMessages.getString("LinkListInformationControl.unknownLink"); //$NON-NLS-1$ + + if (i == 0) { + text= MessageFormat.format(HyperlinkMessages.getString("LinkListInformationControl.defaultLinkPattern"), new Object[] { text }); //$NON-NLS-1$ + } + + linkControl.setText("" + text + ""); //$NON-NLS-1$ //$NON-NLS-2$ + linkControl.setBackground(parent.getBackground()); + linkControl.setForeground(parent.getForeground()); + + linkControl.addSelectionListener(new SelectionAdapter() { + /* (non-Javadoc) + * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent) + */ + public void widgetSelected(SelectionEvent e) { + LinkListInformationControl.this.dispose(); + link.open(); + } + }); + + } + } + } + + private class MultipleHyperlinkInformationProvider implements IInformationProvider, IInformationProviderExtension, IInformationProviderExtension2 { + + /** + * @see org.eclipse.jface.text.information.IInformationProvider#getInformation(org.eclipse.jface.text.ITextViewer, org.eclipse.jface.text.IRegion) + * @deprecated + */ + public String getInformation(ITextViewer textViewer, IRegion subject) { + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.text.information.IInformationProvider#getSubject(org.eclipse.jface.text.ITextViewer, int) + */ + public IRegion getSubject(ITextViewer textViewer, int offset) { + return fSubjectRegion; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.text.information.IInformationProviderExtension#getInformation2(org.eclipse.jface.text.ITextViewer, org.eclipse.jface.text.IRegion) + */ + public Object getInformation2(ITextViewer textViewer, IRegion subject) { + return fHyperlinks; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.text.information.IInformationProviderExtension2#getInformationPresenterControlCreator() + */ + public IInformationControlCreator getInformationPresenterControlCreator() { + return new IInformationControlCreator() { + public IInformationControl createInformationControl(Shell parent) { + return new LinkListInformationControl(parent, (SWT.RESIZE | SWT.TOOL), HyperlinkMessages.getString("MultipleHyperlinkPresenter.clickLinkAfordance")); //$NON-NLS-1$ + } + }; + } + } + + private final ITextViewer fTextViewer; + private final InformationPresenter fPresenter; + + private IHyperlink[] fHyperlinks; + private Region fSubjectRegion; + + /** + * Creates a new multiple hyperlink presenter which uses + * {@link #HYPERLINK_COLOR} to read the color from the given preference store. + * + * @param store the preference store + * @param viewer the viewer in which to present the hyperlinks + */ + public MultipleHyperlinkPresenter(IPreferenceStore store, ITextViewer viewer) { + super(store); + + fTextViewer= viewer; + fPresenter= createInformationPresenter(); + fPresenter.install(fTextViewer); + } + + /** + * Creates a new multiple hyperlink presenter. + * + * @param color the hyperlink color, to be disposed by the caller + * @param viewer the viewer in which to present the hyperlinks + */ + public MultipleHyperlinkPresenter(RGB color, ITextViewer viewer) { + super(color); + + fTextViewer= viewer; + fPresenter= createInformationPresenter(); + fPresenter.install(fTextViewer); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.text.hyperlink.DefaultHyperlinkPresenter#canShowMultipleHyperlinks() + */ + public boolean canShowMultipleHyperlinks() { + return true; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.text.hyperlink.DefaultHyperlinkPresenter#hideHyperlinks() + */ + public void hideHyperlinks() { + super.hideHyperlinks(); + + fHyperlinks= null; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.text.hyperlink.DefaultHyperlinkPresenter#showHyperlinks(org.eclipse.jface.text.hyperlink.IHyperlink[]) + */ + public void showHyperlinks(final IHyperlink[] hyperlinks) { + super.showHyperlinks(new IHyperlink[] { hyperlinks[0] }); + + if (equals(fHyperlinks, hyperlinks)) + return; + + fHyperlinks= hyperlinks; + fPresenter.disposeInformationControl(); + + if (hyperlinks.length == 1) + return; + + int start= hyperlinks[0].getHyperlinkRegion().getOffset(); + int end= start + hyperlinks[0].getHyperlinkRegion().getLength(); + + for (int i= 1; i < hyperlinks.length; i++) { + int hstart= hyperlinks[i].getHyperlinkRegion().getOffset(); + int hend= hstart + hyperlinks[i].getHyperlinkRegion().getLength(); + + start= Math.min(start, hstart); + end= Math.max(end, hend); + } + + fSubjectRegion= new Region(start, end - start); + + fPresenter.showInformation(); + } + + private boolean equals(IHyperlink[] oldLinks, IHyperlink[] newLinks) { + if (oldLinks == null) + return false; + + if (oldLinks.length != newLinks.length) + return false; + + for (int i= 0; i < newLinks.length; i++) { + if (!oldLinks[i].getHyperlinkRegion().equals(newLinks[i].getHyperlinkRegion())) + return false; + } + + return true; + } + + private InformationPresenter createInformationPresenter() { + final MultipleHyperlinkInformationProvider informationProvider= new MultipleHyperlinkInformationProvider(); + + InformationPresenter result= new InformationPresenter(informationProvider.getInformationPresenterControlCreator()) { + /* (non-Javadoc) + * @see org.eclipse.jface.text.information.InformationPresenter#getInformationProvider(java.lang.String) + */ + public IInformationProvider getInformationProvider(String contentType) { + return informationProvider; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.text.AbstractInformationControlManager#showInformation() + */ + public void showInformation() { + doShowInformation(); + } + }; + + result.takesFocusWhenVisible(false); + return result; + } +}