basic/qa/cppunit/test_scanner.cxx | 17 +++ basic/source/comp/scanner.cxx | 3 basic/source/runtime/methods.cxx | 3 cui/source/inc/numpages.hxx | 1 cui/source/options/optjava.cxx | 19 +++- cui/source/options/optjava.hxx | 1 cui/source/tabpages/numpages.cxx | 7 + formula/source/core/api/FormulaCompiler.cxx | 7 + include/vcl/vclenum.hxx | 3 sc/inc/clipparam.hxx | 2 sc/inc/dbdata.hxx | 4 sc/inc/document.hxx | 8 - sc/qa/unit/data/ods/tdf95640.ods |binary sc/qa/unit/data/ods/tdf95640_standard_list.ods |binary sc/qa/unit/data/ods/validation-copypaste.ods |binary sc/qa/unit/data/xlsx/tdf95640.xlsx |binary sc/qa/unit/subsequent_export-test.cxx | 102 +++++++++++++++++++++ sc/source/core/data/table2.cxx | 5 - sc/source/core/data/table3.cxx | 4 sc/source/core/tool/compiler.cxx | 19 ++++ sc/source/filter/excel/excrecds.cxx | 64 +++++++++++++ sc/source/filter/inc/autofilterbuffer.hxx | 30 ++++++ sc/source/filter/inc/autofiltercontext.hxx | 39 ++++++++ sc/source/filter/inc/excrecds.hxx | 3 sc/source/filter/oox/autofilterbuffer.cxx | 116 +++++++++++++++++++++++-- sc/source/filter/oox/autofiltercontext.cxx | 68 ++++++++++++++ sc/source/filter/oox/tablebuffer.cxx | 2 sw/source/core/doc/doclay.cxx | 8 - sw/source/filter/basflt/shellio.cxx | 1 sw/source/uibase/uiview/view2.cxx | 9 + vcl/source/window/layout.cxx | 9 + vcl/source/window/printdlg.cxx | 24 +++-- vcl/unx/gtk3/gtk3gtkinst.cxx | 3 33 files changed, 528 insertions(+), 53 deletions(-)
New commits: commit ab9d80265a3c7628f22f7ab4d1e7b4daecc22ba0 Author: Caolán McNamara <[email protected]> AuthorDate: Mon Sep 14 14:44:25 2020 +0100 Commit: Andras Timar <[email protected]> CommitDate: Sat Sep 19 21:11:54 2020 +0200 rhbz#1878275 should use value_changed for spinbutton changes Change-Id: I8d042eb9c288e9db69a49cb9e097b23cf765aae6 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/102678 Tested-by: Jenkins Reviewed-by: Adolfo Jayme Barrientos <[email protected]> diff --git a/cui/source/inc/numpages.hxx b/cui/source/inc/numpages.hxx index d03f44a868e2..8b45dc53205b 100644 --- a/cui/source/inc/numpages.hxx +++ b/cui/source/inc/numpages.hxx @@ -273,6 +273,7 @@ class SvxNumOptionsTabPage : public SfxTabPage DECL_LINK(CharFmtHdl_Impl, weld::ComboBox&, void); DECL_LINK(EditModifyHdl_Impl, weld::Entry&, void); DECL_LINK(EditListBoxHdl_Impl, weld::ComboBox&, void); + DECL_LINK(SpinModifyHdl_Impl, weld::SpinButton&, void); DECL_LINK(AllLevelHdl_Impl, weld::SpinButton&, void); DECL_LINK(OrientHdl_Impl, weld::ComboBox&, void); DECL_LINK(SameLevelHdl_Impl, weld::ToggleButton&, void); diff --git a/cui/source/tabpages/numpages.cxx b/cui/source/tabpages/numpages.cxx index fdbeb6f7cb4b..5692dd73aefe 100644 --- a/cui/source/tabpages/numpages.cxx +++ b/cui/source/tabpages/numpages.cxx @@ -1072,7 +1072,7 @@ SvxNumOptionsTabPage::SvxNumOptionsTabPage(weld::Container* pPage, weld::DialogC m_xWidthMF->connect_value_changed(LINK(this, SvxNumOptionsTabPage, SizeHdl_Impl)); m_xHeightMF->connect_value_changed(LINK(this, SvxNumOptionsTabPage, SizeHdl_Impl)); m_xRatioCB->connect_toggled(LINK(this, SvxNumOptionsTabPage, RatioHdl_Impl)); - m_xStartED->connect_changed(LINK(this, SvxNumOptionsTabPage, EditModifyHdl_Impl)); + m_xStartED->connect_value_changed(LINK(this, SvxNumOptionsTabPage, SpinModifyHdl_Impl)); m_xPrefixED->connect_changed(LINK(this, SvxNumOptionsTabPage, EditModifyHdl_Impl)); m_xSuffixED->connect_changed(LINK(this, SvxNumOptionsTabPage, EditModifyHdl_Impl)); m_xAllLevelNF->connect_value_changed(LINK(this,SvxNumOptionsTabPage, AllLevelHdl_Impl)); @@ -2098,6 +2098,11 @@ IMPL_LINK(SvxNumOptionsTabPage, EditModifyHdl_Impl, weld::Entry&, rEdit, void) EditModifyHdl_Impl(&rEdit); } +IMPL_LINK(SvxNumOptionsTabPage, SpinModifyHdl_Impl, weld::SpinButton&, rSpinButton, void) +{ + EditModifyHdl_Impl(&rSpinButton); +} + void SvxNumOptionsTabPage::EditModifyHdl_Impl(const weld::Entry* pEdit) { bool bPrefix = pEdit == m_xPrefixED.get(); commit 700df0490e4e674b0bc22d165ff0614fd8e610ae Author: Vasily Melenchuk <[email protected]> AuthorDate: Fri Sep 11 14:06:23 2020 +0300 Commit: Andras Timar <[email protected]> CommitDate: Sat Sep 19 21:11:48 2020 +0200 tdf#135623: modified generation of unique fly name Modified lcl_GetUniqueFlyName() is right now always marks current fly format name number as used. Yes, this can lead to some gaps in numbering is some cases, but meanwhile guarantee that there will be no duplicates if format name does not match SdrObject name. Change-Id: If39ed993614ae1665deba21ae8d5e6bd542fb6e0 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/102460 Tested-by: Jenkins Reviewed-by: Thorsten Behrens <[email protected]> (cherry picked from commit 07a695ec1988ee8b02256cab2e07a1b429ead24b) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/102636 Reviewed-by: Vasily Melenchuk <[email protected]> (cherry picked from commit c514e9cfca2901f325644a65ee1b87455a56e7f0) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/102638 Reviewed-by: Xisco Fauli <[email protected]> diff --git a/sw/source/core/doc/doclay.cxx b/sw/source/core/doc/doclay.cxx index 2a63e2112b6b..ec4861fe39b2 100644 --- a/sw/source/core/doc/doclay.cxx +++ b/sw/source/core/doc/doclay.cxx @@ -1349,11 +1349,9 @@ static OUString lcl_GetUniqueFlyName(const SwDoc* pDoc, const char* pDefStrId, s if (pObj) lcl_collectUsedNums(aUsedNums, nNmLen, *pObj, aName); } - else - { - OUString sName = pFlyFormat->GetName(); - lcl_collectUsedNums(aUsedNums, nNmLen, sName, aName); - } + + OUString sName = pFlyFormat->GetName(); + lcl_collectUsedNums(aUsedNums, nNmLen, sName, aName); } // All numbers are flagged accordingly, so determine the right one commit f1783b3fd850db25ace370df4633f75ff6bc053a Author: Noel Grandin <[email protected]> AuthorDate: Sat Sep 12 18:21:44 2020 +0200 Commit: Andras Timar <[email protected]> CommitDate: Sat Sep 19 21:11:42 2020 +0200 tdf#133327 fix calc loading background color with many cols regression from commit 7282014e362a1529a36c88eb308df8ed359c2cfa tdf#50916 Makes numbers of columns dynamic. Change-Id: Ic9e1b31d74b11367a5ad1a82480ffe9467c37ad8 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/102535 Tested-by: Jenkins Reviewed-by: Noel Grandin <[email protected]> (cherry picked from commit 4176beb7ef831152ce92ac3fa31314438635ec2c) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/102635 Reviewed-by: Xisco Fauli <[email protected]> diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx index 1b0cc1e4bfe1..5a12b0bba520 100644 --- a/sc/source/core/data/table2.cxx +++ b/sc/source/core/data/table2.cxx @@ -2574,10 +2574,9 @@ void ScTable::MergeSelectionPattern( ScMergePatternState& rState, const ScMarkDa for (const sc::ColRowSpan & rSpan : aSpans) { - SCCOL nEnd = ClampToAllocatedColumns(rSpan.mnEnd); - for (SCCOLROW i = rSpan.mnStart; i <= nEnd; ++i) + for (SCCOLROW i = rSpan.mnStart; i <= rSpan.mnEnd; ++i) { - aCol[i].MergeSelectionPattern( rState, rMark, bDeep ); + CreateColumnIfNotExists(i).MergeSelectionPattern( rState, rMark, bDeep ); } } } commit 7628d35af92f9c9d9a04e964ce14bc72648183bb Author: Caolán McNamara <[email protected]> AuthorDate: Thu Sep 10 10:03:26 2020 +0100 Commit: Andras Timar <[email protected]> CommitDate: Sat Sep 19 21:11:36 2020 +0200 tdf#135950 crash in format->character with selected text in table Change-Id: I66e36a638d040d2a38ac234383d6f314a2ff4d88 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/102310 Tested-by: Jenkins Reviewed-by: Xisco Fauli <[email protected]> diff --git a/sw/source/filter/basflt/shellio.cxx b/sw/source/filter/basflt/shellio.cxx index f3fe939f634d..db178e6c97a1 100644 --- a/sw/source/filter/basflt/shellio.cxx +++ b/sw/source/filter/basflt/shellio.cxx @@ -899,6 +899,7 @@ ErrCode SwWriter::Write( WriterRef const & rxWriter, const OUString* pRealFileNa if ( xDoc.is() ) { + pTempCursor.reset(); xDoc.clear(); bWriteAll = false; } commit a14281473fff851deabf917f39e1f4d8026a8e91 Author: Andreas Heinisch <[email protected]> AuthorDate: Sun Sep 6 09:26:47 2020 +0200 Commit: Andras Timar <[email protected]> CommitDate: Sat Sep 19 21:11:31 2020 +0200 tdf#136032 - abort scan of a string beginning with a hashtag Abort scan of a string beginning with a hashtag, if a comma is found. Otherwise, the compiler raises a syntax error. If the string ends with a hashtag too, it will be parsed later checking for a date literal. Change-Id: I078a2302f5c65206367a00fbc584ffa7b9ede031 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/102099 Tested-by: Mike Kaganski <[email protected]> Reviewed-by: Mike Kaganski <[email protected]> (cherry picked from commit 11292d1cc405e7c3b9e1f374cc7581a63a54b994) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/101973 Tested-by: Jenkins Reviewed-by: Xisco Fauli <[email protected]> (cherry picked from commit cc17346d682d85b6c083d76cae2d55dcc022e58f) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/102120 diff --git a/basic/qa/cppunit/test_scanner.cxx b/basic/qa/cppunit/test_scanner.cxx index 42cd637cbd44..b5f14bc57691 100644 --- a/basic/qa/cppunit/test_scanner.cxx +++ b/basic/qa/cppunit/test_scanner.cxx @@ -46,6 +46,7 @@ namespace void testDataType(); void testHexOctal(); void testTdf103104(); + void testTdf136032(); // Adds code needed to register the test suite CPPUNIT_TEST_SUITE(ScannerTest); @@ -62,6 +63,7 @@ namespace CPPUNIT_TEST(testDataType); CPPUNIT_TEST(testHexOctal); CPPUNIT_TEST(testTdf103104); + CPPUNIT_TEST(testTdf136032); // End of test suite definition CPPUNIT_TEST_SUITE_END(); @@ -959,6 +961,21 @@ namespace CPPUNIT_ASSERT_EQUAL(cr, symbols[3].text); } + void ScannerTest::testTdf136032() + { + std::vector<Symbol> symbols; + sal_Int32 errors; + + // tdf#136032 - abort scan of a string beginning with a hashtag, + // if a comma/whitespace is found. Otherwise, the compiler raises a syntax error. + symbols = getSymbols("Print #i,\"A#B\"", errors); + CPPUNIT_ASSERT_EQUAL(size_t(5), symbols.size()); + CPPUNIT_ASSERT_EQUAL(0u, static_cast<unsigned int>(errors)); + symbols = getSymbols("Print #i, \"A#B\"", errors); + CPPUNIT_ASSERT_EQUAL(size_t(5), symbols.size()); + CPPUNIT_ASSERT_EQUAL(0u, static_cast<unsigned int>(errors)); + } + // Put the test suite in the registry CPPUNIT_TEST_SUITE_REGISTRATION(ScannerTest); } // namespace diff --git a/basic/source/comp/scanner.cxx b/basic/source/comp/scanner.cxx index 7c192b3a0107..7c5a0d7b265d 100644 --- a/basic/source/comp/scanner.cxx +++ b/basic/source/comp/scanner.cxx @@ -251,7 +251,8 @@ bool SbiScanner::NextSym() do { nLineTempIdx++; - } while (nLineTempIdx < aLine.getLength() && !BasicCharClass::isWhitespace(aLine[nLineTempIdx]) && aLine[nLineTempIdx] != '#'); + } while (nLineTempIdx < aLine.getLength() && !BasicCharClass::isWhitespace(aLine[nLineTempIdx]) + && aLine[nLineTempIdx] != '#' && aLine[nLineTempIdx] != ','); // leave it if it is a date literal - it will be handled later if (nLineTempIdx >= aLine.getLength() || aLine[nLineTempIdx] != '#') { commit b18f8afadfad5ea993d12c47f0e33863c248dc8c Author: Stephan Bergmann <[email protected]> AuthorDate: Mon Aug 17 13:06:50 2020 +0200 Commit: Andras Timar <[email protected]> CommitDate: Sat Sep 19 21:11:25 2020 +0200 Always display highlighted JRE's location ...when opening the Advanced options page and after adding a new JRE via the "Add..." button, not only after highlighting another JRE line. (I suspect this broke with 1aa246a8e8c7d974ab0f7bdfa16cda36cb700e03 "weld SvxJavaOptionsPage" towards LO 6.4.) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/100860 Tested-by: Jenkins Reviewed-by: Stephan Bergmann <[email protected]> (cherry picked from commit f7fe1e93da753d74485a13d46fe15fb198411932) Change-Id: I5f9b63e2d33a351eeef09712969b703f1e99ef7e Reviewed-on: https://gerrit.libreoffice.org/c/core/+/102286 Tested-by: Jenkins Reviewed-by: Thorsten Behrens <[email protected]> diff --git a/cui/source/options/optjava.cxx b/cui/source/options/optjava.cxx index 37a08f035716..36540800bb62 100644 --- a/cui/source/options/optjava.cxx +++ b/cui/source/options/optjava.cxx @@ -20,6 +20,7 @@ #include <sal/config.h> #include <sal/log.hxx> +#include <cassert> #include <memory> #include <vector> @@ -151,11 +152,7 @@ IMPL_LINK(SvxJavaOptionsPage, CheckHdl_Impl, const row_col&, rRowCol, void) IMPL_LINK_NOARG(SvxJavaOptionsPage, SelectHdl_Impl, weld::TreeView&, void) { - // set installation directory info - OUString sLocation = m_xJavaList->get_selected_id(); - // tdf#80646 insert LTR mark after label - OUString sInfo = m_sInstallText + u"\u200E" + sLocation; - m_xJavaPathText->set_label(sInfo); + UpdateJavaPathText(); } IMPL_LINK_NOARG(SvxJavaOptionsPage, AddHdl_Impl, weld::Button&, void) @@ -348,6 +345,7 @@ void SvxJavaOptionsPage::LoadJREs() if ( jfw_areEqualJavaInfo( pCmpInfo.get(), pSelectedJava.get() ) ) { HandleCheckEntry(i); + UpdateJavaPathText(); break; } ++i; @@ -391,6 +389,16 @@ void SvxJavaOptionsPage::HandleCheckEntry(int nCheckedRow) } } +void SvxJavaOptionsPage::UpdateJavaPathText() +{ + assert(m_xJavaList->get_selected_index() != -1); + // set installation directory info + OUString sLocation = m_xJavaList->get_selected_id(); + // tdf#80646 insert LTR mark after label + OUString sInfo = m_sInstallText + u"\u200E" + sLocation; + m_xJavaPathText->set_label(sInfo); +} + void SvxJavaOptionsPage::AddFolder( const OUString& _rFolder ) { #if HAVE_FEATURE_JAVA @@ -433,6 +441,7 @@ void SvxJavaOptionsPage::AddFolder( const OUString& _rFolder ) } HandleCheckEntry(nPos); + UpdateJavaPathText(); bStartAgain = false; } else if ( JFW_E_NOT_RECOGNIZED == eErr ) diff --git a/cui/source/options/optjava.hxx b/cui/source/options/optjava.hxx index e5537f1e1ff7..f3cbb1e5a1df 100644 --- a/cui/source/options/optjava.hxx +++ b/cui/source/options/optjava.hxx @@ -102,6 +102,7 @@ private: void LoadJREs(); void AddJRE( JavaInfo const * _pInfo ); void HandleCheckEntry(int nCheckedRow); + void UpdateJavaPathText(); void AddFolder( const OUString& _rFolder ); void RequestRestart( svtools::RestartReason eReason ); commit 3da26ff2c878bc6496471b576ee8706f2e1770fd Author: Juergen Funk <[email protected]> AuthorDate: Fri Sep 4 10:53:44 2020 +0200 Commit: Andras Timar <[email protected]> CommitDate: Sat Sep 19 21:11:21 2020 +0200 tdf#127932 fix wrong page number in print progress - in ctor, reset start pages to non-inflated value after size calculation - update label, _then_ progress in setProgress() Change-Id: I66576e339de814922512b68167e6c0a9b1025378 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/102031 Tested-by: Thorsten Behrens <[email protected]> Reviewed-by: Thorsten Behrens <[email protected]> (cherry picked from commit 63bf8f042abe3c0f6989f6763d13f5389182b816) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/102281 Tested-by: Jenkins diff --git a/vcl/source/window/printdlg.cxx b/vcl/source/window/printdlg.cxx index 7d340559806a..1515b8b74264 100644 --- a/vcl/source/window/printdlg.cxx +++ b/vcl/source/window/printdlg.cxx @@ -2159,6 +2159,15 @@ void PrintDialog::previewLast() ActivateHdl(*mxPageEdit); } + +static OUString getNewLabel(const OUString& aLabel, int i_nCurr, int i_nMax) +{ + OUString aNewText( aLabel.replaceFirst( "%p", OUString::number( i_nCurr ) ) ); + aNewText = aNewText.replaceFirst( "%n", OUString::number( i_nMax ) ); + + return aNewText; +} + // PrintProgressDialog PrintProgressDialog::PrintProgressDialog(weld::Window* i_pParent, int i_nMax) : GenericDialogController(i_pParent, "vcl/ui/printprogressdialog.ui", "PrintProgressDialog") @@ -2176,15 +2185,17 @@ PrintProgressDialog::PrintProgressDialog(weld::Window* i_pParent, int i_nMax) //just multiply largest value by 10 and take the width of that string as //the max size we will want - OUString aNewText( maStr.replaceFirst( "%p", OUString::number( mnMax * 10 ) ) ); - aNewText = aNewText.replaceFirst( "%n", OUString::number( mnMax * 10 ) ); - mxText->set_label( aNewText ); + mxText->set_label(getNewLabel(maStr, mnMax * 10, mnMax * 10)); mxText->set_size_request(mxText->get_preferred_size().Width(), -1); //Pick a useful max width mxProgress->set_size_request(mxProgress->get_approximate_digit_width() * 25, -1); mxButton->connect_clicked( LINK( this, PrintProgressDialog, ClickHdl ) ); + + // after this patch f7157f04fab298423e2c4f6a7e5f8e361164b15f, we have seen the calc Max string (sometimes) look above + // now init to the right start vaules + mxText->set_label(getNewLabel(maStr, mnCur, mnMax)); } PrintProgressDialog::~PrintProgressDialog() @@ -2203,11 +2214,10 @@ void PrintProgressDialog::setProgress( int i_nCurrent ) if( mnMax < 1 ) mnMax = 1; - mxProgress->set_percentage(mnCur*100/mnMax); + mxText->set_label(getNewLabel(maStr, mnCur, mnMax)); - OUString aNewText( maStr.replaceFirst( "%p", OUString::number( mnCur ) ) ); - aNewText = aNewText.replaceFirst( "%n", OUString::number( mnMax ) ); - mxText->set_label( aNewText ); + // here view the dialog, with the right label + mxProgress->set_percentage(mnCur*100/mnMax); } void PrintProgressDialog::tick() commit 908d526517b6c5efbae5b50639a8abb95514696a Author: Serge Krot <[email protected]> AuthorDate: Fri Jul 10 11:09:35 2020 +0200 Commit: Andras Timar <[email protected]> CommitDate: Sat Sep 19 21:11:15 2020 +0200 tdf#108673 XLSX: Don't export invalid sheet references in cell validation Change-Id: Id9d88f5e34f3017516f693505df4c3ce82b1890f Reviewed-on: https://gerrit.libreoffice.org/c/core/+/98479 Tested-by: Jenkins Reviewed-by: Eike Rathke <[email protected]> (cherry picked from commit a3b4831208da615789bd1e2d5660dd130807f504) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/102128 Reviewed-by: Thorsten Behrens <[email protected]> diff --git a/sc/inc/clipparam.hxx b/sc/inc/clipparam.hxx index ee9422bc27db..575a04526763 100644 --- a/sc/inc/clipparam.hxx +++ b/sc/inc/clipparam.hxx @@ -27,7 +27,7 @@ * This struct stores general clipboard parameters associated with a * ScDocument instance created in clipboard mode. */ -struct ScClipParam +struct SC_DLLPUBLIC ScClipParam { enum Direction { Unspecified, Column, Row }; diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx index 691d1b8d821d..9d7bd94d8764 100644 --- a/sc/inc/document.hxx +++ b/sc/inc/document.hxx @@ -1545,7 +1545,7 @@ public: SCTAB nTab, InsertDeleteFlags nDelFlag); void DeleteAreaTab(const ScRange& rRange, InsertDeleteFlags nDelFlag); - void CopyToClip( const ScClipParam& rClipParam, ScDocument* pClipDoc, + SC_DLLPUBLIC void CopyToClip( const ScClipParam& rClipParam, ScDocument* pClipDoc, const ScMarkData* pMarks, bool bKeepScenarioFlags, bool bIncludeObjects ); @@ -1596,7 +1596,7 @@ public: /** If pDestRanges is given it overrides rDestRange, rDestRange in this case is the overall encompassing range. */ - void CopyFromClip( const ScRange& rDestRange, const ScMarkData& rMark, + SC_DLLPUBLIC void CopyFromClip( const ScRange& rDestRange, const ScMarkData& rMark, InsertDeleteFlags nInsFlag, ScDocument* pRefUndoDoc, ScDocument* pClipDoc, diff --git a/sc/qa/unit/data/ods/validation-copypaste.ods b/sc/qa/unit/data/ods/validation-copypaste.ods new file mode 100644 index 000000000000..55f8d823b88b Binary files /dev/null and b/sc/qa/unit/data/ods/validation-copypaste.ods differ diff --git a/sc/qa/unit/subsequent_export-test.cxx b/sc/qa/unit/subsequent_export-test.cxx index 80a888f42c39..35fffd679831 100644 --- a/sc/qa/unit/subsequent_export-test.cxx +++ b/sc/qa/unit/subsequent_export-test.cxx @@ -41,6 +41,7 @@ #include <scmod.hxx> #include <dpcache.hxx> #include <dpobject.hxx> +#include <clipparam.hxx> #include <svx/svdpage.hxx> #include <svx/svdograf.hxx> @@ -233,6 +234,7 @@ public: void testTdf126177XLSX(); void testCommentTextVAlignment(); void testCommentTextHAlignment(); + void testValidationCopyPaste(); void testXltxExport(); void testRotatedImageODS(); @@ -369,6 +371,7 @@ public: CPPUNIT_TEST(testTdf126177XLSX); CPPUNIT_TEST(testCommentTextVAlignment); CPPUNIT_TEST(testCommentTextHAlignment); + CPPUNIT_TEST(testValidationCopyPaste); CPPUNIT_TEST(testXltxExport); CPPUNIT_TEST(testRotatedImageODS); @@ -4411,6 +4414,42 @@ void ScExportTest::testTdf91634XLSX() assertXPath(pXmlRels, "/r:Relationships/r:Relationship[@Id='rId1']", "TargetMode", "External"); } +void ScExportTest::testValidationCopyPaste() +{ + ScDocShellRef xDocSh = loadDoc("validation-copypaste.", FORMAT_ODS); + CPPUNIT_ASSERT(xDocSh.is()); + ScDocument& rSrcDoc = xDocSh->GetDocument(); + + // Copy B1 from src doc to clip + ScDocument aClipDoc(SCDOCMODE_CLIP); + ScRange aSrcRange(1, 0, 1); + ScClipParam aClipParam(aSrcRange, false); + ScMarkData aMark(rSrcDoc.MaxRow(), rSrcDoc.MaxCol()); + aMark.SetMarkArea(aSrcRange); + rSrcDoc.CopyToClip(aClipParam, &aClipDoc, &aMark, false, false); + + // Create second document, paste B1 from clip + ScDocShell* pShell2 + = new ScDocShell(SfxModelFlags::EMBEDDED_OBJECT | SfxModelFlags::DISABLE_EMBEDDED_SCRIPTS + | SfxModelFlags::DISABLE_DOCUMENT_RECOVERY); + pShell2->DoInitNew(); + ScDocument& rDestDoc = pShell2->GetDocument(); + ScRange aDstRange(1, 0, 0); + ScMarkData aMark2(rDestDoc.MaxRow(), rDestDoc.MaxCol()); + aMark2.SetMarkArea(aDstRange); + rDestDoc.CopyFromClip(aDstRange, aMark2, InsertDeleteFlags::ALL, nullptr, &aClipDoc); + + // save as XLSX + std::shared_ptr<utl::TempFile> pXPathFile + = ScBootstrapFixture::exportTo(&(*pShell2), FORMAT_XLSX); + + // check validation + xmlDocPtr pDoc + = XPathHelper::parseExport(pXPathFile, m_xSFactory, "xl/worksheets/sheet1.xml"); + CPPUNIT_ASSERT(pDoc); + assertXPathContent(pDoc, "/x:worksheet/x:dataValidations/x:dataValidation/x:formula1", "#REF!"); +} + void ScExportTest::testTdf115159() { ScDocShellRef xShell = loadDoc("tdf115159.", FORMAT_XLSX); diff --git a/sc/source/core/tool/compiler.cxx b/sc/source/core/tool/compiler.cxx index 4305ea572854..d84efe3b1003 100644 --- a/sc/source/core/tool/compiler.cxx +++ b/sc/source/core/tool/compiler.cxx @@ -1440,6 +1440,25 @@ struct ConventionXL_OOX : public ConventionXL_A1 return; } + { + ScAddress aAbs1 = rRef.Ref1.toAbs(rPos); + if (std::make_unsigned_t<sal_Int16>(aAbs1.Tab()) >= rTabNames.size()) + { + rBuf.append(rErrRef); + return; + } + } + + if (!bSingleRef) + { + ScAddress aAbs2 = rRef.Ref2.toAbs(rPos); + if (std::make_unsigned_t<sal_Int16>(aAbs2.Tab()) >= rTabNames.size()) + { + rBuf.append(rErrRef); + return; + } + } + ConventionXL_A1::makeRefStr( pDoc, rBuf, eGram, aPos, rErrRef, rTabNames, rRef, bSingleRef, bFromRangeName); } commit 73c86d55bf9a6fa065a8ac0bff83926276306020 Author: Thorsten Behrens <[email protected]> AuthorDate: Sun Sep 6 17:07:47 2020 +0200 Commit: Andras Timar <[email protected]> CommitDate: Sat Sep 19 21:11:10 2020 +0200 Check range before accessing Calc sort userlist Conflicts: sc/source/filter/excel/excrecds.cxx Change-Id: Ib5078dc4ce3f85be9b42320b60ef6fc40b684cb7 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/102140 Tested-by: Jenkins Tested-by: Serge Krot <[email protected]> Reviewed-by: Thorsten Behrens <[email protected]> Reviewed-on: https://gerrit.libreoffice.org/c/core/+/102255 Reviewed-by: Samuel Mehrbrodt <[email protected]> diff --git a/sc/source/core/data/table3.cxx b/sc/source/core/data/table3.cxx index 1ee6456d84a6..c27c73fb88e1 100644 --- a/sc/source/core/data/table3.cxx +++ b/sc/source/core/data/table3.cxx @@ -1488,9 +1488,9 @@ short ScTable::CompareCell( bool bNaturalSort = aSortParam.bNaturalSort; // natural sort bool bCaseSens = aSortParam.bCaseSens; // case sensitivity - if (bUserDef) + ScUserList* pList = ScGlobal::GetUserList(); + if (bUserDef && pList && pList->size() > aSortParam.nUserIndex ) { - ScUserList* pList = ScGlobal::GetUserList(); const ScUserListData& rData = (*pList)[aSortParam.nUserIndex]; if ( bNaturalSort ) diff --git a/sc/source/filter/excel/excrecds.cxx b/sc/source/filter/excel/excrecds.cxx index d7ab5d7d95af..920955a6540d 100644 --- a/sc/source/filter/excel/excrecds.cxx +++ b/sc/source/filter/excel/excrecds.cxx @@ -935,7 +935,8 @@ ExcAutoFilterRecs::ExcAutoFilterRecs( const XclExpRoot& rRoot, SCTAB nTab, const ScSortParam aSortParam; pData->GetSortParam( aSortParam ); - if (aSortParam.bUserDef) + ScUserList* pList = ScGlobal::GetUserList(); + if (aSortParam.bUserDef && pList && pList->size() > aSortParam.nUserIndex) { // get sorted area without headers maSortRef = ScRange( @@ -943,7 +944,6 @@ ExcAutoFilterRecs::ExcAutoFilterRecs( const XclExpRoot& rRoot, SCTAB nTab, const aParam.nCol2, aParam.nRow2, aParam.nTab ); // get sorted columns with custom lists - ScUserList* pList = ScGlobal::GetUserList(); const ScUserListData& rData = (*pList)[aSortParam.nUserIndex]; // get column index and sorting direction commit d8e0001fd8b4702f78ade095b8b2ce09ac2451e2 Author: Serge Krot <[email protected]> AuthorDate: Mon Jun 29 13:23:34 2020 +0200 Commit: Andras Timar <[email protected]> CommitDate: Sat Sep 19 21:11:04 2020 +0200 tdf#95640 XLSX: import/export of custom sort lists Conflicts: sc/source/filter/excel/excrecds.cxx sc/source/filter/oox/autofilterbuffer.cxx sc/source/filter/oox/tablebuffer.cxx Change-Id: If5ffef39770bf7abd6e75e8de998d4a2b4749a0d Reviewed-on: https://gerrit.libreoffice.org/c/core/+/97399 Tested-by: Jenkins Tested-by: Serge Krot <[email protected]> Reviewed-by: Serge Krot <[email protected]> Reviewed-by: Thorsten Behrens <[email protected]> Reviewed-on: https://gerrit.libreoffice.org/c/core/+/102254 Reviewed-by: Samuel Mehrbrodt <[email protected]> diff --git a/sc/inc/dbdata.hxx b/sc/inc/dbdata.hxx index a7dc35c3b61b..24eaa3be7d18 100644 --- a/sc/inc/dbdata.hxx +++ b/sc/inc/dbdata.hxx @@ -172,8 +172,8 @@ public: OUString GetSourceString() const; OUString GetOperations() const; - void GetSortParam(ScSortParam& rSortParam) const; - void SetSortParam(const ScSortParam& rSortParam); + SC_DLLPUBLIC void GetSortParam(ScSortParam& rSortParam) const; + SC_DLLPUBLIC void SetSortParam(const ScSortParam& rSortParam); /** Remember some more settings of ScSortParam, only to be called at anonymous DB ranges as it at least overwrites bHasHeader. */ diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx index 6e5ba824d938..691d1b8d821d 100644 --- a/sc/inc/document.hxx +++ b/sc/inc/document.hxx @@ -814,8 +814,8 @@ public: bool bRemoveAutoFilter = false ); const ScDBData* GetDBAtCursor(SCCOL nCol, SCROW nRow, SCTAB nTab, ScDBDataPortion ePortion) const; ScDBData* GetDBAtCursor(SCCOL nCol, SCROW nRow, SCTAB nTab, ScDBDataPortion ePortion); - const ScDBData* GetDBAtArea(SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2) const; - ScDBData* GetDBAtArea(SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2); + SC_DLLPUBLIC const ScDBData* GetDBAtArea(SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2) const; + SC_DLLPUBLIC ScDBData* GetDBAtArea(SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2); void RefreshDirtyTableColumnNames(); SC_DLLPUBLIC sc::ExternalDataMapper& GetExternalDataMapper(); diff --git a/sc/qa/unit/data/ods/tdf95640.ods b/sc/qa/unit/data/ods/tdf95640.ods new file mode 100644 index 000000000000..5d435c61cc85 Binary files /dev/null and b/sc/qa/unit/data/ods/tdf95640.ods differ diff --git a/sc/qa/unit/data/ods/tdf95640_standard_list.ods b/sc/qa/unit/data/ods/tdf95640_standard_list.ods new file mode 100644 index 000000000000..37bea8a0c93e Binary files /dev/null and b/sc/qa/unit/data/ods/tdf95640_standard_list.ods differ diff --git a/sc/qa/unit/data/xlsx/tdf95640.xlsx b/sc/qa/unit/data/xlsx/tdf95640.xlsx new file mode 100644 index 000000000000..78c2d32c2cf6 Binary files /dev/null and b/sc/qa/unit/data/xlsx/tdf95640.xlsx differ diff --git a/sc/qa/unit/subsequent_export-test.cxx b/sc/qa/unit/subsequent_export-test.cxx index bf0d74cdf830..80a888f42c39 100644 --- a/sc/qa/unit/subsequent_export-test.cxx +++ b/sc/qa/unit/subsequent_export-test.cxx @@ -195,6 +195,12 @@ public: void testPreserveTextWhitespace2XLSX(); void testTextDirectionXLSX(); + xmlDocPtr testTdf95640(const OUString& rFileName, sal_Int32 nSourceFormat, + sal_Int32 nDestFormat); + void testTdf95640_ods_to_xlsx(); + void testTdf95640_ods_to_xlsx_with_standard_list(); + void testTdf95640_xlsx_to_xlsx(); + void testRefStringXLSX(); void testRefStringConfigXLSX(); void testRefStringUnspecified(); @@ -327,6 +333,9 @@ public: CPPUNIT_TEST(testMoveCellAnchoredShapesODS); CPPUNIT_TEST(testMatrixMultiplicationXLSX); CPPUNIT_TEST(testTextDirectionXLSX); + CPPUNIT_TEST(testTdf95640_ods_to_xlsx); + CPPUNIT_TEST(testTdf95640_ods_to_xlsx_with_standard_list); + CPPUNIT_TEST(testTdf95640_xlsx_to_xlsx); CPPUNIT_TEST(testRefStringXLSX); CPPUNIT_TEST(testRefStringConfigXLSX); @@ -3956,6 +3965,60 @@ void ScExportTest::testTextDirectionXLSX() assertXPath(pDoc, "/x:styleSheet/x:cellXfs/x:xf[3]/x:alignment", "readingOrder", "2");//RTL } +xmlDocPtr ScExportTest::testTdf95640(const OUString& rFileName, sal_Int32 nSourceFormat, + sal_Int32 nDestFormat) +{ + ScDocShellRef xShell = loadDoc(rFileName, nSourceFormat); + CPPUNIT_ASSERT(xShell); + + auto pXPathFile = ScBootstrapFixture::exportTo(&(*xShell), nDestFormat); + xShell->DoClose(); + + return XPathHelper::parseExport(pXPathFile, m_xSFactory, "xl/worksheets/sheet1.xml"); +} + +void ScExportTest::testTdf95640_ods_to_xlsx() +{ + // Roundtripping sort options with user defined list to XLSX + xmlDocPtr pDoc = testTdf95640("tdf95640.", FORMAT_ODS, FORMAT_XLSX); + + assertXPath(pDoc, "//x:worksheet/x:autoFilter", "ref", "A1:B4"); + + assertXPath(pDoc, "//x:worksheet/x:autoFilter/x:sortState/x:sortCondition", "ref", "A2:A4"); + + assertXPath(pDoc, "//x:worksheet/x:autoFilter/x:sortState/x:sortCondition", "customList", + "Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec"); +} + +void ScExportTest::testTdf95640_ods_to_xlsx_with_standard_list() +{ + // Roundtripping sort options with user defined list to XLSX + xmlDocPtr pDoc = testTdf95640("tdf95640_standard_list.", FORMAT_ODS, FORMAT_XLSX); + + assertXPath(pDoc, "//x:worksheet/x:autoFilter", "ref", "A1:B4"); + + assertXPath(pDoc, "//x:worksheet/x:autoFilter/x:sortState/x:sortCondition", "ref", "A2:A4"); + + assertXPath(pDoc, "//x:worksheet/x:autoFilter/x:sortState/x:sortCondition", "customList", + "Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday"); +} + +void ScExportTest::testTdf95640_xlsx_to_xlsx() +{ + // XLSX Roundtripping sort options with custom sort list - note + // that compared to ODS source documents above, here we _actually_ + // can use custom lists (beyond the global user defines), like + // low, medium, high + xmlDocPtr pDoc = testTdf95640("tdf95640.", FORMAT_XLSX, FORMAT_XLSX); + + assertXPath(pDoc, "//x:worksheet/x:autoFilter", "ref", "A1:B4"); + + assertXPath(pDoc, "//x:worksheet/x:autoFilter/x:sortState/x:sortCondition", "ref", "A2:A4"); + + assertXPath(pDoc, "//x:worksheet/x:autoFilter/x:sortState/x:sortCondition", "customList", + "Low,Medium,High"); +} + void ScExportTest::testTdf88657ODS() { ScDocShellRef xDocSh = loadDoc("tdf88657.", FORMAT_ODS); diff --git a/sc/source/filter/excel/excrecds.cxx b/sc/source/filter/excel/excrecds.cxx index 4fbe955d8b52..d7ab5d7d95af 100644 --- a/sc/source/filter/excel/excrecds.cxx +++ b/sc/source/filter/excel/excrecds.cxx @@ -34,6 +34,8 @@ #include <oox/token/tokens.hxx> #include <queryentry.hxx> #include <queryparam.hxx> +#include <sortparam.hxx> +#include <userlist.hxx> #include <root.hxx> #include <xeescher.hxx> @@ -927,6 +929,45 @@ ExcAutoFilterRecs::ExcAutoFilterRecs( const XclExpRoot& rRoot, SCTAB nTab, const if (maFilterList.IsEmpty () && !bConflict) mbAutoFilter = true; + + // get sort criteria + { + ScSortParam aSortParam; + pData->GetSortParam( aSortParam ); + + if (aSortParam.bUserDef) + { + // get sorted area without headers + maSortRef = ScRange( + aParam.nCol1, aParam.nRow1 + (aSortParam.bHasHeader? 1 : 0), aParam.nTab, + aParam.nCol2, aParam.nRow2, aParam.nTab ); + + // get sorted columns with custom lists + ScUserList* pList = ScGlobal::GetUserList(); + const ScUserListData& rData = (*pList)[aSortParam.nUserIndex]; + + // get column index and sorting direction + SCCOLROW nField = 0; + bool bSortAscending=true; + for (const auto & rKey : aSortParam.maKeyState) + { + if (rKey.bDoSort) + { + nField = rKey.nField; + bSortAscending = rKey.bAscending; + break; + } + } + + // remember sort criteria + const ScRange aSortedColumn( + nField, aParam.nRow1 + (aSortParam.bHasHeader? 1 : 0), aParam.nTab, + nField, aParam.nRow2, aParam.nTab ); + const OUString aItemList = rData.GetString(); + + maSortCustomList.emplace_back(aSortedColumn, aItemList, !bSortAscending); + } + } } } } @@ -990,6 +1031,29 @@ void ExcAutoFilterRecs::SaveXml( XclExpXmlStream& rStrm ) // OOXTODO: XML_extLst, XML_sortState if( !maFilterList.IsEmpty() ) maFilterList.SaveXml( rStrm ); + + if (!maSortCustomList.empty()) + { + rWorksheet->startElement(XML_sortState, XML_ref, XclXmlUtils::ToOString(&rStrm.GetRoot().GetDoc(), maSortRef)); + + for (const auto & rSortCriteria : maSortCustomList) + { + if (std::get<2>(rSortCriteria)) + rWorksheet->singleElement(XML_sortCondition, + XML_ref, XclXmlUtils::ToOString(&rStrm.GetRoot().GetDoc(), + std::get<0>(rSortCriteria)), + XML_descending, "1", + XML_customList, std::get<1>(rSortCriteria).toUtf8().getStr()); + else + rWorksheet->singleElement(XML_sortCondition, + XML_ref, XclXmlUtils::ToOString(&rStrm.GetRoot().GetDoc(), + std::get<0>(rSortCriteria)), + XML_customList, std::get<1>(rSortCriteria).toUtf8().getStr()); + } + + rWorksheet->endElement(XML_sortState); + } + rWorksheet->endElement( XML_autoFilter ); } diff --git a/sc/source/filter/inc/autofilterbuffer.hxx b/sc/source/filter/inc/autofilterbuffer.hxx index c6387e5d37d4..ae8e8b4fa2a0 100644 --- a/sc/source/filter/inc/autofilterbuffer.hxx +++ b/sc/source/filter/inc/autofilterbuffer.hxx @@ -184,6 +184,22 @@ private: bool mbShowButton; }; +// class SortCondition + +class SortCondition : public WorkbookHelper +{ +public: + explicit SortCondition( const WorkbookHelper& rHelper ); + + void importSortCondition( const AttributeList& rAttribs, sal_Int16 nSheet ); + + ScRange maRange; // Column/Row that this sort condition applies to. + OUString maSortCustomList; // Sort by a custom list. + bool mbDescending; +}; + +// class AutoFilter + class AutoFilter : public WorkbookHelper { public: @@ -194,17 +210,26 @@ public: /** Imports auto filter settings from the AUTOFILTER record. */ void importAutoFilter( SequenceInputStream& rStrm, sal_Int16 nSheet ); + void importSortState( const AttributeList& rAttribs, sal_Int16 nSheet ); + /** Creates a new auto filter column and stores it internally. */ FilterColumn& createFilterColumn(); + SortCondition& createSortCondition(); + /** Applies the filter to the passed filter descriptor. */ - void finalizeImport( const css::uno::Reference< css::sheet::XSheetFilterDescriptor3>& rxFilterDesc ); + void finalizeImport( const css::uno::Reference< css::sheet::XDatabaseRange >& rxDatabaseRange, + sal_Int16 nSheet ); private: typedef RefVector< FilterColumn > FilterColumnVector; FilterColumnVector maFilterColumns; ScRange maRange; + + ScRange maSortRange; // The whole range of data to sort (not just the sort-by column). + typedef RefVector< SortCondition > SortConditionVector; + SortConditionVector maSortConditions; }; class AutoFilterBuffer : public WorkbookHelper @@ -221,7 +246,8 @@ public: /** Applies the filters to the passed database range object. @return True = this buffer contains valid auto filter settings. */ - bool finalizeImport( const css::uno::Reference< css::sheet::XDatabaseRange >& rxDatabaseRange ); + bool finalizeImport( const css::uno::Reference< css::sheet::XDatabaseRange >& rxDatabaseRange, + sal_Int16 nSheet ); private: /** Returns the auto filter object used to perform auto filtering. */ diff --git a/sc/source/filter/inc/autofiltercontext.hxx b/sc/source/filter/inc/autofiltercontext.hxx index 9a58a8a998e0..ef7bb539c3e7 100644 --- a/sc/source/filter/inc/autofiltercontext.hxx +++ b/sc/source/filter/inc/autofiltercontext.hxx @@ -21,6 +21,7 @@ #define INCLUDED_SC_SOURCE_FILTER_INC_AUTOFILTERCONTEXT_HXX #include "excelhandlers.hxx" +#include "autofilterbuffer.hxx" namespace oox { namespace xls { @@ -61,6 +62,44 @@ private: FilterColumn& mrFilterColumn; }; +// class SortConditionContext + +class SortConditionContext : public WorksheetContextBase +{ +public: + explicit SortConditionContext( WorksheetContextBase& rFragment, SortCondition& rSortCondition ); + +protected: + virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs ) override; + virtual void onStartElement( const AttributeList& rAttribs ) override; + + virtual ::oox::core::ContextHandlerRef onCreateRecordContext( sal_Int32 nRecId, SequenceInputStream& rStrm ) override; + virtual void onStartRecord( SequenceInputStream& rStrm ) override; + +private: + SortCondition& mrSortCondition; +}; + +// class SortStateContext + +class SortStateContext : public WorksheetContextBase +{ +public: + explicit SortStateContext( WorksheetContextBase& rFragment, AutoFilter& rAutoFilter ); + +protected: + virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs ) override; + virtual void onStartElement( const AttributeList& rAttribs ) override; + + virtual ::oox::core::ContextHandlerRef onCreateRecordContext( sal_Int32 nRecId, SequenceInputStream& rStrm ) override; + virtual void onStartRecord( SequenceInputStream& rStrm ) override; + +private: + AutoFilter& mrAutoFilter; +}; + +// class AutoFilterContext + class AutoFilterContext : public WorksheetContextBase { public: diff --git a/sc/source/filter/inc/excrecds.hxx b/sc/source/filter/inc/excrecds.hxx index 74a21cbfa563..a0abbf9410cd 100644 --- a/sc/source/filter/inc/excrecds.hxx +++ b/sc/source/filter/inc/excrecds.hxx @@ -417,6 +417,9 @@ private: std::unique_ptr<XclExpAutofilterinfo> m_pFilterInfo; ScRange maRef; bool mbAutoFilter; + + ScRange maSortRef; // sort area without headers + std::vector< std::tuple<ScRange, OUString, bool> > maSortCustomList; // sorted column with list of sorted items }; /** Sheet filter manager. Contains auto filters or advanced filters from all sheets. */ diff --git a/sc/source/filter/oox/autofilterbuffer.cxx b/sc/source/filter/oox/autofilterbuffer.cxx index 9e53200092ce..8209df526283 100644 --- a/sc/source/filter/oox/autofilterbuffer.cxx +++ b/sc/source/filter/oox/autofilterbuffer.cxx @@ -39,6 +39,10 @@ #include <addressconverter.hxx> #include <defnamesbuffer.hxx> #include <biffhelper.hxx> +#include <document.hxx> +#include <dbdata.hxx> +#include <sortparam.hxx> +#include <userlist.hxx> namespace oox { namespace xls { @@ -530,6 +534,25 @@ ApiFilterSettings FilterColumn::finalizeImport( sal_Int32 nMaxCount ) return aSettings; } +// SortCondition + +SortCondition::SortCondition( const WorkbookHelper& rHelper ) : + WorkbookHelper( rHelper ), + mbDescending( false ) +{ +} + +void SortCondition::importSortCondition( const AttributeList& rAttribs, sal_Int16 nSheet ) +{ + OUString aRangeStr = rAttribs.getString( XML_ref, OUString() ); + AddressConverter::convertToCellRangeUnchecked( maRange, aRangeStr, nSheet ); + + maSortCustomList = rAttribs.getString( XML_customList, OUString() ); + mbDescending = rAttribs.getBool( XML_descending, false ); +} + +// AutoFilter + AutoFilter::AutoFilter( const WorkbookHelper& rHelper ) : WorkbookHelper( rHelper ) { @@ -548,6 +571,12 @@ void AutoFilter::importAutoFilter( SequenceInputStream& rStrm, sal_Int16 nSheet AddressConverter::convertToCellRangeUnchecked( maRange, aBinRange, nSheet ); } +void AutoFilter::importSortState( const AttributeList& rAttribs, sal_Int16 nSheet ) +{ + OUString aRangeStr = rAttribs.getString( XML_ref, OUString() ); + AddressConverter::convertToCellRangeUnchecked( maSortRange, aRangeStr, nSheet ); +} + FilterColumn& AutoFilter::createFilterColumn() { FilterColumnVector::value_type xFilterColumn( new FilterColumn( *this ) ); @@ -555,12 +584,21 @@ FilterColumn& AutoFilter::createFilterColumn() return *xFilterColumn; } -void AutoFilter::finalizeImport( const Reference<XSheetFilterDescriptor3>& rxFilterDesc ) +SortCondition& AutoFilter::createSortCondition() { - if( rxFilterDesc.is() ) + SortConditionVector::value_type xSortCondition = std::make_shared<SortCondition>( *this ); + maSortConditions.push_back( xSortCondition ); + return *xSortCondition; +} + +void AutoFilter::finalizeImport( const Reference< XDatabaseRange >& rxDatabaseRange, sal_Int16 nSheet ) +{ + // convert filter settings using the filter descriptor of the database range + const Reference<XSheetFilterDescriptor3> xFilterDesc( rxDatabaseRange->getFilterDescriptor(), UNO_QUERY_THROW ); + if( xFilterDesc.is() ) { // set some common properties for the auto filter range - PropertySet aDescProps( rxFilterDesc ); + PropertySet aDescProps( xFilterDesc ); aDescProps.setProperty( PROP_IsCaseSensitive, false ); aDescProps.setProperty( PROP_SkipDuplicates, false ); aDescProps.setProperty( PROP_Orientation, TableOrientation_ROWS ); @@ -631,11 +669,71 @@ void AutoFilter::finalizeImport( const Reference<XSheetFilterDescriptor3>& rxFil // insert all filter fields to the filter descriptor if( !aFilterFields.empty() ) - rxFilterDesc->setFilterFields3( ContainerHelper::vectorToSequence( aFilterFields ) ); + xFilterDesc->setFilterFields3( ContainerHelper::vectorToSequence( aFilterFields ) ); // regular expressions bool bUseRegExp = obNeedsRegExp.get( false ); aDescProps.setProperty( PROP_UseRegularExpressions, bUseRegExp ); + + // sort + if (!maSortConditions.empty()) + { + const SortConditionVector::value_type& xSortConditionPointer = *maSortConditions.begin(); + const SortCondition& rSorConditionLoaded = *xSortConditionPointer; + + ScSortParam aParam; + aParam.bUserDef = false; + aParam.nUserIndex = 0; + aParam.bByRow = false; + + ScUserList* pUserList = ScGlobal::GetUserList(); + if (!rSorConditionLoaded.maSortCustomList.isEmpty()) + { + for (size_t i=0; pUserList && i < pUserList->size(); i++) + { + const OUString aEntry((*pUserList)[i].GetString()); + if (aEntry.equalsIgnoreAsciiCase(rSorConditionLoaded.maSortCustomList)) + { + aParam.bUserDef = true; + aParam.nUserIndex = i; + break; + } + } + } + + if (!aParam.bUserDef) + { + pUserList->push_back(new ScUserListData(rSorConditionLoaded.maSortCustomList)); + aParam.bUserDef = true; + aParam.nUserIndex = pUserList->size()-1; + } + + // set sort parameter if we have detected it + if (aParam.bUserDef) + { + SCCOLROW nStartPos = aParam.bByRow ? maRange.aStart.Col() : maRange.aStart.Row(); + if (rSorConditionLoaded.mbDescending) + { + // descending sort - need to enable 1st SortParam slot + assert(aParam.GetSortKeyCount() == DEFSORT); + + aParam.maKeyState[0].bDoSort = true; + aParam.maKeyState[0].bAscending = false; + aParam.maKeyState[0].nField += nStartPos; + } + + ScDocument& rDoc = getScDocument(); + ScDBData* pDBData = rDoc.GetDBAtArea( + nSheet, + maRange.aStart.Col(), maRange.aStart.Row(), + maRange.aEnd.Col(), maRange.aEnd.Row()); + + if (pDBData) + pDBData->SetSortParam(aParam); + else + OSL_FAIL("AutoFilter::finalizeImport(): cannot find matching DBData"); + } + } } } @@ -662,7 +760,7 @@ void AutoFilterBuffer::finalizeImport( sal_Int16 nSheet ) // use the same name for the database range as used for the defined name '_FilterDatabase' Reference< XDatabaseRange > xDatabaseRange = createUnnamedDatabaseRangeObject( aFilterRange ); // first, try to create an auto filter - bool bHasAutoFilter = finalizeImport( xDatabaseRange ); + bool bHasAutoFilter = finalizeImport( xDatabaseRange, nSheet ); // no success: try to create an advanced filter if( !bHasAutoFilter && xDatabaseRange.is() ) { @@ -709,7 +807,7 @@ void AutoFilterBuffer::finalizeImport( sal_Int16 nSheet ) } } -bool AutoFilterBuffer::finalizeImport( const Reference< XDatabaseRange >& rxDatabaseRange ) +bool AutoFilterBuffer::finalizeImport( const Reference< XDatabaseRange >& rxDatabaseRange, sal_Int16 nSheet ) { AutoFilter* pAutoFilter = getActiveAutoFilter(); if( pAutoFilter && rxDatabaseRange.is() ) try @@ -717,9 +815,9 @@ bool AutoFilterBuffer::finalizeImport( const Reference< XDatabaseRange >& rxData // the property 'AutoFilter' enables the drop-down buttons PropertySet aRangeProps( rxDatabaseRange ); aRangeProps.setProperty( PROP_AutoFilter, true ); - // convert filter settings using the filter descriptor of the database range - Reference< XSheetFilterDescriptor3 > xFilterDesc( rxDatabaseRange->getFilterDescriptor(), UNO_QUERY_THROW ); - pAutoFilter->finalizeImport( xFilterDesc ); + + pAutoFilter->finalizeImport( rxDatabaseRange, nSheet ); + // return true to indicate enabled autofilter return true; } diff --git a/sc/source/filter/oox/autofiltercontext.cxx b/sc/source/filter/oox/autofiltercontext.cxx index 1ec7b7138b72..814569e0b45f 100644 --- a/sc/source/filter/oox/autofiltercontext.cxx +++ b/sc/source/filter/oox/autofiltercontext.cxx @@ -116,6 +116,65 @@ void FilterColumnContext::onStartRecord( SequenceInputStream& rStrm ) mrFilterColumn.importFilterColumn( rStrm ); } +// class SortConditionContext + +SortConditionContext::SortConditionContext( WorksheetContextBase& rParent, SortCondition& rSortCondition ) : + WorksheetContextBase( rParent ), + mrSortCondition( rSortCondition ) +{ +} + +ContextHandlerRef SortConditionContext::onCreateContext( sal_Int32 , const AttributeList& ) +{ + return nullptr; +} + +void SortConditionContext::onStartElement( const AttributeList& rAttribs ) +{ + mrSortCondition.importSortCondition( rAttribs, getSheetIndex() ); +} + +ContextHandlerRef SortConditionContext::onCreateRecordContext( sal_Int32 , SequenceInputStream& ) +{ + return nullptr; +} + +void SortConditionContext::onStartRecord( SequenceInputStream& ) +{ +} + +// class SortStateContext + +SortStateContext::SortStateContext( WorksheetContextBase& rParent, AutoFilter& rAutoFilter ) : + WorksheetContextBase( rParent ), + mrAutoFilter( rAutoFilter ) +{ +} + +ContextHandlerRef SortStateContext::onCreateContext( sal_Int32 nElement, const AttributeList& /*rAttribs*/ ) +{ + if( getCurrentElement() == XLS_TOKEN( sortState ) ) switch( nElement ) + { + case XLS_TOKEN( sortCondition ): + return new SortConditionContext( *this, mrAutoFilter.createSortCondition() ); + } + return nullptr; +} + +void SortStateContext::onStartElement( const AttributeList& rAttribs ) +{ + mrAutoFilter.importSortState( rAttribs, getSheetIndex() ); +} + +ContextHandlerRef SortStateContext::onCreateRecordContext( sal_Int32 , SequenceInputStream& ) +{ + return nullptr; +} + +void SortStateContext::onStartRecord( SequenceInputStream& ) +{ +} + AutoFilterContext::AutoFilterContext( WorksheetFragmentBase& rFragment, AutoFilter& rAutoFilter ) : WorksheetContextBase( rFragment ), mrAutoFilter( rAutoFilter ) @@ -124,8 +183,13 @@ AutoFilterContext::AutoFilterContext( WorksheetFragmentBase& rFragment, AutoFilt ContextHandlerRef AutoFilterContext::onCreateContext( sal_Int32 nElement, const AttributeList& /*rAttribs*/ ) { - if( (getCurrentElement() == XLS_TOKEN( autoFilter )) && (nElement == XLS_TOKEN( filterColumn )) ) - return new FilterColumnContext( *this, mrAutoFilter.createFilterColumn() ); + if( getCurrentElement() == XLS_TOKEN( autoFilter ) ) switch( nElement ) + { + case XLS_TOKEN( sortState ): + return new SortStateContext( *this, mrAutoFilter ); + case XLS_TOKEN( filterColumn ): + return new FilterColumnContext( *this, mrAutoFilter.createFilterColumn() ); + } return nullptr; } diff --git a/sc/source/filter/oox/tablebuffer.cxx b/sc/source/filter/oox/tablebuffer.cxx index 8c8526ce9a57..928870276276 100644 --- a/sc/source/filter/oox/tablebuffer.cxx +++ b/sc/source/filter/oox/tablebuffer.cxx @@ -136,7 +136,7 @@ void Table::applyAutoFilters() PropertySet aDocProps( getDocument() ); Reference< XDatabaseRanges > xDatabaseRanges( aDocProps.getAnyProperty( PROP_DatabaseRanges ), UNO_QUERY_THROW ); Reference< XDatabaseRange > xDatabaseRange( xDatabaseRanges->getByName( maDBRangeName ), UNO_QUERY ); - maAutoFilters.finalizeImport( xDatabaseRange ); + maAutoFilters.finalizeImport( xDatabaseRange, maModel.maRange.aStart.Tab() ); } catch( Exception& ) { commit 0cb32df8141eb49eb8b44f0523dfd81079abb2ac Author: Eike Rathke <[email protected]> AuthorDate: Tue Sep 8 21:18:30 2020 +0200 Commit: Andras Timar <[email protected]> CommitDate: Sat Sep 19 21:10:59 2020 +0200 Resolves: tdf#136364 treat svSep type with ocUnion as range type So for RPN sv...Ref(ocPush), sv...Ref(ocPush), svSep(ocUnion), sv...Ref(ocPush) another svSep(ocUnion) instead of svSep(ocSep) is appended. Regression from commit a6032ff5418ad66cc8fec10c636e32b124ee7864 CommitDate: Thu Oct 11 11:26:37 2018 +0200 Resolves: tdf#90698 catch list (1;2) of non-references as error that introduced a conditional check on operands and operators. Reviewed-on: https://gerrit.libreoffice.org/c/core/+/102276 Reviewed-by: Eike Rathke <[email protected]> Tested-by: Jenkins (cherry picked from commit e00e2be30436b636d93f8852bb6af44972638a7c) Change-Id: If5da3a781f24f891ff12c4a8f32a2ec92c6b4c8a Reviewed-on: https://gerrit.libreoffice.org/c/core/+/102279 Tested-by: Jenkins Reviewed-by: Adolfo Jayme Barrientos <[email protected]> diff --git a/formula/source/core/api/FormulaCompiler.cxx b/formula/source/core/api/FormulaCompiler.cxx index 03386af3cd07..16e58f9c8e71 100644 --- a/formula/source/core/api/FormulaCompiler.cxx +++ b/formula/source/core/api/FormulaCompiler.cxx @@ -308,7 +308,7 @@ bool isRangeResultOpCode( OpCode eOp ) @param bRight If bRPN==false, bRight==false means opcodes for left side are checked, bRight==true means opcodes for right side. If bRPN==true - it doesn't matter. + it doesn't matter except for the ocSep converted to ocUnion case. */ bool isPotentialRangeType( FormulaToken const * pToken, bool bRPN, bool bRight ) { @@ -329,6 +329,10 @@ bool isPotentialRangeType( FormulaToken const * pToken, bool bRPN, bool bRight ) case svExternalDoubleRef: case svExternalName: // could be range return true; + case svSep: + // A special case if a previous ocSep was converted to ocUnion it + // stays svSep instead of svByte. + return bRPN && !bRight && pToken->GetOpCode() == ocUnion; default: // Separators are not part of RPN and right opcodes need to be // other StackVar types or functions and thus svByte. @@ -1410,6 +1414,7 @@ void FormulaCompiler::Factor() && ((p = pCode[-1]) != nullptr) && isPotentialRangeType( p, true, true)) { pFacToken->NewOpCode( ocUnion, FormulaToken::PrivateAccess()); + // XXX NOTE: the token's eType is still svSep here! PutCode( pFacToken); } } commit b89fbdcba5226d8c640bfffa6b2eede3935635ce Author: Caolán McNamara <[email protected]> AuthorDate: Tue Sep 8 11:17:45 2020 +0100 Commit: Andras Timar <[email protected]> CommitDate: Sat Sep 19 21:10:52 2020 +0200 tdf#134477 add VclMessageType::Other to indicate image-less generic InfoBox Change-Id: I76e86bf4d82b33771ea2900517712be57ae7f03d Reviewed-on: https://gerrit.libreoffice.org/c/core/+/102130 Tested-by: Jenkins Reviewed-by: Adolfo Jayme Barrientos <[email protected]> diff --git a/basic/source/runtime/methods.cxx b/basic/source/runtime/methods.cxx index e2ed754122c6..30ad9dc10188 100644 --- a/basic/source/runtime/methods.cxx +++ b/basic/source/runtime/methods.cxx @@ -4402,7 +4402,7 @@ void SbRtl_MsgBox(StarBASIC *, SbxArray & rPar, bool) vcl::Window* pParentWin = Application::GetDefDialogParent(); weld::Widget* pParent = pParentWin ? pParentWin->GetFrameWeld() : nullptr; - VclMessageType eType = VclMessageType::Info; + VclMessageType eType = VclMessageType::Other; switch (nDialogType) { @@ -4416,7 +4416,6 @@ void SbRtl_MsgBox(StarBASIC *, SbxArray & rPar, bool) eType = VclMessageType::Warning; break; case 64: - default: eType = VclMessageType::Info; break; } diff --git a/include/vcl/vclenum.hxx b/include/vcl/vclenum.hxx index 3ae12c0373f7..9d4091be23c9 100644 --- a/include/vcl/vclenum.hxx +++ b/include/vcl/vclenum.hxx @@ -258,7 +258,8 @@ enum class VclMessageType Info, Warning, Question, - Error + Error, + Other }; enum class VclSizeGroupMode diff --git a/vcl/source/window/layout.cxx b/vcl/source/window/layout.cxx index b6c1b6ee65eb..52197b51992d 100644 --- a/vcl/source/window/layout.cxx +++ b/vcl/source/window/layout.cxx @@ -2071,11 +2071,13 @@ void MessageDialog::create_message_area() case VclMessageType::Error: m_pImage->SetImage(GetStandardErrorBoxImage()); break; + case VclMessageType::Other: + break; } m_pImage->set_grid_left_attach(0); m_pImage->set_grid_top_attach(0); m_pImage->set_valign(VclAlign::Start); - m_pImage->Show(); + m_pImage->Show(m_eMessageType != VclMessageType::Other); WinBits nWinStyle = WB_CLIPCHILDREN | WB_LEFT | WB_VCENTER | WB_NOLABEL | WB_NOTABSTOP; @@ -2227,6 +2229,9 @@ MessageDialog::MessageDialog(vcl::Window* pParent, case VclMessageType::Error: SetText(GetStandardErrorBoxText()); break; + case VclMessageType::Other: + SetText(Application::GetDisplayName()); + break; } } @@ -2296,6 +2301,8 @@ bool MessageDialog::set_property(const OString &rKey, const OUString &rValue) eMode = VclMessageType::Question; else if (rValue == "error") eMode = VclMessageType::Error; + else if (rValue == "other") + eMode = VclMessageType::Other; else { SAL_WARN("vcl.layout", "unknown message type mode" << rValue); diff --git a/vcl/unx/gtk3/gtk3gtkinst.cxx b/vcl/unx/gtk3/gtk3gtkinst.cxx index 8f50dcb7b260..f1e3a731bf15 100644 --- a/vcl/unx/gtk3/gtk3gtkinst.cxx +++ b/vcl/unx/gtk3/gtk3gtkinst.cxx @@ -5015,6 +5015,9 @@ static GtkMessageType VclToGtk(VclMessageType eType) case VclMessageType::Error: eRet = GTK_MESSAGE_ERROR; break; + case VclMessageType::Other: + eRet = GTK_MESSAGE_OTHER; + break; } return eRet; } commit c14802149fee73defbea3e2e64c09665900e8dc1 Author: Ezinne Nnamani <[email protected]> AuthorDate: Wed Sep 16 00:30:21 2020 +0100 Commit: Andras Timar <[email protected]> CommitDate: Sat Sep 19 20:44:15 2020 +0200 LOK: fix display of page number on status bar Somehow after 8cd1c1efb46cd98a597e3b6fbb6e3340 we got an empty string in the incoming statechanged: .uno:StatePageNumber= message instead to the Page x of y string. Without understanding the details we can safely ignore the extended tip in the LOK case, because we do not use extended tips in Online. Change-Id: I3b89f176c455b830c48d3c53db75e8ab81c7d9f9 diff --git a/sw/source/uibase/uiview/view2.cxx b/sw/source/uibase/uiview/view2.cxx index 2691214240e1..ce3ea308cedf 100644 --- a/sw/source/uibase/uiview/view2.cxx +++ b/sw/source/uibase/uiview/view2.cxx @@ -1382,11 +1382,14 @@ void SwView::StateStatusLine(SfxItemSet &rSet) OUString sTemp( GetPageStr( nPage, nLogPage, sDisplay ) ); const SfxStringItem aTmp( FN_STAT_PAGE, sTemp ); GetViewFrame()->GetBindings().SetState( aTmp ); - // Used to distinguish which tooltip to show - const SfxBoolItem bExtendedTooltip( FN_STAT_PAGE, !sDisplay.isEmpty() && + if (!comphelper::LibreOfficeKit::isActive()) + { + // Used to distinguish which tooltip to show + const SfxBoolItem bExtendedTooltip( FN_STAT_PAGE, !sDisplay.isEmpty() && OUString::number( nPage ) != sDisplay && nPage != nLogPage ); - GetViewFrame()->GetBindings().SetState( bExtendedTooltip ); + GetViewFrame()->GetBindings().SetState( bExtendedTooltip ); + } //if existing page number is not equal to old page number, send out this event. if (m_nOldPageNum != nLogPage ) { _______________________________________________ Libreoffice-commits mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
