2025-03-23 XLStyles XLFont: bool getters now return true when val attribute is omitted

This commit is contained in:
Lars Uffmann 2025-03-24 00:14:59 +01:00
parent 5160060320
commit d25f089908
No known key found for this signature in database
3 changed files with 35 additions and 22 deletions

View File

@ -701,31 +701,16 @@ XLColor XLFont::fontColor() const
/**
* @details getter functions: return the font's bold, italic, underline, strikethrough status
*/
bool XLFont::bold() const { return appendAndGetNodeAttribute(*m_fontNode, "b", "val", "false").as_bool() ; }
bool XLFont::italic() const { return appendAndGetNodeAttribute(*m_fontNode, "i", "val", "false").as_bool() ; }
bool XLFont::strikethrough() const {
if (m_fontNode->empty()) return false;
XMLNode strikeNode = m_fontNode->child("strike");
if( strikeNode.empty() ) // no strike node: return false
return false;
// if execution gets here: strike node is not empty
XMLAttribute valAttr = strikeNode.attribute("val");
if( valAttr.empty() ) { // if no val attribute exists: default to true as per specification
appendAndSetAttribute(strikeNode, "val", "true" ); // explicitly create & set attribute
return true;
}
// if execution gets here: attribute val exists
return valAttr.as_bool(); // return attribute value
}
bool XLFont::bold() const { return getBoolAttributeWhenOmittedMeansTrue(*m_fontNode, "b", "val"); }
bool XLFont::italic() const { return getBoolAttributeWhenOmittedMeansTrue(*m_fontNode, "i", "val"); }
bool XLFont::strikethrough() const { return getBoolAttributeWhenOmittedMeansTrue(*m_fontNode, "strike", "val"); }
XLUnderlineStyle XLFont::underline() const { return XLUnderlineStyleFromString (appendAndGetNodeAttribute(*m_fontNode, "u", "val", "" ).value() ); }
XLFontSchemeStyle XLFont::scheme() const { return XLFontSchemeStyleFromString (appendAndGetNodeAttribute(*m_fontNode, "scheme", "val", "" ).value() ); }
XLVerticalAlignRunStyle XLFont::vertAlign() const { return XLVerticalAlignRunStyleFromString(appendAndGetNodeAttribute(*m_fontNode, "vertAlign", "val", "" ).value() ); }
bool XLFont::outline() const { return appendAndGetNodeAttribute(*m_fontNode, "outline", "val", "false").as_bool() ; }
bool XLFont::shadow() const { return appendAndGetNodeAttribute(*m_fontNode, "shadow", "val", "false").as_bool() ; }
bool XLFont::condense() const { return appendAndGetNodeAttribute(*m_fontNode, "condense", "val", "false").as_bool() ; }
bool XLFont::extend() const { return appendAndGetNodeAttribute(*m_fontNode, "extend", "val", "false").as_bool() ; }
bool XLFont::outline() const { return getBoolAttributeWhenOmittedMeansTrue(*m_fontNode, "outline", "val"); }
bool XLFont::shadow() const { return getBoolAttributeWhenOmittedMeansTrue(*m_fontNode, "shadow", "val"); }
bool XLFont::condense() const { return getBoolAttributeWhenOmittedMeansTrue(*m_fontNode, "condense", "val"); }
bool XLFont::extend() const { return getBoolAttributeWhenOmittedMeansTrue(*m_fontNode, "extend", "val"); }
/**
* @details Setter functions

View File

@ -450,6 +450,30 @@ namespace OpenXLSX
if (removeAttributes) node.remove_attributes();
return appendAndSetAttribute(node, attrName, attrVal);
}
/**
* @brief special bool attribute getter function for tags that should have a val="true" or val="false" attribute,
* but when omitted shall default to "true"
* @param parent node under which tagName shall be found
* @param tagName name of the boolean tag to evaluate
* @param attrName (default: "val") name of boolean attribute that shall default to true
* @returns true if parent & tagName exist, and attribute with attrName is either omitted or as_bool() returns true. Otherwise return false
* @note this will create and explicitly set attrName if omitted
*/
inline bool getBoolAttributeWhenOmittedMeansTrue( XMLNode & parent, std::string const & tagName, std::string const & attrName = "val" )
{
if (parent.empty()) return false; // can't do anything
XMLNode tagNode = parent.child(tagName.c_str());
if( tagNode.empty() ) return false; // if tag does not exist: return false
XMLAttribute valAttr = tagNode.attribute(attrName.c_str());
if( valAttr.empty() ) { // if no attribute with attrName exists: default to true
appendAndSetAttribute(tagNode, attrName, "true" ); // explicitly create & set attribute
return true;
}
// if execution gets here: attribute with attrName exists
return valAttr.as_bool(); // return attribute value
}
} // namespace OpenXLSX
#endif // OPENXLSX_XLUTILITIES_HPP

View File

@ -7,6 +7,10 @@ Microsoft Excel® files, with the .xlsx format.
As the heading says - the latest "Release" that is shown on https://github.com/troldal/OpenXLSX/releases is from 2021-11-06, and severely outdated - please pull / download the latest SW version directly from the repository in its current state. Link for those that do not want to use ```git```: https://github.com/troldal/OpenXLSX/archive/refs/heads/master.zip
## (aral-matrix) 23 March 2025 - XLStyles: get bool settings when omitted attribute shall default to true - addresses #347
* added function ```getBoolAttributeWhenOmittedMeansTrue``` to ```XLUtilities```
* ```XLStyles``` ```XLFont```: changed bool getter functions to return ```true``` when tag exists, but attribute ```val``` is omitted, to be in line with OOXML spec. This addresses https://github.com/troldal/OpenXLSX/issues/347. Affected getters: ```bold()```, ```italic()```, ```strikethrough()```, ```outline()```, ```shadow()```, ```condense()```, ```extend()```
## (aral-matrix) 16 March 2025 - XLSheet::findCell added to address #333, setting an XLFormula to an empty string now deletes the formula
* added function(s) ```XLSheet::findCell``` that allow to try and fetch a cell without creating the row/cell XML (like the non-creating XLCellIterator). This function complements ```XLSheet::cell``` (which always creates the XML cell node and returns a valid object)
* after using ```findCell```, the returned ```XLCellAssignable::empty()``` method must be checked to ensure success before accessing any cell properties