[Libreoffice-commits] core.git: Branch 'libreoffice-6-0' - sc/source

Eike Rathke erack at redhat.com
Thu Mar 15 23:41:23 UTC 2018


 sc/source/filter/inc/addressconverter.hxx |    4 +
 sc/source/filter/oox/excelfilter.cxx      |   69 +++++++++++++++++++++++++++++-
 sc/source/filter/oox/sheetdatacontext.cxx |   21 +++++++--
 sc/source/filter/oox/worksheethelper.cxx  |   10 +++-
 4 files changed, 96 insertions(+), 8 deletions(-)

New commits:
commit 621634923ab7c11ceef9757c481f92977ef863f6
Author: Eike Rathke <erack at redhat.com>
Date:   Wed Feb 28 22:39:30 2018 +0100

    Resolves: tdf#114555 check .xlsx col/row/tab overflow and display warning
    
     This is a combination of 2 commits.
    
    Resolves: tdf#114555 check .xlsx col/row/tab overflow and display warning
    
    Cherry-picked from 66564dac88ffcc781b4fade7ca0f4f72af6b8bca and
    backported / un-weld-ed by using the original patch set
    https://gerrit.libreoffice.org/#/c/50541/1 before weld-ing, and
    getRID_ERRCTX() instead of RID_ERRCTX.
    
    Related: tdf#114555 cater for lastcolumn+1 oddity if last is last possible
    
    Else our own saved .xlsx files raise the excess columns warning.
    
    (cherry picked from commit ccc977ba10b61108a56e00a79c0f7a1517e026cc)
    
    e1791dd026d9faf4b391ad34da43ec0c70c8de83
    
    Change-Id: I3091a890b6d4a3f27d9284fc5c0e2df3bc8ce527
    Reviewed-on: https://gerrit.libreoffice.org/50570
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Bartosz Kosiorek <gang65 at poczta.onet.pl>

diff --git a/sc/source/filter/inc/addressconverter.hxx b/sc/source/filter/inc/addressconverter.hxx
index 57f1f33cabcd..d1d53531e0f1 100644
--- a/sc/source/filter/inc/addressconverter.hxx
+++ b/sc/source/filter/inc/addressconverter.hxx
@@ -479,6 +479,10 @@ public:
     static css::uno::Sequence<css::table::CellRangeAddress>
                         toApiSequence(const ScRangeList& orRanges);
 
+    bool                isColOverflow() const { return mbColOverflow; }
+    bool                isRowOverflow() const { return mbRowOverflow; }
+    bool                isTabOverflow() const { return mbTabOverflow; }
+
 private:
     void                initializeMaxPos(
                             sal_Int16 nMaxXlsTab, sal_Int32 nMaxXlsCol, sal_Int32 nMaxXlsRow );
diff --git a/sc/source/filter/oox/excelfilter.cxx b/sc/source/filter/oox/excelfilter.cxx
index 171f5ff67cf7..55cee4841b7f 100644
--- a/sc/source/filter/oox/excelfilter.cxx
+++ b/sc/source/filter/oox/excelfilter.cxx
@@ -30,6 +30,15 @@
 #include <workbookfragment.hxx>
 #include <xestream.hxx>
 
+#include <addressconverter.hxx>
+#include <document.hxx>
+#include <docsh.hxx>
+#include <scerrors.hxx>
+#include <vcl/msgbox.hxx>
+#include <vcl/vclptr.hxx>
+#include <svtools/sfxecode.hxx>
+#include <tools/urlobj.hxx>
+
 namespace oox {
 namespace xls {
 
@@ -97,9 +106,65 @@ bool ExcelFilter::importDocument()
             the class WorkbookHelper, and execute the import filter by constructing
             an instance of WorkbookFragment and loading the file. */
         WorkbookGlobalsRef xBookGlob(WorkbookHelper::constructGlobals(*this));
-        if (xBookGlob.get() && importFragment(new WorkbookFragment(*xBookGlob, aWorkbookPath)))
+        if (xBookGlob.get())
         {
-            return true;
+            rtl::Reference<FragmentHandler> xWorkbookFragment( new WorkbookFragment(*xBookGlob, aWorkbookPath));
+            bool bRet = importFragment( xWorkbookFragment);
+            if (bRet)
+            {
+                const WorkbookFragment* pWF = static_cast<const WorkbookFragment*>(xWorkbookFragment.get());
+                const AddressConverter& rAC = pWF->getAddressConverter();
+                if (rAC.isTabOverflow() || rAC.isColOverflow() || rAC.isRowOverflow())
+                {
+                    const ScDocument& rDoc = pWF->getScDocument();
+                    if (rDoc.IsUserInteractionEnabled())
+                    {
+                        // Show data loss warning.
+
+                        INetURLObject aURL( getFileUrl());
+                        SfxErrorContext aContext( ERRCTX_SFX_OPENDOC,
+                                aURL.getName( INetURLObject::LAST_SEGMENT, true,
+                                    INetURLObject::DecodeMechanism::WithCharset),
+                                nullptr, getRID_ERRCTX());
+
+                        OUString aWarning;
+                        aContext.GetString( ERRCODE_NONE.MakeWarning(), aWarning);
+                        aWarning += ":\n";
+
+                        OUString aMsg;
+                        if (rAC.isTabOverflow())
+                        {
+                            if (ErrorHandler::GetErrorString( SCWARN_IMPORT_SHEET_OVERFLOW, aMsg))
+                                aWarning += aMsg;
+                        }
+                        if (rAC.isColOverflow())
+                        {
+                            if (!aMsg.isEmpty())
+                                aWarning += "\n";
+                            if (ErrorHandler::GetErrorString( SCWARN_IMPORT_COLUMN_OVERFLOW, aMsg))
+                                aWarning += aMsg;
+                        }
+                        if (rAC.isRowOverflow())
+                        {
+                            if (!aMsg.isEmpty())
+                                aWarning += "\n";
+                            if (ErrorHandler::GetErrorString( SCWARN_IMPORT_ROW_OVERFLOW, aMsg))
+                                aWarning += aMsg;
+                        }
+
+                        /* XXX displaying a dialog here is ugly and should
+                         * rather happen at UI level instead of at the filter
+                         * level, but it seems there's no way to transport
+                         * detailed information other than returning true or
+                         * false at this point? */
+
+                        ScopedVclPtrInstance<WarningBox> pBox( ScDocShell::GetActiveDialogParent(),
+                                MessBoxStyle::Ok | MessBoxStyle::DefaultOk, aWarning);
+                        pBox->Execute();
+                    }
+                }
+            }
+            return bRet;
         }
     }
     catch (...)
diff --git a/sc/source/filter/oox/sheetdatacontext.cxx b/sc/source/filter/oox/sheetdatacontext.cxx
index b221cb16a73b..5f17d8c419b6 100644
--- a/sc/source/filter/oox/sheetdatacontext.cxx
+++ b/sc/source/filter/oox/sheetdatacontext.cxx
@@ -273,6 +273,7 @@ void SheetDataContext::importRow( const AttributeList& rAttribs )
     }
     else
         aModel.mnRow = ++mnRow;
+    mrAddressConv.checkRow( mnRow, true);
     mnCol = -1;
 
     aModel.mfHeight       = rAttribs.getDouble( XML_ht, -1.0 );
@@ -297,8 +298,14 @@ void SheetDataContext::importRow( const AttributeList& rAttribs )
         if( (0 < nSepPos) && (nSepPos + 1 < aColSpanToken.getLength()) )
         {
             // OOXML uses 1-based integer column indexes, row model expects 0-based colspans
-            sal_Int32 nLastCol = ::std::min( aColSpanToken.copy( nSepPos + 1 ).toInt32() - 1, nMaxCol );
-            aModel.insertColSpan( ValueRange( aColSpanToken.copy( 0, nSepPos ).toInt32() - 1, nLastCol ) );
+            const sal_Int32 nCol1 = aColSpanToken.copy( 0, nSepPos ).toInt32() - 1;
+            const bool bValid1 = mrAddressConv.checkCol( nCol1, true);
+            if (bValid1)
+            {
+                const sal_Int32 nCol2 = aColSpanToken.copy( nSepPos + 1 ).toInt32() - 1;
+                mrAddressConv.checkCol( nCol2, true);
+                aModel.insertColSpan( ValueRange( nCol1, ::std::min( nCol2, nMaxCol )));
+            }
         }
     }
 
@@ -314,7 +321,9 @@ bool SheetDataContext::importCell( const AttributeList& rAttribs )
     if (!p)
     {
         ++mnCol;
-        maCellData.maCellAddr = ScAddress( mnCol, mnRow, mnSheet );
+        ScAddress aAddress( mnCol, mnRow, mnSheet );
+        bValid = mrAddressConv.checkCellAddress( aAddress, true );
+        maCellData.maCellAddr = aAddress;
     }
     else
     {
@@ -374,6 +383,7 @@ void SheetDataContext::importRow( SequenceInputStream& rStrm )
     nSpanCount = rStrm.readInt32();
     maCurrPos.mnCol = 0;
 
+    mrAddressConv.checkRow( maCurrPos.mnRow, true);
     // row index is 0-based in BIFF12, but RowModel expects 1-based
     aModel.mnRow          = maCurrPos.mnRow + 1;
     // row height is in twips in BIFF12, convert to points
@@ -393,8 +403,11 @@ void SheetDataContext::importRow( SequenceInputStream& rStrm )
     {
         sal_Int32 nFirstCol, nLastCol;
         nFirstCol = rStrm.readInt32();
+        const bool bValid1 = mrAddressConv.checkCol( nFirstCol, true);
         nLastCol = rStrm.readInt32();
-        aModel.insertColSpan( ValueRange( nFirstCol, ::std::min( nLastCol, nMaxCol ) ) );
+        mrAddressConv.checkCol( nLastCol, true);
+        if (bValid1)
+            aModel.insertColSpan( ValueRange( nFirstCol, ::std::min( nLastCol, nMaxCol ) ) );
     }
 
     // set row properties in the current sheet
diff --git a/sc/source/filter/oox/worksheethelper.cxx b/sc/source/filter/oox/worksheethelper.cxx
index 2ef765d932b5..c1cdae73e4b1 100644
--- a/sc/source/filter/oox/worksheethelper.cxx
+++ b/sc/source/filter/oox/worksheethelper.cxx
@@ -763,8 +763,14 @@ void WorksheetGlobals::setColumnModel( const ColumnModel& rModel )
     sal_Int32 nLastCol = rModel.maRange.mnLast - 1;
     if( getAddressConverter().checkCol( nFirstCol, true ) && (nFirstCol <= nLastCol) )
     {
-        // validate last column index
-        if( !getAddressConverter().checkCol( nLastCol, true ) )
+        // Validate last column index.
+        // If last column is equal to last possible column, Excel adds one
+        // more. We do that also in XclExpColinfo::SaveXml() and for 1024 end
+        // up with 1025 instead, which would lead to excess columns in
+        // checkCol(). Cater for this oddity.
+        if (nLastCol == mrMaxApiPos.Col() + 1)
+            --nLastCol;
+        else if( !getAddressConverter().checkCol( nLastCol, true ) )
             nLastCol = mrMaxApiPos.Col();
         // try to find entry in column model map that is able to merge with the passed model
         bool bInsertModel = true;


More information about the Libreoffice-commits mailing list