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 SwTxtNode& rNd;
49 : sal_Int32 nAktSwPos;
50 :
51 : sal_Int32 SearchNext( sal_Int32 nStartPos );
52 :
53 : public:
54 : SwASC_AttrIter( SwASCWriter& rWrt, const SwTxtNode& rNd, sal_Int32 nStt );
55 :
56 0 : void NextPos()
57 : {
58 0 : nAktSwPos = SearchNext( nAktSwPos + 1 );
59 0 : }
60 :
61 0 : sal_Int32 WhereNext() const
62 : {
63 0 : return nAktSwPos;
64 : }
65 :
66 : bool OutAttr( sal_Int32 nSwPos );
67 : };
68 :
69 0 : SwASC_AttrIter::SwASC_AttrIter(
70 : SwASCWriter& rWr,
71 : const SwTxtNode& rTxtNd,
72 : sal_Int32 nStt )
73 : : rWrt( rWr )
74 : , rNd( rTxtNd )
75 0 : , nAktSwPos( 0 )
76 : {
77 0 : nAktSwPos = SearchNext( nStt + 1 );
78 0 : }
79 :
80 0 : sal_Int32 SwASC_AttrIter::SearchNext( sal_Int32 nStartPos )
81 : {
82 0 : sal_Int32 nMinPos = SAL_MAX_INT32;
83 0 : const SwpHints* pTxtAttrs = rNd.GetpSwpHints();
84 0 : if( pTxtAttrs )
85 : {
86 : // TODO: This can be optimized, if we make use of the fact that the TxtAttrs
87 : // are sorted by starting position. We would need to remember two indices, however.
88 0 : for ( sal_uInt16 i = 0; i < pTxtAttrs->Count(); i++ )
89 : {
90 0 : const SwTxtAttr* pHt = (*pTxtAttrs)[i];
91 0 : if ( pHt->HasDummyChar() )
92 : {
93 0 : sal_Int32 nPos = *pHt->GetStart();
94 :
95 0 : if( nPos >= nStartPos && nPos <= nMinPos )
96 0 : nMinPos = nPos;
97 :
98 0 : if( ( ++nPos ) >= nStartPos && nPos < nMinPos )
99 0 : nMinPos = nPos;
100 : }
101 0 : 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 0 : return nMinPos;
118 : }
119 :
120 0 : bool SwASC_AttrIter::OutAttr( sal_Int32 nSwPos )
121 : {
122 0 : bool bRet = false;
123 0 : const SwpHints* pTxtAttrs = rNd.GetpSwpHints();
124 0 : if( pTxtAttrs )
125 : {
126 : sal_uInt16 i;
127 0 : for( i = 0; i < pTxtAttrs->Count(); i++ )
128 : {
129 0 : const SwTxtAttr* pHt = (*pTxtAttrs)[i];
130 0 : if ( ( pHt->HasDummyChar()
131 0 : || pHt->HasContent() )
132 0 : && nSwPos == *pHt->GetStart() )
133 : {
134 0 : bRet = true;
135 0 : OUString sOut;
136 0 : switch( pHt->Which() )
137 : {
138 : case RES_TXTATR_FIELD:
139 : case RES_TXTATR_ANNOTATION:
140 : case RES_TXTATR_INPUTFIELD:
141 0 : sOut = static_cast<SwTxtFld const*>(pHt)->GetFmtFld().GetField()->ExpandField(true);
142 0 : break;
143 :
144 : case RES_TXTATR_FTN:
145 : {
146 0 : const SwFmtFtn& rFtn = pHt->GetFtn();
147 0 : if( !rFtn.GetNumStr().isEmpty() )
148 0 : sOut = rFtn.GetNumStr();
149 0 : else if( rFtn.IsEndNote() )
150 0 : sOut = rWrt.pDoc->GetEndNoteInfo().aFmt.
151 0 : GetNumStr( rFtn.GetNumber() );
152 : else
153 0 : sOut = rWrt.pDoc->GetFtnInfo().aFmt.
154 0 : GetNumStr( rFtn.GetNumber() );
155 : }
156 0 : break;
157 : }
158 0 : if( !sOut.isEmpty() )
159 0 : rWrt.Strm().WriteUnicodeOrByteText( sOut );
160 : }
161 0 : else if( nSwPos < *pHt->GetStart() )
162 0 : break;
163 : }
164 : }
165 0 : return bRet;
166 : }
167 :
168 : // Output of the node
169 :
170 0 : static Writer& OutASC_SwTxtNode( Writer& rWrt, SwCntntNode& rNode )
171 : {
172 0 : const SwTxtNode& rNd = (SwTxtNode&)rNode;
173 :
174 0 : sal_Int32 nStrPos = rWrt.pCurPam->GetPoint()->nContent.GetIndex();
175 0 : const sal_Int32 nNodeEnd = rNd.Len();
176 0 : sal_Int32 nEnd = nNodeEnd;
177 0 : bool bLastNd = rWrt.pCurPam->GetPoint()->nNode == rWrt.pCurPam->GetMark()->nNode;
178 0 : if( bLastNd )
179 0 : nEnd = rWrt.pCurPam->GetMark()->nContent.GetIndex();
180 :
181 0 : SwASC_AttrIter aAttrIter( (SwASCWriter&)rWrt, rNd, nStrPos );
182 :
183 0 : if( !nStrPos && rWrt.bExportPargraphNumbering )
184 : {
185 0 : OUString numString( rNd.GetNumString() );
186 0 : if (!numString.isEmpty())
187 : {
188 0 : numString += " ";
189 0 : rWrt.Strm().WriteUnicodeOrByteText(numString);
190 0 : }
191 : }
192 :
193 0 : OUString aStr( rNd.GetTxt() );
194 0 : if( rWrt.bASCII_ParaAsBlanc )
195 0 : aStr = aStr.replace(0x0A, ' ');
196 :
197 0 : const bool bExportSoftHyphens = RTL_TEXTENCODING_UCS2 == rWrt.GetAsciiOptions().GetCharSet() ||
198 0 : RTL_TEXTENCODING_UTF8 == rWrt.GetAsciiOptions().GetCharSet();
199 :
200 0 : do {
201 0 : const sal_Int32 nNextAttr = std::min(aAttrIter.WhereNext(), nEnd);
202 :
203 0 : if( !aAttrIter.OutAttr( nStrPos ))
204 : {
205 0 : OUString aOutStr( aStr.copy( nStrPos, nNextAttr - nStrPos ) );
206 0 : if ( !bExportSoftHyphens )
207 0 : aOutStr = comphelper::string::remove(aOutStr, CHAR_SOFTHYPHEN);
208 :
209 0 : rWrt.Strm().WriteUnicodeOrByteText( aOutStr );
210 : }
211 0 : nStrPos = nNextAttr;
212 0 : aAttrIter.NextPos();
213 0 : } while( nStrPos < nEnd );
214 :
215 0 : if( !bLastNd ||
216 0 : ( ( !rWrt.bWriteClipboardDoc && !rWrt.bASCII_NoLastLineEnd )
217 0 : && !nStrPos && nEnd == nNodeEnd ) )
218 0 : rWrt.Strm().WriteUnicodeOrByteText( ((SwASCWriter&)rWrt).GetLineEnd());
219 :
220 0 : return rWrt;
221 : }
222 :
223 : /*
224 : * Create the table for the ASCII function pointers to the output
225 : * functon.
226 : * There are local structures that only need to be known to the ASCII DLL.
227 : */
228 :
229 : SwNodeFnTab aASCNodeFnTab = {
230 : /* RES_TXTNODE */ OutASC_SwTxtNode,
231 : /* RES_GRFNODE */ 0,
232 : /* RES_OLENODE */ 0
233 : };
234 :
235 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|