Skip to content

Commit e27a32d

Browse files
committedJul 11, 2017
Add status bar zoom control to layout designer
1 parent ac83093 commit e27a32d

File tree

8 files changed

+132
-1
lines changed

8 files changed

+132
-1
lines changed
 

‎python/gui/layout/qgslayoutdesignerinterface.sip

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,11 @@ class QgsLayoutDesignerInterface: QObject
5555
Closes the layout designer.
5656
%End
5757

58+
virtual void zoomFull() = 0;
59+
%Docstring
60+
Zooms to full extent of layout.
61+
%End
62+
5863
};
5964

6065
/************************************************************************

‎python/gui/layout/qgslayoutview.sip

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,8 @@ class QgsLayoutView: QGraphicsView
112112
.. seealso:: zoomOut()
113113
%End
114114

115+
void emitZoomLevelChanged();
116+
115117
signals:
116118

117119
void layoutSet( QgsLayout *layout );
@@ -127,6 +129,11 @@ class QgsLayoutView: QGraphicsView
127129
.. seealso:: setTool()
128130
%End
129131

132+
void zoomLevelChanged();
133+
%Docstring
134+
Is emitted whenever the zoom level of the view is changed.
135+
%End
136+
130137
protected:
131138
virtual void mousePressEvent( QMouseEvent *event );
132139

@@ -142,6 +149,8 @@ class QgsLayoutView: QGraphicsView
142149

143150
virtual void keyReleaseEvent( QKeyEvent *event );
144151

152+
virtual void resizeEvent( QResizeEvent *event );
153+
145154

146155
};
147156

‎src/app/layout/qgslayoutdesignerdialog.cpp

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,12 @@
2929
#include "qgsgui.h"
3030
#include "qgslayoutitemguiregistry.h"
3131
#include <QShortcut>
32+
#include <QComboBox>
33+
#include <QLineEdit>
34+
#include <QDesktopWidget>
35+
36+
//add some nice zoom levels for zoom comboboxes
37+
QList<double> QgsLayoutDesignerDialog::sStatusZoomLevelsList { 0.125, 0.25, 0.5, 1.0, 2.0, 4.0, 8.0};
3238

3339
QgsAppLayoutDesignerInterface::QgsAppLayoutDesignerInterface( QgsLayoutDesignerDialog *dialog )
3440
: QgsLayoutDesignerInterface( dialog )
@@ -50,6 +56,11 @@ void QgsAppLayoutDesignerInterface::close()
5056
mDesigner->close();
5157
}
5258

59+
void QgsAppLayoutDesignerInterface::zoomFull()
60+
{
61+
mDesigner->zoomFull();
62+
}
63+
5364

5465
QgsLayoutDesignerDialog::QgsLayoutDesignerDialog( QWidget *parent, Qt::WindowFlags flags )
5566
: QMainWindow( parent, flags )
@@ -122,8 +133,28 @@ QgsLayoutDesignerDialog::QgsLayoutDesignerDialog( QWidget *parent, Qt::WindowFla
122133
connect( mActionZoomAll, &QAction::triggered, mView, &QgsLayoutView::zoomFull );
123134
connect( mActionZoomActual, &QAction::triggered, mView, &QgsLayoutView::zoomActual );
124135

136+
mStatusZoomCombo = new QComboBox();
137+
mStatusZoomCombo->setEditable( true );
138+
mStatusZoomCombo->setInsertPolicy( QComboBox::NoInsert );
139+
mStatusZoomCombo->setCompleter( nullptr );
140+
mStatusZoomCombo->setMinimumWidth( 100 );
141+
//zoom combo box accepts decimals in the range 1-9999, with an optional decimal point and "%" sign
142+
QRegularExpression zoomRx( "\\s*\\d{1,4}(\\.\\d?)?\\s*%?" );
143+
QValidator *zoomValidator = new QRegularExpressionValidator( zoomRx, mStatusZoomCombo );
144+
mStatusZoomCombo->lineEdit()->setValidator( zoomValidator );
145+
146+
Q_FOREACH ( double level, sStatusZoomLevelsList )
147+
{
148+
mStatusZoomCombo->insertItem( 0, tr( "%1%" ).arg( level * 100.0, 0, 'f', 1 ) );
149+
}
150+
connect( mStatusZoomCombo, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsLayoutDesignerDialog::statusZoomCombo_currentIndexChanged );
151+
connect( mStatusZoomCombo->lineEdit(), &QLineEdit::returnPressed, this, &QgsLayoutDesignerDialog::statusZoomCombo_zoomEntered );
152+
153+
mStatusBar->addPermanentWidget( mStatusZoomCombo );
154+
125155
mView->setTool( mSelectTool );
126156
mView->setFocus();
157+
connect( mView, &QgsLayoutView::zoomLevelChanged, this, &QgsLayoutDesignerDialog::updateStatusZoom );
127158

128159
restoreWindowState();
129160
}
@@ -220,6 +251,44 @@ void QgsLayoutDesignerDialog::itemTypeAdded( int type )
220251
} );
221252
}
222253

254+
void QgsLayoutDesignerDialog::statusZoomCombo_currentIndexChanged( int index )
255+
{
256+
double selectedZoom = sStatusZoomLevelsList.at( sStatusZoomLevelsList.count() - index - 1 );
257+
if ( mView )
258+
{
259+
mView->setZoomLevel( selectedZoom );
260+
//update zoom combobox text for correct format (one decimal place, trailing % sign)
261+
whileBlocking( mStatusZoomCombo )->lineEdit()->setText( tr( "%1%" ).arg( selectedZoom * 100.0, 0, 'f', 1 ) );
262+
}
263+
}
264+
265+
void QgsLayoutDesignerDialog::statusZoomCombo_zoomEntered()
266+
{
267+
if ( !mView )
268+
{
269+
return;
270+
}
271+
272+
//need to remove spaces and "%" characters from input text
273+
QString zoom = mStatusZoomCombo->currentText().remove( QChar( '%' ) ).trimmed();
274+
mView->setZoomLevel( zoom.toDouble() / 100 );
275+
}
276+
277+
void QgsLayoutDesignerDialog::updateStatusZoom()
278+
{
279+
double dpi = QgsApplication::desktop()->logicalDpiX();
280+
//monitor dpi is not always correct - so make sure the value is sane
281+
if ( ( dpi < 60 ) || ( dpi > 1200 ) )
282+
dpi = 72;
283+
284+
//pixel width for 1mm on screen
285+
double scale100 = dpi / 25.4;
286+
//current zoomLevel
287+
double zoomLevel = mView->transform().m11() * 100 / scale100;
288+
289+
whileBlocking( mStatusZoomCombo )->lineEdit()->setText( tr( "%1%" ).arg( zoomLevel, 0, 'f', 1 ) );
290+
}
291+
223292
QgsLayoutView *QgsLayoutDesignerDialog::view()
224293
{
225294
return mView;

‎src/app/layout/qgslayoutdesignerdialog.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ class QgsLayoutViewToolAddItem;
2626
class QgsLayoutViewToolPan;
2727
class QgsLayoutViewToolZoom;
2828
class QgsLayoutViewToolSelect;
29+
class QComboBox;
2930

3031
class QgsAppLayoutDesignerInterface : public QgsLayoutDesignerInterface
3132
{
@@ -39,6 +40,7 @@ class QgsAppLayoutDesignerInterface : public QgsLayoutDesignerInterface
3940
public slots:
4041

4142
void close() override;
43+
void zoomFull() override;
4244

4345
private:
4446

@@ -116,6 +118,11 @@ class QgsLayoutDesignerDialog: public QMainWindow, private Ui::QgsLayoutDesigner
116118
private slots:
117119

118120
void itemTypeAdded( int type );
121+
void statusZoomCombo_currentIndexChanged( int index );
122+
void statusZoomCombo_zoomEntered();
123+
124+
//! Updates zoom level in status bar
125+
void updateStatusZoom();
119126

120127
private:
121128

@@ -127,6 +134,11 @@ class QgsLayoutDesignerDialog: public QMainWindow, private Ui::QgsLayoutDesigner
127134

128135
QgsLayoutView *mView = nullptr;
129136

137+
//! Combobox in status bar which shows/adjusts current zoom level
138+
QComboBox *mStatusZoomCombo = nullptr;
139+
140+
static QList<double> sStatusZoomLevelsList;
141+
130142
QgsLayoutViewToolAddItem *mAddItemTool = nullptr;
131143
QgsLayoutViewToolPan *mPanTool = nullptr;
132144
QgsLayoutViewToolZoom *mZoomTool = nullptr;

‎src/gui/layout/qgslayoutdesignerinterface.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,11 @@ class GUI_EXPORT QgsLayoutDesignerInterface: public QObject
6868
*/
6969
virtual void close() = 0;
7070

71+
/**
72+
* Zooms to full extent of layout.
73+
*/
74+
virtual void zoomFull() = 0;
75+
7176
};
7277

7378
#endif // QGSLAYOUTDESIGNERINTERFACE_H

‎src/gui/layout/qgslayoutview.cpp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ void QgsLayoutView::setZoomLevel( double level )
107107
//desired pixel width for 1mm on screen
108108
double scale = qBound( MIN_VIEW_SCALE, level * dpi / 25.4, MAX_VIEW_SCALE );
109109
setTransform( QTransform::fromScale( scale, scale ) );
110+
emit zoomLevelChanged();
110111
}
111112

112113
void QgsLayoutView::zoomFull()
@@ -129,6 +130,11 @@ void QgsLayoutView::zoomActual()
129130
setZoomLevel( 1.0 );
130131
}
131132

133+
void QgsLayoutView::emitZoomLevelChanged()
134+
{
135+
emit zoomLevelChanged();
136+
}
137+
132138
void QgsLayoutView::mousePressEvent( QMouseEvent *event )
133139
{
134140
if ( mTool )
@@ -249,6 +255,12 @@ void QgsLayoutView::keyReleaseEvent( QKeyEvent *event )
249255
QGraphicsView::keyReleaseEvent( event );
250256
}
251257

258+
void QgsLayoutView::resizeEvent( QResizeEvent *event )
259+
{
260+
QGraphicsView::resizeEvent( event );
261+
emit zoomLevelChanged();
262+
}
263+
252264
void QgsLayoutView::wheelZoom( QWheelEvent *event )
253265
{
254266
//get mouse wheel zoom behavior settings
@@ -292,8 +304,8 @@ void QgsLayoutView::wheelZoom( QWheelEvent *event )
292304
}
293305

294306
//update layout for new zoom
295-
#if 0 // TODO
296307
emit zoomLevelChanged();
308+
#if 0 // TODO
297309
updateRulers();
298310
#endif
299311
update();

‎src/gui/layout/qgslayoutview.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,17 @@ class GUI_EXPORT QgsLayoutView: public QGraphicsView
133133
*/
134134
void zoomActual();
135135

136+
/**
137+
* Emits the zoomLevelChanged() signal. This should be called after
138+
* calling any of the QGraphicsView base class methods which alter
139+
* the view's zoom level, i.e. QGraphicsView::fitInView().
140+
*/
141+
// NOTE - I realize these emitXXX methods are gross, but there's no clean
142+
// alternative here. We can't override the non-virtual Qt QGraphicsView
143+
// methods, and adding our own renamed methods which call the base class
144+
// methods also adds noise to the API.
145+
void emitZoomLevelChanged();
146+
136147
signals:
137148

138149
/**
@@ -148,6 +159,11 @@ class GUI_EXPORT QgsLayoutView: public QGraphicsView
148159
*/
149160
void toolSet( QgsLayoutViewTool *tool );
150161

162+
/**
163+
* Is emitted whenever the zoom level of the view is changed.
164+
*/
165+
void zoomLevelChanged();
166+
151167
protected:
152168
void mousePressEvent( QMouseEvent *event ) override;
153169
void mouseReleaseEvent( QMouseEvent *event ) override;
@@ -156,6 +172,7 @@ class GUI_EXPORT QgsLayoutView: public QGraphicsView
156172
void wheelEvent( QWheelEvent *event ) override;
157173
void keyPressEvent( QKeyEvent *event ) override;
158174
void keyReleaseEvent( QKeyEvent *event ) override;
175+
void resizeEvent( QResizeEvent *event ) override;
159176

160177
private:
161178

‎src/gui/layout/qgslayoutviewtoolzoom.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ void QgsLayoutViewToolZoom::layoutPressEvent( QgsLayoutViewMouseEvent *event )
5454

5555
//zoom view to fit desired bounds
5656
view()->fitInView( boundsRect, Qt::KeepAspectRatio );
57+
view()->emitZoomLevelChanged();
5758
}
5859
else
5960
{
@@ -99,6 +100,7 @@ void QgsLayoutViewToolZoom::layoutReleaseEvent( QgsLayoutViewMouseEvent *event )
99100

100101
//zoom view to fit desired bounds
101102
view()->fitInView( newBoundsRect, Qt::KeepAspectRatio );
103+
view()->emitZoomLevelChanged();
102104
}
103105

104106
void QgsLayoutViewToolZoom::keyPressEvent( QKeyEvent *event )

0 commit comments

Comments
 (0)
Please sign in to comment.