handle xlsx with too large sheets the same way as e.g. ods
The generic approach sets an error code on import and then
SfxBaseModel::handleLoadError() takes care of it. This also
allows checking for the warning in unittests. A drawback is
that this generic approach can handle only one error code,
so if a sheets has too many rows and column, there will be
only one warning, but I consider that to be minor.
Change-Id: I1d5f7f9162ef63c3c2e8414823d18a1ff50ad71e
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/131970
Tested-by: Jenkins
Reviewed-by: Luboš Luňák <l.lunak@collabora.com>
diff --git a/sc/qa/unit/data/xlsx/too-many-cols-rows.xlsx b/sc/qa/unit/data/xlsx/too-many-cols-rows.xlsx
new file mode 100644
index 0000000..45ef9a1
--- /dev/null
+++ b/sc/qa/unit/data/xlsx/too-many-cols-rows.xlsx
Binary files differ
diff --git a/sc/qa/unit/subsequent_filters_test2.cxx b/sc/qa/unit/subsequent_filters_test2.cxx
index d54267d..a5173ed 100644
--- a/sc/qa/unit/subsequent_filters_test2.cxx
+++ b/sc/qa/unit/subsequent_filters_test2.cxx
@@ -3086,6 +3086,12 @@ void ScFiltersTest2::testTooManyColsRows()
CPPUNIT_ASSERT(xDocSh->GetErrorCode() == SCWARN_IMPORT_ROW_OVERFLOW
|| xDocSh->GetErrorCode() == SCWARN_IMPORT_COLUMN_OVERFLOW);
xDocSh->DoClose();
xDocSh = loadDoc(u"too-many-cols-rows.", FORMAT_XLSX);
CPPUNIT_ASSERT(xDocSh.is());
CPPUNIT_ASSERT(xDocSh->GetErrorCode() == SCWARN_IMPORT_ROW_OVERFLOW
|| xDocSh->GetErrorCode() == SCWARN_IMPORT_COLUMN_OVERFLOW);
xDocSh->DoClose();
}
CPPUNIT_TEST_SUITE_REGISTRATION(ScFiltersTest2);
diff --git a/sc/source/filter/oox/excelfilter.cxx b/sc/source/filter/oox/excelfilter.cxx
index e581520..e73e020 100644
--- a/sc/source/filter/oox/excelfilter.cxx
+++ b/sc/source/filter/oox/excelfilter.cxx
@@ -33,11 +33,6 @@
#include <document.hxx>
#include <docsh.hxx>
#include <scerrors.hxx>
#include <vcl/svapp.hxx>
#include <vcl/weld.hxx>
#include <svtools/sfxecode.hxx>
#include <svtools/ehdl.hxx>
#include <tools/urlobj.hxx>
#include <tools/diagnose_ex.h>
namespace oox::xls {
@@ -108,66 +103,23 @@ bool ExcelFilter::importDocument()
WorkbookGlobalsRef xBookGlob(WorkbookHelper::constructGlobals(*this));
if (xBookGlob)
{
rtl::Reference<FragmentHandler> xWorkbookFragment( new WorkbookFragment(*xBookGlob, aWorkbookPath));
rtl::Reference<WorkbookFragment> xWorkbookFragment( new WorkbookFragment(*xBookGlob, aWorkbookPath));
const WorkbookFragment* pWF = static_cast<const WorkbookFragment*>(xWorkbookFragment.get());
const ScDocument& rDoc = pWF->getScDocument();
if (ScDocShell* pDocSh = static_cast<ScDocShell*>(rDoc.GetDocumentShell()))
pDocSh->SetInitialLinkUpdate( pDocSh->GetMedium());
ScDocument& rDoc = xWorkbookFragment->getScDocument();
ScDocShell* pDocSh = static_cast<ScDocShell*>(rDoc.GetDocumentShell());
assert( pDocSh );
pDocSh->SetInitialLinkUpdate( pDocSh->GetMedium());
bool bRet = importFragment( xWorkbookFragment);
if (bRet)
if (bRet && !pDocSh->GetErrorCode())
{
const AddressConverter& rAC = pWF->getAddressConverter();
if (rAC.isTabOverflow() || rAC.isColOverflow() || rAC.isRowOverflow())
{
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, RID_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? */
std::unique_ptr<weld::MessageDialog> xWarn(Application::CreateMessageDialog(ScDocShell::GetActiveDialogParent(),
VclMessageType::Warning, VclButtonsType::Ok,
aWarning));
xWarn->run();
}
}
const AddressConverter& rAC = xWorkbookFragment->getAddressConverter();
if (rAC.isTabOverflow())
pDocSh->SetError(SCWARN_IMPORT_SHEET_OVERFLOW);
else if (rAC.isColOverflow())
pDocSh->SetError(SCWARN_IMPORT_COLUMN_OVERFLOW);
else if (rAC.isRowOverflow())
pDocSh->SetError(SCWARN_IMPORT_ROW_OVERFLOW);
}
return bRet;
}