Fixed bug #1404228: Crash on <?php // comment ?>
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpeclipse / phpeditor / PHPAnnotationHover.java
1 package net.sourceforge.phpeclipse.phpeditor;
2
3 /**********************************************************************
4 Copyright (c) 2000, 2002 IBM Corp. and others.
5 All rights reserved. This program and the accompanying materials
6 are made available under the terms of the Common Public License v1.0
7 which accompanies this distribution, and is available at
8 http://www.eclipse.org/legal/cpl-v10.html
9
10 Contributors:
11     IBM Corporation - Initial implementation
12     www.phpeclipse.de
13 **********************************************************************/
14
15 import java.util.ArrayList;
16 import java.util.Iterator;
17 import java.util.List;
18
19 import org.eclipse.core.resources.IMarker;
20 import org.eclipse.jface.text.BadLocationException;
21 import org.eclipse.jface.text.IDocument;
22 import org.eclipse.jface.text.Position;
23 import org.eclipse.jface.text.source.IAnnotationHover;
24 import org.eclipse.jface.text.source.IAnnotationModel;
25 import org.eclipse.jface.text.source.ISourceViewer;
26 import org.eclipse.ui.texteditor.MarkerAnnotation;
27
28 /** 
29  * The PHPAnnotationHover provides the hover support for PHP editors.
30  */
31  
32 public class PHPAnnotationHover implements IAnnotationHover {
33
34         /* (non-Javadoc)
35          * Method declared on IAnnotationHover
36          */
37 //      public String getHoverInfo(ISourceViewer sourceViewer, int lineNumber) {
38 //              IDocument document= sourceViewer.getDocument();
39 //
40 //              try {
41 //                      IRegion info= document.getLineInformation(lineNumber);
42 //                      return document.get(info.getOffset(), info.getLength());
43 //              } catch (BadLocationException x) {
44 //              }
45 //
46 //              return null;
47 //      }
48 //      
49   static final int MAX_INFO_LENGTH = 80;
50
51   /**
52    * @see org.eclipse.jface.text.source.IAnnotationHover#getHoverInfo(org.eclipse.jface.text.source.ISourceViewer, int)
53    */
54         
55   public String getHoverInfo(ISourceViewer viewer, int line) {
56     String info = null;
57     List markers = getMarkersForLine(viewer, line);
58     if (markers != null) {
59       info = "";
60       for (int i =  0; i < markers.size(); i++) {
61         IMarker marker = (IMarker) markers.get(i);
62         String message =
63           marker.getAttribute(IMarker.MESSAGE, (String) null);
64         if (message != null && message.trim().length() > 0) {
65                                         
66           if (message.length() > MAX_INFO_LENGTH) {
67             message = splitMessage(message);
68           }
69           info += message;
70                                         
71           if(i != markers.size() - 1) {
72              info += "\n";
73           }
74         }
75       }
76     }
77     return info;
78   }
79
80   private String splitMessage(String message) {
81     String result = "";
82                 
83     if(message.length() <= MAX_INFO_LENGTH) {
84       return message;
85     }
86                 
87     String tmpStr = new String(message);
88                 
89     while(tmpStr.length() > MAX_INFO_LENGTH) {
90                         
91       int spacepos = tmpStr.indexOf(" ", MAX_INFO_LENGTH);
92                         
93       if(spacepos != -1) {
94         result += tmpStr.substring(0, spacepos) + "\n";
95         tmpStr = tmpStr.substring(spacepos);
96       }
97       else {
98         result += tmpStr.substring(0, MAX_INFO_LENGTH) + "\n";
99         tmpStr = tmpStr.substring(MAX_INFO_LENGTH);
100       }
101                         
102                         
103                         
104     }
105                 
106     result += tmpStr;
107                 
108     return result;
109   }
110
111   /**
112    * Returns all markers which includes the ruler's line of activity.
113    */
114   protected List getMarkersForLine(ISourceViewer aViewer, int aLine) {
115     List markers = new ArrayList();
116     IAnnotationModel model = aViewer.getAnnotationModel();
117     if (model != null) {
118       Iterator e = model.getAnnotationIterator();
119       while (e.hasNext()) {
120         Object o = e.next();
121         if (o instanceof MarkerAnnotation) {
122           MarkerAnnotation a = (MarkerAnnotation) o;
123           if (compareRulerLine(model.getPosition(a),
124             aViewer.getDocument(),
125             aLine)
126             != 0) {
127             markers.add(a.getMarker());
128           }
129         }
130       }
131     }
132     return markers;
133   }
134
135   /**
136    * Returns one marker which includes the ruler's line of activity.
137    */
138   protected IMarker getMarkerForLine(ISourceViewer aViewer, int aLine) {
139     IMarker marker = null;
140     IAnnotationModel model = aViewer.getAnnotationModel();
141     if (model != null) {
142       Iterator e = model.getAnnotationIterator();
143       while (e.hasNext()) {
144         Object o = e.next();
145         if (o instanceof MarkerAnnotation) {
146           MarkerAnnotation a = (MarkerAnnotation) o;
147           if (compareRulerLine(model.getPosition(a),
148             aViewer.getDocument(),
149             aLine)
150             != 0) {
151             marker = a.getMarker();
152           }
153         }
154       }
155     }
156     return marker;
157   }
158
159   /**
160    * Returns distance of given line to specified position (1 = same line,
161    * 2 = included in given position, 0 = not related).
162    */
163   protected int compareRulerLine(
164     Position aPosition,
165     IDocument aDocument,
166     int aLine) {
167     int distance = 0;
168     if (aPosition.getOffset() > -1 && aPosition.getLength() > -1) {
169       try {
170         int markerLine =
171           aDocument.getLineOfOffset(aPosition.getOffset());
172         if (aLine == markerLine) {
173           distance = 1;
174         } else if (
175           markerLine <= aLine
176             && aLine
177               <= aDocument.getLineOfOffset(
178                 aPosition.getOffset()
179                   + aPosition.getLength())) {
180           distance = 2;
181         }
182       } catch (BadLocationException e) {
183       }
184     }
185     return distance;
186   }
187 }