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 <utility>
23 
24 #include <hintids.hxx>
25 #include <rtl/textenc.h>
26 #include <i18nlangtag/mslangid.hxx>
27 #include <com/sun/star/i18n/ScriptType.hpp>
28 #include <unotools/lingucfg.hxx>
29 #include <unotools/viewoptions.hxx>
30 #include <sfx2/sfxsids.hrc>
31 #include <sfx2/printer.hxx>
32 #include <sfx2/docfile.hxx>
33 #include <svl/languageoptions.hxx>
34 #include <editeng/langitem.hxx>
35 #include <swtypes.hxx>
36 #include <ascfldlg.hxx>
37 #include <shellio.hxx>
38 #include <docsh.hxx>
39 #include <doc.hxx>
41 
42 #include <vcl/metric.hxx>
43 
44 using namespace ::com::sun::star;
45 
46 namespace
47 {
48 
49 const sal_Unicode cDialogExtraDataClose = '}';
50 const char sDialogImpExtraData[] = "EncImpDlg:{";
51 const char sDialogExpExtraData[] = "EncExpDlg:{";
52 const sal_Int32 nDialogExtraDataLen = 11; // 12345678901
53 
54 }
55 
57  SvStream* pStream )
58  : SfxDialogController(pParent, "modules/swriter/ui/asciifilterdialog.ui", "AsciiFilterDialog")
59  , m_bSaveLineStatus(true)
60  , m_xCharSetLB(new SvxTextEncodingBox(m_xBuilder->weld_combo_box("charset")))
61  , m_xFontFT(m_xBuilder->weld_label("fontft"))
62  , m_xFontLB(m_xBuilder->weld_combo_box("font"))
63  , m_xLanguageFT(m_xBuilder->weld_label("languageft"))
64  , m_xLanguageLB(new SvxLanguageBox(m_xBuilder->weld_combo_box("language")))
65  , m_xCRLF_RB(m_xBuilder->weld_radio_button("crlf"))
66  , m_xCR_RB(m_xBuilder->weld_radio_button("cr"))
67  , m_xLF_RB(m_xBuilder->weld_radio_button("lf"))
68  , m_xIncludeBOM_CB(m_xBuilder->weld_check_button("includebom"))
69 {
70  m_xFontLB->make_sorted();
71 
72  SwAsciiOptions aOpt;
73  {
74  SvtViewOptions aDlgOpt(EViewType::Dialog, OStringToOUString(m_xDialog->get_help_id(), RTL_TEXTENCODING_UTF8));
75  if (aDlgOpt.Exists())
76  {
77  css::uno::Any aUserItem = aDlgOpt.GetUserItem("UserItem");
78  aUserItem >>= m_sExtraData;
79  }
80 
81  const SfxPoolItem* pItem;
82  OUString sAsciiOptions;
83  if( rDocSh.GetMedium() != nullptr &&
84  rDocSh.GetMedium()->GetItemSet() != nullptr &&
85  SfxItemState::SET == rDocSh.GetMedium()->GetItemSet()->GetItemState(
86  SID_FILE_FILTEROPTIONS, true, &pItem ))
87  {
88  sAsciiOptions = static_cast<const SfxStringItem*>(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, "");
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_uLong 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_uLong 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  {
144  aOpt.SetParaFlags( LINEEND_CRLF );
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::makeAny(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, "" );
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 
339 void 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(), eEnd = LineEnd(-1);
369  LanguageType nLng = m_xFontLB->get_visible()
370  ? m_xLanguageLB->get_active_id()
371  : LANGUAGE_SYSTEM,
372  nOldLng = nLng;
373 
374  rtl_TextEncoding nChrSet = m_xCharSetLB->GetSelectTextEncoding();
375  if( nChrSet == osl_getThreadTextEncoding() )
376  eEnd = GetSystemLineEnd();
377  else
378  {
379  switch( nChrSet )
380  {
381  case RTL_TEXTENCODING_MS_1252:
382 #ifdef UNX
383  eEnd = LINEEND_LF;
384 #else
385  eEnd = LINEEND_CRLF; // ANSI
386 #endif
387  break;
388 
389  case RTL_TEXTENCODING_APPLE_ROMAN: // MAC
390  eEnd = LINEEND_CR;
391  break;
392 
393  case RTL_TEXTENCODING_IBM_850: // DOS
394  eEnd = LINEEND_CRLF;
395  break;
396 
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;
418  }
419  }
420 
421  m_bSaveLineStatus = false;
422  if( eEnd != LineEnd(-1) ) // changed?
423  {
424  if( eOldEnd != eEnd )
425  SetCRLF( eEnd );
426  }
427  else
428  {
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());
433  }
434  m_bSaveLineStatus = true;
435 
436  if (nOldLng != nLng && m_xFontLB->get_visible())
437  m_xLanguageLB->set_active_id(nLng);
438 
439  UpdateIncludeBOMSensitiveState();
440 }
441 
442 IMPL_LINK(SwAsciiFilterDlg, LineEndHdl, weld::Toggleable&, rBtn, void)
443 {
444  if (m_bSaveLineStatus)
445  rBtn.save_state();
446 }
447 
448 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
void SetUserItem(const OUString &sName, const css::uno::Any &aValue)
rtl_TextEncoding GetCharSet() const
Definition: shellio.hxx:72
static vcl::Font GetDefaultFont(DefaultFontType nType, LanguageType eLang, GetDefaultFontFlags nFlags, const OutputDevice *pOutDev=nullptr)
bool GetIncludeBOM() const
Definition: shellio.hxx:81
const OUString & GetFamilyName() const
IMPL_LINK_NOARG(SwAsciiFilterDlg, CharSetSelHdl, weld::ComboBox &, void)
Definition: ascfldlg.cxx:366
std::unique_ptr< weld::Label > m_xLanguageFT
Definition: ascfldlg.hxx:39
std::unique_ptr< weld::Label > m_xFontFT
Definition: ascfldlg.hxx:37
std::string GetValue
IDocumentDeviceAccess const & getIDocumentDeviceAccess() const
Definition: doc.cxx:238
const OUString & GetFontName() const
Definition: shellio.hxx:69
sal_uIntPtr sal_uLong
constexpr TypedWhichId< SvxLanguageItem > RES_CHRATR_LANGUAGE(10)
void disposeAndClear()
LanguageType GetLanguage(SfxItemSet const &aSet, sal_uInt16 nLangWhichId)
Definition: langhelper.cxx:390
Definition: doc.hxx:188
IMPL_LINK(SwAsciiFilterDlg, LineEndHdl, weld::Toggleable &, rBtn, void)
Definition: ascfldlg.cxx:442
LanguageType GetLanguage() const
Definition: shellio.hxx:75
LanguageType nDefaultLanguage_CJK
sal_uInt64 Seek(sal_uInt64 nPos)
static LanguageType resolveSystemLanguageByScriptType(LanguageType nLang, sal_Int16 nType)
void SetParaFlags(LineEnd eVal)
Definition: shellio.hxx:79
LINEEND_CR
TRISTATE_TRUE
std::unique_ptr< SvxLanguageBox > m_xLanguageLB
Definition: ascfldlg.hxx:40
void WriteUserData(OUString &) const
Definition: fltini.cxx:574
void FillOptions(SwAsciiOptions &rOptions)
Definition: ascfldlg.cxx:273
sal_uInt16 sal_Unicode
void SetLanguage(LanguageType nVal)
Definition: shellio.hxx:76
std::unique_ptr< SvxTextEncodingBox > m_xCharSetLB
Definition: ascfldlg.hxx:36
std::unique_ptr< weld::ComboBox > m_xFontLB
Definition: ascfldlg.hxx:38
LineEnd GetCRLF() const
Definition: ascfldlg.cxx:327
LineEnd GetSystemLineEnd()
void SetCRLF(LineEnd eEnd)
Definition: ascfldlg.cxx:311
std::unique_ptr< weld::RadioButton > m_xCR_RB
Definition: ascfldlg.hxx:42
sal_Int16 GetI18NScriptTypeOfLanguage(LanguageType nLang)
SfxItemPool & GetPool() const
void SetCharSet(rtl_TextEncoding nVal)
Definition: shellio.hxx:73
SwDoc * GetDoc()
returns Doc. But be careful!
Definition: docsh.hxx:203
LINEEND_LF
OUString m_sExtraData
Definition: ascfldlg.hxx:34
SfxItemState GetItemState(sal_uInt16 nWhich, bool bSrchInParent=true, const SfxPoolItem **ppItem=nullptr) const
int i
void ReadUserData(const OUString &)
Definition: fltini.cxx:548
void GetOptions(SvtLinguOptions &rOptions) const
#define LANGUAGE_SYSTEM
SwAsciiFilterDlg(weld::Window *pParent, SwDocShell &rDocSh, SvStream *pStream)
Definition: ascfldlg.cxx:56
TRISTATE_FALSE
std::unique_ptr< weld::CheckButton > m_xIncludeBOM_CB
Definition: ascfldlg.hxx:44
void SetIncludeBOM(bool bIncludeBOM)
Definition: ascfldlg.cxx:339
sal_uInt16 GetWhichOfScript(sal_uInt16 nWhich, sal_uInt16 nScript)
Definition: hints.cxx:190
SfxItemSet * GetItemSet() const
void UpdateIncludeBOMSensitiveState()
Definition: ascfldlg.cxx:349
virtual SfxPrinter * getPrinter(bool bCreate) const =0
Return the printer set at the document.
LineEnd
std::size_t ReadBytes(void *pData, std::size_t nSize)
std::unique_ptr< char[]> aBuffer
LanguageType nDefaultLanguage
LanguageType GetAppLanguage()
Definition: init.cxx:723
static VclPtr< reference_type > Create(Arg &&...arg)
bool Exists() const
Reference< XExecutableDialog > m_xDialog
sal_uInt64 Tell() const
css::uno::Any GetUserItem(const OUString &sName) const
std::unique_ptr< weld::RadioButton > m_xLF_RB
Definition: ascfldlg.hxx:43
void SetIncludeBOM(bool bVal)
Definition: shellio.hxx:82
LINEEND_CRLF
LineEnd GetParaFlags() const
Definition: shellio.hxx:78
virtual ~SwAsciiFilterDlg() override
Definition: ascfldlg.cxx:267
std::unique_ptr< weld::RadioButton > m_xCRLF_RB
Definition: ascfldlg.hxx:41
LanguageType nDefaultLanguage_CTL
void SetFontName(const OUString &rFont)
Definition: shellio.hxx:70
bool GetIncludeBOM() const
Definition: ascfldlg.cxx:344
SfxMedium * GetMedium() const