371 lines
12 KiB
C++
371 lines
12 KiB
C++
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
/*
|
|
* This file is part of the LibreOffice project.
|
|
*
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
*
|
|
* This file incorporates work covered by the following license notice:
|
|
*
|
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
* contributor license agreements. See the NOTICE file distributed
|
|
* with this work for additional information regarding copyright
|
|
* ownership. The ASF licenses this file to you under the Apache
|
|
* License, Version 2.0 (the "License"); you may not use this file
|
|
* except in compliance with the License. You may obtain a copy of
|
|
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
|
|
*/
|
|
|
|
#include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
|
|
#include <tools/urlobj.hxx>
|
|
#include <vcl/svapp.hxx>
|
|
#include <unotools/ucbstreamhelper.hxx>
|
|
#include <connectivity/dbtools.hxx>
|
|
#include <osl/diagnose.h>
|
|
|
|
#include <filtuno.hxx>
|
|
#include <miscuno.hxx>
|
|
#include <scdll.hxx>
|
|
#include <imoptdlg.hxx>
|
|
#include <asciiopt.hxx>
|
|
#include <docsh.hxx>
|
|
#include <globstr.hrc>
|
|
#include <scresid.hxx>
|
|
|
|
#include <scabstdlg.hxx>
|
|
#include <i18nlangtag/lang.h>
|
|
|
|
#include <optutil.hxx>
|
|
#include <com/sun/star/uno/Any.hxx>
|
|
#include <com/sun/star/uno/Sequence.hxx>
|
|
#include <comphelper/namedvaluecollection.hxx>
|
|
#include <comphelper/propertysequence.hxx>
|
|
#include <memory>
|
|
|
|
using namespace com::sun::star;
|
|
using namespace com::sun::star::uno;
|
|
using namespace connectivity::dbase;
|
|
|
|
constexpr OUString SCFILTEROPTIONSOBJ_SERVICE = u"com.sun.star.ui.dialogs.FilterOptionsDialog"_ustr;
|
|
constexpr OUStringLiteral SCFILTEROPTIONSOBJ_IMPLNAME = u"com.sun.star.comp.Calc.FilterOptionsDialog";
|
|
|
|
SC_SIMPLE_SERVICE_INFO( ScFilterOptionsObj, SCFILTEROPTIONSOBJ_IMPLNAME, SCFILTEROPTIONSOBJ_SERVICE )
|
|
|
|
constexpr OUStringLiteral SC_UNONAME_FILENAME = u"URL";
|
|
constexpr OUStringLiteral SC_UNONAME_FILTERNAME = u"FilterName";
|
|
constexpr OUString SC_UNONAME_FILTEROPTIONS = u"FilterOptions"_ustr;
|
|
constexpr OUStringLiteral SC_UNONAME_INPUTSTREAM = u"InputStream";
|
|
|
|
constexpr OUString DBF_CHAR_SET = u"CharSet"_ustr;
|
|
constexpr OUString DBF_SEP_PATH_IMPORT = u"Office.Calc/Dialogs/DBFImport"_ustr;
|
|
constexpr OUString DBF_SEP_PATH_EXPORT = u"Office.Calc/Dialogs/DBFExport"_ustr;
|
|
|
|
namespace
|
|
{
|
|
|
|
enum class charsetSource
|
|
{
|
|
charset_from_file,
|
|
charset_from_user_setting,
|
|
charset_default
|
|
};
|
|
|
|
charsetSource load_CharSet(rtl_TextEncoding &nCharSet, bool bExport, SvStream* dbf_Stream)
|
|
{
|
|
if (dbf_Stream && dbfReadCharset(nCharSet, dbf_Stream))
|
|
{
|
|
return charsetSource::charset_from_file;
|
|
}
|
|
|
|
Sequence<Any> aValues;
|
|
const Any *pProperties;
|
|
Sequence<OUString> aNames { DBF_CHAR_SET };
|
|
ScLinkConfigItem aItem( bExport ? DBF_SEP_PATH_EXPORT : DBF_SEP_PATH_IMPORT );
|
|
|
|
aValues = aItem.GetProperties( aNames );
|
|
pProperties = aValues.getConstArray();
|
|
|
|
if( pProperties[0].hasValue() )
|
|
{
|
|
sal_Int32 nChar = 0;
|
|
pProperties[0] >>= nChar;
|
|
if( nChar >= 0)
|
|
{
|
|
nCharSet = static_cast<rtl_TextEncoding>(nChar);
|
|
return charsetSource::charset_from_user_setting;
|
|
}
|
|
}
|
|
|
|
// Default choice
|
|
nCharSet = RTL_TEXTENCODING_IBM_850;
|
|
return charsetSource::charset_default;
|
|
}
|
|
|
|
void save_CharSet( rtl_TextEncoding nCharSet, bool bExport )
|
|
{
|
|
Sequence<Any> aValues;
|
|
Any *pProperties;
|
|
Sequence<OUString> aNames { DBF_CHAR_SET };
|
|
ScLinkConfigItem aItem( bExport ? DBF_SEP_PATH_EXPORT : DBF_SEP_PATH_IMPORT );
|
|
|
|
aValues = aItem.GetProperties( aNames );
|
|
pProperties = aValues.getArray();
|
|
pProperties[0] <<= static_cast<sal_Int32>(nCharSet);
|
|
|
|
aItem.PutProperties(aNames, aValues);
|
|
}
|
|
}
|
|
|
|
ScFilterOptionsObj::ScFilterOptionsObj() :
|
|
bExport( false )
|
|
{
|
|
}
|
|
|
|
ScFilterOptionsObj::~ScFilterOptionsObj()
|
|
{
|
|
}
|
|
|
|
extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
|
|
Calc_FilterOptionsDialog_get_implementation(css::uno::XComponentContext*, css::uno::Sequence<css::uno::Any> const &)
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
ScDLL::Init();
|
|
return cppu::acquire(new ScFilterOptionsObj);
|
|
}
|
|
|
|
// XPropertyAccess
|
|
|
|
uno::Sequence<beans::PropertyValue> SAL_CALL ScFilterOptionsObj::getPropertyValues()
|
|
{
|
|
return comphelper::InitPropertySequence({
|
|
{ SC_UNONAME_FILTEROPTIONS, Any(aFilterOptions) }
|
|
});
|
|
}
|
|
|
|
void SAL_CALL ScFilterOptionsObj::setPropertyValues( const uno::Sequence<beans::PropertyValue>& aProps )
|
|
{
|
|
for (const beans::PropertyValue& rProp : aProps)
|
|
{
|
|
OUString aPropName(rProp.Name);
|
|
|
|
if ( aPropName == SC_UNONAME_FILENAME )
|
|
rProp.Value >>= aFileName;
|
|
else if ( aPropName == SC_UNONAME_FILTERNAME )
|
|
rProp.Value >>= aFilterName;
|
|
else if ( aPropName == SC_UNONAME_FILTEROPTIONS )
|
|
rProp.Value >>= aFilterOptions;
|
|
else if ( aPropName == SC_UNONAME_INPUTSTREAM )
|
|
rProp.Value >>= xInputStream;
|
|
}
|
|
}
|
|
|
|
// XExecutableDialog
|
|
|
|
void SAL_CALL ScFilterOptionsObj::setTitle( const OUString& /* aTitle */ )
|
|
{
|
|
// not used
|
|
}
|
|
|
|
sal_Int16 SAL_CALL ScFilterOptionsObj::execute()
|
|
{
|
|
sal_Int16 nRet = ui::dialogs::ExecutableDialogResults::CANCEL;
|
|
|
|
OUString aFilterString( aFilterName );
|
|
|
|
ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
|
|
|
|
if ( !bExport && aFilterString == ScDocShell::GetAsciiFilterName() )
|
|
{
|
|
// ascii import is special...
|
|
|
|
INetURLObject aURL( aFileName );
|
|
// tdf#132421 - don't URL encode filename for the import ASCII dialog title
|
|
OUString aPrivDatName(aURL.GetLastName(INetURLObject::DecodeMechanism::Unambiguous));
|
|
std::unique_ptr<SvStream> pInStream;
|
|
if ( xInputStream.is() )
|
|
pInStream = utl::UcbStreamHelper::CreateStream( xInputStream );
|
|
|
|
ScopedVclPtr<AbstractScImportAsciiDlg> pDlg(pFact->CreateScImportAsciiDlg(Application::GetFrameWeld(xDialogParent), aPrivDatName,
|
|
pInStream.get(), SC_IMPORTFILE));
|
|
if ( pDlg->Execute() == RET_OK )
|
|
{
|
|
ScAsciiOptions aOptions;
|
|
pDlg->GetOptions( aOptions );
|
|
pDlg->SaveParameters();
|
|
aFilterOptions = aOptions.WriteToString();
|
|
nRet = ui::dialogs::ExecutableDialogResults::OK;
|
|
}
|
|
}
|
|
else if ( aFilterString == ScDocShell::GetWebQueryFilterName() || aFilterString == ScDocShell::GetHtmlFilterName() )
|
|
{
|
|
if (bExport)
|
|
nRet = ui::dialogs::ExecutableDialogResults::OK; // export HTML without dialog
|
|
else
|
|
{
|
|
// HTML import.
|
|
ScopedVclPtr<AbstractScTextImportOptionsDlg> pDlg(
|
|
pFact->CreateScTextImportOptionsDlg(Application::GetFrameWeld(xDialogParent)));
|
|
|
|
if (pDlg->Execute() == RET_OK)
|
|
{
|
|
LanguageType eLang = pDlg->GetLanguageType();
|
|
OUStringBuffer aBuf;
|
|
|
|
aBuf.append(static_cast<sal_Int32>(static_cast<sal_uInt16>(eLang)));
|
|
aBuf.append(' ');
|
|
aBuf.append(pDlg->IsDateConversionSet() ? u'1' : u'0');
|
|
aBuf.append(' ');
|
|
aBuf.append(pDlg->IsScientificConversionSet() ? u'1' : u'0');
|
|
aFilterOptions = aBuf.makeStringAndClear();
|
|
nRet = ui::dialogs::ExecutableDialogResults::OK;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
bool bDBEnc = false;
|
|
bool bAscii = false;
|
|
bool skipDialog = false;
|
|
|
|
sal_Unicode const cStrDel = '"';
|
|
sal_Unicode cAsciiDel = ';';
|
|
rtl_TextEncoding eEncoding = RTL_TEXTENCODING_DONTKNOW;
|
|
|
|
OUString aTitle;
|
|
bool bIncludeBOM = false;
|
|
|
|
if ( aFilterString == ScDocShell::GetAsciiFilterName() )
|
|
{
|
|
// ascii export (import is handled above)
|
|
|
|
INetURLObject aURL( aFileName );
|
|
OUString aExt(aURL.getExtension());
|
|
if (aExt.equalsIgnoreAsciiCase("CSV"))
|
|
cAsciiDel = ',';
|
|
else
|
|
cAsciiDel = '\t';
|
|
|
|
aTitle = ScResId( STR_EXPORT_ASCII );
|
|
bAscii = true;
|
|
|
|
ScAsciiOptions aOptions;
|
|
aOptions.ReadFromString(aFilterOptions);
|
|
bIncludeBOM = aOptions.GetIncludeBOM();
|
|
}
|
|
else if ( aFilterString == ScDocShell::GetLotusFilterName() )
|
|
{
|
|
// lotus is only imported
|
|
OSL_ENSURE( !bExport, "Filter Options for Lotus Export is not implemented" );
|
|
|
|
aTitle = ScResId( STR_IMPORT_LOTUS );
|
|
eEncoding = RTL_TEXTENCODING_IBM_437;
|
|
}
|
|
else if ( aFilterString == ScDocShell::GetDBaseFilterName() )
|
|
{
|
|
if ( bExport )
|
|
{
|
|
// dBase export
|
|
aTitle = ScResId( STR_EXPORT_DBF );
|
|
}
|
|
else
|
|
{
|
|
// dBase import
|
|
aTitle = ScResId( STR_IMPORT_DBF );
|
|
}
|
|
|
|
std::unique_ptr<SvStream> pInStream;
|
|
if ( xInputStream.is() )
|
|
pInStream = utl::UcbStreamHelper::CreateStream( xInputStream );
|
|
switch(load_CharSet( eEncoding, bExport, pInStream.get()))
|
|
{
|
|
case charsetSource::charset_from_file:
|
|
skipDialog = true;
|
|
break;
|
|
case charsetSource::charset_from_user_setting:
|
|
case charsetSource::charset_default:
|
|
break;
|
|
}
|
|
bDBEnc = true;
|
|
// pInStream goes out of scope, the stream is automatically closed
|
|
}
|
|
else if ( aFilterString == ScDocShell::GetDifFilterName() )
|
|
{
|
|
if ( bExport )
|
|
{
|
|
// DIF export
|
|
aTitle = ScResId( STR_EXPORT_DIF );
|
|
}
|
|
else
|
|
{
|
|
// DIF import
|
|
aTitle = ScResId( STR_IMPORT_DIF );
|
|
}
|
|
// common for DIF import/export
|
|
eEncoding = RTL_TEXTENCODING_MS_1252;
|
|
}
|
|
|
|
ScImportOptions aOptions( cAsciiDel, cStrDel, eEncoding);
|
|
aOptions.bIncludeBOM = bIncludeBOM;
|
|
if(skipDialog)
|
|
{
|
|
// TODO: check we are not missing some of the stuff that ScImportOptionsDlg::GetImportOptions
|
|
// (file sc/source/ui/dbgui/scuiimoptdlg.cxx) does
|
|
// that is, if the dialog sets options that are not selected by the user (!)
|
|
// then we are missing them here.
|
|
// Then we may need to rip them out of the dialog.
|
|
// Or we actually change the dialog to not display if skipDialog==true
|
|
// in that case, add an argument skipDialog to CreateScImportOptionsDlg
|
|
nRet = ui::dialogs::ExecutableDialogResults::OK;
|
|
}
|
|
else
|
|
{
|
|
ScopedVclPtr<AbstractScImportOptionsDlg> pDlg(pFact->CreateScImportOptionsDlg(Application::GetFrameWeld(xDialogParent),
|
|
bAscii, &aOptions, &aTitle,
|
|
bDBEnc, !bExport));
|
|
if ( pDlg->Execute() == RET_OK )
|
|
{
|
|
pDlg->SaveImportOptions();
|
|
pDlg->GetImportOptions( aOptions );
|
|
save_CharSet( aOptions.eCharSet, bExport );
|
|
nRet = ui::dialogs::ExecutableDialogResults::OK;
|
|
}
|
|
}
|
|
if (nRet == ui::dialogs::ExecutableDialogResults::OK)
|
|
{
|
|
if ( bAscii )
|
|
aFilterOptions = aOptions.BuildString();
|
|
else
|
|
aFilterOptions = aOptions.aStrFont;
|
|
}
|
|
}
|
|
|
|
xInputStream.clear(); // don't hold the stream longer than necessary
|
|
|
|
return nRet;
|
|
}
|
|
|
|
// XImporter
|
|
|
|
void SAL_CALL ScFilterOptionsObj::setTargetDocument( const uno::Reference<lang::XComponent>& /* xDoc */ )
|
|
{
|
|
bExport = false;
|
|
}
|
|
|
|
// XExporter
|
|
|
|
void SAL_CALL ScFilterOptionsObj::setSourceDocument( const uno::Reference<lang::XComponent>& /* xDoc */ )
|
|
{
|
|
bExport = true;
|
|
}
|
|
|
|
// XInitialization
|
|
|
|
void SAL_CALL ScFilterOptionsObj::initialize(const uno::Sequence<uno::Any>& rArguments)
|
|
{
|
|
::comphelper::NamedValueCollection aProperties(rArguments);
|
|
if (aProperties.has(u"ParentWindow"_ustr))
|
|
aProperties.get(u"ParentWindow"_ustr) >>= xDialogParent;
|
|
}
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|