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