[Libreoffice-commits] core.git: Branch 'private/Sweetshark/mmunocrsrs' - 2 commits - sw/inc sw/source

Bjoern Michaelsen bjoern.michaelsen at canonical.com
Wed May 20 09:18:25 PDT 2015


 sw/inc/unocrsr.hxx                  |    5 --
 sw/inc/unotbl.hxx                   |    8 +--
 sw/source/core/unocore/unochart.cxx |    8 +--
 sw/source/core/unocore/unocrsr.cxx  |   23 +---------
 sw/source/core/unocore/unotbl.cxx   |   78 ++++++++++++++++++------------------
 5 files changed, 52 insertions(+), 70 deletions(-)

New commits:
commit 541619b1718d3ca557a13a8ea1e32933f801fb7e
Author: Bjoern Michaelsen <bjoern.michaelsen at canonical.com>
Date:   Wed May 20 18:17:56 2015 +0200

    use new unocrsrs in SwXCellRange
    
    Change-Id: I8ab1c9c0329bdf3f6ac759012dbd0057f4463231

diff --git a/sw/inc/unocrsr.hxx b/sw/inc/unocrsr.hxx
index 1d66557..f378f72 100644
--- a/sw/inc/unocrsr.hxx
+++ b/sw/inc/unocrsr.hxx
@@ -92,7 +92,7 @@ public:
                                   nsSwCursorSelOverFlags::SELOVER_TOGGLE |
                                   nsSwCursorSelOverFlags::SELOVER_CHANGEPOS )) SAL_OVERRIDE;
 
-    SwUnoTableCrsr * Clone() const;
+    std::shared_ptr<SwUnoCrsr> Clone() const;
 
     void MakeBoxSels();
 
diff --git a/sw/inc/unotbl.hxx b/sw/inc/unotbl.hxx
index 3313b47..7ea995a 100644
--- a/sw/inc/unotbl.hxx
+++ b/sw/inc/unotbl.hxx
@@ -457,7 +457,7 @@ class SwXCellRange : public cppu::WeakImplHelper
     SwRangeDescriptor           aRgDesc;
     const SfxItemPropertySet*   m_pPropSet;
 
-    SwUnoCrsr*                  pTblCrsr;
+    std::shared_ptr<SwUnoCrsr> m_pTblCrsr;
 
     bool m_bFirstRowAsLabel;
     bool m_bFirstColumnAsLabel;
@@ -466,11 +466,10 @@ class SwXCellRange : public cppu::WeakImplHelper
     void setLabelDescriptions(const css::uno::Sequence<OUString>& rDesc, bool bRow);
 
 public:
-    SwXCellRange(SwUnoCrsr* pCrsr, SwFrmFmt& rFrmFmt, SwRangeDescriptor& rDesc);
+    SwXCellRange(std::shared_ptr<SwUnoCrsr> pCrsr, SwFrmFmt& rFrmFmt, SwRangeDescriptor& rDesc);
     void SetLabels(bool bFirstRowAsLabel, bool bFirstColumnAsLabel)
         { m_bFirstRowAsLabel = bFirstRowAsLabel, m_bFirstColumnAsLabel = bFirstColumnAsLabel; }
     std::vector< css::uno::Reference< css::table::XCell > > getCells();
-    virtual ~SwXCellRange();
 
     TYPEINFO_OVERRIDE();
 
@@ -536,7 +535,8 @@ public:
     virtual ::com::sun::star::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames(void) throw( ::com::sun::star::uno::RuntimeException, std::exception ) SAL_OVERRIDE;
 
     //SwClient
-   virtual void Modify( const SfxPoolItem* pOld, const SfxPoolItem *pNew) SAL_OVERRIDE;
+    virtual void Modify( const SfxPoolItem* pOld, const SfxPoolItem *pNew) SAL_OVERRIDE;
+    virtual void SwClientNotify(const SwModify&, const SfxHint&) SAL_OVERRIDE;
 
     SwFrmFmt*   GetFrmFmt() const { return const_cast<SwFrmFmt*>(static_cast<const SwFrmFmt*>(GetRegisteredIn())); }
     sal_uInt16      getRowCount(void);
diff --git a/sw/source/core/unocore/unocrsr.cxx b/sw/source/core/unocore/unocrsr.cxx
index b3de077..92bac9b 100644
--- a/sw/source/core/unocore/unocrsr.cxx
+++ b/sw/source/core/unocore/unocrsr.cxx
@@ -64,14 +64,11 @@ SwUnoCrsr::~SwUnoCrsr()
     }
 }
 
-SwUnoTableCrsr * SwUnoTableCrsr::Clone() const
+std::shared_ptr<SwUnoCrsr> SwUnoTableCrsr::Clone() const
 {
-    assert(!m_bSaneOwnership);
-    SwUnoTableCrsr * pNewCrsr = dynamic_cast<SwUnoTableCrsr*>(
-        GetDoc()->CreateUnoCrsr(
-            *GetPoint(), true /* create SwUnoTableCrsr */ ) );
-    OSL_ENSURE(pNewCrsr, "Clone: cannot create SwUnoTableCrsr?");
-    if (pNewCrsr && HasMark())
+    assert(m_bSaneOwnership);
+    auto pNewCrsr(GetDoc()->CreateUnoCrsr2(*GetPoint(), true));
+    if(HasMark())
     {
         pNewCrsr->SetMark();
         *pNewCrsr->GetMark() = *GetMark();
diff --git a/sw/source/core/unocore/unotbl.cxx b/sw/source/core/unocore/unotbl.cxx
index 0090c4e..ea07cdc 100644
--- a/sw/source/core/unocore/unotbl.cxx
+++ b/sw/source/core/unocore/unotbl.cxx
@@ -2189,7 +2189,7 @@ uno::Reference<table::XCell>  SwXTextTable::getCellByPosition(sal_Int32 nColumn,
     throw lang::IndexOutOfBoundsException();
 }
 
-uno::Reference<table::XCellRange>  SwXTextTable::GetRangeByName(SwFrmFmt* pFmt, SwTable* pTable,
+uno::Reference<table::XCellRange> SwXTextTable::GetRangeByName(SwFrmFmt* pFmt, SwTable* pTable,
         const OUString& rTLName, const OUString& rBRName,
         SwRangeDescriptor& rDesc)
 {
@@ -2202,19 +2202,16 @@ uno::Reference<table::XCellRange>  SwXTextTable::GetRangeByName(SwFrmFmt* pFmt,
     const SwStartNode* pSttNd = pTLBox->GetSttNd();
     SwPosition aPos(*pSttNd);
     // set cursor to the upper-left cell of the range
-    SwUnoCrsr* pUnoCrsr = pFmt->GetDoc()->CreateUnoCrsr(aPos, true);
+    auto pUnoCrsr(pFmt->GetDoc()->CreateUnoCrsr2(aPos, true));
     pUnoCrsr->Move(fnMoveForward, fnGoNode);
     pUnoCrsr->SetRemainInSection(false);
     const SwTableBox* pBRBox(pTable->GetTblBox(rBRName));
     if(!pBRBox)
-    {
-        delete pUnoCrsr;
         return nullptr;
-    }
     pUnoCrsr->SetMark();
     pUnoCrsr->GetPoint()->nNode = *pBRBox->GetSttNd();
     pUnoCrsr->Move( fnMoveForward, fnGoNode );
-    SwUnoTableCrsr* pCrsr = dynamic_cast<SwUnoTableCrsr*>(pUnoCrsr);
+    SwUnoTableCrsr* pCrsr = dynamic_cast<SwUnoTableCrsr*>(pUnoCrsr.get());
     pCrsr->MakeBoxSels();
     // pUnoCrsr will be provided and will not be deleted
     return new SwXCellRange(pUnoCrsr, *pFmt, rDesc);
@@ -3143,18 +3140,18 @@ uno::Sequence<OUString> SwXCellRange::getSupportedServiceNames(void) throw( uno:
         "com.sun.star.style.ParagraphPropertiesComplex" };
 }
 
-SwXCellRange::SwXCellRange(SwUnoCrsr* pCrsr, SwFrmFmt& rFrmFmt,
+SwXCellRange::SwXCellRange(std::shared_ptr<SwUnoCrsr> pCrsr, SwFrmFmt& rFrmFmt,
     SwRangeDescriptor& rDesc)
     : SwClient(&rFrmFmt)
-    , aCursorDepend(this, pCrsr)
+    , aCursorDepend(this, pCrsr.get())
     , m_ChartListeners(m_Mutex)
-    ,
-    aRgDesc(rDesc),
-    m_pPropSet(aSwMapProvider.GetPropertySet(PROPERTY_MAP_TABLE_RANGE)),
-    pTblCrsr(pCrsr),
-    m_bFirstRowAsLabel(false),
-    m_bFirstColumnAsLabel(false)
+    , aRgDesc(rDesc)
+    , m_pPropSet(aSwMapProvider.GetPropertySet(PROPERTY_MAP_TABLE_RANGE))
+    , m_pTblCrsr(pCrsr)
+    , m_bFirstRowAsLabel(false)
+    , m_bFirstColumnAsLabel(false)
 {
+    assert(m_pTblCrsr->m_bSaneOwnership);
     aRgDesc.Normalize();
 }
 
@@ -3171,12 +3168,6 @@ std::vector< uno::Reference< table::XCell > > SwXCellRange::getCells()
     return vResult;
 }
 
-SwXCellRange::~SwXCellRange()
-{
-    SolarMutexGuard aGuard;
-    delete pTblCrsr;
-}
-
 uno::Reference< table::XCell >  SwXCellRange::getCellByPosition(sal_Int32 nColumn, sal_Int32 nRow)
     throw( uno::RuntimeException, lang::IndexOutOfBoundsException, std::exception )
 {
@@ -3230,7 +3221,7 @@ uno::Reference< table::XCellRange >  SwXCellRange::getCellRangeByPosition(
                 const SwStartNode* pSttNd = pTLBox->GetSttNd();
                 SwPosition aPos(*pSttNd);
                 // set cursor in the upper-left cell of the range
-                SwUnoCrsr* pUnoCrsr = pFmt->GetDoc()->CreateUnoCrsr(aPos, true);
+                auto pUnoCrsr(pFmt->GetDoc()->CreateUnoCrsr2(aPos, true));
                 pUnoCrsr->Move( fnMoveForward, fnGoNode );
                 pUnoCrsr->SetRemainInSection( false );
                 const SwTableBox* pBRBox = pTable->GetTblBox( sBRName );
@@ -3239,14 +3230,12 @@ uno::Reference< table::XCellRange >  SwXCellRange::getCellRangeByPosition(
                     pUnoCrsr->SetMark();
                     pUnoCrsr->GetPoint()->nNode = *pBRBox->GetSttNd();
                     pUnoCrsr->Move( fnMoveForward, fnGoNode );
-                    SwUnoTableCrsr* pCrsr = dynamic_cast<SwUnoTableCrsr*>(pUnoCrsr);
+                    SwUnoTableCrsr* pCrsr = dynamic_cast<SwUnoTableCrsr*>(pUnoCrsr.get());
                     pCrsr->MakeBoxSels();
                     // pUnoCrsr will be provided and will not be deleted
                     SwXCellRange* pCellRange = new SwXCellRange(pUnoCrsr, *pFmt, aNewDesc);
                     aRet = pCellRange;
                 }
-                else
-                    delete pUnoCrsr;
             }
         }
     }
@@ -3298,21 +3287,21 @@ void SwXCellRange::setPropertyValue(const OUString& rPropertyName, const uno::An
             if ( pEntry->nFlags & beans::PropertyAttribute::READONLY)
                 throw beans::PropertyVetoException("Property is read-only: " + rPropertyName, static_cast < cppu::OWeakObject * > ( this ) );
 
-            SwDoc* pDoc = pTblCrsr->GetDoc();
+            SwDoc* pDoc = m_pTblCrsr->GetDoc();
             {
                 // remove actions to enable box selection
                 UnoActionRemoveContext aRemoveContext(pDoc);
             }
-            SwUnoTableCrsr& rCrsr = dynamic_cast<SwUnoTableCrsr&>(*pTblCrsr);
+            SwUnoTableCrsr& rCrsr = dynamic_cast<SwUnoTableCrsr&>(*m_pTblCrsr);
             rCrsr.MakeBoxSels();
             switch(pEntry->nWID )
             {
                 case FN_UNO_TABLE_CELL_BACKGROUND:
                 {
                     SvxBrushItem aBrush( RES_BACKGROUND );
-                    pDoc->GetBoxAttr( *pTblCrsr, aBrush );
+                    pDoc->GetBoxAttr( *m_pTblCrsr, aBrush );
                     ((SfxPoolItem&)aBrush).PutValue(aValue, pEntry->nMemberId);
-                    pDoc->SetBoxAttr( *pTblCrsr, aBrush );
+                    pDoc->SetBoxAttr( *m_pTblCrsr, aBrush );
 
                 }
                 break;
@@ -3347,7 +3336,7 @@ void SwXCellRange::setPropertyValue(const OUString& rPropertyName, const uno::An
                     SvxBoxItem aBoxItem(static_cast<const SvxBoxItem&>(aSet.Get(RES_BOX)));
                     ((SfxPoolItem&)aBoxItem).PutValue(aValue, pEntry->nMemberId);
                     aSet.Put(aBoxItem);
-                    pDoc->SetTabBorders( *pTblCrsr, aSet );
+                    pDoc->SetTabBorders( *m_pTblCrsr, aSet );
                 }
                 break;
                 case RES_BOXATR_FORMAT:
@@ -3418,20 +3407,20 @@ uno::Any SwXCellRange::getPropertyValue(const OUString& rPropertyName)
                 case FN_UNO_TABLE_CELL_BACKGROUND:
                 {
                     SvxBrushItem aBrush( RES_BACKGROUND );
-                    if(pTblCrsr->GetDoc()->GetBoxAttr( *pTblCrsr, aBrush ))
+                    if(m_pTblCrsr->GetDoc()->GetBoxAttr( *m_pTblCrsr, aBrush ))
                         aBrush.QueryValue(aRet, pEntry->nMemberId);
 
                 }
                 break;
                 case RES_BOX :
                 {
-                    SwDoc* pDoc = pTblCrsr->GetDoc();
+                    SwDoc* pDoc = m_pTblCrsr->GetDoc();
                     SfxItemSet aSet(pDoc->GetAttrPool(),
                                     RES_BOX, RES_BOX,
                                     SID_ATTR_BORDER_INNER, SID_ATTR_BORDER_INNER,
                                     0);
                     aSet.Put(SvxBoxInfoItem( SID_ATTR_BORDER_INNER ));
-                    pDoc->GetTabBorders(*pTblCrsr, aSet);
+                    pDoc->GetTabBorders(*m_pTblCrsr, aSet);
                     const SvxBoxItem& rBoxItem = static_cast<const SvxBoxItem&>(aSet.Get(RES_BOX));
                     rBoxItem.QueryValue(aRet, pEntry->nMemberId);
                 }
@@ -3442,7 +3431,7 @@ uno::Any SwXCellRange::getPropertyValue(const OUString& rPropertyName)
                 case FN_UNO_PARA_STYLE:
                 {
                     SwFmtColl *const pTmpFmt =
-                        SwUnoCursorHelper::GetCurTxtFmtColl(*pTblCrsr, false);
+                        SwUnoCursorHelper::GetCurTxtFmtColl(*m_pTblCrsr, false);
                     OUString sRet;
                     if(pFmt)
                         sRet = pTmpFmt->GetName();
@@ -3457,13 +3446,13 @@ uno::Any SwXCellRange::getPropertyValue(const OUString& rPropertyName)
                 break;
                 default:
                 {
-                    SfxItemSet aSet(pTblCrsr->GetDoc()->GetAttrPool(),
+                    SfxItemSet aSet(m_pTblCrsr->GetDoc()->GetAttrPool(),
                         RES_CHRATR_BEGIN,       RES_FRMATR_END -1,
                         RES_TXTATR_UNKNOWN_CONTAINER, RES_TXTATR_UNKNOWN_CONTAINER,
                         RES_UNKNOWNATR_CONTAINER, RES_UNKNOWNATR_CONTAINER,
                         0L);
                     // first look at the attributes of the cursor
-                    SwUnoTableCrsr* pCrsr = dynamic_cast<SwUnoTableCrsr*>(pTblCrsr);
+                    SwUnoTableCrsr* pCrsr = dynamic_cast<SwUnoTableCrsr*>(m_pTblCrsr.get());
                     SwUnoCursorHelper::GetCrsrAttr(pCrsr->GetSelRing(), aSet);
                     m_pPropSet->getPropertyValue(*pEntry, aSet, aRet);
                 }
@@ -3576,7 +3565,7 @@ void SwXCellRange::GetDataSequence(
                             // from the text in the cell...
 
                             sal_uInt32 nFIndex;
-                            SvNumberFormatter* pNumFormatter = pTblCrsr->GetDoc()->GetNumberFormatter();
+                            SvNumberFormatter* pNumFormatter = m_pTblCrsr->GetDoc()->GetNumberFormatter();
 
                             // look for SwTblBoxNumFormat value in parents as well
                             const SfxPoolItem* pItem;
@@ -3862,7 +3851,7 @@ void SAL_CALL SwXCellRange::sort(const uno::Sequence< beans::PropertyValue >& rD
     SwFrmFmt* pFmt(GetFrmFmt());
     if(pFmt && SwUnoCursorHelper::ConvertSortProperties(rDescriptor, aSortOpt))
     {
-        SwUnoTableCrsr& rTableCrsr = dynamic_cast<SwUnoTableCrsr&>(*pTblCrsr);
+        SwUnoTableCrsr& rTableCrsr = dynamic_cast<SwUnoTableCrsr&>(*m_pTblCrsr);
         rTableCrsr.MakeBoxSels();
         UnoActionContext aContext(pFmt->GetDoc());
         pFmt->GetDoc()->SortTbl(rTableCrsr.GetSelectedBoxes(), aSortOpt);
@@ -3878,7 +3867,7 @@ sal_uInt16 SwXCellRange::getRowCount(void)
 const SwUnoCrsr* SwXCellRange::GetTblCrsr() const
 {
     SwFrmFmt* pFmt = GetFrmFmt();
-    return pFmt ? pTblCrsr : nullptr;
+    return pFmt ? m_pTblCrsr.get() : nullptr;
 }
 
 void SwXCellRange::Modify( const SfxPoolItem* pOld, const SfxPoolItem *pNew)
@@ -3892,7 +3881,7 @@ void SwXCellRange::Modify( const SfxPoolItem* pOld, const SfxPoolItem *pNew)
          * if(!aCursorDepend.GetRegisteredIn())
             delete pTblCrsr;
          */
-        pTblCrsr = 0;
+        m_pTblCrsr.reset();
         lang::EventObject const ev(static_cast< ::cppu::OWeakObject&>(*this));
         m_ChartListeners.disposeAndClear(ev);
     }
@@ -3902,6 +3891,17 @@ void SwXCellRange::Modify( const SfxPoolItem* pOld, const SfxPoolItem *pNew)
     }
 }
 
+void SwXCellRange::SwClientNotify(const SwModify& rModify, const SfxHint& rHint)
+{
+    //assert(m_pTblCrsr->m_bSaneOwnership);
+    SwClient::SwClientNotify(rModify, rHint);
+    if(m_pTblCrsr && typeid(rHint) == typeid(sw::DocDisposingHint))
+    {
+        m_pTblCrsr->Remove(&aCursorDepend);
+        m_pTblCrsr.reset();
+    }
+}
+
 //  SwXTableRows
 
 OUString SwXTableRows::getImplementationName(void) throw( uno::RuntimeException, std::exception )
commit 64c7d51607a0101b2d2a08e9532a49ffae76516c
Author: Bjoern Michaelsen <bjoern.michaelsen at canonical.com>
Date:   Wed May 20 17:01:12 2015 +0200

    kill faux polymophic SwUnoCrsr::Clone()
    
    - SwUnoCrsr::Clone() is dead code that is never used
    - SwUnoTblCrsr::Clone() is the only implemenation that is used, in a
      context that assumes it to be a SwUnoTblCrsr anyway
    => make this non-virtual
    
    Change-Id: I28ddf314eda3d234f2a383bf386dfbe251966038

diff --git a/sw/inc/unocrsr.hxx b/sw/inc/unocrsr.hxx
index e1732cc..1d66557 100644
--- a/sw/inc/unocrsr.hxx
+++ b/sw/inc/unocrsr.hxx
@@ -69,9 +69,6 @@ public:
     void SetSkipOverHiddenSections( bool bFlag )
                                     { m_bSkipOverHiddenSections = bFlag; }
 
-    // make copy of cursor
-    virtual SwUnoCrsr * Clone() const;
-
     DECL_FIXEDMEMPOOL_NEWDEL( SwUnoCrsr )
 };
 
@@ -95,7 +92,7 @@ public:
                                   nsSwCursorSelOverFlags::SELOVER_TOGGLE |
                                   nsSwCursorSelOverFlags::SELOVER_CHANGEPOS )) SAL_OVERRIDE;
 
-    virtual SwUnoTableCrsr * Clone() const SAL_OVERRIDE;
+    SwUnoTableCrsr * Clone() const;
 
     void MakeBoxSels();
 
diff --git a/sw/source/core/unocore/unochart.cxx b/sw/source/core/unocore/unochart.cxx
index 38b9cbd..0b5d586 100644
--- a/sw/source/core/unocore/unochart.cxx
+++ b/sw/source/core/unocore/unochart.cxx
@@ -1948,7 +1948,7 @@ SwChartDataSequence::SwChartDataSequence( const SwChartDataSequence &rObj ) :
     aColLabelText( SW_RES(STR_CHART2_COL_LABEL_TEXT) ),
     xDataProvider( rObj.pDataProvider ),
     pDataProvider( rObj.pDataProvider ),
-    pTblCrsr( rObj.pTblCrsr->Clone() ),
+    pTblCrsr( dynamic_cast<SwUnoTableCrsr*>(rObj.pTblCrsr.get())->Clone() ),
     aCursorDepend( this, pTblCrsr.get() ),
     _pPropSet( rObj._pPropSet )
 {
@@ -2033,7 +2033,7 @@ uno::Sequence< uno::Any > SAL_CALL SwChartDataSequence::getData()
                 // keep original cursor and make copy of it that gets handed
                 // over to the SwXCellRange object which takes ownership and
                 // thus will destroy the copy later.
-                SwXCellRange aRange( pTblCrsr->Clone(), *pTblFmt, aDesc );
+                SwXCellRange aRange( dynamic_cast<SwUnoTableCrsr*>(pTblCrsr.get())->Clone(), *pTblFmt, aDesc );
                 aRange.GetDataSequence( &aRes, 0, 0 );
             }
         }
@@ -2193,7 +2193,7 @@ uno::Sequence< OUString > SAL_CALL SwChartDataSequence::getTextualData()
                 // keep original cursor and make copy of it that gets handed
                 // over to the SwXCellRange object which takes ownership and
                 // thus will destroy the copy later.
-                SwXCellRange aRange( pTblCrsr->Clone(), *pTblFmt, aDesc );
+                SwXCellRange aRange( dynamic_cast<SwUnoTableCrsr*>(pTblCrsr.get())->Clone(), *pTblFmt, aDesc );
                 aRange.GetDataSequence( 0, &aRes, 0 );
             }
         }
@@ -2222,7 +2222,7 @@ uno::Sequence< double > SAL_CALL SwChartDataSequence::getNumericalData()
                 // keep original cursor and make copy of it that gets handed
                 // over to the SwXCellRange object which takes ownership and
                 // thus will destroy the copy later.
-                SwXCellRange aRange( pTblCrsr->Clone(), *pTblFmt, aDesc );
+                SwXCellRange aRange( dynamic_cast<SwUnoTableCrsr*>(pTblCrsr.get())->Clone(), *pTblFmt, aDesc );
 
                 // get numerical values and make an effort to return the
                 // numerical value for text formatted cells
diff --git a/sw/source/core/unocore/unocrsr.cxx b/sw/source/core/unocore/unocrsr.cxx
index a67a3be..b3de077 100644
--- a/sw/source/core/unocore/unocrsr.cxx
+++ b/sw/source/core/unocore/unocrsr.cxx
@@ -64,18 +64,6 @@ SwUnoCrsr::~SwUnoCrsr()
     }
 }
 
-SwUnoCrsr * SwUnoCrsr::Clone() const
-{
-    assert(!m_bSaneOwnership);
-    SwUnoCrsr * pNewCrsr = GetDoc()->CreateUnoCrsr( *GetPoint() );
-    if (HasMark())
-    {
-        pNewCrsr->SetMark();
-        *pNewCrsr->GetMark() = *GetMark();
-    }
-    return pNewCrsr;
-}
-
 SwUnoTableCrsr * SwUnoTableCrsr::Clone() const
 {
     assert(!m_bSaneOwnership);


More information about the Libreoffice-commits mailing list