1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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>
26 #include <fmtcntnt.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 )
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;
62 aNewOpts
.SetCharSet( RTL_TEXTENCODING_MS_1252
);
63 aNewOpts
.SetParaFlags( LINEEND_CRLF
);
68 aNewOpts
.SetCharSet( RTL_TEXTENCODING_APPLE_ROMAN
);
69 aNewOpts
.SetParaFlags( LINEEND_CR
);
74 aNewOpts
.SetCharSet( RTL_TEXTENCODING_MS_1252
);
75 aNewOpts
.SetParaFlags( LINEEND_LF
);
80 if( rFltNm
.size() >= 4 && rFltNm
.substr( 4 )==u
"_DLG" )
83 aNewOpts
= GetAsciiOptions();
86 SetAsciiOptions( aNewOpts
);
89 SwASCWriter::~SwASCWriter() {}
91 ErrCode
SwASCWriter::WriteStream()
93 static constexpr OUStringLiteral STR_CR
= u
"\015";
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
102 else if( m_bASCII_ParaAsBlank
)
103 m_sLineEnd
= STR_BLANK
;
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
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();
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() &&
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();
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
)
165 switch(GetAsciiOptions().GetCharSet())
167 case RTL_TEXTENCODING_UTF8
:
170 Strm().WriteUChar( 0xEF ).WriteUChar( 0xBB ).WriteUChar( 0xBF );
174 case RTL_TEXTENCODING_UCS2
:
176 Strm().SetEndian(SvStreamEndian::LITTLE
);
178 Strm().SetEndian(SvStreamEndian::BIG
);
182 Strm().StartWritingUnicodeText();
187 bWriteSttTag
= false;
189 Out( aASCNodeFnTab
, *pNd
, *this );
191 bTstFly
= false; // Testing once is enough
194 if( !m_pCurrentPam
->Move( fnMoveForward
, GoInNode
) )
197 if( m_bShowProgress
)
198 ::SetProgressState( sal_Int32(m_pCurrentPam
->GetPoint()->GetNodeIndex()),
199 m_pDoc
->GetDocShell() ); // How far?
202 } while( CopyNextPam( &pPam
) ); // Until all pams are processed
204 Strm().SetStreamCharSet( eOld
);
206 if( m_bShowProgress
)
207 ::EndProgress( m_pDoc
->GetDocShell() );
212 void SwASCWriter::SetupFilterOptions(SfxMedium
& rMedium
)
214 const SfxItemSet
* pSet
= rMedium
.GetItemSet();
215 if( nullptr != pSet
)
217 if( const SfxStringItem
* pItem
= pSet
->GetItemIfSet( SID_FILE_FILTEROPTIONS
) )
221 sItemOpt
= pItem
->GetValue();
222 aOpt
.ReadUserData(sItemOpt
);
223 SetAsciiOptions(aOpt
);
229 std::u16string_view rFltNm
, [[maybe_unused
]] const OUString
& /*rBaseURL*/, WriterRef
& xRet
)
231 xRet
= new SwASCWriter( rFltNm
);
234 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */