ITEM: Refactor ItemType
[LibreOffice.git] / sw / source / ui / dialog / ascfldlg.cxx
blob4efba9159e6fcc1b4071791bde04a4f47743827c
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 <sal/config.h>
22 #include <optional>
23 #include <utility>
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>
39 #include <docsh.hxx>
40 #include <doc.hxx>
41 #include <IDocumentDeviceAccess.hxx>
43 #include <vcl/metric.hxx>
45 using namespace ::com::sun::star;
47 namespace
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,
58 SvStream* pStream )
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();
73 SwAsciiOptions aOpt;
75 SvtViewOptions aDlgOpt(EViewType::Dialog, m_xDialog->get_help_id());
76 if (aDlgOpt.Exists())
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 );
94 if( -1 != nStt )
96 nStt += nDialogExtraDataLen;
97 sal_Int32 nEnd = m_sExtraData.indexOf( cDialogExtraDataClose, nStt );
98 if( -1 != nEnd )
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)
111 if( pStream )
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;
131 case 0xC:
132 case 0x1A:
133 case 0x9: break;
134 default: break;
137 if( !bNullChar )
139 if( bCR )
141 if( bLF )
143 aOpt.SetParaFlags( LINEEND_CRLF );
145 else
147 aOpt.SetParaFlags( LINEEND_CR );
150 else if( bLF )
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() )
163 if(pDoc)
165 const TypedWhichId<SvxLanguageItem> nWhich = GetWhichOfScript( RES_CHRATR_LANGUAGE, nAppScriptType);
166 const SvxLanguageItem& rLangItem = pDoc->GetDefault( nWhich );
167 aOpt.SetLanguage( rLangItem.GetLanguage() );
169 else
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));
177 break;
178 case css::i18n::ScriptType::COMPLEX:
179 aOpt.SetLanguage(MsLangId::resolveSystemLanguageByScriptType(aLinguOpt.nDefaultLanguage_CTL, css::i18n::ScriptType::COMPLEX));
180 break;
181 //SvtScriptType::LATIN:
182 default:
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;
195 if( !pPrt )
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) );
201 bDelPrinter = true;
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());
228 if( bDelPrinter )
229 pPrt.disposeAndClear();
232 // hide the unused Controls for Export
233 m_xIncludeBOM_CB->hide();
235 else
237 // hide the unused Controls for Export
238 m_xFontFT->hide();
239 m_xFontLB->hide();
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();
275 OUString sFont;
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
290 OUString sData;
291 rOptions.WriteUserData( sData );
292 if (sData.isEmpty())
293 return;
295 const OUString sFindNm = OUString::createFromAscii(
296 m_xFontLB->get_visible() ? sDialogImpExtraData
297 : sDialogExpExtraData);
298 sal_Int32 nStt = m_sExtraData.indexOf( sFindNm );
299 if( -1 != nStt )
301 // called twice, so remove "old" settings
302 sal_Int32 nEnd = m_sExtraData.indexOf( cDialogExtraDataClose,
303 nStt + nDialogExtraDataLen );
304 if( -1 != nEnd )
305 m_sExtraData = m_sExtraData.replaceAt( nStt, nEnd - nStt + 1, u"" );
307 m_sExtraData += sFindNm + sData + OUStringChar(cDialogExtraDataClose);
310 void SwAsciiFilterDlg::SetCRLF( LineEnd eEnd )
312 switch (eEnd)
314 case LINEEND_CR:
315 m_xCR_RB->set_active(true);
316 break;
317 case LINEEND_CRLF:
318 m_xCRLF_RB->set_active(true);
319 break;
320 case LINEEND_LF:
321 m_xLF_RB->set_active(true);
322 break;
326 LineEnd SwAsciiFilterDlg::GetCRLF() const
328 LineEnd eEnd;
329 if(m_xCR_RB->get_active())
330 eEnd = LINEEND_CR;
331 else if (m_xLF_RB->get_active())
332 eEnd = LINEEND_LF;
333 else
334 eEnd = LINEEND_CRLF;
335 return eEnd;
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())
351 return;
353 switch (m_xCharSetLB->GetSelectTextEncoding())
355 case RTL_TEXTENCODING_UTF8:
356 case RTL_TEXTENCODING_UCS2:
357 m_xIncludeBOM_CB->set_sensitive(true);
358 break;
359 default:
360 m_xIncludeBOM_CB->set_sensitive(false);
361 break;
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()
371 : LANGUAGE_SYSTEM,
372 nOldLng = nLng;
374 rtl_TextEncoding nChrSet = m_xCharSetLB->GetSelectTextEncoding();
375 if( nChrSet == osl_getThreadTextEncoding() )
376 eEnd = GetSystemLineEnd();
377 else
379 switch( nChrSet )
381 case RTL_TEXTENCODING_MS_1252:
382 #ifdef UNX
383 eEnd = LINEEND_LF;
384 #else
385 eEnd = LINEEND_CRLF; // ANSI
386 #endif
387 break;
389 case RTL_TEXTENCODING_APPLE_ROMAN: // MAC
390 eEnd = LINEEND_CR;
391 break;
393 case RTL_TEXTENCODING_IBM_850: // DOS
394 eEnd = LINEEND_CRLF;
395 break;
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:
416 eEnd = LINEEND_CR;
417 break;
421 m_bSaveLineStatus = false;
422 if( eEnd ) // changed?
424 if( eOldEnd != *eEnd )
425 SetCRLF( *eEnd );
427 else
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)
445 rBtn.save_state();
448 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */