Skip to content
Permalink
Browse files
[layouts] Ensures that 1:1 zoom level on layout designer accounts
for actual screen dpi, and responds correctly when window is dragged
between screens
  • Loading branch information
nyalldawson committed Jul 20, 2021
1 parent d8461a1 commit 9328953aa70979fc85c1788192ee60f21070e2f4
@@ -579,6 +579,8 @@ but is still in a perfectly valid state.

virtual void paintEvent( QPaintEvent *event );

virtual void showEvent( QShowEvent *event );


};

@@ -96,6 +96,8 @@
#include <QClipboard>
#include <QRegularExpression>
#include <QUrl>
#include <QWindow>
#include <QScreen>

#ifdef Q_OS_MACX
#include <ApplicationServices/ApplicationServices.h>
@@ -1617,6 +1619,25 @@ void QgsLayoutDesignerDialog::dragEnterEvent( QDragEnterEvent *event )
}
}

void QgsLayoutDesignerDialog::showEvent( QShowEvent *event )
{
QMainWindow::showEvent( event );

updateDevicePixelFromScreen();
// keep device pixel ratio up to date on screen or resolution change
if ( window()->windowHandle() )
{
connect( window()->windowHandle(), &QWindow::screenChanged, this, [ = ]( QScreen * )
{
disconnect( mScreenDpiChangedConnection );
mScreenDpiChangedConnection = connect( window()->windowHandle()->screen(), &QScreen::physicalDotsPerInchChanged, this, &QgsLayoutDesignerDialog::updateDevicePixelFromScreen );
updateDevicePixelFromScreen();
} );

mScreenDpiChangedConnection = connect( window()->windowHandle()->screen(), &QScreen::physicalDotsPerInchChanged, this, &QgsLayoutDesignerDialog::updateDevicePixelFromScreen );
}
}

void QgsLayoutDesignerDialog::setTitle( const QString &title )
{
mTitle = title;
@@ -1801,7 +1822,7 @@ void QgsLayoutDesignerDialog::updateStatusZoom()
}
else
{
double dpi = QgsApplication::desktop()->logicalDpiX();
double dpi = mScreenDpi;
//monitor dpi is not always correct - so make sure the value is sane
if ( ( dpi < 60 ) || ( dpi > 1200 ) )
dpi = 72;
@@ -4924,6 +4945,13 @@ void QgsLayoutDesignerDialog::onItemAdded( QgsLayoutItem *item )
}
}

void QgsLayoutDesignerDialog::updateDevicePixelFromScreen()
{
if ( window()->windowHandle() )
mScreenDpi = window()->windowHandle()->screen()->physicalDotsPerInch();
updateStatusZoom();
}

void QgsLayoutDesignerDialog::storeExportResults( QgsLayoutExporter::ExportResult result, QgsLayoutExporter *exporter )
{
mLastExportResults = std::make_unique< QgsLayoutDesignerInterface::ExportResults >();
@@ -354,6 +354,7 @@ class QgsLayoutDesignerDialog: public QMainWindow, public Ui::QgsLayoutDesignerB
void closeEvent( QCloseEvent * ) override;
void dropEvent( QDropEvent *event ) override;
void dragEnterEvent( QDragEnterEvent *event ) override;
void showEvent( QShowEvent *event ) override;

private slots:

@@ -417,6 +418,7 @@ class QgsLayoutDesignerDialog: public QMainWindow, public Ui::QgsLayoutDesignerB
void backgroundTaskCountChanged( int total );
void onMapPreviewRefreshed();
void onItemAdded( QgsLayoutItem *item );
void updateDevicePixelFromScreen();

private:

@@ -516,6 +518,9 @@ class QgsLayoutDesignerDialog: public QMainWindow, public Ui::QgsLayoutDesignerB
std::unique_ptr< QgsLayoutDesignerInterface::ExportResults> mLastExportResults;
QMap< QString, QgsLabelingResults *> mLastExportLabelingResults;

double mScreenDpi = 96.0;
QMetaObject::Connection mScreenDpiChangedConnection;

//! Save window state
void saveWindowState();

@@ -42,6 +42,8 @@
#include <QMenu>
#include <QClipboard>
#include <QMimeData>
#include <QWindow>
#include <QScreen>

#define MIN_VIEW_SCALE 0.05
#define MAX_VIEW_SCALE 1000.0
@@ -207,7 +209,7 @@ void QgsLayoutView::setZoomLevel( double level )
}
else
{
double dpi = QgsApplication::desktop()->logicalDpiX();
double dpi = mScreenDpi;
//monitor dpi is not always correct - so make sure the value is sane
if ( ( dpi < 60 ) || ( dpi > 1200 ) )
dpi = 72;
@@ -1154,6 +1156,25 @@ void QgsLayoutView::paintEvent( QPaintEvent *event )
}
}

void QgsLayoutView::showEvent( QShowEvent *event )
{
QGraphicsView::showEvent( event );

updateDevicePixelFromScreen();
// keep device pixel ratio up to date on screen or resolution change
if ( window()->windowHandle() )
{
connect( window()->windowHandle(), &QWindow::screenChanged, this, [ = ]( QScreen * )
{
disconnect( mScreenDpiChangedConnection );
mScreenDpiChangedConnection = connect( window()->windowHandle()->screen(), &QScreen::physicalDotsPerInchChanged, this, &QgsLayoutView::updateDevicePixelFromScreen );
updateDevicePixelFromScreen();
} );

mScreenDpiChangedConnection = connect( window()->windowHandle()->screen(), &QScreen::physicalDotsPerInchChanged, this, &QgsLayoutView::updateDevicePixelFromScreen );
}
}

void QgsLayoutView::invalidateCachedRenders()
{
if ( !currentLayout() )
@@ -1169,6 +1190,12 @@ void QgsLayoutView::invalidateCachedRenders()
}
}

void QgsLayoutView::updateDevicePixelFromScreen()
{
if ( window()->windowHandle() )
mScreenDpi = window()->windowHandle()->screen()->physicalDotsPerInch();
}

void QgsLayoutView::viewChanged()
{
if ( mHorizontalRuler )
@@ -544,10 +544,12 @@ class GUI_EXPORT QgsLayoutView: public QGraphicsView
void scrollContentsBy( int dx, int dy ) override;
void dragEnterEvent( QDragEnterEvent *e ) override;
void paintEvent( QPaintEvent *event ) override;
void showEvent( QShowEvent *event ) override;

private slots:

void invalidateCachedRenders();
void updateDevicePixelFromScreen();

private:

@@ -578,6 +580,9 @@ class GUI_EXPORT QgsLayoutView: public QGraphicsView

bool mPaintingEnabled = true;

double mScreenDpi = 96.0;
QMetaObject::Connection mScreenDpiChangedConnection;

friend class TestQgsLayoutView;
friend class QgsLayoutMouseHandles;

0 comments on commit 9328953

Please sign in to comment.