Mercurial > projects > dwt-addons
comparison dwtx/ui/internal/forms/widgets/FormTextModel.d @ 75:5d489b9f966c
Fix continue porting
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Sat, 24 May 2008 05:11:16 +0200 |
parents | |
children | 4ac9946b9fb5 |
comparison
equal
deleted
inserted
replaced
74:dad2e11b8ae4 | 75:5d489b9f966c |
---|---|
1 /******************************************************************************* | |
2 * Copyright (c) 2000, 2007 IBM Corporation and others. | |
3 * All rights reserved. This program and the accompanying materials | |
4 * are made available under the terms of the Eclipse Public License v1.0 | |
5 * which accompanies this distribution, and is available at | |
6 * http://www.eclipse.org/legal/epl-v10.html | |
7 * | |
8 * Contributors: | |
9 * IBM Corporation - initial API and implementation | |
10 * Port to the D programming language: | |
11 * Frank Benoit <benoit@tionex.de> | |
12 *******************************************************************************/ | |
13 module dwtx.ui.internal.forms.widgets.FormTextModel; | |
14 | |
15 import dwtx.ui.internal.forms.widgets.Paragraph; | |
16 import dwtx.ui.internal.forms.widgets.IFocusSelectable; | |
17 import dwtx.ui.internal.forms.widgets.ParagraphSegment; | |
18 import dwtx.ui.internal.forms.widgets.IHyperlinkSegment; | |
19 import dwtx.ui.internal.forms.widgets.ControlSegment; | |
20 import dwtx.ui.internal.forms.widgets.ImageSegment; | |
21 import dwtx.ui.internal.forms.widgets.ObjectSegment; | |
22 | |
23 import dwt.DWT; | |
24 import dwtx.ui.forms.HyperlinkSettings; | |
25 | |
26 import dwt.dwthelper.utils; | |
27 import dwt.dwthelper.InputStream; | |
28 pragma(msg,"FIXME temp type "~__FILE__); | |
29 public class FormTextModel { | |
30 public static const String BOLD_FONT_ID = "f.____bold"; //$NON-NLS-1$ | |
31 public this() ; | |
32 public Paragraph[] getParagraphs() ; | |
33 public String getAccessibleText() ; | |
34 public void parseTaggedText(String taggedText, bool expandURLs) ; | |
35 public void parseInputStream(InputStream is_, bool expandURLs) ; | |
36 public void parseRegularText(String regularText, bool convertURLs) ; | |
37 public HyperlinkSettings getHyperlinkSettings() ; | |
38 public void setHyperlinkSettings(HyperlinkSettings settings) ; | |
39 IFocusSelectable[] getFocusSelectableSegments() ; | |
40 public IHyperlinkSegment getHyperlink(int index) ; | |
41 public IHyperlinkSegment findHyperlinkAt(int x, int y) ; | |
42 public int getHyperlinkCount() ; | |
43 public int indexOf(IHyperlinkSegment link) ; | |
44 public ParagraphSegment findSegmentAt(int x, int y) ; | |
45 public void clearCache(String fontId) ; | |
46 public IFocusSelectable getSelectedSegment() ; | |
47 public int getSelectedSegmentIndex() ; | |
48 public bool linkExists(IHyperlinkSegment link) ; | |
49 public bool traverseFocusSelectableObjects(bool next) ; | |
50 public IFocusSelectable getNextFocusSegment(bool next) ; | |
51 public bool restoreSavedLink() ; | |
52 public void selectLink(IHyperlinkSegment link) ; | |
53 public void select(IFocusSelectable selectable) ; | |
54 public bool hasFocusSegments() ; | |
55 public void dispose() ; | |
56 public bool isWhitespaceNormalized() ; | |
57 public void setWhitespaceNormalized(bool whitespaceNormalized) ; | |
58 } | |
59 | |
60 /++ | |
61 static import tango.text.xml.Document; | |
62 import tango.util.collection.ArraySeq; | |
63 public class FormTextModel { | |
64 // private static const DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory | |
65 // .newInstance(); | |
66 | |
67 alias tango.text.xml.Document.Document!(char) Document; | |
68 alias Document.NodeImpl Node; | |
69 | |
70 private bool whitespaceNormalized = true; | |
71 | |
72 private alias ArraySeq!(Paragraph) TArraySeqParagraph; | |
73 private TArraySeqParagraph paragraphs; | |
74 | |
75 private IFocusSelectable[] selectableSegments; | |
76 | |
77 private int selectedSegmentIndex = -1; | |
78 | |
79 private int savedSelectedLinkIndex = -1; | |
80 | |
81 private HyperlinkSettings hyperlinkSettings; | |
82 | |
83 public static const String BOLD_FONT_ID = "f.____bold"; //$NON-NLS-1$ | |
84 | |
85 //private static final int TEXT_ONLY_LINK = 1; | |
86 | |
87 //private static final int IMG_ONLY_LINK = 2; | |
88 | |
89 //private static final int TEXT_AND_IMAGES_LINK = 3; | |
90 | |
91 public this() { | |
92 reset(); | |
93 } | |
94 | |
95 /* | |
96 * @see ITextModel#getParagraphs() | |
97 */ | |
98 public Paragraph[] getParagraphs() { | |
99 if (paragraphs is null) | |
100 return new Paragraph[0]; | |
101 return paragraphs | |
102 .toArray(); | |
103 } | |
104 | |
105 public String getAccessibleText() { | |
106 if (paragraphs is null) | |
107 return ""; //$NON-NLS-1$ | |
108 StringBuffer sbuf = new StringBuffer(); | |
109 for (int i = 0; i < paragraphs.size(); i++) { | |
110 Paragraph paragraph = cast(Paragraph) paragraphs.get(i); | |
111 String text = paragraph.getAccessibleText(); | |
112 sbuf.append(text); | |
113 } | |
114 return sbuf.toString(); | |
115 } | |
116 | |
117 /* | |
118 * @see ITextModel#parse(String) | |
119 */ | |
120 public void parseTaggedText(String taggedText, bool expandURLs) { | |
121 if (taggedText is null) { | |
122 reset(); | |
123 return; | |
124 } | |
125 try { | |
126 InputStream stream = new ByteArrayInputStream(taggedText | |
127 .getBytes("UTF8")); //$NON-NLS-1$ | |
128 parseInputStream(stream, expandURLs); | |
129 } catch (UnsupportedEncodingException e) { | |
130 DWT.error(DWT.ERROR_UNSUPPORTED_FORMAT, e); | |
131 } | |
132 } | |
133 | |
134 public void parseInputStream(InputStream is_, bool expandURLs) { | |
135 | |
136 documentBuilderFactory.setNamespaceAware(true); | |
137 documentBuilderFactory.setIgnoringComments(true); | |
138 | |
139 reset(); | |
140 try { | |
141 DocumentBuilder parser = documentBuilderFactory | |
142 .newDocumentBuilder(); | |
143 InputSource source = new InputSource(is_); | |
144 Document doc = parser.parse(source); | |
145 processDocument(doc, expandURLs); | |
146 } catch (ParserConfigurationException e) { | |
147 DWT.error(DWT.ERROR_INVALID_ARGUMENT, e); | |
148 } catch (SAXException e) { | |
149 DWT.error(DWT.ERROR_INVALID_ARGUMENT, e); | |
150 } catch (IOException e) { | |
151 DWT.error(DWT.ERROR_IO, e); | |
152 } | |
153 } | |
154 | |
155 private void processDocument(Document doc, bool expandURLs) { | |
156 Node root = doc.getDocumentElement(); | |
157 NodeList children = root.getChildNodes(); | |
158 processSubnodes(paragraphs, children, expandURLs); | |
159 } | |
160 | |
161 private void processSubnodes(TArraySeqParagraph plist, NodeList children, bool expandURLs) { | |
162 for (int i = 0; i < children.getLength(); i++) { | |
163 Node child = children.item(i); | |
164 if (child.getNodeType() is Node.TEXT_NODE) { | |
165 // Make an implicit paragraph | |
166 String text = getSingleNodeText(child); | |
167 if (text !is null && !isIgnorableWhiteSpace(text, true)) { | |
168 Paragraph p = new Paragraph(true); | |
169 p.parseRegularText(text, expandURLs, true, | |
170 getHyperlinkSettings(), null); | |
171 plist.add(p); | |
172 } | |
173 } else if (child.getNodeType() is Node.ELEMENT_NODE) { | |
174 String tag = child.getNodeName().toLowerCase(); | |
175 if (tag.equals("p")) { //$NON-NLS-1$ | |
176 Paragraph p = processParagraph(child, expandURLs); | |
177 if (p !is null) | |
178 plist.add(p); | |
179 } else if (tag.equals("li")) { //$NON-NLS-1$ | |
180 Paragraph p = processListItem(child, expandURLs); | |
181 if (p !is null) | |
182 plist.add(p); | |
183 } | |
184 } | |
185 } | |
186 } | |
187 | |
188 private Paragraph processParagraph(Node paragraph, bool expandURLs) { | |
189 NodeList children = paragraph.getChildNodes(); | |
190 NamedNodeMap atts = paragraph.getAttributes(); | |
191 Node addSpaceAtt = atts.getNamedItem("addVerticalSpace"); //$NON-NLS-1$ | |
192 bool addSpace = true; | |
193 | |
194 if (addSpaceAtt is null) | |
195 addSpaceAtt = atts.getNamedItem("vspace"); //$NON-NLS-1$ | |
196 | |
197 if (addSpaceAtt !is null) { | |
198 String value = addSpaceAtt.getNodeValue(); | |
199 addSpace = value.equalsIgnoreCase("true"); //$NON-NLS-1$ | |
200 } | |
201 Paragraph p = new Paragraph(addSpace); | |
202 | |
203 processSegments(p, children, expandURLs); | |
204 return p; | |
205 } | |
206 | |
207 private Paragraph processListItem(Node listItem, bool expandURLs) { | |
208 NodeList children = listItem.getChildNodes(); | |
209 NamedNodeMap atts = listItem.getAttributes(); | |
210 Node addSpaceAtt = atts.getNamedItem("addVerticalSpace");//$NON-NLS-1$ | |
211 Node styleAtt = atts.getNamedItem("style");//$NON-NLS-1$ | |
212 Node valueAtt = atts.getNamedItem("value");//$NON-NLS-1$ | |
213 Node indentAtt = atts.getNamedItem("indent");//$NON-NLS-1$ | |
214 Node bindentAtt = atts.getNamedItem("bindent");//$NON-NLS-1$ | |
215 int style = BulletParagraph.CIRCLE; | |
216 int indent = -1; | |
217 int bindent = -1; | |
218 String text = null; | |
219 bool addSpace = true; | |
220 | |
221 if (addSpaceAtt !is null) { | |
222 String value = addSpaceAtt.getNodeValue(); | |
223 addSpace = value.equalsIgnoreCase("true"); //$NON-NLS-1$ | |
224 } | |
225 if (styleAtt !is null) { | |
226 String value = styleAtt.getNodeValue(); | |
227 if (value.equalsIgnoreCase("text")) { //$NON-NLS-1$ | |
228 style = BulletParagraph.TEXT; | |
229 } else if (value.equalsIgnoreCase("image")) { //$NON-NLS-1$ | |
230 style = BulletParagraph.IMAGE; | |
231 } else if (value.equalsIgnoreCase("bullet")) { //$NON-NLS-1$ | |
232 style = BulletParagraph.CIRCLE; | |
233 } | |
234 } | |
235 if (valueAtt !is null) { | |
236 text = valueAtt.getNodeValue(); | |
237 if (style is BulletParagraph.IMAGE) | |
238 text = "i." + text; //$NON-NLS-1$ | |
239 } | |
240 if (indentAtt !is null) { | |
241 String value = indentAtt.getNodeValue(); | |
242 try { | |
243 indent = Integer.parseInt(value); | |
244 } catch (NumberFormatException e) { | |
245 } | |
246 } | |
247 if (bindentAtt !is null) { | |
248 String value = bindentAtt.getNodeValue(); | |
249 try { | |
250 bindent = Integer.parseInt(value); | |
251 } catch (NumberFormatException e) { | |
252 } | |
253 } | |
254 | |
255 BulletParagraph p = new BulletParagraph(addSpace); | |
256 p.setIndent(indent); | |
257 p.setBulletIndent(bindent); | |
258 p.setBulletStyle(style); | |
259 p.setBulletText(text); | |
260 | |
261 processSegments(p, children, expandURLs); | |
262 return p; | |
263 } | |
264 | |
265 private void processSegments(Paragraph p, NodeList children, | |
266 bool expandURLs) { | |
267 for (int i = 0; i < children.getLength(); i++) { | |
268 Node child = children.item(i); | |
269 ParagraphSegment segment = null; | |
270 | |
271 if (child.getNodeType() is Node.TEXT_NODE) { | |
272 String value = getSingleNodeText(child); | |
273 | |
274 if (value !is null && !isIgnorableWhiteSpace(value, false)) { | |
275 p.parseRegularText(value, expandURLs, true, | |
276 getHyperlinkSettings(), null); | |
277 } | |
278 } else if (child.getNodeType() is Node.ELEMENT_NODE) { | |
279 String name = child.getNodeName(); | |
280 if (name.equalsIgnoreCase("img")) { //$NON-NLS-1$ | |
281 segment = processImageSegment(child); | |
282 } else if (name.equalsIgnoreCase("a")) { //$NON-NLS-1$ | |
283 segment = processHyperlinkSegment(child, | |
284 getHyperlinkSettings()); | |
285 } else if (name.equalsIgnoreCase("span")) { //$NON-NLS-1$ | |
286 processTextSegment(p, expandURLs, child); | |
287 } else if (name.equalsIgnoreCase("b")) { //$NON-NLS-1$ | |
288 String text = getNodeText(child); | |
289 String fontId = BOLD_FONT_ID; | |
290 p.parseRegularText(text, expandURLs, true, | |
291 getHyperlinkSettings(), fontId); | |
292 } else if (name.equalsIgnoreCase("br")) { //$NON-NLS-1$ | |
293 segment = new BreakSegment(); | |
294 } else if (name.equalsIgnoreCase("control")) { //$NON-NLS-1$ | |
295 segment = processControlSegment(child); | |
296 } | |
297 } | |
298 if (segment !is null) { | |
299 p.addSegment(segment); | |
300 } | |
301 } | |
302 } | |
303 | |
304 private bool isIgnorableWhiteSpace(String text, bool ignoreSpaces) { | |
305 for (int i = 0; i < text.length(); i++) { | |
306 char c = text.charAt(i); | |
307 if (ignoreSpaces && c is ' ') | |
308 continue; | |
309 if (c is '\n' || c is '\r' || c is '\f') | |
310 continue; | |
311 return false; | |
312 } | |
313 return true; | |
314 } | |
315 | |
316 private ImageSegment processImageSegment(Node image) { | |
317 ImageSegment segment = new ImageSegment(); | |
318 processObjectSegment(segment, image, "i."); //$NON-NLS-1$ | |
319 return segment; | |
320 } | |
321 | |
322 private ControlSegment processControlSegment(Node control) { | |
323 ControlSegment segment = new ControlSegment(); | |
324 processObjectSegment(segment, control, "o."); //$NON-NLS-1$ | |
325 Node fill = control.getAttributes().getNamedItem("fill"); //$NON-NLS-1$ | |
326 if (fill !is null) { | |
327 String value = fill.getNodeValue(); | |
328 bool doFill = value.equalsIgnoreCase("true"); //$NON-NLS-1$ | |
329 segment.setFill(doFill); | |
330 } | |
331 try { | |
332 Node width = control.getAttributes().getNamedItem("width"); //$NON-NLS-1$ | |
333 if (width !is null) { | |
334 String value = width.getNodeValue(); | |
335 int doWidth = Integer.parseInt(value); | |
336 segment.setWidth(doWidth); | |
337 } | |
338 Node height = control.getAttributes().getNamedItem("height"); //$NON-NLS-1$ | |
339 if (height !is null) { | |
340 String value = height.getNodeValue(); | |
341 int doHeight = Integer.parseInt(value); | |
342 segment.setHeight(doHeight); | |
343 } | |
344 } | |
345 catch (NumberFormatException e) { | |
346 // ignore invalid width or height | |
347 } | |
348 return segment; | |
349 } | |
350 | |
351 private void processObjectSegment(ObjectSegment segment, Node object, String prefix) { | |
352 NamedNodeMap atts = object.getAttributes(); | |
353 Node id = atts.getNamedItem("href"); //$NON-NLS-1$ | |
354 Node align_ = atts.getNamedItem("align"); //$NON-NLS-1$ | |
355 if (id !is null) { | |
356 String value = id.getNodeValue(); | |
357 segment.setObjectId(prefix + value); | |
358 } | |
359 if (align_ !is null) { | |
360 String value = align_.getNodeValue().toLowerCase(); | |
361 if (value.equals("top")) //$NON-NLS-1$ | |
362 segment.setVerticalAlignment(ImageSegment.TOP); | |
363 else if (value.equals("middle")) //$NON-NLS-1$ | |
364 segment.setVerticalAlignment(ImageSegment.MIDDLE); | |
365 else if (value.equals("bottom")) //$NON-NLS-1$ | |
366 segment.setVerticalAlignment(ImageSegment.BOTTOM); | |
367 } | |
368 } | |
369 | |
370 private void appendText(String value, StringBuffer buf, int[] spaceCounter) { | |
371 if (!whitespaceNormalized) | |
372 buf.append(value); | |
373 else { | |
374 for (int j = 0; j < value.length(); j++) { | |
375 char c = value.charAt(j); | |
376 if (c is ' ' || c is '\t') { | |
377 // space | |
378 if (++spaceCounter[0] is 1) { | |
379 buf.append(c); | |
380 } | |
381 } else if (c is '\n' || c is '\r' || c is '\f') { | |
382 // new line | |
383 if (++spaceCounter[0] is 1) { | |
384 buf.append(' '); | |
385 } | |
386 } else { | |
387 // other characters | |
388 spaceCounter[0] = 0; | |
389 buf.append(c); | |
390 } | |
391 } | |
392 } | |
393 } | |
394 | |
395 private String getNormalizedText(String text) { | |
396 int[] spaceCounter = new int[1]; | |
397 StringBuffer buf = new StringBuffer(); | |
398 | |
399 if (text is null) | |
400 return null; | |
401 appendText(text, buf, spaceCounter); | |
402 return buf.toString(); | |
403 } | |
404 | |
405 private String getSingleNodeText(Node node) { | |
406 return getNormalizedText(node.getNodeValue()); | |
407 } | |
408 | |
409 private String getNodeText(Node node) { | |
410 NodeList children = node.getChildNodes(); | |
411 StringBuffer buf = new StringBuffer(); | |
412 int[] spaceCounter = new int[1]; | |
413 | |
414 for (int i = 0; i < children.getLength(); i++) { | |
415 Node child = children.item(i); | |
416 if (child.getNodeType() is Node.TEXT_NODE) { | |
417 String value = child.getNodeValue(); | |
418 appendText(value, buf, spaceCounter); | |
419 } | |
420 } | |
421 return buf.toString().trim(); | |
422 } | |
423 | |
424 private ParagraphSegment processHyperlinkSegment(Node link, | |
425 HyperlinkSettings settings) { | |
426 NamedNodeMap atts = link.getAttributes(); | |
427 String href = null; | |
428 bool wrapAllowed = true; | |
429 String boldFontId = null; | |
430 | |
431 Node hrefAtt = atts.getNamedItem("href"); //$NON-NLS-1$ | |
432 if (hrefAtt !is null) { | |
433 href = hrefAtt.getNodeValue(); | |
434 } | |
435 Node boldAtt = atts.getNamedItem("bold"); //$NON-NLS-1$ | |
436 if (boldAtt !is null) { | |
437 boldFontId = BOLD_FONT_ID; | |
438 } | |
439 Node nowrap = atts.getNamedItem("nowrap"); //$NON-NLS-1$ | |
440 if (nowrap !is null) { | |
441 String value = nowrap.getNodeValue(); | |
442 if (value !is null && value.equalsIgnoreCase("true")) //$NON-NLS-1$ | |
443 wrapAllowed = false; | |
444 } | |
445 Object status = checkChildren(link); | |
446 if ( auto child = cast(Node)status ) { | |
447 ImageHyperlinkSegment segment = new ImageHyperlinkSegment(); | |
448 segment.setHref(href); | |
449 segment.setWordWrapAllowed(wrapAllowed); | |
450 Node alt = child.getAttributes().getNamedItem("alt"); //$NON-NLS-1$ | |
451 if (alt !is null) | |
452 segment.setTooltipText(alt.getNodeValue()); | |
453 Node text = child.getAttributes().getNamedItem("text"); //$NON-NLS-1$ | |
454 if (text !is null) | |
455 segment.setText(text.getNodeValue()); | |
456 processObjectSegment(segment, child, "i."); //$NON-NLS-1$ | |
457 return segment; | |
458 } else if ( auto textObj = cast(ArrayWrapperString)status ) { | |
459 String text = textObj.array; | |
460 TextHyperlinkSegment segment = new TextHyperlinkSegment(text, | |
461 settings, null); | |
462 segment.setHref(href); | |
463 segment.setFontId(boldFontId); | |
464 Node alt = atts.getNamedItem("alt"); //$NON-NLS-1$ | |
465 if (alt !is null) | |
466 segment.setTooltipText(alt.getNodeValue()); | |
467 segment.setWordWrapAllowed(wrapAllowed); | |
468 return segment; | |
469 } else { | |
470 AggregateHyperlinkSegment parent = new AggregateHyperlinkSegment(); | |
471 parent.setHref(href); | |
472 NodeList children = link.getChildNodes(); | |
473 for (int i = 0; i < children.getLength(); i++) { | |
474 Node child = children.item(i); | |
475 if (child.getNodeType() is Node.TEXT_NODE) { | |
476 String value = child.getNodeValue(); | |
477 TextHyperlinkSegment ts = new TextHyperlinkSegment( | |
478 getNormalizedText(value), settings, null); | |
479 Node alt = atts.getNamedItem("alt"); //$NON-NLS-1$ | |
480 if (alt !is null) | |
481 ts.setTooltipText(alt.getNodeValue()); | |
482 ts.setWordWrapAllowed(wrapAllowed); | |
483 parent.add(ts); | |
484 } else if (child.getNodeType() is Node.ELEMENT_NODE) { | |
485 String name = child.getNodeName(); | |
486 if (name.equalsIgnoreCase("img")) { //$NON-NLS-1$ | |
487 ImageHyperlinkSegment is_ = new ImageHyperlinkSegment(); | |
488 processObjectSegment(is_, child, "i."); //$NON-NLS-1$ | |
489 Node alt = child.getAttributes().getNamedItem("alt"); //$NON-NLS-1$ | |
490 if (alt !is null) | |
491 is_.setTooltipText(alt.getNodeValue()); | |
492 parent.add(is_); | |
493 is_.setWordWrapAllowed(wrapAllowed); | |
494 } | |
495 } | |
496 } | |
497 return parent; | |
498 } | |
499 } | |
500 | |
501 private Object checkChildren(Node node) { | |
502 bool text = false; | |
503 Node imgNode = null; | |
504 //int status = 0; | |
505 | |
506 NodeList children = node.getChildNodes(); | |
507 for (int i = 0; i < children.getLength(); i++) { | |
508 Node child = children.item(i); | |
509 if (child.getNodeType() is Node.TEXT_NODE) | |
510 text = true; | |
511 else if (child.getNodeType() is Node.ELEMENT_NODE | |
512 && child.getNodeName().equalsIgnoreCase("img")) { //$NON-NLS-1$ | |
513 imgNode = child; | |
514 } | |
515 } | |
516 if (text && imgNode is null) | |
517 return getNodeText(node); | |
518 else if (!text && imgNode !is null) | |
519 return imgNode; | |
520 else return null; | |
521 } | |
522 | |
523 private void processTextSegment(Paragraph p, bool expandURLs, | |
524 Node textNode) { | |
525 String text = getNodeText(textNode); | |
526 | |
527 NamedNodeMap atts = textNode.getAttributes(); | |
528 Node font = atts.getNamedItem("font"); //$NON-NLS-1$ | |
529 Node color = atts.getNamedItem("color"); //$NON-NLS-1$ | |
530 bool wrapAllowed=true; | |
531 Node nowrap = atts.getNamedItem("nowrap"); //$NON-NLS-1$ | |
532 if (nowrap !is null) { | |
533 String value = nowrap.getNodeValue(); | |
534 if (value !is null && value.equalsIgnoreCase("true")) //$NON-NLS-1$ | |
535 wrapAllowed = false; | |
536 } | |
537 String fontId = null; | |
538 String colorId = null; | |
539 if (font !is null) { | |
540 fontId = "f." + font.getNodeValue(); //$NON-NLS-1$ | |
541 } | |
542 if (color !is null) { | |
543 colorId = "c." + color.getNodeValue(); //$NON-NLS-1$ | |
544 } | |
545 p.parseRegularText(text, expandURLs, wrapAllowed, getHyperlinkSettings(), fontId, | |
546 colorId); | |
547 } | |
548 | |
549 public void parseRegularText(String regularText, bool convertURLs) { | |
550 reset(); | |
551 | |
552 if (regularText is null) | |
553 return; | |
554 | |
555 regularText = getNormalizedText(regularText); | |
556 | |
557 Paragraph p = new Paragraph(true); | |
558 paragraphs.append(p); | |
559 int pstart = 0; | |
560 | |
561 for (int i = 0; i < regularText.length(); i++) { | |
562 char c = regularText.charAt(i); | |
563 if (p is null) { | |
564 p = new Paragraph(true); | |
565 paragraphs.append(p); | |
566 } | |
567 if (c is '\n') { | |
568 String text = regularText.substring(pstart, i); | |
569 pstart = i + 1; | |
570 p.parseRegularText(text, convertURLs, true, getHyperlinkSettings(), | |
571 null); | |
572 p = null; | |
573 } | |
574 } | |
575 if (p !is null) { | |
576 // no new line | |
577 String text = regularText.substring(pstart); | |
578 p.parseRegularText(text, convertURLs, true, getHyperlinkSettings(), null); | |
579 } | |
580 } | |
581 | |
582 public HyperlinkSettings getHyperlinkSettings() { | |
583 // #132723 cannot have null settings | |
584 if (hyperlinkSettingsisnull) | |
585 hyperlinkSettings = new HyperlinkSettings(SWTUtil.getStandardDisplay()); | |
586 return hyperlinkSettings; | |
587 } | |
588 | |
589 public void setHyperlinkSettings(HyperlinkSettings settings) { | |
590 this.hyperlinkSettings = settings; | |
591 } | |
592 | |
593 private void reset() { | |
594 if (paragraphs is null) | |
595 paragraphs = new TArraySeqParagraph; | |
596 paragraphs.clear(); | |
597 selectedSegmentIndex = -1; | |
598 savedSelectedLinkIndex = -1; | |
599 selectableSegments = null; | |
600 } | |
601 | |
602 IFocusSelectable[] getFocusSelectableSegments() { | |
603 if (selectableSegments !is null || paragraphs is null) | |
604 return selectableSegments; | |
605 IFocusSelectable[] result; | |
606 for (int i = 0; i < paragraphs.size(); i++) { | |
607 Paragraph p = cast(Paragraph) paragraphs.get(i); | |
608 ParagraphSegment[] segments = p.getSegments(); | |
609 for (int j = 0; j < segments.length; j++) { | |
610 if (null !is cast(IFocusSelectable)segments[j] ) | |
611 result ~= segments[j]; | |
612 } | |
613 } | |
614 selectableSegments = result; | |
615 return selectableSegments; | |
616 } | |
617 | |
618 public IHyperlinkSegment getHyperlink(int index) { | |
619 IFocusSelectable[] selectables = getFocusSelectableSegments(); | |
620 if (selectables.length>index) { | |
621 IFocusSelectable link = selectables[index]; | |
622 if (auto l = cast(IHyperlinkSegment)link ) | |
623 return l; | |
624 } | |
625 return null; | |
626 } | |
627 | |
628 public IHyperlinkSegment findHyperlinkAt(int x, int y) { | |
629 IFocusSelectable[] selectables = getFocusSelectableSegments(); | |
630 for (int i = 0; i < selectables.length; i++) { | |
631 IFocusSelectable segment = selectables[i]; | |
632 if ( auto link = cast(IHyperlinkSegment)segment ) { | |
633 if (link.contains(x, y)) | |
634 return link; | |
635 } | |
636 } | |
637 return null; | |
638 } | |
639 | |
640 public int getHyperlinkCount() { | |
641 return getFocusSelectableSegments().length; | |
642 } | |
643 | |
644 public int indexOf(IHyperlinkSegment link) { | |
645 IFocusSelectable[] selectables = getFocusSelectableSegments(); | |
646 for (int i = 0; i < selectables.length; i++) { | |
647 IFocusSelectable segment = selectables[i]; | |
648 if (auto l = cast(IHyperlinkSegment)segment ) { | |
649 if (link is l) | |
650 return i; | |
651 } | |
652 } | |
653 return -1; | |
654 } | |
655 | |
656 public ParagraphSegment findSegmentAt(int x, int y) { | |
657 for (int i = 0; i < paragraphs.size(); i++) { | |
658 Paragraph p = cast(Paragraph) paragraphs.get(i); | |
659 ParagraphSegment segment = p.findSegmentAt(x, y); | |
660 if (segment !is null) | |
661 return segment; | |
662 } | |
663 return null; | |
664 } | |
665 | |
666 public void clearCache(String fontId) { | |
667 for (int i = 0; i < paragraphs.size(); i++) { | |
668 Paragraph p = cast(Paragraph) paragraphs.get(i); | |
669 p.clearCache(fontId); | |
670 } | |
671 } | |
672 | |
673 public IFocusSelectable getSelectedSegment() { | |
674 if (selectableSegments is null || selectedSegmentIndex is -1) | |
675 return null; | |
676 return selectableSegments[selectedSegmentIndex]; | |
677 } | |
678 | |
679 public int getSelectedSegmentIndex() { | |
680 return selectedSegmentIndex; | |
681 } | |
682 | |
683 public bool linkExists(IHyperlinkSegment link) { | |
684 if (selectableSegmentsisnull) | |
685 return false; | |
686 for (int i=0; i<selectableSegments.length; i++) { | |
687 if (selectableSegments[i] is link) | |
688 return true; | |
689 } | |
690 return false; | |
691 } | |
692 | |
693 public bool traverseFocusSelectableObjects(bool next) { | |
694 IFocusSelectable[] selectables = getFocusSelectableSegments(); | |
695 if (selectables is null) | |
696 return false; | |
697 int size = selectables.length; | |
698 if (next) { | |
699 selectedSegmentIndex++; | |
700 } else | |
701 selectedSegmentIndex--; | |
702 | |
703 if (selectedSegmentIndex < 0 || selectedSegmentIndex > size - 1) { | |
704 selectedSegmentIndex = -1; | |
705 } | |
706 return selectedSegmentIndex !is -1; | |
707 } | |
708 | |
709 public IFocusSelectable getNextFocusSegment(bool next) { | |
710 IFocusSelectable[] selectables = getFocusSelectableSegments(); | |
711 if (selectables is null) | |
712 return null; | |
713 int nextIndex = next?selectedSegmentIndex+1:selectedSegmentIndex-1; | |
714 | |
715 if (nextIndex < 0 || nextIndex > selectables.length - 1) { | |
716 return null; | |
717 } | |
718 return selectables[nextIndex]; | |
719 } | |
720 | |
721 public bool restoreSavedLink() { | |
722 if (savedSelectedLinkIndex!is -1) { | |
723 selectedSegmentIndex = savedSelectedLinkIndex; | |
724 return true; | |
725 } | |
726 return false; | |
727 } | |
728 | |
729 public void selectLink(IHyperlinkSegment link) { | |
730 if (link is null) { | |
731 savedSelectedLinkIndex = selectedSegmentIndex; | |
732 selectedSegmentIndex = -1; | |
733 } | |
734 else { | |
735 select(link); | |
736 | |
737 } | |
738 } | |
739 | |
740 public void select(IFocusSelectable selectable) { | |
741 IFocusSelectable[] selectables = getFocusSelectableSegments(); | |
742 selectedSegmentIndex = -1; | |
743 if (selectables is null) | |
744 return; | |
745 for (int i = 0; i < selectables.length; i++) { | |
746 if (selectables[i].equals(selectable)) { | |
747 selectedSegmentIndex = i; | |
748 break; | |
749 } | |
750 } | |
751 } | |
752 | |
753 public bool hasFocusSegments() { | |
754 IFocusSelectable[] segments = getFocusSelectableSegments(); | |
755 if (segments.length > 0) | |
756 return true; | |
757 return false; | |
758 } | |
759 | |
760 public void dispose() { | |
761 paragraphs = null; | |
762 selectedSegmentIndex = -1; | |
763 savedSelectedLinkIndex = -1; | |
764 selectableSegments = null; | |
765 } | |
766 | |
767 /** | |
768 * @return Returns the whitespaceNormalized. | |
769 */ | |
770 public bool isWhitespaceNormalized() { | |
771 return whitespaceNormalized; | |
772 } | |
773 | |
774 /** | |
775 * @param whitespaceNormalized | |
776 * The whitespaceNormalized to set. | |
777 */ | |
778 public void setWhitespaceNormalized(bool whitespaceNormalized) { | |
779 this.whitespaceNormalized = whitespaceNormalized; | |
780 } | |
781 } | |
782 ++/ |