001: /*******************************************************************************
002: * Copyright (c) 2000, 2007 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.ui.internal.forms.widgets;
011:
012: import java.io.*;
013: import java.util.ArrayList;
014: import java.util.Hashtable;
015: import java.util.Vector;
016:
017: import org.eclipse.swt.graphics.*;
018: import org.eclipse.swt.graphics.GC;
019: import org.eclipse.ui.forms.HyperlinkSettings;
020:
021: /**
022: * @version 1.0
023: * @author
024: */
025: public class Paragraph {
026: public static final String HTTP = "http://"; //$NON-NLS-1$
027:
028: private Vector segments;
029:
030: private boolean addVerticalSpace = true;
031:
032: public Paragraph(boolean addVerticalSpace) {
033: this .addVerticalSpace = addVerticalSpace;
034: }
035:
036: public int getIndent() {
037: return 0;
038: }
039:
040: public boolean getAddVerticalSpace() {
041: return addVerticalSpace;
042: }
043:
044: /*
045: * @see IParagraph#getSegments()
046: */
047: public ParagraphSegment[] getSegments() {
048: if (segments == null)
049: return new ParagraphSegment[0];
050: return (ParagraphSegment[]) segments
051: .toArray(new ParagraphSegment[segments.size()]);
052: }
053:
054: public void addSegment(ParagraphSegment segment) {
055: if (segments == null)
056: segments = new Vector();
057: segments.add(segment);
058: }
059:
060: public void parseRegularText(String text, boolean expandURLs,
061: boolean wrapAllowed, HyperlinkSettings settings,
062: String fontId) {
063: parseRegularText(text, expandURLs, wrapAllowed, settings,
064: fontId, null);
065: }
066:
067: public void parseRegularText(String text, boolean expandURLs,
068: boolean wrapAllowed, HyperlinkSettings settings,
069: String fontId, String colorId) {
070: if (text.length() == 0)
071: return;
072: if (expandURLs) {
073: int loc = text.indexOf(HTTP);
074:
075: if (loc == -1)
076: addSegment(new TextSegment(text, fontId, colorId,
077: wrapAllowed));
078: else {
079: int textLoc = 0;
080: while (loc != -1) {
081: addSegment(new TextSegment(text.substring(textLoc,
082: loc), fontId, colorId, wrapAllowed));
083: boolean added = false;
084: for (textLoc = loc; textLoc < text.length(); textLoc++) {
085: char c = text.charAt(textLoc);
086: if (Character.isSpaceChar(c)) {
087: addHyperlinkSegment(text.substring(loc,
088: textLoc), settings, fontId);
089: added = true;
090: break;
091: }
092: }
093: if (!added) {
094: // there was no space - just end of text
095: addHyperlinkSegment(text.substring(loc),
096: settings, fontId);
097: break;
098: }
099: loc = text.indexOf(HTTP, textLoc);
100: }
101: if (textLoc < text.length()) {
102: addSegment(new TextSegment(text.substring(textLoc),
103: fontId, colorId, wrapAllowed));
104: }
105: }
106: } else {
107: addSegment(new TextSegment(text, fontId, colorId,
108: wrapAllowed));
109: }
110: }
111:
112: private void addHyperlinkSegment(String text,
113: HyperlinkSettings settings, String fontId) {
114: TextHyperlinkSegment hs = new TextHyperlinkSegment(text,
115: settings, fontId);
116: hs.setWordWrapAllowed(false);
117: hs.setHref(text);
118: addSegment(hs);
119: }
120:
121: protected void computeRowHeights(GC gc, int width, Locator loc,
122: int lineHeight, Hashtable resourceTable) {
123: ParagraphSegment[] segments = getSegments();
124: // compute heights
125: Locator hloc = loc.create();
126: ArrayList heights = new ArrayList();
127: hloc.heights = heights;
128: hloc.rowCounter = 0;
129: int innerWidth = width - loc.marginWidth * 2;
130: for (int j = 0; j < segments.length; j++) {
131: ParagraphSegment segment = segments[j];
132: segment.advanceLocator(gc, innerWidth, hloc, resourceTable,
133: true);
134: }
135: hloc.collectHeights();
136: loc.heights = heights;
137: loc.rowCounter = 0;
138: }
139:
140: public void layout(GC gc, int width, Locator loc, int lineHeight,
141: Hashtable resourceTable, IHyperlinkSegment selectedLink) {
142: ParagraphSegment[] segments = getSegments();
143: //int height;
144: if (segments.length > 0) {
145: /*
146: if (segments[0] instanceof TextSegment
147: && ((TextSegment) segments[0]).isSelectable())
148: loc.x += 1;
149: */
150: // compute heights
151: if (loc.heights == null)
152: computeRowHeights(gc, width, loc, lineHeight,
153: resourceTable);
154: for (int j = 0; j < segments.length; j++) {
155: ParagraphSegment segment = segments[j];
156: boolean doSelect = false;
157: if (selectedLink != null
158: && segment.equals(selectedLink))
159: doSelect = true;
160: segment.layout(gc, width, loc, resourceTable, doSelect);
161: }
162: loc.heights = null;
163: loc.y += loc.rowHeight;
164: } else {
165: loc.y += lineHeight;
166: }
167: }
168:
169: public void paint(GC gc, Rectangle repaintRegion,
170: Hashtable resourceTable, IHyperlinkSegment selectedLink,
171: SelectionData selData) {
172: ParagraphSegment[] segments = getSegments();
173:
174: for (int i = 0; i < segments.length; i++) {
175: ParagraphSegment segment = segments[i];
176: if (!segment.intersects(repaintRegion))
177: continue;
178: boolean doSelect = false;
179: if (selectedLink != null && segment.equals(selectedLink))
180: doSelect = true;
181: segment.paint(gc, false, resourceTable, doSelect, selData,
182: repaintRegion);
183: }
184: }
185:
186: public void computeSelection(GC gc, Hashtable resourceTable,
187: IHyperlinkSegment selectedLink, SelectionData selData) {
188: ParagraphSegment[] segments = getSegments();
189:
190: for (int i = 0; i < segments.length; i++) {
191: ParagraphSegment segment = segments[i];
192: //boolean doSelect = false;
193: //if (selectedLink != null && segment.equals(selectedLink))
194: //doSelect = true;
195: segment.computeSelection(gc, resourceTable, selData);
196: }
197: }
198:
199: public String getAccessibleText() {
200: ParagraphSegment[] segments = getSegments();
201: StringWriter swriter = new StringWriter();
202: PrintWriter writer = new PrintWriter(swriter);
203: for (int i = 0; i < segments.length; i++) {
204: ParagraphSegment segment = segments[i];
205: if (segment instanceof TextSegment) {
206: String text = ((TextSegment) segment).getText();
207: writer.print(text);
208: }
209: }
210: writer.println();
211: swriter.flush();
212: return swriter.toString();
213: }
214:
215: public ParagraphSegment findSegmentAt(int x, int y) {
216: if (segments != null) {
217: for (int i = 0; i < segments.size(); i++) {
218: ParagraphSegment segment = (ParagraphSegment) segments
219: .get(i);
220: if (segment.contains(x, y))
221: return segment;
222: }
223: }
224: return null;
225: }
226:
227: public void clearCache(String fontId) {
228: if (segments != null) {
229: for (int i = 0; i < segments.size(); i++) {
230: ParagraphSegment segment = (ParagraphSegment) segments
231: .get(i);
232: segment.clearCache(fontId);
233: }
234: }
235: }
236: }
|