/** Returns the boolean value from the passed string of an attribute in the x: namespace(VMLforspreadsheets).Supportedvalues:f,t,False,True. @parambDefaultForEmptyDefaultvaluefortheemptystring.
*/ bool lclDecodeVmlxBool( std::u16string_view rValue, bool bDefaultForEmpty )
{ if( rValue.empty() ) return bDefaultForEmpty;
sal_Int32 nToken = AttributeConversion::decodeToken( rValue ); // anything else than 't' or 'True' is considered to be false, as specified return (nToken == XML_t) || (nToken == XML_True);
}
void ClientDataContext::onCharacters( const OUString& rChars )
{ /* Empty but existing elements have special meaning, e.g. 'true'. Collect
existing text and convert it in onEndElement(). */
maElementText = rChars;
}
void ClientDataContext::onEndElement()
{ switch( getCurrentElement() )
{ case VMLX_TOKEN( Anchor ): mrClientData.maAnchor = maElementText; break; case VMLX_TOKEN( FmlaMacro ): mrClientData.maFmlaMacro = maElementText; break; case VMLX_TOKEN( FmlaPict ): mrClientData.maFmlaPict = maElementText; break; case VMLX_TOKEN( FmlaLink ): mrClientData.maFmlaLink = maElementText; break; case VMLX_TOKEN( FmlaRange ): mrClientData.maFmlaRange = maElementText; break; case VMLX_TOKEN( FmlaGroup ): mrClientData.maFmlaGroup = maElementText; break; case VMLX_TOKEN( TextHAlign ): mrClientData.mnTextHAlign = AttributeConversion::decodeToken( maElementText ); break; case VMLX_TOKEN( TextVAlign ): mrClientData.mnTextVAlign = AttributeConversion::decodeToken( maElementText ); break; case VMLX_TOKEN( Column ): mrClientData.mnCol = maElementText.toInt32(); break; case VMLX_TOKEN( Row ): mrClientData.mnRow = maElementText.toInt32(); break; case VMLX_TOKEN( Checked ): mrClientData.mnChecked = maElementText.toInt32(); break; case VMLX_TOKEN( DropStyle ): mrClientData.mnDropStyle = AttributeConversion::decodeToken( maElementText ); break; case VMLX_TOKEN( DropLines ): mrClientData.mnDropLines = maElementText.toInt32(); break; case VMLX_TOKEN( Val ): mrClientData.mnVal = maElementText.toInt32(); break; case VMLX_TOKEN( Min ): mrClientData.mnMin = maElementText.toInt32(); break; case VMLX_TOKEN( Max ): mrClientData.mnMax = maElementText.toInt32(); break; case VMLX_TOKEN( Inc ): mrClientData.mnInc = maElementText.toInt32(); break; case VMLX_TOKEN( Page ): mrClientData.mnPage = maElementText.toInt32(); break; case VMLX_TOKEN( SelType ): mrClientData.mnSelType = AttributeConversion::decodeToken( maElementText ); break; case VMLX_TOKEN( VTEdit ): mrClientData.mnVTEdit = maElementText.toInt32(); break; case VMLX_TOKEN( PrintObject ): mrClientData.mbPrintObject = lclDecodeVmlxBool( maElementText, true ); break; case VMLX_TOKEN( Visible ): mrClientData.mbVisible = lclDecodeVmlxBool( maElementText, true ); break; case VMLX_TOKEN( DDE ): mrClientData.mbDde = lclDecodeVmlxBool( maElementText, true ); break; case VMLX_TOKEN( NoThreeD ): mrClientData.mbNo3D = lclDecodeVmlxBool( maElementText, true ); break; case VMLX_TOKEN( NoThreeD2 ): mrClientData.mbNo3D2 = lclDecodeVmlxBool( maElementText, true ); break; case VMLX_TOKEN( MultiLine ): mrClientData.mbMultiLine = lclDecodeVmlxBool( maElementText, true ); break; case VMLX_TOKEN( VScroll ): mrClientData.mbVScroll = lclDecodeVmlxBool( maElementText, true ); break; case VMLX_TOKEN( SecretEdit ): mrClientData.mbSecretEdit = lclDecodeVmlxBool( maElementText, true ); break;
}
}
ShapeTypeContext::ShapeTypeContext(ContextHandler2Helper const & rParent,
std::shared_ptr<ShapeType> const& pShapeType, const AttributeList& rAttribs)
: ShapeContextBase(rParent)
, m_pShapeType(pShapeType) // tdf#112311 keep it alive
, mrTypeModel( pShapeType->getTypeModel() )
{ // shape identifier and shape name bool bHasOspid = rAttribs.hasAttribute( O_TOKEN( spid ) );
mrTypeModel.maShapeId = rAttribs.getXString( bHasOspid ? O_TOKEN( spid ) : XML_id, OUString() );
mrTypeModel.maLegacyId = rAttribs.getStringDefaulted( XML_id);
OSL_ENSURE( !mrTypeModel.maShapeId.isEmpty(), "ShapeTypeContext::ShapeTypeContext - missing shape identifier" ); // builtin shape type identifier
mrTypeModel.moShapeType = rAttribs.getInteger( O_TOKEN( spt ) ); // if the o:spid attribute exists, the id attribute contains the user-defined shape name if( bHasOspid )
{
mrTypeModel.maShapeName = rAttribs.getXString( XML_id, OUString() ); // get ShapeType and ShapeId from name for compatibility static constexpr OUString sShapeTypePrefix = u"shapetype_"_ustr;
std::u16string_view tmp; if( mrTypeModel.maShapeName.startsWith( sShapeTypePrefix ) )
{
mrTypeModel.maShapeId = mrTypeModel.maShapeName;
mrTypeModel.moShapeType = o3tl::toInt32(mrTypeModel.maShapeName.subView(sShapeTypePrefix.getLength()));
} elseif (mrTypeModel.maShapeName.startsWith("_x0000_t", &tmp))
{
mrTypeModel.maShapeId = mrTypeModel.maShapeName;
mrTypeModel.moShapeType = o3tl::toInt32(tmp);
}
}
// coordinate system position/size, CSS style
mrTypeModel.moCoordPos = lclDecodeInt32Pair( rAttribs, XML_coordorigin );
mrTypeModel.moCoordSize = lclDecodeInt32Pair( rAttribs, XML_coordsize );
setStyle( rAttribs.getStringDefaulted( XML_style) ); if( lclDecodeBool( rAttribs, O_TOKEN( hr )).value_or( false ))
{ // MSO's handling of o:hr width is nowhere near what the spec says: // - o:hrpct is not in % but in 0.1% // - if o:hrpct is not given, 100% width is assumed // - given width is used only if explicit o:hrpct="0" is given
OUString hrpct = rAttribs.getString( O_TOKEN( hrpct ), u"1000"_ustr ); if( hrpct != "0" )
mrTypeModel.maWidthPercent = OUString::number( hrpct.toInt32() );
mrTypeModel.maWrapDistanceLeft = "0";
mrTypeModel.maWrapDistanceRight = "0";
mrTypeModel.maPositionHorizontal = rAttribs.getString( O_TOKEN( hralign ), u"left"_ustr );
mrTypeModel.moWrapType = "topAndBottom";
}
// stroke settings (may be overridden by v:stroke element later)
mrTypeModel.maStrokeModel.moStroked = lclDecodeBool( rAttribs, XML_stroked );
mrTypeModel.maStrokeModel.moColor = rAttribs.getString( XML_strokecolor );
mrTypeModel.maStrokeModel.moWeight = rAttribs.getString( XML_strokeweight );
// fill settings (may be overridden by v:fill element later)
mrTypeModel.maFillModel.moFilled = lclDecodeBool( rAttribs, XML_filled );
mrTypeModel.maFillModel.moColor = rAttribs.getString( XML_fillcolor );
// For roundrect we may have an arcsize attribute to read
mrTypeModel.maArcsize = rAttribs.getStringDefaulted(XML_arcsize); // editas
mrTypeModel.maEditAs = rAttribs.getStringDefaulted(XML_editas);
ContextHandlerRef ShapeContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
{ // Excel specific shape client data if( isRootElement() ) switch( nElement )
{ case VML_TOKEN( textbox ):
{ // Calculate the shape type: map both <rect> and <v:shape> with a textbox shape type to // a TextShape.
sal_Int32 nShapeType = 0; if (ShapeContainer* pShapeContainer = mrShape.getContainer())
{
OUString aType = mrShapeModel.maType; if (!aType.isEmpty() && aType[0] == '#')
{
aType = aType.copy(1);
} if (const ShapeType* pShapeType = pShapeContainer->getShapeTypeById(aType))
{
nShapeType = pShapeType->getTypeModel().moShapeType.value();
}
}
mrShapeModel.mbInGroup = (getParentElement() == VML_TOKEN(group));
// FIXME: the shape with textbox should be used for the next cases if (getCurrentElement() == VML_TOKEN(rect) || nShapeType == ESCHER_ShpInst_TextBox)
{ if (mrShapeModel.mbInGroup) // FIXME: without this a text will be added into the group-shape instead of its // parent shape
{ if (mrShape.isTextBox()) dynamic_cast<SimpleShape&>(mrShape).setService(
u"com.sun.star.drawing.CustomShape"_ustr); else dynamic_cast<SimpleShape&>(mrShape).setService(
u"com.sun.star.drawing.TextShape"_ustr);
} else // FIXME: without this we does not handle some properties like shadow dynamic_cast<SimpleShape&>(mrShape).setService(u"com.sun.star.text.TextFrame"_ustr);
} returnnew TextBoxContext( *this, mrShapeModel.createTextBox(mrShape.getTypeModel()), rAttribs,
mrShape.getDrawing().getFilter().getGraphicHelper());
} case VMLX_TOKEN( ClientData ): // tdf#41466 ActiveX control shapes with a textbox are transformed into a frame // (see unit test testActiveXOptionButtonGroup) dynamic_cast<SimpleShape&>(mrShape).setService(u"com.sun.star.text.TextFrame"_ustr); returnnew ClientDataContext( *this, mrShapeModel.createClientData(), rAttribs ); case VMLPPT_TOKEN( textdata ): // Force RectangleShape, this is ugly :( // and is there because of the lines above which change it to TextFrame dynamic_cast< SimpleShape& >( mrShape ).setService(
u"com.sun.star.drawing.RectangleShape"_ustr);
mrShapeModel.maLegacyDiagramPath = getFragmentPathFromRelId(rAttribs.getStringDefaulted(XML_id)); break; case O_TOKEN( signatureline ):
mrShapeModel.mbIsSignatureLine = true;
mrShapeModel.maSignatureId = rAttribs.getStringDefaulted(XML_id);
mrShapeModel.maSignatureLineSuggestedSignerName
= rAttribs.getStringDefaulted(O_TOKEN(suggestedsigner));
mrShapeModel.maSignatureLineSuggestedSignerTitle
= rAttribs.getStringDefaulted(O_TOKEN(suggestedsigner2));
mrShapeModel.maSignatureLineSuggestedSignerEmail
= rAttribs.getStringDefaulted(O_TOKEN(suggestedsigneremail));
mrShapeModel.maSignatureLineSigningInstructions
= rAttribs.getStringDefaulted(O_TOKEN(signinginstructions));
mrShapeModel.mbSignatureLineShowSignDate = ConversionHelper::decodeBool(
rAttribs.getString(XML_showsigndate, u"t"_ustr)); // default is true
mrShapeModel.mbSignatureLineCanAddComment = ConversionHelper::decodeBool(
rAttribs.getString(XML_allowcomments, u"f"_ustr)); // default is false break; case O_TOKEN( lock ): // TODO break;
} // handle remaining stuff in base class return ShapeTypeContext::onCreateContext( nElement, rAttribs );
} void ShapeContext::setWriterShape()
{
mrShape.setTextBox(true);
}
while (nIndex >= 0)
{
sal_Int32 nX = ConversionHelper::decodeMeasureToTwip(
mrShape.getDrawing().getFilter().getGraphicHelper(), o3tl::getToken(rPoints, 0, ',', nIndex), 0, true, true);
sal_Int32 nY = ConversionHelper::decodeMeasureToTwip(
mrShape.getDrawing().getFilter().getGraphicHelper(), o3tl::getToken(rPoints, 0, ',', nIndex), 0, false, true);
mrShapeModel.maPoints.emplace_back(nX, nY);
} // VML polyline has no size in its style attribute. Word writes the size to attribute // coordsize with values in twip but without unit. For others we get size from points. if (!mrShape.getTypeModel().maWidth.isEmpty() || !mrShape.getTypeModel().maHeight.isEmpty()) return;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.