Related: rhbz#1980800 add in improvements

f41
Caolán McNamara 3 years ago
parent 6d279d778f
commit bc1c0f97e2

@ -1,4 +1,4 @@
From c4961f30f3ab5ea1efd1fc143fac0a22d6a4a2a9 Mon Sep 17 00:00:00 2001 From aec3e189e6e9aa1eb2fe91cbb1c46f308b074cd5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= <caolanm@redhat.com> From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= <caolanm@redhat.com>
Date: Tue, 13 Jul 2021 12:38:07 +0100 Date: Tue, 13 Jul 2021 12:38:07 +0100
Subject: [PATCH] rhbz#1980800 allow --convert-to csv to write each sheet to a Subject: [PATCH] rhbz#1980800 allow --convert-to csv to write each sheet to a
@ -22,16 +22,38 @@ Reviewed-on: https://gerrit.libreoffice.org/c/core/+/118850
Tested-by: Jenkins Tested-by: Jenkins
Reviewed-by: Eike Rathke <erack@redhat.com> Reviewed-by: Eike Rathke <erack@redhat.com>
(cherry picked from commit b8903bc106dad036acb3d117e5c4fc955697fe02) (cherry picked from commit b8903bc106dad036acb3d117e5c4fc955697fe02)
Related: tdf#135762 Allow --convert-to csv to specify 1-based sheet number
Same multifile mechanism as for -1 all sheets is used, so
soffice --convert-to csv:"Text - txt - csv (StarCalc)":44,34,UTF8,1,,0,false,true,false,false,false,2 sample.ods
writes a file sample-Sheet2.csv
Change-Id: Ib9248c9561e4e340c88458ac5dfd159e443a4cfd
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/118971
Reviewed-by: Eike Rathke <erack@redhat.com>
Tested-by: Jenkins
(cherry picked from commit fda91f8be16ba760e360940ebafd6244c648cb8c)
Related: tdf#135762 Suppress cout if not command line
Change-Id: I9431221aadf97739bb197871f25fa151ef4c391c
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/119294
Reviewed-by: Eike Rathke <erack@redhat.com>
Tested-by: Jenkins
(cherry picked from commit 0cda081c9aa3b3dcb363f97bac60c845ce9a13e0)
--- ---
desktop/source/app/dispatchwatcher.cxx | 26 +++++-- desktop/source/app/dispatchwatcher.cxx | 50 +++++++--
sc/source/ui/dbgui/imoptdlg.cxx | 7 +- sc/source/ui/dbgui/imoptdlg.cxx | 16 ++-
sc/source/ui/docshell/docsh.cxx | 97 +++++++++++++++++++------- sc/source/ui/docshell/docsh.cxx | 141 +++++++++++++++++++++----
sc/source/ui/inc/docsh.hxx | 2 +- sc/source/ui/inc/docsh.hxx | 2 +-
sc/source/ui/inc/imoptdlg.hxx | 6 +- sc/source/ui/inc/imoptdlg.hxx | 6 +-
5 files changed, 106 insertions(+), 32 deletions(-) 5 files changed, 179 insertions(+), 36 deletions(-)
diff --git a/desktop/source/app/dispatchwatcher.cxx b/desktop/source/app/dispatchwatcher.cxx diff --git a/desktop/source/app/dispatchwatcher.cxx b/desktop/source/app/dispatchwatcher.cxx
index 50b92ecb7834..0660ccf3f83e 100644 index 50b92ecb7834..3df4f34ccf83 100644
--- a/desktop/source/app/dispatchwatcher.cxx --- a/desktop/source/app/dispatchwatcher.cxx
+++ b/desktop/source/app/dispatchwatcher.cxx +++ b/desktop/source/app/dispatchwatcher.cxx
@@ -30,6 +30,7 @@ @@ -30,6 +30,7 @@
@ -51,8 +73,25 @@ index 50b92ecb7834..0660ccf3f83e 100644
if (aFilter.isEmpty()) if (aFilter.isEmpty())
{ {
std::cerr << "Error: no export filter" << std::endl; std::cerr << "Error: no export filter" << std::endl;
@@ -616,10 +619,23 @@ bool DispatchWatcher::executeDispatchRequests( const std::vector<DispatchRequest @@ -605,29 +608,54 @@ bool DispatchWatcher::executeDispatchRequests( const std::vector<DispatchRequest
conversionProperties[1].Name = "FilterName"; else
{
sal_Int32 nFilterOptionsIndex = aFilter.indexOf(':');
- sal_Int32 nProps = ( 0 < nFilterOptionsIndex ) ? 3 : 2;
+ sal_Int32 nProps = ( 0 < nFilterOptionsIndex ) ? 4 : 3;
if ( !aImgOut.isEmpty() )
nProps +=1;
Sequence<PropertyValue> conversionProperties( nProps );
- conversionProperties[0].Name = "Overwrite";
- conversionProperties[0].Value <<= true;
+ conversionProperties[0].Name = "ConversionRequestOrigin";
+ conversionProperties[0].Value <<= OUString("CommandLine");
+ conversionProperties[1].Name = "Overwrite";
+ conversionProperties[1].Value <<= true;
- conversionProperties[1].Name = "FilterName";
+ conversionProperties[2].Name = "FilterName";
if( 0 < nFilterOptionsIndex ) if( 0 < nFilterOptionsIndex )
{ {
- conversionProperties[1].Value <<= aFilter.copy(0, nFilterOptionsIndex); - conversionProperties[1].Value <<= aFilter.copy(0, nFilterOptionsIndex);
@ -62,22 +101,42 @@ index 50b92ecb7834..0660ccf3f83e 100644
+ if (sFilterName == "Text - txt - csv (StarCalc)") + if (sFilterName == "Text - txt - csv (StarCalc)")
+ { + {
+ sal_Int32 nIdx(0); + sal_Int32 nIdx(0);
+ // If the 11th token token is '-1' then we export a file + // If the 11th token is '-1' then we export a file
+ // per sheet where the file name is based on the suggested + // per sheet where the file name is based on the suggested
+ // output filename concatenated with the sheet name, so adjust + // output filename concatenated with the sheet name, so adjust
+ // the output and overwrite messages + // the output and overwrite messages
+ bMultiFileTarget = sFilterOptions.getToken(11, ',', nIdx) == "-1"; + // If the 11th token is not present or numeric 0 then the
+ // default sheet is exported with the output filename. If it
+ // is numeric >0 then that sheet (1-based) with the output
+ // filename concatenated with the sheet name. So even if
+ // that is a single file, the multi file target mechanism is
+ // used.
+ const OUString aTok(sFilterOptions.getToken(11, ',', nIdx));
+ // Actual validity is checked in Calc, here just check for
+ // presence of numeric value at start.
+ bMultiFileTarget = (!aTok.isEmpty() && aTok.toInt32() != 0);
+ } + }
+ +
+ conversionProperties[1].Value <<= sFilterName; + conversionProperties[2].Value <<= sFilterName;
conversionProperties[2].Name = "FilterOptions"; - conversionProperties[2].Name = "FilterOptions";
- conversionProperties[2].Value <<= aFilter.copy(nFilterOptionsIndex + 1); - conversionProperties[2].Value <<= aFilter.copy(nFilterOptionsIndex + 1);
+ conversionProperties[2].Value <<= sFilterOptions; + conversionProperties[3].Name = "FilterOptions";
+ conversionProperties[3].Value <<= sFilterOptions;
} }
else else
{ {
@@ -639,9 +655,11 @@ bool DispatchWatcher::executeDispatchRequests( const std::vector<DispatchRequest - conversionProperties[1].Value <<= aFilter;
+ conversionProperties[2].Value <<= aFilter;
}
if ( !aImgOut.isEmpty() )
{
+ assert(conversionProperties[nProps-1].Name.isEmpty());
conversionProperties[nProps-1].Name = "ImageFilter";
conversionProperties[nProps-1].Value <<= aImgOut;
}
@@ -639,9 +667,11 @@ bool DispatchWatcher::executeDispatchRequests( const std::vector<DispatchRequest
OString aTargetURL8 = OUStringToOString(aTempName, osl_getThreadTextEncoding()); OString aTargetURL8 = OUStringToOString(aTempName, osl_getThreadTextEncoding());
if (aDispatchRequest.aRequestType != REQUEST_CAT) if (aDispatchRequest.aRequestType != REQUEST_CAT)
{ {
@ -92,39 +151,55 @@ index 50b92ecb7834..0660ccf3f83e 100644
} }
try try
diff --git a/sc/source/ui/dbgui/imoptdlg.cxx b/sc/source/ui/dbgui/imoptdlg.cxx diff --git a/sc/source/ui/dbgui/imoptdlg.cxx b/sc/source/ui/dbgui/imoptdlg.cxx
index 071f1b0257bc..d8c4fd810ea3 100644 index 071f1b0257bc..a362e4df0ee7 100644
--- a/sc/source/ui/dbgui/imoptdlg.cxx --- a/sc/source/ui/dbgui/imoptdlg.cxx
+++ b/sc/source/ui/dbgui/imoptdlg.cxx +++ b/sc/source/ui/dbgui/imoptdlg.cxx
@@ -43,6 +43,7 @@ ScImportOptions::ScImportOptions( const OUString& rStr ) @@ -20,6 +20,7 @@
#include <imoptdlg.hxx>
#include <asciiopt.hxx>
#include <comphelper/string.hxx>
+#include <unotools/charclass.hxx>
#include <osl/thread.h>
#include <global.hxx>
@@ -43,6 +44,7 @@ ScImportOptions::ScImportOptions( const OUString& rStr )
bSaveNumberAsSuch = true; bSaveNumberAsSuch = true;
bSaveFormulas = false; bSaveFormulas = false;
bRemoveSpace = false; bRemoveSpace = false;
+ bNewFilePerSheet = false; + nSheetToExport = 0;
sal_Int32 nTokenCount = comphelper::string::getTokenCount(rStr, ','); sal_Int32 nTokenCount = comphelper::string::getTokenCount(rStr, ',');
if ( nTokenCount < 3 ) if ( nTokenCount < 3 )
return; return;
@@ -77,6 +78,8 @@ ScImportOptions::ScImportOptions( const OUString& rStr ) @@ -77,6 +79,16 @@ ScImportOptions::ScImportOptions( const OUString& rStr )
bSaveFormulas = rStr.getToken(0, ',', nIdx) == "true"; bSaveFormulas = rStr.getToken(0, ',', nIdx) == "true";
if ( nTokenCount >= 11 ) if ( nTokenCount >= 11 )
bRemoveSpace = rStr.getToken(0, ',', nIdx) == "true"; bRemoveSpace = rStr.getToken(0, ',', nIdx) == "true";
+ if ( nTokenCount >= 12 ) + if ( nTokenCount >= 12 )
+ bNewFilePerSheet = rStr.getToken(0, ',', nIdx) == "-1"; + {
+ const OUString aTok(rStr.getToken(0, ',', nIdx));
+ if (aTok == "-1")
+ nSheetToExport = -1; // all
+ else if (aTok.isEmpty() || CharClass::isAsciiNumeric(aTok))
+ nSheetToExport = aTok.toInt32();
+ else
+ nSheetToExport = -23; // invalid, force error
+ }
} }
} }
@@ -99,7 +102,9 @@ OUString ScImportOptions::BuildString() const @@ -99,7 +111,9 @@ OUString ScImportOptions::BuildString() const
"," + "," +
OUString::boolean( bSaveFormulas ) + // "save formulas": not in ScAsciiOptions OUString::boolean( bSaveFormulas ) + // "save formulas": not in ScAsciiOptions
"," + "," +
- OUString::boolean( bRemoveSpace ); // same as "Remove space" in ScAsciiOptions - OUString::boolean( bRemoveSpace ); // same as "Remove space" in ScAsciiOptions
+ OUString::boolean( bRemoveSpace ) + // same as "Remove space" in ScAsciiOptions + OUString::boolean( bRemoveSpace ) + // same as "Remove space" in ScAsciiOptions
+ "," + + "," +
+ std::u16string_view(bNewFilePerSheet ? u"-1" : u"0") ; // Only available for command line --convert-to + OUString::number(nSheetToExport) ; // Only available for command line --convert-to
return aResult; return aResult;
} }
diff --git a/sc/source/ui/docshell/docsh.cxx b/sc/source/ui/docshell/docsh.cxx diff --git a/sc/source/ui/docshell/docsh.cxx b/sc/source/ui/docshell/docsh.cxx
index 91020db0b2e0..7cee6bb7f32e 100644 index 91020db0b2e0..5fdfddd0c89b 100644
--- a/sc/source/ui/docshell/docsh.cxx --- a/sc/source/ui/docshell/docsh.cxx
+++ b/sc/source/ui/docshell/docsh.cxx +++ b/sc/source/ui/docshell/docsh.cxx
@@ -44,6 +44,7 @@ @@ -44,6 +44,7 @@
@ -160,7 +235,7 @@ index 91020db0b2e0..7cee6bb7f32e 100644
SCCOL nEndCol; SCCOL nEndCol;
SCROW nEndRow; SCROW nEndRow;
m_aDocument.GetCellArea( nTab, nEndCol, nEndRow ); m_aDocument.GetCellArea( nTab, nEndCol, nEndRow );
@@ -2389,35 +2390,81 @@ bool ScDocShell::ConvertTo( SfxMedium &rMed ) @@ -2389,35 +2390,129 @@ bool ScDocShell::ConvertTo( SfxMedium &rMed )
} }
else if (aFltName == pFilterAscii) else if (aFltName == pFilterAscii)
{ {
@ -177,47 +252,89 @@ index 91020db0b2e0..7cee6bb7f32e 100644
- const SfxPoolItem* pItem; - const SfxPoolItem* pItem;
- if ( pSet && SfxItemState::SET == - if ( pSet && SfxItemState::SET ==
- pSet->GetItemState( SID_FILE_FILTEROPTIONS, true, &pItem ) ) - pSet->GetItemState( SID_FILE_FILTEROPTIONS, true, &pItem ) )
- {
- sItStr = static_cast<const SfxStringItem*>(pItem)->GetValue();
- }
+ sItStr = static_cast<const SfxStringItem*>(pItem)->GetValue(); + sItStr = static_cast<const SfxStringItem*>(pItem)->GetValue();
+ } + }
+
- if ( sItStr.isEmpty() )
- {
- // default for ascii export (from API without options):
- // ISO8859-1/MS_1252 encoding, comma, double quotes
+ if ( sItStr.isEmpty() ) + if ( sItStr.isEmpty() )
+ { + {
+ // default for ascii export (from API without options): + // default for ascii export (from API without options):
+ // ISO8859-1/MS_1252 encoding, comma, double quotes + // ISO8859-1/MS_1252 encoding, comma, double quotes
+
- ScImportOptions aDefOptions( ',', '"', RTL_TEXTENCODING_MS_1252 );
- sItStr = aDefOptions.BuildString();
- }
+ ScImportOptions aDefOptions( ',', '"', RTL_TEXTENCODING_MS_1252 ); + ScImportOptions aDefOptions( ',', '"', RTL_TEXTENCODING_MS_1252 );
+ sItStr = aDefOptions.BuildString(); + sItStr = aDefOptions.BuildString();
+ } + }
+
- weld::WaitObject aWait( GetActiveDialogParent() );
- ScImportOptions aOptions( sItStr );
- AsciiSave( *pStream, aOptions );
+ weld::WaitObject aWait( GetActiveDialogParent() ); + weld::WaitObject aWait( GetActiveDialogParent() );
+ ScImportOptions aOptions( sItStr ); + ScImportOptions aOptions( sItStr );
+ +
+ if (aOptions.bNewFilePerSheet) + if (aOptions.nSheetToExport)
+ { + {
bRet = true; + // Only from command line --convert-to
+ bRet = true;
+
+ // Verbose only from command line, not UI (in case we actually
+ // implement that) nor macro filter options.
+ bool bVerbose = false;
+ const css::uno::Sequence<css::beans::PropertyValue> & rArgs = rMed.GetArgs();
+ const auto pProp = std::find_if( rArgs.begin(), rArgs.end(),
+ [](const css::beans::PropertyValue& rProp) { return rProp.Name == "ConversionRequestOrigin"; });
+ if (pProp != rArgs.end())
{
- sItStr = static_cast<const SfxStringItem*>(pItem)->GetValue();
+ OUString aOrigin;
+ pProp->Value >>= aOrigin;
+ bVerbose = (aOrigin == "CommandLine");
}
- if (m_aDocument.GetTableCount() > 1) - if ( sItStr.isEmpty() )
- if (!rMed.GetError()) + SCTAB nStartTab;
- rMed.SetError(SCWARN_EXPORT_ASCII); + SCTAB nCount = m_aDocument.GetTableCount();
+ if (aOptions.nSheetToExport == -1)
{
- // default for ascii export (from API without options):
- // ISO8859-1/MS_1252 encoding, comma, double quotes
-
- ScImportOptions aDefOptions( ',', '"', RTL_TEXTENCODING_MS_1252 );
- sItStr = aDefOptions.BuildString();
+ // All sheets.
+ nStartTab = 0;
+ }
+ else if (0 < aOptions.nSheetToExport && aOptions.nSheetToExport <= nCount)
+ {
+ // One sheet, 1-based.
+ nCount = aOptions.nSheetToExport;
+ nStartTab = nCount - 1;
+ }
+ else
+ {
+ // Usage error, no export but log.
+ if (bVerbose)
+ {
+ if (aOptions.nSheetToExport < 0)
+ std::cout << "Bad sheet number string given." << std::endl;
+ else
+ std::cout << "No sheet number " << aOptions.nSheetToExport
+ << ", number of sheets is " << nCount << std::endl;
+ }
+ nStartTab = 0;
+ nCount = 0;
+ SetError(SCERR_EXPORT_DATA);
+ bRet = false;
}
- weld::WaitObject aWait( GetActiveDialogParent() );
- ScImportOptions aOptions( sItStr );
- AsciiSave( *pStream, aOptions );
- bRet = true;
+ INetURLObject aURLObject(rMed.GetURLObject()); + INetURLObject aURLObject(rMed.GetURLObject());
+ OUString sExt = aURLObject.CutExtension(); + OUString sExt = aURLObject.CutExtension();
+ OUString sBaseName = aURLObject.GetLastName(); + OUString sBaseName = aURLObject.GetLastName();
+ aURLObject.CutLastName(); + aURLObject.CutLastName();
+
+ for (SCTAB i = 0, nCount = m_aDocument.GetTableCount(); i < nCount; ++i) - if (m_aDocument.GetTableCount() > 1)
- if (!rMed.GetError())
- rMed.SetError(SCWARN_EXPORT_ASCII);
+ for (SCTAB i = nStartTab; i < nCount; ++i)
+ { + {
+ OUString sTabName; + OUString sTabName;
+ if (!m_aDocument.GetName(i, sTabName)) + if (!m_aDocument.GetName(i, sTabName))
@ -230,20 +347,24 @@ index 91020db0b2e0..7cee6bb7f32e 100644
+ +
+ // log similar to DispatchWatcher::executeDispatchRequests + // log similar to DispatchWatcher::executeDispatchRequests
+ OUString aOutFile = aSheetURLObject.GetMainURL(INetURLObject::DecodeMechanism::NONE); + OUString aOutFile = aSheetURLObject.GetMainURL(INetURLObject::DecodeMechanism::NONE);
+ OUString aDisplayedName; + if (bVerbose)
+ if (osl::FileBase::E_None != osl::FileBase::getSystemPathFromFileURL(aOutFile, aDisplayedName)) + {
+ aDisplayedName = aOutFile; + OUString aDisplayedName;
+ std::cout << "Writing sheet " << OUStringToOString(sTabName, osl_getThreadTextEncoding()) << " -> " + if (osl::FileBase::E_None != osl::FileBase::getSystemPathFromFileURL(aOutFile, aDisplayedName))
+ << OUStringToOString(aDisplayedName, osl_getThreadTextEncoding()) + aDisplayedName = aOutFile;
+ << std::endl; + std::cout << "Writing sheet " << OUStringToOString(sTabName, osl_getThreadTextEncoding()) << " -> "
+ << OUStringToOString(aDisplayedName, osl_getThreadTextEncoding())
+ << std::endl;
+ +
+ if (FStatHelper::IsDocument(aOutFile)) + if (FStatHelper::IsDocument(aOutFile))
+ std::cout << "Overwriting: " << OUStringToOString(aDisplayedName, osl_getThreadTextEncoding()) << std::endl ; + std::cout << "Overwriting: " << OUStringToOString(aDisplayedName, osl_getThreadTextEncoding())
+ << std::endl ;
+ }
+ +
+ std::unique_ptr<SvStream> xStm = ::utl::UcbStreamHelper::CreateStream(aOutFile, StreamMode::TRUNC | StreamMode::WRITE); + std::unique_ptr<SvStream> xStm = ::utl::UcbStreamHelper::CreateStream(aOutFile, StreamMode::TRUNC | StreamMode::WRITE);
+ if (!xStm) + if (!xStm)
+ { + {
+ SetError(SCERR_IMPORT_UNKNOWN); + SetError(ERRCODE_IO_CANTCREATE);
+ bRet = false; + bRet = false;
+ break; + break;
+ } + }
@ -279,7 +400,7 @@ index 41c0b30a42a8..3aa5f6caf311 100644
void Execute( SfxRequest& rReq ); void Execute( SfxRequest& rReq );
void GetState( SfxItemSet &rSet ); void GetState( SfxItemSet &rSet );
diff --git a/sc/source/ui/inc/imoptdlg.hxx b/sc/source/ui/inc/imoptdlg.hxx diff --git a/sc/source/ui/inc/imoptdlg.hxx b/sc/source/ui/inc/imoptdlg.hxx
index bac941c2a377..2a4cba786b6e 100644 index bac941c2a377..382067d67813 100644
--- a/sc/source/ui/inc/imoptdlg.hxx --- a/sc/source/ui/inc/imoptdlg.hxx
+++ b/sc/source/ui/inc/imoptdlg.hxx +++ b/sc/source/ui/inc/imoptdlg.hxx
@@ -32,7 +32,8 @@ public: @@ -32,7 +32,8 @@ public:
@ -288,7 +409,7 @@ index bac941c2a377..2a4cba786b6e 100644
bFixedWidth(false), bSaveAsShown(false), bQuoteAllText(false), bFixedWidth(false), bSaveAsShown(false), bQuoteAllText(false),
- bSaveNumberAsSuch(true), bSaveFormulas(false), bRemoveSpace(false) - bSaveNumberAsSuch(true), bSaveFormulas(false), bRemoveSpace(false)
+ bSaveNumberAsSuch(true), bSaveFormulas(false), bRemoveSpace(false), + bSaveNumberAsSuch(true), bSaveFormulas(false), bRemoveSpace(false),
+ bNewFilePerSheet(false) + nSheetToExport(0)
{ SetTextEncoding( nEnc ); } { SetTextEncoding( nEnc ); }
ScImportOptions& operator=( const ScImportOptions& rCpy ) = default; ScImportOptions& operator=( const ScImportOptions& rCpy ) = default;
@ -296,9 +417,9 @@ index bac941c2a377..2a4cba786b6e 100644
bool bSaveNumberAsSuch; bool bSaveNumberAsSuch;
bool bSaveFormulas; bool bSaveFormulas;
bool bRemoveSpace; bool bRemoveSpace;
+ // currently only "0" for 'current sheet' and "-1" for all sheets (each to + // "0" for 'current sheet', "-1" for all sheets (each to a separate file),
+ // a separate file) are options + // or 1-based specific sheet number (to a separate file).
+ bool bNewFilePerSheet; + sal_Int32 nSheetToExport;
}; };
#endif // INCLUDED_SC_SOURCE_UI_INC_IMOPTDLG_HXX #endif // INCLUDED_SC_SOURCE_UI_INC_IMOPTDLG_HXX

Loading…
Cancel
Save