1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sw.hxx"
26 #include <hintids.hxx>
27 #include <tools/stream.hxx>
28 #ifndef _SVSTDARR_HXX
29 #define _SVSTDARR_USHORTS
30 #include <svl/svstdarr.hxx>
31 #endif
32 #include <editeng/fontitem.hxx>
33 #include <pam.hxx>
34 #include <doc.hxx>
35 #include <ndtxt.hxx>
36 #include <wrtasc.hxx>
37 #include <txatbase.hxx>
38 #include <fchrfmt.hxx>
39 #include <txtfld.hxx>
40 #include <txtatr.hxx>
41 #include <fmtftn.hxx>
42 #include <charfmt.hxx>
43 #include <fmtfld.hxx>
44 #include <fldbas.hxx>
45 #include <ftninfo.hxx>
46
47 /*
48 * Dieses File enthaelt alle Ausgabe-Funktionen des ASCII-Writers;
49 * fuer alle Nodes, Attribute, Formate und Chars.
50 */
51
52 class SwASC_AttrIter
53 {
54 SwASCWriter& rWrt;
55 const SwTxtNode& rNd;
56 xub_StrLen nAktSwPos;
57
58 xub_StrLen SearchNext( xub_StrLen nStartPos );
59
60 public:
61 SwASC_AttrIter( SwASCWriter& rWrt, const SwTxtNode& rNd, xub_StrLen nStt );
62
NextPos()63 void NextPos()
64 {
65 nAktSwPos = SearchNext( nAktSwPos + 1 );
66 }
67
WhereNext() const68 xub_StrLen WhereNext() const
69 {
70 return nAktSwPos;
71 }
72
73 sal_Bool OutAttr( xub_StrLen nSwPos );
74 };
75
76
SwASC_AttrIter(SwASCWriter & rWr,const SwTxtNode & rTxtNd,xub_StrLen nStt)77 SwASC_AttrIter::SwASC_AttrIter(
78 SwASCWriter& rWr,
79 const SwTxtNode& rTxtNd,
80 xub_StrLen nStt )
81 : rWrt( rWr )
82 , rNd( rTxtNd )
83 , nAktSwPos( 0 )
84 {
85 nAktSwPos = SearchNext( nStt + 1 );
86 }
87
88
SearchNext(xub_StrLen nStartPos)89 xub_StrLen SwASC_AttrIter::SearchNext( xub_StrLen nStartPos )
90 {
91 xub_StrLen nMinPos = STRING_MAXLEN;
92 const SwpHints* pTxtAttrs = rNd.GetpSwpHints();
93 if( pTxtAttrs )
94 {
95 for ( sal_uInt16 i = 0; i < pTxtAttrs->Count(); i++ )
96 {
97 const SwTxtAttr* pHt = (*pTxtAttrs)[i];
98 if ( pHt->HasDummyChar() )
99 {
100 xub_StrLen nPos = *pHt->GetStart();
101
102 if( nPos >= nStartPos && nPos <= nMinPos )
103 nMinPos = nPos;
104
105 if( ( ++nPos ) >= nStartPos && nPos < nMinPos )
106 nMinPos = nPos;
107 }
108 else if ( pHt->HasContent() )
109 {
110 const xub_StrLen nHintStart = *pHt->GetStart();
111 if ( nHintStart >= nStartPos && nHintStart <= nMinPos )
112 {
113 nMinPos = nHintStart;
114 }
115
116 const xub_StrLen nHintEnd = pHt->End() ? *pHt->End() : STRING_MAXLEN;
117 if ( nHintEnd >= nStartPos && nHintEnd < nMinPos )
118 {
119 nMinPos = nHintEnd;
120 }
121 }
122 }
123 }
124 return nMinPos;
125 }
126
127
OutAttr(xub_StrLen nSwPos)128 sal_Bool SwASC_AttrIter::OutAttr( xub_StrLen nSwPos )
129 {
130 sal_Bool bRet = sal_False;
131 const SwpHints* pTxtAttrs = rNd.GetpSwpHints();
132 if( pTxtAttrs )
133 {
134 sal_uInt16 i;
135 for( i = 0; i < pTxtAttrs->Count(); i++ )
136 {
137 const SwTxtAttr* pHt = (*pTxtAttrs)[i];
138 if ( ( pHt->HasDummyChar()
139 || pHt->HasContent() )
140 && nSwPos == *pHt->GetStart() )
141 {
142 bRet = sal_True;
143 String sOut;
144 switch( pHt->Which() )
145 {
146 case RES_TXTATR_FIELD:
147 case RES_TXTATR_ANNOTATION:
148 case RES_TXTATR_INPUTFIELD:
149 sOut = static_cast<SwTxtFld const*>(pHt)->GetFmtFld().GetField()->ExpandField(true);
150 break;
151
152 case RES_TXTATR_FTN:
153 {
154 const SwFmtFtn& rFtn = pHt->GetFtn();
155 if( rFtn.GetNumStr().Len() )
156 sOut = rFtn.GetNumStr();
157 else if( rFtn.IsEndNote() )
158 sOut = rWrt.pDoc->GetEndNoteInfo().aFmt.
159 GetNumStr( rFtn.GetNumber() );
160 else
161 sOut = rWrt.pDoc->GetFtnInfo().aFmt.
162 GetNumStr( rFtn.GetNumber() );
163 }
164 break;
165 }
166 if( sOut.Len() )
167 rWrt.Strm().WriteUnicodeOrByteText( sOut );
168 }
169 else if( nSwPos < *pHt->GetStart() )
170 break;
171 }
172 }
173 return bRet;
174 }
175
176
177 //------------------------
178 /* Ausgabe der Nodes */
179 //------------------------
180
OutASC_SwTxtNode(Writer & rWrt,SwCntntNode & rNode)181 static Writer& OutASC_SwTxtNode( Writer& rWrt, SwCntntNode& rNode )
182 {
183 const SwTxtNode& rNd = (SwTxtNode&)rNode;
184
185 xub_StrLen nStrPos = rWrt.pCurPam->GetPoint()->nContent.GetIndex();
186 xub_StrLen nNodeEnde = rNd.Len(), nEnde = nNodeEnde;
187 sal_Bool bLastNd = rWrt.pCurPam->GetPoint()->nNode == rWrt.pCurPam->GetMark()->nNode;
188 if( bLastNd )
189 nEnde = rWrt.pCurPam->GetMark()->nContent.GetIndex();
190
191 SwASC_AttrIter aAttrIter( (SwASCWriter&)rWrt, rNd, nStrPos );
192
193 if( !nStrPos && rWrt.bExportPargraphNumbering )
194 {
195 String numString( rNd.GetNumString() );
196 if (numString.Len())
197 {
198 numString.Append(' ');
199 rWrt.Strm().WriteUnicodeOrByteText(numString);
200 }
201 }
202
203 String aStr( rNd.GetTxt() );
204 if( rWrt.bASCII_ParaAsBlanc )
205 aStr.SearchAndReplaceAll( 0x0A, ' ' );
206
207 const bool bExportSoftHyphens = RTL_TEXTENCODING_UCS2 == rWrt.GetAsciiOptions().GetCharSet() ||
208 RTL_TEXTENCODING_UTF8 == rWrt.GetAsciiOptions().GetCharSet();
209
210 do {
211 xub_StrLen nNextAttr = aAttrIter.WhereNext();
212
213 if( nNextAttr > nEnde )
214 nNextAttr = nEnde;
215
216 if( !aAttrIter.OutAttr( nStrPos ))
217 {
218 String aOutStr( aStr.Copy( nStrPos, nNextAttr - nStrPos ) );
219 if ( !bExportSoftHyphens )
220 aOutStr.EraseAllChars( CHAR_SOFTHYPHEN );
221
222 rWrt.Strm().WriteUnicodeOrByteText( aOutStr );
223 }
224 nStrPos = nNextAttr;
225 aAttrIter.NextPos();
226 } while( nStrPos < nEnde );
227
228 if( !bLastNd ||
229 ( ( !rWrt.bWriteClipboardDoc && !rWrt.bASCII_NoLastLineEnd )
230 && !nStrPos && nEnde == nNodeEnde ) )
231 rWrt.Strm().WriteUnicodeOrByteText( ((SwASCWriter&)rWrt).GetLineEnd());
232
233 return rWrt;
234 }
235
236 /*
237 * lege hier jetzt die Tabellen fuer die ASCII-Funktions-Pointer auf
238 * die Ausgabe-Funktionen an.
239 * Es sind lokale Strukturen, die nur innerhalb der ASCII-DLL
240 * bekannt sein muessen.
241 */
242
243 SwNodeFnTab aASCNodeFnTab = {
244 /* RES_TXTNODE */ OutASC_SwTxtNode,
245 /* RES_GRFNODE */ 0,
246 /* RES_OLENODE */ 0
247 };
248
249