QGIS API Documentation 3.41.0-Master (3440c17df1d)
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#include "moc_qgslayoutguidewidget.cpp"
19#include "qgslayout.h"
20#include "qgslayoutview.h"
21#include "qgsdoublespinbox.h"
24#include "qgslayoutundostack.h"
25
27 : QgsPanelWidget( parent )
28 , mLayout( layout )
29{
30 setupUi( this );
31 setPanelTitle( tr( "Guides" ) );
32
33 mHozProxyModel = new QgsLayoutGuideProxyModel( mHozGuidesTableView, Qt::Horizontal, 0 );
34 mHozProxyModel->setSourceModel( &mLayout->guides() );
35 mVertProxyModel = new QgsLayoutGuideProxyModel( mVertGuidesTableView, Qt::Vertical, 0 );
36 mVertProxyModel->setSourceModel( &mLayout->guides() );
37
38 mHozGuidesTableView->setModel( mHozProxyModel );
39 mVertGuidesTableView->setModel( mVertProxyModel );
40
41 mHozGuidesTableView->setEditTriggers( QAbstractItemView::AllEditTriggers );
42 mVertGuidesTableView->setEditTriggers( QAbstractItemView::AllEditTriggers );
43
44 mHozGuidesTableView->setItemDelegateForColumn( 0, new QgsLayoutGuidePositionDelegate( mHozGuidesTableView ) );
45 mHozGuidesTableView->setItemDelegateForColumn( 1, new QgsLayoutGuideUnitDelegate( mHozGuidesTableView ) );
46
47 mVertGuidesTableView->setItemDelegateForColumn( 0, new QgsLayoutGuidePositionDelegate( mVertGuidesTableView ) );
48 mVertGuidesTableView->setItemDelegateForColumn( 1, new QgsLayoutGuideUnitDelegate( mVertGuidesTableView ) );
49
50 connect( mAddHozGuideButton, &QPushButton::clicked, this, &QgsLayoutGuideWidget::addHorizontalGuide );
51 connect( mAddVertGuideButton, &QPushButton::clicked, this, &QgsLayoutGuideWidget::addVerticalGuide );
52
53 connect( mDeleteHozGuideButton, &QPushButton::clicked, this, &QgsLayoutGuideWidget::deleteHorizontalGuide );
54 connect( mDeleteVertGuideButton, &QPushButton::clicked, this, &QgsLayoutGuideWidget::deleteVerticalGuide );
55
56 connect( mClearAllButton, &QPushButton::clicked, this, &QgsLayoutGuideWidget::clearAll );
57 connect( mApplyToAllButton, &QPushButton::clicked, this, &QgsLayoutGuideWidget::applyToAll );
58
59 connect( mLayout->pageCollection(), &QgsLayoutPageCollection::changed, this, &QgsLayoutGuideWidget::updatePageCount );
60 updatePageCount();
61 connect( mPageNumberComboBox, qOverload< int >( &QComboBox::currentIndexChanged ), this, [ = ]( int )
62 {
63 setCurrentPage( mPageNumberComboBox->currentData().toInt() );
64 } );
65
67 setCurrentPage( 0 );
68}
69
70void QgsLayoutGuideWidget::addHorizontalGuide()
71{
72 std::unique_ptr< QgsLayoutGuide > newGuide( new QgsLayoutGuide( Qt::Horizontal, QgsLayoutMeasurement( 0 ), mLayout->pageCollection()->page( mPage ) ) );
73 mLayout->guides().addGuide( newGuide.release() );
74}
75
76void QgsLayoutGuideWidget::addVerticalGuide()
77{
78 std::unique_ptr< QgsLayoutGuide > newGuide( new QgsLayoutGuide( Qt::Vertical, QgsLayoutMeasurement( 0 ), mLayout->pageCollection()->page( mPage ) ) );
79 mLayout->guides().addGuide( newGuide.release() );
80}
81
82void QgsLayoutGuideWidget::deleteHorizontalGuide()
83{
84 mLayout->undoStack()->beginMacro( tr( "Remove Horizontal Guides" ) );
85 const auto constSelectedIndexes = mHozGuidesTableView->selectionModel()->selectedIndexes();
86 for ( const QModelIndex &index : constSelectedIndexes )
87 {
88 mHozGuidesTableView->closePersistentEditor( index );
89 if ( index.column() == 0 )
90 mHozProxyModel->removeRow( index.row() );
91 }
92 mLayout->undoStack()->endMacro();
93}
94
95void QgsLayoutGuideWidget::deleteVerticalGuide()
96{
97 mLayout->undoStack()->beginMacro( tr( "Remove Vertical Guides" ) );
98 const auto constSelectedIndexes = mVertGuidesTableView->selectionModel()->selectedIndexes();
99 for ( const QModelIndex &index : constSelectedIndexes )
100 {
101 mVertGuidesTableView->closePersistentEditor( index );
102 if ( index.column() == 0 )
103 mVertProxyModel->removeRow( index.row() );
104 }
105 mLayout->undoStack()->endMacro();
106}
107
109{
110 mPage = page;
111
112 // have to close any open editors - or we'll get a crash
113
114 // qt - y u no do this for me?
115 const auto horizontalSelectedIndexes = mHozGuidesTableView->selectionModel()->selectedIndexes();
116 for ( const QModelIndex &index : horizontalSelectedIndexes )
117 {
118 mHozGuidesTableView->closePersistentEditor( index );
119 }
120 const auto verticalSelectedIndexes = mVertGuidesTableView->selectionModel()->selectedIndexes();
121 for ( const QModelIndex &index : verticalSelectedIndexes )
122 {
123 mVertGuidesTableView->closePersistentEditor( index );
124 }
125
126 mHozProxyModel->setPage( page );
127 mVertProxyModel->setPage( page );
128
129 whileBlocking( mPageNumberComboBox )->setCurrentIndex( page );
130}
131
132void QgsLayoutGuideWidget::clearAll()
133{
134 // qt - y u no do this for me?
135 const auto horizontalSelectedIndexes = mHozGuidesTableView->selectionModel()->selectedIndexes();
136 for ( const QModelIndex &index : horizontalSelectedIndexes )
137 {
138 mHozGuidesTableView->closePersistentEditor( index );
139 }
140 const auto verticalSelectedIndexes = mVertGuidesTableView->selectionModel()->selectedIndexes();
141 for ( const QModelIndex &index : verticalSelectedIndexes )
142 {
143 mVertGuidesTableView->closePersistentEditor( index );
144 }
145
146 mLayout->undoStack()->beginMacro( tr( "Remove All Guides" ) );
147 mVertProxyModel->removeRows( 0, mVertProxyModel->rowCount() );
148 mHozProxyModel->removeRows( 0, mHozProxyModel->rowCount() );
149 mLayout->undoStack()->endMacro();
150}
151
152void QgsLayoutGuideWidget::applyToAll()
153{
154 mLayout->guides().applyGuidesToAllOtherPages( mPage );
155}
156
157void QgsLayoutGuideWidget::updatePageCount()
158{
159 const int prevPage = mPageNumberComboBox->currentIndex();
160 mPageNumberComboBox->clear();
161 for ( int i = 0; i < mLayout->pageCollection()->pageCount(); ++ i )
162 mPageNumberComboBox->addItem( QString::number( i + 1 ), i );
163
164 if ( mPageNumberComboBox->count() > prevPage )
165 mPageNumberComboBox->setCurrentIndex( prevPage );
166}
167
168
170 : QStyledItemDelegate( parent )
171{
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, [ = ]( double )
183 {
184 // we want to update on every spin change, not just the final
185 const_cast< QgsLayoutGuidePositionDelegate * >( this )->emit commitData( spin );
186 } );
187 return spin;
188}
189
190void QgsLayoutGuidePositionDelegate::setModelData( QWidget *editor, QAbstractItemModel *model, const QModelIndex &index ) const
191{
192 QgsDoubleSpinBox *spin = qobject_cast< QgsDoubleSpinBox * >( editor );
193 model->setData( index, spin->value(), static_cast< int >( QgsLayoutGuideCollection::CustomRole::Position ) );
194}
195
197 : QStyledItemDelegate( parent )
198{
199}
200
201QWidget *QgsLayoutGuideUnitDelegate::createEditor( QWidget *parent, const QStyleOptionViewItem &, const QModelIndex & ) const
202{
203 QgsLayoutUnitsComboBox *unitsCb = new QgsLayoutUnitsComboBox( parent );
204 connect( unitsCb, &QgsLayoutUnitsComboBox::unitChanged, this, [ = ]( Qgis::LayoutUnit )
205 {
206 // we want to update on every unit change, not just the final
207 const_cast< QgsLayoutGuideUnitDelegate * >( this )->emit commitData( unitsCb );
208 } );
209 return unitsCb;
210}
211
212void QgsLayoutGuideUnitDelegate::setModelData( QWidget *editor, QAbstractItemModel *model, const QModelIndex &index ) const
213{
214 QgsLayoutUnitsComboBox *cb = qobject_cast< QgsLayoutUnitsComboBox *>( editor );
215 model->setData( index, static_cast< int >( cb->unit() ), static_cast< int >( QgsLayoutGuideCollection::CustomRole::Units ) );
216}
217
LayoutUnit
Layout measurement units.
Definition qgis.h:4867
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.
@ Units
Guide position units role.
void applyGuidesToAllOtherPages(int sourcePage)
Resets all other pages' guides to match the guides from the specified sourcePage.
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).
void setPage(int page)
Sets the current page for filtering matching guides.
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.
Contains the configuration for a single snap guide used by a layout.
This class provides a method of storing measurements for use in QGIS layouts using a variety of diffe...
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.
void beginMacro(const QString &commandText)
Starts a macro command, with the given descriptive commandText.
void endMacro()
Ends a macro command.
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:49
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.
QgsLayoutUndoStack * undoStack()
Returns a pointer to the layout's undo stack, which manages undo/redo states for the layout and it's ...
Base class for any widget that can be shown as a 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:5862