[Libreoffice-commits] core.git: oox/Library_oox.mk oox/source
Grzegorz Araminowicz
g.araminowicz at gmail.com
Mon Jun 26 20:49:52 UTC 2017
oox/Library_oox.mk | 1
oox/source/drawingml/diagram/diagram.cxx | 1
oox/source/drawingml/diagram/diagramlayoutatoms.cxx | 232 --------------------
oox/source/drawingml/diagram/diagramlayoutatoms.hxx | 23 -
oox/source/drawingml/diagram/layoutatomvisitors.cxx | 222 +++++++++++++++++++
oox/source/drawingml/diagram/layoutatomvisitors.hxx | 103 ++++++++
6 files changed, 327 insertions(+), 255 deletions(-)
New commits:
commit fd233408d650ae7770ad6d3e83850e565c1e4fb1
Author: Grzegorz Araminowicz <g.araminowicz at gmail.com>
Date: Mon Jun 26 16:55:49 2017 +0200
SmartArt: separate LayoutAtomVisitors from LayoutAtoms
Change-Id: Ifbed15c881e4c0b987cd2fdbb903709a0b8b0e36
Reviewed-on: https://gerrit.libreoffice.org/39269
Tested-by: Jenkins <ci at libreoffice.org>
Reviewed-by: Jan Holesovsky <kendy at collabora.com>
diff --git a/oox/Library_oox.mk b/oox/Library_oox.mk
index 632f09bf01ee..db6e9b2d16f7 100644
--- a/oox/Library_oox.mk
+++ b/oox/Library_oox.mk
@@ -144,6 +144,7 @@ $(eval $(call gb_Library_add_exception_objects,oox,\
oox/source/drawingml/diagram/diagramdefinitioncontext \
oox/source/drawingml/diagram/diagramfragmenthandler \
oox/source/drawingml/diagram/diagramlayoutatoms \
+ oox/source/drawingml/diagram/layoutatomvisitors \
oox/source/drawingml/diagram/layoutnodecontext \
oox/source/drawingml/drawingmltypes \
oox/source/drawingml/effectproperties \
diff --git a/oox/source/drawingml/diagram/diagram.cxx b/oox/source/drawingml/diagram/diagram.cxx
index 3272e47da5fe..059d891f4b85 100644
--- a/oox/source/drawingml/diagram/diagram.cxx
+++ b/oox/source/drawingml/diagram/diagram.cxx
@@ -35,6 +35,7 @@
#include "oox/ppt/pptshape.hxx"
#include "diagramlayoutatoms.hxx"
+#include "layoutatomvisitors.hxx"
#include "diagramfragmenthandler.hxx"
#include <iostream>
diff --git a/oox/source/drawingml/diagram/diagramlayoutatoms.cxx b/oox/source/drawingml/diagram/diagramlayoutatoms.cxx
index d77020ad7ab7..f5461a8df2d3 100644
--- a/oox/source/drawingml/diagram/diagramlayoutatoms.cxx
+++ b/oox/source/drawingml/diagram/diagramlayoutatoms.cxx
@@ -512,238 +512,6 @@ bool LayoutNode::setupShape( const ShapePtr& rShape, const Diagram& rDgm, sal_uI
return false;
}
-// Visitation
-
-class ShapeLayoutingVisitor : public LayoutAtomVisitor
-{
- ShapePtr mpParentShape;
- OUString maName;
-
- virtual void visit(ConstraintAtom& rAtom) override;
- virtual void visit(AlgAtom& rAtom) override;
- virtual void visit(ForEachAtom& rAtom) override;
- virtual void visit(ConditionAtom& rAtom) override;
- virtual void visit(ChooseAtom& rAtom) override;
- virtual void visit(LayoutNode& rAtom) override;
-
-public:
- ShapeLayoutingVisitor(const ShapePtr& rParentShape,
- const OUString& rName) :
- mpParentShape(rParentShape),
- maName(rName)
- {}
-
- void defaultVisit(LayoutAtom& rAtom);
-};
-
-class ShallowPresNameVisitor : public LayoutAtomVisitor
-{
- const Diagram& mrDgm;
- size_t mnCnt;
-
- void defaultVisit(LayoutAtom& rAtom);
- virtual void visit(ConstraintAtom& rAtom) override;
- virtual void visit(AlgAtom& rAtom) override;
- virtual void visit(ForEachAtom& rAtom) override;
- virtual void visit(ConditionAtom& rAtom) override;
- virtual void visit(ChooseAtom& rAtom) override;
- virtual void visit(LayoutNode& rAtom) override;
-
-public:
- explicit ShallowPresNameVisitor(const Diagram& rDgm) :
- mrDgm(rDgm),
- mnCnt(0)
- {}
-
- size_t getCount() const
- { return mnCnt; }
-};
-
-void ShapeCreationVisitor::defaultVisit(LayoutAtom& rAtom)
-{
- const std::vector<LayoutAtomPtr>& rChildren=rAtom.getChildren();
- std::for_each( rChildren.begin(), rChildren.end(),
- [this] (LayoutAtomPtr const& pAtom) { pAtom->accept(*this); } );
-}
-
-void ShapeCreationVisitor::visit(ConstraintAtom& /*rAtom*/)
-{
- // TODO: eval the constraints
-}
-
-void ShapeCreationVisitor::visit(AlgAtom& rAtom)
-{
- defaultVisit(rAtom);
-}
-
-void ShapeCreationVisitor::visit(ForEachAtom& rAtom)
-{
- const std::vector<LayoutAtomPtr>& rChildren=rAtom.getChildren();
-
- sal_Int32 nChildren=1;
- if( rAtom.iterator().mnPtType == XML_node )
- {
- // cound child data nodes - check all child Atoms for "name"
- // attribute that is contained in diagram's
- // getPointsPresNameMap()
- ShallowPresNameVisitor aVisitor(mrDgm);
- std::for_each( rChildren.begin(), rChildren.end(),
- [&] (LayoutAtomPtr const& pAtom) { pAtom->accept(aVisitor); } );
- nChildren = aVisitor.getCount();
- }
-
- const sal_Int32 nCnt = std::min(
- nChildren,
- rAtom.iterator().mnCnt==-1 ? nChildren : rAtom.iterator().mnCnt);
-
- const sal_Int32 nOldIdx=mnCurrIdx;
- const sal_Int32 nStep=rAtom.iterator().mnStep;
- for( mnCurrIdx=0; mnCurrIdx<nCnt && nStep>0; mnCurrIdx+=nStep )
- {
- // TODO there is likely some conditions
- std::for_each( rChildren.begin(), rChildren.end(),
- [this] (LayoutAtomPtr const& pAtom) { pAtom->accept(*this); } );
- }
-
- // and restore idx
- mnCurrIdx = nOldIdx;
-}
-
-void ShapeCreationVisitor::visit(ConditionAtom& rAtom)
-{
- defaultVisit(rAtom);
-}
-
-void ShapeCreationVisitor::visit(ChooseAtom& rAtom)
-{
- defaultVisit(rAtom);
-}
-
-void ShapeCreationVisitor::visit(LayoutNode& rAtom)
-{
- ShapePtr pCurrParent(mpParentShape);
- ShapePtr pCurrShape(rAtom.getShape());
- if( pCurrShape )
- {
- SAL_INFO(
- "oox.drawingml",
- "processing shape type "
- << (pCurrShape->getCustomShapeProperties()
- ->getShapePresetType()));
-
- // TODO(F3): cloned shape shares all properties by reference,
- // don't change them!
- ShapePtr pClonedShape(
- new Shape( pCurrShape ));
-
- if( rAtom.setupShape(pClonedShape, mrDgm, mnCurrIdx) )
- {
- pCurrParent->addChild(pClonedShape);
- pCurrParent = pClonedShape;
- }
- }
- else
- {
- SAL_WARN("oox.drawingml", "ShapeCreationVisitor::visit: no shape set while processing layoutnode named " << rAtom.getName() );
- }
-
- // set new parent for children
- ShapePtr pPreviousParent(mpParentShape);
- mpParentShape=pCurrParent;
-
- // process children
- defaultVisit(rAtom);
-
- // restore parent
- mpParentShape=pPreviousParent;
-
- // layout shapes - now all child shapes are created
- ShapeLayoutingVisitor aLayoutingVisitor(pCurrParent,
- rAtom.getName());
- aLayoutingVisitor.defaultVisit(rAtom);
-}
-
-void ShapeLayoutingVisitor::defaultVisit(LayoutAtom& rAtom)
-{
- // visit all children, one of them needs to be the layout algorithm
- const std::vector<LayoutAtomPtr>& rChildren=rAtom.getChildren();
- std::for_each( rChildren.begin(), rChildren.end(),
- [this] (LayoutAtomPtr const& pAtom) { pAtom->accept(*this); } );
-}
-
-void ShapeLayoutingVisitor::visit(ConstraintAtom& /*rAtom*/)
-{
- // stop processing
-}
-
-void ShapeLayoutingVisitor::visit(AlgAtom& rAtom)
-{
- rAtom.layoutShape(mpParentShape, maName);
-}
-
-void ShapeLayoutingVisitor::visit(ForEachAtom& /*rAtom*/)
-{
- // stop processing
-}
-
-void ShapeLayoutingVisitor::visit(ConditionAtom& rAtom)
-{
- defaultVisit(rAtom);
-}
-
-void ShapeLayoutingVisitor::visit(ChooseAtom& rAtom)
-{
- defaultVisit(rAtom);
-}
-
-void ShapeLayoutingVisitor::visit(LayoutNode& /*rAtom*/)
-{
- // stop processing - only traverse Condition/Choose atoms
-}
-
-void ShallowPresNameVisitor::defaultVisit(LayoutAtom& rAtom)
-{
- // visit all children, at least one of them needs to have proper
- // name set
- const std::vector<LayoutAtomPtr>& rChildren=rAtom.getChildren();
- std::for_each( rChildren.begin(), rChildren.end(),
- [this] (LayoutAtomPtr const& pAtom) { pAtom->accept(*this); } );
-}
-
-void ShallowPresNameVisitor::visit(ConstraintAtom& /*rAtom*/)
-{
- // stop processing
-}
-
-void ShallowPresNameVisitor::visit(AlgAtom& /*rAtom*/)
-{
- // stop processing
-}
-
-void ShallowPresNameVisitor::visit(ForEachAtom& rAtom)
-{
- defaultVisit(rAtom);
-}
-
-void ShallowPresNameVisitor::visit(ConditionAtom& rAtom)
-{
- defaultVisit(rAtom);
-}
-
-void ShallowPresNameVisitor::visit(ChooseAtom& rAtom)
-{
- defaultVisit(rAtom);
-}
-
-void ShallowPresNameVisitor::visit(LayoutNode& rAtom)
-{
- DiagramData::PointsNameMap::const_iterator aDataNode=
- mrDgm.getData()->getPointsPresNameMap().find(rAtom.getName());
- if( aDataNode != mrDgm.getData()->getPointsPresNameMap().end() )
- mnCnt = std::max(mnCnt,
- aDataNode->second.size());
-}
-
} }
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/oox/source/drawingml/diagram/diagramlayoutatoms.hxx b/oox/source/drawingml/diagram/diagramlayoutatoms.hxx
index 68cff05e85c8..2df1af060ec2 100644
--- a/oox/source/drawingml/diagram/diagramlayoutatoms.hxx
+++ b/oox/source/drawingml/diagram/diagramlayoutatoms.hxx
@@ -268,29 +268,6 @@ struct LayoutAtomVisitor
virtual void visit(LayoutNode& rAtom) = 0;
};
-class ShapeCreationVisitor : public LayoutAtomVisitor
-{
- ShapePtr mpParentShape;
- const Diagram& mrDgm;
- sal_Int32 mnCurrIdx;
-
- void defaultVisit(LayoutAtom& rAtom);
- virtual void visit(ConstraintAtom& rAtom) override;
- virtual void visit(AlgAtom& rAtom) override;
- virtual void visit(ForEachAtom& rAtom) override;
- virtual void visit(ConditionAtom& rAtom) override;
- virtual void visit(ChooseAtom& rAtom) override;
- virtual void visit(LayoutNode& rAtom) override;
-
-public:
- ShapeCreationVisitor(const ShapePtr& rParentShape,
- const Diagram& rDgm) :
- mpParentShape(rParentShape),
- mrDgm(rDgm),
- mnCurrIdx(0)
- {}
-};
-
} }
#endif
diff --git a/oox/source/drawingml/diagram/layoutatomvisitors.cxx b/oox/source/drawingml/diagram/layoutatomvisitors.cxx
new file mode 100755
index 000000000000..44bbe0d87458
--- /dev/null
+++ b/oox/source/drawingml/diagram/layoutatomvisitors.cxx
@@ -0,0 +1,222 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "layoutatomvisitors.hxx"
+
+#include <functional>
+
+#include <basegfx/numeric/ftools.hxx>
+
+#include "drawingml/customshapeproperties.hxx"
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::xml::sax;
+using namespace ::oox::core;
+
+namespace oox { namespace drawingml {
+
+void ShapeCreationVisitor::defaultVisit(LayoutAtom& rAtom)
+{
+ const std::vector<LayoutAtomPtr>& rChildren=rAtom.getChildren();
+ std::for_each( rChildren.begin(), rChildren.end(),
+ [this] (LayoutAtomPtr const& pAtom) { pAtom->accept(*this); } );
+}
+
+void ShapeCreationVisitor::visit(ConstraintAtom& /*rAtom*/)
+{
+ // TODO: eval the constraints
+}
+
+void ShapeCreationVisitor::visit(AlgAtom& rAtom)
+{
+ defaultVisit(rAtom);
+}
+
+void ShapeCreationVisitor::visit(ForEachAtom& rAtom)
+{
+ const std::vector<LayoutAtomPtr>& rChildren=rAtom.getChildren();
+
+ sal_Int32 nChildren=1;
+ if( rAtom.iterator().mnPtType == XML_node )
+ {
+ // cound child data nodes - check all child Atoms for "name"
+ // attribute that is contained in diagram's
+ // getPointsPresNameMap()
+ ShallowPresNameVisitor aVisitor(mrDgm);
+ std::for_each( rChildren.begin(), rChildren.end(),
+ [&] (LayoutAtomPtr const& pAtom) { pAtom->accept(aVisitor); } );
+ nChildren = aVisitor.getCount();
+ }
+
+ const sal_Int32 nCnt = std::min(
+ nChildren,
+ rAtom.iterator().mnCnt==-1 ? nChildren : rAtom.iterator().mnCnt);
+
+ const sal_Int32 nOldIdx=mnCurrIdx;
+ const sal_Int32 nStep=rAtom.iterator().mnStep;
+ for( mnCurrIdx=0; mnCurrIdx<nCnt && nStep>0; mnCurrIdx+=nStep )
+ {
+ // TODO there is likely some conditions
+ std::for_each( rChildren.begin(), rChildren.end(),
+ [this] (LayoutAtomPtr const& pAtom) { pAtom->accept(*this); } );
+ }
+
+ // and restore idx
+ mnCurrIdx = nOldIdx;
+}
+
+void ShapeCreationVisitor::visit(ConditionAtom& rAtom)
+{
+ defaultVisit(rAtom);
+}
+
+void ShapeCreationVisitor::visit(ChooseAtom& rAtom)
+{
+ defaultVisit(rAtom);
+}
+
+void ShapeCreationVisitor::visit(LayoutNode& rAtom)
+{
+ ShapePtr pCurrParent(mpParentShape);
+ ShapePtr pCurrShape(rAtom.getShape());
+ if( pCurrShape )
+ {
+ SAL_INFO(
+ "oox.drawingml",
+ "processing shape type "
+ << (pCurrShape->getCustomShapeProperties()
+ ->getShapePresetType()));
+
+ // TODO(F3): cloned shape shares all properties by reference,
+ // don't change them!
+ ShapePtr pClonedShape(
+ new Shape( pCurrShape ));
+
+ if( rAtom.setupShape(pClonedShape, mrDgm, mnCurrIdx) )
+ {
+ pCurrParent->addChild(pClonedShape);
+ pCurrParent = pClonedShape;
+ }
+ }
+ else
+ {
+ SAL_WARN("oox.drawingml", "ShapeCreationVisitor::visit: no shape set while processing layoutnode named " << rAtom.getName() );
+ }
+
+ // set new parent for children
+ ShapePtr pPreviousParent(mpParentShape);
+ mpParentShape=pCurrParent;
+
+ // process children
+ defaultVisit(rAtom);
+
+ // restore parent
+ mpParentShape=pPreviousParent;
+
+ // layout shapes - now all child shapes are created
+ ShapeLayoutingVisitor aLayoutingVisitor(pCurrParent,
+ rAtom.getName());
+ aLayoutingVisitor.defaultVisit(rAtom);
+}
+
+void ShapeLayoutingVisitor::defaultVisit(LayoutAtom& rAtom)
+{
+ // visit all children, one of them needs to be the layout algorithm
+ const std::vector<LayoutAtomPtr>& rChildren=rAtom.getChildren();
+ std::for_each( rChildren.begin(), rChildren.end(),
+ [this] (LayoutAtomPtr const& pAtom) { pAtom->accept(*this); } );
+}
+
+void ShapeLayoutingVisitor::visit(ConstraintAtom& /*rAtom*/)
+{
+ // stop processing
+}
+
+void ShapeLayoutingVisitor::visit(AlgAtom& rAtom)
+{
+ rAtom.layoutShape(mpParentShape, maName);
+}
+
+void ShapeLayoutingVisitor::visit(ForEachAtom& /*rAtom*/)
+{
+ // stop processing
+}
+
+void ShapeLayoutingVisitor::visit(ConditionAtom& rAtom)
+{
+ defaultVisit(rAtom);
+}
+
+void ShapeLayoutingVisitor::visit(ChooseAtom& rAtom)
+{
+ defaultVisit(rAtom);
+}
+
+void ShapeLayoutingVisitor::visit(LayoutNode& /*rAtom*/)
+{
+ // stop processing - only traverse Condition/Choose atoms
+}
+
+void ShallowPresNameVisitor::defaultVisit(LayoutAtom& rAtom)
+{
+ // visit all children, at least one of them needs to have proper
+ // name set
+ const std::vector<LayoutAtomPtr>& rChildren=rAtom.getChildren();
+ std::for_each( rChildren.begin(), rChildren.end(),
+ [this] (LayoutAtomPtr const& pAtom) { pAtom->accept(*this); } );
+}
+
+void ShallowPresNameVisitor::visit(ConstraintAtom& /*rAtom*/)
+{
+ // stop processing
+}
+
+void ShallowPresNameVisitor::visit(AlgAtom& /*rAtom*/)
+{
+ // stop processing
+}
+
+void ShallowPresNameVisitor::visit(ForEachAtom& rAtom)
+{
+ defaultVisit(rAtom);
+}
+
+void ShallowPresNameVisitor::visit(ConditionAtom& rAtom)
+{
+ defaultVisit(rAtom);
+}
+
+void ShallowPresNameVisitor::visit(ChooseAtom& rAtom)
+{
+ defaultVisit(rAtom);
+}
+
+void ShallowPresNameVisitor::visit(LayoutNode& rAtom)
+{
+ DiagramData::PointsNameMap::const_iterator aDataNode=
+ mrDgm.getData()->getPointsPresNameMap().find(rAtom.getName());
+ if( aDataNode != mrDgm.getData()->getPointsPresNameMap().end() )
+ mnCnt = std::max(mnCnt,
+ aDataNode->second.size());
+}
+
+} }
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/oox/source/drawingml/diagram/layoutatomvisitors.hxx b/oox/source/drawingml/diagram/layoutatomvisitors.hxx
new file mode 100755
index 000000000000..9353f4ba0a4b
--- /dev/null
+++ b/oox/source/drawingml/diagram/layoutatomvisitors.hxx
@@ -0,0 +1,103 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_OOX_SOURCE_DRAWINGML_DIAGRAM_LAYOUTATOMVISITORS_HXX
+#define INCLUDED_OOX_SOURCE_DRAWINGML_DIAGRAM_LAYOUTATOMVISITORS_HXX
+
+#include <memory>
+
+#include "oox/drawingml/shape.hxx"
+#include "diagram.hxx"
+#include "diagramlayoutatoms.hxx"
+
+namespace oox { namespace drawingml {
+
+class ShapeCreationVisitor : public LayoutAtomVisitor
+{
+ ShapePtr mpParentShape;
+ const Diagram& mrDgm;
+ sal_Int32 mnCurrIdx;
+
+ void defaultVisit(LayoutAtom& rAtom);
+ virtual void visit(ConstraintAtom& rAtom) override;
+ virtual void visit(AlgAtom& rAtom) override;
+ virtual void visit(ForEachAtom& rAtom) override;
+ virtual void visit(ConditionAtom& rAtom) override;
+ virtual void visit(ChooseAtom& rAtom) override;
+ virtual void visit(LayoutNode& rAtom) override;
+
+public:
+ ShapeCreationVisitor(const ShapePtr& rParentShape,
+ const Diagram& rDgm) :
+ mpParentShape(rParentShape),
+ mrDgm(rDgm),
+ mnCurrIdx(0)
+ {}
+};
+
+class ShapeLayoutingVisitor : public LayoutAtomVisitor
+{
+ ShapePtr mpParentShape;
+ OUString maName;
+
+ virtual void visit(ConstraintAtom& rAtom) override;
+ virtual void visit(AlgAtom& rAtom) override;
+ virtual void visit(ForEachAtom& rAtom) override;
+ virtual void visit(ConditionAtom& rAtom) override;
+ virtual void visit(ChooseAtom& rAtom) override;
+ virtual void visit(LayoutNode& rAtom) override;
+
+public:
+ ShapeLayoutingVisitor(const ShapePtr& rParentShape,
+ const OUString& rName) :
+ mpParentShape(rParentShape),
+ maName(rName)
+ {}
+
+ void defaultVisit(LayoutAtom& rAtom);
+};
+
+class ShallowPresNameVisitor : public LayoutAtomVisitor
+{
+ const Diagram& mrDgm;
+ size_t mnCnt;
+
+ void defaultVisit(LayoutAtom& rAtom);
+ virtual void visit(ConstraintAtom& rAtom) override;
+ virtual void visit(AlgAtom& rAtom) override;
+ virtual void visit(ForEachAtom& rAtom) override;
+ virtual void visit(ConditionAtom& rAtom) override;
+ virtual void visit(ChooseAtom& rAtom) override;
+ virtual void visit(LayoutNode& rAtom) override;
+
+public:
+ explicit ShallowPresNameVisitor(const Diagram& rDgm) :
+ mrDgm(rDgm),
+ mnCnt(0)
+ {}
+
+ size_t getCount() const
+ { return mnCnt; }
+};
+
+} }
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
More information about the Libreoffice-commits
mailing list