QString KoOdfGraphicStyles::saveOdfGradientStyle(KoGenStyles &mainStyles, const QBrush &brush) { KoGenStyle gradientStyle; if (brush.style() == Qt::RadialGradientPattern) { const QRadialGradient *gradient = static_cast<const QRadialGradient*>(brush.gradient()); gradientStyle = KoGenStyle(KoGenStyle::RadialGradientStyle /*no family name*/); gradientStyle.addAttributePercent("svg:cx", gradient->center().x() * 100); gradientStyle.addAttributePercent("svg:cy", gradient->center().y() * 100); gradientStyle.addAttributePercent("svg:r", gradient->radius() * 100); gradientStyle.addAttributePercent("svg:fx", gradient->focalPoint().x() * 100); gradientStyle.addAttributePercent("svg:fy", gradient->focalPoint().y() * 100); } else if (brush.style() == Qt::LinearGradientPattern) { const QLinearGradient *gradient = static_cast<const QLinearGradient*>(brush.gradient()); gradientStyle = KoGenStyle(KoGenStyle::LinearGradientStyle /*no family name*/); gradientStyle.addAttributePercent("svg:x1", gradient->start().x() * 100); gradientStyle.addAttributePercent("svg:y1", gradient->start().y() * 100); gradientStyle.addAttributePercent("svg:x2", gradient->finalStop().x() * 100); gradientStyle.addAttributePercent("svg:y2", gradient->finalStop().y() * 100); } else if (brush.style() == Qt::ConicalGradientPattern) { const QConicalGradient * gradient = static_cast<const QConicalGradient*>(brush.gradient()); gradientStyle = KoGenStyle(KoGenStyle::ConicalGradientStyle /*no family name*/); gradientStyle.addAttributePercent("svg:cx", gradient->center().x() * 100); gradientStyle.addAttributePercent("svg:cy", gradient->center().y() * 100); gradientStyle.addAttribute("draw:angle", QString("%1").arg(gradient->angle())); } const QGradient * gradient = brush.gradient(); if (gradient->spread() == QGradient::RepeatSpread) gradientStyle.addAttribute("svg:spreadMethod", "repeat"); else if (gradient->spread() == QGradient::ReflectSpread) gradientStyle.addAttribute("svg:spreadMethod", "reflect"); else gradientStyle.addAttribute("svg:spreadMethod", "pad"); if (! brush.transform().isIdentity()) { gradientStyle.addAttribute("svg:gradientTransform", saveTransformation(brush.transform())); } QBuffer buffer; buffer.open(QIODevice::WriteOnly); KoXmlWriter elementWriter(&buffer); // TODO pass indentation level // save stops QGradientStops stops = gradient->stops(); Q_FOREACH (const QGradientStop & stop, stops) { elementWriter.startElement("svg:stop"); elementWriter.addAttribute("svg:offset", QString("%1").arg(stop.first)); elementWriter.addAttribute("svg:stop-color", stop.second.name()); if (stop.second.alphaF() < 1.0) elementWriter.addAttribute("svg:stop-opacity", QString("%1").arg(stop.second.alphaF())); elementWriter.endElement(); }
void KoPAMasterPage::saveOdf( KoShapeSavingContext & context ) const { KoPASavingContext &paContext = static_cast<KoPASavingContext&>( context ); KoGenStyle pageLayoutStyle = pageLayout().saveOdf(); pageLayoutStyle.setAutoStyleInStylesDotXml( true ); pageLayoutStyle.addAttribute( "style:page-usage", "all" ); QString pageLayoutName( paContext.mainStyles().insert( pageLayoutStyle, "pm" ) ); KoGenStyle pageMaster( KoGenStyle::MasterPageStyle ); pageMaster.addAttribute( "style:page-layout-name", pageLayoutName ); pageMaster.addAttribute( "style:display-name", name() ); pageMaster.addAttribute( "draw:style-name", saveOdfPageStyle( paContext ) ); KoXmlWriter &savedWriter = paContext.xmlWriter(); QBuffer buffer; buffer.open( QIODevice::WriteOnly ); KoXmlWriter xmlWriter( &buffer ); paContext.setXmlWriter( xmlWriter ); saveOdfPageContent( paContext ); paContext.setXmlWriter( savedWriter ); QString contentElement = QString::fromUtf8( buffer.buffer(), buffer.buffer().size() ); pageMaster.addChildElement( paContext.masterPageElementName(), contentElement ); paContext.addMasterPage( this, paContext.mainStyles().insert( pageMaster, "Default" ) ); }
void KoGenStyles::Private::saveOdfDocumentStyles(KoXmlWriter* xmlWriter) const { xmlWriter->startElement("office:styles"); for (uint i = 0; i < numStyleData; ++i) { const QMap<int, KoGenStyle>::const_iterator it(defaultStyles.constFind(styleData[i].m_type)); if (it != defaultStyles.constEnd()) { it.value().writeStyle(xmlWriter, *q, "style:default-style", "", styleData[i].m_propertiesElementName, true, styleData[i].m_drawElement); } } for (uint i = 0; i < numStyleData; ++i) { QList<KoGenStyles::NamedStyle> stylesList(styles(false, styleData[i].m_type)); QList<KoGenStyles::NamedStyle>::const_iterator it = stylesList.constBegin(); for (; it != stylesList.constEnd() ; ++it) { if (relations.contains(it->name)) { KoGenStyles::Private::RelationTarget relation = relations.value(it->name); KoGenStyle styleCopy = *(*it).style; styleCopy.addAttribute(relation.attribute, relation.target); styleCopy.writeStyle(xmlWriter, *q, styleData[i].m_elementName, (*it).name, styleData[i].m_propertiesElementName, true, styleData[i].m_drawElement); } else { (*it).style->writeStyle(xmlWriter, *q, styleData[i].m_elementName, (*it).name, styleData[i].m_propertiesElementName, true, styleData[i].m_drawElement); } } } if (!rawOdfDocumentStyles.isEmpty()) { xmlWriter->addCompleteElement(rawOdfDocumentStyles.constData()); } xmlWriter->endElement(); // office:styles }
void Document::slotSectionEnd(wvWare::SharedPtr<const wvWare::Word97::SEP> sep) { kDebug(30513); KoGenStyle* masterPageStyle = 0; KoGenStyle* pageLayoutStyle = 0; QString pageLayoutName; for (int i = 0; i < m_masterPageName_list.size(); i++) { pageLayoutStyle = m_pageLayoutStyle_list[i]; masterPageStyle = m_masterPageStyle_list[i]; Q_ASSERT(pageLayoutStyle); Q_ASSERT(masterPageStyle); //set the margins - depends on whether a header/footer is present if (m_hasHeader_list[i]) { kDebug(30513) << "setting margin for header..."; pageLayoutStyle->addPropertyPt("fo:margin-top", (double)sep->dyaHdrTop / 20.0); } else if (sep->brcTop.brcType == 0) { kDebug(30513) << "setting margin for no header and no top border..."; pageLayoutStyle->addPropertyPt("fo:margin-top", (double)sep->dyaTop / 20.0); } if (m_hasFooter_list[i]) { pageLayoutStyle->addPropertyPt("fo:margin-bottom", (double)sep->dyaHdrBottom / 20.0); } else if (sep->brcBottom.brcType == 0) { pageLayoutStyle->addPropertyPt("fo:margin-bottom", (double)sep->dyaBottom / 20.0); } pageLayoutName = m_mainStyles->insert(*pageLayoutStyle, "Mpm"); masterPageStyle->addAttribute("style:page-layout-name", pageLayoutName); m_mainStyles->insert(*masterPageStyle, m_masterPageName_list[i], KoGenStyles::DontAddNumberToName); //delete objects, we've added them to the collection delete masterPageStyle; delete pageLayoutStyle; } //clear lists m_pageLayoutStyle_list.clear(); m_masterPageStyle_list.clear(); m_masterPageName_list.clear(); m_hasHeader_list.clear(); m_hasFooter_list.clear(); //reset header data m_headerCount = 0; }
void KoSectionStyle::saveOdf(KoGenStyle &style) { // only custom style have a displayname. automatic styles don't have a name set. if (!d->name.isEmpty() && !style.isDefaultStyle()) { style.addAttribute("style:display-name", d->name); } QList<int> keys = d->stylesPrivate.keys(); foreach(int key, keys) { if (key == KoSectionStyle::TextProgressionDirection) { int directionValue = 0; bool ok = false; directionValue = d->stylesPrivate.value(key).toInt(&ok); if (ok) { QString direction; if (directionValue == KoText::LeftRightTopBottom) direction = "lr-tb"; else if (directionValue == KoText::RightLeftTopBottom) direction = "rl-tb"; else if (directionValue == KoText::TopBottomRightLeft) direction = "tb-lr"; else if (directionValue == KoText::InheritDirection) direction = "page"; if (!direction.isEmpty()) style.addProperty("style:writing-mode", direction, KoGenStyle::DefaultType); } } else if (key == QTextFormat::BackgroundBrush) { QBrush backBrush = background(); if (backBrush.style() != Qt::NoBrush) style.addProperty("fo:background-color", backBrush.color().name(), KoGenStyle::ParagraphType); else style.addProperty("fo:background-color", "transparent", KoGenStyle::DefaultType); } else if (key == QTextFormat::BlockLeftMargin) { style.addPropertyPt("fo:margin-left", leftMargin(), KoGenStyle::DefaultType); } else if (key == QTextFormat::BlockRightMargin) { style.addPropertyPt("fo:margin-right", rightMargin(), KoGenStyle::DefaultType); } } }
void KoTblStyle::prepareStyle(KoGenStyle& style) const { if(m_backgroundColor.isValid()) { style.addProperty("fo:background-color", m_backgroundColor.name()); } if (m_breakAfter != KoTblStyle::NoBreak) { style.addProperty("fo:break-after", breakStyleMap.value(m_breakAfter)); } if (m_breakBefore != KoTblStyle::NoBreak) { style.addProperty("fo:break-before", breakStyleMap.value(m_breakBefore)); } style.addProperty("fo:keep-with-next", keepWithNextMap.value(m_keepWithNext)); style.addPropertyPt("fo:margin-top", m_topMargin); style.addPropertyPt("fo:margin-right", m_rightMargin); style.addPropertyPt("fo:margin-bottom", m_bottomMargin); style.addPropertyPt("fo:margin-left", m_leftMargin); // style:width may not be 0, use style:rel-width if width is 0 if (m_widthUnit == PercentageUnit || m_width <= 0) { style.addProperty("style:rel-width", QString::number(m_width) + QLatin1Char('%')); } else { style.addPropertyPt("style:width", m_width); } style.addProperty("style:may-break-between-rows", m_allowBreakBetweenRows ? "true" : "false"); style.addProperty("style:writing-mode", writingModeMap.value(m_writingMode)); style.addProperty("table:align", horizontalAlignMap.value(m_horizontalAlign)); style.addProperty("table:border-model", borderModelMap.value(m_borderModel)); if(!m_display) { style.addProperty("table:display", "false"); } if(!m_masterPageName.isEmpty()) { style.addAttribute("style:master-page-name", m_masterPageName); } }
void Document::slotSectionEnd(wvWare::SharedPtr<const wvWare::Word97::SEP> sep) { kDebug(30513); KoGenStyle* masterPageStyle = 0; KoGenStyle* pageLayoutStyle = 0; QString pageLayoutName; for (int i = 0; i < m_masterPageName_list.size(); i++) { pageLayoutStyle = m_pageLayoutStyle_list[i]; masterPageStyle = m_masterPageStyle_list[i]; Q_ASSERT(pageLayoutStyle); Q_ASSERT(masterPageStyle); //set the margins - depends on whether a header/footer is present // Set default left/right margins for the case when there is no border. // This will be changed below if there are borders defined. pageLayoutStyle->addPropertyPt("fo:margin-left", (double)sep->dxaLeft / 20.0); pageLayoutStyle->addPropertyPt("fo:margin-right", (double)sep->dxaRight / 20.0); // the pgbOffsetFrom variable determines how to calculate the margins and paddings. switch (sep->pgbOffsetFrom) { case pgbFromText: pageLayoutStyle->addPropertyPt("fo:margin-left", sep->dxaLeft / 20.0 - sep->brcLeft.dptSpace); pageLayoutStyle->addPropertyPt("fo:margin-right", sep->dxaRight / 20.0 - sep->brcRight.dptSpace); if (m_hasHeader_list[i]) { // If we have the header in the border, then our margin is the header top position if (m_parser->dop().fIncludeHeader) pageLayoutStyle->addPropertyPt("fo:margin-top", sep->dyaHdrTop / 20.0 - sep->brcTop.dptSpace); else pageLayoutStyle->addPropertyPt("fo:margin-top", (sep->dyaHdrTop + sep->dyaTop) / 20.0 - sep->brcTop.dptSpace); } else { pageLayoutStyle->addPropertyPt("fo:margin-top", sep->dyaTop / 20.0 - sep->brcTop.dptSpace); } if (m_hasFooter_list[i]) { // If we have the footer in the border, then our margin is the header bottom position if (m_parser->dop().fIncludeFooter) pageLayoutStyle->addPropertyPt("fo:margin-bottom", sep->dyaHdrBottom / 20.0 - sep->brcBottom.dptSpace); else pageLayoutStyle->addPropertyPt("fo:margin-bottom", (sep->dyaHdrBottom + sep->dyaBottom) / 20.0 - sep->brcBottom.dptSpace); } else { // same comment for footer as for header pageLayoutStyle->addPropertyPt("fo:margin-bottom", sep->dyaBottom / 20.0 - sep->brcBottom.dptSpace); } pageLayoutStyle->addPropertyPt("fo:padding-left", sep->brcLeft.dptSpace); pageLayoutStyle->addPropertyPt("fo:padding-right", sep->brcRight.dptSpace); pageLayoutStyle->addPropertyPt("fo:padding-top", sep->brcTop.dptSpace); pageLayoutStyle->addPropertyPt("fo:padding-bottom", sep->brcBottom.dptSpace); break; case pgbFromEdge: pageLayoutStyle->addPropertyPt("fo:margin-left", sep->brcLeft.dptSpace); pageLayoutStyle->addPropertyPt("fo:margin-right", sep->brcRight.dptSpace); pageLayoutStyle->addPropertyPt("fo:margin-top", sep->brcTop.dptSpace); pageLayoutStyle->addPropertyPt("fo:margin-bottom", sep->brcBottom.dptSpace); pageLayoutStyle->addPropertyPt("fo:padding-left", sep->dxaLeft / 20.0 - sep->brcLeft.dptSpace); pageLayoutStyle->addPropertyPt("fo:padding-right", sep->dxaRight / 20.0 - sep->brcRight.dptSpace); if (m_hasHeader_list[i]) { // minimum height of headers is not yet calculated but should be smth like: // sep->dyaTop - sep->dyaHdrTop pageLayoutStyle->addPropertyPt("fo:padding-top", sep->dyaHdrTop / 20.0 - sep->brcTop.dptSpace); } else { pageLayoutStyle->addPropertyPt("fo:padding-top", sep->dyaTop / 20.0 - sep->brcTop.dptSpace); } if (m_hasFooter_list[i]) { // same comment for footer as for header pageLayoutStyle->addPropertyPt("fo:padding-bottom", sep->dyaHdrBottom / 20.0 - sep->brcBottom.dptSpace); } else { pageLayoutStyle->addPropertyPt("fo:padding-bottom", sep->dyaBottom / 20.0 - sep->brcBottom.dptSpace); } break; } pageLayoutName = m_mainStyles->insert(*pageLayoutStyle, "Mpm"); masterPageStyle->addAttribute("style:page-layout-name", pageLayoutName); m_mainStyles->insert(*masterPageStyle, m_masterPageName_list[i], KoGenStyles::DontAddNumberToName); //delete objects, we've added them to the collection delete masterPageStyle; delete pageLayoutStyle; } //clear lists m_pageLayoutStyle_list.clear(); m_masterPageStyle_list.clear(); m_masterPageName_list.clear(); m_hasHeader_list.clear(); m_hasFooter_list.clear(); //reset header data m_headerCount = 0; }
//create page-layout and master-page void Document::slotSectionFound(wvWare::SharedPtr<const wvWare::Word97::SEP> sep) { kDebug(30513) ; m_omittMasterPage = false; m_useLastMasterPage = false; //does this section require a specific first page bool firstPage = sep->fTitlePage || sep->pgbApplyTo; // ******************************* // page-layout style // ******************************* kDebug(30513) << "preparing page-layout styles"; KoGenStyle* pageLayoutStyle = new KoGenStyle(KoGenStyle::PageLayoutStyle); //set page-layout attributes setPageLayoutStyle(pageLayoutStyle, sep, 0); pageLayoutStyle->setAutoStyleInStylesDotXml(true); //NOTE: Each section may require a new page-layout. If this is not the //case and the header/footer content didn't change, the <style:master-page> //element can be omitted. Except of continuous section break a manual page //break has to be inserted. //TODO: Even page/Odd page section break support //FIXME: missing support for fo:break-before="page" in table properties so //let's omitt the <style:master-page> element only in case of a continuous //section break if ( !firstPage && !headersChanged() && (m_pageLayoutStyle_last == *pageLayoutStyle) ){ // if (sep->bkc != 0) { // textHandler()->set_breakBeforePage(true); // } switch (sep->bkc) { case bkcContinuous: kDebug(30513) << "omitting page-layout & master-page creation"; m_omittMasterPage = true; break; case bkcNewPage: case bkcEvenPage: case bkcOddPage: kDebug(30513) << "using the last defined master-page"; m_useLastMasterPage = true; m_writeMasterPageName = true; break; default: kWarning(30513) << "Warning: section break type (" << sep->bkc << ") NOT SUPPORTED!"; m_omittMasterPage = true; break; } //cleaning required! delete pageLayoutStyle; } else { //save the actual KoGenStyle! m_pageLayoutStyle_last = *pageLayoutStyle; //add data into corresponding lists m_pageLayoutStyle_list.prepend(pageLayoutStyle); } //yeah, we can omitt creation of a new master-page if (m_omittMasterPage || m_useLastMasterPage) { return; } //check if a first-page specific page-layout has to be created if (firstPage) { pageLayoutStyle = new KoGenStyle(KoGenStyle::PageLayoutStyle); //set page-layout attributes for the first page setPageLayoutStyle(pageLayoutStyle, sep, 1); pageLayoutStyle->setAutoStyleInStylesDotXml(true); //add data into corresponding lists m_pageLayoutStyle_list.prepend(pageLayoutStyle); } // ******************************* // master-page style // ******************************* KoGenStyle* masterStyle = new KoGenStyle(KoGenStyle::MasterPageStyle); QString masterStyleName; //NOTE: The first master-page-name has to be "Standard", words has hard //coded that the value of fo:backgroud-color from this style is used for //the entire frameset. if (m_textHandler->sectionNumber() > 1) { masterStyleName.append("MP"); masterStyleName.append(QString::number(m_textHandler->sectionNumber())); } else { masterStyleName.append("Standard"); } masterStyle->addAttribute("style:display-name", masterStyleName); //add data into corresponding lists m_masterPageName_list.prepend(masterStyleName); m_masterPageStyle_list.prepend(masterStyle); //initialize the header/footer list m_hasHeader_list.prepend(false); m_hasFooter_list.prepend(false); //check if a first-page specific master-page has to be created if (firstPage) { masterStyle = new KoGenStyle(KoGenStyle::MasterPageStyle); masterStyleName.clear(); masterStyleName.append("First_Page"); if (m_textHandler->sectionNumber() > 1) { masterStyleName.append(QString::number(m_textHandler->sectionNumber())); } masterStyle->addAttribute("style:display-name", masterStyleName); masterStyle->addAttribute("style:next-style-name", m_masterPageName_list.last()); //add data into corresponding lists m_masterPageName_list.prepend(masterStyleName); m_masterPageStyle_list.prepend(masterStyle); //initialize the header/footer list m_hasHeader_list.prepend(false); m_hasFooter_list.prepend(false); } //required by handlers m_writeMasterPageName = true; //required by this module m_lastMasterPageName = m_masterPageName_list.first(); for (int i = 0; i < m_masterPageName_list.size(); i++) { kDebug(30513) << "prepared master-page style:" << m_masterPageName_list[i]; } }