[Libreoffice-commits] core.git: desktop/source sc/source

Caolán McNamara (via logerrit) logerrit at kemper.freedesktop.org
Wed Jul 14 18:38:08 UTC 2021


 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(-)

New commits:
commit b8903bc106dad036acb3d117e5c4fc955697fe02
Author:     Caolán McNamara <caolanm at redhat.com>
AuthorDate: Tue Jul 13 12:38:07 2021 +0100
Commit:     Eike Rathke <erack at redhat.com>
CommitDate: Wed Jul 14 20:37:33 2021 +0200

    rhbz#1980800 allow --convert-to csv to write each sheet to a separate file
    
    Related: tdf#135762 except only currently implemented for command line use
    
    sample usage:
    soffice --convert-to csv:"Text - txt - csv (StarCalc)":44,34,UTF8,1,,0,false,true,false,false,false,-1 sample.ods
    where the new (11th!) final token ("-1") enables writing each sheet to a
    new file based on the suggested target name so output in this example
    is files sample-Sheet1.csv and sample-Sheet2.csv
    
    Only -1 for 'all sheets' vs 0 for existing 'current sheet only' (which
    is always sheet 0 from the command line) are currently options but the
    token could be expanded in the future to select specific sheets to
    export.
    
    Change-Id: Ib99a120f1a2c8d1008a7a3c59a6b39f572fb346e
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/118850
    Tested-by: Jenkins
    Reviewed-by: Eike Rathke <erack at redhat.com>

diff --git a/desktop/source/app/dispatchwatcher.cxx b/desktop/source/app/dispatchwatcher.cxx
index a2e79d8283ae..8541c273cc83 100644
--- a/desktop/source/app/dispatchwatcher.cxx
+++ b/desktop/source/app/dispatchwatcher.cxx
@@ -30,6 +30,7 @@
 #include "officeipcthread.hxx"
 #include <rtl/ustring.hxx>
 #include <comphelper/processfactory.hxx>
+#include <comphelper/string.hxx>
 #include <comphelper/synchronousdispatch.hxx>
 #include <com/sun/star/io/IOException.hpp>
 #include <com/sun/star/util/XCloseable.hpp>
@@ -598,6 +599,8 @@ bool DispatchWatcher::executeDispatchRequests( const std::vector<DispatchRequest
                                 aFilter = impl_GuessFilter( aOutFile, aDocService );
                             }
 
+                            bool bMultiFileTarget = false;
+
                             if (aFilter.isEmpty())
                             {
                                 std::cerr << "Error: no export filter" << std::endl;
@@ -616,10 +619,23 @@ bool DispatchWatcher::executeDispatchRequests( const std::vector<DispatchRequest
                                 conversionProperties[1].Name = "FilterName";
                                 if( 0 < nFilterOptionsIndex )
                                 {
-                                    conversionProperties[1].Value <<= aFilter.copy(0, nFilterOptionsIndex);
+                                    OUString sFilterName = aFilter.copy(0, nFilterOptionsIndex);
+                                    OUString sFilterOptions = aFilter.copy(nFilterOptionsIndex + 1);
+
+                                    if (sFilterName == "Text - txt - csv (StarCalc)")
+                                    {
+                                        sal_Int32 nIdx(0);
+                                        // If the 11th token 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";
+                                    }
+
+                                    conversionProperties[1].Value <<= sFilterName;
 
                                     conversionProperties[2].Name = "FilterOptions";
-                                    conversionProperties[2].Value <<= aFilter.copy(nFilterOptionsIndex + 1);
+                                    conversionProperties[2].Value <<= sFilterOptions;
                                 }
                                 else
                                 {
@@ -639,9 +655,11 @@ bool DispatchWatcher::executeDispatchRequests( const std::vector<DispatchRequest
                                 OString aTargetURL8 = OUStringToOString(aTempName, osl_getThreadTextEncoding());
                                 if (aDispatchRequest.aRequestType != REQUEST_CAT)
                                 {
-                                    std::cout << "convert " << aSource8 << " -> " << aTargetURL8;
+                                    std::cout << "convert " << aSource8;
+                                    if (!bMultiFileTarget)
+                                        std::cout << " -> " << aTargetURL8;
                                     std::cout << " using filter : " << OUStringToOString(aFilter, osl_getThreadTextEncoding()) << std::endl;
-                                    if (FStatHelper::IsDocument(aOutFile))
+                                    if (!bMultiFileTarget && FStatHelper::IsDocument(aOutFile))
                                         std::cout << "Overwriting: " << OUStringToOString(aTempName, osl_getThreadTextEncoding()) << std::endl ;
                                 }
                                 try
diff --git a/sc/source/ui/dbgui/imoptdlg.cxx b/sc/source/ui/dbgui/imoptdlg.cxx
index 071f1b0257bc..d8c4fd810ea3 100644
--- a/sc/source/ui/dbgui/imoptdlg.cxx
+++ b/sc/source/ui/dbgui/imoptdlg.cxx
@@ -43,6 +43,7 @@ ScImportOptions::ScImportOptions( const OUString& rStr )
     bSaveNumberAsSuch = true;
     bSaveFormulas = false;
     bRemoveSpace = false;
+    bNewFilePerSheet = false;
     sal_Int32 nTokenCount = comphelper::string::getTokenCount(rStr, ',');
     if ( nTokenCount < 3 )
         return;
@@ -77,6 +78,8 @@ 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";
     }
 }
 
@@ -99,7 +102,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
 
     return aResult;
 }
diff --git a/sc/source/ui/docshell/docsh.cxx b/sc/source/ui/docshell/docsh.cxx
index 055f2fdf727a..873e5c598bab 100644
--- a/sc/source/ui/docshell/docsh.cxx
+++ b/sc/source/ui/docshell/docsh.cxx
@@ -44,6 +44,7 @@
 #include <sfx2/objface.hxx>
 #include <sfx2/viewfrm.hxx>
 #include <svl/documentlockfile.hxx>
+#include <svl/fstathelper.hxx>
 #include <svl/sharecontrolfile.hxx>
 #include <svl/urihelper.hxx>
 #include <osl/file.hxx>
@@ -120,6 +121,7 @@
 #include <comphelper/processfactory.hxx>
 #include <comphelper/string.hxx>
 #include <unotools/configmgr.hxx>
+#include <unotools/ucbstreamhelper.hxx>
 #include <uiitems.hxx>
 #include <dpobject.hxx>
 #include <markdata.hxx>
@@ -1926,7 +1928,7 @@ void escapeTextSep(sal_Int32 nPos, const StrT& rStrDelim, StrT& rStr)
 
 }
 
-void ScDocShell::AsciiSave( SvStream& rStream, const ScImportOptions& rAsciiOpt )
+void ScDocShell::AsciiSave( SvStream& rStream, const ScImportOptions& rAsciiOpt, SCTAB nTab )
 {
     sal_Unicode cDelim    = rAsciiOpt.nFieldSepCode;
     sal_Unicode cStrDelim = rAsciiOpt.nTextSepCode;
@@ -1972,7 +1974,6 @@ void ScDocShell::AsciiSave( SvStream& rStream, const ScImportOptions& rAsciiOpt
 
     SCCOL nStartCol = 0;
     SCROW nStartRow = 0;
-    SCTAB nTab = GetSaveTab();
     SCCOL nEndCol;
     SCROW nEndRow;
     m_aDocument.GetCellArea( nTab, nEndCol, nEndRow );
@@ -2390,35 +2391,81 @@ bool ScDocShell::ConvertTo( SfxMedium &rMed )
     }
     else if (aFltName == pFilterAscii)
     {
-        SvStream* pStream = rMed.GetOutStream();
-        if (pStream)
+        OUString sItStr;
+        SfxItemSet*  pSet = rMed.GetItemSet();
+        const SfxPoolItem* pItem;
+        if ( pSet && SfxItemState::SET ==
+             pSet->GetItemState( SID_FILE_FILTEROPTIONS, true, &pItem ) )
         {
-            OUString sItStr;
-            SfxItemSet*  pSet = rMed.GetItemSet();
-            const SfxPoolItem* pItem;
-            if ( pSet && SfxItemState::SET ==
-                 pSet->GetItemState( SID_FILE_FILTEROPTIONS, true, &pItem ) )
-            {
-                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() )
+        {
+            //  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)
+        {
             bRet = true;
 
-            if (m_aDocument.GetTableCount() > 1)
-                if (!rMed.GetError())
-                    rMed.SetError(SCWARN_EXPORT_ASCII);
+            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)
+            {
+                OUString sTabName;
+                if (!m_aDocument.GetName(i, sTabName))
+                    sTabName = OUString::number(i);
+                INetURLObject aSheetURLObject(aURLObject);
+                OUString sFileName = sBaseName + "-" + sTabName;
+                if (!sExt.isEmpty())
+                    sFileName = sFileName + "." + sExt;
+                aSheetURLObject.Append(sFileName);
+
+                // 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 (FStatHelper::IsDocument(aOutFile))
+                    std::cout << "Overwriting: " << OUStringToOString(aDisplayedName, osl_getThreadTextEncoding()) << std::endl ;
+
+                std::unique_ptr<SvStream> xStm = ::utl::UcbStreamHelper::CreateStream(aOutFile, StreamMode::TRUNC | StreamMode::WRITE);
+                if (!xStm)
+                {
+                    SetError(SCERR_IMPORT_UNKNOWN);
+                    bRet = false;
+                    break;
+                }
+                AsciiSave(*xStm, aOptions, i);
+            }
+        }
+        else
+        {
+            SvStream* pStream = rMed.GetOutStream();
+            if (pStream)
+            {
+                AsciiSave(*pStream, aOptions, GetSaveTab());
+                bRet = true;
+
+                if (m_aDocument.GetTableCount() > 1)
+                    if (!rMed.GetError())
+                        rMed.SetError(SCWARN_EXPORT_ASCII);
+            }
         }
     }
     else if (aFltName == pFilterDBase)
diff --git a/sc/source/ui/inc/docsh.hxx b/sc/source/ui/inc/docsh.hxx
index 3a6366699b52..eb6203362110 100644
--- a/sc/source/ui/inc/docsh.hxx
+++ b/sc/source/ui/inc/docsh.hxx
@@ -227,7 +227,7 @@ public:
 
     ScDrawLayer*    MakeDrawLayer();
 
-    void            AsciiSave( SvStream& rStream, const ScImportOptions& rOpt );
+    void            AsciiSave( SvStream& rStream, const ScImportOptions& rOpt, SCTAB nTab );
 
     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 c162da6d7740..2314349f602a 100644
--- a/sc/source/ui/inc/imoptdlg.hxx
+++ b/sc/source/ui/inc/imoptdlg.hxx
@@ -31,7 +31,8 @@ public:
         ScImportOptions( sal_Unicode nFieldSep, sal_Unicode nTextSep, rtl_TextEncoding nEnc )
             : nFieldSepCode(nFieldSep), nTextSepCode(nTextSep),
             bFixedWidth(false), bSaveAsShown(false), bQuoteAllText(false),
-            bSaveNumberAsSuch(true), bSaveFormulas(false), bRemoveSpace(false)
+            bSaveNumberAsSuch(true), bSaveFormulas(false), bRemoveSpace(false),
+            bNewFilePerSheet(false)
         { SetTextEncoding( nEnc ); }
 
     ScImportOptions& operator=( const ScImportOptions& rCpy ) = default;
@@ -50,6 +51,9 @@ public:
     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;
 };
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */


More information about the Libreoffice-commits mailing list