Source Code Cross Referenced for TextRun.java in  » Collaboration » poi-3.0.2-beta2 » org » apache » poi » hslf » model » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Collaboration » poi 3.0.2 beta2 » org.apache.poi.hslf.model 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /* ====================================================================
002:         Licensed to the Apache Software Foundation (ASF) under one or more
003:         contributor license agreements.  See the NOTICE file distributed with
004:         this work for additional information regarding copyright ownership.
005:         The ASF licenses this file to You under the Apache License, Version 2.0
006:         (the "License"); you may not use this file except in compliance with
007:         the License.  You may obtain a copy of the License at
008:
009:         http://www.apache.org/licenses/LICENSE-2.0
010:
011:         Unless required by applicable law or agreed to in writing, software
012:         distributed under the License is distributed on an "AS IS" BASIS,
013:         WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014:         See the License for the specific language governing permissions and
015:         limitations under the License.
016:         ==================================================================== */
017:
018:        package org.apache.poi.hslf.model;
019:
020:        import java.util.LinkedList;
021:        import java.util.Vector;
022:
023:        import org.apache.poi.hslf.model.textproperties.TextPropCollection;
024:        import org.apache.poi.hslf.record.*;
025:        import org.apache.poi.hslf.usermodel.RichTextRun;
026:        import org.apache.poi.hslf.usermodel.SlideShow;
027:        import org.apache.poi.util.StringUtil;
028:
029:        /**
030:         * This class represents a run of text in a powerpoint document. That
031:         *  run could be text on a sheet, or text in a note.
032:         *  It is only a very basic class for now
033:         *
034:         * @author Nick Burch
035:         */
036:
037:        public class TextRun {
038:            // Note: These fields are protected to help with unit testing
039:            //   Other classes shouldn't really go playing with them!
040:            protected TextHeaderAtom _headerAtom;
041:            protected TextBytesAtom _byteAtom;
042:            protected TextCharsAtom _charAtom;
043:            protected StyleTextPropAtom _styleAtom;
044:            protected boolean _isUnicode;
045:            protected RichTextRun[] _rtRuns;
046:            private SlideShow slideShow;
047:            private Sheet sheet;
048:            private int shapeId;
049:            private int slwtIndex; //position in the owning SlideListWithText
050:            /**
051:             * all text run records that follow TextHeaderAtom.
052:             * (there can be misc InteractiveInfo, TxInteractiveInfo and other records)
053:             */
054:            protected Record[] _records;
055:
056:            /**
057:             * Constructs a Text Run from a Unicode text block
058:             *
059:             * @param tha the TextHeaderAtom that defines what's what
060:             * @param tca the TextCharsAtom containing the text
061:             * @param sta the StyleTextPropAtom which defines the character stylings
062:             */
063:            public TextRun(TextHeaderAtom tha, TextCharsAtom tca,
064:                    StyleTextPropAtom sta) {
065:                this (tha, null, tca, sta);
066:            }
067:
068:            /**
069:             * Constructs a Text Run from a Ascii text block
070:             *
071:             * @param tha the TextHeaderAtom that defines what's what
072:             * @param tba the TextBytesAtom containing the text
073:             * @param sta the StyleTextPropAtom which defines the character stylings
074:             */
075:            public TextRun(TextHeaderAtom tha, TextBytesAtom tba,
076:                    StyleTextPropAtom sta) {
077:                this (tha, tba, null, sta);
078:            }
079:
080:            /**
081:             * Internal constructor and initializer
082:             */
083:            private TextRun(TextHeaderAtom tha, TextBytesAtom tba,
084:                    TextCharsAtom tca, StyleTextPropAtom sta) {
085:                _headerAtom = tha;
086:                _styleAtom = sta;
087:                if (tba != null) {
088:                    _byteAtom = tba;
089:                    _isUnicode = false;
090:                } else {
091:                    _charAtom = tca;
092:                    _isUnicode = true;
093:                }
094:                String runRawText = getText();
095:
096:                // Figure out the rich text runs
097:                LinkedList pStyles = new LinkedList();
098:                LinkedList cStyles = new LinkedList();
099:                if (_styleAtom != null) {
100:                    // Get the style atom to grok itself
101:                    _styleAtom.setParentTextSize(runRawText.length());
102:                    pStyles = _styleAtom.getParagraphStyles();
103:                    cStyles = _styleAtom.getCharacterStyles();
104:                }
105:
106:                // Handle case of no current style, with a default
107:                if (pStyles.size() == 0 || cStyles.size() == 0) {
108:                    _rtRuns = new RichTextRun[1];
109:                    _rtRuns[0] = new RichTextRun(this , 0, runRawText.length());
110:                } else {
111:                    // Build up Rich Text Runs, one for each 
112:                    //  character/paragraph style pair
113:                    Vector rtrs = new Vector();
114:
115:                    int pos = 0;
116:
117:                    int curP = 0;
118:                    int curC = 0;
119:                    int pLenRemain = -1;
120:                    int cLenRemain = -1;
121:
122:                    // Build one for each run with the same style
123:                    while (pos <= runRawText.length() && curP < pStyles.size()
124:                            && curC < cStyles.size()) {
125:                        // Get the Props to use
126:                        TextPropCollection pProps = (TextPropCollection) pStyles
127:                                .get(curP);
128:                        TextPropCollection cProps = (TextPropCollection) cStyles
129:                                .get(curC);
130:
131:                        int pLen = pProps.getCharactersCovered();
132:                        int cLen = cProps.getCharactersCovered();
133:
134:                        // Handle new pass
135:                        boolean freshSet = false;
136:                        if (pLenRemain == -1 && cLenRemain == -1) {
137:                            freshSet = true;
138:                        }
139:                        if (pLenRemain == -1) {
140:                            pLenRemain = pLen;
141:                        }
142:                        if (cLenRemain == -1) {
143:                            cLenRemain = cLen;
144:                        }
145:
146:                        // So we know how to build the eventual run
147:                        int runLen = -1;
148:                        boolean pShared = false;
149:                        boolean cShared = false;
150:
151:                        // Same size, new styles - neither shared
152:                        if (pLen == cLen && freshSet) {
153:                            runLen = cLen;
154:                            pShared = false;
155:                            cShared = false;
156:                            curP++;
157:                            curC++;
158:                            pLenRemain = -1;
159:                            cLenRemain = -1;
160:                        } else {
161:                            // Some sharing
162:
163:                            // See if we are already in a shared block
164:                            if (pLenRemain < pLen) {
165:                                // Existing shared p block
166:                                pShared = true;
167:
168:                                // Do we end with the c block, or either side of it?
169:                                if (pLenRemain == cLenRemain) {
170:                                    // We end at the same time
171:                                    cShared = false;
172:                                    runLen = pLenRemain;
173:                                    curP++;
174:                                    curC++;
175:                                    pLenRemain = -1;
176:                                    cLenRemain = -1;
177:                                } else if (pLenRemain < cLenRemain) {
178:                                    // We end before the c block
179:                                    cShared = true;
180:                                    runLen = pLenRemain;
181:                                    curP++;
182:                                    cLenRemain -= pLenRemain;
183:                                    pLenRemain = -1;
184:                                } else {
185:                                    // We end after the c block
186:                                    cShared = false;
187:                                    runLen = cLenRemain;
188:                                    curC++;
189:                                    pLenRemain -= cLenRemain;
190:                                    cLenRemain = -1;
191:                                }
192:                            } else if (cLenRemain < cLen) {
193:                                // Existing shared c block
194:                                cShared = true;
195:
196:                                // Do we end with the p block, or either side of it?
197:                                if (pLenRemain == cLenRemain) {
198:                                    // We end at the same time
199:                                    pShared = false;
200:                                    runLen = cLenRemain;
201:                                    curP++;
202:                                    curC++;
203:                                    pLenRemain = -1;
204:                                    cLenRemain = -1;
205:                                } else if (cLenRemain < pLenRemain) {
206:                                    // We end before the p block
207:                                    pShared = true;
208:                                    runLen = cLenRemain;
209:                                    curC++;
210:                                    pLenRemain -= cLenRemain;
211:                                    cLenRemain = -1;
212:                                } else {
213:                                    // We end after the p block
214:                                    pShared = false;
215:                                    runLen = pLenRemain;
216:                                    curP++;
217:                                    cLenRemain -= pLenRemain;
218:                                    pLenRemain = -1;
219:                                }
220:                            } else {
221:                                // Start of a shared block
222:                                if (pLenRemain < cLenRemain) {
223:                                    // Shared c block
224:                                    pShared = false;
225:                                    cShared = true;
226:                                    runLen = pLenRemain;
227:                                    curP++;
228:                                    cLenRemain -= pLenRemain;
229:                                    pLenRemain = -1;
230:                                } else {
231:                                    // Shared p block
232:                                    pShared = true;
233:                                    cShared = false;
234:                                    runLen = cLenRemain;
235:                                    curC++;
236:                                    pLenRemain -= cLenRemain;
237:                                    cLenRemain = -1;
238:                                }
239:                            }
240:                        }
241:
242:                        // Wind on
243:                        int prevPos = pos;
244:                        pos += runLen;
245:                        // Adjust for end-of-run extra 1 length
246:                        if (pos > runRawText.length()) {
247:                            runLen--;
248:                        }
249:
250:                        // Save
251:                        RichTextRun rtr = new RichTextRun(this , prevPos,
252:                                runLen, pProps, cProps, pShared, cShared);
253:                        rtrs.add(rtr);
254:                    }
255:
256:                    // Build the array
257:                    _rtRuns = new RichTextRun[rtrs.size()];
258:                    rtrs.copyInto(_rtRuns);
259:                }
260:            }
261:
262:            // Update methods follow
263:
264:            /**
265:             * Saves the given string to the records. Doesn't touch the stylings. 
266:             */
267:            private void storeText(String s) {
268:                // Remove a single trailing \n, as there is an implicit one at the
269:                //  end of every record
270:                if (s.endsWith("\n")) {
271:                    s = s.substring(0, s.length() - 1);
272:                }
273:
274:                // Store in the appropriate record
275:                if (_isUnicode) {
276:                    // The atom can safely convert to unicode
277:                    _charAtom.setText(s);
278:                } else {
279:                    // Will it fit in a 8 bit atom?
280:                    boolean hasMultibyte = StringUtil.hasMultibyte(s);
281:                    if (!hasMultibyte) {
282:                        // Fine to go into 8 bit atom
283:                        byte[] text = new byte[s.length()];
284:                        StringUtil.putCompressedUnicode(s, text, 0);
285:                        _byteAtom.setText(text);
286:                    } else {
287:                        // Need to swap a TextBytesAtom for a TextCharsAtom
288:
289:                        // Build the new TextCharsAtom
290:                        _charAtom = new TextCharsAtom();
291:                        _charAtom.setText(s);
292:
293:                        // Use the TextHeaderAtom to do the swap on the parent
294:                        RecordContainer parent = _headerAtom.getParentRecord();
295:                        Record[] cr = parent.getChildRecords();
296:                        for (int i = 0; i < cr.length; i++) {
297:                            // Look for TextBytesAtom
298:                            if (cr[i].equals(_byteAtom)) {
299:                                // Found it, so replace, then all done
300:                                cr[i] = _charAtom;
301:                                break;
302:                            }
303:                        }
304:
305:                        // Flag the change
306:                        _byteAtom = null;
307:                        _isUnicode = true;
308:                    }
309:                }
310:            }
311:
312:            /**
313:             * Handles an update to the text stored in one of the Rich Text Runs
314:             * @param run
315:             * @param s
316:             */
317:            public synchronized void changeTextInRichTextRun(RichTextRun run,
318:                    String s) {
319:                // Figure out which run it is
320:                int runID = -1;
321:                for (int i = 0; i < _rtRuns.length; i++) {
322:                    if (run.equals(_rtRuns[i])) {
323:                        runID = i;
324:                    }
325:                }
326:                if (runID == -1) {
327:                    throw new IllegalArgumentException(
328:                            "Supplied RichTextRun wasn't from this TextRun");
329:                }
330:
331:                // Ensure a StyleTextPropAtom is present, adding if required
332:                ensureStyleAtomPresent();
333:
334:                // Update the text length for its Paragraph and Character stylings
335:                // If it's shared:
336:                //   * calculate the new length based on the run's old text
337:                //   * this should leave in any +1's for the end of block if needed
338:                // If it isn't shared:
339:                //   * reset the length, to the new string's length
340:                //   * add on +1 if the last block
341:                // The last run needs its stylings to be 1 longer than the raw
342:                //  text is. This is to define the stylings that any new text
343:                //  that is added will inherit
344:                TextPropCollection pCol = run._getRawParagraphStyle();
345:                TextPropCollection cCol = run._getRawCharacterStyle();
346:                int newSize = s.length();
347:                if (runID == _rtRuns.length - 1) {
348:                    newSize++;
349:                }
350:
351:                if (run._isParagraphStyleShared()) {
352:                    pCol.updateTextSize(pCol.getCharactersCovered()
353:                            - run.getLength() + s.length());
354:                } else {
355:                    pCol.updateTextSize(newSize);
356:                }
357:                if (run._isCharacterStyleShared()) {
358:                    cCol.updateTextSize(cCol.getCharactersCovered()
359:                            - run.getLength() + s.length());
360:                } else {
361:                    cCol.updateTextSize(newSize);
362:                }
363:
364:                // Build up the new text
365:                // As we go through, update the start position for all subsequent runs
366:                // The building relies on the old text still being present
367:                StringBuffer newText = new StringBuffer();
368:                for (int i = 0; i < _rtRuns.length; i++) {
369:                    int newStartPos = newText.length();
370:
371:                    // Build up the new text
372:                    if (i != runID) {
373:                        // Not the affected run, so keep old text
374:                        newText.append(_rtRuns[i].getRawText());
375:                    } else {
376:                        // Affected run, so use new text
377:                        newText.append(s);
378:                    }
379:
380:                    // Do we need to update the start position of this run?
381:                    // (Need to get the text before we update the start pos)
382:                    if (i <= runID) {
383:                        // Change is after this, so don't need to change start position
384:                    } else {
385:                        // Change has occured, so update start position
386:                        _rtRuns[i].updateStartPosition(newStartPos);
387:                    }
388:                }
389:
390:                // Now we can save the new text
391:                storeText(newText.toString());
392:            }
393:
394:            /**
395:             * Changes the text, and sets it all to have the same styling
396:             *  as the the first character has. 
397:             * If you care about styling, do setText on a RichTextRun instead 
398:             */
399:            public synchronized void setText(String s) {
400:                // Save the new text to the atoms
401:                storeText(s);
402:                RichTextRun fst = _rtRuns[0];
403:
404:                // Finally, zap and re-do the RichTextRuns
405:                for (int i = 0; i < _rtRuns.length; i++) {
406:                    _rtRuns[i] = null;
407:                }
408:                _rtRuns = new RichTextRun[1];
409:                _rtRuns[0] = fst;
410:
411:                // Now handle record stylings:
412:                // If there isn't styling
413:                //  no change, stays with no styling
414:                // If there is styling:
415:                //  everthing gets the same style that the first block has
416:                if (_styleAtom != null) {
417:                    LinkedList pStyles = _styleAtom.getParagraphStyles();
418:                    while (pStyles.size() > 1) {
419:                        pStyles.removeLast();
420:                    }
421:
422:                    LinkedList cStyles = _styleAtom.getCharacterStyles();
423:                    while (cStyles.size() > 1) {
424:                        cStyles.removeLast();
425:                    }
426:
427:                    _rtRuns[0].setText(s);
428:                } else {
429:                    // Recreate rich text run with no styling
430:                    _rtRuns[0] = new RichTextRun(this , 0, s.length());
431:                }
432:            }
433:
434:            /**
435:             * Ensure a StyleTextPropAtom is present for this run, 
436:             *  by adding if required. Normally for internal TextRun use.
437:             */
438:            public synchronized void ensureStyleAtomPresent() {
439:                if (_styleAtom != null) {
440:                    // All there
441:                    return;
442:                }
443:
444:                // Create a new one at the right size
445:                _styleAtom = new StyleTextPropAtom(getRawText().length() + 1);
446:
447:                // Use the TextHeader atom to get at the parent
448:                RecordContainer runAtomsParent = _headerAtom.getParentRecord();
449:
450:                // Add the new StyleTextPropAtom after the TextCharsAtom / TextBytesAtom
451:                Record addAfter = _byteAtom;
452:                if (_byteAtom == null) {
453:                    addAfter = _charAtom;
454:                }
455:                runAtomsParent.addChildAfter(_styleAtom, addAfter);
456:
457:                // Feed this to our sole rich text run
458:                if (_rtRuns.length != 1) {
459:                    throw new IllegalStateException(
460:                            "Needed to add StyleTextPropAtom when had many rich text runs");
461:                }
462:                // These are the only styles for now 
463:                _rtRuns[0].supplyTextProps((TextPropCollection) _styleAtom
464:                        .getParagraphStyles().get(0),
465:                        (TextPropCollection) _styleAtom.getCharacterStyles()
466:                                .get(0), false, false);
467:            }
468:
469:            // Accesser methods follow
470:
471:            /**
472:             * Returns the text content of the run, which has been made safe
473:             * for printing and other use.
474:             */
475:            public String getText() {
476:                String rawText = getRawText();
477:
478:                // PowerPoint seems to store files with \r as the line break
479:                // The messes things up on everything but a Mac, so translate
480:                //  them to \n
481:                String text = rawText.replace('\r', '\n');
482:                return text;
483:            }
484:
485:            /**
486:             * Returns the raw text content of the run. This hasn't had any
487:             *  changes applied to it, and so is probably unlikely to print
488:             *  out nicely.
489:             */
490:            public String getRawText() {
491:                if (_isUnicode) {
492:                    return _charAtom.getText();
493:                } else {
494:                    return _byteAtom.getText();
495:                }
496:            }
497:
498:            /**
499:             * Fetch the rich text runs (runs of text with the same styling) that
500:             *  are contained within this block of text
501:             */
502:            public RichTextRun[] getRichTextRuns() {
503:                return _rtRuns;
504:            }
505:
506:            /**
507:             * Returns the type of the text, from the TextHeaderAtom.
508:             * Possible values can be seen from TextHeaderAtom
509:             * @see org.apache.poi.hslf.record.TextHeaderAtom
510:             */
511:            public int getRunType() {
512:                return _headerAtom.getTextType();
513:            }
514:
515:            /**
516:             * Changes the type of the text. Values should be taken
517:             *  from TextHeaderAtom. No checking is done to ensure you
518:             *  set this to a valid value!
519:             * @see org.apache.poi.hslf.record.TextHeaderAtom
520:             */
521:            public void setRunType(int type) {
522:                _headerAtom.setTextType(type);
523:            }
524:
525:            /**
526:             * Supply the SlideShow we belong to.
527:             * Also passes it on to our child RichTextRuns
528:             */
529:            public void supplySlideShow(SlideShow ss) {
530:                slideShow = ss;
531:                if (_rtRuns != null) {
532:                    for (int i = 0; i < _rtRuns.length; i++) {
533:                        _rtRuns[i].supplySlideShow(slideShow);
534:                    }
535:                }
536:            }
537:
538:            public void setSheet(Sheet sheet) {
539:                this .sheet = sheet;
540:            }
541:
542:            public Sheet getSheet() {
543:                return this .sheet;
544:            }
545:
546:            /**
547:             * @return  Shape ID
548:             */
549:            protected int getShapeId() {
550:                return shapeId;
551:            }
552:
553:            /**
554:             *  @param id Shape ID
555:             */
556:            protected void setShapeId(int id) {
557:                shapeId = id;
558:            }
559:
560:            /**
561:             * @return  0-based index of the text run in the SLWT container
562:             */
563:            protected int getIndex() {
564:                return slwtIndex;
565:            }
566:
567:            /**
568:             *  @param id 0-based index of the text run in the SLWT container
569:             */
570:            protected void setIndex(int id) {
571:                slwtIndex = id;
572:            }
573:
574:            /**
575:             * Returns the array of all hyperlinks in this text run
576:             *
577:             * @return the array of all hyperlinks in this text run
578:             * or <code>null</code> if not found.
579:             */
580:            public Hyperlink[] getHyperlinks() {
581:                return Hyperlink.find(this);
582:            }
583:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.