Exemplo n.º 1
0
void Document::setPageLayoutStyle(KoGenStyle* pageLayoutStyle,
                                  wvWare::SharedPtr<const wvWare::Word97::SEP> sep,
                                  bool firstPage)
{
    // TODO: Check page-layout attributes specific for the first page.

    //get width & height in points
    double width = (double)sep->xaPage / 20.0;
    double height = (double)sep->yaPage / 20.0;
    pageLayoutStyle->addPropertyPt("fo:page-width", width);
    pageLayoutStyle->addPropertyPt("fo:page-height", height);
    pageLayoutStyle->addProperty("style:footnote-max-height", "0in");
    pageLayoutStyle->addProperty("style:writing-mode", "lr-tb");
    bool landscape = (sep->dmOrientPage == 2);
    pageLayoutStyle->addProperty("style:print-orientation", landscape ? "landscape" : "portrait");
    pageLayoutStyle->addProperty("style:num-format", "1");

    DrawStyle ds = m_graphicsHandler->getBgDrawStyle();
    if (ds.fFilled()) {
        switch (ds.fillType()) {
        case msofillSolid:
        {
            // PptToOdp::toQColor helper function can be used instead of this conversion
            MSO::OfficeArtCOLORREF clr = ds.fillColor();
            QColor color(clr.red, clr.green, clr.blue);
            QString tmp = color.name();
            pageLayoutStyle->addProperty("fo:background-color", tmp);

            //update the background-color information if required
            if (tmp != currentBgColor()) {
                updateBgColor(tmp);
            }
            break;
        }
        //TODO:
//         case msofillShade:
//         case msofillShadeCenter:
//         case msofillShadeShape:
//         case msofillShadeScale:
//         case msofillShadeTitle:
//
        //TODO:
//         case msofillPattern:
//         case msofillTexture:
//
        case msofillPicture:
        {
            // picture can be stored in OfficeArtBStoreContainer or in
            // fillBlip_complex if complex = true only picture in
            // OfficeArtBStoreContainer is handled now
            QString filePath = m_graphicsHandler->getPicturePath(ds.fillBlip());

            if (!filePath.isEmpty()) {
                QBuffer buffer;
                KoXmlWriter bkgImageWriter(&buffer);

                bkgImageWriter.startElement("style:background-image");
                bkgImageWriter.addAttribute("xlink:href", filePath);
                bkgImageWriter.addAttribute("xlink:type", "simple");
                bkgImageWriter.addAttribute("xlink:actuate", "onLoad");
                bkgImageWriter.endElement(); //style:background-image

                QString contents = QString::fromUtf8(((QBuffer*)bkgImageWriter.device())->buffer(),
                                         ((QBuffer*)bkgImageWriter.device())->buffer().size());

                pageLayoutStyle->addChildElement("0", contents);
            }
        break;
        }
        //TODO:
//         case msofillBackground:
        default:
            break;
        }
    }

    // NOTE: margin-top and margin-bottom are updated in slotSectionFound based
    // on the information if the header/footer was empty/non-empty.
    //
    // Maybe we should set the minimum height of header/footer to qAbs(dyaTop -
    // dyaHdrTop)/qAbs(dyaBottom - dyaHdrBottom)
    //
    // The height of both header and footer is unknown, so it's not possible to
    // set margin-bottom for the header and margin-top for the footer properly.
    // Both dyaTop and dyaBottom do not tell us where the header/footer ends.
    //
    // MSWord specific:
    // For each x in {header, footer, body}, x has an independent ruler.
    //
    // Also both header and footer are treated like a separate document, so if
    // you insert a border into the body, then header/footer margins do not
    // change.  We are not able to store this into ODF properly.

    QString header("<style:header-style>");
    header.append("<style:header-footer-properties");

    // The spec says the top-margin MUST be grown to avoid overlapping the
    // space that is occupied by headers.  Not ODF compatible.
    if (sep->dyaTop >= 0) {
        header.append(" style:dynamic-spacing=\"true\"");
        header.append(" fo:margin-bottom=\"0pt\"");
    } else {
        //TODO: tests required, I would prefer margin-bottom set to ZERO
        header.append(" style:dynamic-spacing=\"false\"");
        header.append(" fo:margin-bottom=\"");
#if 0
        qreal headerMarginTop = qAbs(sep->dyaTop) - sep->dyaHdrTop;
        if (headerMarginTop > 0) {
            header.append(QString::number(headerMarginTop / 20.0, 'f'));
        } else
#endif
            header.append("0");
        header.append("pt\"");

    }
    header.append(" fo:min-height=\"14pt\"/>");
    header.append("</style:header-style>");

    QString footer("<style:footer-style>");
    footer.append("<style:header-footer-properties");

    // The spec says the bottom-margin MUST be grown to avoid overlapping the
    // space that is occupied by footers or footnotes.  Not ODF compatible.
    if (sep->dyaBottom > 0) {
        footer.append(" style:dynamic-spacing=\"true\"");
        footer.append(" fo:margin-top=\"0pt\"");
    } else {
        //TODO: tests required, I would prefer margin-top set to ZERO
        footer.append(" style:dynamic-spacing=\"false\"");
        footer.append(" fo:margin-top=\"");
        qreal headerMarginBottom = qAbs(sep->dyaBottom) - sep->dyaHdrBottom;
        if (headerMarginBottom >= 400) {
            footer.append(QString::number(headerMarginBottom / 20.0, 'f'));
        } else {
            footer.append("14");
        }
        footer.append("pt\"");
    }
    footer.append(" fo:min-height=\"10pt\"/>");
    footer.append("</style:footer-style>");

    pageLayoutStyle->addProperty("1header-style", header, KoGenStyle::StyleChildElement);
    pageLayoutStyle->addProperty("2footer-style", footer, KoGenStyle::StyleChildElement);

    //Page borders, check to which page-layout the border information has to be
    //applied: 0 - all pages, 1 - first page only, 2 - all but first.

    //NOTE: 3 - whole document, not mentioned in the "Word Binary File Format
    //(.doc) Structure Specification", but mentiond in word97_generated.h
    if ( (sep->pgbApplyTo == 0) ||
        ((sep->pgbApplyTo == 1) && firstPage) ||
        ((sep->pgbApplyTo == 2) && !firstPage))
    {
        // FIXME: check if we can use fo:border instead of fo:border-left, etc.
        if (sep->brcLeft.brcType != 0) {
            pageLayoutStyle->addProperty("fo:border-left",
                                         Conversion::setBorderAttributes(sep->brcLeft));
            pageLayoutStyle->addProperty("calligra:specialborder-left",
                                         Conversion::borderCalligraAttributes(sep->brcLeft));
        }
        if (sep->brcTop.brcType != 0) {
            pageLayoutStyle->addProperty("fo:border-top",
                                         Conversion::setBorderAttributes(sep->brcTop));
            pageLayoutStyle->addProperty("calligra:specialborder-top",
                                         Conversion::borderCalligraAttributes(sep->brcTop));
        }
        if (sep->brcRight.brcType != 0) {
            pageLayoutStyle->addProperty("fo:border-right",
                                         Conversion::setBorderAttributes(sep->brcRight));
            pageLayoutStyle->addProperty("calligra:specialborder-right",
                                         Conversion::borderCalligraAttributes(sep->brcRight));
        }
        if (sep->brcBottom.brcType != 0) {
            pageLayoutStyle->addProperty("fo:border-bottom",
                                         Conversion::setBorderAttributes(sep->brcBottom));
            pageLayoutStyle->addProperty("calligra:specialborder-bottom",
                                         Conversion::borderCalligraAttributes(sep->brcBottom));
        }
    }
    // TODO: use sep->fEndNote to set the 'use endnotes or footnotes' flag
}
Exemplo n.º 2
0
void Document::setPageLayoutStyle(KoGenStyle* pageLayoutStyle,
                                  wvWare::SharedPtr<const wvWare::Word97::SEP> sep,
                                  bool firstPage)
{
    // TODO: Check page-layout attributes specific for the first page.

    //get width & height in points
    double width = (double)sep->xaPage / 20.0;
    double height = (double)sep->yaPage / 20.0;
    pageLayoutStyle->addPropertyPt("fo:page-width", width);
    pageLayoutStyle->addPropertyPt("fo:page-height", height);
    pageLayoutStyle->addProperty("style:footnote-max-height", "0in");
    pageLayoutStyle->addProperty("style:writing-mode", "lr-tb");
    bool landscape = (sep->dmOrientPage == 2);
    pageLayoutStyle->addProperty("style:print-orientation", landscape ? "landscape" : "portrait");
    pageLayoutStyle->addProperty("style:num-format", "1");

    // 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);

    DrawStyle ds = m_graphicsHandler->getDrawingStyle();
    // TODO: use ds.fillType to enable fill efects for document background

    // When more complete background-color implementation will be added to filter,
    // PptToOdp::toQColor helper function can be used instead of this conversion
    MSO::OfficeArtCOLORREF clr = ds.fillColor();
    QColor color(clr.red, clr.green, clr.blue);
    QString tmp = color.name();
    pageLayoutStyle->addProperty("fo:background-color", tmp);

    //update the background-color information if required
    if (tmp != currentBgColor()) {
        updateBgColor(tmp);
    }

    //set the minimum height of header/footer to the full margin minus margin above header
    //problem with footer is that it is not possible to say how big the footer is.
    QString header("<style:header-style>");
    header.append("<style:header-footer-properties fo:margin-bottom=\"");
    header.append(QString::number((sep->dyaTop - sep->dyaHdrTop) / 20.0));
    header.append("pt\" fo:min-height=\"14pt\"/>");
    header.append("</style:header-style>");

    QString footer("<style:footer-style>");
    footer.append("<style:header-footer-properties fo:margin-top=\"");
    if (sep->dyaBottom > (int)sep->dyaHdrBottom) {
        if ((sep->dyaBottom - sep->dyaHdrBottom) >= 400) {
            footer.append(QString::number((sep->dyaBottom - sep->dyaHdrBottom) / 20.0));
        } else {
            footer.append("14");
        }
    }
    else {
        footer.append("14");
    }
    footer.append("pt\" fo:min-height=\"10pt\"/>");
    footer.append("</style:footer-style>");

    pageLayoutStyle->addProperty("1header-style", header, KoGenStyle::StyleChildElement);
    pageLayoutStyle->addProperty("2footer-style", footer, KoGenStyle::StyleChildElement);

    //Page borders, check to which page-layout the border information has to be
    //applied: 0 - all pages, 1 - first page only, 2 - all but first.

    //NOTE: 3 - whole document, not mentioned in the "Word Binary File Format
    //(.doc) Structure Specification", but mentiond in word97_generated.h
    if ( (sep->pgbApplyTo == 0) ||
        ((sep->pgbApplyTo == 1) && firstPage) ||
        ((sep->pgbApplyTo == 2) && !firstPage))
    {
        // FIXME: check if we can use fo:border instead of fo:border-left, etc.
        if (sep->brcLeft.brcType != 0) {
            pageLayoutStyle->addProperty("fo:border-left",
                                         Conversion::setBorderAttributes(sep->brcLeft));
            pageLayoutStyle->addProperty("koffice:specialborder-left",
                                         Conversion::borderKOfficeAttributes(sep->brcLeft));
        }
        if (sep->brcTop.brcType != 0) {
            pageLayoutStyle->addProperty("fo:border-top",
                                         Conversion::setBorderAttributes(sep->brcTop));
            pageLayoutStyle->addProperty("koffice:specialborder-top",
                                         Conversion::borderKOfficeAttributes(sep->brcTop));
        }
        if (sep->brcRight.brcType != 0) {
            pageLayoutStyle->addProperty("fo:border-right",
                                         Conversion::setBorderAttributes(sep->brcRight));
            pageLayoutStyle->addProperty("koffice:specialborder-right",
                                         Conversion::borderKOfficeAttributes(sep->brcRight));
        }
        if (sep->brcBottom.brcType != 0) {
            pageLayoutStyle->addProperty("fo:border-bottom",
                                         Conversion::setBorderAttributes(sep->brcBottom));
            pageLayoutStyle->addProperty("koffice:specialborder-bottom",
                                         Conversion::borderKOfficeAttributes(sep->brcBottom));
        }
    }
    // the pgbOffsetFrom variable determins how to calculate the margins and paddings.
    if (sep->pgbOffsetFrom == 0) {
        // page border offset is from the text
        pageLayoutStyle->addPropertyPt("fo:padding-left",   sep->brcLeft.dptSpace);
        pageLayoutStyle->addPropertyPt("fo:padding-top",    sep->brcTop.dptSpace);
        pageLayoutStyle->addPropertyPt("fo:padding-right",  sep->brcRight.dptSpace);
        pageLayoutStyle->addPropertyPt("fo:padding-bottom", sep->brcBottom.dptSpace);
        // FIXME: How should fo:margin be created in this case?
    } else {
        // page border offset is from the edge of the page

        // Add margin. This value is fetched directly from the BRC's.
        pageLayoutStyle->addPropertyPt("fo:margin-left",   sep->brcLeft.dptSpace);
        pageLayoutStyle->addPropertyPt("fo:margin-top",    sep->brcTop.dptSpace);
        pageLayoutStyle->addPropertyPt("fo:margin-right",  sep->brcRight.dptSpace);
        pageLayoutStyle->addPropertyPt("fo:margin-bottom", sep->brcBottom.dptSpace);

        // The *20 and /20 below is the conversion between twips (1/20th of a point) and points.
        pageLayoutStyle->addPropertyPt("fo:padding-left",
                                         (sep->dxaLeft - (sep->brcLeft.dptSpace * 20)) / 20);
        pageLayoutStyle->addPropertyPt("fo:padding-top",
                                         (sep->dyaTop - (sep->brcTop.dptSpace * 20)) / 20);
        pageLayoutStyle->addPropertyPt("fo:padding-right",
                                         (sep->dxaRight - (sep->brcRight.dptSpace * 20)) / 20);
        pageLayoutStyle->addPropertyPt("fo:padding-bottom",
                                         (sep->dyaBottom - (sep->brcBottom.dptSpace * 20)) / 20);
    }
    // TODO: use sep->fEndNote to set the 'use endnotes or footnotes' flag
}