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 <osl/endian.h>
28 #include <tools/stream.hxx>
29 #include <pam.hxx>
30 #include <doc.hxx>
31 #include <ndtxt.hxx>
32 #include <mdiexp.hxx> // ...Percent()
33 #include <docary.hxx>
34 #include <fmtcntnt.hxx>
35 #include <frmfmt.hxx>
36 #include <wrtasc.hxx>
37
38 #ifndef _STATSTR_HRC
39 #include <statstr.hrc> // ResId fuer Statusleiste
40 #endif
41
42 //-----------------------------------------------------------------
43
SwASCWriter(const String & rFltNm)44 SwASCWriter::SwASCWriter( const String& rFltNm )
45 {
46 SwAsciiOptions aNewOpts;
47
48 switch( 5 <= rFltNm.Len() ? rFltNm.GetChar( 4 ) : 0 )
49 {
50 case 'D':
51 #if !defined(PM2)
52 aNewOpts.SetCharSet( RTL_TEXTENCODING_IBM_850 );
53 aNewOpts.SetParaFlags( LINEEND_CRLF );
54 #endif
55 if( 5 < rFltNm.Len() )
56 switch( rFltNm.Copy( 5 ).ToInt32() )
57 {
58 case 437: aNewOpts.SetCharSet( RTL_TEXTENCODING_IBM_437 ); break;
59 case 850: aNewOpts.SetCharSet( RTL_TEXTENCODING_IBM_850 ); break;
60 case 860: aNewOpts.SetCharSet( RTL_TEXTENCODING_IBM_860 ); break;
61 case 861: aNewOpts.SetCharSet( RTL_TEXTENCODING_IBM_861 ); break;
62 case 863: aNewOpts.SetCharSet( RTL_TEXTENCODING_IBM_863 ); break;
63 case 865: aNewOpts.SetCharSet( RTL_TEXTENCODING_IBM_865 ); break;
64 }
65 break;
66
67 case 'A':
68 #if !defined(WNT)
69 aNewOpts.SetCharSet( RTL_TEXTENCODING_MS_1252 );
70 aNewOpts.SetParaFlags( LINEEND_CRLF );
71 #endif
72 break;
73
74 case 'M':
75 aNewOpts.SetCharSet( RTL_TEXTENCODING_APPLE_ROMAN );
76 aNewOpts.SetParaFlags( LINEEND_CR );
77 break;
78
79 case 'X':
80 #if !defined(UNX)
81 aNewOpts.SetCharSet( RTL_TEXTENCODING_MS_1252 );
82 aNewOpts.SetParaFlags( LINEEND_LF );
83 #endif
84 break;
85
86 default:
87 if( rFltNm.Copy( 4 ).EqualsAscii( "_DLG" ))
88 {
89 // use the options
90 aNewOpts = GetAsciiOptions();
91 }
92 }
93 SetAsciiOptions( aNewOpts );
94 }
95
~SwASCWriter()96 SwASCWriter::~SwASCWriter() {}
97
WriteStream()98 sal_uLong SwASCWriter::WriteStream()
99 {
100 sal_Char cLineEnd[ 3 ];
101 sal_Char* pCEnd = cLineEnd;
102 if( bASCII_ParaAsCR ) // falls vorgegeben ist.
103 *pCEnd++ = '\015';
104 else if( bASCII_ParaAsBlanc )
105 *pCEnd++ = ' ';
106 else
107 switch( GetAsciiOptions().GetParaFlags() )
108 {
109 case LINEEND_CR: *pCEnd++ = '\015'; break;
110 case LINEEND_LF: *pCEnd++ = '\012'; break;
111 case LINEEND_CRLF: *pCEnd++ = '\015', *pCEnd++ = '\012'; break;
112 }
113 *pCEnd = 0;
114
115 sLineEnd.AssignAscii( cLineEnd );
116
117 long nMaxNode = pDoc->GetNodes().Count();
118
119 if( bShowProgress )
120 ::StartProgress( STR_STATSTR_W4WWRITE, 0, nMaxNode, pDoc->GetDocShell() );
121
122 SwPaM* pPam = pOrigPam;
123
124 sal_Bool bWriteSttTag = bUCS2_WithStartChar &&
125 (RTL_TEXTENCODING_UCS2 == GetAsciiOptions().GetCharSet() ||
126 RTL_TEXTENCODING_UTF8 == GetAsciiOptions().GetCharSet());
127
128 rtl_TextEncoding eOld = Strm().GetStreamCharSet();
129 Strm().SetStreamCharSet( GetAsciiOptions().GetCharSet() );
130
131 // gebe alle Bereich des Pams in das ASC-File aus.
132 do {
133 sal_Bool bTstFly = sal_True;
134 while( pCurPam->GetPoint()->nNode.GetIndex() < pCurPam->GetMark()->nNode.GetIndex() ||
135 (pCurPam->GetPoint()->nNode.GetIndex() == pCurPam->GetMark()->nNode.GetIndex() &&
136 pCurPam->GetPoint()->nContent.GetIndex() <= pCurPam->GetMark()->nContent.GetIndex()) )
137 {
138 SwTxtNode* pNd = pCurPam->GetPoint()->nNode.GetNode().GetTxtNode();
139 if( pNd )
140 {
141 // sollten nur Rahmen vorhanden sein?
142 // (Moeglich, wenn Rahmen-Selektion ins Clipboard
143 // gestellt wurde)
144 if( bTstFly && bWriteAll &&
145 // keine Laenge
146 !pNd->GetTxt().Len() &&
147 // Rahmen vorhanden
148 pDoc->GetSpzFrmFmts()->Count() &&
149 // nur ein Node im Array
150 pDoc->GetNodes().GetEndOfExtras().GetIndex() + 3 ==
151 pDoc->GetNodes().GetEndOfContent().GetIndex() &&
152 // und genau der ist selektiert
153 pDoc->GetNodes().GetEndOfContent().GetIndex() - 1 ==
154 pCurPam->GetPoint()->nNode.GetIndex() )
155 {
156 // dann den Inhalt vom Rahmen ausgeben.
157 // dieser steht immer an Position 0 !!
158 SwFrmFmt* pFmt = (*pDoc->GetSpzFrmFmts())[ 0 ];
159 const SwNodeIndex* pIdx = pFmt->GetCntnt().GetCntntIdx();
160 if( pIdx )
161 {
162 delete pCurPam;
163 pCurPam = NewSwPaM( *pDoc, pIdx->GetIndex(),
164 pIdx->GetNode().EndOfSectionIndex() );
165 pCurPam->Exchange();
166 continue; // while-Schleife neu aufsetzen !!
167 }
168 }
169 else
170 {
171 if (bWriteSttTag)
172 {
173 switch(GetAsciiOptions().GetCharSet())
174 {
175 case RTL_TEXTENCODING_UTF8:
176 Strm() << sal_uInt8(0xEF) << sal_uInt8(0xBB) <<
177 sal_uInt8(0xBF);
178 break;
179 case RTL_TEXTENCODING_UCS2:
180 //Strm().StartWritingUnicodeText();
181 Strm().SetEndianSwap(sal_False);
182 #ifdef OSL_LITENDIAN
183 Strm() << sal_uInt8(0xFF) << sal_uInt8(0xFE);
184 #else
185 Strm() << sal_uInt8(0xFE) << sal_uInt8(0xFF);
186 #endif
187 break;
188
189 }
190 bWriteSttTag = sal_False;
191 }
192 Out( aASCNodeFnTab, *pNd, *this );
193 }
194 bTstFly = sal_False; // eimal Testen reicht
195 }
196
197 if( !pCurPam->Move( fnMoveForward, fnGoNode ) )
198 break;
199
200 if( bShowProgress )
201 ::SetProgressState( pCurPam->GetPoint()->nNode.GetIndex(),
202 pDoc->GetDocShell() ); // Wie weit ?
203
204 }
205 } while( CopyNextPam( &pPam ) ); // bis alle Pam bearbeitet
206
207 Strm().SetStreamCharSet( eOld );
208
209 if( bShowProgress )
210 ::EndProgress( pDoc->GetDocShell() );
211
212 return 0;
213 }
214
215
GetASCWriter(const String & rFltNm,const String &,WriterRef & xRet)216 void GetASCWriter( const String& rFltNm, const String& /*rBaseURL*/, WriterRef& xRet )
217 {
218 xRet = new SwASCWriter( rFltNm );
219 }
220
221
222