Пример #1
0
QSizeF ChartTextObject::intrinsicSize(QTextDocument *doc, int posInDocument,
            const QTextFormat &format)
{
    Q_UNUSED(posInDocument);

    QSizeF size( format.property( Size ).toSizeF() );

    switch ( format.property( Unit ).toInt() ) {
    case Percent: {
        const qreal pageWidth = doc->pageSize().width();
        const qreal percent = size.width();
        const qreal ratio = size.height() / size.width();

        qreal newWidth = pageWidth * percent / 100.0;

        //XXX For some reason 100% width charts will get cropped
        //need to make a little room
        if ( percent == 100.0 )
            newWidth -= 9;

        return QSizeF( newWidth, newWidth * ratio );
        }
    case Millimeters:
        return QSizeF( mmToPixels( size.width() ), mmToPixels( size.height() ) );
    }

    return QSizeF();
}
Пример #2
0
qreal KDReports::ReportPrivate::mainTextDocHeight() const
{
    const qreal height = rawMainTextDocHeight();
    const bool skip = height <= 0;
    if ( skip ) {
        qreal textDocHeight = paperSize().height() - mmToPixels( m_marginTop + m_marginBottom );
        textDocHeight -= mmToPixels( m_headerBodySpacing );
        textDocHeight -= mmToPixels( m_footerBodySpacing );
        return textDocHeight;
    }
    return height;
}
Пример #3
0
// The height of the text doc, by calculation. Adjusted by caller, if negative.
qreal KDReports::ReportPrivate::rawMainTextDocHeight() const
{
    qreal textDocHeight = paperSize().height() - mmToPixels( m_marginTop + m_marginBottom );
    const qreal headerHeight = m_headers.height();
    textDocHeight -= headerHeight;
    textDocHeight -= mmToPixels( m_headerBodySpacing );
    const qreal footerHeight = m_footers.height();
    textDocHeight -= mmToPixels( m_footerBodySpacing );
    textDocHeight -= footerHeight;
    //qDebug() << "pageContent height (pixels): paper size" << m_paperSize.height() << "minus margins" << mmToPixels( m_marginTop + m_marginBottom )
    //        << "minus headerHeight" << headerHeight << "minus footerHeight" << footerHeight << "and spacings =" << textDocHeight;
    return textDocHeight;
}
Пример #4
0
void KDReports::Frame::build( ReportBuilder& builder ) const
{
    // prepare the frame
    QTextFrameFormat format;
    if ( d->m_width ) {
        if ( d->m_widthUnit == Millimeters ) {
            format.setWidth( QTextLength( QTextLength::FixedLength, mmToPixels( d->m_width ) ) );
        } else {
            format.setWidth( QTextLength( QTextLength::PercentageLength, d->m_width ) );
        }
    }
    if ( d->m_height ) {
        if ( d->m_heightUnit == Millimeters ) {
            format.setHeight( QTextLength( QTextLength::FixedLength, mmToPixels( d->m_height ) ) );
        } else {
            format.setHeight( QTextLength( QTextLength::PercentageLength, d->m_height ) );
        }
    }

    format.setPadding( mmToPixels( padding() ) );
    format.setBorder( d->m_border );
    // TODO borderBrush like in AbstractTableElement
    format.setPosition( QTextFrameFormat::InFlow );

    QTextCursor& textDocCursor = builder.cursor();

    QTextFrame *frame = textDocCursor.insertFrame(format);

    QTextCursor contentsCursor = frame->firstCursorPosition();

    ReportBuilder contentsBuilder( builder.currentDocumentData(),
                                   contentsCursor, builder.report() );
    contentsBuilder.copyStateFrom( builder );

    foreach( const KDReports::ElementData& ed, d->m_elements )
    {
        switch ( ed.m_type ) {
        case KDReports::ElementData::Inline:
            contentsBuilder.addInlineElement( *ed.m_element );
            break;
        case KDReports::ElementData::Block:
            contentsBuilder.addBlockElement( *ed.m_element, ed.m_align );
            break;
        case KDReports::ElementData::Variable:
            contentsBuilder.addVariable( ed.m_variableType );
            break;
        }
    }

    textDocCursor.movePosition( QTextCursor::End );
}
Пример #5
0
bool KDReports::Report::exportToImage( const QSize& size, const QString& fileName, const char* format )
{
    // Get the document to fit into one page

    QPrinter::PageSize savePageSize = pageSize();
    const qreal saveLayoutWidth = d->m_layoutWidth;
    d->m_layoutWidth = d->m_layout->idealWidth() + mmToPixels(d->m_marginLeft + d->m_marginRight);
    d->m_pageContentSizeDirty = true;
    d->ensureLayouted();

    const qreal zoomFactor = qMin( (qreal)size.width() / d->m_paperSize.width(),
                                   (qreal)size.height() / d->m_paperSize.height() );
    //qDebug() << "zoomFactor=" << zoomFactor;

    QImage image( size, QImage::Format_ARGB32_Premultiplied );
    image.fill( Qt::white );

    QPainter painter( &image );
    painter.setRenderHint( QPainter::Antialiasing );
    painter.setRenderHint( QPainter::SmoothPixmapTransform );
    painter.fillRect( QRectF(0, 0, size.width(), size.height()), QBrush(Qt::white) );
    painter.scale( zoomFactor, zoomFactor );
    d->paintPage( 0, painter );

    // restore textdoc size and header widths
    d->m_layoutWidth = saveLayoutWidth;
    setPageSize( savePageSize ); // redo layout
    qDebug() << "Saving pixmap" << image.size() << "into" << fileName << "with format" << format;
    return image.save( fileName, format );
}
Пример #6
0
QSizeF KDReports::ReportPrivate::paperSize() const
{
    // determine m_paperSize from m_pageSize if needed
    if (m_paperSize.isEmpty()) {
        int width_index = 0;
        int height_index = 1;
        if (m_orientation == QPrinter::Landscape) {
            width_index = 1;
            height_index = 0;
        }
        m_paperSize = QSizeF(mmToPixels(kdr_paperSizes[m_pageSize][width_index]),
                             mmToPixels(kdr_paperSizes[m_pageSize][height_index]));
    }
    //qDebug() << "m_paperSize=" << m_paperSize;
    return m_paperSize;
}
Пример #7
0
QSizeF KDReports::ReportPrivate::layoutAsOnePage( qreal docWidth )
{
    m_headers.layoutWithTextWidth( docWidth );
    m_footers.layoutWithTextWidth( docWidth );

    const qreal docHeight = m_layout->layoutAsOnePage(docWidth);

    qreal pageWidth = docWidth + mmToPixels( m_marginLeft + m_marginRight );
    qreal pageHeight = docHeight + mmToPixels( m_marginTop + m_marginBottom );
    pageHeight += m_headers.height();
    pageHeight += m_footers.height();

    m_pageContentSizeDirty = false;

    //qDebug() << "One-page document is" << pageWidth << "x" << pageHeight;
    return QSizeF( pageWidth, pageHeight );
}
Пример #8
0
void KDReports::Report::setWidthForEndlessPrinter( qreal widthMM )
{
    if ( widthMM ) {
        d->m_endlessPrinterWidth = widthMM;
        d->m_layoutWidth = mmToPixels( widthMM );
        d->m_pageContentSizeDirty = true;
        d->ensureLayouted();
    } else {
        d->m_layoutWidth = 0;
        d->m_pageContentSizeDirty = true;
        // caller will call setPageSize...
    }
}
void KDReports::AbstractTableElement::fillTableFormat( QTextTableFormat& tableFormat, QTextCursor& textDocCursor ) const
{
    if ( d->m_width ) {
        if ( d->m_unit == Millimeters ) {
            tableFormat.setWidth( QTextLength( QTextLength::FixedLength, mmToPixels( d->m_width ) ) );
        } else {
            tableFormat.setWidth( QTextLength( QTextLength::PercentageLength, d->m_width ) );
        }
    }

    tableFormat.setBorder( border() );
#if QT_VERSION >= 0x040300
    tableFormat.setBorderBrush( borderBrush() );
    tableFormat.setBorderStyle( QTextFrameFormat::BorderStyle_Solid );
#endif
    tableFormat.setCellPadding( mmToPixels( padding() ) );
    tableFormat.setCellSpacing( -1 ); // HTML-like table borders look so old century
    if ( d->m_fontSpecified ) {
        QTextCharFormat charFormat = textDocCursor.charFormat();
        charFormat.setFont( d->m_defaultFont );
        textDocCursor.setCharFormat( charFormat );
    }
}
Пример #10
0
void KDReports::Report::setPaperSize( const QSizeF & paperSize, QPrinter::Unit unit )
{
    qreal factor = 1.0;
    switch ( unit ) {
    case QPrinter::DevicePixel:
        break;
    case QPrinter::Millimeter:
        factor = mmToPixels( 1.0 );
        break;
    case QPrinter::Point:
        factor = 72.0 * qt_defaultDpi();
        break;
    case QPrinter::Inch:
        factor = qt_defaultDpi();
        break;
    default:
        qWarning( "Unsupported printer unit %d", unit );
    }
    d->m_paperSize = QSizeF( paperSize.width() * factor, paperSize.height() * factor );
    d->m_pageContentSizeDirty = true;
}
Пример #11
0
/*
   [top margin]
   [header]
   [m_headerBodySpacing]
   [body]
   [m_footerBodySpacing]
   [footer]
   [bottom margin]
 */
void KDReports::ReportPrivate::setPaperSizeFromPrinter( const QSizeF& paperSize )
{
    Q_ASSERT( !wantEndlessPrinting() ); // call ensureLayouted instead!

    m_paperSize = paperSize;
    const qreal marginsInPixels = mmToPixels( m_marginLeft + m_marginRight );
    qreal textDocWidth = m_paperSize.width() - marginsInPixels;

    m_headers.layoutWithTextWidth( textDocWidth );
    m_footers.layoutWithTextWidth( textDocWidth );

    const qreal textDocHeight = mainTextDocHeight();

    // Font scaling
    // Problem: how to re-implement this without a layout document?
    // We would risk cumulating rounding problems...?
    // ### 2nd problem: what about fonts in headers and footers? shouldn't they scale too?
    //if ( m_scaleFontsBy != 1.0 )
    //    m_textDocument.scaleFontsBy( m_scaleFontsBy );

    m_layout->setPageContentSize( QSizeF( textDocWidth, textDocHeight ) );

    m_pageContentSizeDirty = false;
}
Пример #12
0
void KDReports::ReportPrivate::ensureLayouted()
{
    // We need to do a layout if
    // m_pageContentSizeDirty is true, i.e. page size has changed etc.
    if (m_pageContentSizeDirty) {
        if (!wantEndlessPrinting()) {
            setPaperSizeFromPrinter(paperSize());
        } else {
            // Get the document to fit into one page
            Q_ASSERT(m_layoutWidth != 0);
            qreal textDocWidth = m_layoutWidth - mmToPixels(m_marginLeft + m_marginRight);
            m_paperSize = layoutAsOnePage(textDocWidth);

            qDebug() << "setPaperSizeFromPrinter: endless printer. m_layoutWidth=" << m_layoutWidth
              << "textDocWidth=" << textDocWidth
              << "single page has size" << m_paperSize << "pixels";

            Q_ASSERT(m_layout->numberOfPages() == 1);
        }
        // at this point m_pageContentSizeDirty has been set to false in all cases
    }

    m_layout->ensureLayouted();
}
Пример #13
0
qreal KDReports::ReportPrivate::textDocumentWidth() const
{
    return paperSize().width() - mmToPixels( m_marginLeft + m_marginRight );
}
Пример #14
0
void KDReports::ReportPrivate::paintPage( int pageNumber, QPainter& painter )
{
    ensureLayouted();

    const int pageCount = m_layout->numberOfPages();
    KDReports::Header* header = m_headers.headerForPage( pageNumber + 1, pageCount );
    if ( header ) {
        header->preparePaintingPage( pageNumber + m_firstPageNumber - 1 );
    }
    KDReports::Header* footer = m_footers.headerForPage( pageNumber + 1, pageCount );
    if ( footer ) {
        footer->preparePaintingPage( pageNumber + m_firstPageNumber - 1 );
    }

    const qreal textDocWidth = m_paperSize.width() - mmToPixels( m_marginLeft + m_marginRight );
    const qreal textDocHeight = mainTextDocHeight();

    const int left = qRound( mmToPixels( m_marginLeft ) );
    const int top = qRound( mmToPixels( m_marginTop ) );
    //const int right = qRound( mmToPixels( m_marginRight ) );
    const int bottom = qRound( mmToPixels( m_marginBottom ) );
    const bool skipHeadersFooters = this->skipHeadersFooters();
    const int headerHeightWithSpacing = qRound( ( skipHeadersFooters ? 0 : m_headers.height() ) + mmToPixels( m_headerBodySpacing ) );
    const int footerHeight = skipHeadersFooters ? 0 : qRound( m_footers.height() );
    //const int footerHeightWithspacing = qRound( m_footers.height() + mmToPixels( m_footerBodySpacing ) );
    //const QRect paperRect( 0, 0, qRound( m_paperSize.width() ), qRound( m_paperSize.height() ) );
    //const QRect textDocRect = paperRect.adjusted( left, top + headerHeightWithSpacing,
    //                                              -right, - bottom - footerHeightWithspacing);
    const QRect textDocRect( left, top + headerHeightWithSpacing,
                             textDocWidth, textDocHeight );

    /*qDebug() << "paintPage: in pixels: top=" << top << " headerHeight=" << headerHeightWithSpacing
             << " textDoc size:" << textDocRect.size()
             << " bottom=" << bottom << " footerHeight=" << footerHeight;*/

    if( !m_watermarkText.isEmpty() ) {
        painter.save();
        painter.translate( textDocRect.center() );
        painter.rotate( m_watermarkRotation );
        painter.setFont( m_watermarkFont );
        painter.setPen( m_watermarkColor );
        const QSize textSize( painter.fontMetrics().size( Qt::TextSingleLine, m_watermarkText ) );
        const QRect textRect( -textSize.width() / 2, -textSize.height()/2, textSize.width(), textSize.height() );
        painter.drawText( textRect, Qt::AlignCenter, m_watermarkText );
        painter.restore();
    }

    if( !m_watermarkImage.isNull() ) {
        // We paint it without scaling it, for better quality.
        // But this means the actual size depends on the zoom level or printer resolution...
        //
        // It also means the image could end up being bigger than the page, and we don't want that.
        // So we scale down if necessary. But never up.
        QImage img = m_watermarkImage;
        if ( m_watermarkImage.width() > textDocRect.width() ||
             m_watermarkImage.height() > textDocRect.height() ) {
            // should probably be cached?
            img = m_watermarkImage.scaled( textDocRect.size(), Qt::KeepAspectRatio, Qt::SmoothTransformation );
        }
        const QRect imageRect = QStyle::alignedRect( Qt::LeftToRight, Qt::AlignCenter, img.size(), textDocRect );
        //qDebug() << "textDocRect=" << textDocRect << "size=" << img.size() << "-> imageRect=" << imageRect;
        painter.drawImage( imageRect.topLeft(), img );
    }


    painter.save();
    //painter.setClipRect( textDocRect, Qt::IntersectClip ); // triggers a Qt-Windows bug when printing
    painter.setClipRect( textDocRect );
    painter.translate( left, top + headerHeightWithSpacing );
    m_layout->paintPageContent( pageNumber, painter );
    painter.restore();

    QAbstractTextDocumentLayout::PaintContext ctx;
    ctx.palette.setColor(QPalette::Text, Qt::black);
    if ( header && !skipHeadersFooters ) {
        painter.save();
        painter.translate( left, top );
        ctx.clip = painter.clipRegion().boundingRect();
        header->doc().contentDocument().documentLayout()->draw(&painter, ctx);
        painter.restore();
    }
    if ( footer && !skipHeadersFooters ) {
        painter.save();
        painter.translate( left, m_paperSize.height() - bottom - footerHeight );
        ctx.clip = painter.clipRegion().boundingRect();
        footer->doc().contentDocument().documentLayout()->draw(&painter, ctx);
        painter.restore();
    }
}
Пример #15
0
void KDReports::Report::setFixedRowHeight(qreal mm)
{
    d->m_layout->setFixedRowHeight( mmToPixels(mm) );
}