QGIS API Documentation 4.1.0-Master (d6fb7a379fb)
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 QgsLayoutGuidePositionDelegate *hozPosDelegate = new QgsLayoutGuidePositionDelegate( mHozGuidesTableView );
47 mHozGuidesTableView->setItemDelegateForColumn( 0, hozPosDelegate );
48 mHozGuidesTableView->setItemDelegateForColumn( 1, new QgsLayoutGuideUnitDelegate( mHozGuidesTableView ) );
49
50 QgsLayoutGuidePositionDelegate *vertPosDelegate = new QgsLayoutGuidePositionDelegate( mVertGuidesTableView );
51 mVertGuidesTableView->setItemDelegateForColumn( 0, vertPosDelegate );
52 mVertGuidesTableView->setItemDelegateForColumn( 1, new QgsLayoutGuideUnitDelegate( mVertGuidesTableView ) );
53
54 connect( hozPosDelegate, &QAbstractItemDelegate::closeEditor, mHozProxyModel, [this]( QWidget *, QAbstractItemDelegate::EndEditHint ) { mHozProxyModel->invalidate(); } );
55 connect( vertPosDelegate, &QAbstractItemDelegate::closeEditor, mVertProxyModel, [this]( QWidget *, QAbstractItemDelegate::EndEditHint ) { mVertProxyModel->invalidate(); } );
56
57 connect( mAddHozGuideButton, &QPushButton::clicked, this, &QgsLayoutGuideWidget::addHorizontalGuide );
58 connect( mAddVertGuideButton, &QPushButton::clicked, this, &QgsLayoutGuideWidget::addVerticalGuide );
59
60 connect( mDeleteHozGuideButton, &QPushButton::clicked, this, &QgsLayoutGuideWidget::deleteHorizontalGuide );
61 connect( mDeleteVertGuideButton, &QPushButton::clicked, this, &QgsLayoutGuideWidget::deleteVerticalGuide );
62
63 connect( mClearAllButton, &QPushButton::clicked, this, &QgsLayoutGuideWidget::clearAll );
64 connect( mApplyToAllButton, &QPushButton::clicked, this, &QgsLayoutGuideWidget::applyToAll );
65
66 connect( mLayout->pageCollection(), &QgsLayoutPageCollection::changed, this, &QgsLayoutGuideWidget::updatePageCount );
67 updatePageCount();
68 connect( mPageNumberComboBox, qOverload<int>( &QComboBox::currentIndexChanged ), this, [this]( int ) { setCurrentPage( mPageNumberComboBox->currentData().toInt() ); } );
69
71 setCurrentPage( 0 );
72}
73
74void QgsLayoutGuideWidget::addHorizontalGuide()
75{
76 const int newSourceRow = mLayout->guides().rowCount( QModelIndex() );
77 auto newGuide = std::make_unique<QgsLayoutGuide>( Qt::Horizontal, QgsLayoutMeasurement( 0 ), mLayout->pageCollection()->page( mPage ) );
78 mLayout->guides().addGuide( newGuide.release() );
79
80 const QModelIndex sourceIndex = mLayout->guides().index( newSourceRow, 0 );
81 const QModelIndex proxyIndex = mHozProxyModel->mapFromSource( sourceIndex );
82 if ( proxyIndex.isValid() )
83 {
84 mHozGuidesTableView->selectionModel()->select( proxyIndex, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows );
85 mHozGuidesTableView->edit( proxyIndex );
86 }
87}
88
89void QgsLayoutGuideWidget::addVerticalGuide()
90{
91 const int newSourceRow = mLayout->guides().rowCount( QModelIndex() );
92 auto newGuide = std::make_unique<QgsLayoutGuide>( Qt::Vertical, QgsLayoutMeasurement( 0 ), mLayout->pageCollection()->page( mPage ) );
93 mLayout->guides().addGuide( newGuide.release() );
94
95 const QModelIndex sourceIndex = mLayout->guides().index( newSourceRow, 0 );
96 const QModelIndex proxyIndex = mVertProxyModel->mapFromSource( sourceIndex );
97 if ( proxyIndex.isValid() )
98 {
99 mVertGuidesTableView->selectionModel()->select( proxyIndex, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows );
100 mVertGuidesTableView->edit( proxyIndex );
101 }
102}
103
104void QgsLayoutGuideWidget::deleteHorizontalGuide()
105{
106 mLayout->undoStack()->beginMacro( tr( "Remove Horizontal Guides" ) );
107 const auto constSelectedIndexes = mHozGuidesTableView->selectionModel()->selectedIndexes();
108 for ( const QModelIndex &index : constSelectedIndexes )
109 {
110 mHozGuidesTableView->closePersistentEditor( index );
111 if ( index.column() == 0 )
112 mHozProxyModel->removeRow( index.row() );
113 }
114 mLayout->undoStack()->endMacro();
115}
116
117void QgsLayoutGuideWidget::deleteVerticalGuide()
118{
119 mLayout->undoStack()->beginMacro( tr( "Remove Vertical Guides" ) );
120 const auto constSelectedIndexes = mVertGuidesTableView->selectionModel()->selectedIndexes();
121 for ( const QModelIndex &index : constSelectedIndexes )
122 {
123 mVertGuidesTableView->closePersistentEditor( index );
124 if ( index.column() == 0 )
125 mVertProxyModel->removeRow( index.row() );
126 }
127 mLayout->undoStack()->endMacro();
128}
129
131{
132 mPage = page;
133
134 // have to close any open editors - or we'll get a crash
135
136 // qt - y u no do this for me?
137 const auto horizontalSelectedIndexes = mHozGuidesTableView->selectionModel()->selectedIndexes();
138 for ( const QModelIndex &index : horizontalSelectedIndexes )
139 {
140 mHozGuidesTableView->closePersistentEditor( index );
141 }
142 const auto verticalSelectedIndexes = mVertGuidesTableView->selectionModel()->selectedIndexes();
143 for ( const QModelIndex &index : verticalSelectedIndexes )
144 {
145 mVertGuidesTableView->closePersistentEditor( index );
146 }
147
148 mHozProxyModel->setPage( page );
149 mVertProxyModel->setPage( page );
150
151 whileBlocking( mPageNumberComboBox )->setCurrentIndex( page );
152}
153
154void QgsLayoutGuideWidget::clearAll()
155{
156 // qt - y u no do this for me?
157 const auto horizontalSelectedIndexes = mHozGuidesTableView->selectionModel()->selectedIndexes();
158 for ( const QModelIndex &index : horizontalSelectedIndexes )
159 {
160 mHozGuidesTableView->closePersistentEditor( index );
161 }
162 const auto verticalSelectedIndexes = mVertGuidesTableView->selectionModel()->selectedIndexes();
163 for ( const QModelIndex &index : verticalSelectedIndexes )
164 {
165 mVertGuidesTableView->closePersistentEditor( index );
166 }
167
168 mLayout->undoStack()->beginMacro( tr( "Remove All Guides" ) );
169 mVertProxyModel->removeRows( 0, mVertProxyModel->rowCount() );
170 mHozProxyModel->removeRows( 0, mHozProxyModel->rowCount() );
171 mLayout->undoStack()->endMacro();
172}
173
174void QgsLayoutGuideWidget::applyToAll()
175{
176 mLayout->guides().applyGuidesToAllOtherPages( mPage );
177}
178
179void QgsLayoutGuideWidget::updatePageCount()
180{
181 const int prevPage = mPageNumberComboBox->currentIndex();
182 mPageNumberComboBox->clear();
183 for ( int i = 0; i < mLayout->pageCollection()->pageCount(); ++i )
184 mPageNumberComboBox->addItem( QString::number( i + 1 ), i );
185
186 if ( mPageNumberComboBox->count() > prevPage )
187 mPageNumberComboBox->setCurrentIndex( prevPage );
188}
189
190
192 : QStyledItemDelegate( parent )
193{}
194
195QWidget *QgsLayoutGuidePositionDelegate::createEditor( QWidget *parent, const QStyleOptionViewItem &, const QModelIndex & ) const
196{
197 QgsDoubleSpinBox *spin = new QgsDoubleSpinBox( parent );
198 spin->setMinimum( 0 );
199 spin->setMaximum( 1000000 );
200 spin->setDecimals( 2 );
201 spin->setShowClearButton( false );
202 connect( spin, static_cast<void ( QgsDoubleSpinBox::* )( double )>( &QgsDoubleSpinBox::valueChanged ), this, [this, spin]( double ) {
203 // we want to update on every spin change, not just the final
204 const_cast<QgsLayoutGuidePositionDelegate *>( this )->emit commitData( spin );
205 } );
206 return spin;
207}
208
209void QgsLayoutGuidePositionDelegate::setModelData( QWidget *editor, QAbstractItemModel *model, const QModelIndex &index ) const
210{
211 QgsDoubleSpinBox *spin = qobject_cast<QgsDoubleSpinBox *>( editor );
212 model->setData( index, spin->value(), static_cast<int>( QgsLayoutGuideCollection::CustomRole::Position ) );
213}
214
216 : QStyledItemDelegate( parent )
217{}
218
219QWidget *QgsLayoutGuideUnitDelegate::createEditor( QWidget *parent, const QStyleOptionViewItem &, const QModelIndex & ) const
220{
221 QgsLayoutUnitsComboBox *unitsCb = new QgsLayoutUnitsComboBox( parent );
222 connect( unitsCb, &QgsLayoutUnitsComboBox::unitChanged, this, [this, unitsCb]( Qgis::LayoutUnit ) {
223 // we want to update on every unit change, not just the final
224 const_cast<QgsLayoutGuideUnitDelegate *>( this )->emit commitData( unitsCb );
225 } );
226 return unitsCb;
227}
228
229void QgsLayoutGuideUnitDelegate::setModelData( QWidget *editor, QAbstractItemModel *model, const QModelIndex &index ) const
230{
231 QgsLayoutUnitsComboBox *cb = qobject_cast<QgsLayoutUnitsComboBox *>( editor );
232 model->setData( index, static_cast<int>( cb->unit() ), static_cast<int>( QgsLayoutGuideCollection::CustomRole::Units ) );
233}
LayoutUnit
Layout measurement units.
Definition qgis.h:5572
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.
int rowCount(const QModelIndex &) const override
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:51
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:7127