1 /***************************************************************************
2    qgsscalewidget.cpp
3     --------------------------------------
4    Date                 : 08.01.2015
5    Copyright            : (C) 2014 Denis Rouzaud
6    Email                : denis.rouzaud@gmail.com
7 ***************************************************************************
8 *                                                                         *
9 *   This program is free software; you can redistribute it and/or modify  *
10 *   it under the terms of the GNU General Public License as published by  *
11 *   the Free Software Foundation; either version 2 of the License, or     *
12 *   (at your option) any later version.                                   *
13 *                                                                         *
14 ***************************************************************************/
15 
16 #include <QHBoxLayout>
17 
18 #include "qgsapplication.h"
19 #include "qgsscalewidget.h"
20 #include "qgsmapcanvas.h"
21 #include "qgsproject.h"
22 #include "qgslayoutmanager.h"
23 #include "qgslayoutitemmap.h"
24 #include "qgsprintlayout.h"
25 
26 #include <QMenu>
27 
QgsScaleWidget(QWidget * parent)28 QgsScaleWidget::QgsScaleWidget( QWidget *parent )
29   : QWidget( parent )
30 {
31   QHBoxLayout *layout = new QHBoxLayout( this );
32   layout->setContentsMargins( 0, 0, 0, 0 );
33   layout->setSpacing( 6 );
34 
35   mScaleComboBox = new QgsScaleComboBox( this );
36   layout->addWidget( mScaleComboBox );
37 
38   mCurrentScaleButton = new QToolButton( this );
39   mCurrentScaleButton->setToolTip( tr( "Set to current canvas scale" ) );
40   mCurrentScaleButton->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/mActionMapIdentification.svg" ) ) );
41 
42   mMenu = new QMenu( this );
43   mCurrentScaleButton->setMenu( mMenu );
44   mCurrentScaleButton->setPopupMode( QToolButton::MenuButtonPopup );
45   connect( mMenu, &QMenu::aboutToShow, this, &QgsScaleWidget::menuAboutToShow );
46 
47   layout->addWidget( mCurrentScaleButton );
48   mCurrentScaleButton->hide();
49 
50   connect( mScaleComboBox, &QgsScaleComboBox::scaleChanged, this, &QgsScaleWidget::scaleChanged );
51   connect( mCurrentScaleButton, &QAbstractButton::clicked, this, &QgsScaleWidget::setScaleFromCanvas );
52 }
53 
setShowCurrentScaleButton(bool showCurrentScaleButton)54 void QgsScaleWidget::setShowCurrentScaleButton( bool showCurrentScaleButton )
55 {
56   mShowCurrentScaleButton = showCurrentScaleButton;
57   mCurrentScaleButton->setVisible( mShowCurrentScaleButton && mCanvas );
58 }
59 
setMapCanvas(QgsMapCanvas * canvas)60 void QgsScaleWidget::setMapCanvas( QgsMapCanvas *canvas )
61 {
62   mCanvas = canvas;
63   mCurrentScaleButton->setVisible( mShowCurrentScaleButton && mCanvas );
64 }
65 
isNull() const66 bool QgsScaleWidget::isNull() const
67 {
68   return mScaleComboBox->isNull();
69 }
70 
setAllowNull(bool allowNull)71 void QgsScaleWidget::setAllowNull( bool allowNull )
72 {
73   mScaleComboBox->setAllowNull( allowNull );
74 }
75 
allowNull() const76 bool QgsScaleWidget::allowNull() const
77 {
78   return mScaleComboBox->allowNull();
79 }
80 
setScaleFromCanvas()81 void QgsScaleWidget::setScaleFromCanvas()
82 {
83   if ( !mCanvas )
84     return;
85 
86   setScale( mCanvas->scale() );
87 }
88 
setNull()89 void QgsScaleWidget::setNull()
90 {
91   mScaleComboBox->setNull();
92 }
93 
setScale(double scale)94 void QgsScaleWidget::setScale( double scale )
95 {
96   mScaleComboBox->setScale( scale );
97 }
98 
menuAboutToShow()99 void QgsScaleWidget::menuAboutToShow()
100 {
101   mMenu->clear();
102 
103   double scale = mCanvas->scale();
104   QAction *canvasScaleAction = new QAction( QgsApplication::getThemeIcon( QStringLiteral( "/mActionMapIdentification.svg" ) ),
105       tr( "Current Canvas Scale (1:%1)" ).arg( qgsDoubleToString( scale, 0 ) ), mMenu );
106   connect( canvasScaleAction, &QAction::triggered, this, [this, scale] { setScale( scale ); } );
107   mMenu->addAction( canvasScaleAction );
108 
109   bool first = true;
110   if ( QgsLayoutManager *manager = QgsProject::instance()->layoutManager() )
111   {
112     const QList<QgsPrintLayout *> layouts = manager->printLayouts();
113     for ( const QgsPrintLayout *layout : layouts )
114     {
115       QList< QgsLayoutItemMap * > maps;
116       layout->layoutItems( maps );
117       if ( maps.empty() )
118         continue;
119 
120       if ( first )
121         mMenu->addSeparator();
122 
123       first = false;
124 
125       QMenu *layoutMenu = new QMenu( layout->name(), mMenu );
126       for ( const QgsLayoutItemMap *map : std::as_const( maps ) )
127       {
128         scale = map->scale();
129         QAction *mapScaleAction = new QAction( tr( "%1 (1:%2)" ).arg( map->displayName(), qgsDoubleToString( scale, 0 ) ), mMenu );
130         connect( mapScaleAction, &QAction::triggered, this, [this, scale] { setScale( scale ); } );
131         layoutMenu->addAction( mapScaleAction );
132       }
133       mMenu->addMenu( layoutMenu );
134     }
135   }
136 }
137