Mercurial > projects > dwt-addons
diff dwtx/jface/text/source/DefaultAnnotationHover.d @ 129:eb30df5ca28b
Added JFace Text sources
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Sat, 23 Aug 2008 19:10:48 +0200 |
parents | |
children | c4fb132a086c |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/source/DefaultAnnotationHover.d Sat Aug 23 19:10:48 2008 +0200 @@ -0,0 +1,239 @@ +/******************************************************************************* + * Copyright (c) 2006, 2007 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 + * Port to the D programming language: + * Frank Benoit <benoit@tionex.de> + *******************************************************************************/ +module dwtx.jface.text.source.DefaultAnnotationHover; + +import dwt.dwthelper.utils; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import dwtx.jface.text.BadLocationException; +import dwtx.jface.text.IDocument; +import dwtx.jface.text.Position; +import dwtx.jface.text.source.projection.AnnotationBag; + +/** + * Standard implementation of {@link dwtx.jface.text.source.IAnnotationHover}. + * + * @since 3.2 + */ +public class DefaultAnnotationHover : IAnnotationHover { + + + /** + * Tells whether the line number should be shown when no annotation is found + * under the cursor. + * + * @since 3.4 + */ + private bool fShowLineNumber; + + /** + * Creates a new default annotation hover. + * + * @since 3.4 + */ + public DefaultAnnotationHover() { + this(false); + } + + /** + * Creates a new default annotation hover. + * + * @param showLineNumber <code>true</code> if the line number should be shown when no annotation is found + * @since 3.4 + */ + public DefaultAnnotationHover(bool showLineNumber) { + fShowLineNumber= showLineNumber; + } + + /* + * @see dwtx.jface.text.source.IAnnotationHover#getHoverInfo(dwtx.jface.text.source.ISourceViewer, int) + */ + public String getHoverInfo(ISourceViewer sourceViewer, int lineNumber) { + List javaAnnotations= getAnnotationsForLine(sourceViewer, lineNumber); + if (javaAnnotations !is null) { + + if (javaAnnotations.size() is 1) { + + // optimization + Annotation annotation= (Annotation) javaAnnotations.get(0); + String message= annotation.getText(); + if (message !is null && message.trim().length() > 0) + return formatSingleMessage(message); + + } else { + + List messages= new ArrayList(); + + Iterator e= javaAnnotations.iterator(); + while (e.hasNext()) { + Annotation annotation= (Annotation) e.next(); + String message= annotation.getText(); + if (message !is null && message.trim().length() > 0) + messages.add(message.trim()); + } + + if (messages.size() is 1) + return formatSingleMessage((String)messages.get(0)); + + if (messages.size() > 1) + return formatMultipleMessages(messages); + } + } + + if (fShowLineNumber && lineNumber > -1) + return JFaceTextMessages.getFormattedString("DefaultAnnotationHover.lineNumber", new String[] { Integer.toString(lineNumber + 1) }); //$NON-NLS-1$ + + return null; + } + + /** + * Tells whether the annotation should be included in + * the computation. + * + * @param annotation the annotation to test + * @return <code>true</code> if the annotation is included in the computation + */ + protected bool isIncluded(Annotation annotation) { + return true; + } + + /** + * Hook method to format the given single message. + * <p> + * Subclasses can change this to create a different + * format like HTML. + * </p> + * + * @param message the message to format + * @return the formatted message + */ + protected String formatSingleMessage(String message) { + return message; + } + + /** + * Hook method to formats the given messages. + * <p> + * Subclasses can change this to create a different + * format like HTML. + * </p> + * + * @param messages the messages to format + * @return the formatted message + */ + protected String formatMultipleMessages(List messages) { + StringBuffer buffer= new StringBuffer(); + buffer.append(JFaceTextMessages.getString("DefaultAnnotationHover.multipleMarkers")); //$NON-NLS-1$ + + Iterator e= messages.iterator(); + while (e.hasNext()) { + buffer.append('\n'); + String listItemText= (String) e.next(); + buffer.append(JFaceTextMessages.getFormattedString("DefaultAnnotationHover.listItem", new String[] { listItemText })); //$NON-NLS-1$ + } + return buffer.toString(); + } + + private bool isRulerLine(Position position, IDocument document, int line) { + if (position.getOffset() > -1 && position.getLength() > -1) { + try { + return line is document.getLineOfOffset(position.getOffset()); + } catch (BadLocationException x) { + } + } + return false; + } + + private IAnnotationModel getAnnotationModel(ISourceViewer viewer) { + if (viewer instanceof ISourceViewerExtension2) { + ISourceViewerExtension2 extension= (ISourceViewerExtension2) viewer; + return extension.getVisualAnnotationModel(); + } + return viewer.getAnnotationModel(); + } + + private bool isDuplicateAnnotation(Map messagesAtPosition, Position position, String message) { + if (messagesAtPosition.containsKey(position)) { + Object value= messagesAtPosition.get(position); + if (message.equals(value)) + return true; + + if (value instanceof List) { + List messages= (List)value; + if (messages.contains(message)) + return true; + + messages.add(message); + } else { + ArrayList messages= new ArrayList(); + messages.add(value); + messages.add(message); + messagesAtPosition.put(position, messages); + } + } else + messagesAtPosition.put(position, message); + return false; + } + + private bool includeAnnotation(Annotation annotation, Position position, HashMap messagesAtPosition) { + if (!isIncluded(annotation)) + return false; + + String text= annotation.getText(); + return (text !is null && !isDuplicateAnnotation(messagesAtPosition, position, text)); + } + + private List getAnnotationsForLine(ISourceViewer viewer, int line) { + IAnnotationModel model= getAnnotationModel(viewer); + if (model is null) + return null; + + IDocument document= viewer.getDocument(); + List javaAnnotations= new ArrayList(); + HashMap messagesAtPosition= new HashMap(); + Iterator iterator= model.getAnnotationIterator(); + + while (iterator.hasNext()) { + Annotation annotation= (Annotation) iterator.next(); + + Position position= model.getPosition(annotation); + if (position is null) + continue; + + if (!isRulerLine(position, document, line)) + continue; + + if (annotation instanceof AnnotationBag) { + AnnotationBag bag= (AnnotationBag) annotation; + Iterator e= bag.iterator(); + while (e.hasNext()) { + annotation= (Annotation) e.next(); + position= model.getPosition(annotation); + if (position !is null && includeAnnotation(annotation, position, messagesAtPosition)) + javaAnnotations.add(annotation); + } + continue; + } + + if (includeAnnotation(annotation, position, messagesAtPosition)) + javaAnnotations.add(annotation); + } + + return javaAnnotations; + } +}