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> 23 #include <unotools/ucbstreamhelper.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> 42 #include <comphelper/namedvaluecollection.hxx> 43 #include <comphelper/propertysequence.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 #define SCFILTEROPTIONSOBJ_SERVICE "com.sun.star.ui.dialogs.FilterOptionsDialog" 51 #define SCFILTEROPTIONSOBJ_IMPLNAME "com.sun.star.comp.Calc.FilterOptionsDialog" 52 53 SC_SIMPLE_SERVICE_INFO( ScFilterOptionsObj, SCFILTEROPTIONSOBJ_IMPLNAME, SCFILTEROPTIONSOBJ_SERVICE ) 54 55 #define SC_UNONAME_FILENAME "URL" 56 #define SC_UNONAME_FILTERNAME "FilterName" 57 #define SC_UNONAME_FILTEROPTIONS "FilterOptions" 58 #define SC_UNONAME_INPUTSTREAM "InputStream" 59 60 #define DBF_CHAR_SET "CharSet" 61 #define DBF_SEP_PATH_IMPORT "Office.Calc/Dialogs/DBFImport" 62 #define DBF_SEP_PATH_EXPORT "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; 83 Sequence<OUString> aNames { DBF_CHAR_SET }; 84 ScLinkConfigItem aItem( OUString::createFromAscii( 85 bExport?DBF_SEP_PATH_EXPORT:DBF_SEP_PATH_IMPORT ) ); 86 87 aValues = aItem.GetProperties( aNames ); 88 pProperties = aValues.getConstArray(); 89 90 if( pProperties[0].hasValue() ) 91 { 92 sal_Int32 nChar = 0; 93 pProperties[0] >>= nChar; 94 if( nChar >= 0) 95 { 96 nCharSet = static_cast<rtl_TextEncoding>(nChar); 97 return charsetSource::charset_from_user_setting; 98 } 99 } 100 101 // Default choice 102 nCharSet = RTL_TEXTENCODING_IBM_850; 103 return charsetSource::charset_default; 104 } 105 106 void save_CharSet( rtl_TextEncoding nCharSet, bool bExport ) 107 { 108 Sequence<Any> aValues; 109 Any *pProperties; 110 Sequence<OUString> aNames { DBF_CHAR_SET }; 111 ScLinkConfigItem aItem( OUString::createFromAscii( 112 bExport?DBF_SEP_PATH_EXPORT:DBF_SEP_PATH_IMPORT ) ); 113 114 aValues = aItem.GetProperties( aNames ); 115 pProperties = aValues.getArray(); 116 pProperties[0] <<= static_cast<sal_Int32>(nCharSet); 117 118 aItem.PutProperties(aNames, aValues); 119 } 120 } 121 122 ScFilterOptionsObj::ScFilterOptionsObj() : 123 bExport( false ) 124 { 125 } 126 127 ScFilterOptionsObj::~ScFilterOptionsObj() 128 { 129 } 130 131 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface* 132 Calc_FilterOptionsDialog_get_implementation(css::uno::XComponentContext*, css::uno::Sequence<css::uno::Any> const &) 133 { 134 SolarMutexGuard aGuard; 135 ScDLL::Init(); 136 return cppu::acquire(new ScFilterOptionsObj); 137 } 138 139 // XPropertyAccess 140 141 uno::Sequence<beans::PropertyValue> SAL_CALL ScFilterOptionsObj::getPropertyValues() 142 { 143 return comphelper::InitPropertySequence({ 144 { SC_UNONAME_FILTEROPTIONS, Any(aFilterOptions) } 145 }); 146 } 147 148 void SAL_CALL ScFilterOptionsObj::setPropertyValues( const uno::Sequence<beans::PropertyValue>& aProps ) 149 { 150 for (const beans::PropertyValue& rProp : aProps) 151 { 152 OUString aPropName(rProp.Name); 153 154 if ( aPropName == SC_UNONAME_FILENAME ) 155 rProp.Value >>= aFileName; 156 else if ( aPropName == SC_UNONAME_FILTERNAME ) 157 rProp.Value >>= aFilterName; 158 else if ( aPropName == SC_UNONAME_FILTEROPTIONS ) 159 rProp.Value >>= aFilterOptions; 160 else if ( aPropName == SC_UNONAME_INPUTSTREAM ) 161 rProp.Value >>= xInputStream; 162 } 163 } 164 165 // XExecutableDialog 166 167 void SAL_CALL ScFilterOptionsObj::setTitle( const OUString& /* aTitle */ ) 168 { 169 // not used 170 } 171 172 sal_Int16 SAL_CALL ScFilterOptionsObj::execute() 173 { 174 sal_Int16 nRet = ui::dialogs::ExecutableDialogResults::CANCEL; 175 176 OUString aFilterString( aFilterName ); 177 178 ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create(); 179 180 if ( !bExport && aFilterString == ScDocShell::GetAsciiFilterName() ) 181 { 182 // ascii import is special... 183 184 INetURLObject aURL( aFileName ); 185 OUString aPrivDatName(aURL.getName()); 186 std::unique_ptr<SvStream> pInStream; 187 if ( xInputStream.is() ) 188 pInStream = utl::UcbStreamHelper::CreateStream( xInputStream ); 189 190 ScopedVclPtr<AbstractScImportAsciiDlg> pDlg(pFact->CreateScImportAsciiDlg(Application::GetFrameWeld(xDialogParent), aPrivDatName, 191 pInStream.get(), SC_IMPORTFILE)); 192 if ( pDlg->Execute() == RET_OK ) 193 { 194 ScAsciiOptions aOptions; 195 pDlg->GetOptions( aOptions ); 196 pDlg->SaveParameters(); 197 aFilterOptions = aOptions.WriteToString(); 198 nRet = ui::dialogs::ExecutableDialogResults::OK; 199 } 200 } 201 else if ( aFilterString == ScDocShell::GetWebQueryFilterName() || aFilterString == ScDocShell::GetHtmlFilterName() ) 202 { 203 if (bExport) 204 nRet = ui::dialogs::ExecutableDialogResults::OK; // export HTML without dialog 205 else 206 { 207 // HTML import. 208 ScopedVclPtr<AbstractScTextImportOptionsDlg> pDlg( 209 pFact->CreateScTextImportOptionsDlg(Application::GetFrameWeld(xDialogParent))); 210 211 if (pDlg->Execute() == RET_OK) 212 { 213 LanguageType eLang = pDlg->GetLanguageType(); 214 OUStringBuffer aBuf; 215 216 aBuf.append(OUString::number(static_cast<sal_uInt16>(eLang))); 217 aBuf.append(' '); 218 aBuf.append(pDlg->IsDateConversionSet() ? u'1' : u'0'); 219 aFilterOptions = aBuf.makeStringAndClear(); 220 nRet = ui::dialogs::ExecutableDialogResults::OK; 221 } 222 } 223 } 224 else 225 { 226 bool bDBEnc = false; 227 bool bAscii = false; 228 bool skipDialog = false; 229 230 sal_Unicode const cStrDel = '"'; 231 sal_Unicode cAsciiDel = ';'; 232 rtl_TextEncoding eEncoding = RTL_TEXTENCODING_DONTKNOW; 233 234 OUString aTitle; 235 236 if ( aFilterString == ScDocShell::GetAsciiFilterName() ) 237 { 238 // ascii export (import is handled above) 239 240 INetURLObject aURL( aFileName ); 241 OUString aExt(aURL.getExtension()); 242 if (aExt.equalsIgnoreAsciiCase("CSV")) 243 cAsciiDel = ','; 244 else 245 cAsciiDel = '\t'; 246 247 aTitle = ScResId( STR_EXPORT_ASCII ); 248 bAscii = true; 249 } 250 else if ( aFilterString == ScDocShell::GetLotusFilterName() ) 251 { 252 // lotus is only imported 253 OSL_ENSURE( !bExport, "Filter Options for Lotus Export is not implemented" ); 254 255 aTitle = ScResId( STR_IMPORT_LOTUS ); 256 eEncoding = RTL_TEXTENCODING_IBM_437; 257 } 258 else if ( aFilterString == ScDocShell::GetDBaseFilterName() ) 259 { 260 if ( bExport ) 261 { 262 // dBase export 263 aTitle = ScResId( STR_EXPORT_DBF ); 264 } 265 else 266 { 267 // dBase import 268 aTitle = ScResId( STR_IMPORT_DBF ); 269 } 270 271 std::unique_ptr<SvStream> pInStream; 272 if ( xInputStream.is() ) 273 pInStream = utl::UcbStreamHelper::CreateStream( xInputStream ); 274 switch(load_CharSet( eEncoding, bExport, pInStream.get())) 275 { 276 case charsetSource::charset_from_file: 277 skipDialog = true; 278 break; 279 case charsetSource::charset_from_user_setting: 280 case charsetSource::charset_default: 281 break; 282 } 283 bDBEnc = true; 284 // pInStream goes out of scope, the stream is automatically closed 285 } 286 else if ( aFilterString == ScDocShell::GetDifFilterName() ) 287 { 288 if ( bExport ) 289 { 290 // DIF export 291 aTitle = ScResId( STR_EXPORT_DIF ); 292 } 293 else 294 { 295 // DIF import 296 aTitle = ScResId( STR_IMPORT_DIF ); 297 } 298 // common for DIF import/export 299 eEncoding = RTL_TEXTENCODING_MS_1252; 300 } 301 302 ScImportOptions aOptions( cAsciiDel, cStrDel, eEncoding); 303 if(skipDialog) 304 { 305 // TODO: check we are not missing some of the stuff that ScImportOptionsDlg::GetImportOptions 306 // (file sc/source/ui/dbgui/scuiimoptdlg.cxx) does 307 // that is, if the dialog sets options that are not selected by the user (!) 308 // then we are missing them here. 309 // Then we may need to rip them out of the dialog. 310 // Or we actually change the dialog to not display if skipDialog==true 311 // in that case, add an argument skipDialog to CreateScImportOptionsDlg 312 nRet = ui::dialogs::ExecutableDialogResults::OK; 313 } 314 else 315 { 316 ScopedVclPtr<AbstractScImportOptionsDlg> pDlg(pFact->CreateScImportOptionsDlg(Application::GetFrameWeld(xDialogParent), 317 bAscii, &aOptions, &aTitle, 318 bDBEnc, !bExport)); 319 if ( pDlg->Execute() == RET_OK ) 320 { 321 pDlg->SaveImportOptions(); 322 pDlg->GetImportOptions( aOptions ); 323 save_CharSet( aOptions.eCharSet, bExport ); 324 nRet = ui::dialogs::ExecutableDialogResults::OK; 325 } 326 } 327 if (nRet == ui::dialogs::ExecutableDialogResults::OK) 328 { 329 if ( bAscii ) 330 aFilterOptions = aOptions.BuildString(); 331 else 332 aFilterOptions = aOptions.aStrFont; 333 } 334 } 335 336 xInputStream.clear(); // don't hold the stream longer than necessary 337 338 return nRet; 339 } 340 341 // XImporter 342 343 void SAL_CALL ScFilterOptionsObj::setTargetDocument( const uno::Reference<lang::XComponent>& /* xDoc */ ) 344 { 345 bExport = false; 346 } 347 348 // XExporter 349 350 void SAL_CALL ScFilterOptionsObj::setSourceDocument( const uno::Reference<lang::XComponent>& /* xDoc */ ) 351 { 352 bExport = true; 353 } 354 355 // XInitialization 356 357 void SAL_CALL ScFilterOptionsObj::initialize(const uno::Sequence<uno::Any>& rArguments) 358 { 359 ::comphelper::NamedValueCollection aProperties(rArguments); 360 if (aProperties.has("ParentWindow")) 361 aProperties.get("ParentWindow") >>= xDialogParent; 362 } 363 364 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ 365
