LibreOffice Module sc (master)  1
filtuno.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 <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
21 #include <tools/urlobj.hxx>
22 #include <vcl/svapp.hxx>
24 #include <connectivity/dbtools.hxx>
25 #include <osl/diagnose.h>
26 
27 #include <filtuno.hxx>
28 #include <miscuno.hxx>
29 #include <scdll.hxx>
30 #include <imoptdlg.hxx>
31 #include <asciiopt.hxx>
32 #include <docsh.hxx>
33 #include <globstr.hrc>
34 #include <scresid.hxx>
35 
36 #include <scabstdlg.hxx>
37 #include <i18nlangtag/lang.h>
38 
39 #include <optutil.hxx>
40 #include <com/sun/star/uno/Any.hxx>
41 #include <com/sun/star/uno/Sequence.hxx>
44 #include <memory>
45 
46 using namespace com::sun::star;
47 using namespace com::sun::star::uno;
48 using namespace connectivity::dbase;
49 
50 constexpr OUStringLiteral SCFILTEROPTIONSOBJ_SERVICE = u"com.sun.star.ui.dialogs.FilterOptionsDialog";
51 constexpr OUStringLiteral SCFILTEROPTIONSOBJ_IMPLNAME = u"com.sun.star.comp.Calc.FilterOptionsDialog";
52 
54 
55 constexpr OUStringLiteral SC_UNONAME_FILENAME = u"URL";
56 constexpr OUStringLiteral SC_UNONAME_FILTERNAME = u"FilterName";
57 constexpr OUStringLiteral SC_UNONAME_FILTEROPTIONS = u"FilterOptions";
58 constexpr OUStringLiteral SC_UNONAME_INPUTSTREAM = u"InputStream";
59 
60 constexpr OUStringLiteral DBF_CHAR_SET = u"CharSet";
61 constexpr OUStringLiteral DBF_SEP_PATH_IMPORT = u"Office.Calc/Dialogs/DBFImport";
62 constexpr OUStringLiteral DBF_SEP_PATH_EXPORT = u"Office.Calc/Dialogs/DBFExport";
63 
64 namespace
65 {
66 
67  enum class charsetSource
68  {
69  charset_from_file,
70  charset_from_user_setting,
71  charset_default
72  };
73 
74  charsetSource load_CharSet(rtl_TextEncoding &nCharSet, bool bExport, SvStream* dbf_Stream)
75  {
76  if (dbf_Stream && dbfReadCharset(nCharSet, dbf_Stream))
77  {
78  return charsetSource::charset_from_file;
79  }
80 
81  Sequence<Any> aValues;
82  const Any *pProperties;
85 
86  aValues = aItem.GetProperties( aNames );
87  pProperties = aValues.getConstArray();
88 
89  if( pProperties[0].hasValue() )
90  {
91  sal_Int32 nChar = 0;
92  pProperties[0] >>= nChar;
93  if( nChar >= 0)
94  {
95  nCharSet = static_cast<rtl_TextEncoding>(nChar);
96  return charsetSource::charset_from_user_setting;
97  }
98  }
99 
100  // Default choice
101  nCharSet = RTL_TEXTENCODING_IBM_850;
102  return charsetSource::charset_default;
103  }
104 
105  void save_CharSet( rtl_TextEncoding nCharSet, bool bExport )
106  {
107  Sequence<Any> aValues;
108  Any *pProperties;
109  Sequence<OUString> aNames { DBF_CHAR_SET };
111 
112  aValues = aItem.GetProperties( aNames );
113  pProperties = aValues.getArray();
114  pProperties[0] <<= static_cast<sal_Int32>(nCharSet);
115 
116  aItem.PutProperties(aNames, aValues);
117  }
118 }
119 
121  bExport( false )
122 {
123 }
124 
126 {
127 }
128 
129 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
130 Calc_FilterOptionsDialog_get_implementation(css::uno::XComponentContext*, css::uno::Sequence<css::uno::Any> const &)
131 {
132  SolarMutexGuard aGuard;
133  ScDLL::Init();
134  return cppu::acquire(new ScFilterOptionsObj);
135 }
136 
137 // XPropertyAccess
138 
139 uno::Sequence<beans::PropertyValue> SAL_CALL ScFilterOptionsObj::getPropertyValues()
140 {
143  });
144 }
145 
146 void SAL_CALL ScFilterOptionsObj::setPropertyValues( const uno::Sequence<beans::PropertyValue>& aProps )
147 {
148  for (const beans::PropertyValue& rProp : aProps)
149  {
150  OUString aPropName(rProp.Name);
151 
152  if ( aPropName == SC_UNONAME_FILENAME )
153  rProp.Value >>= aFileName;
154  else if ( aPropName == SC_UNONAME_FILTERNAME )
155  rProp.Value >>= aFilterName;
156  else if ( aPropName == SC_UNONAME_FILTEROPTIONS )
157  rProp.Value >>= aFilterOptions;
158  else if ( aPropName == SC_UNONAME_INPUTSTREAM )
159  rProp.Value >>= xInputStream;
160  }
161 }
162 
163 // XExecutableDialog
164 
165 void SAL_CALL ScFilterOptionsObj::setTitle( const OUString& /* aTitle */ )
166 {
167  // not used
168 }
169 
170 sal_Int16 SAL_CALL ScFilterOptionsObj::execute()
171 {
172  sal_Int16 nRet = ui::dialogs::ExecutableDialogResults::CANCEL;
173 
174  OUString aFilterString( aFilterName );
175 
177 
178  if ( !bExport && aFilterString == ScDocShell::GetAsciiFilterName() )
179  {
180  // ascii import is special...
181 
183  // tdf#132421 - don't URL encode filename for the import ASCII dialog title
184  OUString aPrivDatName(aURL.GetLastName(INetURLObject::DecodeMechanism::Unambiguous));
185  std::unique_ptr<SvStream> pInStream;
186  if ( xInputStream.is() )
188 
190  pInStream.get(), SC_IMPORTFILE));
191  if ( pDlg->Execute() == RET_OK )
192  {
193  ScAsciiOptions aOptions;
194  pDlg->GetOptions( aOptions );
195  pDlg->SaveParameters();
196  aFilterOptions = aOptions.WriteToString();
197  nRet = ui::dialogs::ExecutableDialogResults::OK;
198  }
199  }
200  else if ( aFilterString == ScDocShell::GetWebQueryFilterName() || aFilterString == ScDocShell::GetHtmlFilterName() )
201  {
202  if (bExport)
203  nRet = ui::dialogs::ExecutableDialogResults::OK; // export HTML without dialog
204  else
205  {
206  // HTML import.
209 
210  if (pDlg->Execute() == RET_OK)
211  {
212  LanguageType eLang = pDlg->GetLanguageType();
213  OUStringBuffer aBuf;
214 
215  aBuf.append(static_cast<sal_Int32>(static_cast<sal_uInt16>(eLang)));
216  aBuf.append(' ');
217  aBuf.append(pDlg->IsDateConversionSet() ? u'1' : u'0');
218  aFilterOptions = aBuf.makeStringAndClear();
219  nRet = ui::dialogs::ExecutableDialogResults::OK;
220  }
221  }
222  }
223  else
224  {
225  bool bDBEnc = false;
226  bool bAscii = false;
227  bool skipDialog = false;
228 
229  sal_Unicode const cStrDel = '"';
230  sal_Unicode cAsciiDel = ';';
231  rtl_TextEncoding eEncoding = RTL_TEXTENCODING_DONTKNOW;
232 
233  OUString aTitle;
234 
235  if ( aFilterString == ScDocShell::GetAsciiFilterName() )
236  {
237  // ascii export (import is handled above)
238 
240  OUString aExt(aURL.getExtension());
241  if (aExt.equalsIgnoreAsciiCase("CSV"))
242  cAsciiDel = ',';
243  else
244  cAsciiDel = '\t';
245 
246  aTitle = ScResId( STR_EXPORT_ASCII );
247  bAscii = true;
248  }
249  else if ( aFilterString == ScDocShell::GetLotusFilterName() )
250  {
251  // lotus is only imported
252  OSL_ENSURE( !bExport, "Filter Options for Lotus Export is not implemented" );
253 
254  aTitle = ScResId( STR_IMPORT_LOTUS );
255  eEncoding = RTL_TEXTENCODING_IBM_437;
256  }
257  else if ( aFilterString == ScDocShell::GetDBaseFilterName() )
258  {
259  if ( bExport )
260  {
261  // dBase export
262  aTitle = ScResId( STR_EXPORT_DBF );
263  }
264  else
265  {
266  // dBase import
267  aTitle = ScResId( STR_IMPORT_DBF );
268  }
269 
270  std::unique_ptr<SvStream> pInStream;
271  if ( xInputStream.is() )
273  switch(load_CharSet( eEncoding, bExport, pInStream.get()))
274  {
275  case charsetSource::charset_from_file:
276  skipDialog = true;
277  break;
278  case charsetSource::charset_from_user_setting:
279  case charsetSource::charset_default:
280  break;
281  }
282  bDBEnc = true;
283  // pInStream goes out of scope, the stream is automatically closed
284  }
285  else if ( aFilterString == ScDocShell::GetDifFilterName() )
286  {
287  if ( bExport )
288  {
289  // DIF export
290  aTitle = ScResId( STR_EXPORT_DIF );
291  }
292  else
293  {
294  // DIF import
295  aTitle = ScResId( STR_IMPORT_DIF );
296  }
297  // common for DIF import/export
298  eEncoding = RTL_TEXTENCODING_MS_1252;
299  }
300 
301  ScImportOptions aOptions( cAsciiDel, cStrDel, eEncoding);
302  if(skipDialog)
303  {
304  // TODO: check we are not missing some of the stuff that ScImportOptionsDlg::GetImportOptions
305  // (file sc/source/ui/dbgui/scuiimoptdlg.cxx) does
306  // that is, if the dialog sets options that are not selected by the user (!)
307  // then we are missing them here.
308  // Then we may need to rip them out of the dialog.
309  // Or we actually change the dialog to not display if skipDialog==true
310  // in that case, add an argument skipDialog to CreateScImportOptionsDlg
311  nRet = ui::dialogs::ExecutableDialogResults::OK;
312  }
313  else
314  {
316  bAscii, &aOptions, &aTitle,
317  bDBEnc, !bExport));
318  if ( pDlg->Execute() == RET_OK )
319  {
320  pDlg->SaveImportOptions();
321  pDlg->GetImportOptions( aOptions );
322  save_CharSet( aOptions.eCharSet, bExport );
323  nRet = ui::dialogs::ExecutableDialogResults::OK;
324  }
325  }
326  if (nRet == ui::dialogs::ExecutableDialogResults::OK)
327  {
328  if ( bAscii )
329  aFilterOptions = aOptions.BuildString();
330  else
331  aFilterOptions = aOptions.aStrFont;
332  }
333  }
334 
335  xInputStream.clear(); // don't hold the stream longer than necessary
336 
337  return nRet;
338 }
339 
340 // XImporter
341 
342 void SAL_CALL ScFilterOptionsObj::setTargetDocument( const uno::Reference<lang::XComponent>& /* xDoc */ )
343 {
344  bExport = false;
345 }
346 
347 // XExporter
348 
349 void SAL_CALL ScFilterOptionsObj::setSourceDocument( const uno::Reference<lang::XComponent>& /* xDoc */ )
350 {
351  bExport = true;
352 }
353 
354 // XInitialization
355 
356 void SAL_CALL ScFilterOptionsObj::initialize(const uno::Sequence<uno::Any>& rArguments)
357 {
359  if (aProperties.has("ParentWindow"))
360  aProperties.get("ParentWindow") >>= xDialogParent;
361 }
362 
363 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
virtual css::uno::Sequence< css::beans::PropertyValue > SAL_CALL getPropertyValues() override
Definition: filtuno.cxx:139
virtual sal_Int16 SAL_CALL execute() override
Definition: filtuno.cxx:170
charsetSource
Definition: filtuno.cxx:67
URL aURL
OUString ScResId(TranslateId aId)
Definition: scdll.cxx:89
virtual void SAL_CALL setTitle(const OUString &aTitle) override
Definition: filtuno.cxx:165
css::uno::Reference< css::io::XInputStream > xInputStream
Definition: filtuno.hxx:45
constexpr OUStringLiteral SC_UNONAME_FILTEROPTIONS
Definition: filtuno.cxx:57
static OUString GetAsciiFilterName()
Definition: docsh.cxx:2813
virtual void GetOptions(ScAsciiOptions &rOpt)=0
constexpr OUStringLiteral SCFILTEROPTIONSOBJ_IMPLNAME
Definition: filtuno.cxx:51
aBuf
static OUString GetHtmlFilterName()
Definition: docsh.cxx:2803
OUString GetLastName(DecodeMechanism eMechanism=DecodeMechanism::ToIUri, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8) const
constexpr OUStringLiteral SCFILTEROPTIONSOBJ_SERVICE
Definition: filtuno.cxx:50
OUString aFilterName
Definition: filtuno.hxx:43
virtual short Execute()=0
static OUString GetWebQueryFilterName()
Definition: docsh.cxx:2808
OUString WriteToString() const
Definition: asciiopt.cxx:195
sal_uInt16 sal_Unicode
bool dbfReadCharset(rtl_TextEncoding &nCharSet, SvStream *dbf_Stream)
static std::unique_ptr< SvStream > CreateStream(const OUString &rFileName, StreamMode eOpenMode, css::uno::Reference< css::awt::XWindow > xParentWin=nullptr)
PropertiesInfo aProperties
virtual void SAL_CALL setSourceDocument(const css::uno::Reference< css::lang::XComponent > &xDoc) override
Definition: filtuno.cxx:349
constexpr OUStringLiteral SC_UNONAME_FILENAME
Definition: filtuno.cxx:55
OUString aStrFont
Definition: imoptdlg.hxx:46
css::uno::Sequence< css::beans::PropertyValue > InitPropertySequence(::std::initializer_list< ::std::pair< OUString, css::uno::Any > > vInit)
virtual void SAL_CALL initialize(const css::uno::Sequence< css::uno::Any > &rArguments) override
Definition: filtuno.cxx:356
OUString aFilterOptions
Definition: filtuno.hxx:44
constexpr OUStringLiteral DBF_CHAR_SET
Definition: filtuno.cxx:60
constexpr OUStringLiteral DBF_SEP_PATH_IMPORT
Definition: filtuno.cxx:61
static OUString GetLotusFilterName()
Definition: docsh.cxx:2818
static SC_DLLPUBLIC void Init()
DLL-init/exit-code must be linked to the DLL only.
Definition: scdll.cxx:99
static weld::Window * GetFrameWeld(const css::uno::Reference< css::awt::XWindow > &rWindow)
float u
constexpr OUStringLiteral SC_UNONAME_INPUTSTREAM
Definition: filtuno.cxx:58
#define SC_SIMPLE_SERVICE_INFO(ClassName, ClassNameAscii, ServiceAscii)
Definition: miscuno.hxx:63
virtual void SAL_CALL setPropertyValues(const css::uno::Sequence< css::beans::PropertyValue > &aProps) override
Definition: filtuno.cxx:146
virtual VclPtr< AbstractScTextImportOptionsDlg > CreateScTextImportOptionsDlg(weld::Window *pParent)=0
OUString aFileName
Definition: filtuno.hxx:42
constexpr OUStringLiteral DBF_SEP_PATH_EXPORT
Definition: filtuno.cxx:62
virtual VclPtr< AbstractScImportOptionsDlg > CreateScImportOptionsDlg(weld::Window *pParent, bool bAscii, const ScImportOptions *pOptions, const OUString *pStrTitle, bool bOnlyDbtoolsEncodings, bool bImport=true)=0
SAL_DLLPUBLIC_EXPORT css::uno::XInterface * Calc_FilterOptionsDialog_get_implementation(css::uno::XComponentContext *, css::uno::Sequence< css::uno::Any > const &)
Definition: filtuno.cxx:130
virtual VclPtr< AbstractScImportAsciiDlg > CreateScImportAsciiDlg(weld::Window *pParent, const OUString &aDatName, SvStream *pInStream, ScImportAsciiCall eCall)=0
constexpr OUStringLiteral SC_UNONAME_FILTERNAME
Definition: filtuno.cxx:56
static SC_DLLPUBLIC ScAbstractDialogFactory * Create()
Definition: scabstdlg.cxx:37
RET_OK
static OUString GetDBaseFilterName()
Definition: docsh.cxx:2823
bool has(const char *_pAsciiValueName) const
OUString BuildString() const
Definition: imoptdlg.cxx:98
css::uno::Reference< css::awt::XWindow > xDialogParent
Definition: filtuno.hxx:46
rtl_TextEncoding eCharSet
Definition: imoptdlg.hxx:47
const css::uno::Any & get(const char *_pAsciiValueName) const
virtual void SaveParameters()=0
virtual void SAL_CALL setTargetDocument(const css::uno::Reference< css::lang::XComponent > &xDoc) override
Definition: filtuno.cxx:342
OUString FilterName
virtual ~ScFilterOptionsObj() override
Definition: filtuno.cxx:125
OUString getExtension(sal_Int32 nIndex=LAST_SEGMENT, bool bIgnoreFinalSlash=true, DecodeMechanism eMechanism=DecodeMechanism::ToIUri, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8) const
static OUString GetDifFilterName()
Definition: docsh.cxx:2828