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
, "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"))
71 m_xFontLB
->make_sorted();
75 SvtViewOptions
aDlgOpt(EViewType::Dialog
, m_xDialog
->get_help_id());
78 css::uno::Any aUserItem
= aDlgOpt
.GetUserItem("UserItem");
79 aUserItem
>>= m_sExtraData
;
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
)))
88 sAsciiOptions
= pItem
->GetValue();
91 const OUString sFindNm
= OUString::createFromAscii(
92 pStream
? sDialogImpExtraData
93 : sDialogExpExtraData
);
94 sal_Int32 nStt
= m_sExtraData
.indexOf( sFindNm
);
97 nStt
+= nDialogExtraDataLen
;
98 sal_Int32 nEnd
= m_sExtraData
.indexOf( cDialogExtraDataClose
, nStt
);
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
"");
107 if(!sAsciiOptions
.isEmpty())
108 aOpt
.ReadUserData(sAsciiOptions
);
111 // read the first chars and check the charset, (language - with L&H)
114 char aBuffer
[ 4098 ];
115 const sal_uInt64 nOldPos
= pStream
->Tell();
116 const size_t nBytesRead
= pStream
->ReadBytes(aBuffer
, 4096);
117 pStream
->Seek( nOldPos
);
119 if( nBytesRead
<= 4096 )
121 aBuffer
[ nBytesRead
] = '0';
122 aBuffer
[ nBytesRead
+1 ] = '0';
125 bool bCR
= false, bLF
= false, bNullChar
= false;
126 for( sal_uInt64 nCnt
= 0; nCnt
< nBytesRead
; ++nCnt
)
127 switch( aBuffer
[ nCnt
] )
129 case 0x0: bNullChar
= true; break;
130 case 0xA: bLF
= true; break;
131 case 0xD: bCR
= true; break;
144 aOpt
.SetParaFlags( LINEEND_CRLF
);
148 aOpt
.SetParaFlags( LINEEND_CR
);
153 aOpt
.SetParaFlags( LINEEND_LF
);
157 const sal_uInt16 nAppScriptType
= SvtLanguageOptions::GetI18NScriptTypeOfLanguage( GetAppLanguage() );
158 SwDoc
* pDoc
= rDocSh
.GetDoc();
160 // initialize language
162 if( !aOpt
.GetLanguage() )
166 const sal_uInt16 nWhich
= GetWhichOfScript( RES_CHRATR_LANGUAGE
, nAppScriptType
);
167 aOpt
.SetLanguage( static_cast<const SvxLanguageItem
&>(pDoc
->
168 GetDefault( nWhich
)).GetLanguage());
172 SvtLinguOptions aLinguOpt
;
173 SvtLinguConfig().GetOptions( aLinguOpt
);
174 switch(nAppScriptType
)
176 case css::i18n::ScriptType::ASIAN
:
177 aOpt
.SetLanguage(MsLangId::resolveSystemLanguageByScriptType(aLinguOpt
.nDefaultLanguage_CJK
, css::i18n::ScriptType::ASIAN
));
179 case css::i18n::ScriptType::COMPLEX
:
180 aOpt
.SetLanguage(MsLangId::resolveSystemLanguageByScriptType(aLinguOpt
.nDefaultLanguage_CTL
, css::i18n::ScriptType::COMPLEX
));
182 //SvtScriptType::LATIN:
184 aOpt
.SetLanguage(MsLangId::resolveSystemLanguageByScriptType(aLinguOpt
.nDefaultLanguage
, css::i18n::ScriptType::LATIN
));
189 m_xLanguageLB
->SetLanguageList( SvxLanguageListFlags::ALL
, true );
190 m_xLanguageLB
->set_active_id(aOpt
.GetLanguage());
194 bool bDelPrinter
= false;
195 VclPtr
<SfxPrinter
> pPrt
= pDoc
? pDoc
->getIDocumentDeviceAccess().getPrinter(false) : nullptr;
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
) );
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
++ )
210 FontMetric
aFontMetric( pPrt
->GetFontMetricFromCollection( i
) );
211 aFontNames
.insert( aFontMetric
.GetFamilyName() );
214 // insert into listbox
215 for( const auto& rFontName
: aFontNames
)
217 m_xFontLB
->append_text(rFontName
);
220 if( aOpt
.GetFontName().isEmpty() )
222 LanguageType eLang
= aOpt
.GetLanguage();
223 vcl::Font
aTmpFont(OutputDevice::GetDefaultFont(DefaultFontType::FIXED
, eLang
, GetDefaultFontFlags::OnlyOne
, pPrt
));
224 aOpt
.SetFontName(aTmpFont
.GetFamilyName());
227 m_xFontLB
->set_active_text(aOpt
.GetFontName());
230 pPrt
.disposeAndClear();
233 // hide the unused Controls for Export
234 m_xIncludeBOM_CB
->hide();
238 // hide the unused Controls for Export
241 m_xLanguageFT
->hide();
242 m_xLanguageLB
->hide();
245 SetIncludeBOM(aOpt
.GetIncludeBOM());
246 m_xIncludeBOM_CB
->save_state();
249 // initialize character set
250 m_xCharSetLB
->FillFromTextEncodingTable( pStream
!= nullptr );
251 m_xCharSetLB
->SelectTextEncoding( aOpt
.GetCharSet() );
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
));
258 SetCRLF( aOpt
.GetParaFlags() );
260 m_xCRLF_RB
->save_state();
261 m_xLF_RB
->save_state();
262 m_xCR_RB
->save_state();
264 UpdateIncludeBOMSensitiveState();
267 SwAsciiFilterDlg::~SwAsciiFilterDlg()
269 SvtViewOptions
aDlgOpt(EViewType::Dialog
, m_xDialog
->get_help_id());
270 aDlgOpt
.SetUserItem("UserItem", uno::Any(m_sExtraData
));
273 void SwAsciiFilterDlg::FillOptions( SwAsciiOptions
& rOptions
)
275 sal_uLong nCCode
= m_xCharSetLB
->GetSelectTextEncoding();
277 LanguageType nLng
= LANGUAGE_SYSTEM
;
278 if (m_xFontLB
->get_visible())
280 sFont
= m_xFontLB
->get_active_text();
281 nLng
= m_xLanguageLB
->get_active_id();
284 rOptions
.SetFontName( sFont
);
285 rOptions
.SetCharSet( rtl_TextEncoding( nCCode
) );
286 rOptions
.SetLanguage( nLng
);
287 rOptions
.SetParaFlags( GetCRLF() );
288 rOptions
.SetIncludeBOM( GetIncludeBOM() );
290 // save the user settings
292 rOptions
.WriteUserData( sData
);
296 const OUString sFindNm
= OUString::createFromAscii(
297 m_xFontLB
->get_visible() ? sDialogImpExtraData
298 : sDialogExpExtraData
);
299 sal_Int32 nStt
= m_sExtraData
.indexOf( sFindNm
);
302 // called twice, so remove "old" settings
303 sal_Int32 nEnd
= m_sExtraData
.indexOf( cDialogExtraDataClose
,
304 nStt
+ nDialogExtraDataLen
);
306 m_sExtraData
= m_sExtraData
.replaceAt( nStt
, nEnd
- nStt
+ 1, u
"" );
308 m_sExtraData
+= sFindNm
+ sData
+ OUStringChar(cDialogExtraDataClose
);
311 void SwAsciiFilterDlg::SetCRLF( LineEnd eEnd
)
316 m_xCR_RB
->set_active(true);
319 m_xCRLF_RB
->set_active(true);
322 m_xLF_RB
->set_active(true);
327 LineEnd
SwAsciiFilterDlg::GetCRLF() const
330 if(m_xCR_RB
->get_active())
332 else if (m_xLF_RB
->get_active())
339 void SwAsciiFilterDlg::SetIncludeBOM( bool bIncludeBOM
)
341 m_xIncludeBOM_CB
->set_state(bIncludeBOM
? TRISTATE_TRUE
: TRISTATE_FALSE
);
344 bool SwAsciiFilterDlg::GetIncludeBOM() const
346 return m_xIncludeBOM_CB
->get_state() != TRISTATE_FALSE
;
349 void SwAsciiFilterDlg::UpdateIncludeBOMSensitiveState()
351 if (!m_xIncludeBOM_CB
->get_visible())
354 switch (m_xCharSetLB
->GetSelectTextEncoding())
356 case RTL_TEXTENCODING_UTF8
:
357 case RTL_TEXTENCODING_UCS2
:
358 m_xIncludeBOM_CB
->set_sensitive(true);
361 m_xIncludeBOM_CB
->set_sensitive(false);
366 IMPL_LINK_NOARG(SwAsciiFilterDlg
, CharSetSelHdl
, weld::ComboBox
&, void)
368 LineEnd eOldEnd
= GetCRLF();
369 std::optional
<LineEnd
> eEnd
;
370 LanguageType nLng
= m_xFontLB
->get_visible()
371 ? m_xLanguageLB
->get_active_id()
375 rtl_TextEncoding nChrSet
= m_xCharSetLB
->GetSelectTextEncoding();
376 if( nChrSet
== osl_getThreadTextEncoding() )
377 eEnd
= GetSystemLineEnd();
382 case RTL_TEXTENCODING_MS_1252
:
386 eEnd
= LINEEND_CRLF
; // ANSI
390 case RTL_TEXTENCODING_APPLE_ROMAN
: // MAC
394 case RTL_TEXTENCODING_IBM_850
: // DOS
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
:
422 m_bSaveLineStatus
= false;
423 if( eEnd
) // changed?
425 if( eOldEnd
!= *eEnd
)
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());
435 m_bSaveLineStatus
= true;
437 if (nOldLng
!= nLng
&& m_xFontLB
->get_visible())
438 m_xLanguageLB
->set_active_id(nLng
);
440 UpdateIncludeBOMSensitiveState();
443 IMPL_LINK(SwAsciiFilterDlg
, LineEndHdl
, weld::Toggleable
&, rBtn
, void)
445 if (m_bSaveLineStatus
)
449 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */