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.
|
Draws the background for the item.
|
||||||
%End
|
%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 );
|
virtual void setFixedSize( const QgsLayoutSize &size );
|
||||||
%Docstring
|
%Docstring
|
||||||
Sets a fixed ``size`` for the layout item, which prevents it from being freely
|
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 * )
|
void QgsLayoutItem::paint( QPainter *painter, const QStyleOptionGraphicsItem *itemStyle, QWidget * )
|
||||||
{
|
{
|
||||||
if ( !painter || !painter->device() || !shouldDrawItem() )
|
if ( !painter || !painter->device() || !shouldDrawItem( painter ) )
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -431,15 +431,13 @@ bool QgsLayoutItem::shouldBlockUndoCommands() const
|
|||||||
return !mLayout || mLayout != scene() || mBlockUndoCommands;
|
return !mLayout || mLayout != scene() || mBlockUndoCommands;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QgsLayoutItem::shouldDrawItem() const
|
bool QgsLayoutItem::shouldDrawItem( QPainter *painter ) const
|
||||||
{
|
{
|
||||||
#if 0 //TODO
|
if ( isPreviewRender( painter ) )
|
||||||
if ( ( mLayout && mLayout->plotStyle() == QgsComposition::Preview ) || !mLayout )
|
|
||||||
{
|
{
|
||||||
//preview mode or no composition, so OK to draw item
|
//preview mode so OK to draw item
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
//exporting layout, so check if item is excluded from exports
|
//exporting layout, so check if item is excluded from exports
|
||||||
return !mEvaluatedExcludeFromExports;
|
return !mEvaluatedExcludeFromExports;
|
||||||
@ -769,6 +767,31 @@ void QgsLayoutItem::drawBackground( QgsRenderContext &context )
|
|||||||
p->restore();
|
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 )
|
void QgsLayoutItem::setFixedSize( const QgsLayoutSize &size )
|
||||||
{
|
{
|
||||||
mFixedSize = size;
|
mFixedSize = size;
|
||||||
|
@ -583,6 +583,13 @@ class CORE_EXPORT QgsLayoutItem : public QgsLayoutObject, public QGraphicsRectIt
|
|||||||
*/
|
*/
|
||||||
virtual void drawBackground( QgsRenderContext &context );
|
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
|
* 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.
|
* 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
|
* 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 TestQgsLayoutItem;
|
||||||
|
friend class TestQgsLayoutView;
|
||||||
friend class QgsLayoutItemGroup;
|
friend class QgsLayoutItemGroup;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -23,9 +23,12 @@
|
|||||||
#include "qgslayoutitemregistry.h"
|
#include "qgslayoutitemregistry.h"
|
||||||
#include "qgslayoutitemguiregistry.h"
|
#include "qgslayoutitemguiregistry.h"
|
||||||
#include "qgslayoutitemwidget.h"
|
#include "qgslayoutitemwidget.h"
|
||||||
|
#include "qgslayoutitemshape.h"
|
||||||
#include "qgsproject.h"
|
#include "qgsproject.h"
|
||||||
#include "qgsgui.h"
|
#include "qgsgui.h"
|
||||||
#include <QtTest/QSignalSpy>
|
#include <QtTest/QSignalSpy>
|
||||||
|
#include <QSvgGenerator>
|
||||||
|
#include <QPrinter>
|
||||||
|
|
||||||
class TestQgsLayoutView: public QObject
|
class TestQgsLayoutView: public QObject
|
||||||
{
|
{
|
||||||
@ -40,6 +43,7 @@ class TestQgsLayoutView: public QObject
|
|||||||
void events();
|
void events();
|
||||||
void guiRegistry();
|
void guiRegistry();
|
||||||
void rubberBand();
|
void rubberBand();
|
||||||
|
void isPreviewRender();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
@ -320,5 +324,88 @@ void TestQgsLayoutView::rubberBand()
|
|||||||
QCOMPARE( band.pen().color(), QColor( 0, 255, 0 ) );
|
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 )
|
QGSTEST_MAIN( TestQgsLayoutView )
|
||||||
#include "testqgslayoutview.moc"
|
#include "testqgslayoutview.moc"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user