void KoPAPage::loadOdfPageTag( const KoXmlElement &element, KoPALoadingContext &loadingContext ) { QString master = element.attributeNS (KoXmlNS::draw, "master-page-name" ); KoPAMasterPage *masterPage = loadingContext.masterPageByName(master); if (masterPage) setMasterPage(masterPage); #ifndef NDEBUG else kWarning(30010) << "Loading didn't provide a page under name; " << master; #endif KoStyleStack& styleStack = loadingContext.odfLoadingContext().styleStack(); int pageProperties = UseMasterBackground | DisplayMasterShapes | DisplayMasterBackground; if ( styleStack.hasProperty( KoXmlNS::draw, "fill" ) ) { KoPAPageBase::loadOdfPageTag( element, loadingContext ); pageProperties = DisplayMasterShapes; } m_pageProperties = pageProperties; QString name; if ( element.hasAttributeNS( KoXmlNS::draw, "name" ) ) { name = element.attributeNS( KoXmlNS::draw, "name" ); loadingContext.addPage( name, this ); } if ( element.hasAttributeNS( KoXmlNS::koffice, "name" ) ) { name = element.attributeNS( KoXmlNS::koffice, "name" ); } setName( name ); }
bool RectangleShape::loadOdf(const KoXmlElement &element, KoShapeLoadingContext &context) { loadOdfAttributes(element, context, OdfMandatories | OdfGeometry | OdfAdditionalAttributes | OdfCommonChildElements); if (element.hasAttributeNS(KoXmlNS::svg, "rx") && element.hasAttributeNS(KoXmlNS::svg, "ry")) { qreal rx = KoUnit::parseValue(element.attributeNS(KoXmlNS::svg, "rx", "0")); qreal ry = KoUnit::parseValue(element.attributeNS(KoXmlNS::svg, "ry", "0")); m_cornerRadiusX = rx / (0.5 * size().width()) * 100; m_cornerRadiusY = ry / (0.5 * size().height()) * 100; } else { QString cornerRadius = element.attributeNS(KoXmlNS::draw, "corner-radius", ""); if (! cornerRadius.isEmpty()) { qreal radius = KoUnit::parseValue(cornerRadius); m_cornerRadiusX = qMin<qreal>(radius / (0.5 * size().width()) * 100, qreal(100)); m_cornerRadiusY = qMin<qreal>(radius / (0.5 * size().height()) * 100, qreal(100)); } } updatePath(size()); updateHandles(); loadOdfAttributes(element, context, OdfTransformation); loadText(element, context); return true; }
bool KoPathShape::loadOdf(const KoXmlElement & element, KoShapeLoadingContext &context) { loadOdfAttributes(element, context, OdfMandatories | OdfAdditionalAttributes | OdfCommonChildElements); // first clear the path data from the default path clear(); if (element.localName() == "line") { QPointF start; start.setX(KoUnit::parseValue(element.attributeNS(KoXmlNS::svg, "x1", ""))); start.setY(KoUnit::parseValue(element.attributeNS(KoXmlNS::svg, "y1", ""))); QPointF end; end.setX(KoUnit::parseValue(element.attributeNS(KoXmlNS::svg, "x2", ""))); end.setY(KoUnit::parseValue(element.attributeNS(KoXmlNS::svg, "y2", ""))); moveTo(start); lineTo(end); } else if (element.localName() == "polyline" || element.localName() == "polygon") { QString points = element.attributeNS(KoXmlNS::draw, "points").simplified(); points.replace(',', ' '); points.remove('\r'); points.remove('\n'); bool firstPoint = true; const QStringList coordinateList = points.split(' '); for (QStringList::ConstIterator it = coordinateList.constBegin(); it != coordinateList.constEnd(); ++it) { QPointF point; point.setX((*it).toDouble()); ++it; point.setY((*it).toDouble()); if (firstPoint) { moveTo(point); firstPoint = false; } else lineTo(point); } if (element.localName() == "polygon") close(); } else { // path loading KoPathShapeLoader loader(this); loader.parseSvg(element.attributeNS(KoXmlNS::svg, "d"), true); loadNodeTypes(element); } applyViewboxTransformation(element); QPointF pos = normalize(); setTransformation(QMatrix()); if (element.hasAttributeNS(KoXmlNS::svg, "x") || element.hasAttributeNS(KoXmlNS::svg, "y")) { pos.setX(KoUnit::parseValue(element.attributeNS(KoXmlNS::svg, "x", QString()))); pos.setY(KoUnit::parseValue(element.attributeNS(KoXmlNS::svg, "y", QString()))); } setPosition(pos); loadOdfAttributes(element, context, OdfTransformation); return true; }
bool KoFormulaShape::loadOdfFrameElement(const KoXmlElement &element, KoShapeLoadingContext &context) { // If this formula is embedded and not inline, then load the embedded document. if ( element.tagName() == "object" && element.hasAttributeNS( KoXmlNS::xlink, "href" )) { m_isInline = false; // This calls loadOdfEmbedded(). return loadEmbeddedDocument( context.odfLoadingContext().store(), element, context.odfLoadingContext() ); } // It's not a frame:object, so it must be inline. const KoXmlElement& topLevelElement = KoXml::namedItemNS(element, KoXmlNS::math, "math"); if (topLevelElement.isNull()) { kWarning() << "no math element as first child"; return false; } // Create a new root element, load the formula and replace the old one. FormulaElement* formulaElement = new FormulaElement(); formulaElement->readMathML( topLevelElement ); delete m_formulaData->formulaElement(); m_formulaData->setFormulaElement(formulaElement); m_formulaData->notifyDataChange(0, false); m_isInline = true; return true; }
// Font size is a bit special. "115%" applies to "the fontsize of the parent style". // This can be generalized though (hasPropertyThatCanBePercentOfParent() ? :) qreal KoStyleStack::fontSize(const qreal defaultFontPointSize) const { const QString name = "font-size"; qreal percent = 1; QList<KoXmlElement>::ConstIterator it = m_stack.end(); // reverse iterator while (it != m_stack.begin()) { --it; KoXmlElement properties = KoXml::namedItemNS(*it, m_styleNSURI, m_propertiesTagName).toElement(); if (properties.hasAttributeNS(m_foNSURI, name)) { const QString value = properties.attributeNS(m_foNSURI, name, QString()); if (value.endsWith('%')) { //sebsauer, 20070609, the specs don't say that we have to calc them together but //just that we are looking for a valid parent fontsize. So, let's only take the //first percent definition into account and keep on to seek for a valid parent, //percent *= value.left( value.length() - 1 ).toDouble() / 100.0; if (percent == 1) percent = value.left(value.length() - 1).toDouble() / 100.0; } else return percent * KoUnit::parseValue(value); // e.g. 12pt } } //if there was no valid parent, we return the default fontsize together with an optional calculated percent-value. return percent * defaultFontPointSize; }
inline bool KoStyleStack::hasProperty(const QString &nsURI, const QString &name, const QString *detail) const { QString fullName(name); if (detail) { fullName += '-'; fullName += *detail; } QList<KoXmlElement>::ConstIterator it = m_stack.end(); while (it != m_stack.begin()) { --it; const KoXmlElement properties = KoXml::namedItemNS(*it, m_styleNSURI, m_propertiesTagName); if (properties.hasAttributeNS(nsURI, name) || (detail && properties.hasAttributeNS(nsURI, fullName))) return true; } return false; }
bool KPrPageLayout::loadOdf( const KoXmlElement &element, const QRectF & pageRect ) { if ( element.hasAttributeNS( KoXmlNS::style, "display-name" ) ) { m_name = element.attributeNS( KoXmlNS::style, "display-name" ); } else { m_name = element.attributeNS( KoXmlNS::style, "name" ); } KoXmlElement child; forEachElement( child, element ) { if ( child.tagName() == "placeholder" && child.namespaceURI() == KoXmlNS::presentation ) { KPrPlaceholder * placeholder = new KPrPlaceholder; if ( placeholder->loadOdf( child, pageRect ) ) { m_placeholders.append( placeholder ); if ( placeholder->presentationObject() == "handout" ) { m_layoutType = Handout; } } else { warnStage << "loading placeholder failed"; delete placeholder; } } else { warnStage << "unknown tag" << child.namespaceURI() << child.tagName() << "when loading page layout"; } } bool retval = true; if ( m_placeholders.isEmpty() ) { warnStage << "no placeholder for page layout" << m_name << "found"; retval = false; } else { /* * do fixups for wrong saved data from OO somehow they save negative values for width and height somethimes * <style:presentation-page-layout style:name="AL10T12"> * <presentation:placeholder presentation:object="title" svg:x="2.057cm" svg:y="1.743cm" svg:width="23.911cm" svg:height="3.507cm"/> * <presentation:placeholder presentation:object="outline" svg:x="2.057cm" svg:y="5.838cm" svg:width="11.669cm" svg:height="13.23cm"/> * <presentation:placeholder presentation:object="object" svg:x="14.309cm" svg:y="5.838cm" svg:width="-0.585cm" svg:height="6.311cm"/> * <presentation:placeholder presentation:object="object" svg:x="14.309cm" svg:y="12.748cm" svg:width="-0.585cm" svg:height="-0.601cm"/> * </style:presentation-page-layout> */ QList<KPrPlaceholder *>::iterator it( m_placeholders.begin() ); KPrPlaceholder * last = *it; ++it; for ( ; it != m_placeholders.end(); ++it ) { ( *it )->fix( last->rect( QSizeF( 1, 1 ) ) ); last = *it; } } return retval; }
void KoPathShape::loadStyle(const KoXmlElement & element, KoShapeLoadingContext &context) { KoShape::loadStyle(element, context); KoStyleStack &styleStack = context.odfLoadingContext().styleStack(); styleStack.save(); // fill the style stack with the shapes style if (element.hasAttributeNS(KoXmlNS::draw, "style-name")) { context.odfLoadingContext().fillStyleStack(element, KoXmlNS::draw, "style-name", "graphic"); } else if (element.hasAttributeNS(KoXmlNS::presentation, "style-name")) { context.odfLoadingContext().fillStyleStack(element, KoXmlNS::presentation, "style-name", "presentation"); } styleStack.setTypeProperties("graphic"); if (styleStack.hasProperty(KoXmlNS::svg, "fill-rule")) { QString rule = styleStack.property(KoXmlNS::svg, "fill-rule"); d->fillRule = rule == "nonzero" ? Qt::WindingFill : Qt::OddEvenFill; } styleStack.restore(); }
void KoOdfLoadingContext::fillStyleStack(const KoXmlElement& object, const QString &nsURI, const QString &attrName, const QString &family) { // find all styles associated with an object and push them on the stack if (object.hasAttributeNS(nsURI, attrName)) { const QString styleName = object.attributeNS(nsURI, attrName, QString()); const KoXmlElement * style = d->stylesReader.findStyle(styleName, family, d->useStylesAutoStyles); if (style) addStyles(style, family, d->useStylesAutoStyles); else kWarning(32500) << "style" << styleName << "not found in" << (d->useStylesAutoStyles ? "styles.xml" : "content.xml"); } }
bool Surface::loadOdf( const KoXmlElement &surfaceElement, KoShapeLoadingContext &context ) { KoStyleStack &styleStack = context.odfLoadingContext().styleStack(); styleStack.save(); if ( surfaceElement.hasAttributeNS( KoXmlNS::chart, "style-name" ) ) { KDChart::BackgroundAttributes backgroundAttributes = d->kdPlane->backgroundAttributes(); KDChart::FrameAttributes frameAttributes = d->kdPlane->frameAttributes(); styleStack.clear(); context.odfLoadingContext().fillStyleStack( surfaceElement, KoXmlNS::chart, "style-name", "chart" ); styleStack.setTypeProperties( "graphic" ); if ( styleStack.hasProperty( KoXmlNS::draw, "stroke" ) ) { frameAttributes.setVisible( true ); QString stroke = styleStack.property( KoXmlNS::draw, "stroke" ); if( stroke == "solid" || stroke == "dash" ) { QPen pen = KoOdfGraphicStyles::loadOdfStrokeStyle( styleStack, stroke, context.odfLoadingContext().stylesReader() ); frameAttributes.setPen( pen ); } } if ( styleStack.hasProperty( KoXmlNS::draw, "fill" ) ) { backgroundAttributes.setVisible( true ); QBrush brush; QString fill = styleStack.property( KoXmlNS::draw, "fill" ); if ( fill == "solid" || fill == "hatch" ) brush = KoOdfGraphicStyles::loadOdfFillStyle( styleStack, fill, context.odfLoadingContext().stylesReader() ); else if ( fill == "gradient" ) { brush = KoOdfGraphicStyles::loadOdfGradientStyle( styleStack, context.odfLoadingContext().stylesReader(), QSizeF( 5.0, 60.0 ) ); } else if ( fill == "bitmap" ) brush = KoOdfGraphicStyles::loadOdfPatternStyle( styleStack, context.odfLoadingContext(), QSizeF( 5.0, 60.0 ) ); backgroundAttributes.setBrush( brush ); } d->kdPlane->setBackgroundAttributes( backgroundAttributes ); d->kdPlane->setFrameAttributes( frameAttributes ); } styleStack.restore(); return true; }
bool KoTextInlineRdf::loadOdf(const KoXmlElement &e) { d->id = e.attribute("id", QString()); d->subject = e.attributeNS(KoXmlNS::xhtml, "about"); d->predicate = e.attributeNS(KoXmlNS::xhtml, "property"); d->dt = e.attributeNS(KoXmlNS::xhtml, "datatype"); QString content = e.attributeNS(KoXmlNS::xhtml, "content"); // // Content / triple object explicitly set through an attribute // if (e.hasAttributeNS(KoXmlNS::xhtml, "content")) { d->isObjectAttriuteUsed = true; d->object = content; } return true; }
bool EnhancedPathHandle::loadOdf(const KoXmlElement &element, KoShapeLoadingContext &context) { if (element.localName() != "handle" || element.namespaceURI() != KoXmlNS::draw) { return false; } QString position = element.attributeNS(KoXmlNS::draw, "handle-position"); #ifndef NWORKAROUND_ODF_BUGS KoOdfWorkaround::fixEnhancedPathPolarHandlePosition(position, element, context); #endif QStringList tokens = position.simplified().split(' '); if (tokens.count() != 2) { return false; } setPosition(m_parent->parameter(tokens[0]), m_parent->parameter(tokens[1])); // check if we have a polar handle if (element.hasAttributeNS(KoXmlNS::draw, "handle-polar")) { QString polar = element.attributeNS(KoXmlNS::draw, "handle-polar"); QStringList tokens = polar.simplified().split(' '); if (tokens.count() == 2) { setPolarCenter(m_parent->parameter(tokens[0]), m_parent->parameter(tokens[1])); QString minRadius = element.attributeNS(KoXmlNS::draw, "handle-radius-range-minimum"); QString maxRadius = element.attributeNS(KoXmlNS::draw, "handle-radius-range-maximum"); if (!minRadius.isEmpty() && !maxRadius.isEmpty()) { setRadiusRange(m_parent->parameter(minRadius), m_parent->parameter(maxRadius)); } } } else { QString minX = element.attributeNS(KoXmlNS::draw, "handle-range-x-minimum"); QString maxX = element.attributeNS(KoXmlNS::draw, "handle-range-x-maximum"); if (!minX.isEmpty() && ! maxX.isEmpty()) { setRangeX(m_parent->parameter(minX), m_parent->parameter(maxX)); } QString minY = element.attributeNS(KoXmlNS::draw, "handle-range-y-minimum"); QString maxY = element.attributeNS(KoXmlNS::draw, "handle-range-y-maximum"); if (!minY.isEmpty() && ! maxY.isEmpty()) { setRangeY(m_parent->parameter(minY), m_parent->parameter(maxY)); } } return hasPosition(); }
void KoPAMasterPage::loadOdfPageTag( const KoXmlElement &element, KoPALoadingContext &loadingContext ) { KoPAPageBase::loadOdfPageTag( element, loadingContext ); if ( element.hasAttributeNS( KoXmlNS::style, "display-name" ) ) { setName( element.attributeNS( KoXmlNS::style, "display-name" ) ); } else { setName( element.attributeNS( KoXmlNS::style, "name" ) ); } QString pageLayoutName = element.attributeNS( KoXmlNS::style, "page-layout-name" ); const KoOdfStylesReader& styles = loadingContext.odfLoadingContext().stylesReader(); const KoXmlElement* masterPageStyle = styles.findStyle( pageLayoutName ); KoPageLayout pageLayout; if ( masterPageStyle ) { pageLayout.loadOdf( *masterPageStyle ); } setPageLayout( pageLayout ); }
bool KPrPlaceholderShapeFactory::supports(const KoXmlElement & e, KoShapeLoadingContext &context) const { Q_UNUSED(context); // check parent if placeholder is set to true KoXmlNode parent = e.parentNode(); if ( !parent.isNull() ) { KoXmlElement element = parent.toElement(); if ( !element.isNull() ) { bool supported = element.attributeNS( KoXmlNS::presentation, "placeholder", "false" ) == "true"; kDebug(33001) << "placeholder:" << supported; #ifndef NWORKAROUND_ODF_BUGS if (!supported && KoOdfWorkaround::fixPresentationPlaceholder() && element.hasAttributeNS(KoXmlNS::presentation, "class")) { supported = true; kDebug(33001) << "workaround OO placeholder bug" << supported; } #endif return supported; } } return false; }
void Conditions::loadOdfConditions(const KoXmlElement &element, const ValueParser *parser, const StyleManager *styleManager) { kDebug(36003) << "Loading conditional styles"; KoXmlNode node(element); while (!node.isNull()) { KoXmlElement elementItem = node.toElement(); if (elementItem.tagName() == "map" && elementItem.namespaceURI() == KoXmlNS::style) { QString conditionValue = elementItem.attributeNS(KoXmlNS::style, "condition", QString()); QString applyStyleName; if (elementItem.hasAttributeNS(KoXmlNS::style, "apply-style-name")) applyStyleName = elementItem.attributeNS(KoXmlNS::style, "apply-style-name", QString()); if (!applyStyleName.isEmpty() && styleManager) { QString odfStyle = styleManager->openDocumentName(applyStyleName); if (!odfStyle.isEmpty()) applyStyleName = odfStyle; } QString baseCellAddress = elementItem.attributeNS(KoXmlNS::style, "base-cell-address"); loadOdfCondition(conditionValue, applyStyleName, baseCellAddress, parser); } node = node.nextSibling(); } }
bool Surface::loadOdf(const KoXmlElement &surfaceElement, KoShapeLoadingContext &context) { // Get the current style stack and save it's state. KoStyleStack &styleStack = context.odfLoadingContext().styleStack(); bool brushLoaded = false; if (surfaceElement.hasAttributeNS(KoXmlNS::chart, "style-name")) { KDChart::BackgroundAttributes backgroundAttributes = d->kdPlane->backgroundAttributes(); KDChart::FrameAttributes frameAttributes = d->kdPlane->frameAttributes(); // Add the chart style to the style stack. styleStack.clear(); context.odfLoadingContext().fillStyleStack(surfaceElement, KoXmlNS::chart, "style-name", "chart"); styleStack.setTypeProperties("graphic"); // If there is a "stroke" property, then get the stroke style // and set the pen accordingly. if (styleStack.hasProperty(KoXmlNS::draw, "stroke")) { frameAttributes.setVisible(true); QString stroke = styleStack.property(KoXmlNS::draw, "stroke"); QPen pen(Qt::NoPen); if (stroke == "solid" || stroke == "dash") pen = KoOdfGraphicStyles::loadOdfStrokeStyle(styleStack, stroke, context.odfLoadingContext().stylesReader()); frameAttributes.setPen(pen); } // If there is a "fill" property, then get the fill style, and // set the brush for the surface accordingly. if (styleStack.hasProperty(KoXmlNS::draw, "fill")) { backgroundAttributes.setVisible(true); QBrush brush; QString fill = styleStack.property(KoXmlNS::draw, "fill"); if (fill == "solid" || fill == "hatch") { brushLoaded = true; brush = KoOdfGraphicStyles::loadOdfFillStyle(styleStack, fill, context.odfLoadingContext().stylesReader()); } else if (fill == "gradient") { brushLoaded = true; brush = KoOdfGraphicStyles::loadOdfGradientStyle(styleStack, context.odfLoadingContext().stylesReader(), QSizeF(5.0, 60.0)); } else if (fill == "bitmap") { brushLoaded = true; brush = loadOdfPatternStyle(styleStack, context.odfLoadingContext(), QSizeF(5.0, 60.0)); } backgroundAttributes.setBrush(brush); } // Finally actually set the attributes. d->kdPlane->setBackgroundAttributes(backgroundAttributes); d->kdPlane->setFrameAttributes(frameAttributes); } #ifndef NWORKAROUND_ODF_BUGS if (!brushLoaded) { KDChart::BackgroundAttributes backgroundAttributes = d->kdPlane->backgroundAttributes(); QColor fillColor = KoOdfWorkaround::fixMissingFillColor(surfaceElement, context); if (fillColor.isValid()) { backgroundAttributes.setVisible(true); backgroundAttributes.setBrush(fillColor); d->kdPlane->setBackgroundAttributes(backgroundAttributes); } } #endif return true; }
void Validity::loadOdfValidation(Cell* const cell, const QString& validationName, OdfLoadingContext& tableContext) { KoXmlElement element = tableContext.validities.value(validationName); Validity validity; if (element.hasAttributeNS(KoXmlNS::table, "condition")) { QString valExpression = element.attributeNS(KoXmlNS::table, "condition", QString()); kDebug(36003) << " element.attribute( table:condition )" << valExpression; //Condition ::= ExtendedTrueCondition | TrueFunction 'and' TrueCondition //TrueFunction ::= cell-content-is-whole-number() | cell-content-is-decimal-number() | cell-content-is-date() | cell-content-is-time() //ExtendedTrueCondition ::= ExtendedGetFunction | cell-content-text-length() Operator Value //TrueCondition ::= GetFunction | cell-content() Operator Value //GetFunction ::= cell-content-is-between(Value, Value) | cell-content-is-not-between(Value, Value) //ExtendedGetFunction ::= cell-content-text-length-is-between(Value, Value) | cell-content-text-length-is-not-between(Value, Value) //Operator ::= '<' | '>' | '<=' | '>=' | '=' | '!=' //Value ::= NumberValue | String | Formula //A Formula is a formula without an equals (=) sign at the beginning. See section 8.1.3 for more information. //A String comprises one or more characters surrounded by quotation marks. //A NumberValue is a whole or decimal number. It must not contain comma separators for numbers of 1000 or greater. //ExtendedTrueCondition if (valExpression.contains("cell-content-text-length()")) { //"cell-content-text-length()>45" valExpression = valExpression.remove("oooc:cell-content-text-length()"); kDebug(36003) << " valExpression = :" << valExpression; setRestriction(Validity::TextLength); loadOdfValidationCondition(valExpression, cell->sheet()->map()->parser()); } else if (valExpression.contains("cell-content-is-text()")) { setRestriction(Validity::Text); } //cell-content-text-length-is-between(Value, Value) | cell-content-text-length-is-not-between(Value, Value) | cell-content-is-in-list( StringList ) else if (valExpression.contains("cell-content-text-length-is-between")) { setRestriction(Validity::TextLength); setCondition(Conditional::Between); valExpression = valExpression.remove("oooc:cell-content-text-length-is-between("); kDebug(36003) << " valExpression :" << valExpression; valExpression = valExpression.remove(')'); QStringList listVal = valExpression.split(',', QString::SkipEmptyParts); loadOdfValidationValue(listVal, cell->sheet()->map()->parser()); } else if (valExpression.contains("cell-content-text-length-is-not-between")) { setRestriction(Validity::TextLength); setCondition(Conditional::Different); valExpression = valExpression.remove("oooc:cell-content-text-length-is-not-between("); kDebug(36003) << " valExpression :" << valExpression; valExpression = valExpression.remove(')'); kDebug(36003) << " valExpression :" << valExpression; QStringList listVal = valExpression.split(',', QString::SkipEmptyParts); loadOdfValidationValue(listVal, cell->sheet()->map()->parser()); } else if (valExpression.contains("cell-content-is-in-list(")) { setRestriction(Validity::List); valExpression = valExpression.remove("oooc:cell-content-is-in-list("); kDebug(36003) << " valExpression :" << valExpression; valExpression = valExpression.remove(')'); setValidityList(valExpression.split(';', QString::SkipEmptyParts)); } //TrueFunction ::= cell-content-is-whole-number() | cell-content-is-decimal-number() | cell-content-is-date() | cell-content-is-time() else { if (valExpression.contains("cell-content-is-whole-number()")) { setRestriction(Validity::Number); valExpression = valExpression.remove("oooc:cell-content-is-whole-number() and "); } else if (valExpression.contains("cell-content-is-decimal-number()")) { setRestriction(Validity::Integer); valExpression = valExpression.remove("oooc:cell-content-is-decimal-number() and "); } else if (valExpression.contains("cell-content-is-date()")) { setRestriction(Validity::Date); valExpression = valExpression.remove("oooc:cell-content-is-date() and "); } else if (valExpression.contains("cell-content-is-time()")) { setRestriction(Validity::Time); valExpression = valExpression.remove("oooc:cell-content-is-time() and "); } kDebug(36003) << "valExpression :" << valExpression; if (valExpression.contains("cell-content()")) { valExpression = valExpression.remove("cell-content()"); loadOdfValidationCondition(valExpression, cell->sheet()->map()->parser()); } //GetFunction ::= cell-content-is-between(Value, Value) | cell-content-is-not-between(Value, Value) //for the moment we support just int/double value, not text/date/time :( if (valExpression.contains("cell-content-is-between(")) { valExpression = valExpression.remove("cell-content-is-between("); valExpression = valExpression.remove(')'); QStringList listVal = valExpression.split(',', QString::SkipEmptyParts); loadOdfValidationValue(listVal, cell->sheet()->map()->parser()); setCondition(Conditional::Between); } if (valExpression.contains("cell-content-is-not-between(")) { valExpression = valExpression.remove("cell-content-is-not-between("); valExpression = valExpression.remove(')'); QStringList listVal = valExpression.split(',', QString::SkipEmptyParts); loadOdfValidationValue(listVal, cell->sheet()->map()->parser()); setCondition(Conditional::Different); } } } if (element.hasAttributeNS(KoXmlNS::table, "allow-empty-cell")) { kDebug(36003) << " element.hasAttribute( table:allow-empty-cell ) :" << element.hasAttributeNS(KoXmlNS::table, "allow-empty-cell"); setAllowEmptyCell(((element.attributeNS(KoXmlNS::table, "allow-empty-cell", QString()) == "true") ? true : false)); } if (element.hasAttributeNS(KoXmlNS::table, "base-cell-address")) { //todo what is it ? } KoXmlElement help = KoXml::namedItemNS(element, KoXmlNS::table, "help-message"); if (!help.isNull()) { if (help.hasAttributeNS(KoXmlNS::table, "title")) { kDebug(36003) << "help.attribute( table:title ) :" << help.attributeNS(KoXmlNS::table, "title", QString()); setTitleInfo(help.attributeNS(KoXmlNS::table, "title", QString())); } if (help.hasAttributeNS(KoXmlNS::table, "display")) { kDebug(36003) << "help.attribute( table:display ) :" << help.attributeNS(KoXmlNS::table, "display", QString()); setDisplayValidationInformation(((help.attributeNS(KoXmlNS::table, "display", QString()) == "true") ? true : false)); } KoXmlElement attrText = KoXml::namedItemNS(help, KoXmlNS::text, "p"); if (!attrText.isNull()) { kDebug(36003) << "help text :" << attrText.text(); setMessageInfo(attrText.text()); } } KoXmlElement error = KoXml::namedItemNS(element, KoXmlNS::table, "error-message"); if (!error.isNull()) { if (error.hasAttributeNS(KoXmlNS::table, "title")) setTitle(error.attributeNS(KoXmlNS::table, "title", QString())); if (error.hasAttributeNS(KoXmlNS::table, "message-type")) { QString str = error.attributeNS(KoXmlNS::table, "message-type", QString()); if (str == "warning") setAction(Validity::Warning); else if (str == "information") setAction(Validity::Information); else if (str == "stop") setAction(Validity::Stop); else kDebug(36003) << "validation : message type unknown :" << str; } if (error.hasAttributeNS(KoXmlNS::table, "display")) { kDebug(36003) << " display message :" << error.attributeNS(KoXmlNS::table, "display", QString()); setDisplayMessage((error.attributeNS(KoXmlNS::table, "display", QString()) == "true")); } KoXmlElement attrText = KoXml::namedItemNS(error, KoXmlNS::text, "p"); if (!attrText.isNull()) setMessage(attrText.text()); } cell->setValidity(validity); }
bool Legend::loadOdf(const KoXmlElement &legendElement, KoShapeLoadingContext &context) { KoStyleStack &styleStack = context.odfLoadingContext().styleStack(); styleStack.clear(); // FIXME: If the style isn't present we shouldn't care about it at all // and move everything related to the legend style in this if clause if (legendElement.hasAttributeNS(KoXmlNS::chart, "style-name")) { context.odfLoadingContext().fillStyleStack(legendElement, KoXmlNS::chart, "style-name", "chart"); styleStack.setTypeProperties("graphic"); } if (!legendElement.isNull()) { int attributesToLoad = OdfAllAttributes; QString lp = legendElement.attributeNS(KoXmlNS::chart, "legend-position", QString()); if (!lp.isEmpty()) { attributesToLoad ^= OdfPosition; } // FIXME according to odf if legend-position is provided the x // and y value should not be used. // // FIXME also width and height are not supported at this place if (legendElement.hasAttributeNS(KoXmlNS::svg, "x") || legendElement.hasAttributeNS(KoXmlNS::svg, "y") || legendElement.hasAttributeNS(KoXmlNS::svg, "width") || legendElement.hasAttributeNS(KoXmlNS::svg, "height")) { d->shape->layout()->setPosition(this, FloatingPosition); } loadOdfAttributes(legendElement, context, attributesToLoad); QString lalign = legendElement.attributeNS(KoXmlNS::chart, "legend-align", QString()); if (legendElement.hasAttributeNS(KoXmlNS::style, "legend-expansion")) { QString lexpansion = legendElement.attributeNS(KoXmlNS::style, "legend-expansion", QString()); if (lexpansion == "wide") setExpansion(WideLegendExpansion); else if (lexpansion == "high") setExpansion(HighLegendExpansion); else setExpansion(BalancedLegendExpansion); } if (lalign == "start") { setAlignment(Qt::AlignLeft); } else if (lalign == "end") { setAlignment(Qt::AlignRight); } else { setAlignment(Qt::AlignCenter); } if (lp == "start") { setLegendPosition(StartPosition); } else if (lp == "top") { setLegendPosition(TopPosition); } else if (lp == "bottom") { setLegendPosition(BottomPosition); } else if (lp == "top-start") { setLegendPosition(TopStartPosition); } else if (lp == "bottom-start") { setLegendPosition(BottomStartPosition); } else if (lp == "top-end") { setLegendPosition(TopEndPosition); } else if (lp == "bottom-end") { setLegendPosition(BottomEndPosition); } else { setLegendPosition(EndPosition); } if (legendElement.hasAttributeNS(KoXmlNS::office, "title")) { setTitle(legendElement.attributeNS(KoXmlNS::office, "title", QString())); } styleStack.setTypeProperties("text"); if (styleStack.hasProperty(KoXmlNS::fo, "font-family")) { QString fontFamily = styleStack.property(KoXmlNS::fo, "font-family"); QFont font = d->font; font.setFamily(fontFamily); setFont(font); } if (styleStack.hasProperty(KoXmlNS::fo, "font-size")) { qreal fontSize = KoUnit::parseValue(styleStack.property(KoXmlNS::fo, "font-size")); setFontSize(fontSize); } if (styleStack.hasProperty(KoXmlNS::fo, "font-color")) { QColor color = styleStack.property(KoXmlNS::fo, "font-color"); if (color.isValid()) { setFontColor(color); } } } else { // No legend element, use default legend. // FIXME: North?? Isn't that a bit strange as default? /IW setLegendPosition(TopPosition); setAlignment(Qt::AlignCenter); } d->pixmapRepaintRequested = true; return true; }
bool KoShapeAnchor::loadOdf(const KoXmlElement &element, KoShapeLoadingContext &context) { d->offset = shape()->position(); if (! shape()->hasAdditionalAttribute("text:anchor-type")) return false; QString anchorType = shape()->additionalAttribute("text:anchor-type"); if (anchorType == "char") { d->anchorType = AnchorToCharacter; } else if (anchorType == "as-char") { d->anchorType = AnchorAsCharacter; } else if (anchorType == "paragraph") { d->anchorType = AnchorParagraph; } else if (anchorType == "page") { d->anchorType = AnchorPage; // it has different defaults at least LO thinks so - ODF doesn't define defaults for this d->horizontalPos = HFromLeft; d->verticalPos = VFromTop; d->horizontalRel = HPage; d->verticalRel = VPage; } if (anchorType == "page" && shape()->hasAdditionalAttribute("text:anchor-page-number")) { d->pageNumber = shape()->additionalAttribute("text:anchor-page-number").toInt(); if (d->pageNumber <= 0) { // invalid if the page-number is invalid (OO.org does the same) // see http://bugs.kde.org/show_bug.cgi?id=281869 d->pageNumber = -1; } } else { d->pageNumber = -1; } // always make it invisible or it will create empty rects on the first page // during initial layout. This is because only when we layout it's final page is // the shape moved away from page 1 // in KWRootAreaProvider of textlayout it's set back to visible shape()->setVisible(false); // load settings from graphic style KoStyleStack &styleStack = context.odfLoadingContext().styleStack(); styleStack.save(); if (element.hasAttributeNS(KoXmlNS::draw, "style-name")) { context.odfLoadingContext().fillStyleStack(element, KoXmlNS::draw, "style-name", "graphic"); styleStack.setTypeProperties("graphic"); } QString verticalPos = styleStack.property(KoXmlNS::style, "vertical-pos"); QString verticalRel = styleStack.property(KoXmlNS::style, "vertical-rel"); QString horizontalPos = styleStack.property(KoXmlNS::style, "horizontal-pos"); QString horizontalRel = styleStack.property(KoXmlNS::style, "horizontal-rel"); d->wrapInfluenceOnPosition = styleStack.property(KoXmlNS::draw, "wrap-influence-on-position"); QString flowWithText = styleStack.property(KoXmlNS::style, "flow-with-text"); d->flowWithText = flowWithText.isEmpty() ? false : flowWithText == "true"; styleStack.restore(); // vertical-pos if (verticalPos == "below") {//svg:y attribute is ignored d->verticalPos = VBelow; d->offset.setY(0); } else if (verticalPos == "bottom") {//svg:y attribute is ignored d->verticalPos = VBottom; d->offset.setY(-shape()->size().height()); } else if (verticalPos == "from-top") { d->verticalPos = VFromTop; } else if (verticalPos == "middle") {//svg:y attribute is ignored d->verticalPos = VMiddle; d->offset.setY(-(shape()->size().height()/2)); } else if (verticalPos == "top") {//svg:y attribute is ignored d->verticalPos = VTop; d->offset.setY(0); } // vertical-rel if (verticalRel == "baseline") d->verticalRel = VBaseline; else if (verticalRel == "char") d->verticalRel = VChar; else if (verticalRel == "frame") d->verticalRel = VFrame; else if (verticalRel == "frame-content") d->verticalRel = VFrameContent; else if (verticalRel == "line") d->verticalRel = VLine; else if (verticalRel == "page") d->verticalRel = VPage; else if (verticalRel == "page-content") d->verticalRel = VPageContent; else if (verticalRel == "paragraph") d->verticalRel = VParagraph; else if (verticalRel == "paragraph-content") d->verticalRel = VParagraphContent; else if (verticalRel == "text") d->verticalRel = VText; // horizontal-pos if (horizontalPos == "center") {//svg:x attribute is ignored d->horizontalPos = HCenter; d->offset.setX(-(shape()->size().width()/2)); } else if (horizontalPos == "from-inside") { d->horizontalPos = HFromInside; } else if (horizontalPos == "from-left") { d->horizontalPos = HFromLeft; } else if (horizontalPos == "inside") {//svg:x attribute is ignored d->horizontalPos = HInside; d->offset.setX(0); } else if (horizontalPos == "left") {//svg:x attribute is ignored d->horizontalPos = HLeft; d->offset.setX(0); }else if (horizontalPos == "outside") {//svg:x attribute is ignored d->horizontalPos = HOutside; d->offset.setX(-shape()->size().width()); }else if (horizontalPos == "right") {//svg:x attribute is ignored d->horizontalPos = HRight; d->offset.setX(-shape()->size().width()); } // horizontal-rel if (horizontalRel == "char") d->horizontalRel = HChar; else if (horizontalRel == "page") d->horizontalRel = HPage; else if (horizontalRel == "page-content") d->horizontalRel = HPageContent; else if (horizontalRel == "page-start-margin") d->horizontalRel = HPageStartMargin; else if (horizontalRel == "page-end-margin") d->horizontalRel = HPageEndMargin; else if (horizontalRel == "frame") d->horizontalRel = HFrame; else if (horizontalRel == "frame-content") d->horizontalRel = HFrameContent; else if (horizontalRel == "frame-end-margin") d->horizontalRel = HFrameEndMargin; else if (horizontalRel == "frame-start-margin") d->horizontalRel = HFrameStartMargin; else if (horizontalRel == "paragraph") d->horizontalRel = HParagraph; else if (horizontalRel == "paragraph-content") d->horizontalRel = HParagraphContent; else if (horizontalRel == "paragraph-end-margin") d->horizontalRel = HParagraphEndMargin; else if (horizontalRel == "paragraph-start-margin") d->horizontalRel = HParagraphStartMargin; // if svg:x or svg:y should be ignored set new position shape()->setPosition(d->offset); if (element.hasAttributeNS(KoXmlNS::calligra, "anchor-type")) { QString anchorType = element.attributeNS(KoXmlNS::calligra, "anchor-type"); // our enriched properties QStringList types = anchorType.split('|'); if (types.count() > 1) { QString vertical = types[0]; QString horizontal = types[1]; if (vertical == "TopOfFrame") { d->verticalRel = VPageContent; d->verticalPos = VTop; } else if (vertical == "TopOfParagraph") { d->verticalRel = VParagraph; d->verticalPos = VTop; } else if (vertical == "AboveCurrentLine") { d->verticalRel = VLine; d->verticalPos = VTop; } else if (vertical == "BelowCurrentLine") { d->verticalRel = VLine; d->verticalPos = VBottom; } else if (vertical == "BottomOfParagraph") { d->verticalRel = VParagraph; d->verticalPos = VBottom; } else if (vertical == "BottomOfFrame") { d->verticalRel = VPageContent; d->verticalPos = VBottom; } else if (vertical == "VerticalOffset") { d->verticalRel = VLine; d->verticalPos = VTop; } if (horizontal == "Left") { d->horizontalRel = HPageContent; d->horizontalPos = HLeft; } else if (horizontal == "Right") { d->horizontalRel = HPageContent; d->horizontalPos = HRight; } else if (horizontal == "Center") { d->horizontalRel = HPageContent; d->horizontalPos = HCenter; } else if (horizontal == "ClosestToBinding") { d->horizontalRel = HPageContent; d->horizontalPos = HInside; } else if (horizontal == "FurtherFromBinding") { d->horizontalRel = HPageContent; d->horizontalPos = HOutside; } else if (horizontal == "HorizontalOffset") { d->horizontalRel = HChar; d->horizontalPos = HLeft; } } d->offset = QPointF(); } if (d->anchorType == AnchorAsCharacter) { d->horizontalRel = HChar; d->horizontalPos = HLeft; } return true; }
bool KoFormulaShape::loadEmbeddedDocument( KoStore *store, const KoXmlElement &objectElement, const KoOdfLoadingContext &odfLoadingContext) { if ( !objectElement.hasAttributeNS( KoXmlNS::xlink, "href" ) ) { kError() << "Object element has no valid xlink:href attribute"; return false; } QString url = objectElement.attributeNS( KoXmlNS::xlink, "href" ); // It can happen that the url is empty e.g. when it is a // presentation:placeholder. if ( url.isEmpty() ) { return true; } QString tmpURL; if ( url[0] == '#' ) url = url.mid( 1 ); #define INTERNAL_PROTOCOL "intern" #define STORE_PROTOCOL "tar" if (KUrl::isRelativeUrl( url )) { if ( url.startsWith( "./" ) ) tmpURL = QString( INTERNAL_PROTOCOL ) + ":/" + url.mid( 2 ); else tmpURL = QString( INTERNAL_PROTOCOL ) + ":/" + url; } else tmpURL = url; QString path = tmpURL; if ( tmpURL.startsWith( INTERNAL_PROTOCOL ) ) { path = store->currentDirectory(); if ( !path.isEmpty() && !path.endsWith( '/' ) ) path += '/'; QString relPath = KUrl( tmpURL ).path(); path += relPath.mid( 1 ); // remove leading '/' } if ( !path.endsWith( '/' ) ) path += '/'; const QString mimeType = odfLoadingContext.mimeTypeForPath( path ); //kDebug(35001) << "path for manifest file=" << path << "mimeType=" << mimeType; if ( mimeType.isEmpty() ) { //kDebug(35001) << "Manifest doesn't have media-type for" << path; return false; } const bool isOdf = mimeType.startsWith( "application/vnd.oasis.opendocument" ); if ( !isOdf ) { tmpURL += "/maindoc.xml"; //kDebug(35001) << "tmpURL adjusted to" << tmpURL; } //kDebug(35001) << "tmpURL=" << tmpURL; QString errorMsg; KoDocumentEntry e = KoDocumentEntry::queryByMimeType( mimeType ); if ( e.isEmpty() ) { return false; } bool res = true; if ( tmpURL.startsWith( STORE_PROTOCOL ) || tmpURL.startsWith( INTERNAL_PROTOCOL ) || KUrl::isRelativeUrl( tmpURL ) ) { if ( isOdf ) { store->pushDirectory(); Q_ASSERT( tmpURL.startsWith( INTERNAL_PROTOCOL ) ); QString relPath = KUrl( tmpURL ).path().mid( 1 ); store->enterDirectory( relPath ); res = m_document->loadOasisFromStore( store ); store->popDirectory(); } else { if ( tmpURL.startsWith( INTERNAL_PROTOCOL ) ) tmpURL = KUrl( tmpURL ).path().mid( 1 ); res = m_document->loadFromStore( store, tmpURL ); } m_document->setStoreInternal( true ); } else { // Reference to an external document. Hmmm... m_document->setStoreInternal( false ); KUrl url( tmpURL ); if ( !url.isLocalFile() ) { //QApplication::restoreOverrideCursor(); // For security reasons we need to ask confirmation if the // url is remote. int result = KMessageBox::warningYesNoCancel( 0, i18n( "This document contains an external link to a remote document\n%1", tmpURL ), i18n( "Confirmation Required" ), KGuiItem( i18n( "Download" ) ), KGuiItem( i18n( "Skip" ) ) ); if ( result == KMessageBox::Cancel ) { //d->m_parent->setErrorMessage("USER_CANCELED"); return false; } if ( result == KMessageBox::Yes ) res = m_document->openUrl( url ); // and if == No, res will still be false so we'll use a kounavail below } else res = m_document->openUrl( url ); } if ( !res ) { QString errorMessage = m_document->errorMessage(); return false; } tmpURL.clear(); return res; }
void CalculationSettings::loadOdf(const KoXmlElement& body) { KoXmlNode settings = KoXml::namedItemNS( body, KoXmlNS::table, "calculation-settings" ); kDebug() <<"Calculation settings found?"<< !settings.isNull(); if ( !settings.isNull() ) { KoXmlElement element = settings.toElement(); if ( element.hasAttributeNS( KoXmlNS::table, "case-sensitive" ) ) { d->caseSensitiveComparisons = true; QString value = element.attributeNS( KoXmlNS::table, "case-sensitive", "true" ); if ( value == "false" ) d->caseSensitiveComparisons = false; } else if ( element.hasAttributeNS( KoXmlNS::table, "precision-as-shown" ) ) { d->precisionAsShown = false; QString value = element.attributeNS( KoXmlNS::table, "precision-as-shown", "false" ); if ( value == "true" ) d->precisionAsShown = true; } else if ( element.hasAttributeNS( KoXmlNS::table, "search-criteria-must-apply-to-whole-cell" ) ) { d->wholeCellSearchCriteria = true; QString value = element.attributeNS( KoXmlNS::table, "search-criteria-must-apply-to-whole-cell", "true" ); if ( value == "false" ) d->wholeCellSearchCriteria = false; } else if ( element.hasAttributeNS( KoXmlNS::table, "automatic-find-labels" ) ) { d->automaticFindLabels = true; QString value = element.attributeNS( KoXmlNS::table, "automatic-find-labels", "true" ); if ( value == "false" ) d->automaticFindLabels = false; } else if ( element.hasAttributeNS( KoXmlNS::table, "use-regular-expressions" ) ) { d->useRegularExpressions = true; QString value = element.attributeNS( KoXmlNS::table, "use-regular-expressions", "true" ); if ( value == "false" ) d->useRegularExpressions = false; } else if ( element.hasAttributeNS( KoXmlNS::table, "null-year" ) ) { d->refYear = 1930; QString value = element.attributeNS( KoXmlNS::table, "null-year", "1930" ); if ( value == "false" ) d->refYear = false; } forEachElement( element, settings ) { if ( element.namespaceURI() != KoXmlNS::table ) continue; else if ( element.tagName() == "null-date" ) { d->refDate = QDate( 1899, 12, 30 ); QString valueType = element.attributeNS( KoXmlNS::table, "value-type", "date" ); if( valueType == "date" ) { QString value = element.attributeNS( KoXmlNS::table, "date-value", "1899-12-30" ); QDate date = QDate::fromString( value, Qt::ISODate ); if ( date.isValid() ) d->refDate = date; } else { kDebug() <<"CalculationSettings: Error on loading null date." << "Value type """ << valueType << """ not handled" << ", falling back to default." << endl; // NOTE Stefan: I don't know why different types are possible here! } } else if ( element.tagName() == "iteration" ) { // TODO } } }
bool ChartShape::Private::loadOdfLabel(KoShape *label, KoXmlElement &labelElement, KoShapeLoadingContext &context) { TextLabelData *labelData = qobject_cast<TextLabelData*>(label->userData()); if (!labelData) return false; // Following will always return false cause KoTextShapeData::loadOdf will try to load // a frame while our text:p is not within a frame. So, let's just not call loadOdf then... //label->loadOdf(labelElement, context); // 1. set the text KoXmlElement pElement = KoXml::namedItemNS(labelElement, KoXmlNS::text, "p"); QTextDocument* doc = labelData->document(); doc->setPlainText(pElement.text()); // 2. set the position QPointF pos = label->position(); bool posChanged = false; if (labelElement.hasAttributeNS(KoXmlNS::svg, "x")) { pos.setX(KoUnit::parseValue(labelElement.attributeNS(KoXmlNS::svg, "x", QString()))); posChanged = true; } if (labelElement.hasAttributeNS(KoXmlNS::svg, "y")) { pos.setY(KoUnit::parseValue(labelElement.attributeNS(KoXmlNS::svg, "y", QString()))); posChanged = true; } if (posChanged) { label->setPosition(pos); } // 3. set the styles if (labelElement.hasAttributeNS(KoXmlNS::chart, "style-name")) { KoStyleStack &styleStack = context.odfLoadingContext().styleStack(); styleStack.clear(); context.odfLoadingContext().fillStyleStack(labelElement, KoXmlNS::chart, "style-name", "chart"); styleStack.setTypeProperties("chart"); if (styleStack.hasProperty(KoXmlNS::style, "rotation-angle")) { qreal rotationAngle = 360 - KoUnit::parseValue(styleStack.property(KoXmlNS::style, "rotation-angle")); label->rotate(rotationAngle); } styleStack.setTypeProperties("text"); if (styleStack.hasProperty(KoXmlNS::fo, "font-size")) { const qreal fontSize = KoUnit::parseValue(styleStack.property(KoXmlNS::fo, "font-size")); QFont font = doc->defaultFont(); font.setPointSizeF(fontSize); doc->setDefaultFont(font); } if (styleStack.hasProperty(KoXmlNS::fo, "font-family")) { const QString fontFamily = styleStack.property(KoXmlNS::fo, "font-family"); QFont font = doc->defaultFont(); font.setFamily(fontFamily); doc->setDefaultFont(font); } } // 4. set the size if (labelElement.hasAttributeNS(KoXmlNS::svg, "width") && labelElement.hasAttributeNS(KoXmlNS::svg, "height")) { const qreal width = KoUnit::parseValue(labelElement.attributeNS(KoXmlNS::svg, "width")); const qreal height = KoUnit::parseValue(labelElement.attributeNS(KoXmlNS::svg, "height")); label->setSize(QSizeF(width, height)); } else { QSizeF size = shape->size(); QRect r = QFontMetrics(doc->defaultFont()).boundingRect( labelData->shapeMargins().left, labelData->shapeMargins().top, qMax(CM_TO_POINT(5), qreal(size.width() - pos.x() * 2.0 - labelData->shapeMargins().right)), qMax(CM_TO_POINT(0.6), qreal(size.height() - labelData->shapeMargins().bottom)), Qt::AlignLeft | Qt::AlignTop | Qt::TextWordWrap, doc->toPlainText()); label->setSize(r.size()); } return true; }
bool Ko3dScene::loadOdf(const KoXmlElement &sceneElement) { QString dummy; // Check if there is a 3d scene at all in this element. We // approximate that by checking if there are any camera parameters. if (!sceneElement.hasAttributeNS(KoXmlNS::dr3d, "vrp") && !sceneElement.hasAttributeNS(KoXmlNS::dr3d, "vpn") && !sceneElement.hasAttributeNS(KoXmlNS::dr3d, "vup")) { return false; } // 1. Load the scene attributes. // Camera attributes dummy = sceneElement.attributeNS(KoXmlNS::dr3d, "vrp"); d->vrp = odfToVector3D(dummy); dummy = sceneElement.attributeNS(KoXmlNS::dr3d, "vpn"); d->vpn = odfToVector3D(dummy); dummy = sceneElement.attributeNS(KoXmlNS::dr3d, "vup", "(0.0 0.0 1.0)"); d->vup = odfToVector3D(dummy); dummy = sceneElement.attributeNS(KoXmlNS::dr3d, "projection", "perspective"); if (dummy == "parallel") { d->projection = Parallel; } else { d->projection = Perspective; } d->distance = sceneElement.attributeNS(KoXmlNS::dr3d, "distance"); d->focalLength = sceneElement.attributeNS(KoXmlNS::dr3d, "focal-length"); d->shadowSlant = sceneElement.attributeNS(KoXmlNS::dr3d, "shadow-slant"); d->ambientColor = QColor(sceneElement.attributeNS(KoXmlNS::dr3d, "ambient-color", "#888888")); // Rendering attributes dummy = sceneElement.attributeNS(KoXmlNS::dr3d, "shade-mode", "gouraud"); if (dummy == "flat") { d->shadeMode = Flat; } else if (dummy == "phong") { d->shadeMode = Phong; } else if (dummy == "draft") { d->shadeMode = Draft; } else { d->shadeMode = Gouraud; } d->lightingMode = (sceneElement.attributeNS(KoXmlNS::dr3d, "lighting-mode") == "true"); d->transform = sceneElement.attributeNS(KoXmlNS::dr3d, "transform"); // 2. Load the light sources. // From the ODF 1.1 spec section 9.4.1: KoXmlElement elem; forEachElement(elem, sceneElement) { if (elem.localName() == "light" && elem.namespaceURI() == KoXmlNS::dr3d) { Lightsource light; light.loadOdf(elem); d->lights.append(light); } } //kDebug(31000) << "Lights:" << d->lights.size(); return true; }
bool KoConnectionShape::loadOdf(const KoXmlElement & element, KoShapeLoadingContext &context) { Q_D(KoConnectionShape); loadOdfAttributes(element, context, OdfMandatories | OdfCommonChildElements | OdfAdditionalAttributes); QString type = element.attributeNS(KoXmlNS::draw, "type", "standard"); if (type == "lines") d->connectionType = Lines; else if (type == "line") d->connectionType = Straight; else if (type == "curve") d->connectionType = Curve; else d->connectionType = Standard; // reset connection point indices d->connectionPointId1 = -1; d->connectionPointId2 = -1; // reset connected shapes d->shape1 = 0; d->shape2 = 0; if (element.hasAttributeNS(KoXmlNS::draw, "start-shape")) { d->connectionPointId1 = element.attributeNS(KoXmlNS::draw, "start-glue-point", QString()).toInt(); QString shapeId1 = element.attributeNS(KoXmlNS::draw, "start-shape", QString()); kDebug(30006) << "references start-shape" << shapeId1 << "at glue-point" << d->connectionPointId1; d->shape1 = context.shapeById(shapeId1); if (d->shape1) { kDebug(30006) << "start-shape was already loaded"; d->shape1->addDependee(this); if (d->shape1->hasConnectionPoint(d->connectionPointId1)) { kDebug(30006) << "connecting to start-shape"; d->handles[StartHandle] = d->shape1->absoluteTransformation(0).map(d->shape1->connectionPoint(d->connectionPointId1).position); kDebug(30006) << "start handle position =" << d->handles[StartHandle]; } } else { kDebug(30006) << "start-shape not loaded yet, deferring connection"; context.updateShape(shapeId1, new KoConnectionShapeLoadingUpdater(this, KoConnectionShapeLoadingUpdater::First)); } } else { d->handles[StartHandle].setX(KoUnit::parseValue(element.attributeNS(KoXmlNS::svg, "x1", QString()))); d->handles[StartHandle].setY(KoUnit::parseValue(element.attributeNS(KoXmlNS::svg, "y1", QString()))); } if (element.hasAttributeNS(KoXmlNS::draw, "end-shape")) { d->connectionPointId2 = element.attributeNS(KoXmlNS::draw, "end-glue-point", "").toInt(); QString shapeId2 = element.attributeNS(KoXmlNS::draw, "end-shape", ""); kDebug(30006) << "references end-shape " << shapeId2 << "at glue-point" << d->connectionPointId2; d->shape2 = context.shapeById(shapeId2); if (d->shape2) { kDebug(30006) << "end-shape was already loaded"; d->shape2->addDependee(this); if (d->shape2->hasConnectionPoint(d->connectionPointId2)) { kDebug(30006) << "connecting to end-shape"; d->handles[EndHandle] = d->shape2->absoluteTransformation(0).map(d->shape2->connectionPoint(d->connectionPointId2).position); kDebug(30006) << "end handle position =" << d->handles[EndHandle]; } } else { kDebug(30006) << "end-shape not loaded yet, deferring connection"; context.updateShape(shapeId2, new KoConnectionShapeLoadingUpdater(this, KoConnectionShapeLoadingUpdater::Second)); } } else { d->handles[EndHandle].setX(KoUnit::parseValue(element.attributeNS(KoXmlNS::svg, "x2", QString()))); d->handles[EndHandle].setY(KoUnit::parseValue(element.attributeNS(KoXmlNS::svg, "y2", QString()))); } QString skew = element.attributeNS(KoXmlNS::draw, "line-skew", QString()); QStringList skewValues = skew.simplified().split(' ', QString::SkipEmptyParts); // TODO apply skew values once we support them // load the path data if there is any d->hasCustomPath = element.hasAttributeNS(KoXmlNS::svg, "d"); if (d->hasCustomPath) { KoPathShapeLoader loader(this); loader.parseSvg(element.attributeNS(KoXmlNS::svg, "d"), true); if (m_subpaths.size() > 0) { QRectF viewBox = loadOdfViewbox(element); if (viewBox.isEmpty()) { // there should be a viewBox to transform the path data // if there is none, use the bounding rectangle of the parsed path viewBox = outline().boundingRect(); } // convert path to viewbox coordinates to have a bounding rect of (0,0 1x1) // which can later be fitted back into the target rect once we have all // the required information QTransform viewMatrix; viewMatrix.scale(viewBox.width() ? static_cast<qreal>(1.0) / viewBox.width() : 1.0, viewBox.height() ? static_cast<qreal>(1.0) / viewBox.height() : 1.0); viewMatrix.translate(-viewBox.left(), -viewBox.top()); d->map(viewMatrix); // trigger finishing the connections in case we have all data // otherwise it gets called again once the shapes we are // connected to are loaded } else { d->hasCustomPath = false; } finishLoadingConnection(); } else { d->forceUpdate = true; updateConnections(); } loadText(element, context); return true; }