Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <hintids.hxx>
21 : #include <tools/stream.hxx>
22 : #include <comphelper/string.hxx>
23 : #include <editeng/fontitem.hxx>
24 : #include <pam.hxx>
25 : #include <doc.hxx>
26 : #include <ndtxt.hxx>
27 : #include <wrtasc.hxx>
28 : #include <txatbase.hxx>
29 : #include <fchrfmt.hxx>
30 : #include <txtfld.hxx>
31 : #include <txtatr.hxx>
32 : #include <fmtftn.hxx>
33 : #include <charfmt.hxx>
34 : #include <fmtfld.hxx>
35 : #include <fldbas.hxx>
36 : #include <ftninfo.hxx>
37 :
38 : #include <algorithm>
39 :
40 : /*
41 : * This file contains all output functions of the ASCII-Writer;
42 : * For all nodes, attributes, formats and chars.
43 : */
44 :
45 : class SwASC_AttrIter
46 : {
47 : SwASCWriter& rWrt;
48 : const SwTextNode& rNd;
49 : sal_Int32 nAktSwPos;
50 :
51 : sal_Int32 SearchNext( sal_Int32 nStartPos );
52 :
53 : public:
54 : SwASC_AttrIter( SwASCWriter& rWrt, const SwTextNode& rNd, sal_Int32 nStt );
55 :
56 14 : void NextPos()
57 : {
58 14 : nAktSwPos = SearchNext( nAktSwPos + 1 );
59 14 : }
60 :
61 10775 : sal_Int32 WhereNext() const
62 : {
63 10775 : return nAktSwPos;
64 : }
65 :
66 : bool OutAttr( sal_Int32 nSwPos );
67 : };
68 :
69 10761 : SwASC_AttrIter::SwASC_AttrIter(
70 : SwASCWriter& rWr,
71 : const SwTextNode& rTextNd,
72 : sal_Int32 nStt )
73 : : rWrt( rWr )
74 : , rNd( rTextNd )
75 10761 : , nAktSwPos( 0 )
76 : {
77 10761 : nAktSwPos = SearchNext( nStt + 1 );
78 10761 : }
79 :
80 10775 : sal_Int32 SwASC_AttrIter::SearchNext( sal_Int32 nStartPos )
81 : {
82 10775 : sal_Int32 nMinPos = SAL_MAX_INT32;
83 10775 : const SwpHints* pTextAttrs = rNd.GetpSwpHints();
84 10775 : if( pTextAttrs )
85 : {
86 : // TODO: This can be optimized, if we make use of the fact that the TextAttrs
87 : // are sorted by starting position. We would need to remember two indices, however.
88 4326 : for ( size_t i = 0; i < pTextAttrs->Count(); ++i )
89 : {
90 3030 : const SwTextAttr* pHt = (*pTextAttrs)[i];
91 3030 : if ( pHt->HasDummyChar() )
92 : {
93 1068 : sal_Int32 nPos = pHt->GetStart();
94 :
95 1068 : if( nPos >= nStartPos && nPos <= nMinPos )
96 37 : nMinPos = nPos;
97 :
98 1068 : if( ( ++nPos ) >= nStartPos && nPos < nMinPos )
99 36 : nMinPos = nPos;
100 : }
101 1962 : else if ( pHt->HasContent() )
102 : {
103 0 : const sal_Int32 nHintStart = pHt->GetStart();
104 0 : if ( nHintStart >= nStartPos && nHintStart <= nMinPos )
105 : {
106 0 : nMinPos = nHintStart;
107 : }
108 :
109 0 : const sal_Int32 nHintEnd = pHt->End() ? *pHt->End() : COMPLETE_STRING;
110 0 : if ( nHintEnd >= nStartPos && nHintEnd < nMinPos )
111 : {
112 0 : nMinPos = nHintEnd;
113 : }
114 : }
115 : }
116 : }
117 10775 : return nMinPos;
118 : }
119 :
120 10775 : bool SwASC_AttrIter::OutAttr( sal_Int32 nSwPos )
121 : {
122 10775 : bool bRet = false;
123 10775 : const SwpHints* pTextAttrs = rNd.GetpSwpHints();
124 10775 : if( pTextAttrs )
125 : {
126 3929 : for( size_t i = 0; i < pTextAttrs->Count(); ++i )
127 : {
128 2758 : const SwTextAttr* pHt = (*pTextAttrs)[i];
129 5516 : if ( ( pHt->HasDummyChar()
130 1867 : || pHt->HasContent() )
131 3649 : && nSwPos == pHt->GetStart() )
132 : {
133 36 : bRet = true;
134 36 : OUString sOut;
135 36 : switch( pHt->Which() )
136 : {
137 : case RES_TXTATR_FIELD:
138 : case RES_TXTATR_ANNOTATION:
139 : case RES_TXTATR_INPUTFIELD:
140 57 : sOut = static_txtattr_cast<SwTextField const*>(pHt)
141 38 : ->GetFormatField().GetField()->ExpandField(true);
142 19 : break;
143 :
144 : case RES_TXTATR_FTN:
145 : {
146 0 : const SwFormatFootnote& rFootnote = pHt->GetFootnote();
147 0 : if( !rFootnote.GetNumStr().isEmpty() )
148 0 : sOut = rFootnote.GetNumStr();
149 0 : else if( rFootnote.IsEndNote() )
150 0 : sOut = rWrt.pDoc->GetEndNoteInfo().aFormat.
151 0 : GetNumStr( rFootnote.GetNumber() );
152 : else
153 0 : sOut = rWrt.pDoc->GetFootnoteInfo().aFormat.
154 0 : GetNumStr( rFootnote.GetNumber() );
155 : }
156 0 : break;
157 : }
158 36 : if( !sOut.isEmpty() )
159 16 : rWrt.Strm().WriteUnicodeOrByteText( sOut );
160 : }
161 2722 : else if( nSwPos < pHt->GetStart() )
162 125 : break;
163 : }
164 : }
165 10775 : return bRet;
166 : }
167 :
168 : // Output of the node
169 :
170 10761 : static Writer& OutASC_SwTextNode( Writer& rWrt, SwContentNode& rNode )
171 : {
172 10761 : const SwTextNode& rNd = static_cast<SwTextNode&>(rNode);
173 :
174 10761 : sal_Int32 nStrPos = rWrt.pCurPam->GetPoint()->nContent.GetIndex();
175 10761 : const sal_Int32 nNodeEnd = rNd.Len();
176 10761 : sal_Int32 nEnd = nNodeEnd;
177 10761 : bool bLastNd = rWrt.pCurPam->GetPoint()->nNode == rWrt.pCurPam->GetMark()->nNode;
178 10761 : if( bLastNd )
179 8075 : nEnd = rWrt.pCurPam->GetMark()->nContent.GetIndex();
180 :
181 10761 : SwASC_AttrIter aAttrIter( static_cast<SwASCWriter&>(rWrt), rNd, nStrPos );
182 :
183 10761 : if( !nStrPos && rWrt.bExportPargraphNumbering )
184 : {
185 4 : OUString numString( rNd.GetNumString() );
186 4 : if (!numString.isEmpty())
187 : {
188 0 : numString += " ";
189 0 : rWrt.Strm().WriteUnicodeOrByteText(numString);
190 4 : }
191 : }
192 :
193 10761 : OUString aStr( rNd.GetText() );
194 10761 : if( rWrt.bASCII_ParaAsBlanc )
195 0 : aStr = aStr.replace(0x0A, ' ');
196 :
197 10762 : const bool bExportSoftHyphens = RTL_TEXTENCODING_UCS2 == rWrt.GetAsciiOptions().GetCharSet() ||
198 10762 : RTL_TEXTENCODING_UTF8 == rWrt.GetAsciiOptions().GetCharSet();
199 :
200 : for (;;) {
201 10775 : const sal_Int32 nNextAttr = std::min(aAttrIter.WhereNext(), nEnd);
202 :
203 10775 : if( !aAttrIter.OutAttr( nStrPos ))
204 : {
205 10739 : OUString aOutStr( aStr.copy( nStrPos, nNextAttr - nStrPos ) );
206 10739 : if ( !bExportSoftHyphens )
207 0 : aOutStr = comphelper::string::remove(aOutStr, CHAR_SOFTHYPHEN);
208 :
209 10739 : rWrt.Strm().WriteUnicodeOrByteText( aOutStr );
210 : }
211 10775 : nStrPos = nNextAttr;
212 10775 : if (nStrPos >= nEnd)
213 : {
214 10761 : break;
215 : }
216 14 : aAttrIter.NextPos();
217 14 : }
218 :
219 18836 : if( !bLastNd ||
220 16150 : ( ( !rWrt.bWriteClipboardDoc && !rWrt.bASCII_NoLastLineEnd )
221 0 : && !nStrPos && nEnd == nNodeEnd ) )
222 2686 : rWrt.Strm().WriteUnicodeOrByteText( static_cast<SwASCWriter&>(rWrt).GetLineEnd());
223 :
224 10761 : return rWrt;
225 : }
226 :
227 : /*
228 : * Create the table for the ASCII function pointers to the output
229 : * functon.
230 : * There are local structures that only need to be known to the ASCII DLL.
231 : */
232 :
233 : SwNodeFnTab aASCNodeFnTab = {
234 : /* RES_TXTNODE */ OutASC_SwTextNode,
235 : /* RES_GRFNODE */ 0,
236 : /* RES_OLENODE */ 0
237 177 : };
238 :
239 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|