LibreOffice Module sw (master) 1
ascfldlg.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20#include <sal/config.h>
21
22#include <optional>
23#include <utility>
24
25#include <hintids.hxx>
26#include <rtl/textenc.h>
28#include <com/sun/star/i18n/ScriptType.hpp>
29#include <unotools/lingucfg.hxx>
31#include <sfx2/sfxsids.hrc>
32#include <sfx2/printer.hxx>
33#include <sfx2/docfile.hxx>
35#include <editeng/langitem.hxx>
36#include <swtypes.hxx>
37#include <ascfldlg.hxx>
38#include <shellio.hxx>
39#include <docsh.hxx>
40#include <doc.hxx>
42
43#include <vcl/metric.hxx>
44
45using namespace ::com::sun::star;
46
47namespace
48{
49
50const sal_Unicode cDialogExtraDataClose = '}';
51const char sDialogImpExtraData[] = "EncImpDlg:{";
52const char sDialogExpExtraData[] = "EncExpDlg:{";
53const sal_Int32 nDialogExtraDataLen = 11; // 12345678901
54
55}
56
58 SvStream* pStream )
59 : SfxDialogController(pParent, "modules/swriter/ui/asciifilterdialog.ui", "AsciiFilterDialog")
60 , m_bSaveLineStatus(true)
61 , m_xCharSetLB(new SvxTextEncodingBox(m_xBuilder->weld_combo_box("charset")))
62 , m_xFontFT(m_xBuilder->weld_label("fontft"))
63 , m_xFontLB(m_xBuilder->weld_combo_box("font"))
64 , m_xLanguageFT(m_xBuilder->weld_label("languageft"))
65 , m_xLanguageLB(new SvxLanguageBox(m_xBuilder->weld_combo_box("language")))
66 , m_xCRLF_RB(m_xBuilder->weld_radio_button("crlf"))
67 , m_xCR_RB(m_xBuilder->weld_radio_button("cr"))
68 , m_xLF_RB(m_xBuilder->weld_radio_button("lf"))
69 , m_xIncludeBOM_CB(m_xBuilder->weld_check_button("includebom"))
70{
71 m_xFontLB->make_sorted();
72
73 SwAsciiOptions aOpt;
74 {
75 SvtViewOptions aDlgOpt(EViewType::Dialog, OStringToOUString(m_xDialog->get_help_id(), RTL_TEXTENCODING_UTF8));
76 if (aDlgOpt.Exists())
77 {
78 css::uno::Any aUserItem = aDlgOpt.GetUserItem("UserItem");
79 aUserItem >>= m_sExtraData;
80 }
81
82 const SfxStringItem* pItem;
83 OUString sAsciiOptions;
84 if( rDocSh.GetMedium() != nullptr &&
85 rDocSh.GetMedium()->GetItemSet() != nullptr &&
86 (pItem = rDocSh.GetMedium()->GetItemSet()->GetItemIfSet( SID_FILE_FILTEROPTIONS )))
87 {
88 sAsciiOptions = pItem->GetValue();
89 }
90
91 const OUString sFindNm = OUString::createFromAscii(
92 pStream ? sDialogImpExtraData
93 : sDialogExpExtraData);
94 sal_Int32 nStt = m_sExtraData.indexOf( sFindNm );
95 if( -1 != nStt )
96 {
97 nStt += nDialogExtraDataLen;
98 sal_Int32 nEnd = m_sExtraData.indexOf( cDialogExtraDataClose, nStt );
99 if( -1 != nEnd )
100 {
101 if(sAsciiOptions.isEmpty())
102 sAsciiOptions = m_sExtraData.copy(nStt, nEnd - nStt);
103 nStt -= nDialogExtraDataLen;
104 m_sExtraData = m_sExtraData.replaceAt(nStt, nEnd - nStt + 1, u"");
105 }
106 }
107 if(!sAsciiOptions.isEmpty())
108 aOpt.ReadUserData(sAsciiOptions);
109 }
110
111 // read the first chars and check the charset, (language - with L&H)
112 if( pStream )
113 {
114 char aBuffer[ 4098 ];
115 const sal_uInt64 nOldPos = pStream->Tell();
116 const size_t nBytesRead = pStream->ReadBytes(aBuffer, 4096);
117 pStream->Seek( nOldPos );
118
119 if( nBytesRead <= 4096 )
120 {
121 aBuffer[ nBytesRead ] = '0';
122 aBuffer[ nBytesRead+1 ] = '0';
123 }
124
125 bool bCR = false, bLF = false, bNullChar = false;
126 for( sal_uInt64 nCnt = 0; nCnt < nBytesRead; ++nCnt )
127 switch( aBuffer[ nCnt ] )
128 {
129 case 0x0: bNullChar = true; break;
130 case 0xA: bLF = true; break;
131 case 0xD: bCR = true; break;
132 case 0xC:
133 case 0x1A:
134 case 0x9: break;
135 default: break;
136 }
137
138 if( !bNullChar )
139 {
140 if( bCR )
141 {
142 if( bLF )
143 {
145 }
146 else
147 {
148 aOpt.SetParaFlags( LINEEND_CR );
149 }
150 }
151 else if( bLF )
152 {
153 aOpt.SetParaFlags( LINEEND_LF );
154 }
155 }
156
157 const sal_uInt16 nAppScriptType = SvtLanguageOptions::GetI18NScriptTypeOfLanguage( GetAppLanguage() );
158 SwDoc* pDoc = rDocSh.GetDoc();
159
160 // initialize language
161 {
162 if( !aOpt.GetLanguage() )
163 {
164 if(pDoc)
165 {
166 const sal_uInt16 nWhich = GetWhichOfScript( RES_CHRATR_LANGUAGE, nAppScriptType);
167 aOpt.SetLanguage( static_cast<const SvxLanguageItem&>(pDoc->
168 GetDefault( nWhich )).GetLanguage());
169 }
170 else
171 {
172 SvtLinguOptions aLinguOpt;
173 SvtLinguConfig().GetOptions( aLinguOpt );
174 switch(nAppScriptType)
175 {
176 case css::i18n::ScriptType::ASIAN:
177 aOpt.SetLanguage(MsLangId::resolveSystemLanguageByScriptType(aLinguOpt.nDefaultLanguage_CJK, css::i18n::ScriptType::ASIAN));
178 break;
179 case css::i18n::ScriptType::COMPLEX:
180 aOpt.SetLanguage(MsLangId::resolveSystemLanguageByScriptType(aLinguOpt.nDefaultLanguage_CTL, css::i18n::ScriptType::COMPLEX));
181 break;
182 //SvtScriptType::LATIN:
183 default:
184 aOpt.SetLanguage(MsLangId::resolveSystemLanguageByScriptType(aLinguOpt.nDefaultLanguage, css::i18n::ScriptType::LATIN));
185 }
186 }
187 }
188
189 m_xLanguageLB->SetLanguageList( SvxLanguageListFlags::ALL, true );
190 m_xLanguageLB->set_active_id(aOpt.GetLanguage());
191 }
192
193 {
194 bool bDelPrinter = false;
195 VclPtr<SfxPrinter> pPrt = pDoc ? pDoc->getIDocumentDeviceAccess().getPrinter(false) : nullptr;
196 if( !pPrt )
197 {
198 auto pSet = std::make_unique<SfxItemSetFixed
199 <SID_PRINTER_NOTFOUND_WARN, SID_PRINTER_NOTFOUND_WARN,
200 SID_PRINTER_CHANGESTODOC, SID_PRINTER_CHANGESTODOC>>( rDocSh.GetPool() );
201 pPrt = VclPtr<SfxPrinter>::Create( std::move(pSet) );
202 bDelPrinter = true;
203 }
204
205 // get the set of distinct available family names
206 std::set< OUString > aFontNames;
207 int nFontNames = pPrt->GetFontFaceCollectionCount();
208 for( int i = 0; i < nFontNames; i++ )
209 {
210 FontMetric aFontMetric( pPrt->GetFontMetricFromCollection( i ) );
211 aFontNames.insert( aFontMetric.GetFamilyName() );
212 }
213
214 // insert into listbox
215 for( const auto& rFontName : aFontNames )
216 {
217 m_xFontLB->append_text(rFontName);
218 }
219
220 if( aOpt.GetFontName().isEmpty() )
221 {
222 LanguageType eLang = aOpt.GetLanguage();
223 vcl::Font aTmpFont(OutputDevice::GetDefaultFont(DefaultFontType::FIXED, eLang, GetDefaultFontFlags::OnlyOne, pPrt));
224 aOpt.SetFontName(aTmpFont.GetFamilyName());
225 }
226
227 m_xFontLB->set_active_text(aOpt.GetFontName());
228
229 if( bDelPrinter )
230 pPrt.disposeAndClear();
231 }
232
233 // hide the unused Controls for Export
234 m_xIncludeBOM_CB->hide();
235 }
236 else
237 {
238 // hide the unused Controls for Export
239 m_xFontFT->hide();
240 m_xFontLB->hide();
241 m_xLanguageFT->hide();
242 m_xLanguageLB->hide();
243
244
246 m_xIncludeBOM_CB->save_state();
247 }
248
249 // initialize character set
250 m_xCharSetLB->FillFromTextEncodingTable( pStream != nullptr );
251 m_xCharSetLB->SelectTextEncoding( aOpt.GetCharSet() );
252
253 m_xCharSetLB->connect_changed( LINK( this, SwAsciiFilterDlg, CharSetSelHdl ));
254 m_xCRLF_RB->connect_toggled( LINK( this, SwAsciiFilterDlg, LineEndHdl ));
255 m_xLF_RB->connect_toggled( LINK( this, SwAsciiFilterDlg, LineEndHdl ));
256 m_xCR_RB->connect_toggled( LINK( this, SwAsciiFilterDlg, LineEndHdl ));
257
258 SetCRLF( aOpt.GetParaFlags() );
259
260 m_xCRLF_RB->save_state();
261 m_xLF_RB->save_state();
262 m_xCR_RB->save_state();
263
265}
266
268{
269 SvtViewOptions aDlgOpt(EViewType::Dialog, OStringToOUString(m_xDialog->get_help_id(), RTL_TEXTENCODING_UTF8));
270 aDlgOpt.SetUserItem("UserItem", uno::Any(m_sExtraData));
271}
272
274{
275 sal_uLong nCCode = m_xCharSetLB->GetSelectTextEncoding();
276 OUString sFont;
278 if (m_xFontLB->get_visible())
279 {
280 sFont = m_xFontLB->get_active_text();
281 nLng = m_xLanguageLB->get_active_id();
282 }
283
284 rOptions.SetFontName( sFont );
285 rOptions.SetCharSet( rtl_TextEncoding( nCCode ) );
286 rOptions.SetLanguage( nLng );
287 rOptions.SetParaFlags( GetCRLF() );
288 rOptions.SetIncludeBOM( GetIncludeBOM() );
289
290 // save the user settings
291 OUString sData;
292 rOptions.WriteUserData( sData );
293 if (sData.isEmpty())
294 return;
295
296 const OUString sFindNm = OUString::createFromAscii(
297 m_xFontLB->get_visible() ? sDialogImpExtraData
298 : sDialogExpExtraData);
299 sal_Int32 nStt = m_sExtraData.indexOf( sFindNm );
300 if( -1 != nStt )
301 {
302 // called twice, so remove "old" settings
303 sal_Int32 nEnd = m_sExtraData.indexOf( cDialogExtraDataClose,
304 nStt + nDialogExtraDataLen );
305 if( -1 != nEnd )
306 m_sExtraData = m_sExtraData.replaceAt( nStt, nEnd - nStt + 1, u"" );
307 }
308 m_sExtraData += sFindNm + sData + OUStringChar(cDialogExtraDataClose);
309}
310
312{
313 switch (eEnd)
314 {
315 case LINEEND_CR:
316 m_xCR_RB->set_active(true);
317 break;
318 case LINEEND_CRLF:
319 m_xCRLF_RB->set_active(true);
320 break;
321 case LINEEND_LF:
322 m_xLF_RB->set_active(true);
323 break;
324 }
325}
326
328{
329 LineEnd eEnd;
330 if(m_xCR_RB->get_active())
331 eEnd = LINEEND_CR;
332 else if (m_xLF_RB->get_active())
333 eEnd = LINEEND_LF;
334 else
335 eEnd = LINEEND_CRLF;
336 return eEnd;
337}
338
339void SwAsciiFilterDlg::SetIncludeBOM( bool bIncludeBOM )
340{
341 m_xIncludeBOM_CB->set_state(bIncludeBOM ? TRISTATE_TRUE : TRISTATE_FALSE);
342}
343
345{
346 return m_xIncludeBOM_CB->get_state() != TRISTATE_FALSE;
347}
348
350{
351 if (!m_xIncludeBOM_CB->get_visible())
352 return;
353
354 switch (m_xCharSetLB->GetSelectTextEncoding())
355 {
356 case RTL_TEXTENCODING_UTF8:
357 case RTL_TEXTENCODING_UCS2:
358 m_xIncludeBOM_CB->set_sensitive(true);
359 break;
360 default:
361 m_xIncludeBOM_CB->set_sensitive(false);
362 break;
363 }
364}
365
367{
368 LineEnd eOldEnd = GetCRLF();
369 std::optional<LineEnd> eEnd;
370 LanguageType nLng = m_xFontLB->get_visible()
371 ? m_xLanguageLB->get_active_id()
373 nOldLng = nLng;
374
375 rtl_TextEncoding nChrSet = m_xCharSetLB->GetSelectTextEncoding();
376 if( nChrSet == osl_getThreadTextEncoding() )
377 eEnd = GetSystemLineEnd();
378 else
379 {
380 switch( nChrSet )
381 {
382 case RTL_TEXTENCODING_MS_1252:
383#ifdef UNX
384 eEnd = LINEEND_LF;
385#else
386 eEnd = LINEEND_CRLF; // ANSI
387#endif
388 break;
389
390 case RTL_TEXTENCODING_APPLE_ROMAN: // MAC
391 eEnd = LINEEND_CR;
392 break;
393
394 case RTL_TEXTENCODING_IBM_850: // DOS
395 eEnd = LINEEND_CRLF;
396 break;
397
398 case RTL_TEXTENCODING_APPLE_ARABIC:
399 case RTL_TEXTENCODING_APPLE_CENTEURO:
400 case RTL_TEXTENCODING_APPLE_CROATIAN:
401 case RTL_TEXTENCODING_APPLE_CYRILLIC:
402 case RTL_TEXTENCODING_APPLE_DEVANAGARI:
403 case RTL_TEXTENCODING_APPLE_FARSI:
404 case RTL_TEXTENCODING_APPLE_GREEK:
405 case RTL_TEXTENCODING_APPLE_GUJARATI:
406 case RTL_TEXTENCODING_APPLE_GURMUKHI:
407 case RTL_TEXTENCODING_APPLE_HEBREW:
408 case RTL_TEXTENCODING_APPLE_ICELAND:
409 case RTL_TEXTENCODING_APPLE_ROMANIAN:
410 case RTL_TEXTENCODING_APPLE_THAI:
411 case RTL_TEXTENCODING_APPLE_TURKISH:
412 case RTL_TEXTENCODING_APPLE_UKRAINIAN:
413 case RTL_TEXTENCODING_APPLE_CHINSIMP:
414 case RTL_TEXTENCODING_APPLE_CHINTRAD:
415 case RTL_TEXTENCODING_APPLE_JAPANESE:
416 case RTL_TEXTENCODING_APPLE_KOREAN:
417 eEnd = LINEEND_CR;
418 break;
419 }
420 }
421
422 m_bSaveLineStatus = false;
423 if( eEnd ) // changed?
424 {
425 if( eOldEnd != *eEnd )
426 SetCRLF( *eEnd );
427 }
428 else
429 {
430 // restore old user choice (not the automatic!)
431 m_xCRLF_RB->set_state(m_xCRLF_RB->get_saved_state());
432 m_xCR_RB->set_state(m_xCR_RB->get_saved_state());
433 m_xLF_RB->set_state(m_xLF_RB->get_saved_state());
434 }
435 m_bSaveLineStatus = true;
436
437 if (nOldLng != nLng && m_xFontLB->get_visible())
438 m_xLanguageLB->set_active_id(nLng);
439
440 UpdateIncludeBOMSensitiveState();
441}
442
444{
445 if (m_bSaveLineStatus)
446 rBtn.save_state();
447}
448
449/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
IMPL_LINK(SwAsciiFilterDlg, LineEndHdl, weld::Toggleable &, rBtn, void)
Definition: ascfldlg.cxx:443
IMPL_LINK_NOARG(SwAsciiFilterDlg, CharSetSelHdl, weld::ComboBox &, void)
Definition: ascfldlg.cxx:366
Reference< XExecutableDialog > m_xDialog
const OUString & GetValue() const
virtual SfxPrinter * getPrinter(bool bCreate) const =0
Return the printer set at the document.
static LanguageType resolveSystemLanguageByScriptType(LanguageType nLang, sal_Int16 nType)
static vcl::Font GetDefaultFont(DefaultFontType nType, LanguageType eLang, GetDefaultFontFlags nFlags, const OutputDevice *pOutDev=nullptr)
const T * GetItemIfSet(TypedWhichId< T > nWhich, bool bSrchInParent=true) const
SfxItemSet * GetItemSet() const
SfxMedium * GetMedium() const
SfxItemPool & GetPool() const
sal_uInt64 Tell() const
sal_uInt64 Seek(sal_uInt64 nPos)
std::size_t ReadBytes(void *pData, std::size_t nSize)
void GetOptions(SvtLinguOptions &rOptions) const
css::uno::Any GetUserItem(const OUString &sName) const
void SetUserItem(const OUString &sName, const css::uno::Any &aValue)
bool Exists() const
SwAsciiFilterDlg(weld::Window *pParent, SwDocShell &rDocSh, SvStream *pStream)
Definition: ascfldlg.cxx:57
std::unique_ptr< weld::Label > m_xFontFT
Definition: ascfldlg.hxx:37
OUString m_sExtraData
Definition: ascfldlg.hxx:34
void SetCRLF(LineEnd eEnd)
Definition: ascfldlg.cxx:311
std::unique_ptr< weld::Label > m_xLanguageFT
Definition: ascfldlg.hxx:39
LineEnd GetCRLF() const
Definition: ascfldlg.cxx:327
void UpdateIncludeBOMSensitiveState()
Definition: ascfldlg.cxx:349
std::unique_ptr< weld::RadioButton > m_xCRLF_RB
Definition: ascfldlg.hxx:41
void SetIncludeBOM(bool bIncludeBOM)
Definition: ascfldlg.cxx:339
virtual ~SwAsciiFilterDlg() override
Definition: ascfldlg.cxx:267
std::unique_ptr< weld::RadioButton > m_xLF_RB
Definition: ascfldlg.hxx:43
std::unique_ptr< SvxTextEncodingBox > m_xCharSetLB
Definition: ascfldlg.hxx:36
void FillOptions(SwAsciiOptions &rOptions)
Definition: ascfldlg.cxx:273
bool GetIncludeBOM() const
Definition: ascfldlg.cxx:344
std::unique_ptr< weld::CheckButton > m_xIncludeBOM_CB
Definition: ascfldlg.hxx:44
std::unique_ptr< weld::ComboBox > m_xFontLB
Definition: ascfldlg.hxx:38
std::unique_ptr< weld::RadioButton > m_xCR_RB
Definition: ascfldlg.hxx:42
std::unique_ptr< SvxLanguageBox > m_xLanguageLB
Definition: ascfldlg.hxx:40
void WriteUserData(OUString &) const
Definition: fltini.cxx:573
void SetLanguage(LanguageType nVal)
Definition: shellio.hxx:80
void SetFontName(const OUString &rFont)
Definition: shellio.hxx:74
rtl_TextEncoding GetCharSet() const
Definition: shellio.hxx:76
LanguageType GetLanguage() const
Definition: shellio.hxx:79
LineEnd GetParaFlags() const
Definition: shellio.hxx:82
void SetIncludeBOM(bool bVal)
Definition: shellio.hxx:86
void SetParaFlags(LineEnd eVal)
Definition: shellio.hxx:83
const OUString & GetFontName() const
Definition: shellio.hxx:73
void SetCharSet(rtl_TextEncoding nVal)
Definition: shellio.hxx:77
bool GetIncludeBOM() const
Definition: shellio.hxx:85
void ReadUserData(std::u16string_view)
Definition: fltini.cxx:547
SwDoc * GetDoc()
returns Doc. But be careful!
Definition: docsh.hxx:204
Definition: doc.hxx:195
IDocumentDeviceAccess const & getIDocumentDeviceAccess() const
Definition: doc.cxx:246
void disposeAndClear()
static VclPtr< reference_type > Create(Arg &&... arg)
const OUString & GetFamilyName() const
float u
TRISTATE_FALSE
TRISTATE_TRUE
constexpr TypedWhichId< SvxLanguageItem > RES_CHRATR_LANGUAGE(10)
sal_uInt16 GetWhichOfScript(sal_uInt16 nWhich, sal_uInt16 nScript)
Definition: hints.cxx:184
LanguageType GetAppLanguage()
Definition: init.cxx:739
#define LANGUAGE_SYSTEM
LineEnd
LINEEND_LF
LINEEND_CRLF
LINEEND_CR
LineEnd GetSystemLineEnd()
sal_Int16 GetI18NScriptTypeOfLanguage(LanguageType nLang)
LanguageType GetLanguage(SfxItemSet const &aSet, sal_uInt16 nLangWhichId)
Definition: langhelper.cxx:393
int i
sal_uIntPtr sal_uLong
LanguageType nDefaultLanguage
LanguageType nDefaultLanguage_CTL
LanguageType nDefaultLanguage_CJK
sal_uInt16 sal_Unicode
std::unique_ptr< char[]> aBuffer