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 <sal/config.h>
25 #include <hintids.hxx>
26 #include <rtl/textenc.h>
27 #include <i18nlangtag/mslangid.hxx>
28 #include <com/sun/star/i18n/ScriptType.hpp>
29 #include <unotools/lingucfg.hxx>
30 #include <unotools/viewoptions.hxx>
31 #include <sfx2/sfxsids.hrc>
32 #include <sfx2/printer.hxx>
33 #include <sfx2/docfile.hxx>
34 #include <svl/languageoptions.hxx>
35 #include <editeng/langitem.hxx>
36 #include <swtypes.hxx>
37 #include <ascfldlg.hxx>
38 #include <shellio.hxx>
41 #include <IDocumentDeviceAccess.hxx>
43 #include <vcl/metric.hxx>
45 using namespace ::com::sun::star
;
50 const sal_Unicode cDialogExtraDataClose
= '}';
51 const char sDialogImpExtraData
[] = "EncImpDlg:{";
52 const char sDialogExpExtraData
[] = "EncExpDlg:{";
53 const sal_Int32 nDialogExtraDataLen
= 11; // 12345678901
57 SwAsciiFilterDlg::SwAsciiFilterDlg( weld::Window
* pParent
, SwDocShell
& rDocSh
,
59 : SfxDialogController(pParent
, u
"modules/swriter/ui/asciifilterdialog.ui"_ustr
, u
"AsciiFilterDialog"_ustr
)
60 , m_bSaveLineStatus(true)
61 , m_xCharSetLB(new SvxTextEncodingBox(m_xBuilder
->weld_combo_box(u
"charset"_ustr
)))
62 , m_xFontFT(m_xBuilder
->weld_label(u
"fontft"_ustr
))
63 , m_xFontLB(m_xBuilder
->weld_combo_box(u
"font"_ustr
))
64 , m_xLanguageFT(m_xBuilder
->weld_label(u
"languageft"_ustr
))
65 , m_xLanguageLB(new SvxLanguageBox(m_xBuilder
->weld_combo_box(u
"language"_ustr
)))
66 , m_xCRLF_RB(m_xBuilder
->weld_radio_button(u
"crlf"_ustr
))
67 , m_xCR_RB(m_xBuilder
->weld_radio_button(u
"cr"_ustr
))
68 , m_xLF_RB(m_xBuilder
->weld_radio_button(u
"lf"_ustr
))
69 , m_xIncludeBOM_CB(m_xBuilder
->weld_check_button(u
"includebom"_ustr
))
71 m_xFontLB
->make_sorted();
75 SvtViewOptions
aDlgOpt(EViewType::Dialog
, m_xDialog
->get_help_id());
78 css::uno::Any aUserItem
= aDlgOpt
.GetUserItem(u
"UserItem"_ustr
);
79 aUserItem
>>= m_sExtraData
;
82 const SfxStringItem
* pItem
;
83 OUString sAsciiOptions
;
84 if( rDocSh
.GetMedium() != nullptr &&
85 (pItem
= rDocSh
.GetMedium()->GetItemSet().GetItemIfSet( SID_FILE_FILTEROPTIONS
)))
87 sAsciiOptions
= pItem
->GetValue();
90 const OUString sFindNm
= OUString::createFromAscii(
91 pStream
? sDialogImpExtraData
92 : sDialogExpExtraData
);
93 sal_Int32 nStt
= m_sExtraData
.indexOf( sFindNm
);
96 nStt
+= nDialogExtraDataLen
;
97 sal_Int32 nEnd
= m_sExtraData
.indexOf( cDialogExtraDataClose
, nStt
);
100 if(sAsciiOptions
.isEmpty())
101 sAsciiOptions
= m_sExtraData
.copy(nStt
, nEnd
- nStt
);
102 nStt
-= nDialogExtraDataLen
;
103 m_sExtraData
= m_sExtraData
.replaceAt(nStt
, nEnd
- nStt
+ 1, u
"");
106 if(!sAsciiOptions
.isEmpty())
107 aOpt
.ReadUserData(sAsciiOptions
);
110 // read the first chars and check the charset, (language - with L&H)
113 char aBuffer
[ 4098 ];
114 const sal_uInt64 nOldPos
= pStream
->Tell();
115 const size_t nBytesRead
= pStream
->ReadBytes(aBuffer
, 4096);
116 pStream
->Seek( nOldPos
);
118 if( nBytesRead
<= 4096 )
120 aBuffer
[ nBytesRead
] = '0';
121 aBuffer
[ nBytesRead
+1 ] = '0';
124 bool bCR
= false, bLF
= false, bNullChar
= false;
125 for( sal_uInt64 nCnt
= 0; nCnt
< nBytesRead
; ++nCnt
)
126 switch( aBuffer
[ nCnt
] )
128 case 0x0: bNullChar
= true; break;
129 case 0xA: bLF
= true; break;
130 case 0xD: bCR
= true; break;
143 aOpt
.SetParaFlags( LINEEND_CRLF
);
147 aOpt
.SetParaFlags( LINEEND_CR
);
152 aOpt
.SetParaFlags( LINEEND_LF
);
156 const sal_uInt16 nAppScriptType
= SvtLanguageOptions::GetI18NScriptTypeOfLanguage( GetAppLanguage() );
157 SwDoc
* pDoc
= rDocSh
.GetDoc();
159 // initialize language
161 if( !aOpt
.GetLanguage() )
165 const TypedWhichId
<SvxLanguageItem
> nWhich
= GetWhichOfScript( RES_CHRATR_LANGUAGE
, nAppScriptType
);
166 const SvxLanguageItem
& rLangItem
= pDoc
->GetDefault( nWhich
);
167 aOpt
.SetLanguage( rLangItem
.GetLanguage() );
171 SvtLinguOptions aLinguOpt
;
172 SvtLinguConfig().GetOptions( aLinguOpt
);
173 switch(nAppScriptType
)
175 case css::i18n::ScriptType::ASIAN
:
176 aOpt
.SetLanguage(MsLangId::resolveSystemLanguageByScriptType(aLinguOpt
.nDefaultLanguage_CJK
, css::i18n::ScriptType::ASIAN
));
178 case css::i18n::ScriptType::COMPLEX
:
179 aOpt
.SetLanguage(MsLangId::resolveSystemLanguageByScriptType(aLinguOpt
.nDefaultLanguage_CTL
, css::i18n::ScriptType::COMPLEX
));
181 //SvtScriptType::LATIN:
183 aOpt
.SetLanguage(MsLangId::resolveSystemLanguageByScriptType(aLinguOpt
.nDefaultLanguage
, css::i18n::ScriptType::LATIN
));
188 m_xLanguageLB
->SetLanguageList( SvxLanguageListFlags::ALL
, true );
189 m_xLanguageLB
->set_active_id(aOpt
.GetLanguage());
193 bool bDelPrinter
= false;
194 VclPtr
<SfxPrinter
> pPrt
= pDoc
? pDoc
->getIDocumentDeviceAccess().getPrinter(false) : nullptr;
197 auto pSet
= std::make_unique
<SfxItemSetFixed
198 <SID_PRINTER_NOTFOUND_WARN
, SID_PRINTER_NOTFOUND_WARN
,
199 SID_PRINTER_CHANGESTODOC
, SID_PRINTER_CHANGESTODOC
>>( rDocSh
.GetPool() );
200 pPrt
= VclPtr
<SfxPrinter
>::Create( std::move(pSet
) );
204 // get the set of distinct available family names
205 std::set
< OUString
> aFontNames
;
206 int nFontNames
= pPrt
->GetFontFaceCollectionCount();
207 for( int i
= 0; i
< nFontNames
; i
++ )
209 FontMetric
aFontMetric( pPrt
->GetFontMetricFromCollection( i
) );
210 aFontNames
.insert( aFontMetric
.GetFamilyName() );
213 // insert into listbox
214 for( const auto& rFontName
: aFontNames
)
216 m_xFontLB
->append_text(rFontName
);
219 if( aOpt
.GetFontName().isEmpty() )
221 LanguageType eLang
= aOpt
.GetLanguage();
222 vcl::Font
aTmpFont(OutputDevice::GetDefaultFont(DefaultFontType::FIXED
, eLang
, GetDefaultFontFlags::OnlyOne
, pPrt
));
223 aOpt
.SetFontName(aTmpFont
.GetFamilyName());
226 m_xFontLB
->set_active_text(aOpt
.GetFontName());
229 pPrt
.disposeAndClear();
232 // hide the unused Controls for Export
233 m_xIncludeBOM_CB
->hide();
237 // hide the unused Controls for Export
240 m_xLanguageFT
->hide();
241 m_xLanguageLB
->hide();
244 SetIncludeBOM(aOpt
.GetIncludeBOM());
245 m_xIncludeBOM_CB
->save_state();
248 // initialize character set
249 m_xCharSetLB
->FillFromTextEncodingTable( pStream
!= nullptr );
250 m_xCharSetLB
->SelectTextEncoding( aOpt
.GetCharSet() );
252 m_xCharSetLB
->connect_changed( LINK( this, SwAsciiFilterDlg
, CharSetSelHdl
));
253 m_xCRLF_RB
->connect_toggled( LINK( this, SwAsciiFilterDlg
, LineEndHdl
));
254 m_xLF_RB
->connect_toggled( LINK( this, SwAsciiFilterDlg
, LineEndHdl
));
255 m_xCR_RB
->connect_toggled( LINK( this, SwAsciiFilterDlg
, LineEndHdl
));
257 SetCRLF( aOpt
.GetParaFlags() );
259 m_xCRLF_RB
->save_state();
260 m_xLF_RB
->save_state();
261 m_xCR_RB
->save_state();
263 UpdateIncludeBOMSensitiveState();
266 SwAsciiFilterDlg::~SwAsciiFilterDlg()
268 SvtViewOptions
aDlgOpt(EViewType::Dialog
, m_xDialog
->get_help_id());
269 aDlgOpt
.SetUserItem(u
"UserItem"_ustr
, uno::Any(m_sExtraData
));
272 void SwAsciiFilterDlg::FillOptions( SwAsciiOptions
& rOptions
)
274 sal_uLong nCCode
= m_xCharSetLB
->GetSelectTextEncoding();
276 LanguageType nLng
= LANGUAGE_SYSTEM
;
277 if (m_xFontLB
->get_visible())
279 sFont
= m_xFontLB
->get_active_text();
280 nLng
= m_xLanguageLB
->get_active_id();
283 rOptions
.SetFontName( sFont
);
284 rOptions
.SetCharSet( rtl_TextEncoding( nCCode
) );
285 rOptions
.SetLanguage( nLng
);
286 rOptions
.SetParaFlags( GetCRLF() );
287 rOptions
.SetIncludeBOM( GetIncludeBOM() );
289 // save the user settings
291 rOptions
.WriteUserData( sData
);
295 const OUString sFindNm
= OUString::createFromAscii(
296 m_xFontLB
->get_visible() ? sDialogImpExtraData
297 : sDialogExpExtraData
);
298 sal_Int32 nStt
= m_sExtraData
.indexOf( sFindNm
);
301 // called twice, so remove "old" settings
302 sal_Int32 nEnd
= m_sExtraData
.indexOf( cDialogExtraDataClose
,
303 nStt
+ nDialogExtraDataLen
);
305 m_sExtraData
= m_sExtraData
.replaceAt( nStt
, nEnd
- nStt
+ 1, u
"" );
307 m_sExtraData
+= sFindNm
+ sData
+ OUStringChar(cDialogExtraDataClose
);
310 void SwAsciiFilterDlg::SetCRLF( LineEnd eEnd
)
315 m_xCR_RB
->set_active(true);
318 m_xCRLF_RB
->set_active(true);
321 m_xLF_RB
->set_active(true);
326 LineEnd
SwAsciiFilterDlg::GetCRLF() const
329 if(m_xCR_RB
->get_active())
331 else if (m_xLF_RB
->get_active())
338 void SwAsciiFilterDlg::SetIncludeBOM( bool bIncludeBOM
)
340 m_xIncludeBOM_CB
->set_state(bIncludeBOM
? TRISTATE_TRUE
: TRISTATE_FALSE
);
343 bool SwAsciiFilterDlg::GetIncludeBOM() const
345 return m_xIncludeBOM_CB
->get_state() != TRISTATE_FALSE
;
348 void SwAsciiFilterDlg::UpdateIncludeBOMSensitiveState()
350 if (!m_xIncludeBOM_CB
->get_visible())
353 switch (m_xCharSetLB
->GetSelectTextEncoding())
355 case RTL_TEXTENCODING_UTF8
:
356 case RTL_TEXTENCODING_UCS2
:
357 m_xIncludeBOM_CB
->set_sensitive(true);
360 m_xIncludeBOM_CB
->set_sensitive(false);
365 IMPL_LINK_NOARG(SwAsciiFilterDlg
, CharSetSelHdl
, weld::ComboBox
&, void)
367 LineEnd eOldEnd
= GetCRLF();
368 std::optional
<LineEnd
> eEnd
;
369 LanguageType nLng
= m_xFontLB
->get_visible()
370 ? m_xLanguageLB
->get_active_id()
374 rtl_TextEncoding nChrSet
= m_xCharSetLB
->GetSelectTextEncoding();
375 if( nChrSet
== osl_getThreadTextEncoding() )
376 eEnd
= GetSystemLineEnd();
381 case RTL_TEXTENCODING_MS_1252
:
385 eEnd
= LINEEND_CRLF
; // ANSI
389 case RTL_TEXTENCODING_APPLE_ROMAN
: // MAC
393 case RTL_TEXTENCODING_IBM_850
: // DOS
397 case RTL_TEXTENCODING_APPLE_ARABIC
:
398 case RTL_TEXTENCODING_APPLE_CENTEURO
:
399 case RTL_TEXTENCODING_APPLE_CROATIAN
:
400 case RTL_TEXTENCODING_APPLE_CYRILLIC
:
401 case RTL_TEXTENCODING_APPLE_DEVANAGARI
:
402 case RTL_TEXTENCODING_APPLE_FARSI
:
403 case RTL_TEXTENCODING_APPLE_GREEK
:
404 case RTL_TEXTENCODING_APPLE_GUJARATI
:
405 case RTL_TEXTENCODING_APPLE_GURMUKHI
:
406 case RTL_TEXTENCODING_APPLE_HEBREW
:
407 case RTL_TEXTENCODING_APPLE_ICELAND
:
408 case RTL_TEXTENCODING_APPLE_ROMANIAN
:
409 case RTL_TEXTENCODING_APPLE_THAI
:
410 case RTL_TEXTENCODING_APPLE_TURKISH
:
411 case RTL_TEXTENCODING_APPLE_UKRAINIAN
:
412 case RTL_TEXTENCODING_APPLE_CHINSIMP
:
413 case RTL_TEXTENCODING_APPLE_CHINTRAD
:
414 case RTL_TEXTENCODING_APPLE_JAPANESE
:
415 case RTL_TEXTENCODING_APPLE_KOREAN
:
421 m_bSaveLineStatus
= false;
422 if( eEnd
) // changed?
424 if( eOldEnd
!= *eEnd
)
429 // restore old user choice (not the automatic!)
430 m_xCRLF_RB
->set_state(m_xCRLF_RB
->get_saved_state());
431 m_xCR_RB
->set_state(m_xCR_RB
->get_saved_state());
432 m_xLF_RB
->set_state(m_xLF_RB
->get_saved_state());
434 m_bSaveLineStatus
= true;
436 if (nOldLng
!= nLng
&& m_xFontLB
->get_visible())
437 m_xLanguageLB
->set_active_id(nLng
);
439 UpdateIncludeBOMSensitiveState();
442 IMPL_LINK(SwAsciiFilterDlg
, LineEndHdl
, weld::Toggleable
&, rBtn
, void)
444 if (m_bSaveLineStatus
)
448 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */