chart2/source/model/main/ChartModel.cxx | 9 + chart2/source/model/main/ChartModel_Persistence.cxx | 34 ++++ sc/inc/PivotChartDataProvider.hxx | 1 sc/source/ui/drawfunc/fuins2.cxx | 88 +++++++----- sc/source/ui/unoobj/PivotChartDataProvider.cxx | 145 ++++++++++++++------ 5 files changed, 197 insertions(+), 80 deletions(-)
New commits: commit 376fc4e8f43f7b1e9383cb12c4491fb1dd9ce945 Author: Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk> Date: Wed Mar 1 22:40:09 2017 +0100 pivotcharts: collect and set the number format for the data Change-Id: I5eb2e9b9cb5abb798b99a23cfa16d790ff62ff08 diff --git a/sc/inc/PivotChartDataProvider.hxx b/sc/inc/PivotChartDataProvider.hxx index d1139a5..1c2df5a 100644 --- a/sc/inc/PivotChartDataProvider.hxx +++ b/sc/inc/PivotChartDataProvider.hxx @@ -150,6 +150,7 @@ private: std::vector<std::vector<PivotChartItem>> m_aCategoriesColumnOrientation; std::vector<std::vector<PivotChartItem>> m_aCategoriesRowOrientation; std::vector<std::vector<PivotChartItem>> m_aLabels; + std::vector<std::vector<PivotChartItem>> m_aDataRowVector; std::vector<css::uno::Reference<css::util::XModifyListener>> m_aValueListeners; }; diff --git a/sc/source/ui/unoobj/PivotChartDataProvider.cxx b/sc/source/ui/unoobj/PivotChartDataProvider.cxx index 8d9b3e1..37becaf 100644 --- a/sc/source/ui/unoobj/PivotChartDataProvider.cxx +++ b/sc/source/ui/unoobj/PivotChartDataProvider.cxx @@ -41,6 +41,8 @@ #include <com/sun/star/chart/ChartDataChangeEvent.hpp> +#include <unordered_map> + using namespace css; namespace sc @@ -244,9 +246,35 @@ uno::Reference<chart2::data::XDataSource> PivotChartDataProvider::createPivotCha void PivotChartDataProvider::collectPivotTableData(ScDPObject* pDPObject) { + uno::Reference<sheet::XDataPilotResults> xDPResults(pDPObject->GetSource(), uno::UNO_QUERY); + uno::Sequence<uno::Sequence<sheet::DataResult>> xDataResultsSequence = xDPResults->getResults(); + + double fNan; + rtl::math::setNan(&fNan); + + for (uno::Sequence<sheet::DataResult> const & xDataResults : xDataResultsSequence) + { + size_t nIndex = 0; + for (sheet::DataResult const & rDataResult : xDataResults) + { + if (rDataResult.Flags == 0 || rDataResult.Flags & css::sheet::DataResultFlags::HASDATA) + { + if (nIndex >= m_aDataRowVector.size()) + m_aDataRowVector.resize(nIndex + 1); + m_aDataRowVector[nIndex].push_back(PivotChartItem(rDataResult.Flags ? rDataResult.Value : fNan, 0)); + } + nIndex++; + } + } + uno::Reference<sheet::XDimensionsSupplier> xDimensionsSupplier(pDPObject->GetSource()); uno::Reference<container::XIndexAccess> xDims = new ScNameToIndexAccess(xDimensionsSupplier->getDimensions()); + std::unordered_map<OUString, sal_Int32, OUStringHash> aDataFieldNumberFormatMap; + std::vector<OUString> aDataFieldNamesVectors; + + sheet::DataPilotFieldOrientation eDataFieldOrientation = sheet::DataPilotFieldOrientation_HIDDEN; + for (long nDim = 0; nDim < xDims->getCount(); nDim++) { uno::Reference<uno::XInterface> xDim = ScUnoHelpFunctions::AnyToInterface(xDims->getByIndex(nDim)); @@ -261,11 +289,9 @@ void PivotChartDataProvider::collectPivotTableData(ScDPObject* pDPObject) ScUnoHelpFunctions::GetEnumProperty(xDimProp, SC_UNO_DP_ORIENTATION, sheet::DataPilotFieldOrientation_HIDDEN)); - long nDimPos = ScUnoHelpFunctions::GetLongProperty(xDimProp, SC_UNO_DP_POSITION); - sal_Int32 nNumberFormat = ScUnoHelpFunctions::GetLongProperty(xDimProp, SC_UNO_DP_NUMBERFO); - if (eDimOrient == sheet::DataPilotFieldOrientation_HIDDEN) continue; + uno::Reference<container::XIndexAccess> xHiers = new ScNameToIndexAccess(xDimSupp->getHierarchies()); long nHierarchy = ScUnoHelpFunctions::GetLongProperty(xDimProp, SC_UNO_DP_USEDHIERARCHY); if (nHierarchy >= xHiers->getCount()) @@ -286,6 +312,10 @@ void PivotChartDataProvider::collectPivotTableData(ScDPObject* pDPObject) uno::Reference<container::XNamed> xLevName(xLevel, uno::UNO_QUERY); uno::Reference<sheet::XDataPilotMemberResults> xLevRes(xLevel, uno::UNO_QUERY ); + bool bIsDataLayout = ScUnoHelpFunctions::GetBoolProperty(xDimProp, SC_UNO_DP_ISDATALAYOUT); + long nDimPos = ScUnoHelpFunctions::GetLongProperty(xDimProp, SC_UNO_DP_POSITION); + sal_Int32 nNumberFormat = ScUnoHelpFunctions::GetLongProperty(xDimProp, SC_UNO_DP_NUMBERFO); + if (xLevName.is() && xLevRes.is()) { switch (eDimOrient) @@ -294,7 +324,8 @@ void PivotChartDataProvider::collectPivotTableData(ScDPObject* pDPObject) { uno::Sequence<sheet::MemberResult> aSeq = xLevRes->getResults(); size_t i = 0; - OUString sValue; + OUString sCaption; + OUString sName; m_aLabels.resize(aSeq.getLength()); for (sheet::MemberResult & rMember : aSeq) { @@ -302,12 +333,20 @@ void PivotChartDataProvider::collectPivotTableData(ScDPObject* pDPObject) rMember.Flags & sheet::MemberResultFlags::CONTINUE) { if (!(rMember.Flags & sheet::MemberResultFlags::CONTINUE)) - sValue = rMember.Caption; + { + sCaption = rMember.Caption; + sName = rMember.Name; + } if (size_t(nDimPos) >= m_aLabels[i].size()) m_aLabels[i].resize(nDimPos + 1); - m_aLabels[i][nDimPos] = PivotChartItem(sValue); + m_aLabels[i][nDimPos] = PivotChartItem(sCaption); + if (bIsDataLayout) + { + aDataFieldNamesVectors.push_back(sName); + eDataFieldOrientation = sheet::DataPilotFieldOrientation_COLUMN; + } i++; } } @@ -318,6 +357,7 @@ void PivotChartDataProvider::collectPivotTableData(ScDPObject* pDPObject) uno::Sequence<sheet::MemberResult> aSeq = xLevRes->getResults(); m_aCategoriesRowOrientation.resize(aSeq.getLength()); size_t i = 0; + OUString sName; for (sheet::MemberResult & rMember : aSeq) { if (rMember.Flags & sheet::MemberResultFlags::HASMEMBER || @@ -326,17 +366,24 @@ void PivotChartDataProvider::collectPivotTableData(ScDPObject* pDPObject) std::unique_ptr<PivotChartItem> pItem; double fValue = rMember.Value; - if (rtl::math::isNan(fValue)) { - OUString sValue; - if (!(rMember.Flags & sheet::MemberResultFlags::CONTINUE)) - sValue = rMember.Caption; - pItem.reset(new PivotChartItem(sValue)); + if (rMember.Flags & sheet::MemberResultFlags::CONTINUE) + { + pItem.reset(new PivotChartItem("")); + } + else + { + sName = rMember.Name; + pItem.reset(new PivotChartItem(rMember.Caption)); + } } else { - pItem.reset(new PivotChartItem(fValue, nNumberFormat)); + if (rMember.Flags & sheet::MemberResultFlags::CONTINUE) + pItem.reset(new PivotChartItem()); + else + pItem.reset(new PivotChartItem(fValue, nNumberFormat)); } if (size_t(nDimPos) >= m_aCategoriesColumnOrientation.size()) @@ -347,17 +394,56 @@ void PivotChartDataProvider::collectPivotTableData(ScDPObject* pDPObject) m_aCategoriesRowOrientation[i].resize(nDimPos + 1); m_aCategoriesRowOrientation[i][nDimPos] = *pItem; + if (bIsDataLayout) + { + aDataFieldNamesVectors.push_back(sName); + eDataFieldOrientation = sheet::DataPilotFieldOrientation_ROW; + } i++; } } break; } + case sheet::DataPilotFieldOrientation_DATA: + { + aDataFieldNumberFormatMap[xLevName->getName()] = nNumberFormat; + } default: break; } } } } + + // Apply number format to the data + if (eDataFieldOrientation == sheet::DataPilotFieldOrientation_ROW) + { + for (std::vector<PivotChartItem> & rDataRow : m_aDataRowVector) + { + size_t i = 0; + for (PivotChartItem & rItem : rDataRow) + { + OUString sName = aDataFieldNamesVectors[i]; + sal_Int32 nNumberFormat = aDataFieldNumberFormatMap[sName]; + rItem.m_nNumberFormat = nNumberFormat; + i++; + } + } + } + else if (eDataFieldOrientation == sheet::DataPilotFieldOrientation_COLUMN) + { + size_t i = 0; + for (std::vector<PivotChartItem> & rDataRow : m_aDataRowVector) + { + OUString sName = aDataFieldNamesVectors[i]; + sal_Int32 nNumberFormat = aDataFieldNumberFormatMap[sName]; + for (PivotChartItem & rItem : rDataRow) + { + rItem.m_nNumberFormat = nNumberFormat; + } + i++; + } + } } uno::Reference<chart2::data::XDataSource> PivotChartDataProvider::createPivotChartDataSource(OUString const & aRangeRepresentation) @@ -365,6 +451,7 @@ uno::Reference<chart2::data::XDataSource> PivotChartDataProvider::createPivotCha m_aCategoriesColumnOrientation.clear(); m_aCategoriesRowOrientation.clear(); m_aLabels.clear(); + m_aDataRowVector.clear(); uno::Reference<chart2::data::XDataSource> xDataSource; std::vector<uno::Reference<chart2::data::XLabeledDataSequence>> aLabeledSequences; @@ -378,8 +465,6 @@ uno::Reference<chart2::data::XDataSource> PivotChartDataProvider::createPivotCha collectPivotTableData(pDPObject); - uno::Reference<sheet::XDataPilotResults> xDPResults(pDPObject->GetSource(), uno::UNO_QUERY); - { std::vector<PivotChartItem> aFirstCategories; std::copy (m_aCategoriesColumnOrientation[0].begin(), @@ -392,35 +477,11 @@ uno::Reference<chart2::data::XDataSource> PivotChartDataProvider::createPivotCha } { - uno::Sequence<uno::Sequence<sheet::DataResult>> xDataResultsSequence = xDPResults->getResults(); - - std::vector<std::vector<PivotChartItem>> aDataRowVector; - - double fNan; - rtl::math::setNan(&fNan); - - for (uno::Sequence<sheet::DataResult> const & xDataResults : xDataResultsSequence) - { - size_t nIndex = 0; - for (sheet::DataResult const & rDataResult : xDataResults) - { - if (rDataResult.Flags == 0 || rDataResult.Flags & css::sheet::DataResultFlags::HASDATA) - { - - if (nIndex >= aDataRowVector.size()) - aDataRowVector.resize(nIndex + 1); - aDataRowVector[nIndex].push_back(PivotChartItem(rDataResult.Flags ? rDataResult.Value : fNan, 0)); - } - nIndex++; - } - } - int i = 0; - - for (std::vector<PivotChartItem> const & rDataRow : aDataRowVector) + for (std::vector<PivotChartItem> const & rRowOfData : m_aDataRowVector) { - OUString aValuesId = "Data " + OUString::number(i); - OUString aLabelsId = "Label " + OUString::number(i); + OUString aValuesId = "Data " + OUString::number(i + 1); + OUString aLabelsId = "Label " + OUString::number(i + 1); OUString aLabel; bool bFirst = true; @@ -440,7 +501,7 @@ uno::Reference<chart2::data::XDataSource> PivotChartDataProvider::createPivotCha std::vector<PivotChartItem> aLabelVector { PivotChartItem(aLabel) }; uno::Reference<chart2::data::XLabeledDataSequence> xResult = createLabeledDataSequence(xContext); - setLabeledDataSequence(xResult, "values-y", aValuesId, rDataRow, + setLabeledDataSequence(xResult, "values-y", aValuesId, rRowOfData, "values-y", aLabelsId, aLabelVector); aLabeledSequences.push_back(xResult); i++; commit 88fb88bccb8d71c7beb8fd7c0d2b685e75aecfe9 Author: Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk> Date: Wed Mar 1 22:36:41 2017 +0100 pivotcharts: modify the pivot chart when the pivot table changes Change-Id: I971e8bf90aaf2363adf3aa530b2cc8fd02abd273 diff --git a/chart2/source/model/main/ChartModel.cxx b/chart2/source/model/main/ChartModel.cxx index fe8ada3..a8dae67 100644 --- a/chart2/source/model/main/ChartModel.cxx +++ b/chart2/source/model/main/ChartModel.cxx @@ -63,6 +63,7 @@ #include <com/sun/star/drawing/XShapes.hpp> #include <com/sun/star/document/DocumentProperties.hpp> #include <com/sun/star/chart2/XTimeBased.hpp> +#include <com/sun/star/util/XModifyBroadcaster.hpp> #include <svl/zforlist.hxx> @@ -746,7 +747,7 @@ Reference< chart2::data::XDataSource > ChartModel::impl_createDefaultData() xIni->initialize(aArgs); } //create data - uno::Sequence< beans::PropertyValue > aArgs( 4 ); + uno::Sequence<beans::PropertyValue> aArgs(4); aArgs[0] = beans::PropertyValue( "CellRangeRepresentation", -1, uno::Any( OUString("all") ), beans::PropertyState_DIRECT_VALUE ); @@ -818,6 +819,12 @@ void SAL_CALL ChartModel::attachDataProvider( const uno::Reference< chart2::data } } + uno::Reference<util::XModifyBroadcaster> xModifyBroadcaster(xDataProvider, uno::UNO_QUERY); + if (xModifyBroadcaster.is()) + { + xModifyBroadcaster->addModifyListener(this); + } + m_xDataProvider.set( xDataProvider ); m_xInternalDataProvider.clear(); diff --git a/chart2/source/model/main/ChartModel_Persistence.cxx b/chart2/source/model/main/ChartModel_Persistence.cxx index c19aeaf..da7ba9c 100644 --- a/chart2/source/model/main/ChartModel_Persistence.cxx +++ b/chart2/source/model/main/ChartModel_Persistence.cxx @@ -22,8 +22,10 @@ #include "macros.hxx" #include "ChartViewHelper.hxx" #include "ChartModelHelper.hxx" +#include "DataSourceHelper.hxx" #include "AxisHelper.hxx" #include "ThreeDHelper.hxx" +#include "DiagramHelper.hxx" #include <com/sun/star/chart2/LegendPosition.hpp> #include <com/sun/star/container/XNameAccess.hpp> @@ -49,6 +51,7 @@ #include <vcl/cvtgrf.hxx> #include <comphelper/processfactory.hxx> #include <comphelper/storagehelper.hxx> +#include <comphelper/sequence.hxx> #include <vcl/svapp.hxx> #include <vcl/settings.hxx> @@ -704,10 +707,35 @@ void SAL_CALL ChartModel::removeModifyListener( } // util::XModifyListener -void SAL_CALL ChartModel::modified( const lang::EventObject& ) +void SAL_CALL ChartModel::modified( const lang::EventObject& rEvenObject) { - if( m_nInLoad == 0 ) - setModified( true ); + uno::Reference<chart2::data::XDataProvider> xDataProvider(rEvenObject.Source, uno::UNO_QUERY); + if (xDataProvider.is()) + { + lockControllers(); + Reference<frame::XModel> xModel(this); + try + { + uno::Sequence<beans::PropertyValue> aArguments = + DataSourceHelper::createArguments("PivotChart", uno::Sequence<sal_Int32>(), true, true, true); + + Reference<chart2::data::XDataSource> xDataSource(xDataProvider->createDataSource(aArguments)); + Reference<lang::XMultiServiceFactory> xFactory(getChartTypeManager(), uno::UNO_QUERY); + Reference<chart2::XDiagram> xDiagram(getFirstDiagram()); + + DiagramHelper::tTemplateWithServiceName aTemplateAndService = DiagramHelper::getTemplateForDiagram(xDiagram, xFactory); + css::uno::Reference<css::chart2::XChartTypeTemplate> xChartTypeTemplate(aTemplateAndService.first); + xChartTypeTemplate->changeDiagramData(xDiagram, xDataSource, aArguments); + } + catch (const uno::Exception & ex) + { + ASSERT_EXCEPTION(ex); + } + unlockControllers(); + } + + if (m_nInLoad == 0) + setModified(true); } // lang::XEventListener (base of util::XModifyListener) commit 1f6e6b2faa9ea798fe553449d9d96241c6f58ad2 Author: Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk> Date: Tue Feb 28 11:04:53 2017 +0100 pivotcharts: insert a pivot chart if cursor is in a pivot table Change-Id: I9fbde8e26cf10e68ff7a886e982b7ac1e5d7ef70 diff --git a/sc/source/ui/drawfunc/fuins2.cxx b/sc/source/ui/drawfunc/fuins2.cxx index d2d2382..5936ddb 100644 --- a/sc/source/ui/drawfunc/fuins2.cxx +++ b/sc/source/ui/drawfunc/fuins2.cxx @@ -63,8 +63,7 @@ #include <com/sun/star/chart/ChartDataRowSource.hpp> #include <cppuhelper/bootstrap.hxx> -using namespace ::com::sun::star; - +#include "PivotChartDataProvider.hxx" #include "chart2uno.hxx" #include "fuinsert.hxx" #include "tabvwsh.hxx" @@ -81,16 +80,20 @@ using namespace ::com::sun::star; #include "gridwin.hxx" #include <memory> -namespace { +using namespace css; + +namespace +{ -void lcl_ChartInit( const uno::Reference < embed::XEmbeddedObject >& xObj, ScViewData* pViewData, - const OUString& rRangeParam ) +void lcl_ChartInit(const uno::Reference <embed::XEmbeddedObject>& xObj, ScViewData* pViewData, + const OUString& rRangeParam, bool bRangeIsPivotTable) { ScDocShell* pDocShell = pViewData->GetDocShell(); ScDocument& rScDoc = pDocShell->GetDocument(); - OUString aRangeString( rRangeParam ); - if ( aRangeString.isEmpty() ) + OUString aRangeString(rRangeParam); + + if (aRangeString.isEmpty() && !bRangeIsPivotTable) { SCCOL nCol1 = 0; SCROW nRow1 = 0; @@ -118,7 +121,7 @@ void lcl_ChartInit( const uno::Reference < embed::XEmbeddedObject >& xObj, ScVie } } - if ( !aRangeString.isEmpty() ) + if (!aRangeString.isEmpty()) { // connect to Calc data (if no range string, leave chart alone, with its own data) @@ -129,8 +132,13 @@ void lcl_ChartInit( const uno::Reference < embed::XEmbeddedObject >& xObj, ScVie OSL_ASSERT( xReceiver.is()); if( xReceiver.is() ) { - uno::Reference< chart2::data::XDataProvider > xDataProvider = new ScChart2DataProvider( &rScDoc ); - xReceiver->attachDataProvider( xDataProvider ); + uno::Reference<chart2::data::XDataProvider> xDataProvider; + if (bRangeIsPivotTable) + xDataProvider.set(new sc::PivotChartDataProvider(&rScDoc, aRangeString)); + else + xDataProvider.set(new ScChart2DataProvider(&rScDoc)); + + xReceiver->attachDataProvider(xDataProvider); uno::Reference< util::XNumberFormatsSupplier > xNumberFormatsSupplier( pDocShell->GetModel(), uno::UNO_QUERY ); xReceiver->attachNumberFormatsSupplier( xNumberFormatsSupplier ); @@ -329,7 +337,7 @@ FuInsertOLE::FuInsertOLE(ScTabViewShell* pViewSh, vcl::Window* pWin, ScDrawView* // Chart initialisieren ? if ( SvtModuleOptions().IsChart() && SotExchange::IsChart( SvGlobalName( xObj->getClassID() ) ) ) - lcl_ChartInit( xObj, &pViewSh->GetViewData(), OUString() ); + lcl_ChartInit(xObj, &pViewSh->GetViewData(), OUString(), false); ScViewData& rData = pViewSh->GetViewData(); @@ -393,7 +401,7 @@ FuInsertChart::FuInsertChart(ScTabViewShell* pViewSh, vcl::Window* pWin, ScDrawV SdrModel* pDoc, SfxRequest& rReq) : FuPoor(pViewSh, pWin, pViewP, pDoc, rReq) { - const SfxItemSet* pReqArgs = rReq.GetArgs(); + const SfxItemSet* pReqArgs = rReq.GetArgs(); if( ! rReq.IsAPI() ) rReq.Done(); @@ -405,6 +413,7 @@ FuInsertChart::FuInsertChart(ScTabViewShell* pViewSh, vcl::Window* pWin, ScDrawV // get range OUString aRangeString; + bool bRangeIsPivotTable = false; ScRange aPositionRange; // cell range for chart positioning ScMarkData aMark = pViewSh->GetViewData().GetMarkData(); if( pReqArgs ) @@ -417,35 +426,46 @@ FuInsertChart::FuInsertChart(ScTabViewShell* pViewSh, vcl::Window* pWin, ScDrawV } else { - bool bAutomaticMark = false; - if ( !aMark.IsMarked() && !aMark.IsMultiMarked() ) + ScDocument* pDocument = pViewSh->GetViewData().GetDocument(); + ScDPObject* pObject = pDocument->GetDPAtCursor(pViewSh->GetViewData().GetCurX(), + pViewSh->GetViewData().GetCurY(), + pViewSh->GetViewData().GetTabNo()); + if (pObject) { - pViewSh->GetViewData().GetView()->MarkDataArea(); - bAutomaticMark = true; + aRangeString = pObject->GetName(); + bRangeIsPivotTable = true; } + else + { + bool bAutomaticMark = false; + if ( !aMark.IsMarked() && !aMark.IsMultiMarked() ) + { + pViewSh->GetViewData().GetView()->MarkDataArea(); + bAutomaticMark = true; + } - ScMarkData aMultiMark( aMark ); - aMultiMark.MarkToMulti(); + ScMarkData aMultiMark( aMark ); + aMultiMark.MarkToMulti(); - ScRangeList aRanges; - aMultiMark.FillRangeListWithMarks( &aRanges, false ); - OUString aStr; - ScDocument* pDocument = pViewSh->GetViewData().GetDocument(); - aRanges.Format( aStr, ScRefFlags::RANGE_ABS_3D, pDocument, pDocument->GetAddressConvention() ); - aRangeString = aStr; + ScRangeList aRanges; + aMultiMark.FillRangeListWithMarks( &aRanges, false ); + OUString aStr; + aRanges.Format( aStr, ScRefFlags::RANGE_ABS_3D, pDocument, pDocument->GetAddressConvention() ); + aRangeString = aStr; - // get "total" range for positioning - if ( !aRanges.empty() ) - { - aPositionRange = *aRanges[ 0 ]; - for ( size_t i = 1, nCount = aRanges.size(); i < nCount; ++i ) + // get "total" range for positioning + if ( !aRanges.empty() ) { - aPositionRange.ExtendTo( *aRanges[ i ] ); + aPositionRange = *aRanges[ 0 ]; + for ( size_t i = 1, nCount = aRanges.size(); i < nCount; ++i ) + { + aPositionRange.ExtendTo( *aRanges[ i ] ); + } } - } - if(bAutomaticMark) - pViewSh->GetViewData().GetView()->Unmark(); + if(bAutomaticMark) + pViewSh->GetViewData().GetView()->Unmark(); + } } // adapted old code @@ -568,7 +588,7 @@ FuInsertChart::FuInsertChart(ScTabViewShell* pViewSh, vcl::Window* pWin, ScDrawV } } - lcl_ChartInit( xObj, &rData, aRangeString ); // set source range, auto-detect column/row headers + lcl_ChartInit(xObj, &rData, aRangeString, bRangeIsPivotTable); // set source range, auto-detect column/row headers // Objekt-Position
_______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits