mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-18 00:03:05 -04:00
[layouts] Nicer detection of rendering in a view
In compositions, a flag must be explicitly set to indicate whether the render occuring is for "previews" (i.e. rendering in a graphics view) or outputs (i.e. rendering to a image/pdf/other destination device) This isn't nice api. So we avoid this by checking the paint device type when an item is being rendered.
This commit is contained in:
parent
625eef80eb
commit
9630a39190
@ -589,6 +589,14 @@ class QgsLayoutItem : QgsLayoutObject, QGraphicsRectItem, QgsLayoutUndoObjectInt
|
||||
Draws the background for the item.
|
||||
%End
|
||||
|
||||
bool isPreviewRender( QPainter *painter ) const;
|
||||
%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
|
||||
|
||||
virtual void setFixedSize( const QgsLayoutSize &size );
|
||||
%Docstring
|
||||
Sets a fixed ``size`` for the layout item, which prevents it from being freely
|
||||
|
@ -224,7 +224,7 @@ void QgsLayoutItem::setParentGroup( QgsLayoutItemGroup *group )
|
||||
|
||||
void QgsLayoutItem::paint( QPainter *painter, const QStyleOptionGraphicsItem *itemStyle, QWidget * )
|
||||
{
|
||||
if ( !painter || !painter->device() || !shouldDrawItem() )
|
||||
if ( !painter || !painter->device() || !shouldDrawItem( painter ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
@ -431,15 +431,13 @@ bool QgsLayoutItem::shouldBlockUndoCommands() const
|
||||
return !mLayout || mLayout != scene() || mBlockUndoCommands;
|
||||
}
|
||||
|
||||
bool QgsLayoutItem::shouldDrawItem() const
|
||||
bool QgsLayoutItem::shouldDrawItem( QPainter *painter ) const
|
||||
{
|
||||
#if 0 //TODO
|
||||
if ( ( mLayout && mLayout->plotStyle() == QgsComposition::Preview ) || !mLayout )
|
||||
if ( isPreviewRender( painter ) )
|
||||
{
|
||||
//preview mode or no composition, so OK to draw item
|
||||
//preview mode so OK to draw item
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
//exporting layout, so check if item is excluded from exports
|
||||
return !mEvaluatedExcludeFromExports;
|
||||
@ -769,6 +767,31 @@ void QgsLayoutItem::drawBackground( QgsRenderContext &context )
|
||||
p->restore();
|
||||
}
|
||||
|
||||
bool QgsLayoutItem::isPreviewRender( QPainter *painter ) const
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
void QgsLayoutItem::setFixedSize( const QgsLayoutSize &size )
|
||||
{
|
||||
mFixedSize = size;
|
||||
|
@ -583,6 +583,13 @@ class CORE_EXPORT QgsLayoutItem : public QgsLayoutObject, public QGraphicsRectIt
|
||||
*/
|
||||
virtual void drawBackground( QgsRenderContext &context );
|
||||
|
||||
/**
|
||||
* 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).
|
||||
*/
|
||||
bool isPreviewRender( QPainter *painter ) const;
|
||||
|
||||
/**
|
||||
* Sets a fixed \a size for the layout item, which prevents it from being freely
|
||||
* resized. Set an empty size if item can be freely resized.
|
||||
@ -770,10 +777,12 @@ class CORE_EXPORT QgsLayoutItem : public QgsLayoutObject, public QGraphicsRectIt
|
||||
|
||||
/**
|
||||
* Returns whether the item should be drawn in the current context
|
||||
* and to the given \a painter.
|
||||
*/
|
||||
bool shouldDrawItem() const;
|
||||
bool shouldDrawItem( QPainter *painter ) const;
|
||||
|
||||
friend class TestQgsLayoutItem;
|
||||
friend class TestQgsLayoutView;
|
||||
friend class QgsLayoutItemGroup;
|
||||
};
|
||||
|
||||
|
@ -23,9 +23,12 @@
|
||||
#include "qgslayoutitemregistry.h"
|
||||
#include "qgslayoutitemguiregistry.h"
|
||||
#include "qgslayoutitemwidget.h"
|
||||
#include "qgslayoutitemshape.h"
|
||||
#include "qgsproject.h"
|
||||
#include "qgsgui.h"
|
||||
#include <QtTest/QSignalSpy>
|
||||
#include <QSvgGenerator>
|
||||
#include <QPrinter>
|
||||
|
||||
class TestQgsLayoutView: public QObject
|
||||
{
|
||||
@ -40,6 +43,7 @@ class TestQgsLayoutView: public QObject
|
||||
void events();
|
||||
void guiRegistry();
|
||||
void rubberBand();
|
||||
void isPreviewRender();
|
||||
|
||||
private:
|
||||
|
||||
@ -320,5 +324,88 @@ 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 = 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( !item->isPreviewRender( nullptr ) );
|
||||
QImage im = QImage( 250, 250, QImage::Format_RGB32 );
|
||||
QPainter painter;
|
||||
QVERIFY( painter.begin( &im ) );
|
||||
QVERIFY( !item->isPreviewRender( &painter ) );
|
||||
painter.end();
|
||||
|
||||
// render to svg
|
||||
QSvgGenerator generator;
|
||||
generator.setFileName( QDir::tempPath() + "/layout_text.svg" );
|
||||
QVERIFY( painter.begin( &generator ) );
|
||||
QVERIFY( !item->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( !item->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"
|
||||
|
Loading…
x
Reference in New Issue
Block a user