QGIS API Documentation 3.99.0-Master (26c88405ac0)
Loading...
Searching...
No Matches
qgslayoutguidewidget.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgslayoutguidewidget.cpp
3 ------------------------
4 begin : July 2017
5 copyright : (C) 2017 by Nyall Dawson
6 email : nyall dot dawson at gmail dot com
7 ***************************************************************************/
8/***************************************************************************
9 * *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 ***************************************************************************/
16
18
19#include "qgsdoublespinbox.h"
20#include "qgslayout.h"
22#include "qgslayoutundostack.h"
24#include "qgslayoutview.h"
25
26#include "moc_qgslayoutguidewidget.cpp"
27
29 : QgsPanelWidget( parent )
30 , mLayout( layout )
31{
32 setupUi( this );
33 setPanelTitle( tr( "Guides" ) );
34
35 mHozProxyModel = new QgsLayoutGuideProxyModel( mHozGuidesTableView, Qt::Horizontal, 0 );
36 mHozProxyModel->setSourceModel( &mLayout->guides() );
37 mVertProxyModel = new QgsLayoutGuideProxyModel( mVertGuidesTableView, Qt::Vertical, 0 );
38 mVertProxyModel->setSourceModel( &mLayout->guides() );
39
40 mHozGuidesTableView->setModel( mHozProxyModel );
41 mVertGuidesTableView->setModel( mVertProxyModel );
42
43 mHozGuidesTableView->setEditTriggers( QAbstractItemView::AllEditTriggers );
44 mVertGuidesTableView->setEditTriggers( QAbstractItemView::AllEditTriggers );
45
46 mHozGuidesTableView->setItemDelegateForColumn( 0, new QgsLayoutGuidePositionDelegate( mHozGuidesTableView ) );
47 mHozGuidesTableView->setItemDelegateForColumn( 1, new QgsLayoutGuideUnitDelegate( mHozGuidesTableView ) );
48
49 mVertGuidesTableView->setItemDelegateForColumn( 0, new QgsLayoutGuidePositionDelegate( mVertGuidesTableView ) );
50 mVertGuidesTableView->setItemDelegateForColumn( 1, new QgsLayoutGuideUnitDelegate( mVertGuidesTableView ) );
51
52 connect( mAddHozGuideButton, &QPushButton::clicked, this, &QgsLayoutGuideWidget::addHorizontalGuide );
53 connect( mAddVertGuideButton, &QPushButton::clicked, this, &QgsLayoutGuideWidget::addVerticalGuide );
54
55 connect( mDeleteHozGuideButton, &QPushButton::clicked, this, &QgsLayoutGuideWidget::deleteHorizontalGuide );
56 connect( mDeleteVertGuideButton, &QPushButton::clicked, this, &QgsLayoutGuideWidget::deleteVerticalGuide );
57
58 connect( mClearAllButton, &QPushButton::clicked, this, &QgsLayoutGuideWidget::clearAll );
59 connect( mApplyToAllButton, &QPushButton::clicked, this, &QgsLayoutGuideWidget::applyToAll );
60
61 connect( mLayout->pageCollection(), &QgsLayoutPageCollection::changed, this, &QgsLayoutGuideWidget::updatePageCount );
62 updatePageCount();
63 connect( mPageNumberComboBox, qOverload<int>( &QComboBox::currentIndexChanged ), this, [this]( int ) {
64 setCurrentPage( mPageNumberComboBox->currentData().toInt() );
65 } );
66
68 setCurrentPage( 0 );
69}
70
71void QgsLayoutGuideWidget::addHorizontalGuide()
72{
73 auto newGuide = std::make_unique<QgsLayoutGuide>( Qt::Horizontal, QgsLayoutMeasurement( 0 ), mLayout->pageCollection()->page( mPage ) );
74 mLayout->guides().addGuide( newGuide.release() );
75}
76
77void QgsLayoutGuideWidget::addVerticalGuide()
78{
79 auto newGuide = std::make_unique<QgsLayoutGuide>( Qt::Vertical, QgsLayoutMeasurement( 0 ), mLayout->pageCollection()->page( mPage ) );
80 mLayout->guides().addGuide( newGuide.release() );
81}
82
83void QgsLayoutGuideWidget::deleteHorizontalGuide()
84{
85 mLayout->undoStack()->beginMacro( tr( "Remove Horizontal Guides" ) );
86 const auto constSelectedIndexes = mHozGuidesTableView->selectionModel()->selectedIndexes();
87 for ( const QModelIndex &index : constSelectedIndexes )
88 {
89 mHozGuidesTableView->closePersistentEditor( index );
90 if ( index.column() == 0 )
91 mHozProxyModel->removeRow( index.row() );
92 }
93 mLayout->undoStack()->endMacro();
94}
95
96void QgsLayoutGuideWidget::deleteVerticalGuide()
97{
98 mLayout->undoStack()->beginMacro( tr( "Remove Vertical Guides" ) );
99 const auto constSelectedIndexes = mVertGuidesTableView->selectionModel()->selectedIndexes();
100 for ( const QModelIndex &index : constSelectedIndexes )
101 {
102 mVertGuidesTableView->closePersistentEditor( index );
103 if ( index.column() == 0 )
104 mVertProxyModel->removeRow( index.row() );
105 }
106 mLayout->undoStack()->endMacro();
107}
108
110{
111 mPage = page;
112
113 // have to close any open editors - or we'll get a crash
114
115 // qt - y u no do this for me?
116 const auto horizontalSelectedIndexes = mHozGuidesTableView->selectionModel()->selectedIndexes();
117 for ( const QModelIndex &index : horizontalSelectedIndexes )
118 {
119 mHozGuidesTableView->closePersistentEditor( index );
120 }
121 const auto verticalSelectedIndexes = mVertGuidesTableView->selectionModel()->selectedIndexes();
122 for ( const QModelIndex &index : verticalSelectedIndexes )
123 {
124 mVertGuidesTableView->closePersistentEditor( index );
125 }
126
127 mHozProxyModel->setPage( page );
128 mVertProxyModel->setPage( page );
129
130 whileBlocking( mPageNumberComboBox )->setCurrentIndex( page );
131}
132
133void QgsLayoutGuideWidget::clearAll()
134{
135 // qt - y u no do this for me?
136 const auto horizontalSelectedIndexes = mHozGuidesTableView->selectionModel()->selectedIndexes();
137 for ( const QModelIndex &index : horizontalSelectedIndexes )
138 {
139 mHozGuidesTableView->closePersistentEditor( index );
140 }
141 const auto verticalSelectedIndexes = mVertGuidesTableView->selectionModel()->selectedIndexes();
142 for ( const QModelIndex &index : verticalSelectedIndexes )
143 {
144 mVertGuidesTableView->closePersistentEditor( index );
145 }
146
147 mLayout->undoStack()->beginMacro( tr( "Remove All Guides" ) );
148 mVertProxyModel->removeRows( 0, mVertProxyModel->rowCount() );
149 mHozProxyModel->removeRows( 0, mHozProxyModel->rowCount() );
150 mLayout->undoStack()->endMacro();
151}
152
153void QgsLayoutGuideWidget::applyToAll()
154{
155 mLayout->guides().applyGuidesToAllOtherPages( mPage );
156}
157
158void QgsLayoutGuideWidget::updatePageCount()
159{
160 const int prevPage = mPageNumberComboBox->currentIndex();
161 mPageNumberComboBox->clear();
162 for ( int i = 0; i < mLayout->pageCollection()->pageCount(); ++i )
163 mPageNumberComboBox->addItem( QString::number( i + 1 ), i );
164
165 if ( mPageNumberComboBox->count() > prevPage )
166 mPageNumberComboBox->setCurrentIndex( prevPage );
167}
168
169
171 : QStyledItemDelegate( parent )
172{
173}
174
175QWidget *QgsLayoutGuidePositionDelegate::createEditor( QWidget *parent, const QStyleOptionViewItem &, const QModelIndex & ) const
176{
177 QgsDoubleSpinBox *spin = new QgsDoubleSpinBox( parent );
178 spin->setMinimum( 0 );
179 spin->setMaximum( 1000000 );
180 spin->setDecimals( 2 );
181 spin->setShowClearButton( false );
182 connect( spin, static_cast<void ( QgsDoubleSpinBox::* )( double )>( &QgsDoubleSpinBox::valueChanged ), this, [this, spin]( double ) {
183 // we want to update on every spin change, not just the final
184 const_cast<QgsLayoutGuidePositionDelegate *>( this )->emit commitData( spin );
185 } );
186 return spin;
187}
188
189void QgsLayoutGuidePositionDelegate::setModelData( QWidget *editor, QAbstractItemModel *model, const QModelIndex &index ) const
190{
191 QgsDoubleSpinBox *spin = qobject_cast<QgsDoubleSpinBox *>( editor );
192 model->setData( index, spin->value(), static_cast<int>( QgsLayoutGuideCollection::CustomRole::Position ) );
193}
194
196 : QStyledItemDelegate( parent )
197{
198}
199
200QWidget *QgsLayoutGuideUnitDelegate::createEditor( QWidget *parent, const QStyleOptionViewItem &, const QModelIndex & ) const
201{
202 QgsLayoutUnitsComboBox *unitsCb = new QgsLayoutUnitsComboBox( parent );
203 connect( unitsCb, &QgsLayoutUnitsComboBox::unitChanged, this, [this, unitsCb]( Qgis::LayoutUnit ) {
204 // we want to update on every unit change, not just the final
205 const_cast<QgsLayoutGuideUnitDelegate *>( this )->emit commitData( unitsCb );
206 } );
207 return unitsCb;
208}
209
210void QgsLayoutGuideUnitDelegate::setModelData( QWidget *editor, QAbstractItemModel *model, const QModelIndex &index ) const
211{
212 QgsLayoutUnitsComboBox *cb = qobject_cast<QgsLayoutUnitsComboBox *>( editor );
213 model->setData( index, static_cast<int>( cb->unit() ), static_cast<int>( QgsLayoutGuideCollection::CustomRole::Units ) );
214}
LayoutUnit
Layout measurement units.
Definition qgis.h:5203
The QgsSpinBox is a spin box with a clear button that will set the value to the defined clear value.
void setShowClearButton(bool showClearButton)
Sets whether the widget will show a clear button.
void addGuide(QgsLayoutGuide *guide)
Adds a guide to the collection.
View delegate displaying a QgsDoubleSpinBox for the layout guide position.
QWidget * createEditor(QWidget *parent, const QStyleOptionViewItem &, const QModelIndex &index) const override
QgsLayoutGuidePositionDelegate(QObject *parent)
constructor
void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const override
Filters QgsLayoutGuideCollection models to guides of a single orientation (horizontal or vertical).
View delegate displaying a QgsLayoutUnitsComboBox for the layout guide unit.
void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const override
QgsLayoutGuideUnitDelegate(QObject *parent)
constructor
QWidget * createEditor(QWidget *parent, const QStyleOptionViewItem &, const QModelIndex &index) const override
QgsLayoutGuideWidget(QWidget *parent, QgsLayout *layout, QgsLayoutView *layoutView)
constructor
void setCurrentPage(int page)
Sets the current page number to manage the guides for.
Provides a method of storing measurements for use in QGIS layouts using a variety of different measur...
void changed()
Emitted when pages are added or removed from the collection.
QgsLayoutItemPage * page(int pageNumber)
Returns a specific page (by pageNumber) from the collection.
A custom combo box for selecting units for layout settings.
void unitChanged(Qgis::LayoutUnit unit)
Emitted when the unit is changed.
A graphical widget to display and interact with QgsLayouts.
void pageChanged(int page)
Emitted when the page visible in the view is changed.
Base class for layouts, which can contain items such as maps, labels, scalebars, etc.
Definition qgslayout.h:50
QgsLayoutPageCollection * pageCollection()
Returns a pointer to the layout's page collection, which stores and manages page items in the layout.
QgsLayoutGuideCollection & guides()
Returns a reference to the layout's guide collection, which manages page snap guides.
QgsPanelWidget(QWidget *parent=nullptr)
Base class for any widget that can be shown as an inline panel.
void setPanelTitle(const QString &panelTitle)
Set the title of the panel when shown in the interface.
QgsSignalBlocker< Object > whileBlocking(Object *object)
Temporarily blocks signals from a QObject while calling a single method from the object.
Definition qgis.h:6511