diff options
Diffstat (limited to 'sc')
29 files changed, 200 insertions, 43 deletions
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx index dff46dffd699..a5b9c8fbe781 100644 --- a/sc/inc/document.hxx +++ b/sc/inc/document.hxx @@ -541,6 +541,8 @@ private: bool mbTrackFormulasPending : 1; bool mbFinalTrackFormulas : 1; + // This indicates if a ScOutputData::LayoutStrings() is in progress. + bool mbLayoutStrings : 1; size_t mnMutationGuardFlags; @@ -2429,6 +2431,9 @@ public: SC_DLLPUBLIC ScColumnsRange GetColumnsRange(SCTAB nTab, SCCOL nColBegin, SCCOL nColEnd) const; + bool IsInLayoutStrings() const { return mbLayoutStrings; } + void SetLayoutStrings(bool bSet) { mbLayoutStrings = bSet; } + private: /** diff --git a/sc/inc/documentimport.hxx b/sc/inc/documentimport.hxx index 1a8b1cbd514f..7e5be71c8339 100644 --- a/sc/inc/documentimport.hxx +++ b/sc/inc/documentimport.hxx @@ -123,6 +123,8 @@ public: void setMergedCells(SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2); + void invalidateBlockPositionSet(SCTAB nTab); + void finalize(); /** Broadcast all formula cells that are marked with diff --git a/sc/inc/mtvelements.hxx b/sc/inc/mtvelements.hxx index f13562d47fbd..e441e0473558 100644 --- a/sc/inc/mtvelements.hxx +++ b/sc/inc/mtvelements.hxx @@ -169,6 +169,7 @@ public: ~TableColumnBlockPositionSet(); ColumnBlockPosition* getBlockPosition( SCCOL nCol ); + void invalidate(); // discards cached positions }; ScRefCellValue toRefCell( const sc::CellStoreType::const_iterator& itPos, size_t nOffset ); diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx index dae1f6f36eaf..e4a9d79ff86c 100644 --- a/sc/inc/table.hxx +++ b/sc/inc/table.hxx @@ -464,6 +464,8 @@ public: void GetLastDataPos(SCCOL& rCol, SCROW& rRow) const; ScPostIt* ReleaseNote( SCCOL nCol, SCROW nRow ); + ScPostIt* GetNote( SCCOL nCol, SCROW nRow ); + void SetNote( SCCOL nCol, SCROW nRow, ScPostIt* pNote ); size_t GetNoteCount( SCCOL nCol ) const; SCROW GetNotePosition( SCCOL nCol, size_t nIndex ) const; diff --git a/sc/qa/extras/scpdfexport.cxx b/sc/qa/extras/scpdfexport.cxx index 02f00f8fac5d..69bcbde242d6 100644 --- a/sc/qa/extras/scpdfexport.cxx +++ b/sc/qa/extras/scpdfexport.cxx @@ -55,12 +55,16 @@ private: // unit tests public: void testExportRange_Tdf120161(); + void testForcepoint97(); CPPUNIT_TEST_SUITE(ScPDFExportTest); CPPUNIT_TEST(testExportRange_Tdf120161); + CPPUNIT_TEST(testForcepoint97); CPPUNIT_TEST_SUITE_END(); }; +char const DATA_DIRECTORY[] = "/sc/qa/extras/testdocuments/"; + void ScPDFExportTest::setUp() { test::BootstrapFixture::setUp(); @@ -278,6 +282,18 @@ void ScPDFExportTest::testExportRange_Tdf120161() } } +// just needs to not crash on export to pdf +void ScPDFExportTest::testForcepoint97() +{ + mxComponent = loadFromDesktop(m_directories.getURLFromSrc(DATA_DIRECTORY) + "forcepoint97.xlsx", + "com.sun.star.sheet.SpreadsheetDocument"); + uno::Reference<frame::XModel> xModel(mxComponent, uno::UNO_QUERY); + + // A1:H81 + ScRange range1(0, 0, 0, 7, 81, 0); + std::shared_ptr<utl::TempFile> pPDFFile = exportToPdf(xModel, range1); +} + CPPUNIT_TEST_SUITE_REGISTRATION(ScPDFExportTest); CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/sc/qa/extras/testdocuments/forcepoint97.xlsx b/sc/qa/extras/testdocuments/forcepoint97.xlsx Binary files differnew file mode 100644 index 000000000000..152fbbc45a9f --- /dev/null +++ b/sc/qa/extras/testdocuments/forcepoint97.xlsx diff --git a/sc/qa/unit/data/xlsx/forcepoint107.xlsx b/sc/qa/unit/data/xlsx/forcepoint107.xlsx Binary files differnew file mode 100644 index 000000000000..f5238dcb5c3e --- /dev/null +++ b/sc/qa/unit/data/xlsx/forcepoint107.xlsx diff --git a/sc/qa/unit/filters-test.cxx b/sc/qa/unit/filters-test.cxx index 2a0afb4323aa..48b60471fc8e 100644 --- a/sc/qa/unit/filters-test.cxx +++ b/sc/qa/unit/filters-test.cxx @@ -85,6 +85,7 @@ public: void testSortWithSheetExternalReferencesODS(); void testSortWithSheetExternalReferencesODS_Impl( ScDocShellRef const & xDocShRef, SCROW nRow1, SCROW nRow2, bool bCheckRelativeInSheet ); + void testForcepoint107(); CPPUNIT_TEST_SUITE(ScFiltersTest); CPPUNIT_TEST(testCVEs); @@ -106,6 +107,7 @@ public: CPPUNIT_TEST(testEnhancedProtectionXLSX); CPPUNIT_TEST(testSortWithSharedFormulasODS); CPPUNIT_TEST(testSortWithSheetExternalReferencesODS); + CPPUNIT_TEST(testForcepoint107); CPPUNIT_TEST_SUITE_END(); @@ -761,6 +763,13 @@ void ScFiltersTest::testSortWithSheetExternalReferencesODS_Impl( ScDocShellRef c } } +// just needs to not crash on recalc +void ScFiltersTest::testForcepoint107() +{ + ScDocShellRef xDocSh = loadDoc(u"forcepoint107.", FORMAT_XLSX, true); + xDocSh->DoHardRecalc(); +} + ScFiltersTest::ScFiltersTest() : ScBootstrapFixture( "sc/qa/unit/data" ) , mbUpdateReferenceOnSort(false) diff --git a/sc/source/core/data/colorscale.cxx b/sc/source/core/data/colorscale.cxx index 4ea3606e48b8..a257fae0a87d 100644 --- a/sc/source/core/data/colorscale.cxx +++ b/sc/source/core/data/colorscale.cxx @@ -484,8 +484,10 @@ Color CalcColor( double nVal, double nVal1, const Color& rCol1, double nVal2, co double GetPercentile( const std::vector<double>& rArray, double fPercentile ) { size_t nSize = rArray.size(); - size_t nIndex = static_cast<size_t>(::rtl::math::approxFloor( fPercentile * (nSize-1))); - double fDiff = fPercentile * (nSize-1) - ::rtl::math::approxFloor( fPercentile * (nSize-1)); + double fFloor = ::rtl::math::approxFloor(fPercentile * (nSize-1)); + SAL_WARN_IF(fFloor < 0, "sc", "negative percentile"); + size_t nIndex = fFloor >= 0 ? static_cast<size_t>(fFloor) : 0; + double fDiff = fPercentile * (nSize-1) - fFloor; std::vector<double>::const_iterator iter = rArray.begin() + nIndex; if (fDiff == 0.0) return *iter; diff --git a/sc/source/core/data/documen2.cxx b/sc/source/core/data/documen2.cxx index 88c9b972c912..a810494b056c 100644 --- a/sc/source/core/data/documen2.cxx +++ b/sc/source/core/data/documen2.cxx @@ -221,6 +221,7 @@ ScDocument::ScDocument( ScDocumentMode eMode, SfxObjectShell* pDocShell ) : mbUseEmbedFonts(false), mbTrackFormulasPending(false), mbFinalTrackFormulas(false), + mbLayoutStrings(false), mnMutationGuardFlags(0) { SetStorageGrammar( formula::FormulaGrammar::GRAM_STORAGE_DEFAULT); diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx index 06a1a532e628..ea10ba0913f3 100644 --- a/sc/source/core/data/document.cxx +++ b/sc/source/core/data/document.cxx @@ -6448,7 +6448,7 @@ ScPostIt* ScDocument::GetNote(const ScAddress& rPos) ScPostIt* ScDocument::GetNote(SCCOL nCol, SCROW nRow, SCTAB nTab) { if (ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size())) - return maTabs[nTab]->aCol[nCol].GetCellNote(nRow); + return maTabs[nTab]->GetNote(nCol, nRow); else return nullptr; @@ -6461,7 +6461,8 @@ void ScDocument::SetNote(const ScAddress& rPos, ScPostIt* pNote) void ScDocument::SetNote(SCCOL nCol, SCROW nRow, SCTAB nTab, ScPostIt* pNote) { - return maTabs[nTab]->aCol[nCol].SetCellNote(nRow, pNote); + if (ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size())) + maTabs[nTab]->SetNote(nCol, nRow, std::move(pNote)); } bool ScDocument::HasNote(const ScAddress& rPos) const @@ -6491,6 +6492,9 @@ bool ScDocument::HasColNotes(SCCOL nCol, SCTAB nTab) const if (!pTab) return false; + if (nCol >= MAXCOLCOUNT) + return false; + return pTab->aCol[nCol].HasCellNotes(); } @@ -6534,6 +6538,7 @@ ScPostIt* ScDocument::GetOrCreateNote(const ScAddress& rPos) else return CreateNote(rPos); } + ScPostIt* ScDocument::CreateNote(const ScAddress& rPos) { ScPostIt* pPostIt = new ScPostIt(*this, rPos); diff --git a/sc/source/core/data/documentimport.cxx b/sc/source/core/data/documentimport.cxx index a7a3ba8e0326..04aa11c9b4b7 100644 --- a/sc/source/core/data/documentimport.cxx +++ b/sc/source/core/data/documentimport.cxx @@ -93,6 +93,15 @@ struct ScDocumentImportImpl return rTab.getBlockPosition(nCol); } + void invalidateBlockPositionSet(SCTAB nTab) + { + if (sal_uInt16(nTab) >= maBlockPosSet.size()) + return; + + sc::TableColumnBlockPositionSet& rTab = maBlockPosSet[nTab]; + rTab.invalidate(); + } + void initForSheets() { size_t n = mrDoc.GetTableCount(); @@ -180,6 +189,11 @@ void ScDocumentImport::setOriginDate(sal_uInt16 nYear, sal_uInt16 nMonth, sal_uI mpImpl->mrDoc.pDocOptions->SetDate(nDay, nMonth, nYear); } +void ScDocumentImport::invalidateBlockPositionSet(SCTAB nTab) +{ + mpImpl->invalidateBlockPositionSet(nTab); +} + void ScDocumentImport::setAutoInput(const ScAddress& rPos, const OUString& rStr, const ScSetStringParam* pStringParam) { ScTable* pTab = mpImpl->mrDoc.FetchTable(rPos.Tab()); @@ -367,6 +381,14 @@ void ScDocumentImport::setFormulaCell(const ScAddress& rPos, ScFormulaCell* pCel mpImpl->mrDoc.CheckLinkFormulaNeedingCheck( *pCell->GetCode()); sc::CellStoreType& rCells = pTab->aCol[rPos.Col()].maCells; + + sc::CellStoreType::position_type aPos = rCells.position(rPos.Row()); + if (aPos.first != rCells.end() && aPos.first->type == sc::element_type_formula) + { + ScFormulaCell* p = sc::formula_block::at(*aPos.first->data, aPos.second); + sc::SharedFormulaUtil::unshareFormulaCell(aPos, *p); + } + pBlockPos->miCellPos = rCells.set(pBlockPos->miCellPos, rPos.Row(), pCell); } diff --git a/sc/source/core/data/dpobject.cxx b/sc/source/core/data/dpobject.cxx index cb733d25a8da..22d1941f1eb0 100644 --- a/sc/source/core/data/dpobject.cxx +++ b/sc/source/core/data/dpobject.cxx @@ -1038,7 +1038,16 @@ bool ScDPObject::GetMembers( sal_Int32 nDim, sal_Int32 nHier, vector<ScDPLabelDa for (sal_Int32 i = 0; i < nCount; ++i) { - Reference<container::XNamed> xMember(xMembersIA->getByIndex(i), UNO_QUERY); + Reference<container::XNamed> xMember; + try + { + xMember = Reference<container::XNamed>(xMembersIA->getByIndex(i), UNO_QUERY); + } + catch (const container::NoSuchElementException&) + { + //TOOLS_WARN_EXCEPTION("sc", "ScNameToIndexAccess getByIndex failed"); + } + ScDPLabelData::Member aMem; if (xMember.is()) diff --git a/sc/source/core/data/dptabres.cxx b/sc/source/core/data/dptabres.cxx index 38107b70e09f..d3e0d108f38a 100644 --- a/sc/source/core/data/dptabres.cxx +++ b/sc/source/core/data/dptabres.cxx @@ -2769,7 +2769,10 @@ ScDPResultDimension::~ScDPResultDimension() ScDPResultMember *ScDPResultDimension::FindMember( SCROW iData ) const { if( bIsDataLayout ) - return maMemberArray[0].get(); + { + SAL_WARN_IF(maMemberArray.empty(), "sc.core", "MemberArray is empty"); + return !maMemberArray.empty() ? maMemberArray[0].get() : nullptr; + } MemberHash::const_iterator aRes = maMemberHash.find( iData ); if( aRes != maMemberHash.end()) { @@ -2976,8 +2979,11 @@ void ScDPResultDimension::LateInitFrom( long ScDPResultDimension::GetSize(long nMeasure) const { - long nTotal = 0; long nMemberCount = maMemberArray.size(); + if (!nMemberCount) + return 0; + + long nTotal = 0; if (bIsDataLayout) { OSL_ENSURE(nMeasure == SC_DPMEASURE_ALL || pResultData->GetMeasureCount() == 1, @@ -3130,7 +3136,7 @@ void ScDPResultDimension::SortMembers( ScDPResultMember* pRefMember ) // handle children // for data layout, call only once - sorting measure is always taken from settings - long nLoopCount = bIsDataLayout ? 1 : nCount; + long nLoopCount = bIsDataLayout ? std::min<long>(1, nCount) : nCount; for (long i=0; i<nLoopCount; i++) { ScDPResultMember* pMember = maMemberArray[i].get(); diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx index b43e908352ed..77b6746a7fcb 100644 --- a/sc/source/core/data/formulacell.cxx +++ b/sc/source/core/data/formulacell.cxx @@ -939,6 +939,9 @@ ScFormulaCell::~ScFormulaCell() if (!mxGroup || !mxGroup->mpCode) // Formula token is not shared. delete pCode; + + if (mxGroup && mxGroup->mpTopCell == this) + mxGroup->mpTopCell = nullptr; } ScFormulaCell* ScFormulaCell::Clone() const @@ -2010,7 +2013,8 @@ void ScFormulaCell::InterpretTail( ScInterpreterContext& rContext, ScInterpretTa // XXX if mbNeedsNumberFormat was set even if the current format // was not General then we'd have to obtain the current format here // and check at least the types. - if (bSetFormat && (bForceNumberFormat || ((nFormatIndex % SV_COUNTRY_LANGUAGE_OFFSET) != 0))) + const bool bSetNumberFormat = bSetFormat && (bForceNumberFormat || ((nFormatIndex % SV_COUNTRY_LANGUAGE_OFFSET) != 0)); + if (bSetNumberFormat && !pDocument->IsInLayoutStrings()) { // set number format explicitly if (!pDocument->IsThreadedGroupCalcInProgress()) diff --git a/sc/source/core/data/mtvelements.cxx b/sc/source/core/data/mtvelements.cxx index e34010af54d8..598b43f963f3 100644 --- a/sc/source/core/data/mtvelements.cxx +++ b/sc/source/core/data/mtvelements.cxx @@ -153,6 +153,11 @@ ColumnBlockPosition* TableColumnBlockPositionSet::getBlockPosition( SCCOL nCol ) return &it->second; } +void TableColumnBlockPositionSet::invalidate() +{ + mpImpl->maColumns.clear(); +} + ScRefCellValue toRefCell( const sc::CellStoreType::const_iterator& itPos, size_t nOffset ) { switch (itPos->type) diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx index e640b31622f4..66c072d12cc0 100644 --- a/sc/source/core/data/table2.cxx +++ b/sc/source/core/data/table2.cxx @@ -1600,6 +1600,21 @@ ScPostIt* ScTable::ReleaseNote( SCCOL nCol, SCROW nRow ) return aCol[nCol].ReleaseNote(nRow); } +ScPostIt* ScTable::GetNote( SCCOL nCol, SCROW nRow ) +{ + if (!ValidCol(nCol) || nCol >= MAXCOLCOUNT) + return nullptr; + return aCol[nCol].GetCellNote(nRow); +} + +void ScTable::SetNote( SCCOL nCol, SCROW nRow, ScPostIt* pNote ) +{ + if (!ValidColRow(nCol, nRow)) + return; + + CreateColumnIfNotExists(nCol).SetCellNote(nRow, std::move(pNote)); +} + size_t ScTable::GetNoteCount( SCCOL nCol ) const { if (!ValidCol(nCol)) @@ -3714,7 +3729,7 @@ void ScTable::CopyData( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW n if (bThisTab) { - aCell.release(aCol[nDestX], nDestY); + aCell.release(CreateColumnIfNotExists(nDestX), nDestY); SetPattern( nDestX, nDestY, *GetPattern( nCol, nRow ) ); } else diff --git a/sc/source/core/data/table3.cxx b/sc/source/core/data/table3.cxx index 487e7eec6626..0b78cd9c31f4 100644 --- a/sc/source/core/data/table3.cxx +++ b/sc/source/core/data/table3.cxx @@ -3145,6 +3145,10 @@ SCSIZE ScTable::Query(const ScQueryParam& rParamOrg, bool bKeepSub) if (bResult) { CopyData( aParam.nCol1,j, aParam.nCol2,j, aParam.nDestCol,nOutRow,aParam.nDestTab ); +#if 0 + if( nTab == aParam.nDestTab ) // copy to self, changes may invalidate caching position hints + blockPos.invalidate(); +#endif ++nOutRow; } } diff --git a/sc/source/core/inc/interpre.hxx b/sc/source/core/inc/interpre.hxx index e7d7f5e2aff8..b4fcbd9698eb 100644 --- a/sc/source/core/inc/interpre.hxx +++ b/sc/source/core/inc/interpre.hxx @@ -237,6 +237,7 @@ private: inline bool MustHaveParamCount( short nAct, short nMust ); inline bool MustHaveParamCount( short nAct, short nMust, short nMax ); inline bool MustHaveParamCountMin( short nAct, short nMin ); + inline bool MustHaveParamCountMinWithStackCheck( short nAct, short nMin ); void PushParameterExpected(); void PushIllegalParameter(); void PushIllegalArgument(); @@ -1064,6 +1065,17 @@ inline bool ScInterpreter::MustHaveParamCountMin( short nAct, short nMin ) return false; } +inline bool ScInterpreter::MustHaveParamCountMinWithStackCheck( short nAct, short nMin ) +{ + assert(sp >= nAct); + if (sp < nAct) + { + PushParameterExpected(); + return false; + } + return MustHaveParamCountMin( nAct, nMin); +} + inline bool ScInterpreter::CheckStringPositionArgument( double & fVal ) { if (!rtl::math::isFinite( fVal)) diff --git a/sc/source/core/tool/interpr1.cxx b/sc/source/core/tool/interpr1.cxx index 2f7502073b46..2fcb409a5307 100644 --- a/sc/source/core/tool/interpr1.cxx +++ b/sc/source/core/tool/interpr1.cxx @@ -7384,7 +7384,7 @@ void ScInterpreter::ScVLookup() void ScInterpreter::ScSubTotal() { sal_uInt8 nParamCount = GetByte(); - if ( MustHaveParamCountMin( nParamCount, 2 ) ) + if ( MustHaveParamCountMinWithStackCheck( nParamCount, 2 ) ) { // We must fish the 1st parameter deep from the stack! And push it on top. const FormulaToken* p = pStack[ sp - nParamCount ]; @@ -7431,7 +7431,7 @@ void ScInterpreter::ScSubTotal() void ScInterpreter::ScAggregate() { sal_uInt8 nParamCount = GetByte(); - if ( MustHaveParamCountMin( nParamCount, 3 ) ) + if ( MustHaveParamCountMinWithStackCheck( nParamCount, 3 ) ) { // fish the 1st parameter from the stack and push it on top. const FormulaToken* p = pStack[ sp - nParamCount ]; diff --git a/sc/source/core/tool/interpr4.cxx b/sc/source/core/tool/interpr4.cxx index 32238916e162..d234ed16d896 100644 --- a/sc/source/core/tool/interpr4.cxx +++ b/sc/source/core/tool/interpr4.cxx @@ -4029,11 +4029,19 @@ StackVar ScInterpreter::Interpret() eOp = ocNone; // JumpMatrix created nStackBase = sp; } - else + else if (sp >= pCur->GetParamCount()) nStackBase = sp - pCur->GetParamCount(); + else + { + SAL_WARN("sc.core", "Stack anomaly at " << aPos.Format( + ScRefFlags::VALID | ScRefFlags::FORCE_DOC | ScRefFlags::TAB_3D, pDok) + << " eOp: " << static_cast<int>(eOp) + << " params: " << static_cast<int>(pCur->GetParamCount()) + << " nStackBase: " << nStackBase << " sp: " << sp); + nStackBase = sp; + assert(!"underflow"); + } } - if ( nStackBase > sp ) - nStackBase = sp; // underflow?!? switch( eOp ) { diff --git a/sc/source/core/tool/interpr7.cxx b/sc/source/core/tool/interpr7.cxx index 7b11e6faddab..56f6b2b3e6d4 100644 --- a/sc/source/core/tool/interpr7.cxx +++ b/sc/source/core/tool/interpr7.cxx @@ -220,6 +220,7 @@ void ScInterpreter::ScFilterXML() case XPATH_STRING: PushString(OUString::createFromAscii(reinterpret_cast<char*>(pXPathObj->stringval))); break; +#if LIBXML_VERSION < 21000 || defined(LIBXML_XPTR_LOCS_ENABLED) case XPATH_POINT: PushNoValue(); break; @@ -229,13 +230,13 @@ void ScInterpreter::ScFilterXML() case XPATH_LOCATIONSET: PushNoValue(); break; +#endif case XPATH_USERS: PushNoValue(); break; case XPATH_XSLT_TREE: PushNoValue(); break; - } } } diff --git a/sc/source/filter/lotus/op.cxx b/sc/source/filter/lotus/op.cxx index 7dec5cfbd0d1..d2510ff5d1ab 100644 --- a/sc/source/filter/lotus/op.cxx +++ b/sc/source/filter/lotus/op.cxx @@ -580,14 +580,9 @@ void OP_SheetName123(LotusContext& rContext, SvStream& rStream, sal_uInt16 nLeng SCTAB nSheetNum = static_cast<SCTAB>(nDummy); rContext.pDoc->MakeTable(nSheetNum); - ::std::vector<sal_Char> sSheetName; - sSheetName.reserve(nLength-4); - for (sal_uInt16 i = 4; i < nLength; ++i) - { - sal_Char c; - rStream.ReadChar( c ); - sSheetName.push_back(c); - } + const size_t nStrLen = nLength - 4; + std::vector<sal_Char> sSheetName(nStrLen + 1); + sSheetName[rStream.ReadBytes(sSheetName.data(), nStrLen)] = 0; if (!sSheetName.empty()) { diff --git a/sc/source/filter/oox/sheetdatabuffer.cxx b/sc/source/filter/oox/sheetdatabuffer.cxx index cf44072cd9e3..ccca237964f7 100644 --- a/sc/source/filter/oox/sheetdatabuffer.cxx +++ b/sc/source/filter/oox/sheetdatabuffer.cxx @@ -402,10 +402,23 @@ void SheetDataBuffer::addColXfStyle( sal_Int32 nXfId, sal_Int32 nFormatId, const void SheetDataBuffer::finalizeImport() { + ScDocumentImport& rDocImport = getDocImport(); + + SCTAB nStartTabInvalidatedIters(SCTAB_MAX); + SCTAB nEndTabInvalidatedIters(0); + // create all array formulas for( ArrayFormulaVector::iterator aIt = maArrayFormulas.begin(), aEnd = maArrayFormulas.end(); aIt != aEnd; ++aIt ) + { finalizeArrayFormula( aIt->first, aIt->second ); + nStartTabInvalidatedIters = std::min(aIt->first.aStart.Tab(), nStartTabInvalidatedIters); + nEndTabInvalidatedIters = std::max(aIt->first.aEnd.Tab(), nEndTabInvalidatedIters); + } + + for (SCTAB nTab = nStartTabInvalidatedIters; nTab <= nEndTabInvalidatedIters; ++nTab) + rDocImport.invalidateBlockPositionSet(nTab); + // create all table operations for( TableOperationVector::iterator aIt = maTableOperations.begin(), aEnd = maTableOperations.end(); aIt != aEnd; ++aIt ) finalizeTableOperation( aIt->first, aIt->second ); diff --git a/sc/source/filter/xml/XMLCalculationSettingsContext.cxx b/sc/source/filter/xml/XMLCalculationSettingsContext.cxx index fd7aab6ddb23..802cbf35a00c 100644 --- a/sc/source/filter/xml/XMLCalculationSettingsContext.cxx +++ b/sc/source/filter/xml/XMLCalculationSettingsContext.cxx @@ -150,12 +150,14 @@ ScXMLNullDateContext::ScXMLNullDateContext( ScXMLImport& rImport, if (aIter != rAttrList->end()) { util::DateTime aDateTime; - ::sax::Converter::parseDateTime(aDateTime, aIter.toString()); - util::Date aDate; - aDate.Day = aDateTime.Day; - aDate.Month = aDateTime.Month; - aDate.Year = aDateTime.Year; - pCalcSet->SetNullDate(aDate); + if (::sax::Converter::parseDateTime(aDateTime, aIter.toString())) + { + util::Date aDate; + aDate.Day = aDateTime.Day; + aDate.Month = aDateTime.Month; + aDate.Year = aDateTime.Year; + pCalcSet->SetNullDate(aDate); + } } } } diff --git a/sc/source/filter/xml/xmlexprt.cxx b/sc/source/filter/xml/xmlexprt.cxx index 8cd6ebc11085..b189f4f67762 100644 --- a/sc/source/filter/xml/xmlexprt.cxx +++ b/sc/source/filter/xml/xmlexprt.cxx @@ -108,6 +108,7 @@ #include <tools/color.hxx> #include <tools/urlobj.hxx> +#include <tools/diagnose_ex.h> #include <rtl/math.hxx> #include <svl/zforlist.hxx> #include <svx/unoshape.hxx> @@ -3453,16 +3454,23 @@ void ScXMLExport::ExportShape(const uno::Reference < drawing::XShape >& xShape, uno::Sequence< OUString > aRepresentations( xReceiver->getUsedRangeRepresentations()); SvXMLAttributeList* pAttrList = nullptr; - if(aRepresentations.getLength()) + try { - // add the ranges used by the chart to the shape - // element to be able to start listening after - // load (when the chart is not yet loaded) - uno::Reference< chart2::data::XRangeXMLConversion > xRangeConverter( xChartDoc->getDataProvider(), uno::UNO_QUERY ); - sRanges = lcl_RangeSequenceToString( aRepresentations, xRangeConverter ); - pAttrList = new SvXMLAttributeList(); - pAttrList->AddAttribute( - GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_DRAW, GetXMLToken(XML_NOTIFY_ON_UPDATE_OF_RANGES) ), sRanges ); + if (aRepresentations.getLength()) + { + // add the ranges used by the chart to the shape + // element to be able to start listening after + // load (when the chart is not yet loaded) + uno::Reference< chart2::data::XRangeXMLConversion > xRangeConverter( xChartDoc->getDataProvider(), uno::UNO_QUERY ); + sRanges = lcl_RangeSequenceToString( aRepresentations, xRangeConverter ); + pAttrList = new SvXMLAttributeList(); + pAttrList->AddAttribute( + GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_DRAW, GetXMLToken(XML_NOTIFY_ON_UPDATE_OF_RANGES) ), sRanges ); + } + } + catch (const lang::IllegalArgumentException&) + { + //TOOLS_WARN_EXCEPTION("sc", "Exception in lcl_RangeSequenceToString - invalid range?"); } GetShapeExport()->exportShape(xShape, XMLShapeExportFlags::NO_CHART_DATA | SEF_DEFAULT, pPoint, pAttrList); } diff --git a/sc/source/ui/docshell/docsh4.cxx b/sc/source/ui/docshell/docsh4.cxx index 52a44126539d..916cd1aa1b30 100644 --- a/sc/source/ui/docshell/docsh4.cxx +++ b/sc/source/ui/docshell/docsh4.cxx @@ -1108,10 +1108,10 @@ void ScDocShell::Execute( SfxRequest& rReq ) EnableSharedSettings( false ); - if ( pBindings ) - { - pBindings->ExecuteSynchron( SID_SAVEDOC ); - } + // Do *not* use dispatch mechanism in this place - we don't want others (extensions etc.) to intercept this. + uno::Reference<frame::XStorable> xStorable2( + GetModel(), uno::UNO_QUERY_THROW); + xStorable2->store(); ScTabView* pTabView = dynamic_cast< ScTabView* >( pViewData->GetView() ); if ( pTabView ) diff --git a/sc/source/ui/unoobj/chart2uno.cxx b/sc/source/ui/unoobj/chart2uno.cxx index 89ebe89061ee..e019dbb6dfa1 100644 --- a/sc/source/ui/unoobj/chart2uno.cxx +++ b/sc/source/ui/unoobj/chart2uno.cxx @@ -2206,7 +2206,10 @@ OUString SAL_CALL ScChart2DataProvider::convertRangeToXML( const OUString& sRang ScRefTokenHelper::compileRangeRepresentation( aRefTokens, sRangeRepresentation, m_pDocument, cSep, m_pDocument->GetGrammar(), true); if (aRefTokens.empty()) + { + SAL_WARN("sc", "convertRangeToXML throw IllegalArgumentException from input of: " << sRangeRepresentation); throw lang::IllegalArgumentException(); + } Tokens2RangeStringXML converter(m_pDocument); converter = ::std::for_each(aRefTokens.begin(), aRefTokens.end(), converter); diff --git a/sc/source/ui/view/output2.cxx b/sc/source/ui/view/output2.cxx index 3dfaaa9889f9..a956be4a7205 100644 --- a/sc/source/ui/view/output2.cxx +++ b/sc/source/ui/view/output2.cxx @@ -74,6 +74,7 @@ #include <scopetools.hxx> #include <com/sun/star/i18n/DirectionProperty.hpp> +#include <comphelper/scopeguard.hxx> #include <comphelper/string.hxx> #include <memory> @@ -1453,6 +1454,12 @@ void ScOutputData::DrawStrings( bool bPixelToLogic ) tools::Rectangle ScOutputData::LayoutStrings(bool bPixelToLogic, bool bPaint, const ScAddress &rAddress) { + bool bOrigIsInLayoutStrings = mpDoc->IsInLayoutStrings(); + mpDoc->SetLayoutStrings(true); + comphelper::ScopeGuard g([this, bOrigIsInLayoutStrings] { + mpDoc->SetLayoutStrings(bOrigIsInLayoutStrings); + }); + OSL_ENSURE( mpDev == mpRefDevice || mpDev->GetMapMode().GetMapUnit() == mpRefDevice->GetMapMode().GetMapUnit(), "LayoutStrings: different MapUnits ?!?!" ); |