sc/inc/compiler.hxx | 15 +- sc/inc/externalrefmgr.hxx | 7 + sc/inc/tokenstringcontext.hxx | 4 sc/qa/unit/ucalc_formula.cxx | 10 + sc/source/core/tool/compiler.cxx | 172 ++++++++++++----------------- sc/source/core/tool/token.cxx | 35 +++++ sc/source/core/tool/tokenstringcontext.cxx | 17 ++ sc/source/ui/docshell/externalrefmgr.cxx | 14 ++ 8 files changed, 168 insertions(+), 106 deletions(-)
New commits: commit 4ab50bff9d446a049f7704e2ce77b1907447bf3a Author: Kohei Yoshida <kohei.yosh...@collabora.com> Date: Mon Nov 18 15:26:05 2013 -0500 Handle external reference bits too. This is the last missing piece. Change-Id: Ib1dd18bb5a8d70c53722ac91e2340d05bbc7798a diff --git a/sc/inc/externalrefmgr.hxx b/sc/inc/externalrefmgr.hxx index c072cfd..d5b4d7f 100644 --- a/sc/inc/externalrefmgr.hxx +++ b/sc/inc/externalrefmgr.hxx @@ -586,6 +586,13 @@ public: * @return const OUString* external document URI. */ const OUString* getExternalFileName(sal_uInt16 nFileId, bool bForceOriginal = false); + + /** + * Get all cached external file names as an array. Array indices of the + * returned name array correspond with external file ID's. + */ + std::vector<OUString> getAllCachedExternalFileNames() const; + bool hasExternalFile(sal_uInt16 nFileId) const; bool hasExternalFile(const OUString& rFile) const; const SrcFileData* getExternalFileData(sal_uInt16 nFileId) const; diff --git a/sc/inc/tokenstringcontext.hxx b/sc/inc/tokenstringcontext.hxx index 7af90eb..85b61f7 100644 --- a/sc/inc/tokenstringcontext.hxx +++ b/sc/inc/tokenstringcontext.hxx @@ -27,6 +27,7 @@ namespace sc { struct SC_DLLPUBLIC TokenStringContext { typedef boost::unordered_map<sal_uInt16, OUString> IndexNameMapType; + typedef boost::unordered_map<size_t, std::vector<OUString> > IndexNamesMapType; typedef boost::unordered_map<SCTAB, IndexNameMapType> TabIndexMapType; formula::FormulaGrammar::Grammar meGram; @@ -39,6 +40,9 @@ struct SC_DLLPUBLIC TokenStringContext TabIndexMapType maSheetRangeNames; IndexNameMapType maNamedDBs; + std::vector<OUString> maExternalFileNames; + IndexNamesMapType maExternalCachedTabNames; + TokenStringContext( const ScDocument* pDoc, formula::FormulaGrammar::Grammar eGram ); }; diff --git a/sc/qa/unit/ucalc_formula.cxx b/sc/qa/unit/ucalc_formula.cxx index 7ae2554..6db441c 100644 --- a/sc/qa/unit/ucalc_formula.cxx +++ b/sc/qa/unit/ucalc_formula.cxx @@ -115,11 +115,21 @@ void Test::testFormulaCreateStringFromTokens() "SUM(sheetx;x;y;z)", // sheet local and global named ranges mixed "MAX(Table1)+MIN(Table2)*SUM(Table3)", // database ranges "{1;TRUE;3|FALSE;5;\"Text\"|;;}", // inline matrix + "SUM('file:///path/to/fake.file'#$Sheet.A1:B10)", }; boost::scoped_ptr<ScTokenArray> pArray; sc::TokenStringContext aCxt(m_pDoc, formula::FormulaGrammar::GRAM_ENGLISH); + + // Artificially add external refererence data after the context object is + // initialized. + aCxt.maExternalFileNames.push_back("file:///path/to/fake.file"); + std::vector<OUString> aExtTabNames; + aExtTabNames.push_back("Sheet"); + aCxt.maExternalCachedTabNames.insert( + sc::TokenStringContext::IndexNamesMapType::value_type(0, aExtTabNames)); + ScAddress aPos(0,0,0); for (size_t i = 0, n = SAL_N_ELEMENTS(aTests); i < n; ++i) diff --git a/sc/source/core/tool/token.cxx b/sc/source/core/tool/token.cxx index ff7294e..c5e4fd1 100644 --- a/sc/source/core/tool/token.cxx +++ b/sc/source/core/tool/token.cxx @@ -3181,7 +3181,40 @@ void appendTokenByType( sc::TokenStringContext& rCxt, OUStringBuffer& rBuf, cons { if (rToken.IsExternalRef()) { - // TODO : Implement this. + size_t nFileId = rToken.GetIndex(); + OUString aTabName = rToken.GetString().getString(); + if (nFileId >= rCxt.maExternalFileNames.size()) + // out of bound + return; + + OUString aFileName = rCxt.maExternalFileNames[nFileId]; + + switch (rToken.GetType()) + { + case svExternalName: + rBuf.append(rCxt.mpRefConv->makeExternalNameStr(aFileName, aTabName)); + break; + case svExternalSingleRef: + rCxt.mpRefConv->makeExternalRefStr( + rBuf, rPos, aFileName, aTabName, static_cast<const ScToken&>(rToken).GetSingleRef()); + break; + case svExternalDoubleRef: + { + sc::TokenStringContext::IndexNamesMapType::const_iterator it = + rCxt.maExternalCachedTabNames.find(nFileId); + + if (it == rCxt.maExternalCachedTabNames.end()) + return; + + rCxt.mpRefConv->makeExternalRefStr( + rBuf, rPos, aFileName, it->second, aTabName, static_cast<const ScToken&>(rToken).GetDoubleRef()); + } + break; + default: + // warning, not error, otherwise we may end up with a never + // ending message box loop if this was the cursor cell to be redrawn. + OSL_FAIL("appendTokenByType: unknown type of ocExternalRef"); + } return; } diff --git a/sc/source/core/tool/tokenstringcontext.cxx b/sc/source/core/tool/tokenstringcontext.cxx index e3aea0e..a68ae75 100644 --- a/sc/source/core/tool/tokenstringcontext.cxx +++ b/sc/source/core/tool/tokenstringcontext.cxx @@ -11,6 +11,7 @@ #include "compiler.hxx" #include "document.hxx" #include "dbdata.hxx" +#include "externalrefmgr.hxx" using namespace com::sun::star; @@ -86,6 +87,22 @@ TokenStringContext::TokenStringContext( const ScDocument* pDoc, formula::Formula maNamedDBs.insert(IndexNameMapType::value_type(rData.GetIndex(), rData.GetName())); } } + + // Fetch all relevant bits for external references. + if (pDoc->HasExternalRefManager()) + { + const ScExternalRefManager* pRefMgr = pDoc->GetExternalRefManager(); + maExternalFileNames = pRefMgr->getAllCachedExternalFileNames(); + for (size_t i = 0, n = maExternalFileNames.size(); i < n; ++i) + { + sal_uInt16 nFileId = static_cast<sal_uInt16>(i); + std::vector<OUString> aTabNames; + pRefMgr->getAllCachedTableNames(nFileId, aTabNames); + if (!aTabNames.empty()) + maExternalCachedTabNames.insert( + IndexNamesMapType::value_type(nFileId, aTabNames)); + } + } } } diff --git a/sc/source/ui/docshell/externalrefmgr.cxx b/sc/source/ui/docshell/externalrefmgr.cxx index c06490e..4646103 100644 --- a/sc/source/ui/docshell/externalrefmgr.cxx +++ b/sc/source/ui/docshell/externalrefmgr.cxx @@ -2480,6 +2480,20 @@ const OUString* ScExternalRefManager::getExternalFileName(sal_uInt16 nFileId, bo return &maSrcFiles[nFileId].maFileName; } +std::vector<OUString> ScExternalRefManager::getAllCachedExternalFileNames() const +{ + std::vector<OUString> aNames; + aNames.reserve(maSrcFiles.size()); + std::vector<SrcFileData>::const_iterator it = maSrcFiles.begin(), itEnd = maSrcFiles.end(); + for (; it != itEnd; ++it) + { + const SrcFileData& rData = *it; + aNames.push_back(rData.maFileName); + } + + return aNames; +} + bool ScExternalRefManager::hasExternalFile(sal_uInt16 nFileId) const { return nFileId < maSrcFiles.size(); commit 8615f7431e8db69d7000744a4b7cdcd3fa942861 Author: Kohei Yoshida <kohei.yosh...@collabora.com> Date: Mon Nov 18 14:39:13 2013 -0500 Avoid passing the external ref manager pointer to make it re-entrant. Change-Id: I67a0df1dcd0635ea82bfc397041a9c43dedbe75d diff --git a/sc/inc/compiler.hxx b/sc/inc/compiler.hxx index b6251f7..a8757e7 100644 --- a/sc/inc/compiler.hxx +++ b/sc/inc/compiler.hxx @@ -252,13 +252,14 @@ public: virtual OUString makeExternalNameStr( const OUString& rFile, const OUString& rName ) const = 0; - virtual void makeExternalRefStr( OUStringBuffer& rBuffer, const ScAddress& rPos, - sal_uInt16 nFileId, const OUString& rTabName, const ScSingleRefData& rRef, - ScExternalRefManager* pRefMgr ) const = 0; - - virtual void makeExternalRefStr( OUStringBuffer& rBuffer, const ScAddress& rPos, - sal_uInt16 nFileId, const OUString& rTabName, const ScComplexRefData& rRef, - ScExternalRefManager* pRefMgr ) const = 0; + virtual void makeExternalRefStr( + OUStringBuffer& rBuffer, const ScAddress& rPos, const OUString& rFileName, + const OUString& rTabName, const ScSingleRefData& rRef ) const = 0; + + virtual void makeExternalRefStr( + OUStringBuffer& rBuffer, const ScAddress& rPos, + const OUString& rFileName, const std::vector<OUString>& rTabNames, + const OUString& rTabName, const ScComplexRefData& rRef ) const = 0; enum SpecialSymbolType { diff --git a/sc/source/core/tool/compiler.cxx b/sc/source/core/tool/compiler.cxx index d3e696e..1668973 100644 --- a/sc/source/core/tool/compiler.cxx +++ b/sc/source/core/tool/compiler.cxx @@ -821,22 +821,17 @@ struct ConventionOOO_A1 : public Convention_A1 } bool makeExternalSingleRefStr( - OUStringBuffer& rBuffer, sal_uInt16 nFileId, - const OUString& rTabName, const ScSingleRefData& rRef, const ScAddress& rPos, - ScExternalRefManager* pRefMgr, bool bDisplayTabName, bool bEncodeUrl ) const + OUStringBuffer& rBuffer, const OUString& rFileName, const OUString& rTabName, + const ScSingleRefData& rRef, const ScAddress& rPos, bool bDisplayTabName, bool bEncodeUrl ) const { ScAddress aAbsRef = rRef.toAbs(rPos); if (bDisplayTabName) { OUString aFile; - const OUString* p = pRefMgr->getExternalFileName(nFileId); - if (p) - { - if (bEncodeUrl) - aFile = *p; - else - aFile = INetURLObject::decode(*p, INET_HEX_ESCAPE, INetURLObject::DECODE_UNAMBIGUOUS); - } + if (bEncodeUrl) + aFile = rFileName; + else + aFile = INetURLObject::decode(rFileName, INET_HEX_ESCAPE, INetURLObject::DECODE_UNAMBIGUOUS); rBuffer.append("'" + aFile.replaceAll("'", "''") + "'#"); @@ -857,29 +852,30 @@ struct ConventionOOO_A1 : public Convention_A1 return true; } - void makeExternalRefStrImpl( OUStringBuffer& rBuffer, const ScAddress& rPos, - sal_uInt16 nFileId, const OUString& rTabName, const ScSingleRefData& rRef, - ScExternalRefManager* pRefMgr, bool bODF ) const + void makeExternalRefStrImpl( + OUStringBuffer& rBuffer, const ScAddress& rPos, const OUString& rFileName, + const OUString& rTabName, const ScSingleRefData& rRef, bool bODF ) const { if (bODF) rBuffer.append( '['); bool bEncodeUrl = bODF; - makeExternalSingleRefStr(rBuffer, nFileId, rTabName, rRef, rPos, pRefMgr, true, bEncodeUrl); + makeExternalSingleRefStr(rBuffer, rFileName, rTabName, rRef, rPos, true, bEncodeUrl); if (bODF) rBuffer.append( ']'); } - virtual void makeExternalRefStr( OUStringBuffer& rBuffer, const ScAddress& rPos, - sal_uInt16 nFileId, const OUString& rTabName, const ScSingleRefData& rRef, - ScExternalRefManager* pRefMgr ) const + virtual void makeExternalRefStr( + OUStringBuffer& rBuffer, const ScAddress& rPos, const OUString& rFileName, + const OUString& rTabName, const ScSingleRefData& rRef ) const { - makeExternalRefStrImpl(rBuffer, rPos, nFileId, rTabName, rRef, pRefMgr, false); + makeExternalRefStrImpl(rBuffer, rPos, rFileName, rTabName, rRef, false); } - void makeExternalRefStrImpl( OUStringBuffer& rBuffer, const ScAddress& rPos, - sal_uInt16 nFileId, const OUString& rTabName, const ScComplexRefData& rRef, - ScExternalRefManager* pRefMgr, bool bODF ) const + void makeExternalRefStrImpl( + OUStringBuffer& rBuffer, const ScAddress& rPos, const OUString& rFileName, + const std::vector<OUString>& rTabNames, const OUString& rTabName, + const ScComplexRefData& rRef, bool bODF ) const { ScRange aAbsRange = rRef.toAbs(rPos); @@ -890,7 +886,7 @@ struct ConventionOOO_A1 : public Convention_A1 do { - if (!makeExternalSingleRefStr(rBuffer, nFileId, rTabName, rRef.Ref1, rPos, pRefMgr, true, bEncodeUrl)) + if (!makeExternalSingleRefStr(rBuffer, rFileName, rTabName, rRef.Ref1, rPos, true, bEncodeUrl)) break; rBuffer.append(':'); @@ -900,14 +896,7 @@ struct ConventionOOO_A1 : public Convention_A1 if (bDisplayTabName) { // Get the name of the last table. - vector<OUString> aTabNames; - pRefMgr->getAllCachedTableNames(nFileId, aTabNames); - if (aTabNames.empty()) - { - OSL_TRACE( "ConventionOOO_A1::makeExternalRefStrImpl: no sheet names for document ID %d", nFileId); - } - - if (!lcl_getLastTabName(aLastTabName, rTabName, aTabNames, aAbsRange)) + if (!lcl_getLastTabName(aLastTabName, rTabName, rTabNames, aAbsRange)) { OSL_FAIL( "ConventionOOO_A1::makeExternalRefStrImpl: sheet name not found"); // aLastTabName contains #REF!, proceed. @@ -915,18 +904,20 @@ struct ConventionOOO_A1 : public Convention_A1 } else if (bODF) rBuffer.append( '.'); // need at least the sheet separator in ODF - makeExternalSingleRefStr( rBuffer, nFileId, aLastTabName, - rRef.Ref2, rPos, pRefMgr, bDisplayTabName, bEncodeUrl); + makeExternalSingleRefStr( + rBuffer, rFileName, aLastTabName, rRef.Ref2, rPos, bDisplayTabName, bEncodeUrl); } while (0); + if (bODF) rBuffer.append( ']'); } - virtual void makeExternalRefStr( OUStringBuffer& rBuffer, const ScAddress& rPos, - sal_uInt16 nFileId, const OUString& rTabName, const ScComplexRefData& rRef, - ScExternalRefManager* pRefMgr ) const + virtual void makeExternalRefStr( + OUStringBuffer& rBuffer, const ScAddress& rPos, const OUString& rFileName, + const std::vector<OUString>& rTabNames, const OUString& rTabName, + const ScComplexRefData& rRef ) const { - makeExternalRefStrImpl(rBuffer, rPos, nFileId, rTabName, rRef, pRefMgr, false); + makeExternalRefStrImpl(rBuffer, rPos, rFileName, rTabNames, rTabName, rRef, false); } }; @@ -975,18 +966,19 @@ struct ConventionOOO_A1_ODF : public ConventionOOO_A1 return lcl_makeExternalNameStr( rFile, rName, '#', true); } - virtual void makeExternalRefStr( OUStringBuffer& rBuffer, const ScAddress& rPos, - sal_uInt16 nFileId, const OUString& rTabName, const ScSingleRefData& rRef, - ScExternalRefManager* pRefMgr ) const + virtual void makeExternalRefStr( + OUStringBuffer& rBuffer, const ScAddress& rPos, const OUString& rFileName, + const OUString& rTabName, const ScSingleRefData& rRef ) const { - makeExternalRefStrImpl(rBuffer, rPos, nFileId, rTabName, rRef, pRefMgr, true); + makeExternalRefStrImpl(rBuffer, rPos, rFileName, rTabName, rRef, true); } - virtual void makeExternalRefStr( OUStringBuffer& rBuffer, const ScAddress& rPos, - sal_uInt16 nFileId, const OUString& rTabName, const ScComplexRefData& rRef, - ScExternalRefManager* pRefMgr ) const + virtual void makeExternalRefStr( + OUStringBuffer& rBuffer, const ScAddress& rPos, const OUString& rFileName, + const std::vector<OUString>& rTabNames, + const OUString& rTabName, const ScComplexRefData& rRef ) const { - makeExternalRefStrImpl(rBuffer, rPos, nFileId, rTabName, rRef, pRefMgr, true); + makeExternalRefStrImpl(rBuffer, rPos, rFileName, rTabNames, rTabName, rRef, true); } }; @@ -1277,9 +1269,9 @@ struct ConventionXL_A1 : public Convention_A1, public ConventionXL return ConventionXL::makeExternalNameStr(rFile, rName); } - virtual void makeExternalRefStr( OUStringBuffer& rBuffer, const ScAddress& rPos, - sal_uInt16 nFileId, const OUString& rTabName, const ScSingleRefData& rRef, - ScExternalRefManager* pRefMgr ) const + virtual void makeExternalRefStr( + OUStringBuffer& rBuffer, const ScAddress& rPos, const OUString& rFileName, + const OUString& rTabName, const ScSingleRefData& rRef ) const { // ['file:///path/to/file/filename.xls']'Sheet Name'!$A$1 // This is a little different from the format Excel uses, as Excel @@ -1287,34 +1279,22 @@ struct ConventionXL_A1 : public Convention_A1, public ConventionXL // whole file path with [] because the file name can contain any // characters. - const OUString* pFullName = pRefMgr->getExternalFileName(nFileId); - if (!pFullName) - return; - - ConventionXL::makeExternalDocStr(rBuffer, *pFullName, false); + ConventionXL::makeExternalDocStr(rBuffer, rFileName, false); ScRangeStringConverter::AppendTableName(rBuffer, rTabName); rBuffer.append('!'); makeSingleCellStr(rBuffer, rRef, rRef.toAbs(rPos)); } - virtual void makeExternalRefStr( OUStringBuffer& rBuffer, const ScAddress& rPos, - sal_uInt16 nFileId, const OUString& rTabName, const ScComplexRefData& rRef, - ScExternalRefManager* pRefMgr ) const + virtual void makeExternalRefStr( + OUStringBuffer& rBuffer, const ScAddress& rPos, const OUString& rFileName, + const std::vector<OUString>& rTabNames, const OUString& rTabName, + const ScComplexRefData& rRef ) const { - const OUString* pFullName = pRefMgr->getExternalFileName(nFileId); - if (!pFullName) - return; - - vector<OUString> aTabNames; - pRefMgr->getAllCachedTableNames(nFileId, aTabNames); - if (aTabNames.empty()) - return; - ScRange aAbsRef = rRef.toAbs(rPos); - ConventionXL::makeExternalDocStr(rBuffer, *pFullName, false); - ConventionXL::makeExternalTabNameRange(rBuffer, rTabName, aTabNames, aAbsRef); + ConventionXL::makeExternalDocStr(rBuffer, rFileName, false); + ConventionXL::makeExternalTabNameRange(rBuffer, rTabName, rTabNames, aAbsRef); rBuffer.append('!'); makeSingleCellStr(rBuffer, rRef.Ref1, aAbsRef.aStart); @@ -1470,9 +1450,9 @@ struct ConventionXL_R1C1 : public ScCompiler::Convention, public ConventionXL return ConventionXL::makeExternalNameStr(rFile, rName); } - virtual void makeExternalRefStr( OUStringBuffer& rBuffer, const ScAddress& rPos, - sal_uInt16 nFileId, const OUString& rTabName, const ScSingleRefData& rRef, - ScExternalRefManager* pRefMgr ) const + virtual void makeExternalRefStr( + OUStringBuffer& rBuffer, const ScAddress& rPos, const OUString& rFileName, + const OUString& rTabName, const ScSingleRefData& rRef ) const { // ['file:///path/to/file/filename.xls']'Sheet Name'!$A$1 // This is a little different from the format Excel uses, as Excel @@ -1480,13 +1460,8 @@ struct ConventionXL_R1C1 : public ScCompiler::Convention, public ConventionXL // whole file path with [] because the file name can contain any // characters. - const OUString* pFullName = pRefMgr->getExternalFileName(nFileId); - if (!pFullName) - return; - ScAddress aAbsRef = rRef.toAbs(rPos); - - ConventionXL::makeExternalDocStr(rBuffer, *pFullName, false); + ConventionXL::makeExternalDocStr(rBuffer, rFileName, false); ScRangeStringConverter::AppendTableName(rBuffer, rTabName); rBuffer.append('!'); @@ -1494,23 +1469,15 @@ struct ConventionXL_R1C1 : public ScCompiler::Convention, public ConventionXL r1c1_add_col(rBuffer, rRef, aAbsRef); } - virtual void makeExternalRefStr( OUStringBuffer& rBuffer, const ScAddress& rPos, - sal_uInt16 nFileId, const OUString& rTabName, const ScComplexRefData& rRef, - ScExternalRefManager* pRefMgr ) const + virtual void makeExternalRefStr( + OUStringBuffer& rBuffer, const ScAddress& rPos, const OUString& rFileName, + const std::vector<OUString>& rTabNames, const OUString& rTabName, + const ScComplexRefData& rRef ) const { - const OUString* pFullName = pRefMgr->getExternalFileName(nFileId); - if (!pFullName) - return; - - vector<OUString> aTabNames; - pRefMgr->getAllCachedTableNames(nFileId, aTabNames); - if (aTabNames.empty()) - return; - ScRange aAbsRef = rRef.toAbs(rPos); - ConventionXL::makeExternalDocStr(rBuffer, *pFullName, false); - ConventionXL::makeExternalTabNameRange(rBuffer, rTabName, aTabNames, aAbsRef); + ConventionXL::makeExternalDocStr(rBuffer, rFileName, false); + ConventionXL::makeExternalTabNameRange(rBuffer, rTabName, rTabNames, aAbsRef); rBuffer.append('!'); if (!ValidCol(aAbsRef.aEnd.Col()) || !ValidRow(aAbsRef.aEnd.Row())) @@ -4083,23 +4050,32 @@ void ScCompiler::CreateStringFromExternal(OUStringBuffer& rBuffer, FormulaToken* { FormulaToken* t = pTokenP; ScExternalRefManager* pRefMgr = pDoc->GetExternalRefManager(); + const OUString* pFileName = pRefMgr->getExternalFileName(t->GetIndex()); + if (!pFileName) + return; + switch (t->GetType()) { case svExternalName: - { - const OUString *pStr = pRefMgr->getExternalFileName(t->GetIndex()); - OUString aFileName = pStr ? *pStr : ScGlobal::GetRscString(STR_NO_NAME_REF); - rBuffer.append(pConv->makeExternalNameStr( aFileName, t->GetString().getString())); - } + rBuffer.append(pConv->makeExternalNameStr(*pFileName, t->GetString().getString())); break; case svExternalSingleRef: pConv->makeExternalRefStr( - rBuffer, GetPos(), t->GetIndex(), t->GetString().getString(), static_cast<ScToken*>(t)->GetSingleRef(), pRefMgr); + rBuffer, GetPos(), *pFileName, t->GetString().getString(), + static_cast<ScToken*>(t)->GetSingleRef()); break; case svExternalDoubleRef: + { + vector<OUString> aTabNames; + pRefMgr->getAllCachedTableNames(t->GetIndex(), aTabNames); + if (aTabNames.empty()) + return; + pConv->makeExternalRefStr( - rBuffer, GetPos(), t->GetIndex(), t->GetString().getString(), static_cast<ScToken*>(t)->GetDoubleRef(), pRefMgr); - break; + rBuffer, GetPos(), *pFileName, aTabNames, t->GetString().getString(), + static_cast<ScToken*>(t)->GetDoubleRef()); + } + break; default: // warning, not error, otherwise we may end up with a never // ending message box loop if this was the cursor cell to be redrawn. _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits