This is an automated email from the ASF dual-hosted git repository.

jimjag pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/openoffice.git

commit dadd651f52f1b9ef2dfee0bdde61aa44a31cd418
Author: Jim Jagielski <[email protected]>
AuthorDate: Tue Nov 3 06:13:26 2026 -0500

    Write the ODF 1.4 draw:handle attributes, form:input-required and chart 
plot-area as ODF 1.4 requires
---
 main/xmloff/inc/EnhancedCustomShapeToken.hxx       |  6 ++
 main/xmloff/inc/xmloff/xmltoken.hxx                |  8 +++
 main/xmloff/source/chart/SchXMLExport.cxx          |  3 +-
 main/xmloff/source/core/xmltoken.cxx               |  8 +++
 .../source/draw/EnhancedCustomShapeToken.cxx       |  6 ++
 main/xmloff/source/draw/shapeexport4.cxx           | 27 ++++++++
 main/xmloff/source/draw/ximpcustomshape.cxx        | 76 ++++++++++++++++++++++
 main/xmloff/source/forms/elementexport.cxx         |  7 +-
 main/xmloff/source/forms/elementimport.cxx         |  6 ++
 9 files changed, 144 insertions(+), 3 deletions(-)

diff --git a/main/xmloff/inc/EnhancedCustomShapeToken.hxx 
b/main/xmloff/inc/EnhancedCustomShapeToken.hxx
index 18cc2f83c3..706b37d2a4 100644
--- a/main/xmloff/inc/EnhancedCustomShapeToken.hxx
+++ b/main/xmloff/inc/EnhancedCustomShapeToken.hxx
@@ -88,6 +88,12 @@ namespace xmloff { namespace EnhancedCustomShapeToken {
                EAS_handle_polar,
                EAS_handle_radius_range_minimum,
                EAS_handle_radius_range_maximum,
+               EAS_handle_position_x,
+               EAS_handle_position_y,
+               EAS_handle_polar_pole_x,
+               EAS_handle_polar_pole_y,
+               EAS_handle_polar_radius,
+               EAS_handle_polar_angle,
 
                EAS_CustomShapeEngine,
                EAS_CustomShapeData,
diff --git a/main/xmloff/inc/xmloff/xmltoken.hxx 
b/main/xmloff/inc/xmloff/xmltoken.hxx
index c5f8e0ec73..46f3a003a6 100644
--- a/main/xmloff/inc/xmloff/xmltoken.hxx
+++ b/main/xmloff/inc/xmloff/xmltoken.hxx
@@ -3152,6 +3152,14 @@ namespace xmloff { namespace token {
         // ODF 1.3
         XML_CREATOR_INITIALS,
 
+        // ODF 1.4
+        XML_HANDLE_POSITION_X,
+        XML_HANDLE_POSITION_Y,
+        XML_HANDLE_POLAR_POLE_X,
+        XML_HANDLE_POLAR_POLE_Y,
+        XML_HANDLE_POLAR_RADIUS,
+        XML_HANDLE_POLAR_ANGLE,
+
         XML_TOKEN_END
     };
 
diff --git a/main/xmloff/source/chart/SchXMLExport.cxx 
b/main/xmloff/source/chart/SchXMLExport.cxx
index 32e0598d58..488db2fa33 100644
--- a/main/xmloff/source/chart/SchXMLExport.cxx
+++ b/main/xmloff/source/chart/SchXMLExport.cxx
@@ -2000,7 +2000,8 @@ void SchXMLExportHelper_Impl::exportPlotArea(
 
         if( msChartAddress.getLength() )
         {
-            if( !bIncludeTable )
+            // ODF 1.4 removed table:cell-range-address from chart:plot-area; 
the importer takes the data from the series ranges
+            if( !bIncludeTable && mrExport.getDefaultVersion() < 
SvtSaveOptions::ODFVER_014 )
                 mrExport.AddAttribute( XML_NAMESPACE_TABLE, 
XML_CELL_RANGE_ADDRESS, msChartAddress );
 
             Reference< chart::XChartDocument > xDoc( mrExport.GetModel(), 
uno::UNO_QUERY );
diff --git a/main/xmloff/source/core/xmltoken.cxx 
b/main/xmloff/source/core/xmltoken.cxx
index eeab76506a..b2f2b93607 100644
--- a/main/xmloff/source/core/xmltoken.cxx
+++ b/main/xmloff/source/core/xmltoken.cxx
@@ -3152,6 +3152,14 @@ namespace xmloff { namespace token {
         // ODF 1.3
         TOKEN( "creator-initials",             XML_CREATOR_INITIALS ),
 
+        // ODF 1.4
+        TOKEN( "handle-position-x",            XML_HANDLE_POSITION_X ),
+        TOKEN( "handle-position-y",            XML_HANDLE_POSITION_Y ),
+        TOKEN( "handle-polar-pole-x",          XML_HANDLE_POLAR_POLE_X ),
+        TOKEN( "handle-polar-pole-y",          XML_HANDLE_POLAR_POLE_Y ),
+        TOKEN( "handle-polar-radius",          XML_HANDLE_POLAR_RADIUS ),
+        TOKEN( "handle-polar-angle",           XML_HANDLE_POLAR_ANGLE ),
+
 #if OSL_DEBUG_LEVEL > 0
         { 0, NULL, NULL,                       XML_TOKEN_END }
 #else
diff --git a/main/xmloff/source/draw/EnhancedCustomShapeToken.cxx 
b/main/xmloff/source/draw/EnhancedCustomShapeToken.cxx
index a7d223a54b..64ceed8043 100644
--- a/main/xmloff/source/draw/EnhancedCustomShapeToken.cxx
+++ b/main/xmloff/source/draw/EnhancedCustomShapeToken.cxx
@@ -104,6 +104,12 @@ static const TokenTable pTokenTableArray[] =
        { "handle-polar",                                               
EAS_handle_polar },
        { "handle-radius-range-minimum",                
EAS_handle_radius_range_minimum },
        { "handle-radius-range-maximum",                
EAS_handle_radius_range_maximum },
+       { "handle-position-x",                                  
EAS_handle_position_x },
+       { "handle-position-y",                                  
EAS_handle_position_y },
+       { "handle-polar-pole-x",                                
EAS_handle_polar_pole_x },
+       { "handle-polar-pole-y",                                
EAS_handle_polar_pole_y },
+       { "handle-polar-radius",                                
EAS_handle_polar_radius },
+       { "handle-polar-angle",                         EAS_handle_polar_angle 
},
 
        { "CustomShapeEngine",                                  
EAS_CustomShapeEngine },
        { "CustomShapeData",                                    
EAS_CustomShapeData },
diff --git a/main/xmloff/source/draw/shapeexport4.cxx 
b/main/xmloff/source/draw/shapeexport4.cxx
index d91a50230c..6fee08701d 100644
--- a/main/xmloff/source/draw/shapeexport4.cxx
+++ b/main/xmloff/source/draw/shapeexport4.cxx
@@ -184,10 +184,16 @@ void ImpExportHandles( SvXMLExport& rExport, const 
uno::Sequence< beans::Propert
        {
                rtl::OUString           aStr;
                rtl::OUStringBuffer aStrBuffer;
+               // ODF 1.4 requires draw:handle-position-x/-y or 
draw:handle-polar-pole-x/-y with draw:handle-polar-radius/-angle;
+               // the deprecated draw:handle-position and draw:handle-polar 
stay, older AOO versions drop the handles without them
+               const sal_Bool bODF14 = rExport.getDefaultVersion() >= 
SvtSaveOptions::ODFVER_014;
 
                for ( i = 0; i < nElements; i++ )
                {
                        sal_Bool bPosition = sal_False;
+                       sal_Bool bPolar = sal_False;
+                       
com::sun::star::drawing::EnhancedCustomShapeParameterPair aPosition14;
+                       
com::sun::star::drawing::EnhancedCustomShapeParameterPair aPolar14;
                        const uno::Sequence< beans::PropertyValue >& rPropSeq = 
rHandles[ i ];
                        for ( j = 0; j < (sal_uInt32)rPropSeq.getLength(); j++ )
                        {
@@ -199,6 +205,7 @@ void ImpExportHandles( SvXMLExport& rExport, const 
uno::Sequence< beans::Propert
                                                
com::sun::star::drawing::EnhancedCustomShapeParameterPair aPosition;
                                                if ( rPropVal.Value >>= 
aPosition )
                                                {
+                                                       aPosition14 = aPosition;
                                                        ExportParameter( 
aStrBuffer, aPosition.First );
                                                        ExportParameter( 
aStrBuffer, aPosition.Second );
                                                        aStr = 
aStrBuffer.makeStringAndClear();
@@ -236,6 +243,8 @@ void ImpExportHandles( SvXMLExport& rExport, const 
uno::Sequence< beans::Propert
                                                
com::sun::star::drawing::EnhancedCustomShapeParameterPair aPolar;
                                                if ( rPropVal.Value >>= aPolar )
                                                {
+                                                       aPolar14 = aPolar;
+                                                       bPolar = sal_True;
                                                        ExportParameter( 
aStrBuffer, aPolar.First );
                                                        ExportParameter( 
aStrBuffer, aPolar.Second );
                                                        aStr = 
aStrBuffer.makeStringAndClear();
@@ -313,6 +322,24 @@ void ImpExportHandles( SvXMLExport& rExport, const 
uno::Sequence< beans::Propert
                                                break;
                                }
                        }
+                       if ( bPosition && bODF14 )
+                       {
+                               // a polar handle has its pole in the polar 
pair and its radius and angle in the position pair
+                               const XMLTokenEnum eFirst = bPolar ? 
XML_HANDLE_POLAR_POLE_X : XML_HANDLE_POSITION_X;
+                               const XMLTokenEnum eSecond = bPolar ? 
XML_HANDLE_POLAR_POLE_Y : XML_HANDLE_POSITION_Y;
+                               const 
com::sun::star::drawing::EnhancedCustomShapeParameterPair& rFirst = bPolar ? 
aPolar14 : aPosition14;
+                               ExportParameter( aStrBuffer, rFirst.First );
+                               rExport.AddAttribute( XML_NAMESPACE_DRAW, 
eFirst, aStrBuffer.makeStringAndClear() );
+                               ExportParameter( aStrBuffer, rFirst.Second );
+                               rExport.AddAttribute( XML_NAMESPACE_DRAW, 
eSecond, aStrBuffer.makeStringAndClear() );
+                               if ( bPolar )
+                               {
+                                       ExportParameter( aStrBuffer, 
aPosition14.First );
+                                       rExport.AddAttribute( 
XML_NAMESPACE_DRAW, XML_HANDLE_POLAR_RADIUS, aStrBuffer.makeStringAndClear() );
+                                       ExportParameter( aStrBuffer, 
aPosition14.Second );
+                                       rExport.AddAttribute( 
XML_NAMESPACE_DRAW, XML_HANDLE_POLAR_ANGLE, aStrBuffer.makeStringAndClear() );
+                               }
+                       }
                        if ( bPosition )
                                SvXMLElementExport aOBJ( rExport, 
XML_NAMESPACE_DRAW, XML_HANDLE, sal_True, sal_True );
                        else
diff --git a/main/xmloff/source/draw/ximpcustomshape.cxx 
b/main/xmloff/source/draw/ximpcustomshape.cxx
index af08fbb94a..364a2dd8eb 100644
--- a/main/xmloff/source/draw/ximpcustomshape.cxx
+++ b/main/xmloff/source/draw/ximpcustomshape.cxx
@@ -1379,6 +1379,11 @@ SvXMLImportContext* 
XMLEnhancedCustomShapeContext::CreateChildContext( sal_uInt1
        else if ( aTokenEnum == EAS_handle )
        {
                std::vector< com::sun::star::beans::PropertyValue > aHandle;
+        // ODF 1.4: draw:handle-position-x/-y, or draw:handle-polar-pole-x/-y 
with -radius and -angle;
+        // the old draw:handle-position and draw:handle-polar win when both 
forms are present
+               bool bHasPosition = false, bHasPolar = false;
+               com::sun::star::drawing::EnhancedCustomShapeParameter aPosX, 
aPosY, aPoleX, aPoleY, aRadius, aAngle;
+               bool bPosX = false, bPosY = false, bPoleX = false, bPoleY = 
false, bRadius = false, bAngle = false;
         const sal_Int16 nLength = xAttrList->getLength();
                for( sal_Int16 nAttr = 0; nAttr < nLength; nAttr++ )
                {
@@ -1398,6 +1403,43 @@ SvXMLImportContext* 
XMLEnhancedCustomShapeContext::CreateChildContext( sal_uInt1
                                break;
                                case EAS_handle_position :
                                        GetEnhancedParameterPair( aHandle, 
rValue, EAS_Position );
+                                       bHasPosition = true;
+                               break;
+                               case EAS_handle_position_x :
+                               {
+                                       sal_Int32 nIndex = 0;
+                                       bPosX = GetNextParameter( aPosX, 
nIndex, rValue );
+                               }
+                               break;
+                               case EAS_handle_position_y :
+                               {
+                                       sal_Int32 nIndex = 0;
+                                       bPosY = GetNextParameter( aPosY, 
nIndex, rValue );
+                               }
+                               break;
+                               case EAS_handle_polar_pole_x :
+                               {
+                                       sal_Int32 nIndex = 0;
+                                       bPoleX = GetNextParameter( aPoleX, 
nIndex, rValue );
+                               }
+                               break;
+                               case EAS_handle_polar_pole_y :
+                               {
+                                       sal_Int32 nIndex = 0;
+                                       bPoleY = GetNextParameter( aPoleY, 
nIndex, rValue );
+                               }
+                               break;
+                               case EAS_handle_polar_radius :
+                               {
+                                       sal_Int32 nIndex = 0;
+                                       bRadius = GetNextParameter( aRadius, 
nIndex, rValue );
+                               }
+                               break;
+                               case EAS_handle_polar_angle :
+                               {
+                                       sal_Int32 nIndex = 0;
+                                       bAngle = GetNextParameter( aAngle, 
nIndex, rValue );
+                               }
                                break;
                                case EAS_handle_range_x_minimum :
                                        GetEnhancedParameter( aHandle, rValue, 
EAS_RangeXMinimum );
@@ -1413,6 +1455,7 @@ SvXMLImportContext* 
XMLEnhancedCustomShapeContext::CreateChildContext( sal_uInt1
                                break;
                                case EAS_handle_polar :
                                        GetEnhancedParameterPair( aHandle, 
rValue, EAS_Polar );
+                                       bHasPolar = true;
                                break;
                                case EAS_handle_radius_range_minimum :
                                        GetEnhancedParameter( aHandle, rValue, 
EAS_RadiusRangeMinimum );
@@ -1424,6 +1467,39 @@ SvXMLImportContext* 
XMLEnhancedCustomShapeContext::CreateChildContext( sal_uInt1
                                        break;
                        }
                }
+               if ( !bHasPosition && !bHasPolar )
+               {
+                       beans::PropertyValue aProp;
+                       
com::sun::star::drawing::EnhancedCustomShapeParameterPair aPair;
+                       if ( bPosX && bPosY )
+                       {
+                               aPair.First = aPosX;
+                               aPair.Second = aPosY;
+                               aProp.Name = EASGet( EAS_Position );
+                               aProp.Value <<= aPair;
+                               aHandle.push_back( aProp );
+                       }
+                       else if ( bPoleX && bPoleY )
+                       {
+                               aPair.First = aPoleX;
+                               aPair.Second = aPoleY;
+                               aProp.Name = EASGet( EAS_Polar );
+                               aProp.Value <<= aPair;
+                               aHandle.push_back( aProp );
+                               // the handle position of a polar handle is its 
radius and angle, both 0 when absent
+                               sal_Int32 nIndex = 0;
+                               if ( !bRadius )
+                                       GetNextParameter( aRadius, nIndex, 
rtl::OUString::createFromAscii( "0" ) );
+                               nIndex = 0;
+                               if ( !bAngle )
+                                       GetNextParameter( aAngle, nIndex, 
rtl::OUString::createFromAscii( "0" ) );
+                               aPair.First = aRadius;
+                               aPair.Second = aAngle;
+                               aProp.Name = EASGet( EAS_Position );
+                               aProp.Value <<= aPair;
+                               aHandle.push_back( aProp );
+                       }
+               }
                beans::PropertyValues aPropSeq( aHandle.size() );
                std::vector< beans::PropertyValue >::const_iterator aIter = 
aHandle.begin();
                std::vector< beans::PropertyValue >::const_iterator aEnd = 
aHandle.end();
diff --git a/main/xmloff/source/forms/elementexport.cxx 
b/main/xmloff/source/forms/elementexport.cxx
index 56038c9b8c..e7ff814888 100644
--- a/main/xmloff/source/forms/elementexport.cxx
+++ b/main/xmloff/source/forms/elementexport.cxx
@@ -918,14 +918,17 @@ namespace xmloff
         if ( DA_INPUT_REQUIRED & m_nIncludeDatabase )
         {
             // form:input-required is an ODF 1.4 attribute
-            if ( SvtSaveOptions::IsODFStrict( 
m_rContext.getGlobalContext().getDefaultVersion() ) )
+            const SvtSaveOptions::ODFDefaultVersion eVersion = 
m_rContext.getGlobalContext().getDefaultVersion();
+            if ( SvtSaveOptions::IsODFStrict( eVersion ) && eVersion < 
SvtSaveOptions::ODFVER_014 )
                 exportedProperty( PROPERTY_INPUT_REQUIRED );
             else
             exportBooleanPropertyAttribute(
                 OAttributeMetaData::getDatabaseAttributeNamespace( 
DA_INPUT_REQUIRED ),
                 OAttributeMetaData::getDatabaseAttributeName( 
DA_INPUT_REQUIRED ),
                 PROPERTY_INPUT_REQUIRED,
-                BOOLATTR_DEFAULT_TRUE
+                // the property is true by default and an absent attribute 
means true to older readers, but ODF 1.4
+                // defines the attribute as false by default: write it 
explicitly in the 1.4 modes
+                ( eVersion >= SvtSaveOptions::ODFVER_014 ) ? 
BOOLATTR_DEFAULT_VOID : BOOLATTR_DEFAULT_TRUE
             );
             RESET_BIT( nIncludeDatabase, DA_INPUT_REQUIRED );
         }
diff --git a/main/xmloff/source/forms/elementimport.cxx 
b/main/xmloff/source/forms/elementimport.cxx
index 76cd8e4e71..9310c4eb3f 100644
--- a/main/xmloff/source/forms/elementimport.cxx
+++ b/main/xmloff/source/forms/elementimport.cxx
@@ -54,6 +54,7 @@
 #include <tools/diagnose_ex.h>
 #include <tools/time.hxx>
 #include <rtl/logfile.hxx>
+#include <comphelper/documentconstants.hxx>
 #include <comphelper/extract.hxx>
 #include <comphelper/types.hxx>
 
@@ -852,6 +853,11 @@ namespace xmloff
                // let the base class handle all the attributes
                OElementImport::StartElement(xAttributes);
 
+               // ODF 1.4 defines form:input-required as false by default, the 
property is true by default
+               if ( m_xElement.is() && m_xInfo.is() && 
m_xInfo->hasPropertyByName( PROPERTY_INPUT_REQUIRED )
+                               && GetImport().GetODFVersion().compareTo( 
ODFVER_014_TEXT ) >= 0 )
+                       simulateDefaultedAttribute( 
OAttributeMetaData::getDatabaseAttributeName( DA_INPUT_REQUIRED ), 
PROPERTY_INPUT_REQUIRED, "false" );
+
                if ( !m_aValueProperties.empty() && m_xElement.is())
                {
                        // get the property set info

Reply via email to