Revert "tdf#158280 Replace usage of InputDialog with SvxNameDialog"
[LibreOffice.git] / sw / source / filter / ascii / wrtasc.cxx
blob6b7ada9bd87e68b7c6803529b52cefa2fc5e8400
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <osl/endian.h>
21 #include <tools/stream.hxx>
22 #include <pam.hxx>
23 #include <doc.hxx>
24 #include <ndtxt.hxx>
25 #include <mdiexp.hxx>
26 #include <fmtcntnt.hxx>
27 #include <frmfmt.hxx>
28 #include "wrtasc.hxx"
29 #include <frameformats.hxx>
30 #include <sfx2/docfile.hxx>
31 #include <sfx2/sfxsids.hrc>
32 #include <o3tl/string_view.hxx>
34 #include <strings.hrc>
36 SwASCWriter::SwASCWriter( std::u16string_view rFltNm )
38 SwAsciiOptions aNewOpts;
40 switch( 5 <= rFltNm.size() ? rFltNm[4] : 0 )
42 case 'D':
43 aNewOpts.SetCharSet( RTL_TEXTENCODING_IBM_850 );
44 aNewOpts.SetParaFlags( LINEEND_CRLF );
45 if( 5 < rFltNm.size() )
47 std::u16string_view aFilterNum = rFltNm.substr( 5 );
48 switch( o3tl::toInt32(aFilterNum) )
50 case 437: aNewOpts.SetCharSet( RTL_TEXTENCODING_IBM_437 ); break;
51 case 850: aNewOpts.SetCharSet( RTL_TEXTENCODING_IBM_850 ); break;
52 case 860: aNewOpts.SetCharSet( RTL_TEXTENCODING_IBM_860 ); break;
53 case 861: aNewOpts.SetCharSet( RTL_TEXTENCODING_IBM_861 ); break;
54 case 863: aNewOpts.SetCharSet( RTL_TEXTENCODING_IBM_863 ); break;
55 case 865: aNewOpts.SetCharSet( RTL_TEXTENCODING_IBM_865 ); break;
58 break;
60 case 'A':
61 #ifndef _WIN32
62 aNewOpts.SetCharSet( RTL_TEXTENCODING_MS_1252 );
63 aNewOpts.SetParaFlags( LINEEND_CRLF );
64 #endif
65 break;
67 case 'M':
68 aNewOpts.SetCharSet( RTL_TEXTENCODING_APPLE_ROMAN );
69 aNewOpts.SetParaFlags( LINEEND_CR );
70 break;
72 case 'X':
73 #ifdef _WIN32
74 aNewOpts.SetCharSet( RTL_TEXTENCODING_MS_1252 );
75 aNewOpts.SetParaFlags( LINEEND_LF );
76 #endif
77 break;
79 default:
80 if( rFltNm.size() >= 4 && rFltNm.substr( 4 )==u"_DLG" )
82 // use the options
83 aNewOpts = GetAsciiOptions();
86 SetAsciiOptions( aNewOpts );
89 SwASCWriter::~SwASCWriter() {}
91 ErrCode SwASCWriter::WriteStream()
93 static constexpr OUString STR_CR = u"\015"_ustr;
94 static constexpr OUStringLiteral STR_LF = u"\012";
95 static constexpr OUStringLiteral STR_CRLF = u"\015\012";
96 static constexpr OUStringLiteral STR_BLANK = u" ";
97 bool bIncludeBOM = GetAsciiOptions().GetIncludeBOM();
98 bool bIncludeHidden = GetAsciiOptions().GetIncludeHidden();
100 if( m_bASCII_ParaAsCR ) // If predefined
101 m_sLineEnd = STR_CR;
102 else if( m_bASCII_ParaAsBlank )
103 m_sLineEnd = STR_BLANK;
104 else
105 switch( GetAsciiOptions().GetParaFlags() )
107 case LINEEND_CR: m_sLineEnd = STR_CR; break;
108 case LINEEND_LF: m_sLineEnd = STR_LF; break;
109 case LINEEND_CRLF: m_sLineEnd = STR_CRLF; break;
112 SwNodeOffset nMaxNode = m_pDoc->GetNodes().Count();
114 if( m_bShowProgress )
115 ::StartProgress( STR_STATSTR_W4WWRITE, 0, sal_Int32(nMaxNode), m_pDoc->GetDocShell() );
117 SwPaM* pPam = m_pOrigPam;
119 bool bWriteSttTag = m_bUCS2_WithStartChar &&
120 (RTL_TEXTENCODING_UCS2 == GetAsciiOptions().GetCharSet() ||
121 RTL_TEXTENCODING_UTF8 == GetAsciiOptions().GetCharSet());
123 rtl_TextEncoding eOld = Strm().GetStreamCharSet();
124 Strm().SetStreamCharSet( GetAsciiOptions().GetCharSet() );
126 // Output all areas of the pam into the ASC file
127 do {
128 bool bTstFly = true;
129 while( m_pCurrentPam->GetPoint()->GetNodeIndex() < m_pCurrentPam->GetMark()->GetNodeIndex() ||
130 (m_pCurrentPam->GetPoint()->GetNodeIndex() == m_pCurrentPam->GetMark()->GetNodeIndex() &&
131 m_pCurrentPam->GetPoint()->GetContentIndex() <= m_pCurrentPam->GetMark()->GetContentIndex()) )
133 SwTextNode* pNd = m_pCurrentPam->GetPoint()->GetNode().GetTextNode();
134 if( pNd )
136 // Should we have frames only?
137 // That's possible, if we put a frame selection into the clipboard
138 if( bTstFly && m_bWriteAll &&
139 pNd->GetText().isEmpty() &&
140 // Frame exists
141 !m_pDoc->GetSpzFrameFormats()->empty() &&
142 // Only one node in the array
143 m_pDoc->GetNodes().GetEndOfExtras().GetIndex() + 3 ==
144 m_pDoc->GetNodes().GetEndOfContent().GetIndex() &&
145 // And exactly this one is selected
146 m_pDoc->GetNodes().GetEndOfContent().GetIndex() - 1 ==
147 m_pCurrentPam->GetPoint()->GetNodeIndex() )
149 // Print the frame's content.
150 // It is always at position 0!
151 const SwFrameFormat* pFormat = (*m_pDoc->GetSpzFrameFormats())[ 0 ];
152 const SwNodeIndex* pIdx = pFormat->GetContent().GetContentIdx();
153 if( pIdx )
155 m_pCurrentPam = NewUnoCursor(*m_pDoc, pIdx->GetIndex(),
156 pIdx->GetNode().EndOfSectionIndex() );
157 m_pCurrentPam->Exchange();
158 continue; // reset while loop!
161 else if (!pNd->IsHidden() || bIncludeHidden)
163 if (bWriteSttTag)
165 switch(GetAsciiOptions().GetCharSet())
167 case RTL_TEXTENCODING_UTF8:
168 if( bIncludeBOM )
170 Strm().WriteUChar( 0xEF ).WriteUChar( 0xBB ).WriteUChar( 0xBF );
173 break;
174 case RTL_TEXTENCODING_UCS2:
175 #ifdef OSL_LITENDIAN
176 Strm().SetEndian(SvStreamEndian::LITTLE);
177 #else
178 Strm().SetEndian(SvStreamEndian::BIG);
179 #endif
180 if( bIncludeBOM )
182 Strm().StartWritingUnicodeText();
184 break;
187 bWriteSttTag = false;
190 SwTableNode* pTableNd = pNd->FindTableNode();
192 // Handle a table
193 if (pTableNd && m_bWriteAll)
194 WriteTable(pTableNd, pNd);
195 else
196 Out( aASCNodeFnTab, *pNd, *this );
198 bTstFly = false; // Testing once is enough
201 if( !m_pCurrentPam->Move( fnMoveForward, GoInNode ) )
202 break;
204 if( m_bShowProgress )
205 ::SetProgressState( sal_Int32(m_pCurrentPam->GetPoint()->GetNodeIndex()),
206 m_pDoc->GetDocShell() ); // How far?
209 } while( CopyNextPam( &pPam ) ); // Until all pams are processed
211 Strm().SetStreamCharSet( eOld );
213 if( m_bShowProgress )
214 ::EndProgress( m_pDoc->GetDocShell() );
216 return ERRCODE_NONE;
219 void SwASCWriter::SetupFilterOptions(SfxMedium& rMedium)
221 if( const SfxStringItem* pItem = rMedium.GetItemSet().GetItemIfSet( SID_FILE_FILTEROPTIONS ) )
223 SwAsciiOptions aOpt;
224 OUString sItemOpt;
225 sItemOpt = pItem->GetValue();
226 aOpt.ReadUserData(sItemOpt);
227 SetAsciiOptions(aOpt);
231 void SwASCWriter::WriteTable(SwTableNode* pTableNd, SwTextNode* pNd)
233 OUString sPreLineEnd = this->m_sLineEnd;
234 m_sLineEnd = u""_ustr;
236 const SwTableLine* pEndTabLine = pTableNd->GetTable().GetTabLines().back();
237 const SwTableBox* pEndTabBox = pEndTabLine->GetTabBoxes().back();
239 for( const SwTableLine* pLine : pTableNd->GetTable().GetTabLines() )
241 for( const SwTableBox* pBox : pLine->GetTabBoxes() )
243 Out( aASCNodeFnTab, *pNd, *this );
245 Point aPrevBoxPoint;
246 const SwTableBox* pTableBox = pNd->GetTableBox();
247 if (pTableBox)
248 aPrevBoxPoint = pTableBox->GetCoordinates();
249 m_pCurrentPam->Move(fnMoveForward, GoInNode);
250 pNd = m_pCurrentPam->GetPoint()->GetNode().GetTextNode();
251 pTableBox = pNd->GetTableBox();
253 // Line break in a box
254 // Each line is a new SwTextNode so we
255 // need to parse inside the current box
256 while (pTableBox && pTableBox->GetCoordinates() == aPrevBoxPoint)
258 Strm().WriteUnicodeOrByteText(sPreLineEnd);
259 Out(aASCNodeFnTab, *pNd, *this);
261 m_pCurrentPam->Move(fnMoveForward, GoInNode);
262 pNd = m_pCurrentPam->GetPoint()->GetNode().GetTextNode();
263 pTableBox = pNd->GetTableBox();
265 if (pBox != pLine->GetTabBoxes().back())
266 Strm().WriteUChar( 0x9 );
268 if (pBox == pEndTabBox)
269 this->m_sLineEnd = sPreLineEnd;
271 }// end for each Box
273 if (pLine == pEndTabLine)
275 m_pCurrentPam->Move(fnMoveBackward, GoInNode);
276 pNd = m_pCurrentPam->GetPoint()->GetNode().GetTextNode();
277 Strm().WriteUnicodeOrByteText( sPreLineEnd );
279 if (pLine != pEndTabLine)
280 Strm().WriteUnicodeOrByteText( sPreLineEnd );
282 }// end For each row
283 this->m_sLineEnd = sPreLineEnd;
286 void GetASCWriter(
287 std::u16string_view rFltNm, [[maybe_unused]] const OUString& /*rBaseURL*/, WriterRef& xRet )
289 xRet = new SwASCWriter( rFltNm );
292 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */