From bc1c0f97e2bd68d3f0a5bedafd9db79b42269cf6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= Date: Sun, 25 Jul 2021 14:56:10 +0100 Subject: [PATCH] Related: rhbz#1980800 add in improvements --- ...ow-convert-to-csv-to-write-each-shee.patch | 245 +++++++++++++----- 1 file changed, 183 insertions(+), 62 deletions(-) diff --git a/0001-rhbz-1980800-allow-convert-to-csv-to-write-each-shee.patch b/0001-rhbz-1980800-allow-convert-to-csv-to-write-each-shee.patch index 67ff1f9..b1224ac 100644 --- a/0001-rhbz-1980800-allow-convert-to-csv-to-write-each-shee.patch +++ b/0001-rhbz-1980800-allow-convert-to-csv-to-write-each-shee.patch @@ -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?= Date: Tue, 13 Jul 2021 12:38:07 +0100 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 Reviewed-by: Eike Rathke (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 +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 +Tested-by: Jenkins +(cherry picked from commit 0cda081c9aa3b3dcb363f97bac60c845ce9a13e0) --- - desktop/source/app/dispatchwatcher.cxx | 26 +++++-- - sc/source/ui/dbgui/imoptdlg.cxx | 7 +- - sc/source/ui/docshell/docsh.cxx | 97 +++++++++++++++++++------- - sc/source/ui/inc/docsh.hxx | 2 +- - sc/source/ui/inc/imoptdlg.hxx | 6 +- - 5 files changed, 106 insertions(+), 32 deletions(-) + desktop/source/app/dispatchwatcher.cxx | 50 +++++++-- + sc/source/ui/dbgui/imoptdlg.cxx | 16 ++- + sc/source/ui/docshell/docsh.cxx | 141 +++++++++++++++++++++---- + sc/source/ui/inc/docsh.hxx | 2 +- + sc/source/ui/inc/imoptdlg.hxx | 6 +- + 5 files changed, 179 insertions(+), 36 deletions(-) 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 +++ b/desktop/source/app/dispatchwatcher.cxx @@ -30,6 +30,7 @@ @@ -51,8 +73,25 @@ index 50b92ecb7834..0660ccf3f83e 100644 if (aFilter.isEmpty()) { std::cerr << "Error: no export filter" << std::endl; -@@ -616,10 +619,23 @@ bool DispatchWatcher::executeDispatchRequests( const std::vector 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 ) { - conversionProperties[1].Value <<= aFilter.copy(0, nFilterOptionsIndex); @@ -62,22 +101,42 @@ index 50b92ecb7834..0660ccf3f83e 100644 + if (sFilterName == "Text - txt - csv (StarCalc)") + { + 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 + // output filename concatenated with the sheet name, so adjust + // 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 <<= sFilterOptions; ++ conversionProperties[3].Name = "FilterOptions"; ++ conversionProperties[3].Value <<= sFilterOptions; } else { -@@ -639,9 +655,11 @@ bool DispatchWatcher::executeDispatchRequests( const std::vector + #include + #include ++#include + #include + #include + +@@ -43,6 +44,7 @@ ScImportOptions::ScImportOptions( const OUString& rStr ) bSaveNumberAsSuch = true; bSaveFormulas = false; bRemoveSpace = false; -+ bNewFilePerSheet = false; ++ nSheetToExport = 0; sal_Int32 nTokenCount = comphelper::string::getTokenCount(rStr, ','); if ( nTokenCount < 3 ) 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"; if ( nTokenCount >= 11 ) bRemoveSpace = rStr.getToken(0, ',', nIdx) == "true"; + 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( 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; } 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 +++ b/sc/source/ui/docshell/docsh.cxx @@ -44,6 +44,7 @@ @@ -160,7 +235,7 @@ index 91020db0b2e0..7cee6bb7f32e 100644 SCCOL nEndCol; SCROW 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) { @@ -177,47 +252,89 @@ index 91020db0b2e0..7cee6bb7f32e 100644 - const SfxPoolItem* pItem; - if ( pSet && SfxItemState::SET == - pSet->GetItemState( SID_FILE_FILTEROPTIONS, true, &pItem ) ) -- { -- sItStr = static_cast(pItem)->GetValue(); -- } + sItStr = static_cast(pItem)->GetValue(); + } - -- if ( sItStr.isEmpty() ) -- { -- // default for ascii export (from API without options): -- // ISO8859-1/MS_1252 encoding, comma, double quotes ++ + if ( sItStr.isEmpty() ) + { + // 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(); -- } ++ + ScImportOptions aDefOptions( ',', '"', RTL_TEXTENCODING_MS_1252 ); + sItStr = aDefOptions.BuildString(); + } - -- weld::WaitObject aWait( GetActiveDialogParent() ); -- ScImportOptions aOptions( sItStr ); -- AsciiSave( *pStream, aOptions ); ++ + weld::WaitObject aWait( GetActiveDialogParent() ); + 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 & 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(pItem)->GetValue(); ++ OUString aOrigin; ++ pProp->Value >>= aOrigin; ++ bVerbose = (aOrigin == "CommandLine"); + } -- if (m_aDocument.GetTableCount() > 1) -- if (!rMed.GetError()) -- rMed.SetError(SCWARN_EXPORT_ASCII); +- if ( sItStr.isEmpty() ) ++ SCTAB nStartTab; ++ 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()); + OUString sExt = aURLObject.CutExtension(); + OUString sBaseName = aURLObject.GetLastName(); + 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; + if (!m_aDocument.GetName(i, sTabName)) @@ -230,20 +347,24 @@ index 91020db0b2e0..7cee6bb7f32e 100644 + + // log similar to DispatchWatcher::executeDispatchRequests + OUString aOutFile = aSheetURLObject.GetMainURL(INetURLObject::DecodeMechanism::NONE); -+ OUString aDisplayedName; -+ if (osl::FileBase::E_None != osl::FileBase::getSystemPathFromFileURL(aOutFile, aDisplayedName)) -+ aDisplayedName = aOutFile; -+ std::cout << "Writing sheet " << OUStringToOString(sTabName, osl_getThreadTextEncoding()) << " -> " -+ << OUStringToOString(aDisplayedName, osl_getThreadTextEncoding()) -+ << std::endl; ++ if (bVerbose) ++ { ++ OUString aDisplayedName; ++ if (osl::FileBase::E_None != osl::FileBase::getSystemPathFromFileURL(aOutFile, aDisplayedName)) ++ aDisplayedName = aOutFile; ++ std::cout << "Writing sheet " << OUStringToOString(sTabName, osl_getThreadTextEncoding()) << " -> " ++ << OUStringToOString(aDisplayedName, osl_getThreadTextEncoding()) ++ << std::endl; + -+ if (FStatHelper::IsDocument(aOutFile)) -+ std::cout << "Overwriting: " << OUStringToOString(aDisplayedName, osl_getThreadTextEncoding()) << std::endl ; ++ if (FStatHelper::IsDocument(aOutFile)) ++ std::cout << "Overwriting: " << OUStringToOString(aDisplayedName, osl_getThreadTextEncoding()) ++ << std::endl ; ++ } + + std::unique_ptr xStm = ::utl::UcbStreamHelper::CreateStream(aOutFile, StreamMode::TRUNC | StreamMode::WRITE); + if (!xStm) + { -+ SetError(SCERR_IMPORT_UNKNOWN); ++ SetError(ERRCODE_IO_CANTCREATE); + bRet = false; + break; + } @@ -279,7 +400,7 @@ index 41c0b30a42a8..3aa5f6caf311 100644 void Execute( SfxRequest& rReq ); void GetState( SfxItemSet &rSet ); 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 +++ b/sc/source/ui/inc/imoptdlg.hxx @@ -32,7 +32,8 @@ public: @@ -288,7 +409,7 @@ index bac941c2a377..2a4cba786b6e 100644 bFixedWidth(false), bSaveAsShown(false), bQuoteAllText(false), - bSaveNumberAsSuch(true), bSaveFormulas(false), bRemoveSpace(false) + bSaveNumberAsSuch(true), bSaveFormulas(false), bRemoveSpace(false), -+ bNewFilePerSheet(false) ++ nSheetToExport(0) { SetTextEncoding( nEnc ); } ScImportOptions& operator=( const ScImportOptions& rCpy ) = default; @@ -296,9 +417,9 @@ index bac941c2a377..2a4cba786b6e 100644 bool bSaveNumberAsSuch; bool bSaveFormulas; bool bRemoveSpace; -+ // currently only "0" for 'current sheet' and "-1" for all sheets (each to -+ // a separate file) are options -+ bool bNewFilePerSheet; ++ // "0" for 'current sheet', "-1" for all sheets (each to a separate file), ++ // or 1-based specific sheet number (to a separate file). ++ sal_Int32 nSheetToExport; }; #endif // INCLUDED_SC_SOURCE_UI_INC_IMOPTDLG_HXX