xref: /trunk/main/sw/source/filter/ascii/ascatr.cxx (revision dec99bbd)
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