Skip to content
Permalink
Browse files

Revert automatic detection for preview renders

Turns out there's no reliable way to differentiate widget
vs QImage based renders inside QGraphicsItems
  • Loading branch information
nyalldawson committed Oct 16, 2017
1 parent edecc37 commit 4a1bcb32664b01f18187e4051de0d724491261cc
@@ -125,6 +125,14 @@ class QgsLayoutContext : QObject
:rtype: QgsLayoutMeasurementConverter
%End

bool isPreviewRender() const;
%Docstring
Returns true if the render current being conducted is a preview render,
i.e. it is being rendered inside a QGraphicsView widget as opposed to a destination
device (such as an image).
:rtype: bool
%End

bool gridVisible() const;
%Docstring
Returns true if the page grid should be drawn.
@@ -73,14 +73,6 @@ class QgsLayoutUtils
%End


static bool isPreviewRender( QPainter *painter );
%Docstring
Returns true if the render to the specified ``painter`` is a preview render,
i.e. is being rendered inside a QGraphicsView widget as opposed to a destination
device (such as an image).
:rtype: bool
%End

};

/************************************************************************
@@ -174,7 +174,7 @@ class QgsLayoutChecker : QgsMultiRenderChecker
Sets the output (reference) image ``size``.
%End

bool runTest( QString &report, int page = 0, int pixelDiff = 0 );
bool testLayout( QString &report, int page = 0, int pixelDiff = 0 );
%Docstring
Runs a render check on the layout, adding results to the specified ``report``.

@@ -141,6 +141,13 @@ class CORE_EXPORT QgsLayoutContext : public QObject
*/
QgsLayoutMeasurementConverter &measurementConverter() { return mMeasurementConverter; }

/**
* Returns true if the render current being conducted is a preview render,
* i.e. it is being rendered inside a QGraphicsView widget as opposed to a destination
* device (such as an image).
*/
bool isPreviewRender() const { return mIsPreviewRender; }

/**
* Returns true if the page grid should be drawn.
* \see setGridVisible()
@@ -198,10 +205,13 @@ class CORE_EXPORT QgsLayoutContext : public QObject

QgsLayoutMeasurementConverter mMeasurementConverter;

bool mIsPreviewRender = true;
bool mGridVisible = false;
bool mBoundingBoxesVisible = true;
bool mPagesVisible = true;

friend class QgsLayoutExporter;


};

@@ -51,6 +51,8 @@ void QgsLayoutExporter::renderRegion( QPainter *painter, const QRectF &region )
return;
}

mLayout->context().mIsPreviewRender = false;

#if 0 //TODO
setSnapLinesVisible( false );
#endif
@@ -60,5 +62,7 @@ void QgsLayoutExporter::renderRegion( QPainter *painter, const QRectF &region )
#if 0 // TODO
setSnapLinesVisible( true );
#endif

mLayout->context().mIsPreviewRender = true;
}

@@ -224,7 +224,7 @@ void QgsLayoutItem::setParentGroup( QgsLayoutItemGroup *group )

void QgsLayoutItem::paint( QPainter *painter, const QStyleOptionGraphicsItem *itemStyle, QWidget * )
{
if ( !painter || !painter->device() || !shouldDrawItem( painter ) )
if ( !painter || !painter->device() || !shouldDrawItem() )
{
return;
}
@@ -431,9 +431,9 @@ bool QgsLayoutItem::shouldBlockUndoCommands() const
return !mLayout || mLayout != scene() || mBlockUndoCommands;
}

bool QgsLayoutItem::shouldDrawItem( QPainter *painter ) const
bool QgsLayoutItem::shouldDrawItem() const
{
if ( QgsLayoutUtils::isPreviewRender( painter ) )
if ( !mLayout || mLayout->context().isPreviewRender() )
{
//preview mode so OK to draw item
return true;
@@ -769,10 +769,9 @@ class CORE_EXPORT QgsLayoutItem : public QgsLayoutObject, public QGraphicsRectIt
bool shouldBlockUndoCommands() const;

/**
* Returns whether the item should be drawn in the current context
* and to the given \a painter.
* Returns whether the item should be drawn in the current context.
*/
bool shouldDrawItem( QPainter *painter ) const;
bool shouldDrawItem() const;

friend class TestQgsLayoutItem;
friend class TestQgsLayoutView;
@@ -178,7 +178,7 @@ void QgsLayoutItemPage::draw( QgsRenderContext &context, const QStyleOptionGraph
QPainter *painter = context.painter();
painter->save();

if ( QgsLayoutUtils::isPreviewRender( context.painter() ) )
if ( mLayout->context().isPreviewRender() )
{
//if in preview mode, draw page border and shadow so that it's
//still possible to tell where pages with a transparent style begin and end
@@ -254,7 +254,7 @@ void QgsLayoutItemPageGrid::paint( QPainter *painter, const QStyleOptionGraphics
if ( !mLayout )
return;

if ( !QgsLayoutUtils::isPreviewRender( painter ) )
if ( !mLayout->context().isPreviewRender() )
return;

const QgsLayoutContext &context = mLayout->context();
@@ -109,28 +109,3 @@ double QgsLayoutUtils::relativePosition( const double position, const double bef
//return linearly scaled position
return m * position + c;
}

bool QgsLayoutUtils::isPreviewRender( QPainter *painter )
{
if ( !painter || !painter->device() )
return false;

// if rendering to a QGraphicsView, we are in preview mode
QPaintDevice *device = painter->device();
if ( dynamic_cast< QPixmap * >( device ) )
return true;

QObject *obj = dynamic_cast< QObject *>( device );
if ( !obj )
return false;

const QMetaObject *mo = obj->metaObject();
while ( mo )
{
if ( mo->className() == QStringLiteral( "QGraphicsView" ) )
return true;

mo = mo->superClass();
}
return false;
}
@@ -82,13 +82,6 @@ class CORE_EXPORT QgsLayoutUtils
static double relativePosition( const double position, const double beforeMin, const double beforeMax, const double afterMin, const double afterMax );


/**
* Returns true if the render to the specified \a painter is a preview render,
* i.e. is being rendered inside a QGraphicsView widget as opposed to a destination
* device (such as an image).
*/
static bool isPreviewRender( QPainter *painter );

};

#endif //QGSLAYOUTUTILS_H
@@ -188,7 +188,7 @@ QgsLayoutChecker::QgsLayoutChecker( const QString &testName, QgsLayout *layout )
setColorTolerance( 5 );
}

bool QgsLayoutChecker::runTest( QString &checkedReport, int page, int pixelDiff )
bool QgsLayoutChecker::testLayout( QString &checkedReport, int page, int pixelDiff )
{
if ( !mLayout )
{
@@ -197,7 +197,7 @@ class CORE_EXPORT QgsLayoutChecker : public QgsMultiRenderChecker
*
* Returns false if the rendered layout differs from the expected reference image.
*/
bool runTest( QString &report, int page = 0, int pixelDiff = 0 );
bool testLayout( QString &report, int page = 0, int pixelDiff = 0 );

private:
QgsLayoutChecker() = delete;
@@ -57,7 +57,7 @@ void QgsLayoutMouseHandles::paint( QPainter *painter, const QStyleOptionGraphics
Q_UNUSED( itemStyle );
Q_UNUSED( pWidget );

if ( !QgsLayoutUtils::isPreviewRender( painter ) )
if ( !mLayout->context().isPreviewRender() )
{
//don't draw selection handles in layout outputs
return;
@@ -24,6 +24,7 @@
#include "qgssinglesymbolrenderer.h"
#include "qgsfillsymbollayer.h"
#include "qgslinesymbollayer.h"
#include "qgsmultirenderchecker.h"
#include <QObject>
#include "qgstest.h"

@@ -40,6 +41,7 @@ class TestQgsLayoutPage : public QObject
void pageSize();
void decodePageOrientation();
void grid();
void transparentPaper(); //test totally transparent paper style

void hiddenPages(); //test hidden page boundaries

@@ -165,6 +167,26 @@ void TestQgsLayoutPage::grid()

}

void TestQgsLayoutPage::transparentPaper()
{
QgsProject p;
QgsLayout l( &p );
std::unique_ptr< QgsLayoutItemPage > page( new QgsLayoutItemPage( &l ) );
page->setPageSize( QgsLayoutSize( 297, 210, QgsUnitTypes::LayoutMillimeters ) );
l.pageCollection()->addPage( page.release() );

QgsSimpleFillSymbolLayer *simpleFill = new QgsSimpleFillSymbolLayer();
std::unique_ptr< QgsFillSymbol > fillSymbol( new QgsFillSymbol() );
fillSymbol->changeSymbolLayer( 0, simpleFill );
simpleFill->setColor( Qt::transparent );
simpleFill->setStrokeColor( Qt::transparent );
l.pageCollection()->setPageStyleSymbol( fillSymbol.get() );

QgsLayoutChecker checker( QStringLiteral( "composerpaper_transparent" ), &l );
checker.setControlPathPrefix( QStringLiteral( "composer_paper" ) );
QVERIFY( checker.testLayout( mReport ) );
}

void TestQgsLayoutPage::hiddenPages()
{
QgsProject p;
@@ -44,7 +44,6 @@ class TestQgsLayoutView: public QObject
void events();
void guiRegistry();
void rubberBand();
void isPreviewRender();

private:

@@ -325,88 +324,5 @@ void TestQgsLayoutView::rubberBand()
QCOMPARE( band.pen().color(), QColor( 0, 255, 0 ) );
}

class TestViewItem : public QgsLayoutItem
{
Q_OBJECT

public:

TestViewItem( QgsLayout *layout ) : QgsLayoutItem( layout )
{
}

//implement pure virtual methods
int type() const override { return QgsLayoutItemRegistry::LayoutItem + 101; }
QString stringType() const override { return QStringLiteral( "TestItemType" ); }
bool mDrawn = false;
bool mPreview = false;

protected:
void paint( QPainter *painter, const QStyleOptionGraphicsItem *, QWidget * ) override
{
mDrawn = true;
mPreview = QgsLayoutUtils::isPreviewRender( painter );
}
void draw( QgsRenderContext &, const QStyleOptionGraphicsItem * ) override
{

}

};

void TestQgsLayoutView::isPreviewRender()
{
// test if items can detect whether a preview render is occurring
QgsProject p;
QgsLayoutView *view = new QgsLayoutView();
QgsLayout *layout = new QgsLayout( &p );
view->setCurrentLayout( layout );

TestViewItem *item = new TestViewItem( layout );
layout->addLayoutItem( item );
item->attemptMove( QgsLayoutPoint( 0, 0 ) );
item->attemptResize( QgsLayoutSize( 100, 100 ) );
layout->updateBounds();


// render to image
QVERIFY( !QgsLayoutUtils::isPreviewRender( nullptr ) );
QImage im = QImage( 250, 250, QImage::Format_RGB32 );
QPainter painter;
QVERIFY( painter.begin( &im ) );
QVERIFY( !QgsLayoutUtils::isPreviewRender( &painter ) );
painter.end();

// render to svg
QSvgGenerator generator;
generator.setFileName( QDir::tempPath() + "/layout_text.svg" );
QVERIFY( painter.begin( &generator ) );
QVERIFY( !QgsLayoutUtils::isPreviewRender( &painter ) );
painter.end();

// render to pdf
QPrinter printer;
printer.setOutputFileName( QString() );
printer.setOutputFormat( QPrinter::PdfFormat );
printer.setOutputFileName( QDir::tempPath() + "/layout_text.pdf" );
QVERIFY( painter.begin( &printer ) );
QVERIFY( !QgsLayoutUtils::isPreviewRender( &painter ) );
painter.end();

// render in view - kinda gross!
item->mDrawn = false;
item->mPreview = false;
view->show();
view->zoomFull();
while ( !item->mDrawn )
{
QApplication::processEvents();
}

QVERIFY( item->mDrawn );
QVERIFY( item->mPreview );

}

QGSTEST_MAIN( TestQgsLayoutView )
#include "testqgslayoutview.moc"

0 comments on commit 4a1bcb3

Please sign in to comment.
You can’t perform that action at this time.